The R Project SVN R-packages

Rev

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

Rev Author Line No. Line
3419 mrmanese 1
#define __SQLITE_MATRIX__
2
#include "sqlite_dataframe.h"
3
 
4
/****************************************************************************
3808 mrmanese 5
 * UTILITY FUNCTIONS
6
 ****************************************************************************/
7
static SEXP _create_smat_sexp(const char *mat_iname, const char *type, 
8
        int nrows, int ncols, SEXP colnames) {
9
    SEXP ret, tmp;
10
    int i;
11
 
12
    /* return smat sexp */
13
    PROTECT(ret = NEW_LIST(3)); i = 1; /* 1 for names sexp above */
14
    SET_VECTOR_ELT(ret, 0, mkString(mat_iname));
15
    SET_VECTOR_ELT(ret, 1, mkString("sdf_data"));
16
    SET_VECTOR_ELT(ret, 2, mkString("V1"));
17
 
18
    /* set smat data name */
19
    PROTECT(tmp = NEW_CHARACTER(3)); i++;
20
    SET_STRING_ELT(tmp, 0, mkChar("iname"));
21
    SET_STRING_ELT(tmp, 1, mkChar("tblname"));
22
    SET_STRING_ELT(tmp, 2, mkChar("varname"));
23
    SET_NAMES(ret, tmp);
24
 
25
    /* set class */
26
    PROTECT(tmp = mkString("sqlite.matrix")); i++;
27
    SET_CLASS(ret, tmp);
28
 
29
    /* set smat dim */
30
    PROTECT(tmp = NEW_INTEGER(2)); i++;
31
    INTEGER(tmp)[0] = nrows;
32
    INTEGER(tmp)[1] = ncols;  /* mind [row names], w/c is not included in the count */
33
    setAttrib(ret, SDF_DimSymbol, tmp);
34
 
35
    /* set smat dimname */
36
    PROTECT(tmp = NEW_LIST(2)); i++;
37
    SET_VECTOR_ELT(tmp, 0, _create_svector_sexp(mat_iname, 
38
                "sdf_matrix_rownames", "name", "character"));
39
    SET_VECTOR_ELT(tmp, 1, colnames);
40
    setAttrib(ret, SDF_DimNamesSymbol, tmp);
41
 
42
    /* set sdf.vector.type */
43
    setAttrib(ret, SDF_VectorTypeSymbol, mkString(type));
44
 
45
    UNPROTECT(i);
46
 
47
    return ret;
48
}
49
 
50
/****************************************************************************
3419 mrmanese 51
 * SMAT FUNCTIONS
52
 ****************************************************************************/
53
SEXP sdf_as_matrix(SEXP sdf, SEXP name) {
54
    char *iname, *mat_iname, *type;
4160 mrmanese 55
    const char *dectype, *colname, *vectype = NULL;
3419 mrmanese 56
    sqlite3_stmt *stmt, *stmt2;
57
    int ncols, nrows, i;
4160 mrmanese 58
    SEXP ret, names;
3419 mrmanese 59
 
60
    iname = SDF_INAME(sdf);
61
 
62
    if (!USE_SDF1(iname, TRUE, TRUE)) return R_NilValue;
63
 
64
    /* check column types, and determine matrix mode */
65
    sprintf(g_sql_buf[0], "select * from [%s].sdf_data", iname);
66
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, 0);
67
    sqlite3_step(stmt);
68
 
69
    ncols = sqlite3_column_count(stmt);
70
    type = NULL;
71
    for (i = 1; i < ncols; i++) {
72
        dectype = sqlite3_column_decltype(stmt, i);
73
        colname = sqlite3_column_name(stmt, i);
74
        if (strcmp(dectype, "double") == 0) {
3808 mrmanese 75
            type = "double"; vectype = "numeric";
3419 mrmanese 76
        } else if (strcmp(dectype, "int") == 0) {
77
            if (_is_factor2(iname, "factor", colname) || _is_factor2(iname, "ordered", colname)) {
3808 mrmanese 78
                type = "text"; vectype = "character"; break;
79
            } 
3419 mrmanese 80
            type = "double";
81
        } else if (strcmp(dectype, "bit") == 0) {
3808 mrmanese 82
            if (type == NULL) { type = "bit"; vectype = "logical";  }
3419 mrmanese 83
        } else if (strcmp(dectype, "text") == 0) {
3808 mrmanese 84
            type = "text"; vectype = "character"; break;
3419 mrmanese 85
        }
86
    }
