// 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; }
/* 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; }