The R Project SVN R-packages

Rev

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

Rev 3251 Rev 3252
Line 3... Line 3...
3
#include "R.h"
3
#include "R.h"
4
#include "Rdefines.h"
4
#include "Rdefines.h"
5
#include "Rinternals.h"
5
#include "Rinternals.h"
6
#include "sqlite3.h"
6
#include "sqlite3.h"
7
 
7
 
-
 
8
#define __SQLITE_WORKSPACE__
8
sqlite3 *workspace = NULL;
9
#include "sqlite_dataframe.h"
9
 
10
 
-
 
11
sqlite3 *g_workspace = NULL;
-
 
12
char *g_sql_buf[NBUFS];
-
 
13
int g_sql_buf_sz[NBUFS];
-
 
14
 
10
sqlite3* _is_sqlitedb(filename) {
15
sqlite3* _is_sqlitedb(char *filename) {
11
    sqlite3 *db;
16
    sqlite3 *db;
12
    int res;
17
    int res;
13
    res = sqlite3_open(filename, &db);
18
    res = sqlite3_open(filename, &db);
14
    if (res != SQLITE_OK) { goto is_sqlitedb_FAIL; }
19
    if (res != SQLITE_OK) { goto is_sqlitedb_FAIL; }
15
 
20
 
16
    sqlite3_stmt *stmt; char *sql = "select * from workspace";
21
    sqlite3_stmt *stmt; char *sql = "select * from sqlite_master";
17
    res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0);
22
    res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0);
18
    if (stmt != NULL) sqlite3_finalize(stmt);
23
    if (stmt != NULL) sqlite3_finalize(stmt);
19
    /*char **result_set;
24
    /*char **result_set;
20
    char nrow, ncol;
25
    char nrow, ncol;
21
    res = sqlite3_get_table(db, "select * from sqlite_master limit 0", 
26
    res = sqlite3_get_table(db, "select * from sqlite_master limit 0", 
Line 24... Line 29...
24
    if (res != SQLITE_OK) goto is_sqlitedb_FAIL;
29
    if (res != SQLITE_OK) goto is_sqlitedb_FAIL;
25
 
30
 
26
    return db;
31
    return db;
27
 
32
 
28
is_sqlitedb_FAIL:
33
is_sqlitedb_FAIL:
29
    sqlite_close(db);
34
    sqlite3_close(db);
30
    return NULL;
35
    return NULL;
31
}
36
}
32
 
37
 
33
sqlite3* _is_workspace(char *filename) {
38
sqlite3* _is_workspace(char *filename) {
34
    sqlite3* db = _is_sqlitedb(filename); 
39
    sqlite3* db = _is_sqlitedb(filename); 
Line 39... Line 44...
39
        int res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0), ncols;
44
        int res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0), ncols;
40
        if ((res != SQLITE_OK) || /* no workspace table */
45
        if ((res != SQLITE_OK) || /* no workspace table */
41
              ((ncols = sqlite3_column_count(stmt)) != 2) ||
46
              ((ncols = sqlite3_column_count(stmt)) != 2) ||
42
              /* below also checks the ordering of the columns */
47
              /* below also checks the ordering of the columns */
43
              (strcmp(sqlite3_column_name(stmt, 0), "filename") != 0) ||
48
              (strcmp(sqlite3_column_name(stmt, 0), "filename") != 0) ||
44
              (strcmp(sqlite3_column_decl(stmt, 0), "text") != 0) ||
49
              (strcmp(sqlite3_column_decltype(stmt, 0), "text") != 0) ||
45
              (strcmp(sqlite3_column_name(stmt, 1), "internal_name") != 0) ||
50
              (strcmp(sqlite3_column_name(stmt, 1), "internal_name") != 0) ||
46
              (strcmp(sqlite3_column_decl(stmt, 1), "text") != 0)) {
51
              (strcmp(sqlite3_column_decltype(stmt, 1), "text") != 0)) {
47
            sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
52
            sqlite3_finalize(stmt); sqlite3_close(db); db = NULL;
48
        } else {
53
        } else {
49
            sqlite3_finalize(stmt);
54
            sqlite3_finalize(stmt);
50
        }
