/// <summary> /// Initializes a command with the given SQL, connection and transaction /// </summary> /// <param name="commandText">The SQL command text</param> /// <param name="connection">The connection to associate with the command</param> /// <param name="transaction">The transaction the command should be associated with</param> public SQLiteCommand(string commandText, SQLiteConnection connection, SQLiteTransaction transaction) { _commandTimeout = 30; _parameterCollection = new SQLiteParameterCollection(this); _designTimeVisible = true; _updateRowSource = UpdateRowSource.None; if (commandText != null) { CommandText = commandText; } if (connection != null) { DbConnection = connection; _commandTimeout = connection.DefaultTimeout; } if (transaction != null) { Transaction = transaction; } SQLiteConnection.OnChanged(connection, new ConnectionEventArgs( SQLiteConnectionEventType.NewCommand, null, transaction, this, null, null, null, null)); }
/////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Creates a <see cref="SQLiteBlob" /> object. This will not work /// for tables that were created WITHOUT ROWID. /// </summary> /// <param name="connection"> /// The connection to use when opening the blob object. /// </param> /// <param name="databaseName"> /// The name of the database containing the blob object. /// </param> /// <param name="tableName"> /// The name of the table containing the blob object. /// </param> /// <param name="columnName"> /// The name of the column containing the blob object. /// </param> /// <param name="rowId"> /// The integer identifier for the row associated with the desired /// blob object. /// </param> /// <param name="readOnly"> /// Non-zero to open the blob object for read-only access. /// </param> /// <returns> /// The newly created <see cref="SQLiteBlob" /> instance -OR- null /// if an error occurs. /// </returns> public static SQLiteBlob Create( SQLiteConnection connection, string databaseName, string tableName, string columnName, long rowId, bool readOnly ) { if (connection == null) { throw new ArgumentNullException("connection"); } SQLite3 sqlite3 = connection._sql as SQLite3; if (sqlite3 == null) { throw new InvalidOperationException("Connection has no wrapper"); } SQLiteConnectionHandle handle = sqlite3._sql; if (handle == null) { throw new InvalidOperationException("Connection has an invalid handle."); } SQLiteBlobHandle blob = null; try { // do nothing. } finally /* NOTE: Thread.Abort() protection. */ { IntPtr ptrBlob = IntPtr.Zero; SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_blob_open( handle, SQLiteConvert.ToUTF8(databaseName), SQLiteConvert.ToUTF8(tableName), SQLiteConvert.ToUTF8( columnName), rowId, readOnly ? 0 : 1, ref ptrBlob); if (rc != SQLiteErrorCode.Ok) { throw new SQLiteException(rc, null); } blob = new SQLiteBlobHandle(handle, ptrBlob); } SQLiteConnection.OnChanged(connection, new ConnectionEventArgs( SQLiteConnectionEventType.NewCriticalHandle, null, null, null, null, blob, null, new object[] { typeof(SQLiteBlob), databaseName, tableName, columnName, rowId, readOnly })); return(new SQLiteBlob(sqlite3, blob)); }
internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool) { // // NOTE: If the database connection is currently open, attempt to // close it now. This must be done because the file name or // other parameters that may impact the underlying database // connection may have changed. // if (_sql != null) { Close(true); } // // NOTE: If the connection was not closed successfully, throw an // exception now. // if (_sql != null) { throw new SQLiteException("connection handle is still active"); } _usePool = usePool; _fileName = strFilename; if (usePool) { _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Open16 (Pool): {0}", (_sql != null) ? _sql.ToString() : "<null>")); #endif } if (_sql == null) { try { // do nothing. } finally /* NOTE: Thread.Abort() protection. */ { IntPtr db = IntPtr.Zero; SQLiteErrorCode n; #if !SQLITE_STANDARD if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions) { n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), openFlags, ref db); } else #endif { // // NOTE: This flag check is designed to enforce the constraint that opening // a database file that does not already exist requires specifying the // "Create" flag, even when a native API is used that does not accept // a flags parameter. // if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename)) { throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename); } n = UnsafeNativeMethods.sqlite3_open16(strFilename, ref db); } #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("Open16: {0}", db)); #endif if (n != SQLiteErrorCode.Ok) { throw new SQLiteException(n, null); } _sql = new SQLiteConnectionHandle(db, true); } lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ } SQLiteConnection.OnChanged(null, new ConnectionEventArgs( SQLiteConnectionEventType.NewCriticalHandle, null, null, null, null, _sql, strFilename, new object[] { strFilename, connectionFlags, openFlags, maxPoolSize, usePool })); } // Bind functions to this connection. If any previous functions of the same name // were already bound, then the new bindings replace the old. if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions) { if (_functions == null) { _functions = new List <SQLiteFunction>(); } _functions.AddRange(new List <SQLiteFunction>(SQLiteFunction.BindFunctions(this, connectionFlags))); } SetTimeout(0); GC.KeepAlive(_sql); }
internal override void Open(string strFilename, string vfsName, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool) { // // NOTE: If the database connection is currently open, attempt to // close it now. This must be done because the file name or // other parameters that may impact the underlying database // connection may have changed. // if (_sql != null) { Close(false); } // // NOTE: If the connection was not closed successfully, throw an // exception now. // if (_sql != null) { throw new SQLiteException("connection handle is still active"); } _usePool = usePool; _fileName = strFilename; _flags = connectionFlags; if (usePool) { _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion); SQLiteConnection.OnChanged(null, new ConnectionEventArgs( SQLiteConnectionEventType.OpenedFromPool, null, null, null, null, _sql, strFilename, new object[] { typeof(SQLite3_UTF16), strFilename, vfsName, connectionFlags, openFlags, maxPoolSize, usePool, _poolVersion })); #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(HelperMethods.StringFormat( CultureInfo.CurrentCulture, "Open16 (Pool): {0}", HandleToString())); #endif } if (_sql == null) { try { // do nothing. } finally /* NOTE: Thread.Abort() protection. */ { IntPtr db = IntPtr.Zero; SQLiteErrorCode n; int extFuncs = HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoExtensionFunctions) ? 0 : 1; #if !SQLITE_STANDARD if ((vfsName != null) || (extFuncs != 0)) { n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), ToUTF8(vfsName), openFlags, extFuncs, ref db); } else #endif { // // NOTE: This flag check is designed to enforce the constraint that opening // a database file that does not already exist requires specifying the // "Create" flag, even when a native API is used that does not accept // a flags parameter. // if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename)) { throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename); } if (vfsName != null) { throw new SQLiteException(SQLiteErrorCode.CantOpen, HelperMethods.StringFormat( CultureInfo.CurrentCulture, "cannot open using UTF-16 and VFS \"{0}\": need interop assembly", vfsName)); } n = UnsafeNativeMethods.sqlite3_open16(strFilename, ref db); } #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(HelperMethods.StringFormat( CultureInfo.CurrentCulture, "Open16: {0}", db)); #endif if (n != SQLiteErrorCode.Ok) { throw new SQLiteException(n, null); } _sql = new SQLiteConnectionHandle(db, true); } lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ } SQLiteConnection.OnChanged(null, new ConnectionEventArgs( SQLiteConnectionEventType.NewCriticalHandle, null, null, null, null, _sql, strFilename, new object[] { typeof(SQLite3_UTF16), strFilename, vfsName, connectionFlags, openFlags, maxPoolSize, usePool })); } // Bind functions to this connection. If any previous functions of the same name // were already bound, then the new bindings replace the old. if (!HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoBindFunctions)) { if (_functions == null) { _functions = new Dictionary <SQLiteFunctionAttribute, SQLiteFunction>(); } foreach (KeyValuePair <SQLiteFunctionAttribute, SQLiteFunction> pair in SQLiteFunction.BindFunctions(this, connectionFlags)) { _functions[pair.Key] = pair.Value; } } SetTimeout(0); GC.KeepAlive(_sql); }
/////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Disposes of the command and clears all member variables /// </summary> /// <param name="disposing">Whether or not the class is being explicitly or implicitly disposed</param> protected override void Dispose(bool disposing) { SQLiteConnection.OnChanged(_cnn, new ConnectionEventArgs( SQLiteConnectionEventType.DisposingCommand, null, _transaction, this, null, null, null, new object[] { disposing, disposed })); bool skippedDispose = false; try { if (!disposed) { if (disposing) { //////////////////////////////////// // dispose managed resources here... //////////////////////////////////// // If a reader is active on this command, don't destroy the command, instead let the reader do it SQLiteDataReader reader = null; if (_activeReader != null) { try { reader = _activeReader.Target as SQLiteDataReader; } catch (InvalidOperationException) { } } if (reader != null) { reader._disposeCommand = true; _activeReader = null; skippedDispose = true; return; } Connection = null; _parameterCollection.Clear(); _commandText = null; } ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// } } finally { if (!skippedDispose) { base.Dispose(disposing); // // NOTE: Everything should be fully disposed at this point. // disposed = true; } } }
/////////////////////////////////////////////////////////////////////////////////////////////// #region Static "Factory" Methods /// <summary> /// Creates a <see cref="SQLiteBlob" /> object. This will not work /// for tables that were created WITHOUT ROWID -OR- if the query /// does not include the "rowid" column or one of its aliases -OR- /// if the <see cref="SQLiteDataReader" /> was not created with the /// <see cref="CommandBehavior.KeyInfo" /> flag. /// </summary> /// <param name="dataReader"> /// The <see cref="SQLiteDataReader" /> instance with a result set /// containing the desired blob column. /// </param> /// <param name="i"> /// The index of the blob column. /// </param> /// <param name="readOnly"> /// Non-zero to open the blob object for read-only access. /// </param> /// <returns> /// The newly created <see cref="SQLiteBlob" /> instance -OR- null /// if an error occurs. /// </returns> public static SQLiteBlob Create( SQLiteDataReader dataReader, int i, bool readOnly ) { SQLiteConnection connection = SQLiteDataReader.GetConnection( dataReader); if (connection == null) { throw new InvalidOperationException("Connection not available"); } SQLite3 sqlite3 = connection._sql as SQLite3; if (sqlite3 == null) { throw new InvalidOperationException("Connection has no wrapper"); } SQLiteConnectionHandle handle = sqlite3._sql; if (handle == null) { throw new InvalidOperationException("Connection has an invalid handle."); } long?rowId = dataReader.GetRowId(i); if (rowId == null) { throw new InvalidOperationException("No RowId is available"); } SQLiteBlobHandle blob = null; try { // do nothing. } finally /* NOTE: Thread.Abort() protection. */ { IntPtr ptrBlob = IntPtr.Zero; SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_blob_open( sqlite3._sql, SQLiteConvert.ToUTF8( dataReader.GetDatabaseName(i)), SQLiteConvert.ToUTF8( dataReader.GetTableName(i)), SQLiteConvert.ToUTF8( dataReader.GetName(i)), (long)rowId, readOnly ? 0 : 1, ref ptrBlob); if (rc != SQLiteErrorCode.Ok) { throw new SQLiteException(rc, null); } blob = new SQLiteBlobHandle(handle, ptrBlob); } SQLiteConnection.OnChanged(null, new ConnectionEventArgs( SQLiteConnectionEventType.NewCriticalHandle, null, null, null, dataReader, blob, null, new object[] { typeof(SQLiteBlob), dataReader, i, readOnly })); return(new SQLiteBlob(sqlite3, blob)); }