The R Project SVN R-packages

Rev

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

Rev 3282 Rev 3307
Line 2... Line 2...
2
#include <string.h>
2
#include <string.h>
3
 
3
 
4
#define __SQLITE_WORKSPACE__
4
#define __SQLITE_WORKSPACE__
5
#include "sqlite_dataframe.h"
5
#include "sqlite_dataframe.h"
6
 
6
 
-
 
7
/* global variables */
7
sqlite3 *g_workspace = NULL;
8
sqlite3 *g_workspace = NULL;
8
char *g_sql_buf[NBUFS];
9
char *g_sql_buf[NBUFS];
9
int g_sql_buf_sz[NBUFS];
10
int g_sql_buf_sz[NBUFS];
10
 
11
 
-
 
12
/****************************************************************************
-
 
13
 * UTILITY FUNCTIONS
-
 
14
 ****************************************************************************/
-
 
15
 
-
 
16
/* test if a file is a sqlite database file */
11
sqlite3* _is_sqlitedb(char *filename) {
17
sqlite3* _is_sqlitedb(char *filename) {
12
    sqlite3 *db;
18
    sqlite3 *db;
13
    int res;
19
    int res;
14
    res = sqlite3_open(filename, &db);
20
    res = sqlite3_open(filename, &db);
15
    if (res != SQLITE_OK) { goto is_sqlitedb_FAIL; }
21
    if (res != SQLITE_OK) { goto is_sqlitedb_FAIL; }
Line 29... Line 35...
29
is_sqlitedb_FAIL:
35
is_sqlitedb_FAIL:
30
    sqlite3_close(db);
36
    sqlite3_close(db);
31
    return NULL;
37
    return NULL;
32
}
38
}
33
 
39
 
-
 
40
/* test if a file is a SQLiteDF workspace */
34
sqlite3* _is_workspace(char *filename) {
41
sqlite3* _is_workspace(char *filename) {
35
    sqlite3* db = _is_sqlitedb(filename); 
42
    sqlite3* db = _is_sqlitedb(filename); 
36
 
43
 
37
    if (db != NULL) {
44
    if (db != NULL) {
38
        sqlite3_stmt *stmt;
45
        sqlite3_stmt *stmt;
Line 54... Line 61...
54
    }
61
    }
55
 
62
 
56
    return db;
63
    return db;
57
}
64
}
58
 
65
 
-
 
66
/* test if a file is a sqlite.data.frame. returns the internal name of the
-
 
67
 * sdf if file is an sdf or NULL otherwise */
