The R Project SVN R-packages

Rev

Rev 3307 | Rev 3324 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3307 Rev 3308
Line 51... Line 51...
51
              (strcmp(sqlite3_column_name(stmt, 0), "rel_filename") != 0) ||
51
              (strcmp(sqlite3_column_name(stmt, 0), "rel_filename") != 0) ||
52
              (strcmp(sqlite3_column_decltype(stmt, 0), "text") != 0) ||
52
              (strcmp(sqlite3_column_decltype(stmt, 0), "text") != 0) ||
53
              (strcmp(sqlite3_column_name(stmt, 1), "full_filename") != 0) ||
53
              (strcmp(sqlite3_column_name(stmt, 1), "full_filename") != 0) ||
54
              (strcmp(sqlite3_column_decltype(stmt, 1), "text") != 0) ||
54
              (strcmp(sqlite3_column_decltype(stmt, 1), "text") != 0) ||
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) ||
-
 
58
              (strcmp(sqlite3_column_decltype(stmt, 3), "bit") != 0) ||
-
 
59
              (strcmp(sqlite3_column_name(stmt, 4), "uses") != 0) ||
-
 
60
              (strcmp(sqlite3_column_decltype(stmt, 4), "int") != 0)) {
57
            sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
61
            sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
58
        } else {
62
        } else {
59
            sqlite3_finalize(stmt);
63
            sqlite3_finalize(stmt);
60
        }
64
        }
61
    }
65
    }
Line 112... Line 116...
112
    _sqlite_exec(g_sql_buf[2]);
116
    _sqlite_exec(g_sql_buf[2]);
113
}
117
}
114
 
118
 
115
/* add a sdf to the workspace */
119
/* add a sdf to the workspace */
116
int _add_sdf1(char *filename, char *internal_name) {
120
int _add_sdf1(char *filename, char *internal_name) {
117
    sprintf(g_sql_buf[1], "insert into workspace(rel_filename, full_filename, internal_name) values('%s', '%s', '%s')",
121
    sprintf(g_sql_buf[1], "insert into workspace(rel_filename, full_filename, "
-
 
122
            "internal_name, loaded, uses) values('%s', '%s', '%s', 0, 0)",
118
            filename, _get_full_pathname2(filename), internal_name);
123
            filename, _get_full_pathname2(filename), internal_name);
119
    return _sqlite_exec(g_sql_buf[1]);
124
    return _sqlite_exec(g_sql_buf[1]);
120
}
125
}
121
 
126
 
122
 
127
 
Line 183... Line 188...
183
    PROTECT(ret = NEW_LOGICAL(1));
188
    PROTECT(ret = NEW_LOGICAL(1));
