DBD-SQLeet
view release on metacpan or search on metacpan
dbdimp_virtual_table.inc view on Meta::CPAN
warn("vtab->OPEN() method returned %d vals instead of 1", count);
SP -= count;
goto cleanup;
}
perl_cursor = POPs;
if ( !sv_isobject(perl_cursor) ) {
warn("vtab->OPEN() method did not return a blessed cursor");
goto cleanup;
}
/* everything went OK */
rc = SQLITE_OK;
cleanup:
if (rc == SQLITE_OK) {
cursor->perl_cursor_obj = SvREFCNT_inc(perl_cursor);
*ppCursor = &cursor->base;
}
else {
sqlite3_free(cursor);
}
PUTBACK;
FREETMPS;
LEAVE;
return rc;
}
static int perl_vt_Close(sqlite3_vtab_cursor *pVtabCursor){
dTHX;
dSP;
perl_vtab_cursor *perl_pVTabCursor;
ENTER;
SAVETMPS;
/* Note : there is no explicit call to a CLOSE() method; if
needed, the Perl class can implement a DESTROY() method */
perl_pVTabCursor = (perl_vtab_cursor *) pVtabCursor;
SvREFCNT_dec(perl_pVTabCursor->perl_cursor_obj);
sqlite3_free(perl_pVTabCursor);
PUTBACK;
FREETMPS;
LEAVE;
return SQLITE_OK;
}
static int perl_vt_Filter( sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv ){
dTHX;
dSP;
dMY_CXT;
int i, count;
int is_unicode = MY_CXT.last_dbh_is_unicode;
ENTER;
SAVETMPS;
/* call the FILTER() method with ($idxNum, $idxStr, @args) */
PUSHMARK(SP);
XPUSHs(((perl_vtab_cursor *) pVtabCursor)->perl_cursor_obj);
XPUSHs(sv_2mortal(newSViv(idxNum)));
XPUSHs(sv_2mortal(newSVpv(idxStr, 0)));
for(i = 0; i < argc; i++) {
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ argv[i], is_unicode));
}
PUTBACK;
count = call_method("FILTER", G_VOID);
SPAGAIN;
SP -= count;
PUTBACK;
FREETMPS;
LEAVE;
return SQLITE_OK;
}
static int perl_vt_Next(sqlite3_vtab_cursor *pVtabCursor){
dTHX;
dSP;
int count;
ENTER;
SAVETMPS;
/* call the next() method */
PUSHMARK(SP);
XPUSHs(((perl_vtab_cursor *) pVtabCursor)->perl_cursor_obj);
PUTBACK;
count = call_method ("NEXT", G_VOID);
SPAGAIN;
SP -= count;
PUTBACK;
FREETMPS;
LEAVE;
return SQLITE_OK;
}
static int perl_vt_Eof(sqlite3_vtab_cursor *pVtabCursor){
dTHX;
dSP;
int count, eof;
ENTER;
SAVETMPS;
/* call the eof() method */
PUSHMARK(SP);
XPUSHs(((perl_vtab_cursor *) pVtabCursor)->perl_cursor_obj);
PUTBACK;
count = call_method ("EOF", G_SCALAR);
SPAGAIN;
if (count != 1) {
warn("cursor->EOF() method returned %d vals instead of 1", count);
SP -= count;
}
else {
SV *sv = POPs; /* need 2 lines, because this doesn't work : */
eof = SvTRUE(sv); /* eof = SvTRUE(POPs); # I don't understand why :-( */
}
dbdimp_virtual_table.inc view on Meta::CPAN
PUTBACK;
count = call_method ("COLUMN", G_SCALAR);
SPAGAIN;
if (count != 1) {
warn("cursor->COLUMN() method returned %d vals instead of 1", count);
SP -= count;
sqlite3_result_error(context, "column error", 12);
}
else {
SV *result = POPs;
sqlite_set_result(aTHX_ context, result, 0 );
rc = SQLITE_OK;
}
PUTBACK;
FREETMPS;
LEAVE;
return rc;
}
static int perl_vt_Rowid( sqlite3_vtab_cursor *pVtabCursor,
sqlite3_int64 *pRowid ){
dTHX;
dSP;
int count;
int rc = SQLITE_ERROR;
ENTER;
SAVETMPS;
/* call the rowid() method */
PUSHMARK(SP);
XPUSHs(((perl_vtab_cursor *) pVtabCursor)->perl_cursor_obj);
PUTBACK;
count = call_method ("ROWID", G_SCALAR);
SPAGAIN;
if (count != 1) {
warn("cursor->ROWID() returned %d vals instead of 1", count);
SP -= count;
}
else {
*pRowid =POPi;
rc = SQLITE_OK;
}
PUTBACK;
FREETMPS;
LEAVE;
return rc;
}
static int perl_vt_Update( sqlite3_vtab *pVTab,
int argc, sqlite3_value **argv,
sqlite3_int64 *pRowid ){
dTHX;
dSP;
dMY_CXT;
int count, i;
int is_unicode = MY_CXT.last_dbh_is_unicode;
int rc = SQLITE_ERROR;
SV *rowidsv;
ENTER;
SAVETMPS;
/* call the _SQLITE_UPDATE() method */
PUSHMARK(SP);
XPUSHs(((perl_vtab *) pVTab)->perl_vtab_obj);
for(i = 0; i < argc; i++) {
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ argv[i], is_unicode));
}
PUTBACK;
count = call_method ("_SQLITE_UPDATE", G_SCALAR);
SPAGAIN;
if (count != 1) {
warn("cursor->_SQLITE_UPDATE() returned %d vals instead of 1", count);
SP -= count;
}
else {
if (argc > 1 && sqlite3_value_type(argv[0]) == SQLITE_NULL
&& sqlite3_value_type(argv[1]) == SQLITE_NULL) {
/* this was an insert without any given rowid, so the result of
the method call must be passed in *pRowid*/
rowidsv = POPs;
if (!SvOK(rowidsv))
*pRowid = 0;
else if (SvUOK(rowidsv))
*pRowid = SvUV(rowidsv);
else if (SvIOK(rowidsv))
*pRowid = SvIV(rowidsv);
else
*pRowid = (sqlite3_int64)SvNV(rowidsv);
}
rc = SQLITE_OK;
}
PUTBACK;
FREETMPS;
LEAVE;
return rc;
}
static int perl_vt_Begin(sqlite3_vtab *pVTab){
return _call_perl_vtab_method(pVTab, "BEGIN_TRANSACTION", 0);
}
static int perl_vt_Sync(sqlite3_vtab *pVTab){
return _call_perl_vtab_method(pVTab, "SYNC_TRANSACTION", 0);
}
static int perl_vt_Commit(sqlite3_vtab *pVTab){
return _call_perl_vtab_method(pVTab, "COMMIT_TRANSACTION", 0);
}
static int perl_vt_Rollback(sqlite3_vtab *pVTab){
return _call_perl_vtab_method(pVTab, "ROLLBACK_TRANSACTION", 0);
}
static int perl_vt_FindFunction(sqlite3_vtab *pVTab,
int nArg, const char *zName,
void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
void **ppArg){
dTHX;
dSP;
dMY_CXT;
int count;
int is_overloaded = 0;
char *func_name = sqlite3_mprintf("%s\t%d", zName, nArg);
STRLEN len = strlen(func_name);
HV *functions = ((perl_vtab *) pVTab)->functions;
SV* coderef = NULL;
SV** val;
SV *result;
ENTER;
SAVETMPS;
/* check if that function was already in cache */
if (hv_exists(functions, func_name, len)) {
val = hv_fetch(functions, func_name, len, FALSE);
if (val && SvOK(*val)) {
coderef = *val;
}
}
else {
/* call the FIND_FUNCTION() method */
PUSHMARK(SP);
XPUSHs(((perl_vtab *) pVTab)->perl_vtab_obj);
XPUSHs(sv_2mortal(newSViv(nArg)));
XPUSHs(sv_2mortal(newSVpv(zName, 0)));
PUTBACK;
count = call_method ("FIND_FUNCTION", G_SCALAR);
SPAGAIN;
if (count != 1) {
warn("vtab->FIND_FUNCTION() method returned %d vals instead of 1", count);
SP -= count;
goto cleanup;
}
result = POPs;
if (SvTRUE(result)) {
/* the coderef must be valid for the lifetime of pVTab, so
make a copy */
coderef = newSVsv(result);
}
/* store result in cache */
hv_store(functions, func_name, len, coderef ? coderef : &PL_sv_undef, 0);
}
/* return function information for sqlite3 within *pxFunc and *ppArg */
is_overloaded = coderef && SvTRUE(coderef);
if (is_overloaded) {
*pxFunc = MY_CXT.last_dbh_is_unicode ? sqlite_db_func_dispatcher_unicode
: sqlite_db_func_dispatcher_no_unicode;
*ppArg = coderef;
}
cleanup:
PUTBACK;
FREETMPS;
LEAVE;
sqlite3_free(func_name);
return is_overloaded;
}
static int perl_vt_Rename(sqlite3_vtab *pVTab, const char *zNew){
dTHX;
dSP;
int count;
int rc = SQLITE_ERROR;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(((perl_vtab *) pVTab)->perl_vtab_obj);
XPUSHs(sv_2mortal(newSVpv(zNew, 0)));
PUTBACK;
count = call_method("RENAME", G_SCALAR);
SPAGAIN;
if (count != 1) {
warn("vtab->RENAME() returned %d args instead of 1", count);
SP -= count;
}
else {
rc = POPi;
}
PUTBACK;
FREETMPS;
LEAVE;
return rc;
}
static int perl_vt_Savepoint(sqlite3_vtab *pVTab, int point){
return _call_perl_vtab_method(pVTab, "SAVEPOINT", point);
}
static int perl_vt_Release(sqlite3_vtab *pVTab, int point){
return _call_perl_vtab_method(pVTab, "RELEASE", point);
}
static int perl_vt_RollbackTo(sqlite3_vtab *pVTab, int point){
return _call_perl_vtab_method(pVTab, "ROLLBACK_TO", point);
}
static sqlite3_module perl_vt_Module = {
1, /* iVersion */
perl_vt_Create, /* xCreate */
perl_vt_Connect, /* xConnect */
perl_vt_BestIndex, /* xBestIndex */
perl_vt_Disconnect, /* xDisconnect */
( run in 1.033 second using v1.01-cache-2.11-cpan-39bf76dae61 )