87
 
88
 
89
    /* create sdf with 1 column */
90
    mat_iname = _create_svector1(name, type, NULL, TRUE);
91
 
92
    /* create and set sdf_matrix_rownames & sdf_matrix_colnames */
93
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_rownames(name text)", mat_iname);
94
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
95
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames "
96
            "select [row name] from [%s].sdf_data", mat_iname, iname);
97
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
98
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_colnames(name text)", mat_iname);
99
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
100
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_colnames values (?)", mat_iname);
101
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt2, 0);
102
 
103
    /* store names in a SEXP */
104
    names = NEW_CHARACTER(ncols - 1);
105
 
106
    /* insert cast-ed values, and column names */
3509 mrmanese 107
    nrows = _get_row_count2(iname, TRUE);
108
    _sqlite_begin;
3419 mrmanese 109
    for (i = 1; i < ncols; i++) {
110
        colname = sqlite3_column_name(stmt, i);
111
 
112
        sqlite3_reset(stmt2);
113
        sqlite3_bind_text(stmt2, 1, colname, -1, SQLITE_STATIC);
114
        sqlite3_step(stmt2);
115
 
116
        SET_STRING_ELT(names, i-1, mkChar(colname));
117
 
118
        if ((_is_factor2(iname, "ordered", colname) && ((dectype = "ordered"))) || 
119
            ( _is_factor2(iname, "factor", colname) && ((dectype = "factor")))) {
120
            sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
121
                    "select [row name]|| %d, [%s].[%s %s].label from [%s].sdf_data "
122
                    "join [%s].[%s %s] on [%s].sdf_data.[%s]=[%s].[%s %s].level",
123
                    mat_iname, i, iname, dectype, colname, iname, iname, dectype, 
124
                    colname, iname, colname, iname, dectype, colname);
125
        } else {
126
            sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
127
                    "select [row name] || %d, cast([%s] as %s) from [%s].sdf_data", mat_iname, i,
128
                    colname, type, iname);
129
        }
130
        _sqlite_error(_sqlite_exec(g_sql_buf[0]));
131
    }
132
    sqlite3_finalize(stmt2);
133
    sqlite3_finalize(stmt);
3509 mrmanese 134
    _sqlite_commit;
3419 mrmanese 135
 
136
    /* return smat sexp */
3808 mrmanese 137
    ret = _create_smat_sexp(mat_iname, vectype, nrows, ncols - 1, names);
3419 mrmanese 138
 
3808 mrmanese 139
    UNUSE_SDF2(iname);
140
    UNUSE_SDF2(mat_iname);
141
    return ret;
142
}
3419 mrmanese 143
 
3808 mrmanese 144
/* "decorate" passed svec w/ rownames & colnames to make it a sqlite.matrix */
145
SEXP sdf_create_smat(SEXP svec, SEXP dimnames) {
146
    SEXP tmp, ret = svec;
147
    sqlite3_stmt *stmt;
148
    char *mat_iname;
149
    int i, nrows, ncols;
150
 
151
    mat_iname = SDF_INAME(svec);
152
    if (!USE_SDF1(mat_iname, TRUE, TRUE)) return R_NilValue;
153
 
154
    /* create and set sdf_matrix_rownames */
155
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_rownames(name text)", mat_iname);
156
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
157
 
158
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames(name) values (?)", mat_iname);
159
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
160
    tmp = VECTOR_ELT(dimnames, 0);
161
 
162
    if (inherits(tmp, "sqlite.vector")) {
163
        char *iname = SDF_INAME(tmp), *tblname = SVEC_TBLNAME(tmp),
164
             *varname = SVEC_VARNAME(tmp);
165
        USE_SDF1(iname, TRUE, TRUE);
166
        nrows = _get_row_count2(iname, TRUE);
167
        sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames(name) "
168
                "select [%s] from [%s].[%s]", mat_iname, varname, iname, tblname);
169
        _sqlite_error(_sqlite_exec(g_sql_buf[0]));
170
        UNUSE_SDF2(iname);
171
    } else {
172
        nrows = LENGTH(tmp);
173
        _sqlite_begin;
174
        for (i = 0; i < nrows; i++) {
175
            sqlite3_reset(stmt);
176
            sqlite3_bind_text(stmt, 1, CHAR_ELT(tmp, i), -1, SQLITE_STATIC);
177
            sqlite3_step(stmt);
178
        }
179
        _sqlite_commit;
180
    }
