DBD-SQLeet
view release on metacpan or search on metacpan
int
sqlite_db_login6(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pass, SV *attr)
{
dTHX;
int rc;
HV *hv;
SV **val;
int extended = 0;
int flag = 0;
int unicode = 0;
sqlite_trace(dbh, imp_dbh, 3, form("login '%s' (version %s)", dbname, sqlite3_version));
if (SvROK(attr)) {
hv = (HV*)SvRV(attr);
if (hv_exists(hv, "sqlite_extended_result_codes", 28)) {
val = hv_fetch(hv, "sqlite_extended_result_codes", 28, 0);
extended = (val && SvOK(*val)) ? !(!SvTRUE(*val)) : 0;
}
if (hv_exists(hv, "ReadOnly", 8)) {
val = hv_fetch(hv, "ReadOnly", 8, 0);
if ((val && SvOK(*val)) ? SvIV(*val) : 0) {
flag |= SQLITE_OPEN_READONLY;
}
}
if (hv_exists(hv, "sqlite_open_flags", 17)) {
val = hv_fetch(hv, "sqlite_open_flags", 17, 0);
flag |= (val && SvOK(*val)) ? SvIV(*val) : 0;
if (flag & SQLITE_OPEN_READONLY) {
hv_stores(hv, "ReadOnly", newSViv(1));
}
}
/* sqlite_unicode should be detected earlier, to register default functions correctly */
if (hv_exists(hv, "sqlite_unicode", 14)) {
val = hv_fetch(hv, "sqlite_unicode", 14, 0);
unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
} else if (hv_exists(hv, "unicode", 7)) {
val = hv_fetch(hv, "unicode", 7, 0);
unicode = (val && SvOK(*val)) ? SvIV(*val) : 0;
}
}
rc = sqlite_open2(dbname, &(imp_dbh->db), flag, extended);
if ( rc != SQLITE_OK ) {
return FALSE; /* -> undef in lib/DBD/SQLeet.pm */
}
DBIc_IMPSET_on(imp_dbh);
imp_dbh->unicode = unicode;
imp_dbh->functions = newAV();
imp_dbh->aggregates = newAV();
imp_dbh->collation_needed_callback = newSVsv( &PL_sv_undef );
imp_dbh->timeout = SQL_TIMEOUT;
imp_dbh->handle_binary_nulls = FALSE;
imp_dbh->allow_multiple_statements = FALSE;
imp_dbh->use_immediate_transaction = TRUE;
imp_dbh->see_if_its_a_number = FALSE;
imp_dbh->extended_result_codes = extended;
imp_dbh->stmt_list = NULL;
imp_dbh->began_transaction = FALSE;
sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);
#if 0
/*
** As of 1.26_06 foreign keys support was enabled by default,
** but with further discussion, we agreed to follow what
** sqlite team does, i.e. wait until the team think it
** reasonable to enable the support by default, as they have
** larger users and will allocate enough time for people to
** get used to the foreign keys. However, we should say it loud
** that sometime in the (near?) future, this feature may break
** your applications (and it actually broke applications).
** Let everyone be prepared.
*/
sqlite_exec(dbh, "PRAGMA foreign_keys = ON");
#endif
#if 0
/*
** Enable this to see if you (wrongly) expect an implicit order
** of return values from a SELECT statement without ORDER BY.
*/
sqlite_exec(dbh, "PRAGMA reverse_unordered_selects = ON");
#endif
DBIc_ACTIVE_on(imp_dbh);
return TRUE;
}
int
sqlite_db_do_sv(SV *dbh, imp_dbh_t *imp_dbh, SV *sv_statement)
{
dTHX;
int rc = 0;
int i;
char *statement;
if (!DBIc_ACTIVE(imp_dbh)) {
sqlite_error(dbh, -2, "attempt to do on inactive database handle");
return -2; /* -> undef in SQLeet.xsi */
}
/* sqlite3_prepare wants an utf8-encoded SQL statement */
if (imp_dbh->unicode) {
sv_utf8_upgrade(sv_statement);
}
statement = SvPV_nolen(sv_statement);
sqlite_trace(dbh, imp_dbh, 3, form("do statement: %s", statement));
croak_if_db_is_null();
if (sqlite3_get_autocommit(imp_dbh->db)) {
const char *sql = statement;
_skip_whitespaces(sql);
if (_starts_with_begin(sql)) {
if (DBIc_is(imp_dbh, DBIcf_AutoCommit)) {
if (!DBIc_is(imp_dbh, DBIcf_BegunWork)) {
imp_dbh->began_transaction = TRUE;
_stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_USED, "lookaside_used");
#if SQLITE_VERSION_NUMBER >= 3007000
_stores_dbstatus(SQLITE_DBSTATUS_CACHE_USED, "cache_used");
#endif
#if SQLITE_VERSION_NUMBER >= 3007001
_stores_dbstatus(SQLITE_DBSTATUS_SCHEMA_USED, "schema_used");
_stores_dbstatus(SQLITE_DBSTATUS_STMT_USED, "stmt_used");
#endif
#if SQLITE_VERSION_NUMBER >= 3007005
_stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_HIT, "lookaside_hit");
_stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, "lookaside_miss_size");
_stores_dbstatus(SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, "lookaside_miss_full");
#endif
#if SQLITE_VERSION_NUMBER >= 3007009
_stores_dbstatus(SQLITE_DBSTATUS_CACHE_HIT, "cache_hit");
_stores_dbstatus(SQLITE_DBSTATUS_CACHE_MISS, "cache_miss");
#endif
#if SQLITE_VERSION_NUMBER >= 3007012
_stores_dbstatus(SQLITE_DBSTATUS_CACHE_WRITE, "cache_write");
#endif
return hv;
}
HV *
_sqlite_st_status(pTHX_ SV* sth, int reset)
{
D_imp_sth(sth);
HV *hv = newHV();
#if SQLITE_VERSION_NUMBER >= 3006004
_stores_ststatus(SQLITE_STMTSTATUS_FULLSCAN_STEP, "fullscan_step");
_stores_ststatus(SQLITE_STMTSTATUS_SORT, "sort");
#endif
#if SQLITE_VERSION_NUMBER >= 3007000
_stores_ststatus(SQLITE_STMTSTATUS_AUTOINDEX, "autoindex");
#endif
return hv;
}
SV *
sqlite_db_filename(pTHX_ SV *dbh)
{
D_imp_dbh(dbh);
const char *filename;
if (!imp_dbh->db) {
return &PL_sv_undef;
}
croak_if_db_is_null();
#if SQLITE_VERSION_NUMBER >= 3007010
filename = sqlite3_db_filename(imp_dbh->db, "main");
#endif
return filename ? newSVpv(filename, 0) : &PL_sv_undef;
}
int
sqlite_db_busy_timeout(pTHX_ SV *dbh, SV *timeout )
{
D_imp_dbh(dbh);
croak_if_db_is_null();
if (timeout && SvIOK(timeout)) {
imp_dbh->timeout = SvIV(timeout);
if (!DBIc_ACTIVE(imp_dbh)) {
sqlite_error(dbh, -2, "attempt to set busy timeout on inactive database handle");
return -2;
}
sqlite3_busy_timeout(imp_dbh->db, imp_dbh->timeout);
}
return imp_dbh->timeout;
}
static void
sqlite_db_func_dispatcher(int is_unicode, sqlite3_context *context, int argc, sqlite3_value **value)
{
dTHX;
dSP;
int count;
int i;
SV *func;
func = sqlite3_user_data(context);
ENTER;
SAVETMPS;
PUSHMARK(SP);
for ( i=0; i < argc; i++ ) {
XPUSHs(stacked_sv_from_sqlite3_value(aTHX_ value[i], is_unicode));
}
PUTBACK;
count = call_sv(func, G_SCALAR|G_EVAL);
SPAGAIN;
/* Check for an error */
if (SvTRUE(ERRSV) ) {
sqlite_set_result(aTHX_ context, ERRSV, 1);
POPs;
} else if ( count != 1 ) {
SV *err = sv_2mortal(newSVpvf( "function should return 1 argument, got %d",
count ));
sqlite_set_result(aTHX_ context, err, 1);
/* Clear the stack */
for ( i=0; i < count; i++ ) {
POPs;
}
} else {
sqlite_set_result(aTHX_ context, POPs, 0 );
}
PUTBACK;
FREETMPS;
LEAVE;
}
static void
sqlite_db_func_dispatcher_unicode(sqlite3_context *context, int argc, sqlite3_value **value)
{
sqlite_db_func_dispatcher(1, context, argc, value);
}
static void
sqlite_db_func_dispatcher_no_unicode(sqlite3_context *context, int argc, sqlite3_value **value)
{
sqlite_db_func_dispatcher(0, context, argc, value);
( run in 1.112 second using v1.01-cache-2.11-cpan-98e64b0badf )