void SQLiteQuery::BindValue(int index, const SQLiteValue& value) { if (!stmt) throw SQLiteError(SQL_ERRCODE_NO_INIT); if (!index) throw SQLiteError(SQL_ERRCODE_NO_PARAM); int result = 0; switch (value.type) { case TYPE_STRING: { ObjString& str = (ObjString&)*value.object; result = sqlite3_bind_text(stmt, index, str.GetValue(), -1, SQLITE_TRANSIENT); } break; case TYPE_WSTRING: { ObjWString& str = (ObjWString&)*value.object; result = sqlite3_bind_text16(stmt, index, str.GetValue(), -1, SQLITE_TRANSIENT); } break; case TYPE_INT: { ObjNumber& num = (ObjNumber&)value.object; result = sqlite3_bind_int(stmt, index, (int)num.GetValue()); }break; case TYPE_DOUBLE: { ObjNumber& num = (ObjNumber&)value.object; result = sqlite3_bind_double(stmt, index, num.GetValue()); }break; case TYPE_BLOB: { ObjBlob& blob = (ObjBlob&)value.object; size_t length; BYTE* data = blob.GetData(length); result = sqlite3_bind_blob(stmt, index, data, length, SQLITE_TRANSIENT); }break; } // Handle any errors switch (result) { case SQLITE_OK: break; default: throw SQLiteError(parent.LastError()); break; } }
bool SQLiteReader::next() { retry: switch(sqlite3_step(m_stmt)) { case SQLITE_DONE: return false; case SQLITE_ROW: return true; case SQLITE_BUSY: goto retry; case SQLITE_ERROR: case SQLITE_MISUSE: default: { std::ostringstream str; str << "SQLiteReader::next(): " << m_db.get_error_msg(); throw SQLiteError(str.str()); return false; } } }
void SQLiteQuery::prepare_statement() { // Get a statement handle, on failure abort. if (sqlite3_prepare_v2(parent.GetSQLite(), query, -1, &stmt, NULL) != SQLITE_OK) { throw SQLiteError(parent.LastError()); } }
std::unique_ptr<SQLiteResult> SQLiteQuery::Execute() { std::unique_ptr<SQLiteResult> out_result(new SQLiteResult()); char* err_info = query; while (1) { int result = sqlite3_step(stmt); if (result == SQLITE_DONE) break; if (result == SQLITE_ROW) { // data! /*if (!out_result) { // no data was expected error = SQL_ERRCODE_NDE; break; }*/ std::unique_ptr<SQLiteRow> row(new SQLiteRow()); int columns = sqlite3_column_count(stmt); for (int x = 0; x < columns; x++) { int type = sqlite3_column_type(stmt, x); const char* name = sqlite3_column_name(stmt, x); switch (type) { case SQLITE_INTEGER: row->AddColumn(Object::unique_ptr( new ObjNumber(sqlite3_column_int(stmt, x))), name); break; case SQLITE_FLOAT: row->AddColumn(Object::unique_ptr( new ObjNumber(sqlite3_column_double(stmt, x))), name); break; case SQLITE_TEXT: row->AddColumn(Object::unique_ptr( new ObjWString((const wchar_t*)sqlite3_column_text16(stmt, x))), name); break; case SQLITE_BLOB: row->AddColumn(Object::unique_ptr( new ObjBlob((BYTE*)sqlite3_column_blob(stmt, x), sqlite3_column_bytes(stmt, x))), name); break; } } out_result->AddRow(std::move(row)); } else { // error throw SQLiteError(parent.LastError()); } } sqlite3_finalize(stmt); stmt = NULL; return out_result; }
SQLiteReader::~SQLiteReader() { sqlite3_clear_bindings(m_stmt); if (sqlite3_reset(m_stmt) != SQLITE_OK) { std::ostringstream str; str << "~SQLiteReader():" << m_db.get_error_msg(); throw SQLiteError(str.str()); } }
//----------------------------------------------------------------------------------------- // Class: SQLite // SQLite::SQLite(const std::string& path_to_db) { int result = sqlite3_open(path_to_db.c_str(), &sqlhandle); if (result != SQLITE_OK) { // some error std::string desc = LastError(); sqlite3_close(sqlhandle); throw SQLiteError(desc.c_str()); } }
sqlite3* SQLite::GetSQLite() { if (!sqlhandle) throw SQLiteError(SQL_ERRCODE_CLOSED); return sqlhandle; }
void SQLiteQuery::BindValue(const char* name, const SQLiteValue& value) { if (!stmt) throw SQLiteError("invalid query state"); BindValue(sqlite3_bind_parameter_index(stmt, name), value); }