181
 
182
    /* create and set sdf_matrix_colnames */
183
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_colnames(name text)", mat_iname);
184
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
185
 
186
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames(name) values (?)", mat_iname);
187
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt, NULL);
188
    tmp = VECTOR_ELT(dimnames, 1);
189
    ncols = LENGTH(tmp);
190
    _sqlite_begin;
191
    for (i = 0; i < ncols; i++) {
192
        sqlite3_reset(stmt);
193
        sqlite3_bind_text(stmt, 1, CHAR_ELT(tmp, i), -1, SQLITE_STATIC);
194
        sqlite3_step(stmt);
195
    }
196
    _sqlite_commit;
197
 
198
    /* modify the passed svec sexp to smat */
3419 mrmanese 199
    /* set class */
3808 mrmanese 200
    PROTECT(tmp = mkString("sqlite.matrix")); i = 1;
3419 mrmanese 201
    SET_CLASS(ret, tmp);
202
 
203
    /* set smat dim */
204
    PROTECT(tmp = NEW_INTEGER(2)); i++;
205
    INTEGER(tmp)[0] = nrows;
3808 mrmanese 206
    INTEGER(tmp)[1] = ncols; 
3509 mrmanese 207
    setAttrib(ret, SDF_DimSymbol, tmp);
3419 mrmanese 208
 
209
    /* set smat dimname */
210
    PROTECT(tmp = NEW_LIST(2)); i++;
3684 mrmanese 211
    SET_VECTOR_ELT(tmp, 0, _create_svector_sexp(mat_iname, 
212
                "sdf_matrix_rownames", "name", "character"));
3808 mrmanese 213
    SET_VECTOR_ELT(tmp, 1, duplicate(VECTOR_ELT(dimnames, 1)));
3509 mrmanese 214
    setAttrib(ret, SDF_DimNamesSymbol, tmp);
3419 mrmanese 215
 
3808 mrmanese 216
    /* sdf.vector.type already set */
217
 
3419 mrmanese 218
    UNPROTECT(i);
3808 mrmanese 219
    UNUSE_SDF2(mat_iname);
3419 mrmanese 220
 
3808 mrmanese 221
    return ret;
222
}
223
 