59
int _is_sdf(char *filename) {
68
char * _is_sdf2(char *filename) {
60
    sqlite3* db = _is_sqlitedb(filename); 
69
    sqlite3* db = _is_sqlitedb(filename); 
61
    int ret = (db != NULL);
70
    char *ret = (db == NULL) ? NULL : filename;
62
 
71
 
63
    if (ret) {
72
    if (ret) {
64
        sqlite3_stmt *stmt;
73
        sqlite3_stmt *stmt;
65
        char *sql = "select * from sdf_attributes";
74
        char *sql = "select * from sdf_attributes where attr='name'";
-
 
75
        int res, ncols;
66
        int res = sqlite3_prepare(db, sql, -1, &stmt, NULL), ncols;
76
        res = sqlite3_prepare(db, sql, -1, &stmt, NULL);
67
        ret = ((res == SQLITE_OK) && /* no attribute table */
77
        ret = (((res == SQLITE_OK) && /* no attribute table */
68
               ((ncols = sqlite3_column_count(stmt)) == 2) &&
78
               ((ncols = sqlite3_column_count(stmt)) == 2) &&
69
               (strcmp(sqlite3_column_name(stmt, 0), "attr") == 0) &&
79
               (strcmp(sqlite3_column_name(stmt, 0), "attr") == 0) &&
70
               (strcmp(sqlite3_column_decltype(stmt, 0), "text") == 0) &&
80
               (strcmp(sqlite3_column_decltype(stmt, 0), "text") == 0) &&
71
               (strcmp(sqlite3_column_name(stmt, 1), "value") == 0) &&
81
               (strcmp(sqlite3_column_name(stmt, 1), "value") == 0) &&
72
               (strcmp(sqlite3_column_decltype(stmt, 1), "text") == 0)) ;
82
               (strcmp(sqlite3_column_decltype(stmt, 1), "text") == 0))) ? ret : NULL ;
73
        
-
 
74
        if (!ret) goto _is_sdf_cleanup;
-
 
75
        sqlite3_finalize(stmt); 
-
 
76
        
83
        
-
 
84
        if (ret == NULL) goto _is_sdf_cleanup;
-
 
85
 
-
 
86
        /* get internal name */
-
 
87
        res = sqlite3_step(stmt);
-
 
88
        ret = (res == SQLITE_ROW) ? ret : NULL;
-
 
89
        if (ret == NULL) goto _is_sdf_cleanup;
-
 
90
 
-
 
91
        /* copy to buf2, because when we finalize stmt, we won't be sure
-
 
92
         * if sqlite3_column_text()'s ret value will still be there */
-
 
93
        strcpy(g_sql_buf[2], (char *)sqlite3_column_text(stmt, 1));
-
 
94
        ret = g_sql_buf[2];
-
 
95
        sqlite3_finalize(stmt);
77
        
96
        
78
        sql = "select * from sdf_data";
97
        sql = "select * from sdf_data";
79
        res = sqlite3_prepare(db, sql, -1, &stmt, NULL);
98
        res = sqlite3_prepare(db, sql, -1, &stmt, NULL);
80
        ret = (res == SQLITE_OK);  /* if not, missing data table */
99
        ret = (res == SQLITE_OK) ? ret : NULL;  /* if not, missing data table */
81
 
100
 
82
_is_sdf_cleanup:
101
_is_sdf_cleanup:
83
        sqlite3_finalize(stmt);
102
        sqlite3_finalize(stmt);
84
        sqlite3_close(db);
103
        sqlite3_close(db);
85
    }
104
    }
86
 
105
 
87
    return ret;
106
    return ret;
88
}
107
}
89
 
108
 
-
 
109
/* remove an sdf from the workspace */
90
void _delete_sdf2(char *iname) {
110
void _delete_sdf2(char *iname) {
91
    sprintf(g_sql_buf[2], "delete from workspace where internal_name='%s';", iname);
111
    sprintf(g_sql_buf[2], "delete from workspace where internal_name='%s';", iname);
92
    _sqlite_exec(g_sql_buf[2]);
112
    _sqlite_exec(g_sql_buf[2]);
93
}
113
}
94
 
114
 
-
 
115
/* add a sdf to the workspace */
95
int _add_sdf1(char *filename, char *internal_name) {
116
int _add_sdf1(char *filename, char *internal_name) {
96
    sprintf(g_sql_buf[1], "insert into workspace(rel_filename, full_filename, internal_name) values('%s', '%s', '%s')",
117
    sprintf(g_sql_buf[1], "insert into workspace(rel_filename, full_filename, internal_name) values('%s', '%s', '%s')",
97
            filename, _get_full_pathname2(filename), internal_name);
118
            filename, _get_full_pathname2(filename), internal_name);
98
    return _sqlite_exec(g_sql_buf[1]);
119
    return _sqlite_exec(g_sql_buf[1]);
99
}
120
}
100
 
121
 
-
 
122
 
-
 
123
static char* _get_sdf_detail2(char *iname, int what) {
-
 
124
    sqlite3_stmt *stmt;
-
 
125
    char * ret; int res;
-
 
126
 
-
 
127
    sprintf(g_sql_buf[2], "select full_filename from workspace where "
-
 
128
            "internal_name='%s'", iname);
-
 
129
    sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, NULL);
