/// <summary> /// Executes the supplied query and calls the callback function for each row of result /// </summary> /// <remarks> /// <p> /// If the database is busy (ie with another process/thread using it) then /// this method will call Thread.Sleep(), and then retry the query. Number of /// retries and retry delay are configurable using the appropriate properties.</p> /// <p>The result set object may be empty if there are no results, or if the /// query does not return results (eg. UPDATE, INSERT, DELETE etc)</p> /// </remarks> /// <param name="query">The SQL query to execute</param> /// <param name="callback">The callback function to call /// (object Param, string[] ColumnNames, ArrayList Data)</param> /// <param name="Param">A object to pass to the callback function</param> /// <exception cref="SQLiteException"> /// Thrown if an error occurs or if the database is busy and the retries /// are exhausted. /// </exception> public unsafe void Execute(string query, ResultCallBack callback, object Param) { column_names = null; //reset for each new query param = Param; callbackfunc = callback; ResultCode errorCode; string errorMsg; int retries = 0; using (SqliteString sql = new SqliteString(query)) { while ((errorCode = SQLiteClient.sqlite3_exec( this.dbHandle, sql.ToPointer(), (callbackfunc == null) ? null : new SQLiteCallback(CallBack), IntPtr.Zero, out errorMsg)) == ResultCode.BUSY && retries < this.busyRetries) { Thread.Sleep(this.busyRetryDelay); ++retries; continue; } if (errorCode != ResultCode.OK) { throw new SQLiteException(SQLiteClient.GetMessageForError(errorCode) + ":\n" + errorMsg + "\n the query string is :\n" + query, errorCode); } } }
/// <summary> /// Closes the database /// </summary> /// <remarks> /// If a transaction is active when the database is closed, the /// transaction is rolled back. /// </remarks> public void Close() { SQLiteClient.sqlite3_close(this.dbHandle); dbHandle = IntPtr.Zero; }
/// <summary> /// Interrupts the current database operation asap /// </summary> /// <remarks> /// The Interrupt() method can be called from a different thread /// or from a signal handler to cause the current database operation to /// exit at its first opportunity. When this happens, the Execute() /// method (or the equivalent) that started the database operation /// will throw an <see cref="SQLiteException">SQLiteException</see> /// with the <see cref="SQLiteException.ErrorCode">errorcode</see> set to INTERRUPT /// </remarks> public void Interrupt() { SQLiteClient.sqlite3_interrupt(this.dbHandle); }
/// <summary> /// Returns the number of rows changed since the database was last /// "quiescent". /// </summary> /// <remarks> /// <p>The ChangedRows() method returns the number of rows that /// have been inserted, deleted, or modified since the database was /// last quiescent. A "quiescent" database is one in which there are /// no outstanding calls to <see cref="SQLiteClient.Execute(string)">Execute</see>. /// In common usage, /// ChangedRows() returns the number of rows inserted, deleted, or /// modified by the most recent <see cref="SQLiteClient.Execute(string)">Execute</see> call. /// The number reported includes any /// changes that were later undone by a ROLLBACK or ABORT. But rows that /// are deleted because of a DROP TABLE are not counted.</p> /// /// <p>SQLite implements the command "DELETE FROM table" (without a WHERE /// clause) by dropping the table then recreating it. This is much faster /// than deleting the elements of the table individually. But it also means /// that the value returned from ChangedRows() will be zero regardless /// of the number of elements that were originally in the table. If an /// accurate count of the number of elements deleted is necessary, use /// "DELETE FROM table WHERE 1" instead.</p> /// </remarks> /// <returns>Integer of the number of changed rows</returns> public int ChangedRows() { return(SQLiteClient.sqlite3_changes(this.dbHandle)); }
/// <summary> /// Returns the last insert id for this database /// </summary> /// <remarks> /// <p>Every row of an SQLite table has a unique integer key. If the /// table has a column labeled INTEGER PRIMARY KEY, then that column /// serves as the key. If there is no INTEGER PRIMARY KEY column then /// the key is a unique integer. The key for a row can be accessed in a /// SELECT statement or used in a WHERE or ORDER BY clause using any of /// the names "ROWID", "OID", or "_ROWID_".</p> /// /// <p>When you do an insert into a table that does not have an /// INTEGER PRIMARY KEY column, or if the table does have an /// INTEGER PRIMARY KEY but the value for that column is not specified /// in the VALUES clause of the insert, then the key is automatically /// generated. You can find the value of the key for the most recent /// INSERT statement using the this method.</p> /// </remarks> /// <returns>Integer of the id</returns> public int LastInsertID() { return(SQLiteClient.sqlite3_last_insert_rowid(this.dbHandle)); }