internal static sqlite3_stmt GetSqliteStatement(string sql, sqlite3 db) { sqlite3_stmt statement; int rc= raw.sqlite3_prepare_v2(db, sql, out statement); VerifySQLiteResponse(rc, raw.SQLITE_OK, db); return statement; }
internal static void Bind(sqlite3 db, sqlite3_stmt stm, int index, object value) { int rc = 0; if (value == null) { rc = raw.sqlite3_bind_null(stm, index); } else { if (IsSupportedInteger(value)) { rc = raw.sqlite3_bind_int64(stm, index, GetInteger(value)); } else if (IsSupportedFloat(value)) { rc = raw.sqlite3_bind_double(stm, index, GetFloat(value)); } else if (IsSupportedText(value)) { rc = raw.sqlite3_bind_text(stm, index, value.ToString()); } else if (value is byte[]) { rc = raw.sqlite3_bind_blob(stm, index, (byte[])value); } else { throw new SQLiteException("Unable to bind parameter with unsupported type: " + value.GetType().FullName); } } VerifySQLiteResponse(rc, raw.SQLITE_OK, db); }
internal static void VerifySQLiteResponse(int result, int expectedResult, sqlite3 db) { if (result != expectedResult) { string sqliteErrorMessage = raw.sqlite3_errmsg(db); throw new SQLiteException(string.Format("Error executing SQLite command: '{0}'.", sqliteErrorMessage)); } }
/// <summary> Sqlite 3 total changes. </summary> /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception> /// <exception cref="ArgumentException"> Thrown when one or more arguments have unsupported or /// illegal values. </exception> /// <param name="db"> The database. </param> /// <param name="isMaintenanceDb"> (Optional) True if this object is maintenance database. </param> /// <returns> An int. </returns> internal int sqlite3_total_changes(SqliteDatabaseHandle db, bool isMaintenanceDb = false) { if (db == null) { throw new ArgumentNullException(nameof(db)); } DbProvider.sqlite3 database = (isMaintenanceDb ? db.MaintenanceDb : db.Db) ?? throw new ArgumentException((isMaintenanceDb ? "Maintenance mode is specified, but the database is not in Maintenance Mode." : "The database is in Maintenance Mode, but this was not properly specified."), nameof(isMaintenanceDb)); return(DbProviderOperations.sqlite3_total_changes(database)); }
/// <summary> Handler, called when the sqlite 3 progress. </summary> /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception> /// <exception cref="ArgumentException"> Thrown when one or more arguments have unsupported or /// illegal values. </exception> /// <param name="db"> The database. </param> /// <param name="virtualMachineInstructions"> The virtual machine instructions. </param> /// <param name="func"> The function. </param> /// <param name="value"> The value. </param> /// <param name="isMaintenanceDb"> (Optional) True if this object is maintenance database. </param> internal void sqlite3_progress_handler(SqliteDatabaseHandle db, int virtualMachineInstructions, DbProvider.delegate_progress_handler func, object value, bool isMaintenanceDb = false) { if (db == null) { throw new ArgumentNullException(nameof(db)); } DbProvider.sqlite3 database = (isMaintenanceDb ? db.MaintenanceDb : db.Db) ?? throw new ArgumentException((isMaintenanceDb ? "Maintenance mode is specified, but the database is not in Maintenance Mode." : "The database is in Maintenance Mode, but this was not properly specified."), nameof(isMaintenanceDb)); DbProviderOperations.sqlite3_progress_handler(database, virtualMachineInstructions, func, value); }
/// <summary> Sqlite 3 busy timeout. </summary> /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception> /// <exception cref="ArgumentException"> Thrown when one or more arguments have unsupported or /// illegal values. </exception> /// <param name="db"> The database. </param> /// <param name="milliseconds"> The milliseconds. </param> /// <param name="isMaintenanceDb"> (Optional) True if this object is maintenance database. </param> /// <returns> A SqliteResultCode. </returns> internal SqliteResultCode sqlite3_busy_timeout(SqliteDatabaseHandle db, int milliseconds, bool isMaintenanceDb = false) { if (db == null) { throw new ArgumentNullException(nameof(db)); } DbProvider.sqlite3 database = (isMaintenanceDb ? db.MaintenanceDb : db.Db) ?? throw new ArgumentException((isMaintenanceDb ? "Maintenance mode is specified, but the database is not in Maintenance Mode." : "The database is in Maintenance Mode, but this was not properly specified."), nameof(isMaintenanceDb)); return((SqliteResultCode)DbProviderOperations.sqlite3_busy_timeout(database, milliseconds)); }
/// <summary> Sqlite 3 last insert rowid. </summary> /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception> /// <exception cref="ArgumentException"> Thrown when one or more arguments have unsupported or /// illegal values. </exception> /// <param name="db"> The database. </param> /// <param name="isMaintenanceDb"> (Optional) True if this object is maintenance database. </param> /// <returns> A long. </returns> internal long sqlite3_last_insert_rowid(SqliteDatabaseHandle db, bool isMaintenanceDb = false) { if (db == null) { throw new ArgumentNullException(nameof(db)); } lock (_stepLocker) { DbProvider.sqlite3 database = (isMaintenanceDb ? db.MaintenanceDb : db.Db) ?? throw new ArgumentException((isMaintenanceDb ? "Maintenance mode is specified, but the database is not in Maintenance Mode." : "The database is in Maintenance Mode, but this was not properly specified."), nameof(isMaintenanceDb)); return(DbProviderOperations.sqlite3_last_insert_rowid(database)); } }
/// <summary> /// Initializes a new instance of <see cref="MobileServiceSQLiteStore"/> /// </summary> /// <param name="fileName">Name of the local SQLite database file.</param> public MobileServiceSQLiteStore(string fileName) { if (fileName == null) { throw new ArgumentNullException("fileName"); } if (this.connection == null) { // Fully qualify the path var dbPath = fileName.StartsWith("/") ? fileName : Path.Combine(MobileServiceClient.DefaultDatabasePath, fileName); MobileServiceClient.EnsureFileExists(dbPath); this.connection = SQLitePCLRawHelpers.GetSqliteConnection(fileName); } }
static public int sqlite3_wal_checkpoint(sqlite3 db, string dbName) { return _imp.sqlite3_wal_checkpoint(db.ptr, dbName); }
static public int sqlite3_blob_open(sqlite3 db, string sdb, string table, string col, long rowid, int flags, out sqlite3_blob blob) { IntPtr p; int rc = _imp.sqlite3_blob_open(db.ptr, sdb, table, col, rowid, flags, out p); blob = new sqlite3_blob(p); return rc; }
static public sqlite3_stmt sqlite3_next_stmt(sqlite3 db, sqlite3_stmt stmt) { IntPtr prev = IntPtr.Zero; if (stmt != null) { prev = stmt.ptr; } IntPtr p = _imp.sqlite3_next_stmt(db.ptr, prev); if (p == IntPtr.Zero) { return null; } else { return db.find_stmt(p); } }
static public int sqlite3_exec(sqlite3 db, string sql) { string errmsg; return _imp.sqlite3_exec(db.ptr, sql, null, null, out errmsg); }
static public int sqlite3_prepare_v2(sqlite3 db, string sql, out sqlite3_stmt stmt, out string tail) { IntPtr p; int rc = _imp.sqlite3_prepare_v2(db.ptr, sql, out p, out tail); stmt = new sqlite3_stmt(p, db); return rc; }
static public int sqlite3_extended_errcode(sqlite3 db) { return _imp.sqlite3_extended_errcode(db.ptr); }
internal sqlite3_stmt(IntPtr p, sqlite3 db) { _p = p; _db = db; _db.add_stmt(this); }
void OpenSqliteConnection(int flags, SymmetricKey encryptionKey, out sqlite3 db) { LastErrorCode = raw.sqlite3_open_v2(Path, out db, flags, null); if (LastErrorCode != raw.SQLITE_OK) { Path = null; var errMessage = "Failed to open SQLite storage engine at path {0}".Fmt(Path); throw new CouchbaseLiteException(errMessage, StatusCode.DbError); } #if !__ANDROID__ && !NET_3_5 && VERBOSE var i = 0; var val = raw.sqlite3_compileoption_get(i); while (val != null) { Log.V(TAG, "Sqlite Config: {0}".Fmt(val)); val = raw.sqlite3_compileoption_get(++i); } #endif Log.D(TAG, "Open {0} (flags={1}{2})", Path, flags, (encryptionKey != null ? ", encryption key given" : "")); raw.sqlite3_create_collation(db, "JSON", null, CouchbaseSqliteJsonUnicodeCollationFunction.Compare); raw.sqlite3_create_collation(db, "JSON_ASCII", null, CouchbaseSqliteJsonAsciiCollationFunction.Compare); raw.sqlite3_create_collation(db, "JSON_RAW", null, CouchbaseSqliteJsonRawCollationFunction.Compare); raw.sqlite3_create_collation(db, "REVID", null, CouchbaseSqliteRevIdCollationFunction.Compare); }
private sqlite3_stmt BuildCommand(sqlite3 db, string sql, object[] paramArgs) { if (db == null) { throw new ArgumentNullException("db"); } sqlite3_stmt command = null; try { if (!IsOpen) { Open(Path); } lock(Cursor.StmtDisposeLock) { LastErrorCode = raw.sqlite3_prepare_v2(db, sql, out command); } if (LastErrorCode != raw.SQLITE_OK || command == null) { Log.E(TAG, "sqlite3_prepare_v2: " + LastErrorCode); } if (paramArgs != null && paramArgs.Length > 0 && command != null && LastErrorCode != raw.SQLITE_ERROR) { command.bind(paramArgs); } } catch (Exception e) { Log.E(TAG, "Error when build a sql " + sql + " with params " + paramArgs, e); throw; } return command; }
static public int sqlite3_create_function(sqlite3 db, string name, int nArg, object v, delegate_function_aggregate_step func_step, delegate_function_aggregate_final func_final) { return _imp.sqlite3_create_function(db.ptr, name, nArg, v, func_step, func_final); }
static public int sqlite3_extended_result_codes(sqlite3 db, int onoff) { return _imp.sqlite3_extended_result_codes(db.ptr, onoff); }
static public int sqlite3_db_status(sqlite3 db, int op, out int current, out int highest, int resetFlg) { return _imp.sqlite3_db_status(db.ptr, op, out current, out highest, resetFlg); }
static public int sqlite3_prepare_v2(sqlite3 db, string sql, out sqlite3_stmt stmt) { string tail; return sqlite3_prepare_v2(db, sql, out stmt, out tail); }
static public string sqlite3_errmsg(sqlite3 db) { return _imp.sqlite3_errmsg(db.ptr); }
static public int sqlite3_exec(sqlite3 db, string sql, delegate_exec callback, object user_data, out string errMsg) { return _imp.sqlite3_exec(db.ptr, sql, callback, user_data, out errMsg); }
static public int sqlite3_db_readonly(sqlite3 db, string dbName) { return _imp.sqlite3_db_readonly(db.ptr, dbName); }
static public int sqlite3_table_column_metadata(sqlite3 db, string dbName, string tblName, string colName, out string dataType, out string collSeq, out int notNull, out int primaryKey, out int autoInc) { return _imp.sqlite3_table_column_metadata(db.ptr, dbName, tblName, colName, out dataType, out collSeq, out notNull, out primaryKey, out autoInc); }
static public string sqlite3_db_filename(sqlite3 db, string att) { return _imp.sqlite3_db_filename(db.ptr, att); }
static public sqlite3_backup sqlite3_backup_init(sqlite3 destDb, string destName, sqlite3 sourceDb, string sourceName) { IntPtr p = _imp.sqlite3_backup_init(destDb.ptr, destName, sourceDb.ptr, sourceName); return new sqlite3_backup(p); }
static public long sqlite3_last_insert_rowid(sqlite3 db) { return _imp.sqlite3_last_insert_rowid(db.ptr); }
static public int sqlite3_wal_autocheckpoint(sqlite3 db, int n) { return _imp.sqlite3_wal_autocheckpoint(db.ptr, n); }
static public int sqlite3_total_changes(sqlite3 db) { return _imp.sqlite3_total_changes(db.ptr); }
static public int sqlite3_wal_checkpoint_v2(sqlite3 db, string dbName, int eMode, out int logSize, out int framesCheckPointed) { return _imp.sqlite3_wal_checkpoint_v2(db.ptr, dbName, eMode, out logSize, out framesCheckPointed); }
static public int sqlite3_get_autocommit(sqlite3 db) { return _imp.sqlite3_get_autocommit(db.ptr); }
static void Close(ref sqlite3 db) { if (db == null) { return; } var dbCopy = db; db = null; try { // Close any open statements, otherwise the // sqlite connection won't actually close. sqlite3_stmt next = null; while ((next = dbCopy.next_stmt(next))!= null) { next.Dispose(); } dbCopy.close(); } catch (KeyNotFoundException ex) { // Appears to be a bug in sqlite3.find_stmt. Concurrency issue in static dictionary? // Assuming we're done. Log.W(TAG, "Abandoning database close.", ex); } catch (ugly.sqlite3_exception ex) { Log.E(TAG, "Retrying database close.", ex); // Assuming a basic retry fixes this. Thread.Sleep(5000); dbCopy.close(); } GC.Collect(); GC.WaitForPendingFinalizers(); try { dbCopy.Dispose(); } catch (Exception ex) { Log.E(TAG, "Error while closing database.", ex); } }
static public int sqlite3_busy_timeout(sqlite3 db, int ms) { return _imp.sqlite3_busy_timeout(db.ptr, ms); }
private int ExecSQL(string sql, sqlite3 db, params object[] paramArgs) { var t = Factory.StartNew(()=> { sqlite3_stmt command = null; try { command = BuildCommand(db, sql, paramArgs); LastErrorCode = command.step(); if (LastErrorCode == SQLiteResult.ERROR) { throw new CouchbaseLiteException("SQLite error: " + raw.sqlite3_errmsg(db), StatusCode.DbError); } } catch (ugly.sqlite3_exception e) { Log.E(TAG, "Error {0}, {1} ({2}) executing sql '{3}'".Fmt(e.errcode, db.extended_errcode(), raw.sqlite3_errmsg(db), sql), e); LastErrorCode = e.errcode; throw new CouchbaseLiteException(String.Format("Error executing sql '{0}'", sql), e) { Code = StatusCode.DbError }; } finally { if(command != null) { command.Dispose(); } } }, _cts.Token); try { //FIXME.JHB: This wait should be optional (API change) t.Wait(30000, _cts.Token); } catch (AggregateException ex) { throw ex.InnerException; } catch (OperationCanceledException) { //Closing the storage engine will cause the factory to stop processing, but still //accept new jobs into the scheduler. If execution has gotten here, it means that //ExecSQL was called after Close, and the job will be ignored. Might consider //subclassing the factory to avoid this awkward behavior Log.D(TAG, "StorageEngine closed, canceling operation"); return 0; } if (t.Status != TaskStatus.RanToCompletion) { Log.E(TAG, "ExecSQL timed out waiting for Task #{0}", t.Id); throw new CouchbaseLiteException("ExecSQL timed out", StatusCode.InternalServerError); } return db.changes(); }
public static void Dispose2(this sqlite3 db) => sqlite3_close_v2(db);