184
    if ((g_workspace == NULL) && (file_idx < 10000)) {
189
    if ((g_workspace == NULL) && (file_idx < 10000)) {
185
        /* no workspace found but there are still "available" file name */
190
        /* no workspace found but there are still "available" file name */
186
        /* if (file_idx) warn("workspace will be stored at #{filename}") */
191
        /* if (file_idx) warn("workspace will be stored at #{filename}") */
187
        sqlite3_open(filename, &g_workspace);
192
        sqlite3_open(filename, &g_workspace);
188
        _sqlite_exec("create table workspace(rel_filename text, full_filename text, internal_name text)");
193
        _sqlite_exec("create table workspace(rel_filename text, full_filename text,"
-
 
194
               "internal_name text, loaded bit, uses int)");
189
        LOGICAL(ret)[0] = TRUE;
195
        LOGICAL(ret)[0] = TRUE;
190
    } else if (g_workspace != NULL) {
196
    } else if (g_workspace != NULL) {
191
        /* a valid workspace has been found, load each of the tables */
197
        /* a valid workspace has been found, load each of the tables */
192
        int res, nrows, ncols; 
198
        int res, nrows, ncols; 
193
        char **result_set, *fname, *iname;
199
        char **result_set, *fname, *iname;
194
        
200
        
-
 
201
        /* since only 30 can be loaded, sort sdf's by # of uses the last time */
195
        res = sqlite3_get_table(g_workspace, "select * from workspace", 
202
        res = sqlite3_get_table(g_workspace, "select * from workspace order by uses desc", 
196
                &result_set, &nrows, &ncols, NULL);
203
                &result_set, &nrows, &ncols, NULL);
-
 
204
 
-
 
205
        /* reset fields uses and loaded to 0 and false */
-
 
206
        res = _sqlite_exec("update workspace set uses=0, loaded=0");
-
 
207
        _sqlite_error(res);
197
        
208
        
198
        if (res == SQLITE_OK && nrows >= 1 && ncols == WORKSPACE_COLUMNS) {
209
        if (res == SQLITE_OK && nrows >= 1 && ncols == WORKSPACE_COLUMNS) {
-
 
210
            int maxrows;  /* actual # of sdfs to be attached */
-
 
211
            maxrows = (nrows > 30) ? 30 : nrows;
199
            for (i = 1; i <= nrows; i++) {
212
            for (i = 1; i <= maxrows && i < nrows; i++) {
200
                /* we will use rel_filename in opening the file, so that
213
                /* we will use rel_filename in opening the file, so that
201
                 * if the user is "sensible", files will be dir agnostic */
214
                 * if the user is "sensible", files will be dir agnostic */
202
                fname = result_set[i*ncols]; iname = result_set[i*ncols+2];
215
                fname = result_set[i*ncols]; iname = result_set[i*ncols+2];
203
                
216
                
204
                if (!_file_exists(fname)) {
217
                if (!_file_exists(fname)) {
205
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
218
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
206
                    _delete_sdf2(iname);
219
                    _delete_sdf2(iname); maxrows++;
207
                    continue;
220
                    continue;
208
                }
221
                }
209
 
222
 
210
                if (_is_sdf2(fname) == NULL) {
223
                if (_is_sdf2(fname) == NULL) {
211
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
224
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
212
                    _delete_sdf2(iname);
225
                    _delete_sdf2(iname); maxrows++;
213
                    continue;
226
                    continue;
214
                }
227
                }
215
 
228
 
216
                /* attach db */
229
                /* attach db */
217
                sprintf(g_sql_buf[0], "attach '%s' as %s", fname, iname);
230
                sprintf(g_sql_buf[0], "attach '%s' as %s", fname, iname);
218
                _sqlite_exec(g_sql_buf[0]);
231
                _sqlite_exec(g_sql_buf[0]);
219
 
232
 
220
                /* update full_filename */
233
                /* update full_filename */
221
                sprintf(g_sql_buf[0], "update workspace set full_filename='%s' where iname='%s'", _get_full_pathname2(fname), iname);
234
                sprintf(g_sql_buf[0], "update workspace set full_filename='%s', loaded=1 "
-
 
235
                        "where iname='%s'", _get_full_pathname2(fname), iname);
222
                _sqlite_exec(g_sql_buf[0]);
236
                _sqlite_exec(g_sql_buf[0]);
223
            }
237
            }
224
        }
238
        }
225
        sqlite3_free_table(result_set);
239
        sqlite3_free_table(result_set);
226
 
240
 
Line 234... Line 248...
234
    /* register sqlite math functions */
248
    /* register sqlite math functions */
235
    __register_vector_math();
249
    __register_vector_math();
236
    return ret;
250
    return ret;
237
}
251
}
238
        
252
        
-
 
253
int USE_SDF(const char *iname) {
-
 
254
    sqlite3_stmt *stmt;
-
 
255
    int loaded, res;
-
 
256
 
-
 
257
    /* determine if iname is loaded */
-
 
258
    sprintf(g_sql_buf[0], "select loaded, rel_filename from workspace where internal_name='%s'", iname);
-
 
259
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
-
 
260
    res = sqlite3_step(stmt);
-
 
261
    if (res != SQLITE_ROW) { 
-
 
262
        sqlite3_finalize(stmt); 
-
 
263
        Rprintf("Error: No SDF with name '%s' found in the workspace.\n", iname);
-
 
264
        return 0; 
-
 
265
    }
-
 
266
    loaded = sqlite3_column_int(stmt, 0);
-
 
267
    strcpy(g_sql_buf[2], (char*)sqlite3_column_text(stmt, 1));
-
 
268
    sqlite3_finalize(stmt);
-
 
269
 
-
 
270
    if (!loaded) {
-
 
271
        /* test if we have to detach somebody */
-
 
272
        int nloaded;
-
 
273
        sqlite3_prepare(g_workspace, "select count(*) from workspace where loaded=1",
-
 
274
                -1, &stmt, NULL);
-
 
275
        sqlite3_step(stmt);
-
 
276
        nloaded = sqlite3_column_int(stmt, 0);
-
 
277
        sqlite3_finalize(stmt);
-
 
278
 
-
 
279
        if (nloaded == MAX_ATTACHED) {
-
 
280
            /* have to evict */
-
 
281
            sqlite3_prepare(g_workspace, "select internal_name from workspace "
-
 
282
                    "where loaded=1 order by uses", -1, &stmt, NULL);
-
 
283
            sqlite3_step(stmt);
-
 
284
            char *iname;
-
 
285
            iname = (char *)sqlite3_column_text(stmt, 0);
-
 
286
            sprintf(g_sql_buf[0], "detach [%s]", iname);
-
 
287
            sprintf(g_sql_buf[1], "update workspace set loaded=0 where internal_name='%s'", iname);
-
 
288
            sqlite3_finalize(stmt);
-
 
289
 
-
 
290
            _sqlite_exec(g_sql_buf[0]);
-
 
291
            _sqlite_exec(g_sql_buf[1]);
-
 
292
        }
-
 
293
 
-
 
294
        /* set loaded to true */
-
 
295
        sprintf(g_sql_buf[0], "update workspace set loaded=1 where internal_name='%s'", iname);
-
 
296
        _sqlite_exec(g_sql_buf[0]);
-
 
297
 
-
 
298
        /* load, using relative path */
-
 
299
        sprintf(g_sql_buf[0], "attach '%s' as [%s]", g_sql_buf[2], iname);
-
 
300
        res = _sqlite_exec(g_sql_buf[0]);
-
 
301
        if (_sqlite_error(res)) return 0;
-
 
302
    }
-
 
303
 
-
 
304
    /* upgrade its uses count */
-
 
305
    sprintf(g_sql_buf[0], "update workspace set uses=uses+1 where internal_name='%s'", iname);
-
 
306
    _sqlite_exec(g_sql_buf[0]);
-
 
307
    return 1;
-
 
308
}
239
 
