The R Project SVN R-packages

Rev

Rev 3419 | Rev 3684 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3397 mrmanese 1
#include <stdio.h>
2
#include <string.h>
3
#include "sqlite_dataframe.h"
4
 
5
 
6
SEXP sdf_import_sqlite_table(SEXP _dbfilename, SEXP _tblname, SEXP _sdfiname) {
7
    sqlite3 *db;
8
    sqlite3_stmt *stmt;
9
    int res, nrows, ncols, buflen0, buflen1, buflen3, i;
10
    int tblname_len, colname_len, iname_len;
11
    char *dbfilename, *tblname, *iname, *type;
12
    const char *colname;
13
    SEXP ret = NULL;
14
 
15
    dbfilename = CHAR_ELT(_dbfilename, 0);
16
    tblname = CHAR_ELT(_tblname, 0);
17
    /* determine if we were passed a real sqlite db */
18
    db = _is_sqlitedb(dbfilename);
19
 
20
    if (!db) {
21
        Rprintf("Error: %s is not a SQLite database.\n", dbfilename);
22
        return R_NilValue;
23
    }
24
 
25
    /* check if the table exists in the db */
26
    sprintf(g_sql_buf[0], "select count(*) from [%s]", tblname);
27
    res = sqlite3_prepare(db, g_sql_buf[0], -1, &stmt, 0);
28
    if (_sqlite_error(res)) { 
29
        sqlite3_finalize(stmt); sqlite3_close(db);
30
        return R_NilValue; 
31
    }
32
    sqlite3_step(stmt);
33
    nrows = sqlite3_column_int(stmt, 0);
34
    sqlite3_finalize(stmt); sqlite3_close(db);
35
    if (nrows == 0) {
36
        Rprintf("Error: Table contains no rows. Aborting import operation.\n");
37
        return R_NilValue;
38
    }
39
 
40
    /* we have to attach it so we can transfer easily */
41
 
42
    /* unload sdf's if we run to the MAX_ATTACHED limit */
43
    _prepare_attach2();
44
 
45
    /* attach the table to be imported */
46
    sprintf(g_sql_buf[0], "attach '%s' as [@@import@@]", dbfilename);
47
    res = _sqlite_exec(g_sql_buf[0]);
48
    if (_sqlite_error(res)) return R_NilValue;
49
 
50
 
51
    /* create the sdf where the data will be imported to */
3419 mrmanese 52
    iname = _create_sdf_skeleton1(_sdfiname, NULL, FALSE);
3397 mrmanese 53
    if (iname == NULL) goto sdf_import_sqlite_table__out;
54
 
55
    iname_len = strlen(iname);  /* needed for buf resizing below */
56
    tblname_len = strlen(tblname);
57
 
58
    /* get column types and names */
59
    sprintf(g_sql_buf[0], "select * from [@@import@@].[%s]", tblname);
60
    res = sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
61
    _sqlite_error(res);
62
    sqlite3_step(stmt);
63
    ncols = sqlite3_column_count(stmt);
64
 
65
    /* create the sql scripts to execute: the create table and the insert-select */
66
    buflen0 = sprintf(g_sql_buf[0], "create table [%s].sdf_data([row name] text", iname);
67
    buflen1 = sprintf(g_sql_buf[1], "select cumsum(1)");
68
    buflen3 = sprintf(g_sql_buf[3], "from [@@import@@].[%s] ", tblname);
69
    for (i = 0; i < ncols; i++) {
70
        type = _str_tolower(g_sql_buf[2], sqlite3_column_decltype(stmt, i));
71
        colname = sqlite3_column_name(stmt, i);
72
        colname_len = strlen(colname);
73
        if (strstr(type, "int")) {
74
            _expand_buf(0, buflen0 + strlen(colname) + 10);
75
            buflen0 += sprintf(g_sql_buf[0]+buflen0, ",[%s] int", colname);
76
 
77
            _expand_buf(1, buflen1 + colname_len + 10);
78
            buflen1 += sprintf(g_sql_buf[1]+buflen1, ",[%s]", colname);
3473 mrmanese 79
        } else if (strstr(type, "char") || strcmp(type, "text") == 0) {
3397 mrmanese 80
            _expand_buf(0, buflen0 + strlen(colname) + 10);
81
            buflen0 += sprintf(g_sql_buf[0]+buflen0, ",[%s] int", colname);
82
 
83
            _expand_buf(1, buflen1 + colname_len + iname_len + 20);
84
            buflen1 += sprintf(g_sql_buf[1]+buflen1, ",[%s].[factor %s].level",
85
                   iname, colname);
86
 
87
            /* create factor table */
88
            _create_factor_table2(iname, "factor", colname);
89
 
90
            /* insert factor levels and labels */
3473 mrmanese 91
            sprintf(g_sql_buf[2], "insert into [%s].[factor %s] (label)"
92
                   " select distinct [%s] from [@@import@@].[%s]", 
3397 mrmanese 93
                   iname, colname, colname, tblname);
94
            res = _sqlite_exec(g_sql_buf[2]);
95
            _sqlite_error(res);
96
 
3473 mrmanese 97
            _init_sqlite_function_accumulator();
98
            sprintf(g_sql_buf[2], "update [%s].[factor %s] set level=cumsum(1)",
99
                   iname, colname);
100
            res = _sqlite_exec(g_sql_buf[2]);
101
            _sqlite_error(res);
102
 
3397 mrmanese 103
            /* add join clause to from clause */
104
            _expand_buf(3, buflen3 + colname_len * 3 + iname_len * 2 + strlen(tblname) + 32);
105
            buflen3 += sprintf(g_sql_buf[3] + buflen3, " join [%s].[factor %s] "
106
                    "on [@@import@@].[%s].[%s] = [%s].[factor %s].label",
107
                    iname, colname, tblname, colname, iname, colname);
3473 mrmanese 108
        } else if (strcmp(type, "blob") == 0 || !*type) {
3397 mrmanese 109
            /* not supported */
3473 mrmanese 110
            warning("skipping column %s because it is a blob.\n", colname);
3397 mrmanese 111
        } else { /* numeric / float / real / ... */
112
            _expand_buf(0, buflen0 + strlen(colname) + 10);
113
            buflen0 += sprintf(g_sql_buf[0]+buflen0, ",[%s] double", colname);
114
 
115
            _expand_buf(1, buflen1 + colname_len + 10);
116
            buflen1 += sprintf(g_sql_buf[1]+buflen1, ",[%s]", colname);
117
        }
118
    }
119
 
120
    sqlite3_finalize(stmt);
121
 
122
    /* execute create script */
123
    _expand_buf(0, buflen0 + 10);
124
    sprintf(g_sql_buf[0] + buflen0, ")");
125
    res = _sqlite_exec(g_sql_buf[0]);
126
    if (_sqlite_error(res)) {
127
        sdf_detach_sdf(mkString(iname));
128
        goto sdf_import_sqlite_table__out;
129
    }
130
 
3473 mrmanese 131
    /* execute insert-select script */
132
    _init_sqlite_function_accumulator();
3397 mrmanese 133
    _expand_buf(0, buflen1 + buflen3 + iname_len + 32 );
134
    sprintf(g_sql_buf[0], "insert into [%s].sdf_data %s %s", iname, g_sql_buf[1], g_sql_buf[3]);
135
    res = _sqlite_exec(g_sql_buf[0]);
136
    if (_sqlite_error(res)) {
137
        sdf_detach_sdf(mkString(iname));
138
        goto sdf_import_sqlite_table__out;
139
    }
140
 
141
    /* create sexp sdf */
142
    ret = _create_sdf_sexp(iname);
143
 
144
sdf_import_sqlite_table__out:
145
    _sqlite_exec("detach [@@import@@]");
146
    return ret;
147
}