The R Project SVN R-packages

Rev

Rev 4590 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3255 mrmanese 1
#include <stdio.h>
2
#include <string.h>
3
#include <ctype.h>
4
#include <unistd.h>
5
#include "R.h"
6
#include "Rdefines.h"
7
#include "Rinternals.h"
8
 
9
#define __UTIL__
10
#include "sqlite_dataframe.h"
11
 
4798 mrmanese 12
int _is_r_sym(const char *sym) {
3281 mrmanese 13
    int i, len = strlen(sym);
3255 mrmanese 14
 
15
    if (isalpha(sym[0]) || sym[0] == '_') i = 1;
16
    else if (sym[0] == '.') { if (isdigit(sym[1])) return FALSE; i = 2; }
17
    else return FALSE;
18
 
19
    for (; i < len; i++) {
20
        if (!(isalnum(sym[i]) || sym[i] == '.' || sym[i] == '_')) return FALSE;
21
    }
22
 
23
    return TRUE;
24
}
25
 
26
int _file_exists(char *filename) {
27
    FILE *f; int ret = FALSE;
28
    if ((f = fopen(filename, "rb")) != NULL) { fclose(f); ret = TRUE; }
29
    return ret;
30
}
31
 
32
int _empty_callback(void *data, int ncols, char **rows, char **cols) {
33
    return 0;
34
}
35
 
36
char *_fixname(char *rname) {
37
    char *tmp = rname;
3281 mrmanese 38
    while (*tmp) { if (*tmp == '.') *tmp = '_'; tmp++; }
3255 mrmanese 39
    return rname;
40
}
41
 
42
 
43
char *_r2iname(char *rname, char *iname) {
44
    /* basically s/[.!@#$%^&*()-+=]/_/g */
45
    strcpy(iname, rname);
46
    char *tmp = iname;
47
    while ((tmp = strpbrk(tmp, ".!@#$%^&*()-+=")) == NULL) *tmp = '_';
48
    return iname;
49
}
50
 
51
int _check_sql_buf(int i) {
3509 mrmanese 52
    int ret = strlen(g_sql_buf[i]);
3255 mrmanese 53
    if (i >= NBUFS) return FALSE;
54
    if ((ret*1.0/g_sql_buf_sz[i]) > 0.6) {
55
        g_sql_buf_sz[i] *= 2;
56
        g_sql_buf[i] = Realloc(g_sql_buf[i], g_sql_buf_sz[i], char);
57
    } else ret = 0;
58
    return ret;
59
} 
60
 
3821 mrmanese 61
R_INLINE void  _expand_buf(int i, int size) {
3255 mrmanese 62
    if (size >= g_sql_buf_sz[i]) {
63
        g_sql_buf_sz[i] *= 2;
64
        g_sql_buf[i] = Realloc(g_sql_buf[i], g_sql_buf_sz[i], char);
3821 mrmanese 65
        /* return TRUE; */
3255 mrmanese 66
    }
3821 mrmanese 67
    /* return expanded; */
3255 mrmanese 68
}
69
 
4160 mrmanese 70
R_INLINE int _sqlite_error_check(int res, const char *file, int line) {
3255 mrmanese 71
    int ret = FALSE;
72
    if (res != SQLITE_OK) { 
3397 mrmanese 73
        Rprintf("SQLITE ERROR (line %d at %s): %s\n", line, file, sqlite3_errmsg(g_workspace));
3255 mrmanese 74
        ret = TRUE;
75
    }
76
    return ret;
77
}
78
 
79
const char *_get_column_type(const char *class, int type) {
80
    if (type == INTSXP) return "int";
81
    else if (type == REALSXP) return "double";
3397 mrmanese 82
    else if (type == STRSXP) return "text";
3255 mrmanese 83
    else if (type == LGLSXP) return "bit";
3324 mrmanese 84
    else if (strcmp(class, "factor") == 0) return "int"; /* do I really reach this ? */
3255 mrmanese 85
    else if (strcmp(class, "ordered") == 0) return "int";
86
 
87
    return NULL;
88
}
89
 
