321 lines
8.9 KiB
C
321 lines
8.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include <sys/file.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <sqlite3.h>
|
|
#include <uthash/utstring.h>
|
|
|
|
#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;
|
|
}
|
|
}
|
|
|
|
|