-
 
130
    res = sqlite3_step(stmt);
-
 
131
    sqlite3_finalize(stmt);
-
 
132
 
-
 
133
    if (res == SQLITE_DONE) {
-
 
134
        ret = NULL;
-
 
135
    } else {
-
 
136
        ret = g_sql_buf[2];
-
 
137
        switch (what) {
-
 
138
            case SDF_DETAIL_EXISTS: 
-
 
139
                break; /* doesn't matter */
-
 
140
            case SDF_DETAIL_FULLFILENAME:
-
 
141
                strcpy(g_sql_buf[2], (char *)sqlite3_column_text(stmt, 0));
-
 
142
                break;
-
 
143
        }
-
 
144
    }
-
 
145
 
-
 
146
    return ret;
-
 
147
}
-
 
148
 
-
 
149
/* returns TRUE if sdf exists in the workspace */
-
 
150
int _sdf_exists2(char *iname) {
-
 
151
    return _get_sdf_detail2(iname, SDF_DETAIL_EXISTS) != NULL;
-
 
152
}
-
 
153
 
-
 
154
/****************************************************************************
-
 
155
 * WORKSPACE FUNCTIONS
-
 
156
 ****************************************************************************/
-
 
157
 
101
SEXP sdf_init_workspace() {
158
SEXP sdf_init_workspace() {
102
    int file_idx = 0, i;
159
    int file_idx = 0, i;
103
    char *basename = "workspace", *filename;
160
    char *basename = "workspace", *filename;
104
    SEXP ret;
161
    SEXP ret;
105
 
162
 
Line 148... Line 205...
148
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
205
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
149
                    _delete_sdf2(iname);
206
                    _delete_sdf2(iname);
150
                    continue;
207
                    continue;
151
                }
208
                }
152
 
209
 
153
                if (!_is_sdf(fname)) {
210
                if (_is_sdf2(fname) == NULL) {
154
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
211
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
155
                    _delete_sdf2(iname);
212
                    _delete_sdf2(iname);
156
                    continue;
213
                    continue;
157
                }
214
                }
158
 
215
 
Line 171... Line 228...
171
    } else { /* can't find nor create workspace */
228
    } else { /* can't find nor create workspace */
172
        LOGICAL(ret)[0] = FALSE;
229
        LOGICAL(ret)[0] = FALSE;
173
    }
230
    }
174
 
231
 
175
    UNPROTECT(1);
232
    UNPROTECT(1);
-
 
233
 
-
 
234
    /* register sqlite math functions */
-
 
235
    __register_vector_math();
176
    return ret;
236
    return ret;
177
}
237
}
178
        
238
        
179
 
239
 
180
    
240
    
Line 232... Line 292...
232
 
292
 
233
    sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
293
    sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
234
    res = sqlite3_step(stmt);
294
    res = sqlite3_step(stmt);
235
 
295
 
236
    if (res == SQLITE_ROW) ret = _create_sdf_sexp(iname);
296
    if (res == SQLITE_ROW) ret = _create_sdf_sexp(iname);
237
    else ret = R_NilValue;
297
    else { Rprintf("Error: SDF %s not found.\n", iname); ret = R_NilValue; }
238
    
298
    
239
    sqlite3_finalize(stmt);
299
    sqlite3_finalize(stmt);
240
 
300
 
241
    return ret;
301
    return ret;
242
}
302
}
243
 
303
 