55
        }
51
    }
56
    }
Line 53... Line 58...
53
    return db;
58
    return db;
54
}
59
}
55
 
60
 
56
int _is_sdf(char *filename) {
61
int _is_sdf(char *filename) {
57
    sqlite3* db = _is_sqlitedb(filename); 
62
    sqlite3* db = _is_sqlitedb(filename); 
-
 
63
    int ret = (db != NULL);
58
 
64
 
59
    if (db != NULL) {
65
    if (ret) {
60
        sqlite3_stmt *stmt;
66
        sqlite3_stmt *stmt;
61
        char *sql = "select * from sdf_attributes";
67
        char *sql = "select * from sdf_attributes";
62
        int res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0), ncols;
68
        int res = sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL), ncols;
63
        if ((res != SQLITE_OK) || /* no workspace table */
69
        ret = ((res == SQLITE_OK) && /* no attribute table */
64
              ((ncols = sqlite3_column_count(stmt)) != 2) ||
70
               ((ncols = sqlite3_column_count(stmt)) == 2) &&
65
              (strcmp(sqlite3_column_name(stmt, 0), "attr") != 0) ||
71
               (strcmp(sqlite3_column_name(stmt, 0), "attr") == 0) &&
66
              (strcmp(sqlite3_column_decl(stmt, 0), "text") != 0) ||
72
               (strcmp(sqlite3_column_decltype(stmt, 0), "text") == 0) &&
67
              (strcmp(sqlite3_column_name(stmt, 1), "value") != 0) ||
73
               (strcmp(sqlite3_column_name(stmt, 1), "value") == 0) &&
68
              (strcmp(sqlite3_column_decl(stmt, 1), "text") != 0)) {
74
               (strcmp(sqlite3_column_decltype(stmt, 1), "text") == 0)) ;
69
            sqlite3_finalize(stmt); sqlite3_close(db); return NULL;
-
 
70
        } 
-
 
71
        
75
        
72
        /* we also check the contents of sdf_attributes */
76
        if (!ret) goto _is_sdf_cleanup;
73
        sqlite3_finalize(stmt);
77
        sqlite3_finalize(stmt); 
74
        
78
        
-
 
79
        
-
 
80
        sql = "select * from sdf_data";
-
 
81
        res = sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL);
-
 
82
        ret = (res == SQLITE_OK);  /* if not, missing data table */
-
 
83
 
-
 
84
_is_sdf_cleanup:
-
 
85
        sqlite3_finalize(stmt);
-
 
86
        sqlite3_close(db);
75
    }
87
    }
76
 
88
 
77
    return db;
89
    return ret;
78
}
90
}
79
 
91
 
80
int _file_exists(char *filename) {
92
void _delete_sdf2(char *iname) {
81
    FILE *f; int ret = FALSE;
-
 
82
    if ((f = fopen(filename, "rb")) != null) { fclose(f); ret = TRUE; }
93
    sprintf(g_sql_buf[2], "delete from workspace where internal_name='%s';", iname);
83
    return ret;
94
    _sqlite_exec(g_sql_buf[2]);
84
}
95
}
85
 
96
 
86
 
97
 
