| Line 55... |
Line 55... |
| 55 |
(strcmp(sqlite3_column_name(stmt, 2), "internal_name") != 0) ||
|
55 |
(strcmp(sqlite3_column_name(stmt, 2), "internal_name") != 0) ||
|
| 56 |
(strcmp(sqlite3_column_decltype(stmt, 2), "text") != 0) ||
|
56 |
(strcmp(sqlite3_column_decltype(stmt, 2), "text") != 0) ||
|
| 57 |
(strcmp(sqlite3_column_name(stmt, 3), "loaded") != 0) ||
|
57 |
(strcmp(sqlite3_column_name(stmt, 3), "loaded") != 0) ||
|
| 58 |
(strcmp(sqlite3_column_decltype(stmt, 3), "bit") != 0) ||
|
58 |
(strcmp(sqlite3_column_decltype(stmt, 3), "bit") != 0) ||
|
| 59 |
(strcmp(sqlite3_column_name(stmt, 4), "uses") != 0) ||
|
59 |
(strcmp(sqlite3_column_name(stmt, 4), "uses") != 0) ||
|
| - |
|
60 |
(strcmp(sqlite3_column_decltype(stmt, 4), "int") != 0) ||
|
| - |
|
61 |
(strcmp(sqlite3_column_name(stmt, 5), "used") != 0) ||
|
| 60 |
(strcmp(sqlite3_column_decltype(stmt, 4), "int") != 0)) {
|
62 |
(strcmp(sqlite3_column_decltype(stmt, 5), "bit") != 0)) {
|
| 61 |
sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
|
63 |
sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
|
| 62 |
} else {
|
64 |
} else {
|
| 63 |
sqlite3_finalize(stmt);
|
65 |
sqlite3_finalize(stmt);
|
| 64 |
}
|
66 |
}
|
| 65 |
}
|
67 |
}
|
| Line 117... |
Line 119... |
| 117 |
}
|
119 |
}
|
| 118 |
|
120 |
|
| 119 |
/* add a sdf to the workspace */
|
121 |
/* add a sdf to the workspace */
|
| 120 |
int _add_sdf1(char *filename, char *internal_name) {
|
122 |
int _add_sdf1(char *filename, char *internal_name) {
|
| 121 |
sprintf(g_sql_buf[1], "insert into workspace(rel_filename, full_filename, "
|
123 |
sprintf(g_sql_buf[1], "insert into workspace(rel_filename, full_filename, "
|
| 122 |
"internal_name, loaded, uses) values('%s', '%s', '%s', 0, 0)",
|
124 |
"internal_name, loaded, uses, used) values('%s', '%s', '%s', 0, 0, 0)",
|
| 123 |
filename, _get_full_pathname2(filename), internal_name);
|
125 |
filename, _get_full_pathname2(filename), internal_name);
|
| - |
|
126 |
|
| 124 |
return _sqlite_exec(g_sql_buf[1]);
|
127 |
return _sqlite_exec(g_sql_buf[1]);
|
| 125 |
}
|
128 |
}
|
| 126 |
|
129 |
|
| 127 |
|
130 |
|
| 128 |
static char* _get_sdf_detail2(char *iname, int what) {
|
131 |
static char* _get_sdf_detail2(char *iname, int what) {
|
| Line 179... |
Line 182... |
| 179 |
*/
|
182 |
*/
|
| 180 |
filename = R_alloc(18, sizeof(char)); /* workspace10000.db\0 */
|
183 |
filename = R_alloc(18, sizeof(char)); /* workspace10000.db\0 */
|
| 181 |
sprintf(filename, "%s.db", basename);
|
184 |
sprintf(filename, "%s.db", basename);
|
| 182 |
while(_file_exists(filename) && file_idx < 10000) {
|
185 |
while(_file_exists(filename) && file_idx < 10000) {
|
| 183 |
if ((g_workspace = _is_workspace(filename)) != NULL) break;
|
186 |
if ((g_workspace = _is_workspace(filename)) != NULL) break;
|
| 184 |
/* warn("%s is not a workspace", filename) */
|
187 |
Rprintf("%s is not a workspace\n", filename);
|
| 185 |
sprintf(filename, "%s%d.db", basename, ++file_idx);
|
188 |
sprintf(filename, "%s%d.db", basename, ++file_idx);
|
| 186 |
}
|
189 |
}
|
| 187 |
|
190 |
|
| 188 |
PROTECT(ret = NEW_LOGICAL(1));
|
191 |
PROTECT(ret = NEW_LOGICAL(1));
|
| 189 |
if ((g_workspace == NULL) && (file_idx < 10000)) {
|
192 |
if ((g_workspace == NULL) && (file_idx < 10000)) {
|
| 190 |
/* no workspace found but there are still "available" file name */
|
193 |
/* no workspace found but there are still "available" file name */
|
| 191 |
/* if (file_idx) warn("workspace will be stored at #{filename}") */
|
194 |
/* if (file_idx) warn("workspace will be stored at #{filename}") */
|
| 192 |
sqlite3_open(filename, &g_workspace);
|
195 |
sqlite3_open(filename, &g_workspace);
|
| 193 |
_sqlite_exec("create table workspace(rel_filename text, full_filename text,"
|
196 |
_sqlite_exec("create table workspace(rel_filename text, full_filename text,"
|
| 194 |
"internal_name text, loaded bit, uses int)");
|
197 |
"internal_name text, loaded bit, uses int, used bit)");
|
| 195 |
LOGICAL(ret)[0] = TRUE;
|
198 |
LOGICAL(ret)[0] = TRUE;
|
| 196 |
} else if (g_workspace != NULL) {
|
199 |
} else if (g_workspace != NULL) {
|
| 197 |
/* a valid workspace has been found, load each of the tables */
|
200 |
/* a valid workspace has been found, load each of the tables */
|
| 198 |
int res, nrows, ncols;
|
201 |
int res, nrows, ncols;
|
| 199 |
char **result_set, *fname, *iname;
|
202 |
char **result_set, *fname, *iname;
|
| Line 202... |
Line 205... |
| 202 |
res = sqlite3_get_table(g_workspace, "select rel_filename, internal_name"
|
205 |
res = sqlite3_get_table(g_workspace, "select rel_filename, internal_name"
|
| 203 |
" from workspace order by uses desc",
|
206 |
" from workspace order by uses desc",
|
| 204 |
&result_set, &nrows, &ncols, NULL);
|
207 |
&result_set, &nrows, &ncols, NULL);
|
| 205 |
|
208 |
|
| 206 |
/* reset fields uses and loaded to 0 and false */
|
209 |
/* reset fields uses and loaded to 0 and false */
|
| 207 |
res = _sqlite_exec("update workspace set uses=0, loaded=0");
|
210 |
res = _sqlite_exec("update workspace set uses=0, loaded=0, used=0");
|
| 208 |
_sqlite_error(res);
|
211 |
_sqlite_error(res);
|
| 209 |
|
212 |
|
| 210 |
if (res == SQLITE_OK && nrows >= 1 && ncols == 2) {
|
213 |
if (res == SQLITE_OK && nrows >= 1 && ncols == 2) {
|
| 211 |
int maxrows; /* actual # of sdfs to be attached */
|
214 |
int maxrows; /* actual # of sdfs to be attached */
|
| 212 |
maxrows = (nrows > 30) ? 30 : nrows;
|
215 |
maxrows = (nrows > 30) ? 30 : nrows;
|
| 213 |
for (i = 1; i <= maxrows && i < nrows; i++) {
|
216 |
for (i = 1; i <= maxrows && i < nrows; i++) {
|
| 214 |
/* we will use rel_filename in opening the file, so that
|
217 |
/* we will use rel_filename in opening the file, so that
|
| 215 |
* if the user is "sensible", files will be dir agnostic */
|
218 |
* if the user is "sensible", files will be dir agnostic */
|
| 216 |
fname = result_set[i*ncols]; iname = result_set[i*ncols+1];
|
219 |
fname = result_set[i*ncols]; iname = result_set[i*ncols+1];
|
| 217 |
|
220 |
|
| 218 |
if (!USE_SDF1(iname, TRUE)) maxrows++;
|
221 |
if (!USE_SDF1(iname, TRUE, FALSE)) maxrows++;
|
| 219 |
|
222 |
|
| 220 |
/* update full_filename */
|
223 |
/* update full_filename */
|
| 221 |
sprintf(g_sql_buf[0], "update workspace set full_filename='%s', loaded=1 "
|
224 |
sprintf(g_sql_buf[0], "update workspace set full_filename='%s' "
|
| 222 |
"where iname='%s'", _get_full_pathname2(fname), iname);
|
225 |
"where iname='%s'", _get_full_pathname2(fname), iname);
|
| 223 |
_sqlite_exec(g_sql_buf[0]);
|
226 |
_sqlite_exec(g_sql_buf[0]);
|
| 224 |
}
|
227 |
}
|
| 225 |
}
|
228 |
}
|
| 226 |
sqlite3_free_table(result_set);
|
229 |
sqlite3_free_table(result_set);
|
| Line 235... |
Line 238... |
| 235 |
/* register sqlite math functions */
|
238 |
/* register sqlite math functions */
|
| 236 |
__register_vector_math();
|
239 |
__register_vector_math();
|
| 237 |
return ret;
|
240 |
return ret;
|
| 238 |
}
|
241 |
}
|
| 239 |
|
242 |
|
| 240 |
int USE_SDF1(const char *iname, int exists) {
|
243 |
int USE_SDF1(const char *iname, int exists, int protect) {
|
| 241 |
sqlite3_stmt *stmt;
|
244 |
sqlite3_stmt *stmt;
|
| 242 |
int loaded, res;
|
245 |
int loaded, res;
|
| 243 |
|
246 |
|
| 244 |
/* determine if iname is loaded */
|
247 |
/* determine if iname is loaded */
|
| 245 |
sprintf(g_sql_buf[2], "select loaded, rel_filename from workspace where internal_name='%s'", iname);
|
248 |
sprintf(g_sql_buf[2], "select loaded, rel_filename from workspace where internal_name='%s'", iname);
|
| Line 248... |
Line 251... |
| 248 |
if (exists && res != SQLITE_ROW) {
|
251 |
if (exists && res != SQLITE_ROW) {
|
| 249 |
sqlite3_finalize(stmt);
|
252 |
sqlite3_finalize(stmt);
|
| 250 |
Rprintf("Error: No SDF with name '%s' found in the workspace.\n", iname);
|
253 |
Rprintf("Error: No SDF with name '%s' found in the workspace.\n", iname);
|
| 251 |
return 0;
|
254 |
return 0;
|
| 252 |
}
|
255 |
}
|
| 253 |
loaded = sqlite3_column_int(stmt, 0);
|
256 |
loaded = (res == SQLITE_ROW) ? sqlite3_column_int(stmt, 0) : 0;
|
| 254 |
strcpy(g_sql_buf[1], (char*)sqlite3_column_text(stmt, 1)); /* ref filename */
|
257 |
strcpy(g_sql_buf[1], (char*)sqlite3_column_text(stmt, 1)); /* ref filename */
|
| 255 |
sqlite3_finalize(stmt);
|
258 |
sqlite3_finalize(stmt);
|
| 256 |
|
259 |
|
| 257 |
if (!loaded) {
|
260 |
if (!loaded) {
|
| 258 |
char *fname = g_sql_buf[1];
|
261 |
char *fname = g_sql_buf[1];
|
| Line 282... |
Line 285... |
| 282 |
sprintf(g_sql_buf[2], "attach '%s' as [%s]", fname, iname);
|
285 |
sprintf(g_sql_buf[2], "attach '%s' as [%s]", fname, iname);
|
| 283 |
res = _sqlite_exec(g_sql_buf[2]);
|
286 |
res = _sqlite_exec(g_sql_buf[2]);
|
| 284 |
if (_sqlite_error(res)) return 0;
|
287 |
if (_sqlite_error(res)) return 0;
|
| 285 |
}
|
288 |
}
|
| 286 |
|
289 |
|
| 287 |
/* upgrade its uses count */
|
290 |
/* upgrade its uses count, and protect if necessary */
|
| - |
|
291 |
if (protect) protect = 1;
|
| - |
|
292 |
sprintf(g_sql_buf[2], "update workspace set uses=uses+1, used=%d"
|
| - |
|
293 |
" where internal_name='%s'", protect, iname);
|
| - |
|
294 |
_sqlite_exec(g_sql_buf[2]);
|
| - |
|
295 |
return 1;
|
| - |
|
296 |
}
|
| - |
|
297 |
|
| - |
|
298 |
int UNUSE_SDF2(const char *iname) {
|
| 288 |
sprintf(g_sql_buf[2], "update workspace set uses=uses+1 where internal_name='%s'", iname);
|
299 |
sprintf(g_sql_buf[2], "update workspace set used=0 where internal_name='%s'", iname);
|
| 289 |
_sqlite_exec(g_sql_buf[2]);
|
300 |
_sqlite_exec(g_sql_buf[2]);
|
| 290 |
return 1;
|
301 |
return 1;
|
| 291 |
}
|
302 |
}
|
| 292 |
|
303 |
|
| 293 |
|
304 |
|
| Line 337... |
Line 348... |
| 337 |
}
|
348 |
}
|
| 338 |
|
349 |
|
| 339 |
char *iname = CHAR(STRING_ELT(name, 0));
|
350 |
char *iname = CHAR(STRING_ELT(name, 0));
|
| 340 |
SEXP ret;
|
351 |
SEXP ret;
|
| 341 |
|
352 |
|
| 342 |
if (!USE_SDF1(iname, TRUE)) return R_NilValue;
|
353 |
if (!USE_SDF1(iname, TRUE, FALSE)) return R_NilValue;
|
| 343 |
|
354 |
|
| 344 |
ret = _create_sdf_sexp(iname);
|
355 |
ret = _create_sdf_sexp(iname);
|
| 345 |
return ret;
|
356 |
return ret;
|
| 346 |
}
|
357 |
}
|
| 347 |
|
358 |
|
| Line 420... |
Line 431... |
| 420 |
/* add it to workspace */
|
431 |
/* add it to workspace */
|
| 421 |
res = _add_sdf1(fname, iname);
|
432 |
res = _add_sdf1(fname, iname);
|
| 422 |
if (_sqlite_error(res)) return R_NilValue;
|
433 |
if (_sqlite_error(res)) return R_NilValue;
|
| 423 |
|
434 |
|
| 424 |
/* attach using USE_SDF1, detach other SDF if necessary */
|
435 |
/* attach using USE_SDF1, detach other SDF if necessary */
|
| 425 |
USE_SDF1(iname, TRUE);
|
436 |
USE_SDF1(iname, TRUE, FALSE);
|
| 426 |
|
437 |
|
| 427 |
/* if internal name found in newly-attached-SDF is the same as the
|
438 |
/* if internal name found in newly-attached-SDF is the same as the
|
| 428 |
* name wanted by the user, do nothing. otherwise, update sdf_attribute
|
439 |
* name wanted by the user, do nothing. otherwise, update sdf_attribute
|
| 429 |
* on attached-SDF. this is like attachSdf then renameSdf */
|
440 |
* on attached-SDF. this is like attachSdf then renameSdf */
|
| 430 |
if (iname != iname_orig && strcmp(iname, iname_orig) != 0) {
|
441 |
if (iname != iname_orig && strcmp(iname, iname_orig) != 0) {
|
| Line 475... |
Line 486... |
| 475 |
int res, ret_tmp;
|
486 |
int res, ret_tmp;
|
| 476 |
|
487 |
|
| 477 |
iname = SDF_INAME(sdf);
|
488 |
iname = SDF_INAME(sdf);
|
| 478 |
newname = CHAR_ELT(name, 0);
|
489 |
newname = CHAR_ELT(name, 0);
|
| 479 |
|
490 |
|
| 480 |
if (!USE_SDF1(iname, TRUE)) return R_NilValue;
|
491 |
if (!USE_SDF1(iname, TRUE, FALSE)) return R_NilValue;
|
| 481 |
|
492 |
|
| 482 |
/* check if valid r name */
|
493 |
/* check if valid r name */
|
| 483 |
if (!_is_r_sym(newname)) {
|
494 |
if (!_is_r_sym(newname)) {
|
| 484 |
Rprintf("Error: %s is not a valid R symbol.", iname);
|
495 |
Rprintf("Error: %s is not a valid R symbol.", iname);
|
| 485 |
return R_NilValue;
|
496 |
return R_NilValue;
|