The R Project SVN R-packages

Rev

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

Rev 3252 Rev 3255
Line 1... Line 1...
1
#include <stdio.h>
1
#include <stdio.h>
2
#include <string.h>
2
#include <string.h>
3
#include "R.h"
-
 
4
#include "Rdefines.h"
-
 
5
#include "Rinternals.h"
-
 
6
#include "sqlite3.h"
-
 
7
 
3
 
8
#define __SQLITE_WORKSPACE__
4
#define __SQLITE_WORKSPACE__
9
#include "sqlite_dataframe.h"
5
#include "sqlite_dataframe.h"
10
 
6
 
11
sqlite3 *g_workspace = NULL;
7
sqlite3 *g_workspace = NULL;
Line 17... Line 13...
17
    int res;
13
    int res;
18
    res = sqlite3_open(filename, &db);
14
    res = sqlite3_open(filename, &db);
19
    if (res != SQLITE_OK) { goto is_sqlitedb_FAIL; }
15
    if (res != SQLITE_OK) { goto is_sqlitedb_FAIL; }
20
 
16
 
21
    sqlite3_stmt *stmt; char *sql = "select * from sqlite_master";
17
    sqlite3_stmt *stmt; char *sql = "select * from sqlite_master";
22
    res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0);
18
    res = sqlite3_prepare(db, sql, -1, &stmt, 0);
23
    if (stmt != NULL) sqlite3_finalize(stmt);
19
    if (stmt != NULL) sqlite3_finalize(stmt);
24
    /*char **result_set;
20
    /*char **result_set;
25
    char nrow, ncol;
21
    char nrow, ncol;
26
    res = sqlite3_get_table(db, "select * from sqlite_master limit 0", 
22
    res = sqlite3_get_table(db, "select * from sqlite_master limit 0", 
27
            &result_set, &nrow, &ncol, NULL);
23
            &result_set, &nrow, &ncol, NULL);
Line 39... Line 35...
39
    sqlite3* db = _is_sqlitedb(filename); 
35
    sqlite3* db = _is_sqlitedb(filename); 
40
 
36
 
41
    if (db != NULL) {
37
    if (db != NULL) {
42
        sqlite3_stmt *stmt;
38
        sqlite3_stmt *stmt;
43
        char *sql = "select * from workspace";
39
        char *sql = "select * from workspace";
44
        int res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0), ncols;
40
        int res = sqlite3_prepare(db, sql, -1, &stmt, 0), ncols;
45
        if ((res != SQLITE_OK) || /* no workspace table */
41
        if ((res != SQLITE_OK) || /* no workspace table */
46
              ((ncols = sqlite3_column_count(stmt)) != 2) ||
42
              ((ncols = sqlite3_column_count(stmt)) != WORKSPACE_COLUMNS) ||
47
              /* below also checks the ordering of the columns */
43
              /* below also checks the ordering of the columns */
48
              (strcmp(sqlite3_column_name(stmt, 0), "filename") != 0) ||
44
              (strcmp(sqlite3_column_name(stmt, 0), "rel_filename") != 0) ||
49
              (strcmp(sqlite3_column_decltype(stmt, 0), "text") != 0) ||
45
              (strcmp(sqlite3_column_decltype(stmt, 0), "text") != 0) ||
-
 
46
              (strcmp(sqlite3_column_name(stmt, 1), "full_filename") != 0) ||
-
 
47
              (strcmp(sqlite3_column_decltype(stmt, 1), "text") != 0) ||
50
              (strcmp(sqlite3_column_name(stmt, 1), "internal_name") != 0) ||
48
              (strcmp(sqlite3_column_name(stmt, 2), "internal_name") != 0) ||
51
              (strcmp(sqlite3_column_decltype(stmt, 1), "text") != 0)) {
49
              (strcmp(sqlite3_column_decltype(stmt, 2), "text") != 0)) {
52
            sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
50
            sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
53
        } else {
51
        } else {
54
            sqlite3_finalize(stmt);
52
            sqlite3_finalize(stmt);
55
        }
53
        }
56
    }
54
    }
Line 63... Line 61...
63
    int ret = (db != NULL);
61
    int ret = (db != NULL);
64
 
62
 