4590 mrmanese 90
int _get_r_type(const char *decl_type) {
91
    if (strcmp(decl_type, "int") == 0) return INTSXP;
92
    else if (strcmp(decl_type, "double") == 0) return REALSXP;
93
    else if (strcmp(decl_type, "text") == 0) return STRSXP;
94
    else if (strcmp(decl_type, "bit") == 0) return LGLSXP;
95
    return -1;
96
}
97
 
3255 mrmanese 98
const char *_get_r_class(const char *db, const char *type) {
99
    return NULL;
100
}
101
 
3509 mrmanese 102
int _get_row_count2(const char *table, int quote) {
103
    int ret, res;
104
    sqlite3_stmt *stmt;
3255 mrmanese 105
 
3358 mrmanese 106
    if (quote) sprintf(g_sql_buf[2], "select count(*) from [%s].sdf_data", table);
107
    else sprintf(g_sql_buf[2], "select count(*) from %s", table);
3255 mrmanese 108
 
3509 mrmanese 109
    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, NULL);
3255 mrmanese 110
    if (res != SQLITE_OK) return -1;
3509 mrmanese 111
    sqlite3_step(stmt);
112
    ret = sqlite3_column_int(stmt, 0);
113
    sqlite3_finalize(stmt);
3255 mrmanese 114
    return ret;
115
}
116
 
117
/* TODO: windows version */
4798 mrmanese 118
char *_get_full_pathname2(const char *relpath) {
3255 mrmanese 119
    char *tmp1, *tmp2, tmp3, tmp4;
3281 mrmanese 120
    int buflen, relpathlen;
3255 mrmanese 121
 
122
    relpathlen = strlen(relpath);
123
    if (relpath[0] == '/') {
124
        _expand_buf(2, relpathlen);
125
        strcpy(g_sql_buf[2], "/");
126
        buflen = 1;
127
    } else {
128
        while (TRUE) {
129
            tmp1 = getcwd(g_sql_buf[2], g_sql_buf_sz[2]);
130
            if (tmp1 == NULL) _expand_buf(2, g_sql_buf_sz[2]+1);
131
            else { 
132
                buflen = strlen(tmp1); 
133
                strcpy(g_sql_buf[2]+buflen,"/");
134
                buflen += 1;
135
                break;
136
            }
137
        }
138
    }
139
 
140
    /* we'll go along the relpath string "normalizing" relative paths */
4798 mrmanese 141
    tmp1 = strcpy(g_sql_buf[3], relpath);
3255 mrmanese 142
    while (tmp1[0]) {
143
        tmp2 = tmp1;
144
        while(!(*tmp2 == '/' || *tmp2 == 0)) tmp2++;
145
 
146
        tmp3 = *tmp2;
147
        *tmp2 = 0; /* temporarily "end" string at that point */
148
        if (strcmp(tmp1, ".") == 0) {
149
            /* nothing to do */
150
        } else if (strcmp(tmp1, "..") == 0) {
151
            /* remove top dir */
152
            if (buflen > 1) {
153
                buflen--;
154
                do buflen--; 
155
                while (g_sql_buf[2][buflen] != '/' && buflen > 1);
156
                g_sql_buf[2][++buflen] = 0;
157
            }
158
        } else { 
159
            /* non-relative path part, append to buf */
3281 mrmanese 160
            tmp4 = 0;
3255 mrmanese 161
            if (tmp3 == '/') { *tmp2 = '/'; tmp4 = *(tmp2+1); *(tmp2+1) = 0; }
162
            _expand_buf(2, buflen+strlen(tmp1));
163
            strcpy(g_sql_buf[2] + buflen, tmp1);
164
            buflen += strlen(tmp1);
165
            if (tmp3 == '/') { *(tmp2+1) = tmp4; }
166
        }
167
 
168
        if (tmp3 == 0) break;
169
        else { *tmp2 = '/'; tmp1 = tmp2 + 1; }
170
    }
171
 
172
    return g_sql_buf[2];
173
}
174
 
