Index: src/RS-SQLite.c =================================================================== --- src/RS-SQLite.c (revision 330) +++ src/RS-SQLite.c (working copy) @@ -31,7 +31,6 @@ RS_SQLite_bindParam *param); int RS_sqlite_import(sqlite3 *db, const char *zTable, const char *zFile, const char *separator, const char *eol, int skip); -int corrected_sqlite3_step(sqlite3_stmt *pStatement); /* The macro NA_STRING is a CHRSXP in R but a char * in Splus */ #define RS_NA_STRING CHAR(NA_STRING) @@ -390,11 +389,11 @@ qrylen += strlen(tname) + 1; sqlQuery = (char*) R_alloc(qrylen, sizeof(char)); snprintf(sqlQuery, qrylen, sqlFmt, tname); - rc = sqlite3_prepare(db, sqlQuery, -1, &stmt, &tail); + rc = sqlite3_prepare_v2(db, sqlQuery, -1, &stmt, &tail); if (rc != SQLITE_OK) { error("SQL error: %s\n", sqlite3_errmsg(db)); } - rc = corrected_sqlite3_step(stmt); + rc = sqlite3_step(stmt); ans = sqlite3_column_int(stmt, 0); sqlite3_finalize(stmt); return ans; @@ -426,7 +425,7 @@ snprintf(sqlQuery, sizeof(sqlQuery), "select %s from %s", column_name, table_name); - rc = sqlite3_prepare(db_connection, sqlQuery, strlen(sqlQuery), &stmt, &tail); + rc = sqlite3_prepare_v2(db_connection, sqlQuery, strlen(sqlQuery), &stmt, &tail); /* FIXME: how should we be handling errors? Could either follow the pattern in the rest of the package or start to use the condition system and raise specific conditions. @@ -435,7 +434,7 @@ error("SQL error: %s\n", sqlite3_errmsg(db_connection)); } - rc = corrected_sqlite3_step(stmt); + rc = sqlite3_step(stmt); col_type = sqlite3_column_type(stmt, 0); switch(col_type) { case SQLITE_INTEGER: @@ -473,7 +472,7 @@ mkChar((char*)sqlite3_column_text(stmt, 0))); } i++; - rc = corrected_sqlite3_step(stmt); + rc = sqlite3_step(stmt); } sqlite3_finalize(stmt); UNPROTECT(1); @@ -519,13 +518,11 @@ res->completed = (Sint) 0; res->statement = dyn_statement; res->drvResultSet = NULL; - do { - if (db_statement) - sqlite3_finalize(db_statement); - state = sqlite3_prepare(db_connection, dyn_statement, -1, + + state = sqlite3_prepare_v2(db_connection, dyn_statement, -1, &db_statement, NULL); - if (state != SQLITE_OK && state != SQLITE_SCHEMA) { + if (state != SQLITE_OK) { sqlite3_finalize(db_statement); res->drvResultSet = (void *)NULL; @@ -538,7 +535,7 @@ RS_DBI_errorMessage(buf, RS_DBI_ERROR); } - if (db_statement == NULL && state != SQLITE_SCHEMA){ + if (db_statement == NULL){ char *message = "nothing to execute"; RS_SQLite_setException(con, 0, message); RS_DBI_freeResultSet(rsHandle); @@ -569,9 +566,8 @@ } else { /* if no bind parameters exist, we directly execute the query */ if (bind_count == 0) { - if (state != SQLITE_SCHEMA) { - state = corrected_sqlite3_step(db_statement); - if (state != SQLITE_DONE && state != SQLITE_SCHEMA) { + state = sqlite3_step(db_statement); + if (state != SQLITE_DONE) { char errMsg[2048]; sprintf(errMsg, "RS_SQLite_exec: could not execute1: %s", sqlite3_errmsg(db_connection)); @@ -582,7 +578,6 @@ RS_DBI_freeResultSet(rsHandle); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); } - } } else { char bindingErrorMsg[2048]; @@ -634,7 +629,7 @@ string, -1, SQLITE_TRANSIENT); break; } - if (state != SQLITE_OK && state != SQLITE_SCHEMA) { + if (state != SQLITE_OK) { char errMsg[2048]; sprintf(errMsg, "RS_SQLite_exec: could not bind data: %s", sqlite3_errmsg(db_connection)); @@ -649,8 +644,8 @@ } /* execute the statement */ - state = corrected_sqlite3_step(db_statement); - if (state != SQLITE_DONE && state != SQLITE_SCHEMA) { + state = sqlite3_step(db_statement); + if (state != SQLITE_DONE) { char errMsg[2048]; sprintf(errMsg, "RS_SQLite_exec: could not execute: %s", sqlite3_errmsg(db_connection)); @@ -665,7 +660,7 @@ /* reset the bind parameters */ state = sqlite3_reset(db_statement); - if (state != SQLITE_OK && state != SQLITE_SCHEMA) { + if (state != SQLITE_OK) { char errMsg[2048]; sprintf(errMsg, "RS_SQLite_exec: could not reset statement: %s", sqlite3_errmsg(db_connection)); @@ -689,7 +684,6 @@ res->rowsAffected = (Sint) sqlite3_changes(db_connection); RS_SQLite_setException(con, state, "OK"); } - } while (state == SQLITE_SCHEMA); return rsHandle; } @@ -910,52 +904,6 @@ return flds; } -/* Given a DBI resultset handle, call corrected_sqlite3_step once - handling the SQLITE_SCHEMA state indicating that the query needs to - be prepared again. This will occur when the DB schema has - changed. */ -static int single_step_with_reprepare(SEXP rsHandle) -{ - int state, done = 0, reprepare = 0; - RS_DBI_connection *con; - RS_DBI_resultSet *res; - sqlite3 *db_connection; - sqlite3_stmt *db_statement; - - res = RS_DBI_getResultSet(rsHandle); - db_statement = (sqlite3_stmt *)res->drvResultSet; - if (db_statement == NULL) { - RSQLITE_MSG("corrupt SQLite resultSet, missing statement handle", - RS_DBI_ERROR); - } - while (!done) { - if (reprepare) { - con = RS_DBI_getConnection(rsHandle); - db_connection = (sqlite3 *) con->drvConnection; - sqlite3_finalize(db_statement); - res->drvResultSet = (void *)NULL; - state = sqlite3_prepare(db_connection, res->statement, -1, - &db_statement, NULL); - res->drvResultSet = db_statement; - } - state = corrected_sqlite3_step(db_statement); - if (state != SQLITE_ROW && state != SQLITE_DONE - && state != SQLITE_SCHEMA) { - char errMsg[2048]; - (void)sprintf(errMsg, "RS_SQLite_fetch: failed first step: %s", - sqlite3_errmsg(sqlite3_db_handle(db_statement))); - RSQLITE_MSG(errMsg, RS_DBI_ERROR); - } - if (state == SQLITE_SCHEMA) - reprepare = 1; - else { - reprepare = 0; - done = 1; - } - } - return state; -} - /* Fills the output VECSXP with one row of data from the resultset */ static void fill_one_row(sqlite3_stmt *db_statement, SEXP output, int row_idx, @@ -1034,8 +982,20 @@ if (res->completed == 1) return R_NilValue; - state = single_step_with_reprepare(rsHandle); + db_statement = (sqlite3_stmt *)res->drvResultSet; + if (db_statement == NULL) { + RSQLITE_MSG("corrupt SQLite resultSet, missing statement handle", + RS_DBI_ERROR); + } + state = sqlite3_step(db_statement); + if (state != SQLITE_ROW && state != SQLITE_DONE) { + char errMsg[2048]; + (void)sprintf(errMsg, "RS_SQLite_fetch: failed first step: %s", + sqlite3_errmsg(sqlite3_db_handle(db_statement))); + RSQLITE_MSG(errMsg, RS_DBI_ERROR); + } + if (!res->fields) { if (!(res->fields = RS_SQLite_createDataMappings(rsHandle))) { RSQLITE_MSG("corrupt SQLite resultSet, missing fieldDescription", @@ -1053,7 +1013,6 @@ PROTECT(output = NEW_LIST((Sint) num_fields)); RS_DBI_allocOutput(output, flds, num_rec, 0); - db_statement = (sqlite3_stmt *)res->drvResultSet; while (state != SQLITE_DONE) { fill_one_row(db_statement, output, row_idx, flds); row_idx++; @@ -1065,7 +1024,7 @@ else break; /* okay, no more fetching for now */ } - state = corrected_sqlite3_step(db_statement); + state = sqlite3_step(db_statement); if (state != SQLITE_ROW && state != SQLITE_DONE) { char errMsg[2048]; (void)sprintf(errMsg, "RS_SQLite_fetch: failed: %s", @@ -1136,7 +1095,7 @@ RS_DBI_ERROR); } - state = corrected_sqlite3_step(db_statement); + state = sqlite3_step(db_statement); row_idx = 0; if(state!=SQLITE_ROW && state!=SQLITE_DONE){ char errMsg[2048]; @@ -1218,7 +1177,7 @@ else break; /* okay, no more fetching for now */ } - state = corrected_sqlite3_step(db_statement); + state = sqlite3_step(db_statement); if (state != SQLITE_ROW && state != SQLITE_DONE) { char errMsg[2048]; (void)sprintf(errMsg, "RS_SQLite_fetch: failed: %s", @@ -1585,9 +1544,9 @@ zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); if( zSql==0 ) return 0; nByte = strlen(zSql); - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); sqlite3_free(zSql); - if (rc != SQLITE_OK && rc != SQLITE_SCHEMA) { + if (rc != SQLITE_OK) { sqlite3_finalize(pStmt); (void) sprintf(errMsg, "RS_sqlite_import: %s", sqlite3_errmsg(db)); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); @@ -1607,9 +1566,9 @@ } zSql[j++] = ')'; zSql[j] = 0; - rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); free(zSql); - if (rc != SQLITE_OK && rc != SQLITE_SCHEMA) { + if (rc != SQLITE_OK) { sqlite3_finalize(pStmt); (void) sprintf(errMsg, "RS_sqlite_import: %s", sqlite3_errmsg(db)); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); @@ -1656,8 +1615,8 @@ } } - rc = corrected_sqlite3_step(pStmt); - if (rc != SQLITE_DONE && rc != SQLITE_SCHEMA) { + rc = sqlite3_step(pStmt); + if (rc != SQLITE_DONE) { sqlite3_finalize(pStmt); (void) sprintf(errMsg, "RS_sqlite_import: %s", sqlite3_errmsg(db)); RS_DBI_errorMessage(errMsg, RS_DBI_ERROR); @@ -1665,7 +1624,7 @@ rc = sqlite3_reset(pStmt); free(zLine); zLine = NULL; - if (rc != SQLITE_OK && rc != SQLITE_SCHEMA) { + if (rc != SQLITE_OK) { sqlite3_finalize(pStmt); (void) sprintf(errMsg,"RS_sqlite_import: %s", sqlite3_errmsg(db)); zCommit = "ROLLBACK"; @@ -1739,13 +1698,3 @@ return buf; } - -/* from http://www.sqlite.org/capi3ref.html#sqlite3_step */ -int corrected_sqlite3_step(sqlite3_stmt *pStatement){ - int rc; - rc = sqlite3_step(pStatement); - if( rc==SQLITE_ERROR ){ - rc = sqlite3_reset(pStatement); - } - return rc; -}