65
    if (ret) {
63
    if (ret) {
66
        sqlite3_stmt *stmt;
64
        sqlite3_stmt *stmt;
67
        char *sql = "select * from sdf_attributes";
65
        char *sql = "select * from sdf_attributes";
68
        int res = sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL), ncols;
66
        int res = sqlite3_prepare(db, sql, -1, &stmt, NULL), ncols;
69
        ret = ((res == SQLITE_OK) && /* no attribute table */
67
        ret = ((res == SQLITE_OK) && /* no attribute table */
70
               ((ncols = sqlite3_column_count(stmt)) == 2) &&
68
               ((ncols = sqlite3_column_count(stmt)) == 2) &&
71
               (strcmp(sqlite3_column_name(stmt, 0), "attr") == 0) &&
69
               (strcmp(sqlite3_column_name(stmt, 0), "attr") == 0) &&
72
               (strcmp(sqlite3_column_decltype(stmt, 0), "text") == 0) &&
70
               (strcmp(sqlite3_column_decltype(stmt, 0), "text") == 0) &&
73
               (strcmp(sqlite3_column_name(stmt, 1), "value") == 0) &&
71
               (strcmp(sqlite3_column_name(stmt, 1), "value") == 0) &&
Line 76... Line 74...
76
        if (!ret) goto _is_sdf_cleanup;
74
        if (!ret) goto _is_sdf_cleanup;
77
        sqlite3_finalize(stmt); 
75
        sqlite3_finalize(stmt); 
78
        
76
        
79
        
77
        
80
        sql = "select * from sdf_data";
78
        sql = "select * from sdf_data";
81
        res = sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL);
79
        res = sqlite3_prepare(db, sql, -1, &stmt, NULL);
82
        ret = (res == SQLITE_OK);  /* if not, missing data table */
80
        ret = (res == SQLITE_OK);  /* if not, missing data table */
83
 
81
 
84
_is_sdf_cleanup:
82
_is_sdf_cleanup:
85
        sqlite3_finalize(stmt);
83
        sqlite3_finalize(stmt);
86
        sqlite3_close(db);
84
        sqlite3_close(db);
Line 92... Line 90...
92
void _delete_sdf2(char *iname) {
90
void _delete_sdf2(char *iname) {
93
    sprintf(g_sql_buf[2], "delete from workspace where internal_name='%s';", iname);
91
    sprintf(g_sql_buf[2], "delete from workspace where internal_name='%s';", iname);
94
    _sqlite_exec(g_sql_buf[2]);
92
    _sqlite_exec(g_sql_buf[2]);
95
}
93
}
96
 
94
 
-
 
95
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')",
-
 
97
            filename, _get_full_pathname2(filename), internal_name);
-
 
98
    return _sqlite_exec(g_sql_buf[1]);
-
 
99
}
97
 
100
 
