internal static void ResetConnection(SqliteConnectionHandle db) { lock (_lock) { IntPtr stmt = IntPtr.Zero; do { stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt); if (stmt != IntPtr.Zero) { #if !SQLITE_STANDARD UnsafeNativeMethods.sqlite3_reset_interop(stmt); #else UnsafeNativeMethods.sqlite3_reset(stmt); #endif } } while (stmt != IntPtr.Zero); // Not overly concerned with the return value from a rollback. UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt); // but free the error message if any! if (stmt != IntPtr.Zero) { UnsafeNativeMethods.sqlite3_free(stmt); } } }
internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool) { if (_sql != null) { return; } _usePool = usePool; if (usePool) { _fileName = strFilename; _sql = SqliteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); } if (_sql == null) { if ((flags & SQLiteOpenFlagsEnum.Create) == 0 && FileExists(strFilename) == false) { throw new SqliteException((int)SQLiteErrorCode.CantOpen, strFilename); } SqliteConnectionHandle db; int n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, string.Empty); if (n > 0) { throw new SqliteException(n, null); } _sql = db; } // Bind functions to this connection. If any previous functions of the same name // were already bound, then the new bindings replace the old. _functionsArray = SqliteFunction.BindFunctions(this); SetTimeout(0); }
/// <summary> /// Clears out all pooled connections and rev's up the default pool version to force all old active objects /// not in the pool to get discarded rather than returned to their pools. /// </summary> internal static void ClearAllPools() { lock (_connections) { foreach (KeyValuePair <string, Pool> pair in _connections) { while (pair.Value.Queue.Count > 0) { WeakReference cnn = pair.Value.Queue.Dequeue(); SqliteConnectionHandle hdl = cnn.Target as SqliteConnectionHandle; if (hdl != null) { hdl.Dispose(); } } // Keep track of the highest revision so we can go one higher when we're finished if (_poolVersion <= pair.Value.PoolVersion) { _poolVersion = pair.Value.PoolVersion + 1; } } // All pools are cleared and we have a new highest version number to force all old version active items to get discarded // instead of going back to the queue when they are closed. // We can get away with this because we're pumped up the _poolVersion out of range of all active connections, so they // will all get discarded when they try to put themselves back in their pool. _connections.Clear(); } }
// These statics are here for lack of a better place to put them. // They exist here because they are called during the finalization of // a SqliteStatementHandle, SqliteConnectionHandle, and SqliteFunctionCookieHandle. // Therefore these functions have to be static, and have to be low-level. internal static string SQLiteLastError(SqliteConnectionHandle db) { #if !SQLITE_STANDARD int len; return(UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len)); #else return(UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1)); #endif }
internal static void Dispose(this SqliteConnectionHandle connection) { try { SQLiteBase.CloseConnection(connection); } catch (SqliteException) { } }
internal static void CloseConnection(SqliteConnectionHandle db) { lock (_lock) { ResetConnection(db); int n = UnsafeNativeMethods.sqlite3_close(db); if (n > 0) { throw new SqliteException(n, SQLiteLastError(db)); } } }
// It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SqliteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. internal override void Close() { if (_sql != null) { if (_usePool) { SQLiteBase.ResetConnection(_sql); SqliteConnectionPool.Add(_fileName, _sql, _poolVersion); } else _sql.Dispose(); } _sql = null; }
internal static void CloseConnection(SqliteConnectionHandle db) { lock (_lock) { #if !SQLITE_STANDARD int n = UnsafeNativeMethods.sqlite3_close_interop(db); #else ResetConnection(db); int n = UnsafeNativeMethods.sqlite3_close(db); #endif if (n > 0) { throw new SqliteException(n, SQLiteLastError(db)); } } }
internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool) { if (_sql != null) { return; } _usePool = usePool; if (usePool) { _fileName = strFilename; _sql = SqliteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); } if (_sql == null) { IntPtr db; #if !SQLITE_STANDARD int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), (int)flags, out db); #else // Compatibility with versions < 3.5.0 int n; if (UnsafeNativeMethods.use_sqlite3_open_v2) { n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero); } else { Console.WriteLine("Your sqlite3 version is old - please upgrade to at least v3.5.0!"); n = UnsafeNativeMethods.sqlite3_open(ToUTF8(strFilename), out db); } #endif if (n > 0) { throw new SqliteException(n, null); } _sql = db; } // Bind functions to this connection. If any previous functions of the same name // were already bound, then the new bindings replace the old. _functionsArray = SqliteFunction.BindFunctions(this); SetTimeout(0); }
// It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SqliteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. internal override void Close() { if (_sql != null) { if (_usePool) { SQLiteBase.ResetConnection(_sql); SqliteConnectionPool.Add(_fileName, _sql, _poolVersion); } else { _sql.Dispose(); } } _sql = null; }
/// <summary> /// Return a connection to the pool for someone else to use. /// </summary> /// <param name="fileName">The filename of the pool to use</param> /// <param name="hdl">The connection handle to pool</param> /// <param name="version">The pool version the handle was created under</param> /// <remarks> /// If the version numbers don't match between the connection and the pool, then the handle is discarded. /// </remarks> internal static void Add(string fileName, SqliteConnectionHandle hdl, int version) { lock (_connections) { // If the queue doesn't exist in the pool, then it must've been cleared sometime after the connection was created. Pool queue; if (_connections.TryGetValue(fileName, out queue) == true && version == queue.PoolVersion) { ResizePool(queue, true); queue.Queue.Enqueue(new WeakReference(hdl, false)); GC.KeepAlive(hdl); } else { hdl.Dispose(); } } }
// It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SqliteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. internal override void Close() { if (_sql != null) { if (_usePool) { SQLiteBase.ResetConnection(_sql); SqliteConnectionPool.Add(_fileName, _sql, _poolVersion); } else _sql.Dispose(); } _sql = null; #if MONOTOUCH if (gch.IsAllocated) gch.Free (); #endif }
internal static void ResetConnection(SqliteConnectionHandle db) { lock (_lock) { SqliteStatementHandle stmt = null; do { stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt); if (stmt != null) { UnsafeNativeMethods.sqlite3_reset(stmt); } } while (stmt != null); // Not overly concerned with the return value from a rollback. string msg = null; UnsafeNativeMethods.sqlite3_exec(db, "ROLLBACK", out msg); } }
private static void ResizePool(Pool queue, bool forAdding) { int target = queue.MaxPoolSize; if (forAdding && target > 0) { target--; } while (queue.Queue.Count > target) { WeakReference cnn = queue.Queue.Dequeue(); SqliteConnectionHandle hdl = cnn.Target as SqliteConnectionHandle; if (hdl != null) { hdl.Dispose(); } } }
/// <summary> /// Clear a given pool for a given filename. Discards anything in the pool for the given file, and revs the pool /// version so current active objects on the old version of the pool will get discarded rather than be returned to the pool. /// </summary> /// <param name="fileName">The filename of the pool to clear</param> internal static void ClearPool(string fileName) { lock (_connections) { Pool queue; if (_connections.TryGetValue(fileName, out queue) == true) { queue.PoolVersion++; while (queue.Queue.Count > 0) { WeakReference cnn = queue.Queue.Dequeue(); SqliteConnectionHandle hdl = cnn.Target as SqliteConnectionHandle; if (hdl != null) { hdl.Dispose(); } } } } }
/// <summary> /// Attempt to pull a pooled connection out of the queue for active duty /// </summary> /// <param name="fileName">The filename for a desired connection</param> /// <param name="maxPoolSize">The maximum size the connection pool for the filename can be</param> /// <param name="version">The pool version the returned connection will belong to</param> /// <returns>Returns NULL if no connections were available. Even if none are, the poolversion will still be a valid pool version</returns> internal static SqliteConnectionHandle Remove(string fileName, int maxPoolSize, out int version) { lock (_connections) { Pool queue; // Default to the highest pool version version = _poolVersion; // If we didn't find a pool for this file, create one even though it will be empty. // We have to do this here because otherwise calling ClearPool() on the file will not work for active connections // that have never seen the pool yet. if (_connections.TryGetValue(fileName, out queue) == false) { queue = new Pool(_poolVersion, maxPoolSize); _connections.Add(fileName, queue); return(null); } // We found a pool for this file, so use its version number version = queue.PoolVersion; queue.MaxPoolSize = maxPoolSize; ResizePool(queue, false); // Try and get a pooled connection from the queue while (queue.Queue.Count > 0) { WeakReference cnn = queue.Queue.Dequeue(); SqliteConnectionHandle hdl = cnn.Target as SqliteConnectionHandle; if (hdl != null) { return(hdl); } } return(null); } }
// It isn't necessary to cleanup any functions we've registered. If the connection // goes to the pool and is resurrected later, re-registered functions will overwrite the // previous functions. The SqliteFunctionCookieHandle will take care of freeing unmanaged // resources belonging to the previously-registered functions. internal override void Close() { if (_sql != null) { if (_usePool) { SQLiteBase.ResetConnection(_sql); SqliteConnectionPool.Add(_fileName, _sql, _poolVersion); } else { _sql.Dispose(); } } _sql = null; #if MONOTOUCH if (gch.IsAllocated) { gch.Free(); } #endif }
// These statics are here for lack of a better place to put them. // They exist here because they are called during the finalization of // a SqliteStatementHandle, SqliteConnectionHandle, and SqliteFunctionCookieHandle. // Therefore these functions have to be static, and have to be low-level. internal static string SQLiteLastError(SqliteConnectionHandle db) { return(UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1)); }
internal static void ResetConnection(SqliteConnectionHandle db) { lock (_lock) { IntPtr stmt = IntPtr.Zero; do { stmt = UnsafeNativeMethods.sqlite3_next_stmt(db, stmt); if (stmt != IntPtr.Zero) { #if !SQLITE_STANDARD UnsafeNativeMethods.sqlite3_reset_interop(stmt); #else UnsafeNativeMethods.sqlite3_reset(stmt); #endif } } while (stmt != IntPtr.Zero); // Not overly concerned with the return value from a rollback. UnsafeNativeMethods.sqlite3_exec(db, ToUTF8("ROLLBACK"), IntPtr.Zero, IntPtr.Zero, out stmt); } }
// These statics are here for lack of a better place to put them. // They exist here because they are called during the finalization of // a SqliteStatementHandle, SqliteConnectionHandle, and SqliteFunctionCookieHandle. // Therefore these functions have to be static, and have to be low-level. internal static string SQLiteLastError(SqliteConnectionHandle db) { #if !SQLITE_STANDARD int len; return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg_interop(db, out len), len); #else return UTF8ToString(UnsafeNativeMethods.sqlite3_errmsg(db), -1); #endif }
internal static void CloseConnection(SqliteConnectionHandle db) { lock (_lock) { #if !SQLITE_STANDARD int n = UnsafeNativeMethods.sqlite3_close_interop(db); #else ResetConnection(db); int n = UnsafeNativeMethods.sqlite3_close(db); #endif if (n > 0) throw new SqliteException(n, SQLiteLastError(db)); } }
/// <summary> /// Return a connection to the pool for someone else to use. /// </summary> /// <param name="fileName">The filename of the pool to use</param> /// <param name="hdl">The connection handle to pool</param> /// <param name="version">The pool version the handle was created under</param> /// <remarks> /// If the version numbers don't match between the connection and the pool, then the handle is discarded. /// </remarks> internal static void Add(string fileName, SqliteConnectionHandle hdl, int version) { lock (_connections) { // If the queue doesn't exist in the pool, then it must've been cleared sometime after the connection was created. Pool queue; if (_connections.TryGetValue(fileName, out queue) == true && version == queue.PoolVersion) { ResizePool(queue, true); queue.Queue.Enqueue(new WeakReference(hdl, false)); GC.KeepAlive(hdl); } else { hdl.Close(); } } }
internal SqliteStatementHandle(SqliteConnectionHandle cnn, IntPtr stmt) : this() { this._cnn = cnn; this.SetHandle(stmt); }
internal static void Close(this SqliteConnectionHandle connection) { connection.Dispose(); }
internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool) { if (_sql != null) return; _usePool = usePool; if (usePool) { _fileName = strFilename; _sql = SqliteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); } if (_sql == null) { IntPtr db; #if !SQLITE_STANDARD int n = UnsafeNativeMethods.sqlite3_open_interop(ToUTF8(strFilename), (int)flags, out db); #else // Compatibility with versions < 3.5.0 int n; try { n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), out db, (int)flags, IntPtr.Zero); } catch (EntryPointNotFoundException) { Console.WriteLine ("Your sqlite3 version is old - please upgrade to at least v3.5.0!"); n = UnsafeNativeMethods.sqlite3_open (ToUTF8 (strFilename), out db); } #endif if (n > 0) throw new SqliteException(n, null); _sql = db; } // Bind functions to this connection. If any previous functions of the same name // were already bound, then the new bindings replace the old. _functionsArray = SqliteFunction.BindFunctions(this); SetTimeout(0); }