309
 
-
 
310
        
240
    
311
    
241
SEXP sdf_finalize_workspace() {
312
SEXP sdf_finalize_workspace() {
242
    SEXP ret;
313
    SEXP ret;
-
 
314
    int i;
243
    PROTECT(ret = NEW_LOGICAL(1)); 
315
    PROTECT(ret = NEW_LOGICAL(1)); 
244
    LOGICAL(ret)[0] = (sqlite3_close(g_workspace) == SQLITE_OK);
316
    LOGICAL(ret)[0] = (sqlite3_close(g_workspace) == SQLITE_OK);
245
    for (int i = 0; i < NBUFS; i++) Free(g_sql_buf[i]);
317
    for (i = 0; i < NBUFS; i++) Free(g_sql_buf[i]);
246
    UNPROTECT(1);
318
    UNPROTECT(1);
247
    return ret;
319
    return ret;
248
} 
320
} 
249
 
321
 
250
 
322
 
Line 252... Line 324...
252
    SEXP ret;
324
    SEXP ret;
253
    char **result;
325
    char **result;
254
    int nrow, ncol, res, i;
326
    int nrow, ncol, res, i;
255
 
327
 
256
    if (TYPEOF(pattern) != STRSXP) {
328
    if (TYPEOF(pattern) != STRSXP) {
257
        res = sqlite3_get_table(g_workspace, "select internal_name from workspace",
329
        res = sqlite3_get_table(g_workspace, "select internal_name from workspace "
258
                &result, &nrow, &ncol, NULL);
330
                "order by loaded desc, uses desc", &result, &nrow, &ncol, NULL);
259
    } else {
331
    } else {
260
        /* since internal_names must be a valid r symbol, 
332
        /* since internal_names must be a valid r symbol, 
261
           did not check for "'" */
333
           did not check for "'" */
262
        sprintf(g_sql_buf[0], "select internal_name from workspace where "
334
        sprintf(g_sql_buf[0], "select internal_name from workspace where "
263
                "internal_name like '%s%%'", CHAR(STRING_ELT(pattern, 0)));
335
                "internal_name like '%s%%'", CHAR(STRING_ELT(pattern, 0)));
Line 281... Line 353...
281
        return R_NilValue;
353
        return R_NilValue;
282
    }
354
    }
283
 
355
 
284
    char *iname = CHAR(STRING_ELT(name, 0));
356
    char *iname = CHAR(STRING_ELT(name, 0));
285
    SEXP ret;
357
    SEXP ret;
286
    sqlite3_stmt *stmt;
-
 
287
    int res;
-
 
288
 
-
 
289
    res = sqlite3_prepare(g_workspace, "select * from workspace where internal_name=?",
-
 
290
            -1, &stmt, NULL);
-
 
291
    if (_sqlite_error(res)) return R_NilValue;
-
 
292
 
-
 
293
    sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
-
 
294
    res = sqlite3_step(stmt);
-
 
295
 
358
 
296
    if (res == SQLITE_ROW) ret = _create_sdf_sexp(iname);
-
 
297
    else { Rprintf("Error: SDF %s not found.\n", iname); ret = R_NilValue; }
