static int tableExists(sqlite3* db, const char *tableName) { int res; int exists = 0; sqlite3_stmt *statement = NULL; statement = prepareStatement(db, "SELECT 1 FROM sqlite_master WHERE type='table' AND name=?"); res = sqlite3_bind_text(statement, 1, tableName, -1, SQLITE_STATIC); if (res != SQLITE_OK) sqlite_error(res, db, "table existence bind of name failed."); res = sqlite3_step(statement); switch(res) { case SQLITE_DONE: exists = 0; break; case SQLITE_ROW: exists = 1; break; default: sqlite_error(res, db, "select from sqlite_master failed."); } finalizeStatement(db, statement); return exists; }
sqlite3_stmt * Connection::prepare( const string &query, const AttributeList ¶meters ) { if( db_ == NULL ) throw ActiveRecordException( "Database not connected", __FILE__, __LINE__ ); sqlite3_stmt *ppStmt = 0; int prepare_result = sqlite3_prepare_v2( db_, query.c_str(), query.size(), &ppStmt, 0 ); if( prepare_result != SQLITE_OK ) { stringstream error; error << "SQL error: \"" << sqlite_error( prepare_result ) << "\" "; error << "in \"" << query << "\""; bool added = false; for( AttributeList::const_iterator it = parameters.begin(); it != parameters.end(); ++it ) { error << ", "; if( ! added ) error << "["; error << *it; added = true; } if( added ) error << "]"; log( error.str() ); throw ActiveRecordException( error.str(), __FILE__, __LINE__ ); } bind_parameters( ppStmt, parameters ); return ppStmt; }
static void closeDatabase(sqlite3 *db) { int res = sqlite3_close(db); if (res != SQLITE_OK) sqlite_error(res, db, "Closing database failed"); evlog(LOG_SOMETIMES, "Closed %s.", databaseName); }
static sqlite3 *openDatabase(void) { sqlite3 *db; int res; if (!databaseName) { databaseName = getenv(DATABASE_NAME_ENVAR); if(!databaseName) databaseName = DEFAULT_DATABASE_NAME; } if (deleteDatabase) { res = remove(databaseName); if (res) evlog(LOG_ALWAYS, "Could not remove database file %s", databaseName); else evlog(LOG_OFTEN, "Removed database file %s", databaseName); } res = sqlite3_open_v2(databaseName, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); /* use default sqlite_vfs object */ if (res != SQLITE_OK) sqlite_error(res, db, "Opening %s failed", databaseName); evlog(LOG_OFTEN, "Writing to %s.",databaseName); return db; }
static void finalizeStatement(sqlite3 *db, sqlite3_stmt *statement) { int res; res = sqlite3_finalize(statement); if (res != SQLITE_OK) sqlite_error(res, db, "statement finalize failed"); }
/** result_next : 'result -> object? <doc>Returns the next row in the result or [null] if no more result.</doc> **/ static value result_next( value v ) { int i; result *r; val_check_kind(v,k_result); r = val_result(v); if( r->done ) return val_null; switch( sqlite3_step(r->r) ) { case SQLITE_ROW: r->first = 0; v = alloc_object(NULL); for(i=0;i<r->ncols;i++) { value f; switch( sqlite3_column_type(r->r,i) ) { case SQLITE_NULL: f = val_null; break; case SQLITE_INTEGER: if( r->bools[i] ) f = alloc_bool(sqlite3_column_int(r->r,i)); else f = alloc_int(sqlite3_column_int(r->r,i)); break; case SQLITE_FLOAT: f = alloc_float(sqlite3_column_double(r->r,i)); break; case SQLITE_TEXT: f = alloc_string((char*)sqlite3_column_text(r->r,i)); break; case SQLITE_BLOB: { int size = sqlite3_column_bytes(r->r,i); f = alloc_empty_string(size); memcpy(val_string(f),sqlite3_column_blob(r->r,i),size); break; } default: { buffer b = alloc_buffer("Unknown Sqlite type #"); val_buffer(b,alloc_int(sqlite3_column_type(r->r,i))); val_throw(buffer_to_string(b)); } } alloc_field(v,r->names[i],f); } return v; case SQLITE_DONE: finalize_result(r,1); return val_null; case SQLITE_BUSY: val_throw(alloc_string("Database is busy")); case SQLITE_ERROR: sqlite_error(r->db->db); default: neko_error(); } return val_null; }
static void logFileCompleted(sqlite3 *db, int64 completed) { sqlite3_stmt *statement; int res; statement = prepareStatement(db, "UPDATE event_log SET completed=? WHERE serial=?"); res = sqlite3_bind_int64(statement, 2, logSerial); if (res != SQLITE_OK) sqlite_error(res, db, "event_log update bind of serial failed."); res = sqlite3_bind_int64(statement, 1, completed); if (res != SQLITE_OK) sqlite_error(res, db, "event_log update bind of completed failed."); res = sqlite3_step(statement); if (res != SQLITE_DONE) sqlite_error(res, db, "insert into event_log failed."); evlog(LOG_SOMETIMES, "Marked in event_log: %lu events", completed); finalizeStatement(db, statement); }
static void runStatement(sqlite3 *db, const char *sql, const char *description) { int res; evlog(LOG_SELDOM, "%s: %s", description, sql); res = sqlite3_exec(db, sql, NULL, /* No callback */ NULL, /* No callback closure */ NULL); /* error messages handled by sqlite_error */ if (res != SQLITE_OK) sqlite_error(res, db, "%s failed - statement %s", description, sql); }
static sqlite3_stmt *prepareStatement(sqlite3 *db, const char *sql) { int res; sqlite3_stmt *statement; evlog(LOG_SELDOM, "Preparing statement %s", sql); res = sqlite3_prepare_v2(db, sql, -1, /* prepare whole string as statement */ &statement, NULL); if (res != SQLITE_OK) sqlite_error(res, db, "statement preparation failed: %s", sql); return statement; }
static char *bind_real(sqlite3 *db, sqlite3_stmt *stmt, int64 count, int field, char *p) { char *q; double val; int res; while(*p == ' ') ++p; val = strtod(p, &q); if (q == p) error("event %llu field %d not a floating-point value: %s", count, field, p); res = sqlite3_bind_double(stmt, field, val); if (res != SQLITE_OK) sqlite_error(res, db, "event %llu field %d bind failed", count, field); return q; }
static char *bind_int(sqlite3 *db, sqlite3_stmt *stmt, int64 count, int field, char *p) { char *q; long long val; int res; while(*p == ' ') ++p; val = strtoll(p, &q, 16); if (q == p) error("event %llu field %d not an integer: %s", count, field, p); res = sqlite3_bind_int64(stmt, field, val); if (res != SQLITE_OK) sqlite_error(res, db, "event %llu field %d bind failed", count, field); return q; }
static char *bind_text(sqlite3 *db, sqlite3_stmt *stmt, int64 count, int field, char *p) { char *q; int res; while(*p == ' ') ++p; q = p; while((*q != '\n') && (*q != '\0')) { ++ q; } if ((q == p) || (q[-1] != '"')) error("event %llu string field %d has no closing quote mark.", count, field); res = sqlite3_bind_text(stmt, field, p, (int)(q-p-1), SQLITE_STATIC); if (res != SQLITE_OK) sqlite_error(res, db, "event %llu field %d bind failed", count, field); return q; }
static int64 readLog(FILE *input, sqlite3 *db) { int64 eventCount = 0; /* declare statements for every event type */ EVENT_LIST(EVENT_TYPE_DECLARE_STATEMENT, X); /* prepare statements for every event type */ EVENT_LIST(EVENT_TYPE_PREPARE_STATEMENT, X); runStatement(db, "BEGIN", "Transaction start"); while (TRUE) { /* loop for each event */ char line[MAX_LOG_LINE_LENGTH]; char *p; char *q; int last_index=0; sqlite3_stmt *statement = NULL; int res; int64 clock_field; long code; p = fgets(line, MAX_LOG_LINE_LENGTH, input); if (!p) { if (feof(input)) break; else error("Couldn't read line after event %llu", eventCount); } eventCount++; clock_field = strtoll(p, &q, 16); if (q == p) error("event %llu clock field not a hex integer: %s", eventCount, p); if (*q != ' ') error("event %llu code field not preceded by ' ': %s", eventCount, q); while(*q == ' ') ++q; p = q; code = strtol(p, &q, 16); if (q == p) error("event %llu code field not an integer: %s", eventCount, p); p = q; /* Write event to SQLite. */ switch (code) { /* this macro sets statement and last_index */ EVENT_LIST(EVENT_TYPE_WRITE_SQL, X); default: error("Event %llu has Unknown event code %d", eventCount, code); } /* bind the fields we store for every event */ \ res = sqlite3_bind_int64(statement, last_index+1, logSerial); if (res != SQLITE_OK) sqlite_error(res, db, "Event %llu bind of log_serial failed.", eventCount); res = sqlite3_bind_int64(statement, last_index+2, clock_field); if (res != SQLITE_OK) sqlite_error(res, db, "Event %llu bind of clock failed.", eventCount); res = sqlite3_step(statement); if (res != SQLITE_DONE) sqlite_error(res, db, "insert of event %llu failed.", eventCount); res = sqlite3_reset(statement); if (res != SQLITE_OK) sqlite_error(res, db, "Couldn't reset insert statement of event %llu", eventCount); if (progress) { if ((eventCount % SMALL_TICK) == 0) { printf("."); fflush(stdout); if (((eventCount / SMALL_TICK) % BIG_TICK) == 0) { printf("\n"); fflush(stdout); evlog(LOG_SOMETIMES, "%lu events.", (unsigned long)eventCount); } } } } if (progress) { printf("\n"); fflush(stdout); } runStatement(db, "COMMIT", "Transaction finish"); logFileCompleted(db, eventCount); /* finalize all the statements */ EVENT_LIST(EVENT_TYPE_FINALIZE_STATEMENT, X); return eventCount; }
static void registerLogFile(sqlite3 *db, const char *filename) { sqlite3_stmt *statement; int res; const unsigned char *name; int64 completed; int64 file_size; int64 file_modtime; if (filename) { struct stat st; res = stat(filename, &st); if (res != 0) error("Couldn't stat() %s", filename); file_size = st.st_size; file_modtime = st.st_mtime; statement = prepareStatement(db, "SELECT name, serial, completed FROM event_log" " WHERE size = ? AND modtime = ?"); res = sqlite3_bind_int64(statement, 1, file_size); if (res != SQLITE_OK) sqlite_error(res, db, "event_log bind of size failed."); res = sqlite3_bind_int64(statement, 2, file_modtime); if (res != SQLITE_OK) sqlite_error(res, db, "event_log bind of modtime failed."); res = sqlite3_step(statement); switch(res) { case SQLITE_DONE: evlog(LOG_SOMETIMES, "No log file matching '%s' found in database.", filename); break; case SQLITE_ROW: name = sqlite3_column_text(statement, 0); logSerial = sqlite3_column_int64(statement, 1); completed = sqlite3_column_int64(statement, 2); evlog(force ? LOG_OFTEN : LOG_ALWAYS, "Log file matching '%s' already in event_log, named \"%s\" (serial %lu, completed %lu).", filename, name, logSerial, completed); if (force) { evlog(LOG_OFTEN, "Continuing anyway because -f specified."); } else { evlog(LOG_ALWAYS, "Exiting. Specify -f to force events into SQL anyway."); exit(0); } break; default: sqlite_error(res, db, "select from event_log failed."); } finalizeStatement(db, statement); } else { /* stdin */ filename = "<stdin>"; file_size = 0; file_modtime = 0; } statement = prepareStatement(db, "INSERT into event_log (name, size, modtime, completed)" " VALUES (?, ?, ?, 0)"); res = sqlite3_bind_text(statement, 1, filename, -1, SQLITE_STATIC); if (res != SQLITE_OK) sqlite_error(res, db, "event_log insert bind of name failed."); res = sqlite3_bind_int64(statement, 2, file_size); if (res != SQLITE_OK) sqlite_error(res, db, "event_log insert bind of size failed."); res = sqlite3_bind_int64(statement, 3, file_modtime); if (res != SQLITE_OK) sqlite_error(res, db, "event_log insert bind of modtime failed."); res = sqlite3_step(statement); if (res != SQLITE_DONE) sqlite_error(res, db, "insert into event_log failed."); logSerial = sqlite3_last_insert_rowid(db); evlog(LOG_SOMETIMES, "Log file %s added to event_log with serial %lu", filename, logSerial); finalizeStatement(db, statement); }