87
SEXP sdf_init_workspace() {
98
SEXP sdf_init_workspace() {
88
    int file_idx = 0;
99
    int file_idx = 0, i;
89
    char *basename = "workspace", *filename;
100
    char *basename = "workspace", *filename;
90
    FILE *f;
101
    FILE *f;
91
    SEXP ret;
102
    SEXP ret;
92
 
103
 
-
 
104
    /* initialize sql_buf */
-
 
105
    for (i = 0; i < NBUFS; i++) {
-
 
106
        if (g_sql_buf[i] == NULL) {
-
 
107
            g_sql_buf_sz[i] = 1024;
-
 
108
            g_sql_buf[i] = Calloc(g_sql_buf_sz[i], char);
-
 
109
        }
-
 
110
    }
-
 
111
 
-
 
112
    /*
93
    /* check for workspace.db, workspace1.db, ..., workspace9999.db if they
113
     * check for workspace.db, workspace1.db, ..., workspace9999.db if they
94
     * are valid workspace file. if one is found, use that as the workspace.
114
     * are valid workspace file. if one is found, use that as the workspace.
95
     */
115
     */
96
    filename = R_alloc(18, sizeof(char)); /* workspace10000.db\0 */
116
    filename = R_alloc(18, sizeof(char)); /* workspace10000.db\0 */
97
    sprintf(filename, "%s.db", basename);
117
    sprintf(filename, "%s.db", basename);
98
    while(_file_exists(filename) && file_idx < 10000); {
118
    while(_file_exists(filename) && file_idx < 10000) {
99
        if ((workspace = _is_workspace(filename)) != NULL) break;
119
        if ((g_workspace = _is_workspace(filename)) != NULL) break;
100
        /* warn("%s is not a workspace", filename) */
120
        /* warn("%s is not a workspace", filename) */
101
        sprintf(filename, "%s%d.db", basename, ++file_idx);
121
        sprintf(filename, "%s%d.db", basename, ++file_idx);
102
    }
122
    }
103
 
123
 
104
    PROTECT(ret = NEW_LOGICAL(1));
124
    PROTECT(ret = NEW_LOGICAL(1));
105
    if ((workspace == NULL) && (file_idx < 10000)) {
125
    if ((g_workspace == NULL) && (file_idx < 10000)) {
106
        /* no workspace found but there are still "available" file name */
126
        /* no workspace found but there are still "available" file name */
107
        /* if (file_idx) warn("workspace will be stored at #{filename}") */
127
        /* if (file_idx) warn("workspace will be stored at #{filename}") */
108
        sqlite3_open(filename, &workspace);
128
        sqlite3_open(filename, &g_workspace);
109
        sqlite3_exec(workspace, "create table workspace(filename text, internal_name text)", NULL, NULL, NULL);
129
        _sqlite_exec("create table workspace(filename text, internal_name text)");
110
        LOGICAL(ret)[0] = TRUE;
130
        LOGICAL(ret)[0] = TRUE;
111
    } else if (file_idx >= 10000) {
131
    } else if (g_workspace != NULL) {
112
        /* a valid workspace has been found, load each of the tables */
132
        /* a valid workspace has been found, load each of the tables */
113
        int res, nrows, ncols; 
133
        int res, nrows, ncols; 
114
        char **result_set, *fname, *iname;
134
        char **result_set, *fname, *iname;
115
        
135
        
116
        res = sqlite3_get_table(workspace, "select * from workspace", 
136
        res = sqlite3_get_table(g_workspace, "select * from workspace", 
117
                &result_set, &nrows, &ncols, NULL);
137
                &result_set, &nrows, &ncols, NULL);
118
        
138
        
119
        if (res == SQLITE_OK && nrows > 1 && ncols == 2) {
139
        if (res == SQLITE_OK && nrows >= 1 && ncols == 2) {
120
            sqlite3_stmt *stmt;
-
 
121
            for (i = 1; i < nrows; i++) {
140
            for (i = 1; i <= nrows; i++) {
122
                fname = result_set[i*ncols]; iname = result_set[i*ncols+1];
141
                fname = result_set[i*ncols]; iname = result_set[i*ncols+1];
123
                
142
                
124
                if (!_file_exists(fname)) {
143
                if (!_file_exists(fname)) {
125
                    /* warn('table does not exist: #{fname}'); */
144
                    Rprintf("Warning: SDF %s does not exist.\n", iname);
-
 
145
                    _delete_sdf2(iname);
126
                    continue;
146
                    continue;
127
                }
147
                }
128
 
148
 
129
                if (!_is_sdf(fname)) {
149
                if (!_is_sdf(fname)) {
130
                }
-
 
131
 
-
 
132
                sql = sqlite3_mprintf("attach '%s' as %s", fname, iname);
150
                    Rprintf("Warning: %s is not a valid SDF.\n", fname);
133
                res = sqlite3_prepare(db, sql, strlen(sql), &stmt, 0);
-
 
134
                if (res != SQL_OK) { 
151
                    _delete_sdf2(iname);
135
                    /* warn('not an sqlite-db file */
-
 
136
                    continue;
152
                    continue;
137
                }
153
                }
-
 
154
 
-
 
155
                sprintf(g_sql_buf[0], "attach '%s' as %s", fname, iname);
-
 
156
                _sqlite_exec(g_sql_buf[0]);
138
            }
157
            }
139
        }
158
        }
140
        sqlite3_free_table(result_set);
159
        sqlite3_free_table(result_set);
141
 
160
 
142
        LOGICAL(ret)[0] = TRUE;
161
        LOGICAL(ret)[0] = TRUE;
Line 148... Line 167...
148
    return ret;
167
    return ret;
149
}
168
}
150
        
169
        
151
 
170
 
152
    
171
    
-
 
172
SEXP sdf_finalize_workspace() {
-
 
173
    SEXP ret;
-
 
174
    PROTECT(ret = NEW_LOGICAL(1)); 
-
 
175
    LOGICAL(ret)[0] = (sqlite3_close(g_workspace) == SQLITE_OK);
-
 
176
    UNPROTECT(1);
-
 
177
    return ret;
-
 
178
} 
-
 
179
 
-
 
180
 
-
 
181
SEXP sdf_list_sdfs(SEXP pattern) {
-
 
182
    SEXP ret;
-
 
183
    char **result;
-
 
184
    int nrow, ncol, res, i;
-
 
185
 
-
 
186
    if (TYPEOF(pattern) != STRSXP) {
-
 
187
        res = sqlite3_get_table(g_workspace, "select internal_name from workspace",
-
 
188
                &result, &nrow, &ncol, NULL);
-
 
189
    } else {
-
 
190
        /* since internal_names must be a valid r symbol, 
-
 
191
           did not check for "'" */
-
 
192
        sprintf(g_sql_buf[0], "select internal_name from workspace where "
-
 
193
                "internal_name like '%s\%'", CHAR(STRING_ELT(pattern, 0)));
-
 
194
        res = sqlite3_get_table(g_workspace, g_sql_buf[0], &result, &nrow,
-
 
195
                &ncol, NULL);
-
 
196
    }
-
 
197
 
-
 
198
    if (_sqlite_error(res)) return R_NilValue;
-
 
199
    PROTECT(ret = NEW_CHARACTER(nrow));
-
 
200
    
-
 
201
    for (i = 0; i < nrow; i++) SET_STRING_ELT(ret, i, mkChar(result[i+1]));
153
 
202
 
-
 
203
    sqlite3_free_table(result);
-
 
204
    UNPROTECT(1);
-
 
205
    return ret;
-
 
206
}
154
 
207
 
-
 
208
SEXP sdf_get_sdf(SEXP name) {    
-
 
209
    if (TYPEOF(name) != STRSXP) {
-
 
210
        Rprintf("Error: Argument must be a string containing the SDF name.\n");
-
 
211
        return R_NilValue;
-
 
212
    }
-
 
213
 
-
 
214
    char *iname = CHAR(STRING_ELT(name, 0));
-
 
215
    SEXP ret;
-
 
216
    sqlite3_stmt *stmt;
-
 
217
    int res;
-
 
218
 
-
 
219
    res = sqlite3_prepare(g_workspace, "select * from workspace where internal_name=?",
-
 
220
            45, &stmt, NULL);
-
 
221
    if (_sqlite_error(res)) return R_NilValue;
-
 
222
 
-
 
223
    sqlite3_bind_text(stmt, 1, iname, strlen(iname), SQLITE_STATIC);
-
 
224
    res = sqlite3_step(stmt);
-
 
225
 
-
 
226
    if (res == SQLITE_ROW) ret = _create_sdf_sexp(iname);
-
 
227
    else ret = R_NilValue;
-
 
228
    
-
 
229
    sqlite3_finalize(stmt);
-
 
230
 
-
 
231
    return ret;
-
 
232
}