359
    if (!USE_SDF(iname)) return R_NilValue;
298
    
-
 
299
    sqlite3_finalize(stmt);
-
 
300
 
360
 
-
 
361
    ret = _create_sdf_sexp(iname);
301
    return ret;
362
    return ret;
302
}
363
}
303
 
364
 
304
SEXP sdf_attach_sdf(SEXP filename, SEXP internal_name) {
365
SEXP sdf_attach_sdf(SEXP filename, SEXP internal_name) {
305
    /* when studying this, please be mindful of the global buffers used.
366
    /* when studying this, please be mindful of the global buffers used.
Line 371... Line 432...
371
        sqlite3_finalize(stmt);
432
        sqlite3_finalize(stmt);
372
        return R_NilValue;
433
        return R_NilValue;
373
    } 
434
    } 
374
    sqlite3_finalize(stmt);
435
    sqlite3_finalize(stmt);
375
    
436
    
376
    /* finally, attach it. */
437
    /* add it to workspace */
377
    sprintf(g_sql_buf[1], "attach '%s' as [%s]", fname, iname);
-
 
378
    res = _sqlite_exec(g_sql_buf[1]);
438
    res = _add_sdf1(fname, iname);
379
    if (_sqlite_error(res)) return R_NilValue;
439
    if (_sqlite_error(res)) return R_NilValue;
380
 
440
 
-
 
441
    /* attach using USE_SDF, detach other SDF if necessary */
-
 
442
    USE_SDF(iname);
-
 
443
 
381
    /* if internal name found in newly-attached-SDF is the same as the
444
    /* if internal name found in newly-attached-SDF is the same as the
382
     * name wanted by the user, do nothing. otherwise, update sdf_attribute
445
     * name wanted by the user, do nothing. otherwise, update sdf_attribute
383
     * on attached-SDF. this is like attachSdf then renameSdf */
446
     * on attached-SDF. this is like attachSdf then renameSdf */
384
    if (iname != iname_orig && strcmp(iname, iname_orig) != 0) {
447
    if (iname != iname_orig && strcmp(iname, iname_orig) != 0) {
385
        sprintf(g_sql_buf[1], "update [%s].sdf_attributes set value=? where attr='name'",
448
        sprintf(g_sql_buf[1], "update [%s].sdf_attributes set value=? where attr='name'",
Line 394... Line 457...
394
        res = sqlite3_bind_text(stmt, 1, iname, -1, SQLITE_STATIC);
457
        res = sqlite3_bind_text(stmt, 1, iname, -1, SQLITE_STATIC);
395
        res = sqlite3_step(stmt);
458
        res = sqlite3_step(stmt);
396
        sqlite3_finalize(stmt);
459
        sqlite3_finalize(stmt);
397
    } 
460
    } 
398
 
461
 
399
    /* .. and update workspace */
-
 
400
    res = _add_sdf1(fname, iname);
-
 
401
    if (_sqlite_error(res)) return R_NilValue;
-
 
402
 
-
 
403
    return _create_sdf_sexp(iname);
462
    return _create_sdf_sexp(iname);
404
}
463
}
405
 
464
 
-
 
465
/* not necessary anymore, since stuffs will eventually be detached
-
 
466
 * if we keep on adding new sdfs */
406
SEXP sdf_detach_sdf(SEXP internal_name) {
467
SEXP sdf_detach_sdf(SEXP internal_name) {
407
    if (!IS_CHARACTER(internal_name)) {
468
    if (!IS_CHARACTER(internal_name)) {
408
        Rprintf("Error: iname argument is not a string.\n");
469
        Rprintf("Error: iname argument is not a string.\n");
409
        return R_NilValue;
470
        return R_NilValue;
410
    }
471
    }
Line 431... Line 492...
431
    int res, ret_tmp;
492
    int res, ret_tmp;
432
 
493
 
433
    iname = SDF_INAME(sdf);
494
    iname = SDF_INAME(sdf);
434
    newname = CHAR_ELT(name, 0);
495
    newname = CHAR_ELT(name, 0);
435
    
496
    
-
 
497
    if (!USE_SDF(iname)) return R_NilValue;
-
 
498
 
436
    /* check if valid r name */
499
    /* check if valid r name */
437
    if (!_is_r_sym(newname)) {
500
    if (!_is_r_sym(newname)) {
438
        Rprintf("Error: %s is not a valid R symbol.", iname);
501
        Rprintf("Error: %s is not a valid R symbol.", iname);
439
        return R_NilValue;
502
        return R_NilValue;
440
    }
503
    }