175
/* based on p70 of R-exts.pdf */
4798 mrmanese 176
SEXP _getListElement(SEXP list, const char *varname) {
3255 mrmanese 177
    SEXP ret = R_NilValue, names = GET_NAMES(list);
178
    int i;
179
 
180
    for (i = 0; i < LENGTH(list); i++) {
181
        if (strcmp(CHAR(STRING_ELT(names, i)), varname) == 0) {
182
            ret = VECTOR_ELT(list, i);
183
            break;
184
        }
185
    }
186
 
187
    return ret;
188
}
189
 
3397 mrmanese 190
/* return the row names of an sdf as a sqlite.vector */
3307 mrmanese 191
SEXP _get_rownames2(const char *sdf_iname) {
3509 mrmanese 192
    int res;
3281 mrmanese 193
    sqlite3_stmt *stmt;
3509 mrmanese 194
 
3307 mrmanese 195
    sprintf(g_sql_buf[2], "select [row name] from [%s].sdf_data", sdf_iname);
3509 mrmanese 196
    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
3281 mrmanese 197
 
3282 mrmanese 198
    sqlite3_finalize(stmt);
3281 mrmanese 199
    if (_sqlite_error(res)) return R_NilValue; 
200
 
3821 mrmanese 201
    return _create_svector_sexp(sdf_iname, "sdf_data", "row name", "character");
3281 mrmanese 202
}
3282 mrmanese 203
 
3281 mrmanese 204
SEXP _create_sdf_sexp(const char *iname) {
205
    SEXP names, class, variable, ret;
3255 mrmanese 206
    int nprotected = 0;
207
    PROTECT(ret = NEW_LIST(1)); nprotected++;
208
    PROTECT(names = mkString("iname")); nprotected++;
209
    SET_NAMES(ret, names);
210
 
211
    PROTECT(variable = mkString(iname)); nprotected++;
212
    SET_VECTOR_ELT(ret, 0, variable);
213
 
214
    /* set class */
3456 mrmanese 215
    PROTECT(class = NEW_CHARACTER(1)); nprotected++;
3281 mrmanese 216
    SET_STRING_ELT(class, 0, mkChar("sqlite.data.frame"));
217
    SET_CLASS(ret, class);
3457 mrmanese 218
    SET_SDFROWNAMES(ret, _get_rownames2(iname));
3255 mrmanese 219
 
220
    UNPROTECT(nprotected);
221
    return ret;
222
}
223
 
224
static void __attach_levels2(char *table, SEXP var, int len) {
3307 mrmanese 225
    /* arg table is assumed to be surrounded by [] already */
3255 mrmanese 226
    SEXP levels;
227
    int idx = 0, res;
228
    sqlite3_stmt *stmt;
229
 
230
    PROTECT(levels = NEW_CHARACTER(len));
231
    sprintf(g_sql_buf[2], "select level, label from %s order by level asc",
232
            table);
233
    res = sqlite3_prepare(g_workspace, g_sql_buf[2], -1, &stmt, 0);
234
    _sqlite_error(res);
235
    while (sqlite3_step(stmt) == SQLITE_ROW) { 
3284 mrmanese 236
        SET_STRING_ELT(levels, idx, mkChar((char *)sqlite3_column_text(stmt, 1)));
3255 mrmanese 237
        idx++;
238
    }
239
    SET_LEVELS(var, levels);
240
    UNPROTECT(1);
241
}
242
 
4160 mrmanese 243
/* attaches level values and class attributes to the SEXP var if it has class 
244
 * factor and/or ordered */
