#include #include #include #include #include #include #include #include #include #include "log.h" #include "libuv_dbus.h" #include "skins.h" #include "log.h" typedef struct { sqlite3_vtab vTable; sqlite3 *pSqlDb; char *pTblName; } SKINRES_VTBL, *PSKINRES_VTBL; typedef struct { sqlite3_vtab_cursor base; int count; int eof; } SKINRES_CURSOR, *PSKINRES_CURSOR; static int __skin_res_destructor(sqlite3_vtab *pVtab) { PSKINRES_VTBL p = (PSKINRES_VTBL)pVtab; if(p->pTblName != NULL) { free(p->pTblName); p->pTblName = NULL; } sqlite3_free(p); return 0; } static int __skin_res_create(sqlite3 *pDb, void *pAux, int argc, const char * const *argv, sqlite3_vtab **pp_vt, char **pzErr) { UT_string *pSqlCmd; int rc = SQLITE_OK; PSKINRES_VTBL pVTbl; /* Allocate the sqlite3_vtab/example_vtab structure itself */ pVTbl = (PSKINRES_VTBL)sqlite3_malloc(sizeof(SKINRES_VTBL)); if(pVTbl == NULL) { return SQLITE_NOMEM; } pVTbl->pSqlDb = pDb; pVTbl->pTblName = strdup(argv[2]); utstring_new(pSqlCmd); if(strcmp(argv[0], RES_MODE_NAME) == 0) { utstring_printf(pSqlCmd, CREATE_RES_TBL_SQL, ""); } else { utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL, ""); } /* Declare the vtable's structure */ rc = sqlite3_declare_vtab(pDb, utstring_body(pSqlCmd)); utstring_free(pSqlCmd); if(rc != SQLITE_OK) { __skin_res_destructor((sqlite3_vtab*)pVTbl); return SQLITE_ERROR; } /* Success. Set *pp_vt and return */ *pp_vt = &pVTbl->vTable; return SQLITE_OK; } static int __skin_res_connect( sqlite3 *db, void *p_aux, int argc, const char * const *argv, sqlite3_vtab **pp_vt, char **pzErr ) { return __skin_res_create(db, p_aux, argc, argv, pp_vt, pzErr); } static int __skin_res_disconnect(sqlite3_vtab *pVtab) { return __skin_res_destructor(pVtab); } static int __skin_res_destroy(sqlite3_vtab *pVtab) { int rc = SQLITE_OK; //PSKINRES_VTBL p = (PSKINRES_VTBL)pVtab; if(rc == SQLITE_OK) { rc = __skin_res_destructor(pVtab); } return rc; } static int __skin_res_open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) { PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)sqlite3_malloc(sizeof(SKINRES_CURSOR)); *ppCursor = (sqlite3_vtab_cursor*)pCur; return (pCur ? SQLITE_OK : SQLITE_NOMEM); } static int __skin_res_close(sqlite3_vtab_cursor *cur) { PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)cur; sqlite3_free(pCur); return SQLITE_OK; } static int __skin_res_eof(sqlite3_vtab_cursor *cur) { return ((PSKINRES_CURSOR)cur)->eof; } static int __skin_res_next(sqlite3_vtab_cursor *pInCur) { PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; //PSKINRES_VTBL pvTable = (PSKINRES_VTBL)pInCur->pVtab; /* Increment the current row count. */ pCur->count += 1; /* Arbitrary contstraint: when we get to 10 rows, then stop. */ if(pCur->count >= SkinsDefaultSize()) { pCur->eof = 1; } return SQLITE_OK; } static int __skin_res_column(sqlite3_vtab_cursor *pInCur, sqlite3_context *ctx, int iCol) { PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; PSKIN_RES_INFO pItem = SkinsItemById(pCur->count); //PSKINRES_VTBL pvTable = (PSKINRES_VTBL)pInCur->pVtab; /* Just return the ordinal of the column requested. */ switch(iCol) { case 0: sqlite3_result_int(ctx, pCur->count); break; case 1: sqlite3_result_text(ctx, pItem->pResVer, strlen(pItem->pResVer), SQLITE_STATIC); break; case 2: sqlite3_result_text(ctx, pItem->pLocalPath, strlen(pItem->pLocalPath), SQLITE_STATIC); break; case 3: sqlite3_result_text(ctx, pItem->pLocalPath, strlen(pItem->pLocalPath), SQLITE_STATIC); break; case 4: sqlite3_result_text(ctx, pItem->pMD5Chksum, strlen(pItem->pMD5Chksum), SQLITE_STATIC); break; } return SQLITE_OK; } static int __skin_cfg_column(sqlite3_vtab_cursor *pInCur, sqlite3_context *ctx, int iCol) { PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; PSKIN_RES_INFO pItem = SkinsItemById(pCur->count); //PSKINRES_VTBL pvTable = (PSKINRES_VTBL)pInCur->pVtab; /* Just return the ordinal of the column requested. */ switch(iCol) { case 0: sqlite3_result_int(ctx, pCur->count); break; case 1: sqlite3_result_text(ctx, pItem->pKeyName, strlen(pItem->pKeyName), SQLITE_STATIC); break; case 2: sqlite3_result_int(ctx, pItem->resType); break; case 3: sqlite3_result_int(ctx, 0); break; case 4: sqlite3_result_int(ctx, pCur->count); break; case 5: sqlite3_result_text(ctx, "", 0, SQLITE_STATIC); break; } return SQLITE_OK; } static int __skin_res_rowid(sqlite3_vtab_cursor *pInCur, sqlite_int64 *p_rowid) { PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; /* Just use the current row count as the rowid. */ *p_rowid = pCur->count; return SQLITE_OK; } static int __skin_res_filter( sqlite3_vtab_cursor *pVtc, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ) { //int rc; //int i; /* Initialize the cursor structure. */ PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pVtc; /* Zero rows returned thus far. */ pCur->count = 0; /* Have not reached end of set. */ pCur->eof = 0; /* Move cursor to first row. */ return __skin_res_next(pVtc); } /* Pretty involved. We don't implement in this example. */ static int __skin_res_best_index(sqlite3_vtab *pVTbl, sqlite3_index_info *pIdxInfo) { return SQLITE_OK; } static sqlite3_module g_ResModule = { 0, /* iVersion */ __skin_res_create, /* xCreate - create a vtable */ __skin_res_connect, /* xConnect - associate a vtable with a connection */ __skin_res_best_index, /* xBestIndex - best index */ __skin_res_disconnect, /* xDisconnect - disassociate a vtable with a connection */ __skin_res_destroy, /* xDestroy - destroy a vtable */ __skin_res_open, /* xOpen - open a cursor */ __skin_res_close, /* xClose - close a cursor */ __skin_res_filter, /* xFilter - configure scan constraints */ __skin_res_next, /* xNext - advance a cursor */ __skin_res_eof, /* xEof - inidicate end of result set*/ __skin_res_column, /* xColumn - read data */ __skin_res_rowid, /* xRowid - read data */ NULL, /* xUpdate - write data */ NULL, /* xBegin - begin transaction */ NULL, /* xSync - sync transaction */ NULL, /* xCommit - commit transaction */ NULL, /* xRollback - rollback transaction */ NULL, /* xFindFunction - function overloading */ }; static sqlite3_module g_SkinModule = { 0, /* iVersion */ __skin_res_create, /* xCreate - create a vtable */ __skin_res_connect, /* xConnect - associate a vtable with a connection */ __skin_res_best_index, /* xBestIndex - best index */ __skin_res_disconnect, /* xDisconnect - disassociate a vtable with a connection */ __skin_res_destroy, /* xDestroy - destroy a vtable */ __skin_res_open, /* xOpen - open a cursor */ __skin_res_close, /* xClose - close a cursor */ __skin_res_filter, /* xFilter - configure scan constraints */ __skin_res_next, /* xNext - advance a cursor */ __skin_res_eof, /* xEof - inidicate end of result set*/ __skin_cfg_column, /* xColumn - read data */ __skin_res_rowid, /* xRowid - read data */ NULL, /* xUpdate - write data */ NULL, /* xBegin - begin transaction */ NULL, /* xSync - sync transaction */ NULL, /* xCommit - commit transaction */ NULL, /* xRollback - rollback transaction */ NULL, /* xFindFunction - function overloading */ }; int InitSkinRomDatabase(sqlite3 *pDataBase) { if((sqlite3_create_module(pDataBase, SKIN_MODE_NAME, &g_SkinModule, NULL) == SQLITE_OK) && (sqlite3_create_module(pDataBase, RES_MODE_NAME, &g_ResModule, NULL) == SQLITE_OK)) { return 0; } else { return -ERR_SQL_REG_MODULE; } }