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
#include "sqlite_dataframe.h"
3
#include "sqlite_dataframe.h"
8
 
4
 
-
 
5
/****************************************************************************
-
 
6
 * UTILITY FUNCTIONS
-
 
7
 ****************************************************************************/
-
 
8
 
9
SEXP sdf_create_sdf(SEXP df, SEXP name, SEXP sql_create) {
9
/* if user supplied a name, return that name. otherwise, use the 
10
    SEXP ret;
10
 * default "data" */
11
    char *rname, *iname, *biname; 
11
int _check_sdf_name(SEXP name, char **rname, char **iname, int *file_idx) {
12
    int file_idx = 0, namelen, res;
12
    int namelen = 0;
13
 
13
 
14
    /* check if arg name is supplied */
14
    /* check if arg name is supplied */
15
    if (IS_CHARACTER(name)) {
15
    if (IS_CHARACTER(name)) {
16
        rname = CHAR(STRING_ELT(name,0));
16
        *rname = CHAR_ELT(name,0);
17
        if (!_is_r_sym(rname)) { /* error */ return R_NilValue; }
17
        if (!_is_r_sym(*rname)) { 
-
 
18
            Rprintf("Error: supplied name \"%s\"is not a valid R symbol.\n", 
-
 
19
                    *rname); 
-
 
20
            return FALSE; 
-
 
21
        }
18
        namelen = strlen(rname);
22
        namelen = strlen(*rname);
19
        iname = R_alloc(namelen + 9, sizeof(char)); /* <name>10000.db\0 */
23
        *iname = (char*)R_alloc(namelen + 9, sizeof(char)); /* <name>10000.db\0 */
20
        sprintf(iname, "%s.db", rname);
24
        sprintf(*iname, "%s.db", *rname);
21
    } else if (name == R_NilValue) {
25
    } else if (name == R_NilValue) {
22
        rname = "data";
26
        *rname = "data";
23
        namelen = 5;
27
        namelen = 5;
24
        iname = R_alloc(13, sizeof(char)); /* data10000.db\0 */
28
        *iname = (char*)R_alloc(13, sizeof(char)); /* data10000.db\0 */
25
        file_idx = 1;
29
        *file_idx = 1;
26
        sprintf(iname, "%s%d.db", rname, file_idx);
30
        sprintf(*iname, "%s%d.db", *rname, *file_idx);
27
    } else {
31
    } else {
28
        /* how to error??? */
32
        Rprintf("Error: the supplied value for arg name is not a string.\n");
29
        return R_NilValue;
-
 
30
    }
33
    }
-
 
34
    return namelen;
-
 
35
}
31
 
36
 
32
    /* here, iname will contain #{iname}.db */
37
int _find_free_filename(char *rname, char **iname, int *namelen, int *file_idx) {
33
    do {
38
    do {
34
        if (!_file_exists(iname)) break;
39
        if (!_file_exists(*iname)) break;
35
        namelen = sprintf(iname, "%s%d.db", rname, ++file_idx) - 3;
40
        *namelen = sprintf(*iname, "%s%d.db", rname, ++(*file_idx)) - 3;
36
    } while (file_idx < 10000);
41
    } while (*file_idx < 10000);
-
 
42
 
-
 
43
    return *file_idx;
-
 
44
}
-
 
45
 
-
 
46
/* creates an sdf attribute table */
-
 
47
static int _create_sdf_attribute2(const char *iname) {
-
 
48
    sprintf(g_sql_buf[2], "create table [%s].sdf_attributes(attr text, "
-
 
49
            "value text, primary key (attr))", iname);
-
 
50
    int res = _sqlite_exec(g_sql_buf[2]);
-
 
51
    if (res == SQLITE_OK) {
-
 
52
        sprintf(g_sql_buf[2], "insert into [%s].sdf_attributes values ('name',"
-
 
53
                "'%s');", iname, iname);
-
 
54
        res = _sqlite_exec(g_sql_buf[2]);
-
 
55
    }
-
 
56
    return res;
-
 
57
}
-
 
58
 
-
 
59
/* checks if a column has a corresponding factor|ordered table */
-
 
60
static int _is_factor2(const char *iname, const char *factor_type, const char *colname) {
-
 
61
    sqlite3_stmt stmt;
-
 
62
    sprintf(g_sql_buf[2], "select * from [%s].[%s %s]", iname, factor_type,
-
 
63
            colname);
-
 
64
    int res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
-
 
65
    return res == SQLITE_OK;
-
 
66
}
-
 
67
 
-
 
68
/* create a factor|ordered table */
-
 
69
static int _create_factor_table2(const char *iname, const char *factor_type, 
-
 
70
        const char *colname) {
-
 
71
    sqlite3_stmt *stmt;
-
 
72
    sprintf(g_sql_buf[2], "create table [%s].[%s %s] (level int, label text, "
-
 
73
            "primary key(level), unique(label));", iname, factor_type, colname);
-
 
74
    int res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
-
 
75
    sqlite3_finalize(stmt);
-
 
76
    return res; /* error on dup name? */
-
 
77
}
-
 
78
 
-
 
79
/* copy a factor|ordered table from a sdf(db) to another sdf(db) */
-
 
80
static int _copy_factor_levels2(const char *factor_type, const char *iname_src,
-
 
81
        const char *colname_src, const char *iname_dst, const char *colname_dst) {
-
 
82
    sqlite3_stmt *stmt;
-
 
83
    int res;
-
 
84
    res = _create_factor_table2(iname_dst, factor_type, colname_dst);
-
 
85
    if (res == SQLITE_OK) {
-
 
86
        sprintf(g_sql_buf[2], "insert into [%s].[%s %s] select * from [%s].[%s,%s]",
-
 
87
                iname_src, factor_type, colname_src, iname_dst, factor_type,
-
 
88
                colname_dst);
-
 
89
        res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
-
 
90
        sqlite3_finalize(stmt);
-
 
91
    return res; /* error on dup name? */
-
 
92
}
-
 
93
 
-
 
94
 
-
 
95
/* assumes stmt has col_cnt + 1 columns, col 0 is [row name]. returned SEXP is 
-
 
96
 * not UNPROTECT-ed, user will have to do that. will create the names &
-
 
97
 * attach factor infos */
-
 
98
static SEXP _setup_df_sexp1(const char *iname_src, const char *iname_dst,
-
 
99
        sqlite3_stmt *stmt, int col_cnt, int *dup_indices) {
-
 
100
    SEXP ret, tmp, value;
-
 
101
    int i, nprotect;
-
 
102
    const char *colname;
-
 
103
 
-
 
104
    PROTECT(ret = NEW_LIST(col_cnt));
-
 
105
 
-
 
106
    /* set up names */
-
 
107
    PROTECT(tmp = NEW_CHARACTER(col_cnt)); nprotect = 1;
-
 
108
    for (i = 0; i < col_cnt; i++) {
-
 
109
        colname = sqlite3_column_name(stmt, i+1);
-
 
110
        if (dup_indices[i] == 0) {
-
 
111
            strcpy(g_sql_buf[1], colname);
-
 
112
        } else {
-
 
113
            sprintf(g_sql_buf[1], "%s.%d", colname, dup_indices[i]);
-
 
114
        }
-
 
115
 
-
 
116
        SET_STRING_ELT(tmp, i, mkChar(g_sql_buf[1]));
-
 
117
                    
-
 
118
    }
-
 
119
    SET_NAMES(ret, tmp);
-
 
120
    UNPROTECT(nprotect);
-
 
121
    return ret;
-
 
122
}
-
 
123
 
-
 
124
/****************************************************************************
-
 
125
 * SDF FUNCTIONS
-
 
126
 ****************************************************************************/
-
 
127
 
-
 
128
SEXP sdf_create_sdf(SEXP df, SEXP name) {
-
 
129
    SEXP ret;
-
 
130
    char *rname, *iname, *biname; 
-
 
131
    int file_idx = 0, namelen, res, i, j;
-
 
132
 
-
 
133
    namelen = _check_sdf_name(name, &rname, &iname, &file_idx);
-
 
134
    if (!namelen) return R_NilValue;
-
 
135
 
-
 
136
 
-
 
137
    /* at this point, iname will contain #{iname}.db */
-
 
138
    _find_free_filename(rname, &iname, &namelen, &file_idx);
37
    
139
    
38
    /* found a free number */
140
    /* found a free number */
39
    if (file_idx < 10000) {
141
    if (file_idx < 10000) {
40
        /* create a sdf db file by running "attach" statement to non-existent
142
        /* create a sdf db file by running "attach" statement to non-existent
41
         * db file
143
         * db file
42
         */
144
         */
43
        int sql_len, sql_len2, sql_len3, i, j;
145
        int sql_len, sql_len2;
44
        sqlite3_stmt *stmt;
146
        sqlite3_stmt *stmt;
45
 
147
 
46
        iname[namelen] = 0;  /* remove ".db" */
148
        iname[namelen] = 0;  /* remove ".db" */
47
        sql_len = sprintf(g_sql_buf[0], "attach '%s.db' as %s", iname, iname);
149
        sql_len = sprintf(g_sql_buf[0], "attach '%s.db' as %s", iname, iname);
48
 
150
 
Line 51... Line 153...
51
            
153
            
52
 
154
 
53
        /* 
155
        /* 
54
         * create tables for the sdf db
156
         * create tables for the sdf db
55
         */
157
         */
-
 
158
 
-
 
159
        /* create sdf_attributes table */
-
 
160
        res = _create_sdf_attribute2(iname);
-
 
161
        if (_sqlite_error(res)) return R_NilValue;
-
 
162
 
-
 
163
        /* create sdf_data table */
56
        SEXP names = GET_NAMES(df), variable, levels;
164
        SEXP names = GET_NAMES(df), variable, levels;
57
        int ncols = GET_LENGTH(names), type, *types;
165
        int ncols = GET_LENGTH(names), type, *types;
58
        char *col_name, *class, *factor;
166
        char *col_name, *class, *factor;
59
 
167
 
60
        /* TODO: put constraints on table after inserting everything? */
168
        /* TODO: put constraints on table after inserting everything? */
61
 
169
 
62
        /* create sdf_attributes table */
-
 
63
        sprintf(g_sql_buf[0], "create table [%s].sdf_attributes(attr text, "
-
 
64
                "value text, primary key (attr))", iname);
-
 
65
        res = _sqlite_exec(g_sql_buf[0]);
-
 
66
        sprintf(g_sql_buf[0], "insert into [%s].sdf_attributes values ('name',"
-
 
67
                "'%s');", iname, iname);
-
 
68
        _sqlite_exec(g_sql_buf[0]);
-
 
69
 
-
 
70
 
170
 
71
        /* 
171
        /* 
72
         * create the create table and insert sql scripts by looping through
172
         * create the create table and insert sql scripts by looping through
73
         * the columns of df
173
         * the columns of df
74
         */
174
         */
Line 95... Line 195...
95
            strcpy(g_sql_buf[1]+sql_len2, ",?");
195
            strcpy(g_sql_buf[1]+sql_len2, ",?");
96
            sql_len2 += 2; 
196
            sql_len2 += 2; 
97
 
197
 
98
            /* create separate table for factors decode */
198
            /* create separate table for factors decode */
99
            if (strcmp(class, "factor") == 0 || strcmp(class, "ordered") == 0){
199
            if (strcmp(class, "factor") == 0 || strcmp(class, "ordered") == 0){
100
                sprintf(g_sql_buf[2], "create table [%s].[factor %s] ("
-
 
101
                        "level int, label text, primary key(level), "
-
 
102
                        "unique(label));", iname, col_name);
200
                if (_create_factor_table2(iname, class, col_name)) 
103
                res = _sqlite_exec(g_sql_buf[2]);
-
 
104
                if (_sqlite_error(res)) return R_NilValue; /* dup tbl name? */
201
                    return R_NilValue; /* dup tbl name? */
105
 
202
 
106
                levels = GET_LEVELS(variable);
203
                levels = GET_LEVELS(variable);
107
                sql_len3 = sprintf(g_sql_buf[2], "insert into [%s].[factor %s] values(?, ?);", iname, col_name);
204
                sprintf(g_sql_buf[2], "insert into [%s].[%s %s] values(?, ?);",
-
 
205
                        iname, class, col_name);
108
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], sql_len3, &stmt, NULL);
206
                res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, NULL);
109
                if (_sqlite_error(res)) return R_NilValue; /* dup tbl name? */
207
                if (_sqlite_error(res)) return R_NilValue; /* dup tbl name? */
110
 
208
 
111
                for (j = 0; j < GET_LENGTH(levels); j++) {
209
                for (j = 0; j < GET_LENGTH(levels); j++) {
112
                    sqlite3_reset(stmt);
210
                    sqlite3_reset(stmt);
113
                    factor = CHAR(STRING_ELT(levels, j));
211
                    factor = CHAR(STRING_ELT(levels, j));
Line 130... Line 228...
130
         */
228
         */
131
        SEXP rownames = getAttrib(df, R_RowNamesSymbol);
229
        SEXP rownames = getAttrib(df, R_RowNamesSymbol);
132
        int nrows = GET_LENGTH(rownames);
230
        int nrows = GET_LENGTH(rownames);
133
        char *row_name;
231
        char *row_name;
134
 
232
 
135
        sql_len2 += sprintf(g_sql_buf[1]+sql_len2, ")");
233
        sprintf(g_sql_buf[1]+sql_len2, ")");
136
        res = sqlite3_prepare(g_workspace, g_sql_buf[1], sql_len2, &stmt, NULL);
234
        res = sqlite3_prepare(g_workspace, g_sql_buf[1], -1, &stmt, NULL);
137
 
235
 
138
        for (i = 0; i < nrows; i++) {
236
        for (i = 0; i < nrows; i++) {
139
            row_name = CHAR(STRING_ELT(rownames, i));
237
            row_name = CHAR(STRING_ELT(rownames, i));
140
            sqlite3_reset(stmt);
238
            sqlite3_reset(stmt);
141
 
239
 
Line 171... Line 269...
171
        sqlite3_finalize(stmt);
269
        sqlite3_finalize(stmt);
172
 
270
 
173
        /*
271
        /*
174
         * add the new sdf to the workspace
272
         * add the new sdf to the workspace
175
         */
273
         */
176
        sprintf(g_sql_buf[0], "insert into workspace(filename, internal_name)"
274
        strcpy(g_sql_buf[0], iname);
177
                " values('%s.db','%s')", iname, iname);
275
        iname[namelen] = '.';
178
        res = _sqlite_exec(g_sql_buf[0]);
276
        res = _add_sdf1(iname, g_sql_buf[0]);
179
        if (_sqlite_error(res)) return R_NilValue; /* why? */
277
        if (_sqlite_error(res)) return R_NilValue; /* why? */
180
 
278
 
181
        /*
279
        /*
182
         * create a new object representing the sdf
280
         * create a new object representing the sdf
183
         */
281
         */
Line 190... Line 288...
190
        
288
        
191
    return ret;
289
    return ret;
192
}
290
}
193
 
291
 
194
SEXP sdf_get_names(SEXP sdf) {
292
SEXP sdf_get_names(SEXP sdf) {
195
    char *iname = CHAR(STRING_ELT(_getListElement(sdf, "iname"),0));
293
    char *iname = SDF_INAME(sdf);
196
    int len = sprintf(g_sql_buf[0], "select * from [%s].sdf_data;", iname);
294
    int len = sprintf(g_sql_buf[0], "select * from [%s].sdf_data;", iname);
197
 
295
 
198
    sqlite3_stmt *stmt;
296
    sqlite3_stmt *stmt;
199
    int res;
297
    int res;
200
   
298
   
Line 234... Line 332...
234
    sqlite3_finalize(stmt);
332
    sqlite3_finalize(stmt);
235
    UNPROTECT(1);
333
    UNPROTECT(1);
236
    return ret;
334
    return ret;
237
}
335
}
238
 
336
 
-
 
337
/* get row count */
239
SEXP sdf_get_rows(SEXP sdf) {
338
SEXP sdf_get_row_count(SEXP sdf) {
240
    char *iname = CHAR(STRING_ELT(_getListElement(sdf, "iname"),0));
339
    char *iname = CHAR(STRING_ELT(_getListElement(sdf, "iname"),0));
241
    char **out;
340
    char **out;
242
    int res, ncol, nrow;
341
    int res, ncol, nrow;
243
    SEXP ret;
342
    SEXP ret;
244
   
343
   
Line 257... Line 356...
257
    sqlite3_free_table(out);
356
    sqlite3_free_table(out);
258
    return ret;
357
    return ret;
259
}
358
}
260
 
359
 
261
    
360
    
-
 
361
SEXP sdf_import_table(SEXP _filename, SEXP _name, SEXP _sep, SEXP _quote, 
-
 
362
        SEXP _rownames, SEXP _colnames) {
-
 
363
    char *filename = CHAR_ELT(_filename, 0);
-
 
364
    FILE *f = fopen(filename, "r");
-
 
365
 
-
 
366
    if (f == NULL) {
-
 
367
        Rprintf("Error: File %s does not exist.", filename);
-
 
368
        return R_NilValue;
-
 
369
    }
-
 
370
 
-
 
371
    char *sep = CHAR_ELT(_sep, 0), *quote = CHAR_ELT(_quote,0);
-
 
372
    char *name = CHAR_ELT(_name, 0);
-
 
373
 
-
 
374
    /* create the table */
-
 
375
    /* insert the stuffs */
-
 
376
    /* register to workspace */
-
 
377
 
-
 
378
    return R_NilValue;
-
 
379
}
-
 
380
 
-
 
381
SEXP sdf_get_rownames(SEXP sdf) {
-
 
382
    return R_NilValue;
-
 
383
}
-
 
384
 
262
 
385
 
-
 
386
SEXP sdf_get_index(SEXP sdf, SEXP row, SEXP col) {
-
 
387
    SEXP ret, *df;
-
 
388
    char *iname = SDF_INAME(sdf);
-
 
389
    sqlite3_stmt *stmt, *stmt2;
-
 
390
    int buflen = 0, idxlen, col_cnt, index;
-
 
391
    int i, j,res;
-
 
392
    int *col_indices, col_index_len, *dup_indices;
263
 
393
 
-
 
394
    sprintf(g_sql_buf[0], "select * from [%s].sdf_data", iname);
-
 
395
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
-
 
396
    if (_sqlite_error(res)) return R_NilValue;
-
 
397
 
-
 
398
    buflen = sprintf(g_sql_buf[0], "select [row name]");
-
 
399
    idxlen = LENGTH(col);
-
 
400
    col_cnt = sqlite3_column_count(stmt) - 1;
-
 
401
 
-
 
402
    /*
-
 
403
     * PROCESS COLUMN INDEX
-
 
404
     */
-
 
405
    if (MISSING(col)) {
-
 
406
        for (i = 1; i < col_cnt+1; i++) {
-
 
407
            buflen += sprintf(g_sql_buf[0]+buflen, "[%s],", 
-
 
408
                    sqlite3_column_name(stmt, i)); 
-
 
409
        }
-
 
410
        g_sql_buf[0][--buflen] = 0; /* remove trailing "," */
-
 
411
    } else if (col == R_NilValue || idxlen < 1) {
-
 
412
        sqlite3_finalize(stmt);
-
 
413
        return R_NilValue;
-
 
414
    } else if (IS_NUMERIC(col)) {
-
 
415
        col_indices = (int *)R_alloc(idxlen, sizeof(int));
-
 
416
        dup_indices = (int *)R_alloc(idxlen, sizeof(int));
-
 
417
        col_index_len = 0;
-
 
418
 
-
 
419
        for (i = 0; i < idxlen; i++) {
-
 
420
            /* no need to correct for 0 base because col 0 is [row name] */
-
 
421
            index = ((int) REAL(col)[i]); 
-
 
422
            if (index > col_cnt) {
-
 
423
                sqlite3_finalize(stmt);
-
 
424
                Rprintf("Error: undefined columns selected\n");
-
 
425
                return R_NilValue;
-
 
426
            } else if (index > 0) {
-
 
427
                buflen += sprintf(g_sql_buf[0]+buflen, "[%s],", 
-
 
428
                        sqlite3_column_name(stmt,index));
-
 
429
                dup_indices[col_index_len] = 0;
-
 
430
                for (j = 0; j < col_index_len; j++) {
-
 
431
                    if (col_indices[j] == index) dup_indices[col_index_len]++;
-
 
432
                }
-
 
433
                col_indices[col_index_len++] = index;
-
 
434
            } else if (index < 0) {
-
 
435
                sqlite3_finalize(stmt);
-
 
436
                Rprintf("Error: negative indices not supported.\n");
-
 
437
                return R_NilValue;
-
 
438
            }
-
 
439
        }
-
 
440
 
-
 
441
        if (col_index_len == 0) {
-
 
442
            sqlite3_finalize(stmt);
-
 
443
            Rprintf("Error: no indices detected??\n");
-
 
444
            return R_NilValue;
-
 
445
        } else {
-
 
446
            /* remove trailing "," and add the from clause */
-
 
447
            sprintf(g_sql_buf[0] + (--buflen), " from [%s].sdf_data", iname);
-
 
448
        }
-
 
449
    } else if (IS_INTEGER(col)) {
-
 
450
        /* identical logic with IS_NUMERIC, except that we don't have to cast
-
 
451
         * stuffs from SEXP col. the alternative is doing if idxlen times. */
-
 
452
        col_indices = (int *)R_alloc(idxlen, sizeof(int));
-
 
453
        dup_indices = (int *)R_alloc(idxlen, sizeof(int));
-
 
454
        col_index_len = 0;
-
 
455
 
-
 
456
        for (i = 0; i < idxlen; i++) {
-
 
457
            /* no need to correct for 0 base because col 0 is [row name] */
-
 
458
            index = INTEGER(col)[i];
-
 
459
            if (index > col_cnt) {
-
 
460
                sqlite3_finalize(stmt);
-
 
461
                Rprintf("Error: undefined columns selected\n");
-
 
462
                return R_NilValue;
-
 
463
            } else if (index > 0) {
-
 
464
                buflen += sprintf(g_sql_buf[0]+buflen, "[%s],", 
-
 
465
                        sqlite3_column_name(stmt,index));
-
 
466
                dup_indices[col_index_len] = 0;
-
 
467
                for (j = 0; j < col_index_len; j++) {
-
 
468
                    if (col_indices[j] == index) dup_indices[col_index_len]++;
-
 
469
                }
-
 
470
                col_indices[col_index_len++] = index;
-
 
471
            } else if (index < 0) {
-
 
472
                sqlite3_finalize(stmt);
-
 
473
                Rprintf("Error: negative indices not supported.\n");
-
 
474
                return R_NilValue;
-
 
475
            }
-
 
476
        }
-
 
477
 
-
 
478
        if (col_index_len == 0) {
-
 
479
            sqlite3_finalize(stmt);
-
 
480
            Rprintf("Error: no indices detected??\n");
-
 
481
            return R_NilValue;
-
 
482
        } else {
-
 
483
            /* remove trailing "," and add the from clause */
-
 
484
            sprintf(g_sql_buf[0] + (--buflen), " from [%s].sdf_data", iname);
-
 
485
        }
-
 
486
    } else if (IS_LOGICAL(col)) {
-
 
487
        /* recycling stuff, so max column output is the # of cols in the df */
-
 
488
        col_indices = (int *)R_alloc(col_cnt, sizeof(int));
-
 
489
        dup_indices = (int *)R_alloc(col_cnt, sizeof(int));
-
 
490
        col_index_len = 0;
-
 
491
        for (i = 0; i < col_cnt; i++) {
-
 
492
            if (LOGICAL(col)[i%idxlen]) {
-
 
493
                buflen += sprintf(g_sql_buf[0]+buflen, "[%s],", 
-
 
494
                        sqlite3_column_name(stmt,i+1));
-
 
495
                dup_indices[col_index_len] = 0;
-
 
496
                col_indices[col_index_len++] = i;
-
 
497
            }
-
 
498
        }
-
 
499
 
-
 
500
        if (col_index_len == 0) {
-
 
501
            sqlite3_finalize(stmt);
-
 
502
            Rprintf("Warning: no column selected.\n");
-
 
503
            return R_NilValue;
-
 
504
        }
-
 
505
    } else {
-
 
506
        sqlite3_finalize(stmt);
-
 
507
        Rprintf("Error: don't know how to handle column index.\n");
-
 
508
        return R_NilValue;
-
 
509
    }
-
 
510
 
-
 
511
    /* 
-
 
512
     * PROCESS ROW INDEX
-
 
513
     */
-
 
514
    idxlen = LENGTH(row);
-
 
515
    if (MISSING(row)) {
-
 
516
        if (col_index_len > 0) {
-
 
517
            /* create a new SDF, logic similar to sdf_create_sdf */
-
 
518
 
-
 
519
            /* find a new name. data<n> ? */
-
 
520
            char *iname2, *rname2;
-
 
521
            int namelen, file_idx, sql_len, sql_len2, dup_idx;
-
 
522
            namelen = _check_sdf_name(R_NilValue, &rname2, &iname2, &file_idx);
-
 
523
 
-
 
524
            if (!namelen) { sqlite3_finalize(stmt); return R_NilValue; }
-
 
525
 
-
 
526
            _find_free_filename(rname2, &iname2, &namelen, &file_idx);
-
 
527
 
-
 
528
            if (file_idx >= 10000) { 
-
 
529
                Rprintf("Error: cannot find free SDF name.\n");
-
 
530
                sqlite3_finalize(stmt);
-
 
531
                return R_NilValue;
-
 
532
            }
-
 
533
 
-
 
534
            /* create new db by attaching a non-existent file */
-
 
535
            iname[namelen] = 0; /* remove ".db" */
-
 
536
            sprintf(g_sql_buf[1], "attach '%s.db' as %s", iname, iname);
-
 
537
            res = _sqlite_exec(g_sql_buf[1]);
-
 
538
            if (_sqlite_error(res)) return R_NilValue;
-
 
539
 
-
 
540
            /* create attributes table */
-
 
541
            res = _create_sdf_attribute2(iname);
-
 
542
            if (_sqlite_error(res)) { 
-
 
543
                sqlite3_finalize(stmt); return R_NilValue; 
-
 
544
            }
-
 
545
 
-
 
546
            /* create sdf_data table */
-
 
547
            sql_len = sprintf(g_sql_buf[1], "create table [%s],sdf_data ([row name] text", iname);
-
 
548
 
-
 
549
            for (i = 0; i < col_index_len; i++) {
-
 
550
                colname = sqlite3_column_name(stmt, col_indices[i]);
-
 
551
                if (dup_indices[i] == 0) {
-
 
552
                    sql_len2 = sprintf(g_sql_buf[2], ", [%s] %s", colname,
-
 
553
                            sqlite3_column_decltype(stmt, col_indices[i]));
-
 
554
                } else {
-
 
555
                    /* un-duplicate col names by appending num, just like R */
-
 
556
                    sql_len2 = sprintf(g_sql_buf[2], ", [%s.%d] %s", colname,
-
 
557
                            dup_indices[i], 
-
 
558
                            sqlite3_column_decltype(stmt, col_indices[i]));
-
 
559
                }
-
 
560
 
-
 
561
                /* append to g_sql_buf[1], which holds the create 
-
 
562
                 * table script */
-
 
563
                sql_len += sql_len2;
-
 
564
                _expand_buf(1, sql_len);
-
 
565
                strcpy(g_sql_buf[1], g_sql_buf[2]);
-
 
566
 
-
 
567
                /* deal with possibly factor columns */
-
 
568
                if (_is_factor2(iname, "factor", colname)) {
-
 
569
                    /* found a factor column */
-
 
570
                    if (dup_indices[i] == 0)  {
-
 
571
                        _copy_factor_levels2("factor", iname, colname, iname2, colname);
-
 
572
                    } else {
-
 
573
                        sprintf(g_sql_buf[3], "%s.%d", colname, dup_indices[i]);
-
 
574
                        _copy_factor_levels2("factor", iname, colname, iname2, 
-
 
575
                                g_sql_buf[3]);
-
 
576
                    }
-
 
577
                }
-
 
578
 
-
 
579
                /* and deal with ordered factors too... life is hard, then you die */
-
 
580
                if (_is_factor2(iname, "ordered", colname)) {
-
 
581
                    if (dup_indices[i] == 0)  {
-
 
582
                        _copy_factor_levels2("ordered", iname, colname, iname2, 
-
 
583
                                colname);
-
 
584
                    } else {
-
 
585
                        sprintf(g_sql_buf[3], "%s.%d", colname, dup_indices[i]);
-
 
586
                        _copy_factor_levels2("ordered", iname, colname, iname2, 
-
 
587
                                g_sql_buf[3]);
-
 
588
                    }
-
 
589
                }
-
 
590
                                
-
 
591
            }
-
 
592
 
-
 
593
            /* don't need it anymore */
-
 
594
            sqlite3_finalize(stmt);
-
 
595
 
-
 
596
            /* no table index created, that's for v2 I hope*/
-
 
597
            sql_len += sprintf(g_sql_buf[1]+sql_len, ");");
-
 
598
            res = _sqlite_exec(g_sql_buf[1]);
-
 
599
            if (_sqlite_error(res)) return R_NilValue; 
-
 
600
 
-
 
601
            /* insert data (with row names). buf[0] contains a select */
-
 
602
            sprintf(g_sql_buf[1], "insert into [%s].sdf_data %s", iname2,
-
 
603
                    g_sql_buf[0]);
-
 
604
            res = _sqlite_exec(g_sql_buf[1]);
-
 
605
            if (_sqlite_error(res)) return R_NilValue;
-
 
606
 
-
 
607
            /* add new sdf to workspace */
-
 
608
            sprintf(g_sql_buf[0], "%s.db", iname2);
-
 
609
            res = _add_sdf1(iname, g_sql_buf[0]);
-
 
610
            if (_sqlite_error(res)) return R_NilValue;
-
 
611
 
-
 
612
            /* create SEXP for the SDF */
-
 
613
            ret = _create_sdf_sexp(iname2);
-
 
614
        } else { sqlite3_finalize(stmt); return R_NilValue; }
-
 
615
    } else if (row == R_NilValue || idxlen < 1) {
-
 
616
        sqlite3_finalize(stmt);
-
 
617
        return R_NilValue;
-
 
618
    } else if (IS_NUMERIC(row)) {
-
 
619
        sqlite3_finalize(stmt);
-
 
620
 
-
 
621
        /* append " limit ?,1" to the formed select statement */
-
 
622
        _expand_buf(0, buflen+10);
-
 
623
        buflen += sprintf(g_sql_buf[0], " limit ?,1");
-
 
624
 
-
 
625
        /* indexing will be base-1, because [row name] is at 0 */
-
 
626
        index = ((int) REAL(row)[0]);
-
 
627
        if (idxlen < 0 && idxlen == 1) return R_NilValue;
-
 
628
 
-
 
629
        res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
-
 
630
        if (_sqlite_error(res)) return R_NilValue;
-
 
631
 
-
 
632
        sqlite3_bind_int(stmt, 1, index);
-
 
633
        res = sqlite3_step(stmt);
-
 
634
 
-
 
635
        /* create data frame */
-
 
636
        ret = _setup_df_sexp2(stmt, col_index_len, idxlen, dup_indices);
-
 
637
 
-
 
638
        if (index > 0) {
-
 
639
 
-
 
640
        /* put data in it */
-
 
641
    } else if (IS_INTEGER(row)) {
-
 
642
        /* */
-
 
643
    } else if (IS_LOGICAL(row)) {
-
 
644
        /* */
-
 
645
    }
-
 
646
 
-
 
647
        
-
 
648
 
-
 
649
    return ret;
-
 
650
}
264
 
651
 
265
SEXP sopen(SEXP name) {
652
SEXP sopen(SEXP name) {
266
    char *filename;
653
    char *filename;
267
    
654
    
268
    if (IS_CHARACTER(name)) {
655
    if (IS_CHARACTER(name)) {