245
int _get_factor_levels1(const char *iname, const char *varname, SEXP var, int set_class) {
3509 mrmanese 246
    int res;
4160 mrmanese 247
    SEXP class;
3255 mrmanese 248
 
249
    sprintf(g_sql_buf[1], "[%s].[factor %s]", iname, varname);
3509 mrmanese 250
    res = _get_row_count2(g_sql_buf[1], 0);
3255 mrmanese 251
    if (res > 0) { /* res is exptected to be {-1} \union I+ */
252
        __attach_levels2(g_sql_buf[1], var, res);
4160 mrmanese 253
        if (set_class) {
254
            PROTECT(class = mkString("factor"));
255
            SET_CLASS(var, class);
256
            UNPROTECT(1);
257
        }
3509 mrmanese 258
        return VAR_FACTOR;
3255 mrmanese 259
    }
260
 
261
    sprintf(g_sql_buf[1], "[%s].[ordered %s]", iname, varname);
3358 mrmanese 262
    res = _get_row_count2(g_sql_buf[1], 0);
3255 mrmanese 263
    if (res > 0) {
264
        __attach_levels2(g_sql_buf[1], var, res);
4160 mrmanese 265
        if (set_class) {
266
            PROTECT(class = NEW_CHARACTER(2));
267
            SET_STRING_ELT(class, 0, mkChar("ordered"));
268
            SET_STRING_ELT(class, 1, mkChar("factor"));
269
            SET_CLASS(var, class);
270
            UNPROTECT(1);
271
        }
3509 mrmanese 272
        return VAR_ORDERED;
3255 mrmanese 273
    }
274
 
4160 mrmanese 275
    /*
276
    if (set_class) {
277
        PROTECT(class = NEW_CHARACTER(1));
278
        SET_STRING_ELT(class, 0, mkChar("integer"));
279
        SET_CLASS(var, class);
280
        UNPROTECT(1);
281
    }*/
282
 
3509 mrmanese 283
    return VAR_INTEGER;
3255 mrmanese 284
}
285
 
286
SEXP _shrink_vector(SEXP vec, int len) {
287
    int origlen = LENGTH(vec);
288
    SEXP ret = vec;
289
 
290
    if (vec == R_NilValue) return vec;
291
    else if (origlen > len) {
292
        int type = TYPEOF(vec), i;
293
        if (type == CHARSXP) {
294
            PROTECT(ret = NEW_CHARACTER(len));
295
            for (i = 0; i < len; i++) {
296
                SET_STRING_ELT(ret, i, STRING_ELT(vec, i));
297
            }
298
        } else if (type == INTSXP) {
299
            /* for non-strings, memcpy is more efficient but ... */
300
            PROTECT(ret = NEW_INTEGER(len));
301
            for (i = 0; i < len; i++) INTEGER(ret)[i] = INTEGER(vec)[i];
302
        } else if (type == REALSXP) {
303
            PROTECT(ret = NEW_NUMERIC(len));
304
            for (i = 0; i < len; i++) REAL(ret)[i] = REAL(vec)[i];
305
        } else if (type == LGLSXP) {
306
            PROTECT(ret = NEW_LOGICAL(len));
307
            for (i = 0; i < len; i++) LOGICAL(ret)[i] = LOGICAL(vec)[i];
308
        } else return ret;
4160 mrmanese 309
 
310
        /* preserve class, levels for factors/ordered */
311
        if (isFactor(vec)) {
312
            SET_CLASS(ret, duplicate(GET_CLASS(vec)));
313
            SET_LEVELS(ret, duplicate(GET_LEVELS(vec)));
314
        }
315
 
3255 mrmanese 316
        UNPROTECT(1);
317
    }
318
 
319
    return ret;
320
}
321
 
