Exemple #1
0
// TODO: integrate storage scheme into ID?
// TODO: do it at C level?
// sdb.init(id, "ram"|"flash", { <colspec>, ... })
// <colspec> : see stagedb Lua documentation
static int api_init( lua_State *L) {
    struct sdb_table_t *tbl;
    const char *id;
    enum sdb_storage_kind_t storage;
    int r, i;
    sdb_ncolumn_t ncolumns;

    // id, storage, columns
    id       = luaL_checkstring(   L, 1);
    storage  = luaL_checkoption(   L, 2, NULL, storage_options);
    tbl      = lua_newuserdata(    L, sizeof( *tbl));
    ncolumns = lua_objlen(         L, 3);
    // id, storage, columns, udata

    r = sdb_initwithoutcolumns( tbl, id, ncolumns, storage);
    if( r) { lua_pushnil( L); lua_pushinteger( L, r); return 2; }

    lua_getfield(     L, LUA_REGISTRYINDEX, MT_NAME); // id, storage, columns, udata, mt
    lua_setmetatable( L, -2); // id, storage, columns, udata

    luaL_checktype( L, 3, LUA_TTABLE);

    for(i=1, lua_rawgeti( L, 3, 1); !lua_isnil( L, -1); lua_rawgeti( L, 3, ++i)) { // id, storage, columns, udata, val
        const char *colname;
        enum sdb_serialization_method_t method;
        double arg;
        if( lua_isstring( L, -1)) {
            method  = SDB_DEFAULT_SERIALIZATION_METHOD;
            arg = 0.0;
        } else if ( lua_istable(L, -1)) {
            lua_sdb_getcolumnspec( L, &arg, &method, NULL, 3, i); // id, storage, columns, udata, colname
        } else {
            lua_sdb_fargerror( L, 3, "wrong descriptor for column %d (expected a table or a string)", i);
        }
        colname = lua_tostring( L, -1);
        sdb_setcolumn( tbl, colname, method, arg);
        lua_pop( L, 1);  // id, storage, columns, udata
    }
    // id, storage, columns, udata, nil
    lua_pop( L, 1);  // id, storage, columns, udata
    return 1;
}
static int addcolumn(  sdb_table_t *tbl, const char *label) {
    sdb_column_t *c = tbl->columns + tbl->conf_col;
    // TODO: if it's a persisted table, check consistency instead of setting
    // up configuration?
    if( tbl->state != SDB_ST_UNCONFIGURED) return SDB_EBADSTATE;

    c->label_offset = new_conf_string( tbl, label);
    if( c->label_offset<0) {
        return SDB_EMEM;
    } else if( ++tbl->conf_col == tbl->ncolumns) {
        tbl->state = SDB_ST_READING;
        // Trim unnecessary space at the end of sting cfg;
        tbl->conf_strings = BS_MEM_REALLOC( tbl->conf_strings, nextpwr2( tbl->conf_string_idx), tbl->conf_string_idx);
        // read existing cells if table is a file
#ifdef SDB_FILE_SUPPORT
        if( tbl->storage_kind == SDB_SK_FILE) {
            sdb_restore_file_cells( tbl);
        }
#endif
    }

    int r = sdb_setcolumn( tbl, label, SDB_SM_SMALLEST, 0.0);
    return r;
}
Exemple #3
0
/* sdb :newconsolidation(id, storage, { col1=CM1, ..., coln=CMn })
 * sdb :newconsolidation(id, storage, { <columnspec>, ... })
 * CM are Consolidation Methods. <columnspec> are standard column
 * specifications with the `consolidation` field set.
 *
 * Column names are shared between src and dst: the column src.foobar,
 * if it is consolidated, is consolidated in dst.foobar.
 *
 * The dst consolidation table is created on the fly, rather than passed
 * as a parameter. */
static int api_newconsolidation( lua_State *L) {
    struct sdb_table_t *src, *dst;
    const char *id;
    enum sdb_storage_kind_t storage;
    int r, i, ncolumns;

    // src, id, storage, columns
    src      = lua_sdb_checktable( L, 1);
    id       = luaL_checkstring(   L, 2);
    storage  = luaL_checkoption(   L, 3, NULL, storage_options);
    ncolumns = gettablencolumns(   L, 4);
    dst      = lua_newuserdata(    L, sizeof( *dst));
    // src, id, storage, columns, dst

    r = sdb_initwithoutcolumns( dst, id, ncolumns, storage);
    if( r) { lua_pushnil( L); lua_pushinteger( L, r); return 2; }

    lua_getfield(     L, LUA_REGISTRYINDEX, MT_NAME); // id, storage, columns, udata, mt
    lua_setmetatable( L, -2); // id, storage, columns, udata

    luaL_checktype( L, 4, LUA_TTABLE);

    r = sdb_setconstable( src, dst);
    if( r) {
      sdb_close( dst);
      return push_sdb_error( L, r);
    }

    if( lua_objlen(L, 4) == ncolumns) {
        // full column description sequence
        for(i=1, lua_rawgeti( L, 4, 1); !lua_isnil( L, -1); lua_rawgeti( L, 4, ++i)) { // src, id, storage, columns, dst, val
            const char *colname;
            enum sdb_serialization_method_t s_method;
            enum sdb_consolidation_method_t c_method;
            double arg;
            sdb_ncolumn_t src_col;

            lua_sdb_getcolumnspec( L, &arg, &s_method, &c_method, 4, i); // src, id, storage, columns, dst, colname
            colname = lua_tostring( L, -1);
            src_col = sdb_getcolnum( src, colname);
            if( SDB_NCOLUMN_INVALID == src_col) {
                lua_sdb_fargerror( L, 4, "Unknown column %s.", colname);
            }

            r = sdb_setcolumn( dst, colname, s_method, arg);
            if( r) { sdb_close( dst); return push_sdb_error( L, r); }

            r = sdb_setconscolumn( src, src_col, c_method);
            if( r) { sdb_close( dst); return push_sdb_error( L, r); }

            lua_pop( L, 1); // src, id, storage, columns, dst
        }
        // src, id, storage, columns, dst, nil
        lua_pop( L, 1); // src, id, storage, columns, dst
    } else {
        // short colname/consolidation method mapping
        for( lua_pushnil( L); lua_next( L, 4);) { // src, id, storage, columns, dst, key, val
            if( !lua_isstring(L, -2))
                lua_sdb_fargerror( L, 4, "Expected string for columns names, got %s", lua_typename( L, lua_type( L, -1)));
            const char *colname = luaL_checkstring( L, -2);
            enum sdb_serialization_method_t s_method = SDB_DEFAULT_SERIALIZATION_METHOD;
            enum sdb_consolidation_method_t c_method = lua_sdb_getoption( L, -1, consolidation_methods);
            if( !consolidation_methods[c_method]) {
                lua_sdb_fargerror( L, 4, "Invalid consolidation method for %s", colname);
            }

            sdb_ncolumn_t src_col = sdb_getcolnum( src, colname);
            if( SDB_NCOLUMN_INVALID == src_col) {
                lua_sdb_fargerror( L, 4, "Unknown column %s", colname);
            }

            r = sdb_setcolumn( dst, colname, s_method, 0.0);
            if( r) { sdb_close( dst); return push_sdb_error( L, r); }

            r = sdb_setconscolumn( src, src_col, c_method);
            if( r) { sdb_close( dst); return push_sdb_error( L, r); }

            lua_pop( L, 1); // src, id, storage, columns, dst
        }
    }
    // src, id, storage, columns, dst
    return 1;
}