DBD-SQLeet

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

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;

dbdimp.c  view on Meta::CPAN

    _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 )