98
SEXP sdf_init_workspace() {
101
SEXP sdf_init_workspace() {
99
    int file_idx = 0, i;
102
    int file_idx = 0, i;
100
    char *basename = "workspace", *filename;
103
    char *basename = "workspace", *filename;
101
    FILE *f;
104
    FILE *f;
Line 124... Line 127...
124
    PROTECT(ret = NEW_LOGICAL(1));
127
    PROTECT(ret = NEW_LOGICAL(1));
125
    if ((g_workspace == NULL) && (file_idx < 10000)) {
128
    if ((g_workspace == NULL) && (file_idx < 10000)) {
126
        /* no workspace found but there are still "available" file name */
129
        /* no workspace found but there are still "available" file name */
127
        /* if (file_idx) warn("workspace will be stored at #{filename}") */
130
        /* if (file_idx) warn("workspace will be stored at #{filename}") */
128
        sqlite3_open(filename, &g_workspace);
131
        sqlite3_open(filename, &g_workspace);
129
        _sqlite_exec("create table workspace(filename text, internal_name text)");
132
        _sqlite_exec("create table workspace(rel_filename text, full_filename text, internal_name text)");
130
        LOGICAL(ret)[0] = TRUE;
133
        LOGICAL(ret)[0] = TRUE;
131
    } else if (g_workspace != NULL) {
134
    } else if (g_workspace != NULL) {
132
        /* a valid workspace has been found, load each of the tables */
135
        /* a valid workspace has been found, load each of the tables */
133
        int res, nrows, ncols; 
136
        int res, nrows, ncols; 
134
        char **result_set, *fname, *iname;
137
        char **result_set, *fname, *iname;
135
        
138
        
136
        res = sqlite3_get_table(g_workspace, "select * from workspace", 
139
        res = sqlite3_get_table(g_workspace, "select * from workspace", 
137
                &result_set, &nrows, &ncols, NULL);
140
                &result_set, &nrows, &ncols, NULL);
138
        
141
        
139
        if (res == SQLITE_OK && nrows >= 1 && ncols == 2) {
142
        if (res == SQLITE_OK && nrows >= 1 && ncols == WORKSPACE_COLUMNS) {
140
            for (i = 1; i <= nrows; i++) {
143
            for (i = 1; i <= nrows; i++) {
-
 
144
                /* we will use rel_filename in opening the file, so that
-
 
145
                 * if the user is "sensible", files will be dir agnostic */
141
                fname = result_set[i*ncols]; iname = result_set[i*ncols+1];
146
                fname = result_set[i*ncols]; iname = result_set[i*ncols+2];
142
                
147
                
143
                if (!_file_exists(fname)) {
148
                if (!_file_exists(fname)) {
144
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
149
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
145
                    _delete_sdf2(iname);
150
                    _delete_sdf2(iname);
146
                    continue;
151
                    continue;
Line 150... Line 155...
150
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
155
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
151
                    _delete_sdf2(iname);
156
                    _delete_sdf2(iname);
152
                    continue;
157
                    continue;
153
                }
158
                }
154
 
159
 
-
 
160
                /* attach db */
155
                sprintf(g_sql_buf[0], "attach '%s' as %s", fname, iname);
161
                sprintf(g_sql_buf[0], "attach '%s' as %s", fname, iname);
156
                _sqlite_exec(g_sql_buf[0]);
162
                _sqlite_exec(g_sql_buf[0]);
-
 
163
 
-
 
164
                /* update full_filename */
-
 
165
                sprintf(g_sql_buf[0], "update workspace set full_filename='%s' where iname='%s'", _get_full_pathname2(fname), iname);
-
 
166
                _sqlite_exec(g_sql_buf[0]);
157
            }
167
            }
158
        }
168
        }
159
        sqlite3_free_table(result_set);
169
        sqlite3_free_table(result_set);
160
 
170
 
161
        LOGICAL(ret)[0] = TRUE;
171
        LOGICAL(ret)[0] = TRUE;
Line 171... Line 181...
171
    
181
    
172
SEXP sdf_finalize_workspace() {
182
SEXP sdf_finalize_workspace() {
173
    SEXP ret;
183
    SEXP ret;
174
    PROTECT(ret = NEW_LOGICAL(1)); 
184
    PROTECT(ret = NEW_LOGICAL(1)); 
175
    LOGICAL(ret)[0] = (sqlite3_close(g_workspace) == SQLITE_OK);
185
    LOGICAL(ret)[0] = (sqlite3_close(g_workspace) == SQLITE_OK);
-
 
186
    for (int i = 0; i < NBUFS; i++) Free(g_sql_buf[i]);
176
    UNPROTECT(1);
187
    UNPROTECT(1);
177
    return ret;
188
    return ret;
178
} 
189
} 
179
 
190
 
180
 
191
 
Line 215... Line 226...
215
    SEXP ret;
226
    SEXP ret;
216
    sqlite3_stmt *stmt;
227
    sqlite3_stmt *stmt;
217
    int res;
228
    int res;
218
 
229
 
219
    res = sqlite3_prepare(g_workspace, "select * from workspace where internal_name=?",
230
    res = sqlite3_prepare(g_workspace, "select * from workspace where internal_name=?",
220
            45, &stmt, NULL);
231
            -1, &stmt, NULL);
221
    if (_sqlite_error(res)) return R_NilValue;
232
    if (_sqlite_error(res)) return R_NilValue;
222
 
233
 
223
    sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
234
    sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
224
    res = sqlite3_step(stmt);
235
    res = sqlite3_step(stmt);
225
 
236
 
Line 228... Line 239...
228
    
239
    
229
    sqlite3_finalize(stmt);
240
    sqlite3_finalize(stmt);
230
 
241
 
231
    return ret;
242
    return ret;
232
}
243
}
-
 
244
 
-
 
245
SEXP sdf_attach_sdf(SEXP filename, SEXP internal_name) {
-
 
246
    char *fname, *iname;
-
 
247
    int fnamelen, res;
-
 
248
    sqlite3_stmt *stmt;
-
 
249
 
-
 
250
    if (IS_CHARACTER(filename)) {
-
 
251
        fname = CHAR_ELT(filename, 0);
-
 
252
        fnamelen = strlen(fname);
-
 
253
    } else {
-
 
254
        Rprintf("Error: filename argument must be a string.\n");
-
 
255
        return R_NilValue;
-
 
256
    }
-
 
257
 
-
 
258
    if (strcmp(fname+(fnamelen-3),".db") != 0) {
-
 
259
        Rprintf("Error: Cannot attach because extension is not .db, which may cause problems [%s].\n");
-
 
260
        return R_NilValue;
-
 
261
    }
-
 
262
 
-
 
263
    /* check if it exists in the workspace already */
-
 
264
    _get_full_pathname2(fname);
-
 
265
    res = sqlite3_prepare(g_workspace, "select internal_name from workspace where full_filename=?",
-
 
266
            -1, &stmt, NULL);
-
 
267
    sqlite3_bind_text(stmt, 1, g_sql_buf[2], strlen(g_sql_buf[2]), SQLITE_STATIC);
-
 
268
    res = sqlite3_step(stmt);
-
 
269
    if (res == SQLITE_ROW) {
-
 
270
        Rprintf("Warning: That sdf is already attached as '%s'\n",
-
 
271
                sqlite3_column_text(stmt, 0));
-
 
272
        sqlite3_finalize(stmt);
-
 
273
        return R_NilValue;
-
 
274
    } else sqlite3_finalize(stmt);
-
 
275
 
-
 
276
 
-
 
277
    /* internal_name checking and processing. */
-
 
278
    int file_idx, inamelen;
-
 
279
    if (IS_CHARACTER(internal_name)) {
-
 
280
        iname = CHAR_ELT(internal_name, 0);
-
 
281
        if (!_is_r_sym(iname)) {
-
 
282
            Rprintf("Error: %s is not a valid R symbol.", iname);
-
 
283
            return R_NilValue;
-
 
284
        }
-
 
285
 
-
 
286
        res = sqlite3_prepare(g_workspace, "select full_filename from workspace "
-
 
287
               " where internal_name=?", -1, &stmt, NULL);
-
 
288
        sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
-
 
289
        res = sqlite3_step(stmt);
-
 
290
        if (res == SQLITE_ROW) {
-
 
291
            Rprintf("Warning: The sdf internal name '%s' is already taken by file %s.\n",
-
 
292
                    iname, sqlite3_column_text(stmt, 1));
-
 
293
            sqlite3_finalize(stmt);
-
 
294
            return R_NilValue;
-
 
295
        } else sqlite3_finalize(stmt);
-
 
296
    } else {
-
 
297
        file_idx = 1;
-
 
298
        res = sqlite3_prepare(g_workspace, "select 1 from workspace "
-
 
299
               " where internal_name=?", -1, &stmt, NULL);
-
 
300
        
-
 
301
        do {
-
 
302
            inamelen = sprintf(g_sql_buf[0], "data%d", file_idx++);
-
 
303
            sqlite3_bind_text(stmt, 1, g_sql_buf[0], inamelen, SQLITE_STATIC);
-
 
304
            res = sqlite3_step(stmt);
-
 
305
            sqlite3_reset(stmt);
-
 
306
        } while (res == SQLITE_ROW && file_idx < 10000);
-
 
307
 
-
 
308
        sqlite3_finalize(stmt);
-
 
309
 
-
 
310
        if (file_idx < 10000) {
-
 
311
            iname = g_sql_buf[0];
-
 
312
        } else {
-
 
313
            Rprintf("Error: Cannot find a free default file name.\n");
-
 
314
            return R_NilValue;
-
 
315
        }
-
 
316
    }
-
 
317
 
-
 
318
 
-
 
319
    /* check if it is a valid sdf file */
-
 
320
    if (!_is_sdf(fname)) {
-
 
321
        Rprintf("Error: %s is not a valid SDF.\n", fname);
-
 
322
        return R_NilValue;
-
 
323
    }
-
 
324
 
-
 
325
    /* finally, attach it. */
-
 
326
    sprintf(g_sql_buf[1], "attach '%s' as [%s]", fname, iname);
-
 
327
    res = _sqlite_exec(g_sql_buf[1]);
-
 
328
    if (_sqlite_error(res)) return R_NilValue;
-
 
329
 
-
 
330
    /* .. and update workspace */
-
 
331
    res = _add_sdf1(fname, iname);
-
 
332
    if (_sqlite_error(res)) return R_NilValue;
-
 
333
 
-
 
334
    return _create_sdf_sexp(iname);
-
 
335
}
-
 
336
 
-
 
337
SEXP sdf_detach_sdf(SEXP internal_name) {
-
 
338
    if (!IS_CHARACTER(internal_name)) {
-
 
339
        Rprintf("Error: iname argument is not a string.\n");
-
 
340
        return R_NilValue;
-
 
341
    }
-
 
342
 
-
 
343
    char *iname = CHAR_ELT(internal_name, 0);
-
 
344
    sprintf(g_sql_buf[0], "detach [%s]", iname);
-
 
345
 
-
 
346
    SEXP ret; int res;
-
 
347
    res = _sqlite_exec(g_sql_buf[0]);
-
 
348
    res = !_sqlite_error(res);
-
 
349
 
-
 
350
    if (res) _delete_sdf2(iname);
-
 
351
 
-
 
352
    PROTECT(ret = NEW_LOGICAL(1));
-
 
353
    LOGICAL(ret)[0] = res;
-
 
354
    UNPROTECT(1);
-
 
355
 
-
 
356
    return ret;
-
 
357
}