244
SEXP sdf_attach_sdf(SEXP filename, SEXP internal_name) {
304
SEXP sdf_attach_sdf(SEXP filename, SEXP internal_name) {
-
 
305
    /* when studying this, please be mindful of the global buffers used.
-
 
306
     * you have been warned */
245
    char *fname, *iname;
307
    char *fname, *iname, *iname_orig;;
246
    int fnamelen, res;
308
    int fnamelen, res;
247
    sqlite3_stmt *stmt;
309
    sqlite3_stmt *stmt;
248
 
310
 
249
    if (IS_CHARACTER(filename)) {
311
    if (IS_CHARACTER(filename)) {
250
        fname = CHAR_ELT(filename, 0);
312
        fname = CHAR_ELT(filename, 0);
Line 257... Line 319...
257
    if (strcmp(fname+(fnamelen-3),".db") != 0) {
319
    if (strcmp(fname+(fnamelen-3),".db") != 0) {
258
        Rprintf("Error: Cannot attach because extension is not .db, which may cause problems [%s].\n");
320
        Rprintf("Error: Cannot attach because extension is not .db, which may cause problems [%s].\n");
259
        return R_NilValue;
321
        return R_NilValue;
260
    }
322
    }
261
 
323
 
-
 
324
    /* check if it is a valid sdf file */
-
 
325
    if (_is_sdf2(fname) == NULL) {
-
 
326
        Rprintf("Error: %s is not a valid SDF.\n", fname);
-
 
327
        return R_NilValue;
-
 
328
    } else {
-
 
329
        /* _is_sdf2 puts the orig iname in buf2. transfer data to buf0 since
-
 
330
         * functions called below will use buf2 */
-
 
331
        strcpy(g_sql_buf[0], g_sql_buf[2]);
-
 
332
        iname_orig = g_sql_buf[0];
-
 
333
    }
-
 
334
 
262
    /* check if it exists in the workspace already */
335
    /* check if file to be attached exists in the workspace already */
263
    _get_full_pathname2(fname);
336
    _get_full_pathname2(fname);
264
    res = sqlite3_prepare(g_workspace, "select internal_name from workspace where full_filename=?",
337
    res = sqlite3_prepare(g_workspace, "select internal_name from workspace where full_filename=?",
265
            -1, &stmt, NULL);
338
            -1, &stmt, NULL);
266
    sqlite3_bind_text(stmt, 1, g_sql_buf[2], strlen(g_sql_buf[2]), SQLITE_STATIC);
339
    sqlite3_bind_text(stmt, 1, g_sql_buf[2], -1, SQLITE_STATIC);
267
    res = sqlite3_step(stmt);
340
    res = sqlite3_step(stmt);
268
    if (res == SQLITE_ROW) {
341
    if (res == SQLITE_ROW) {
269
        Rprintf("Warning: That sdf is already attached as '%s'\n",
342
        Rprintf("Warning: That sdf is already attached as '%s'\n",
270
                sqlite3_column_text(stmt, 0));
343
                sqlite3_column_text(stmt, 0));
271
        sqlite3_finalize(stmt);
344
        sqlite3_finalize(stmt);
272
        return R_NilValue;
345
        return R_NilValue;
273
    } else sqlite3_finalize(stmt);
346
    } else sqlite3_finalize(stmt);
274
 
347
 
275
 
348
 
276
    /* internal_name checking and processing. */
349
    /* internal_name checking and processing. */
277
    int file_idx, inamelen;
-
 
278
    if (IS_CHARACTER(internal_name)) {
350
    if (IS_CHARACTER(internal_name)) {
-
 
351
        /* if name is specified, rename the sdf. original internal name is the
-
 
352
         * one stored at sdf_attribute */
279
        iname = CHAR_ELT(internal_name, 0);
353
        iname = CHAR_ELT(internal_name, 0);
280
        if (!_is_r_sym(iname)) {
354
        if (!_is_r_sym(iname)) {
281
            Rprintf("Error: %s is not a valid R symbol.", iname);
355
            Rprintf("Error: %s is not a valid R symbol.\n", iname);
282
            return R_NilValue;
356
            return R_NilValue;
283
        }
357
        }
284
 
-
 
285
        res = sqlite3_prepare(g_workspace, "select full_filename from workspace "
-
 
286
               " where internal_name=?", -1, &stmt, NULL);
-
 
287
        sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
-
 
288
        res = sqlite3_step(stmt);
-
 
289
        if (res == SQLITE_ROW) {
-
 
290
            Rprintf("Warning: The sdf internal name '%s' is already taken by file %s.\n",
-
 
291
                    iname, sqlite3_column_text(stmt, 1));
-
 
292
            sqlite3_finalize(stmt);
-
 
293
            return R_NilValue;
-
 
294
        } else sqlite3_finalize(stmt);
-
 
295
    } else {
358
    } else {
296
        file_idx = 1;
-
 
297
        res = sqlite3_prepare(g_workspace, "select 1 from workspace "
-
 
298
               " where internal_name=?", -1, &stmt, NULL);
-
 
299
        
-
 
300
        do {
-
 
301
            inamelen = sprintf(g_sql_buf[0], "data%d", file_idx++);
359
        /* if no name is specified, use original internal name */
302
            sqlite3_bind_text(stmt, 1, g_sql_buf[0], inamelen, SQLITE_STATIC);
-
 
303
            res = sqlite3_step(stmt);
-
 
304
            sqlite3_reset(stmt);
-
 
305
        } while (res == SQLITE_ROW && file_idx < 10000);
-
 
306
 
-
 
307
        sqlite3_finalize(stmt);
-
 
308
 
-
 
309
        if (file_idx < 10000) {
-
 
310
            iname = g_sql_buf[0];
360
        iname = (char *)iname_orig;  /* g_sql_buf[0]! */
311
        } else {
-
 
312
            Rprintf("Error: Cannot find a free default file name.\n");
-
 
313
            return R_NilValue;
-
 
314
        }
-
 
315
    }
361
    }
316
 
362
 
317
 
-
 
318
    /* check if it is a valid sdf file */
363
    /* check if internal name is already used in the workspace */
-
 
364
    res = sqlite3_prepare(g_workspace, "select full_filename from workspace "
-
 
365
           " where internal_name=?", -1, &stmt, NULL);
-
 
366
    sqlite3_bind_text(stmt, 1, iname, -1, SQLITE_STATIC);
-
 
367
    res = sqlite3_step(stmt);
319
    if (!_is_sdf(fname)) {
368
    if (res == SQLITE_ROW) {
320
        Rprintf("Error: %s is not a valid SDF.\n", fname);
369
        Rprintf("Error: The sdf internal name '%s' is already used by file %s.\n",
-
 
370
                iname, sqlite3_column_text(stmt, 1));
-
 
371
        sqlite3_finalize(stmt);
321
        return R_NilValue;
372
        return R_NilValue;
322
    }
373
    } 
-
 
374
    sqlite3_finalize(stmt);
323
 
375
    
324
    /* finally, attach it. */
376
    /* finally, attach it. */
325
    sprintf(g_sql_buf[1], "attach '%s' as [%s]", fname, iname);
377
    sprintf(g_sql_buf[1], "attach '%s' as [%s]", fname, iname);
326
    res = _sqlite_exec(g_sql_buf[1]);
378
    res = _sqlite_exec(g_sql_buf[1]);
327
    if (_sqlite_error(res)) return R_NilValue;
379
    if (_sqlite_error(res)) return R_NilValue;
328
 
380
 
-
 
381
    /* 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
-
 
383
     * on attached-SDF. this is like attachSdf then renameSdf */
-
 
384
    if (iname != iname_orig && strcmp(iname, iname_orig) != 0) {
-
 
385
        sprintf(g_sql_buf[1], "update [%s].sdf_attributes set value=? where attr='name'",
-
 
386
                iname);
-
 
387
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
-
 
388
        if (_sqlite_error(res)) { 
-
 
389
            sqlite3_finalize(stmt); 
-
 
390
            sprintf(g_sql_buf[1], "detach [%s]", iname);
-
 
391
            _sqlite_exec(g_sql_buf[1]);
-
 
392
            return R_NilValue;
-
 
393
        }
-
 
394
        res = sqlite3_bind_text(stmt, 1, iname, -1, SQLITE_STATIC);
-
 
395
        res = sqlite3_step(stmt);
-
 
396
        sqlite3_finalize(stmt);
-
 
397
    } 
-
 
398
 
329
    /* .. and update workspace */
399
    /* .. and update workspace */
330
    res = _add_sdf1(fname, iname);
400
    res = _add_sdf1(fname, iname);
331
    if (_sqlite_error(res)) return R_NilValue;
401
    if (_sqlite_error(res)) return R_NilValue;
332
 
402
 
333
    return _create_sdf_sexp(iname);
403
    return _create_sdf_sexp(iname);
Line 352... Line 422...
352
    LOGICAL(ret)[0] = res;
422
    LOGICAL(ret)[0] = res;
353
    UNPROTECT(1);
423
    UNPROTECT(1);
354
 
424
 
355
    return ret;
425
    return ret;
356
}
426
}
-
 
427
 
-
 
428
SEXP sdf_rename_sdf(SEXP sdf, SEXP name) {
-
 
429
    char *iname, *path, *newname;
-
 
430
    SEXP ret;
-
 
431
    int res, ret_tmp;
-
 
432
 
-
 
433
    iname = SDF_INAME(sdf);
-
 
434
    newname = CHAR_ELT(name, 0);
-
 
435
    
-
 
436
    /* check if valid r name */
-
 
437
    if (!_is_r_sym(newname)) {
-
 
438
        Rprintf("Error: %s is not a valid R symbol.", iname);
-
 
439
        return R_NilValue;
-
 
440
    }
-
 
441
 
-
 
442
    /* check if sdf already exists */
-
 
443
    if (_sdf_exists2(newname)) { /* name is already taken */
-
 
444
        Rprintf("Error: the name \"%s\" is already taken.\n", newname);
-
 
445
        return R_NilValue;
-
 
446
    }
-
 
447
 
-
 
448
    /* get path of the sdf file, because we're goint to detach it */
-
 
449
    path = _get_sdf_detail2(iname, SDF_DETAIL_FULLFILENAME);
-
 
450
    if (path == NULL) {
-
 
451
        Rprintf("Error: no sdf named \"%s\" exists.\n", iname);
-
 
452
        return R_NilValue;
-
 
453
    }
-
 
454
 
-
 
455
    /* change name in sdf_attribute */
-
 
456
    sprintf(g_sql_buf[0], "update [%s].sdf_attributes set value='%s' "
-
 
457
            "where attr='name'", iname, newname);
-
 
458
    res = _sqlite_exec(g_sql_buf[0]);
-
 
459
    Rprintf("result: %d\n", res);
-
 
460
    /* if (_sqlite_error(res)) return R_NilValue; */
-
 
461
 
-
 
462
    /* detach and remove sdf from workspace */
-
 
463
    sprintf(g_sql_buf[0], "detach '%s'", iname);
-
 
464
    res = _sqlite_exec(g_sql_buf[0]);
-
 
465
    ret_tmp = !_sqlite_error(res);
-
 
466
 
-
 
467
    /* remove from ws, attach and add again to ws using new name */
-
 
468
    if (ret_tmp) {
-
 
469
        _delete_sdf2(iname);
-
 
470
        sprintf(g_sql_buf[0], "attach '%s' as '%s'", path, newname);
-
 
471
        res = _sqlite_exec(g_sql_buf[0]);
-
 
472
        ret_tmp = !_sqlite_error(res);
-
 
473
        
-
 
474
        /* TODO: make path relative! */
-
 
475
        _add_sdf1(iname, path);
-
 
476
    }
-
 
477
 
-
 
478
    PROTECT(ret = NEW_LOGICAL(1));
-
 
479
    LOGICAL(ret)[0] = ret_tmp;
-
 
480
    UNPROTECT(1);
-
 
481
 
-
 
482
    return ret;
-
 
483
}
-
 
484