3397 mrmanese 322
/* prepare sdf workspace before attaching a new db */
323
int _prepare_attach2() {
324
    sqlite3_stmt *stmt;
325
    int nloaded;
326
 
327
    sqlite3_prepare(g_workspace, "select count(*) from workspace where loaded=1",
328
            -1, &stmt, NULL);
329
    sqlite3_step(stmt);
330
    nloaded = sqlite3_column_int(stmt, 0);
331
    sqlite3_finalize(stmt);
332
 
333
    /* test if we have to detach somebody */
334
    if (nloaded == MAX_ATTACHED) {
335
        /* have to evict */
3509 mrmanese 336
        char *iname2;
3397 mrmanese 337
        sqlite3_prepare(g_workspace, "select internal_name from workspace "
3419 mrmanese 338
                "where loaded=1 and used=0 order by uses", -1, &stmt, NULL);
3397 mrmanese 339
        sqlite3_step(stmt);
340
        iname2 = (char *)sqlite3_column_text(stmt, 0);
341
        sprintf(g_sql_buf[2], "detach [%s]", iname2);
3419 mrmanese 342
        _sqlite_error(_sqlite_exec(g_sql_buf[2]));
343
        sprintf(g_sql_buf[2], "update workspace set loaded=0 where internal_name='%s'", iname2);
3397 mrmanese 344
        sqlite3_finalize(stmt); 
3419 mrmanese 345
        _sqlite_error(_sqlite_exec(g_sql_buf[2]));
3397 mrmanese 346
    }
347
 
348
    return nloaded == MAX_ATTACHED;
349
}
350
 
351
char *_str_tolower(char *out, const char *ref) {
352
    int i;
353
    for (i = 0; ref[i]; i++) out[i] = tolower(ref[i]);
3473 mrmanese 354
    out[i] = 0;
3397 mrmanese 355
    return out;
356
}
4590 mrmanese 357
 
358
/* note that *plen must be initialized with the # of rows of the indexed
359
 * vector. this is used win idx is a boolean, so that we can recycle it to
360
 * span the whole vector.
361
 * NOTE: index returned is 1-based */
362
int *_make_row_index(SEXP idx, int *plen) {
363
    int idxlen = LENGTH(idx), len = *plen, i, k;
364
    int *ret;
365
 
366
    if (IS_NUMERIC(idx)) {
367
        double tmp;
368
        ret = (int *)R_alloc(idxlen, sizeof(int));
369
        for (i = k = 0; i < idxlen; i++) {
370
            tmp = REAL(idx)[i];
371
            if (!(tmp == NA_REAL || tmp < 1)) ret[k++] = (int) tmp;
372
 
373
            /*
374
            if (tmp == NA_REAL) ret[i] = NA_INTEGER;
375
            else if (tmp < 1) ret[i] = NA_INTEGER;
376
            else ret[i] = (int) tmp;
377
            */
378
        }
379
        *plen = k;
380
    } else if (IS_INTEGER(idx)) {
381
        int tmp;
382
        ret = (int *)R_alloc(idxlen, sizeof(int));
383
        for (i = k = 0; i < idxlen; i++) {
384
            tmp = INTEGER(idx)[i];
385
            if (!(tmp == NA_REAL || tmp < 1)) ret[k++] = (int) tmp;
386
            /*
387
            if (tmp < 1) ret[i] = NA_INTEGER;
388
            else ret[i] = tmp;
389
            */
390
        }
391
        *plen = k;
392
    } else if (IS_LOGICAL(idx)) {
393
        int k, tmp;  /* to deal with recycling */
394
        ret = (int *)R_alloc(len, sizeof(int));
395
        for (i = k = 0; i < len; i++) {
396
            /* i index the values, j the index sexp, k the output index */
397
            if (LOGICAL(idx)[i%idxlen]) ret[k++] = i+1;
398
            /* ret[k++] = (LOGICAL(idx)[j%idxlen]) ? i : NA_INTEGER; */
399
        }
400
        *plen = k;
401
    }
402
 
403
    return ret;
404
}