DBD-SQLite-Amalgamation

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

    SV *errstr = DBIc_ERRSTR(imp_xxh);
    sv_setiv(DBIc_ERR(imp_xxh), (IV)rc);
    sv_setpv(errstr, what);
    sv_catpvf(errstr, "(%d) at %s line %d", rc, file, line);
    
    if (DBIS->debug >= 3) {
        PerlIO_printf(DBILOGFP, "sqlite error %d recorded: %s at %s line %d\n",
            rc, what, file, line);
    }
}

static void
_sqlite_tracef(char *file, int line, int level, const char *fmt, ...)
{
    dTHR;
    
    va_list ap;
    if (DBIS->debug >= level) {
        char format[8192];
        sqlite3_snprintf(8191, format, "sqlite trace: %s at %s line %d\n", fmt, file, line);
        va_start(ap, fmt);
        PerlIO_vprintf(DBILOGFP, format, ap);
        va_end(ap);
    }
}

static void
_sqlite_tracef_noline(int level, const char *fmt, ...)
{
    dTHR;
    
    va_list ap;
    if (DBIS->debug >= level) {
        char format[8192];
        sqlite3_snprintf(8191, format, "sqlite trace: %s\n", fmt);
        va_start(ap, fmt);
        PerlIO_vprintf(DBILOGFP, format, ap);
        va_end(ap);
    }
}

int
sqlite_db_login(SV *dbh, imp_dbh_t *imp_dbh, char *dbname, char *user, char *pass)
{
    dTHR;
    int retval;
    char *errmsg = NULL;

    if (DBIS->debug >= 3) {
        PerlIO_printf(DBILOGFP, "    login '%s' (version %s)\n",
            dbname, sqlite3_version);
    }

    if (sqlite3_open(dbname, &(imp_dbh->db)) != SQLITE_OK) {
        sqlite_error(dbh, (imp_xxh_t*)imp_dbh, 1, (char*)sqlite3_errmsg(imp_dbh->db));
        return FALSE;
    }
    DBIc_IMPSET_on(imp_dbh);

    imp_dbh->in_tran = FALSE;
    imp_dbh->unicode = FALSE;
    imp_dbh->functions = newAV();
    imp_dbh->aggregates = newAV();
    imp_dbh->timeout = SQL_TIMEOUT;
    
    imp_dbh->handle_binary_nulls = FALSE;

    sqlite3_busy_timeout(imp_dbh->db, SQL_TIMEOUT);

    if ((retval = sqlite3_exec(imp_dbh->db, "PRAGMA empty_result_callbacks = ON",
        NULL, NULL, &errmsg))
        != SQLITE_OK)
    {
        /*  warn("failed to set pragma: %s\n", errmsg); */
        sqlite_error(dbh, (imp_xxh_t*)imp_dbh, retval, errmsg);
        return FALSE;
    }

    if ((retval = sqlite3_exec(imp_dbh->db, "PRAGMA show_datatypes = ON",
        NULL, NULL, &errmsg))
        != SQLITE_OK)
    {
        /*  warn("failed to set pragma: %s\n", errmsg); */
        sqlite_error(dbh, (imp_xxh_t*)imp_dbh, retval, errmsg);
        return FALSE;
    }

    DBIc_ACTIVE_on(imp_dbh);

    return TRUE;
}

int
dbd_set_sqlite3_busy_timeout ( SV *dbh, int timeout )
{
  D_imp_dbh(dbh);
  if (timeout) {
    imp_dbh->timeout = timeout;
    sqlite3_busy_timeout(imp_dbh->db, timeout);
  }
  return imp_dbh->timeout;
}

