DBD-SQLite2

 view release on metacpan or  search on metacpan

dbdimp.c  view on Meta::CPAN

#ifndef call_method
#define call_method(x,y) perl_call_method(x,y)
#endif

#ifndef call_sv
#define call_sv(x,y) perl_call_sv(x,y)
#endif

#define sqlite2_error(h,xxh,rc,what) _sqlite2_error(__FILE__, __LINE__, h, xxh, rc, what)

void
sqlite2_init(dbistate_t *dbistate)
{
    dTHR;
    DBIS = dbistate;
}

static void
_sqlite2_error(char *file, int line, SV *h, imp_xxh_t *imp_xxh, int rc, char *what)
{
    dTHR;

    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);
    }
}

int
sqlite2_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, encoding %s)\n",
            dbname, sqlite_version, sqlite_encoding);
    }

    if ((imp_dbh->db = sqlite_open(dbname, 0, &errmsg)) == NULL) {
	sqlite2_error(dbh, (imp_xxh_t*)imp_dbh, 1, errmsg);
        sqlite_freemem(errmsg);
        return FALSE;
    }
    DBIc_IMPSET_on(imp_dbh);

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

    sqlite_busy_timeout(imp_dbh->db, SQL_TIMEOUT);

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

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

    DBIc_ACTIVE_on(imp_dbh);

    return TRUE;
}

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

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

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

    sqlite_close(imp_dbh->db);
    imp_dbh->db = NULL;

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

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

    return TRUE;
}

void
sqlite2_db_destroy (SV *dbh, imp_dbh_t *imp_dbh)
{
    dTHR;
    if (DBIc_ACTIVE(imp_dbh)) {
        sqlite2_db_disconnect(dbh, imp_dbh);
    }
    DBIc_IMPSET_off(imp_dbh);
}

int
sqlite2_db_rollback(SV *dbh, imp_dbh_t *imp_dbh)
{
    dTHR;
    int retval;
    char *errmsg;

    if (imp_dbh->in_tran) {
        if ((retval = sqlite_exec(imp_dbh->db, "ROLLBACK TRANSACTION",
				NULL, NULL, &errmsg)
	   != SQLITE_OK))
        {
	    sqlite2_error(dbh, (imp_xxh_t*)imp_dbh, retval, errmsg);
            sqlite_freemem(errmsg);
            return FALSE;
        }
        imp_dbh->in_tran = FALSE;
    }

    return TRUE;
}

int
sqlite2_db_commit(SV *dbh, imp_dbh_t *imp_dbh)

dbdimp.c  view on Meta::CPAN

            sv_catpvn(ret, "\\0", 2);
            break;
          }
          else {
            die("attempt to quote binary null without sqlite_handle_binary_nulls on");
          }
        case '\\':
          if (imp_dbh->handle_binary_nulls) {
            sv_catpvn(ret, "\\\\", 2);
            break;
          }
        default:
          sv_catpvn(ret, cval, 1);
      }
      *cval++; len--;
    }
    return SvPV_nolen(ret);
}

char *
sqlite2_decode(imp_dbh_t *imp_dbh, char *input, size_t *len)
{
  char *ret;
  char *swit;

  New(1, ret, *len, char);
  swit = ret;

  while (*input) {
    switch (*input) {
      case '\\':
        if (imp_dbh->handle_binary_nulls && input[1] && input[1] == '0') {
          *swit++ = '\0';
          *input++;
          (*len)--;
          break;
        }
        else if (imp_dbh->handle_binary_nulls && input[1] && input[1] == '\\') {
          *swit++ = '\\';
          *input++;
          (*len)--;
          break;
        }
      default:
        *swit++ = *input;
    }
    *input++;
  }
  return ret;
}

int
_sqlite2_fetch_row (imp_sth_t *imp_sth)
{
    while (1)
    {
        if (imp_sth->vm)
          imp_sth->retval = sqlite_step(imp_sth->vm,
            &(imp_sth->ncols), (const char ***)&(imp_sth->results), (const char ***)&(imp_sth->coldata));
        if (imp_sth->retval == SQLITE_BUSY) {
            break; /* We should never get "busy" here because we set sqlite_timeout, so assume error */
        }
        break;
    }
    /* warn("step got: %d\nCol1: %s\n", imp_sth->retval, imp_sth->coldata[0]); */
    return imp_sth->retval;
}

int
sqlite2_st_execute (SV *sth, imp_sth_t *imp_sth)
{
    dTHR;
    D_imp_dbh_from_sth;
    SV *sql;
    I32 pos = 0;
    char *errmsg;
    int num_params = DBIc_NUM_PARAMS(imp_sth);
    I32 i;
    int retval;

    /* warn("execute\n"); */

    if (DBIc_ACTIVE(imp_sth)) {
        sqlite2_st_finish(sth, imp_sth);
    }

    sql = sv_2mortal(newSVsv(AvARRAY(imp_sth->sql)[pos++]));

    for (i = 0; i < num_params; i++) {
        SV *value = av_shift(imp_sth->params);
        if (value && SvOK(value)) {
            /* warn("binding param: %s\n", SvPV_nolen(value); */
            sv_catpvn(sql, "'", 1);
            sv_catpv(sql, sqlite2_quote(imp_dbh, value));
            sv_catpvn(sql, "'", 1);
            /* warn("inserting string length: %d\n", SvCUR(sql)); */
        }
        else {
            /* warn("binding NULL\n"); */
            sv_catpvn(sql, "NULL", 4);
        }
        if (value) {
            SvREFCNT_dec(value);
        }
        sv_catsv(sql, AvARRAY(imp_sth->sql)[pos++]);
    }
    /* warn("Executing: %s;\n", SvPV_nolen(sql)); */

    if ( (!DBIc_is(imp_dbh, DBIcf_AutoCommit)) && (!imp_dbh->in_tran) ) {
        if ((retval = sqlite_exec(imp_dbh->db, "BEGIN TRANSACTION",
				  NULL, NULL, &errmsg)
	     != SQLITE_OK))
        {
            sqlite2_error(sth, (imp_xxh_t*)imp_sth, retval, errmsg);
            sqlite_freemem(errmsg);
            return -2;
        }
        imp_dbh->in_tran = TRUE;
    }

    imp_sth->results = NULL;



( run in 0.477 second using v1.01-cache-2.11-cpan-140bd7fdf52 )