224
SEXP sdf_get_matrix_columns(SEXP smat, SEXP cols) {
225
    SEXP colnames, ret;
226
    sqlite3_stmt *stmt1, *stmt2;
4160 mrmanese 227
    char *mat_iname, *mat2_iname;
3808 mrmanese 228
    const char *coltype, *vectype;
229
    int i, nrows, ncols, index, idxlen, ci_len, ci_actual_len;
230
    int *col_indices;
231
 
232
    mat_iname = SDF_INAME(smat);
233
    if (!USE_SDF1(mat_iname, TRUE, TRUE)) return R_NilValue;
234
 
235
    idxlen = LENGTH(cols);
236
    sprintf(g_sql_buf[0], "[%s].sdf_matrix_colnames", mat_iname);
237
    ncols = _get_row_count2(g_sql_buf[0], FALSE);
238
    sprintf(g_sql_buf[0], "[%s].sdf_matrix_rownames", mat_iname);
239
    nrows = _get_row_count2(g_sql_buf[0], FALSE);
240
 
241
 
242
    /* get column indices selected */
243
    ci_len = (ncols > idxlen) ? ncols : idxlen;
244
    col_indices = (int *)R_alloc(ci_len, sizeof(int));
245
    ci_actual_len = 0;
246
 
247
    if (IS_NUMERIC(cols)) {
248
        for (i = 0; i < idxlen; i++) {
249
            index = (int) REAL(cols)[i];
250
            if (index <= ncols && index > 0) col_indices[ci_actual_len++] = index-1;
251
        }
252
    } else if (IS_INTEGER(cols)) {
253
        for (i = 0; i < idxlen; i++) {
254
            index = INTEGER(cols)[i];
255
            if (index <= ncols && index > 0) col_indices[ci_actual_len++] = index-1;
256
        }
257
    } else if (IS_LOGICAL(cols)) {
258
        for (i = 0; i < ncols; i++) {
259
            if (LOGICAL(cols)[i % ncols]) col_indices[ci_actual_len++] = INTEGER(cols)[i];
260
        }
261
    }
262
 
263
    /* get matrix "mode" / type */
264
    sprintf(g_sql_buf[1], "select [row name], V1 from [%s].[sdf_data] limit ?,?", mat_iname);
265
    sqlite3_prepare(g_workspace, g_sql_buf[1], -1, &stmt1, NULL);
266
    sqlite3_bind_int(stmt1, 1, 1);  /* limit 1,1 */
267
    sqlite3_bind_int(stmt1, 2, 1);
268
    sqlite3_step(stmt1);
269
    coltype = (const char*) strcpy(g_sql_buf[0], sqlite3_column_decltype(stmt1, 1));
270
    sqlite3_finalize(stmt1);
271
 
272
    PROTECT(colnames = NEW_CHARACTER(ci_actual_len));
273
 
274
    /* create new matrix */
275
    mat2_iname = _create_svector1(mkString(mat_iname), coltype, NULL, TRUE);
276
    coltype = strcpy(g_sql_buf[3], g_sql_buf[0]);
277
 
278
    _sqlite_begin;
279
 
280
    /* create sdf_matrix_rownames and sdf_matrix_colnames */
281
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_rownames(name text)", mat2_iname);
282
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
283
    sprintf(g_sql_buf[0], "create table [%s].sdf_matrix_colnames(name text)", mat2_iname);
284
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
285
 
286
    /* stmt to insert-select to the new matrix */
287
    sprintf(g_sql_buf[0], "insert into [%s].sdf_data([row name], V1) "
288
            " select [row name], V1 from [%s].[sdf_data] limit ?,?",
289
            mat2_iname, mat_iname);
290
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt1, NULL);
291
 
292
    /* stmt to insert-select to the new matrix-column table */
293
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_colnames "
294
            " select name from [%s].sdf_matrix_colnames limit ?, 1", mat2_iname, mat_iname);
295
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt2, NULL); 
296
 
297
    for (i = 0; i < ci_actual_len; i++) {
298
        sqlite3_reset(stmt1);
299
        sqlite3_bind_int(stmt1, 1, col_indices[i]*nrows);
300
        sqlite3_bind_int(stmt1, 2, nrows);
301
        sqlite3_step(stmt1);
302
 
303
        sqlite3_reset(stmt2);
304
        sqlite3_bind_int(stmt2, 1, col_indices[i]+1);
305
        sqlite3_step(stmt2);
306
    }
307
 
308
    sqlite3_finalize(stmt1);
309
    sqlite3_finalize(stmt2);
310
 
311
    /* copy colnames to a sexp, as the sexp's names() */
312
    sprintf(g_sql_buf[0], "select name from [%s].sdf_matrix_colnames", mat2_iname);
313
    sqlite3_prepare(g_workspace, g_sql_buf[0], -1, &stmt1, NULL);
314
 
315
    for (i = 0; sqlite3_step(stmt1) == SQLITE_ROW; i++) {
316
        SET_STRING_ELT(colnames, i, mkChar((char *)sqlite3_column_text(stmt1, 0)));
317
    }
318
 
319
    sqlite3_finalize(stmt1);
320
 
321
    /* copy matrix-rows table */
322
    sprintf(g_sql_buf[0], "insert into [%s].sdf_matrix_rownames "
323
            "select * from [%s].sdf_matrix_rownames", mat2_iname, mat_iname);
324
    _sqlite_error(_sqlite_exec(g_sql_buf[0]));
325
 
326
    _sqlite_commit;
327
 
328
    /* return matrix SEXP */
329
    if (strcmp(coltype, "text") == 0) vectype = "character";
330
    else if (strcmp(coltype, "int") == 0) vectype = "integer";
331
    else if (strcmp(coltype, "double") == 0) vectype = "numeric";
332
    ret = _create_smat_sexp(mat2_iname, coltype, nrows, ci_actual_len, colnames);
333
 
334
 
335
 
336
    UNPROTECT(1);
3419 mrmanese 337
    UNUSE_SDF2(mat_iname);
3808 mrmanese 338
    UNUSE_SDF2(mat2_iname);
3419 mrmanese 339
    return ret;
340
}