int
sqlite_db_disconnect (SV *dbh, imp_dbh_t *imp_dbh)
{
    dTHR;
    DBIc_ACTIVE_off(imp_dbh);

    if (DBIc_is(imp_dbh, DBIcf_AutoCommit) == FALSE) {
        sqlite_db_rollback(dbh, imp_dbh);
    }

    if (sqlite3_close(imp_dbh->db) == SQLITE_BUSY) {
        /* active statements! */
        warn("closing dbh with active statement handles");
    }
    imp_dbh->db = NULL;

    av_undef(imp_dbh->functions);
    imp_dbh->functions = (AV *)NULL;

dbdimp.c  view on Meta::CPAN

{
    AV *av;
    D_imp_dbh_from_sth;
    int numFields = DBIc_NUM_FIELDS(imp_sth);
    int chopBlanks = DBIc_is(imp_sth, DBIcf_ChopBlanks);
    int i, retval;

    sqlite_trace(6, "numFields == %d, nrow == %d\n", numFields, imp_sth->nrow);

    if (!DBIc_ACTIVE(imp_sth)) {
        return Nullav;
    }
    
    if (imp_sth->retval == SQLITE_DONE) {
        sqlite_st_finish(sth, imp_sth);
        return Nullav;
    }
    
    if (imp_sth->retval != SQLITE_ROW) {
        /* error */
        sqlite_st_finish(sth, imp_sth);
        sqlite_error(sth, (imp_xxh_t*)imp_sth, imp_sth->retval, (char*)sqlite3_errmsg(imp_dbh->db));
        return Nullav;
    }
    
    imp_sth->nrow++;
    
    av = DBIS->get_fbav(imp_sth);
    for (i = 0; i < numFields; i++) {
        int len;
        char * val;
        int col_type = sqlite3_column_type(imp_sth->stmt, i);
        SV **sql_type = av_fetch(imp_sth->col_types, i, 0);
        if (sql_type && SvOK(*sql_type)) {
            if (SvIV(*sql_type)) {
                col_type = SvIV(*sql_type);
            }
        }
        switch(col_type) {
            case SQLITE_INTEGER:
#if defined(USE_64_BIT_INT)
                sv_setiv(AvARRAY(av)[i], sqlite3_column_int64(imp_sth->stmt, i));
#else
                sv_setnv(AvARRAY(av)[i], (double)sqlite3_column_int64(imp_sth->stmt, i));
#endif
                break;
            case SQLITE_FLOAT:
                sv_setnv(AvARRAY(av)[i], sqlite3_column_double(imp_sth->stmt, i));
                break;
            case SQLITE_TEXT:
                val = (char*)sqlite3_column_text(imp_sth->stmt, i);
                len = sqlite3_column_bytes(imp_sth->stmt, i);
                if (chopBlanks) {
                    val = savepv(val);
                    while((len > 0) && (val[len-1] == ' ')) {
                       len--;
                    }
                    val[len] = '\0';
                }
                sv_setpvn(AvARRAY(av)[i], val, len);
                if (imp_dbh->unicode) {
                  SvUTF8_on(AvARRAY(av)[i]);
                } else {
                  SvUTF8_off(AvARRAY(av)[i]);
                }
                if (chopBlanks) Safefree(val);
                break;
            case SQLITE_BLOB:
                len = sqlite3_column_bytes(imp_sth->stmt, i);
                sv_setpvn(AvARRAY(av)[i], sqlite3_column_blob(imp_sth->stmt, i), len);
                SvUTF8_off(AvARRAY(av)[i]);
                break;
            default:
                sv_setsv(AvARRAY(av)[i], &PL_sv_undef);
                SvUTF8_off(AvARRAY(av)[i]);
                break;
        }
        SvSETMAGIC(AvARRAY(av)[i]);
    }
    
    imp_sth->retval = sqlite3_step(imp_sth->stmt);
    
    return av;
}

int
sqlite_st_finish (SV *sth, imp_sth_t *imp_sth)
{
    return sqlite_st_finish3(sth, imp_sth, 0);
}

int
sqlite_st_finish3 (SV *sth, imp_sth_t *imp_sth, int is_destroy)
{
    D_imp_dbh_from_sth;
    
    /* warn("finish statement\n"); */
    if (!DBIc_ACTIVE(imp_sth))
        return 1;

    DBIc_ACTIVE_off(imp_sth);
    
    av_clear(imp_sth->col_types);
    
    if (!DBIc_ACTIVE(imp_dbh))  /* no longer connected  */
        return 1;

	if (is_destroy) {
		return TRUE;
	}
	
    if ((imp_sth->retval = sqlite3_reset(imp_sth->stmt)) != SQLITE_OK) {
        char *errmsg = (char*)sqlite3_errmsg(imp_dbh->db);
        /* warn("finalize failed! %s\n", errmsg); */
        sqlite_error(sth, (imp_xxh_t*)imp_sth, imp_sth->retval, errmsg);
        return FALSE;
    }
    
    return TRUE;
}

void
sqlite_st_destroy (SV *sth, imp_sth_t *imp_sth)
{
    /* warn("destroy statement: %s\n", imp_sth->statement); */
    DBIc_ACTIVE_off(imp_sth);
    sqlite3_finalize(imp_sth->stmt);
    Safefree(imp_sth->statement);
    SvREFCNT_dec((SV*)imp_sth->params);
    SvREFCNT_dec((SV*)imp_sth->col_types);
    DBIc_IMPSET_off(imp_sth);
}

int
sqlite_st_blob_read (SV *sth, imp_sth_t *imp_sth,
                int field, long offset, long len, SV *destrv, long destoffset)
{
    return 0;
}

int
sqlite_db_STORE_attrib (SV *dbh, imp_dbh_t *imp_dbh, SV *keysv, SV *valuesv)
{
    dTHR;
    char *key = SvPV_nolen(keysv);
    char *errmsg;
    int retval;

    if (strEQ(key, "AutoCommit")) {
        if (SvTRUE(valuesv)) {
            /* commit tran? */
            if ( (!DBIc_is(imp_dbh, DBIcf_AutoCommit)) && (imp_dbh->in_tran) ) {
                sqlite_trace(2, "COMMIT TRAN");
                if ((retval = sqlite3_exec(imp_dbh->db, "COMMIT TRANSACTION",
                    NULL, NULL, &errmsg))
                    != SQLITE_OK)
                {
                    sqlite_error(dbh, (imp_xxh_t*)imp_dbh, retval, errmsg);
                    return TRUE;
                }
                imp_dbh->in_tran = FALSE;
            }
        }
        DBIc_set(imp_dbh, DBIcf_AutoCommit, SvTRUE(valuesv));
        return TRUE;
    }
    if (strEQ(key, "unicode")) {
      imp_dbh->unicode = !(! SvTRUE(valuesv));
      return TRUE;
    }
    return FALSE;
}

SV *
sqlite_db_FETCH_attrib (SV *dbh, imp_dbh_t *imp_dbh, SV *keysv)
{
    dTHR;
    char *key = SvPV_nolen(keysv);

    if (strEQ(key, "sqlite_version")) {
        return newSVpv(sqlite3_version,0);
    }
   if (strEQ(key, "unicode")) {
     return newSViv(imp_dbh->unicode ? 1 : 0);
   }

    return NULL;
}

int
sqlite_st_STORE_attrib (SV *sth, imp_sth_t *imp_sth, SV *keysv, SV *valuesv)
{
    char *key = SvPV_nolen(keysv);
    return FALSE;
}

int
type_to_odbc_type (int type)
{
    switch(type) {
        case SQLITE_INTEGER: return SQL_INTEGER;
        case SQLITE_FLOAT:   return SQL_DOUBLE;
        case SQLITE_TEXT:    return SQL_VARCHAR;
        case SQLITE_BLOB:    return SQL_BLOB;
        case SQLITE_NULL:    return SQL_UNKNOWN_TYPE;
        default:             return SQL_UNKNOWN_TYPE;
    }
}

SV *
sqlite_st_FETCH_attrib (SV *sth, imp_sth_t *imp_sth, SV *keysv)
{
    char *key = SvPV_nolen(keysv);
    SV *retsv = NULL;
    int i,n;

    if (!DBIc_ACTIVE(imp_sth)) {
    	return NULL;
    }
    
    /* warn("fetch: %s\n", key); */
    
    i = DBIc_NUM_FIELDS(imp_sth);

    if (strEQ(key, "NAME")) {
        AV *av = newAV();
/* warn("Fetch NAME fields: %d\n", i); */
        av_extend(av, i);
        retsv = sv_2mortal(newRV(sv_2mortal((SV*)av)));
        for (n = 0; n < i; n++) {
/* warn("Fetch col name %d\n", n); */
            const char *fieldname = sqlite3_column_name(imp_sth->stmt, n);
            if (fieldname) {
                /* warn("Name [%d]: %s\n", n, fieldname); */
                char *dot = instr(fieldname, ".");
                if (dot) /* drop table name from field name */
                    fieldname = ++dot;
                av_store(av, n, newSVpv(fieldname, 0));
            }
        }
    }
    else if (strEQ(key, "PRECISION")) {
        AV *av = newAV();
        retsv = sv_2mortal(newRV(sv_2mortal((SV*)av)));

dbdimp.c  view on Meta::CPAN

  void *func, int len1, const void *string1,
              int len2, const void *string2)
{
    dSP;
    int cmp;
    int n_retval;
    SV *sv1, *sv2;

    ENTER;
    SAVETMPS;
    PUSHMARK(SP);
    sv1 = newSVpvn( string1, len1);
    SvUTF8_on(sv1);
    sv2 = newSVpvn( string2, len2);
    SvUTF8_on(sv2);
    XPUSHs( sv_2mortal ( sv1 ) );
    XPUSHs( sv_2mortal ( sv2 ) );
    PUTBACK;
    n_retval = call_sv((void*)func, G_SCALAR);
    if (n_retval != 1) {
      croak("collation function returned %d arguments", n_retval);
    }
    SPAGAIN;
    cmp = POPi;
    PUTBACK;
    FREETMPS;
    LEAVE;

    return cmp;
}


void
sqlite3_db_create_collation( SV *dbh, const char *name, SV *func )
{
    D_imp_dbh(dbh);
    int rv, rv2;
    void *aa = "aa";
    void *zz = "zz";

    SV *func_sv = newSVsv(func);

    /* Check that this is a proper collation function */
    rv = sqlite_db_collation_dispatcher(func_sv, 2, aa, 2, aa);
    if (rv != 0) {
      warn("improper collation function: %s(aa, aa) returns %d!", name, rv); 
    }
    rv  = sqlite_db_collation_dispatcher(func_sv, 2, aa, 2, zz);
    rv2 = sqlite_db_collation_dispatcher(func_sv, 2, zz, 2, aa);
    if (rv2 != (rv * -1)) {
      warn("improper collation function: '%s' is not symmetric", name); 
    }

    /* Copy the func reference so that it can be deallocated at disconnect */
    av_push( imp_dbh->functions, func_sv );

    /* Register the func within sqlite3 */
    rv = sqlite3_create_collation( 
      imp_dbh->db, name, SQLITE_UTF8,
      func_sv, 
      imp_dbh->unicode ? sqlite_db_collation_dispatcher_utf8 
                       : sqlite_db_collation_dispatcher
      );

    if ( rv != SQLITE_OK )
    {
        croak( "sqlite_create_collation failed with error %s", 
               sqlite3_errmsg(imp_dbh->db) );
    }
}


int sqlite_db_progress_handler_dispatcher( void *handler )
{
    dSP;
    int n_retval;
    int retval;

    PUSHMARK(SP);
    n_retval = call_sv( handler, G_SCALAR );
    if ( n_retval != 1 ) {
      croak( "progress_handler returned %d arguments", n_retval );
    }
    SPAGAIN;
    retval = POPi;
    PUTBACK;

    return retval;
}



void
sqlite3_db_progress_handler( SV *dbh, int n_opcodes, SV *handler )
{
    D_imp_dbh(dbh);

    if (handler == &PL_sv_undef) {
      /* remove previous handler */
      sqlite3_progress_handler( imp_dbh->db, 0, NULL, NULL);
    }
    else {
      int rv;
      SV *handler_sv = newSVsv(handler);

      /* Copy the handler ref so that it can be deallocated at disconnect */
      av_push( imp_dbh->functions, handler_sv );

      /* Register the func within sqlite3 */
      sqlite3_progress_handler( imp_dbh->db, n_opcodes, 
                                sqlite_db_progress_handler_dispatcher,
                                handler_sv );
    }
}



/* end */



( run in 0.846 second using v1.01-cache-2.11-cpan-39bf76dae61 )