/////////////////////////////////////////////////////////////////////// #region Static Table Lookup Methods /// <summary> /// Reads and returns the native pointer to the sqlite3_vtab derived /// structure based on the native pointer to the sqlite3_vtab_cursor /// derived structure. /// </summary> /// <param name="module"> /// The <see cref="SQLiteModule" /> object instance to be used. /// </param> /// <param name="pCursor"> /// The native pointer to the sqlite3_vtab_cursor derived structure /// from which to read the native pointer to the sqlite3_vtab derived /// structure. /// </param> /// <returns> /// The native pointer to the sqlite3_vtab derived structure -OR- /// <see cref="IntPtr.Zero" /> if it cannot be determined. /// </returns> private static IntPtr TableFromCursor( SQLiteModule module, IntPtr pCursor ) { if (pCursor == IntPtr.Zero) return IntPtr.Zero; return Marshal.ReadIntPtr(pCursor); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the /// existing error message, if any. /// </summary> /// <param name="module"> /// The <see cref="SQLiteModule" /> object instance to be used. /// </param> /// <param name="pCursor"> /// The native pointer to the sqlite3_vtab_cursor derived structure /// used to get the native pointer to the sqlite3_vtab derived /// structure. /// </param> /// <param name="logErrors"> /// Non-zero if this error message should also be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="logExceptions"> /// Non-zero if caught exceptions should be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="error"> /// The error message. /// </param> /// <returns> /// Non-zero upon success. /// </returns> private static bool SetCursorError( SQLiteModule module, IntPtr pCursor, bool logErrors, bool logExceptions, string error ) { if (pCursor == IntPtr.Zero) return false; IntPtr pVtab = TableFromCursor(module, pCursor); if (pVtab == IntPtr.Zero) return false; return SetTableError( module, pVtab, logErrors, logExceptions, error); }
/////////////////////////////////////////////////////////////////////// /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the /// existing error message, if any. /// </summary> /// <param name="module"> /// The <see cref="SQLiteModule" /> object instance to be used. /// </param> /// <param name="cursor"> /// The <see cref="SQLiteVirtualTableCursor" /> object instance used to /// lookup the native pointer to the sqlite3_vtab derived structure. /// </param> /// <param name="logErrors"> /// Non-zero if this error message should also be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="logExceptions"> /// Non-zero if caught exceptions should be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="error"> /// The error message. /// </param> /// <returns> /// Non-zero upon success. /// </returns> private static bool SetCursorError( SQLiteModule module, SQLiteVirtualTableCursor cursor, bool logErrors, bool logExceptions, string error ) { if (cursor == null) return false; IntPtr pCursor = cursor.NativeHandle; if (pCursor == IntPtr.Zero) return false; return SetCursorError( module, pCursor, logErrors, logExceptions, error); }
/////////////////////////////////////////////////////////////////////// #region Static Error Handling Helper Methods /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the /// existing error message, if any. /// </summary> /// <param name="module"> /// The <see cref="SQLiteModule" /> object instance to be used. /// </param> /// <param name="pVtab"> /// The native pointer to the sqlite3_vtab derived structure. /// </param> /// <param name="logErrors"> /// Non-zero if this error message should also be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="logExceptions"> /// Non-zero if caught exceptions should be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="error"> /// The error message. /// </param> /// <returns> /// Non-zero upon success. /// </returns> private static bool SetTableError( SQLiteModule module, IntPtr pVtab, bool logErrors, bool logExceptions, string error ) { try { if (logErrors) { SQLiteLog.LogMessage(SQLiteErrorCode.Error, String.Format(CultureInfo.CurrentCulture, "Virtual table error: {0}", error)); /* throw */ } } catch { // do nothing. } bool success = false; IntPtr pNewError = IntPtr.Zero; try { if (pVtab == IntPtr.Zero) return false; int offset = 0; offset = SQLiteMarshal.NextOffsetOf(offset, IntPtr.Size, sizeof(int)); offset = SQLiteMarshal.NextOffsetOf(offset, sizeof(int), IntPtr.Size); IntPtr pOldError = SQLiteMarshal.ReadIntPtr(pVtab, offset); if (pOldError != IntPtr.Zero) { SQLiteMemory.Free(pOldError); pOldError = IntPtr.Zero; SQLiteMarshal.WriteIntPtr(pVtab, offset, pOldError); } if (error == null) return true; pNewError = SQLiteString.Utf8IntPtrFromString(error); SQLiteMarshal.WriteIntPtr(pVtab, offset, pNewError); success = true; } catch (Exception e) /* NOTE: Must catch ALL. */ { try { if (logExceptions) { SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION, String.Format(CultureInfo.CurrentCulture, "Caught exception in \"SetTableError\" method: {0}", e)); /* throw */ } } catch { // do nothing. } } finally { if (!success && (pNewError != IntPtr.Zero)) { SQLiteMemory.Free(pNewError); pNewError = IntPtr.Zero; } } return success; }
/////////////////////////////////////////////////////////////////////// /// <summary> /// Arranges for the specified error message to be placed into the /// zErrMsg field of a sqlite3_vtab derived structure, freeing the /// existing error message, if any. /// </summary> /// <param name="module"> /// The <see cref="SQLiteModule" /> object instance to be used. /// </param> /// <param name="table"> /// The <see cref="SQLiteVirtualTable" /> object instance used to /// lookup the native pointer to the sqlite3_vtab derived structure. /// </param> /// <param name="logErrors"> /// Non-zero if this error message should also be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="logExceptions"> /// Non-zero if caught exceptions should be logged using the /// <see cref="SQLiteLog" /> class. /// </param> /// <param name="error"> /// The error message. /// </param> /// <returns> /// Non-zero upon success. /// </returns> private static bool SetTableError( SQLiteModule module, SQLiteVirtualTable table, bool logErrors, bool logExceptions, string error ) { if (table == null) return false; IntPtr pVtab = table.NativeHandle; if (pVtab == IntPtr.Zero) return false; return SetTableError( module, pVtab, logErrors, logExceptions, error); }
/////////////////////////////////////////////////////////////////// #region Public Constructors /// <summary> /// Constructs an instance of this class. /// </summary> /// <param name="module"> /// The <see cref="SQLiteModule" /> object instance used to provide /// an implementation of the <see cref="ISQLiteNativeModule" /> /// interface. /// </param> public SQLiteNativeModule( SQLiteModule module ) { this.module = module; }
/////////////////////////////////////////////////////////////////// /// <summary> /// Disposes of this object instance. /// </summary> /// <param name="disposing"> /// Non-zero if this method is being called from the /// <see cref="Dispose()" /> method. Zero if this method is being /// called from the finalizer. /// </param> private /* protected virtual */ void Dispose(bool disposing) { if (!disposed) { //if (disposing) //{ // //////////////////////////////////// // // dispose managed resources here... // //////////////////////////////////// //} ////////////////////////////////////// // release unmanaged resources here... ////////////////////////////////////// // // NOTE: The module is not owned by us; therefore, do not // dispose it. // if (module != null) module = null; disposed = true; } }
/// <summary> /// Calls the native SQLite core library in order to declare a virtual table /// in response to a call into the <see cref="ISQLiteNativeModule.xCreate" /> /// or <see cref="ISQLiteNativeModule.xConnect" /> virtual table methods. /// </summary> /// <param name="module"> /// The virtual table module that is to be responsible for the virtual table /// being declared. /// </param> /// <param name="strSql"> /// The string containing the SQL statement describing the virtual table to /// be declared. /// </param> /// <param name="error"> /// Upon success, the contents of this parameter are undefined. Upon failure, /// it should contain an appropriate error message. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> internal override SQLiteErrorCode DeclareVirtualTable( SQLiteModule module, string strSql, ref string error ) { if (_sql == null) { error = "connection has an invalid handle"; return SQLiteErrorCode.Error; } IntPtr pSql = IntPtr.Zero; try { pSql = SQLiteString.Utf8IntPtrFromString(strSql); SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_declare_vtab( _sql, pSql); if ((n == SQLiteErrorCode.Ok) && (module != null)) module.Declared = true; if (n != SQLiteErrorCode.Ok) error = GetLastError(); return n; } finally { if (pSql != IntPtr.Zero) { SQLiteMemory.Free(pSql); pSql = IntPtr.Zero; } } }
/// <summary> /// Calls the native SQLite core library in order to declare a virtual table /// function in response to a call into the <see cref="ISQLiteNativeModule.xCreate" /> /// or <see cref="ISQLiteNativeModule.xConnect" /> virtual table methods. /// </summary> /// <param name="module"> /// The virtual table module that is to be responsible for the virtual table /// function being declared. /// </param> /// <param name="argumentCount"> /// The number of arguments to the function being declared. /// </param> /// <param name="name"> /// The name of the function being declared. /// </param> /// <param name="error"> /// Upon success, the contents of this parameter are undefined. Upon failure, /// it should contain an appropriate error message. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> internal override SQLiteErrorCode DeclareVirtualFunction( SQLiteModule module, int argumentCount, string name, ref string error ) { if (_sql == null) { error = "connection has an invalid handle"; return SQLiteErrorCode.Error; } IntPtr pName = IntPtr.Zero; try { pName = SQLiteString.Utf8IntPtrFromString(name); SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_overload_function( _sql, pName, argumentCount); if (n != SQLiteErrorCode.Ok) error = GetLastError(); return n; } finally { if (pName != IntPtr.Zero) { SQLiteMemory.Free(pName); pName = IntPtr.Zero; } } }
/// <summary> /// Calls the native SQLite core library in order to cleanup the resources /// associated with a module containing the implementation of a virtual table. /// </summary> /// <param name="module"> /// The module object previously passed to the <see cref="CreateModule" /> /// method. /// </param> /// <param name="flags"> /// The flags for the associated <see cref="SQLiteConnection" /> object instance. /// </param> internal override void DisposeModule(SQLiteModule module, SQLiteConnectionFlags flags) { if (module == null) throw new ArgumentNullException("module"); module.Dispose(); }
/// <summary> /// Calls the native SQLite core library in order to create a disposable /// module containing the implementation of a virtual table. /// </summary> /// <param name="module"> /// The module object to be used when creating the native disposable module. /// </param> /// <param name="flags"> /// The flags for the associated <see cref="SQLiteConnection" /> object instance. /// </param> internal override void CreateModule(SQLiteModule module, SQLiteConnectionFlags flags) { if (module == null) throw new ArgumentNullException("module"); if ((flags & SQLiteConnectionFlags.NoLogModule) != SQLiteConnectionFlags.NoLogModule) { module.LogErrors = ((flags & SQLiteConnectionFlags.LogModuleError) == SQLiteConnectionFlags.LogModuleError); module.LogExceptions = ((flags & SQLiteConnectionFlags.LogModuleException) == SQLiteConnectionFlags.LogModuleException); } if (_sql == null) throw new SQLiteException("connection has an invalid handle"); SetLoadExtension(true); LoadExtension(UnsafeNativeMethods.SQLITE_DLL, "sqlite3_vtshim_init"); if (module.CreateDisposableModule(_sql)) { if (_modules == null) _modules = new Dictionary<string, SQLiteModule>(); _modules.Add(module.Name, module); if (_usePool) { _usePool = false; #if !NET_COMPACT_20 && TRACE_CONNECTION Trace.WriteLine(String.Format("CreateModule (Pool) Disabled: {0}", _sql)); #endif } } else { throw new SQLiteException(GetLastError()); } }
/// <summary> /// Calls the native SQLite core library in order to declare a virtual table /// function in response to a call into the <see cref="ISQLiteNativeModule.xCreate" /> /// or <see cref="ISQLiteNativeModule.xConnect" /> virtual table methods. /// </summary> /// <param name="module"> /// The virtual table module that is to be responsible for the virtual table /// function being declared. /// </param> /// <param name="argumentCount"> /// The number of arguments to the function being declared. /// </param> /// <param name="name"> /// The name of the function being declared. /// </param> /// <param name="error"> /// Upon success, the contents of this parameter are undefined. Upon failure, /// it should contain an appropriate error message. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> internal abstract SQLiteErrorCode DeclareVirtualFunction(SQLiteModule module, int argumentCount, string name, ref string error);
/// <summary> /// Calls the native SQLite core library in order to declare a virtual table /// in response to a call into the <see cref="ISQLiteNativeModule.xCreate" /> /// or <see cref="ISQLiteNativeModule.xConnect" /> virtual table methods. /// </summary> /// <param name="module"> /// The virtual table module that is to be responsible for the virtual table /// being declared. /// </param> /// <param name="strSql"> /// The string containing the SQL statement describing the virtual table to /// be declared. /// </param> /// <param name="error"> /// Upon success, the contents of this parameter are undefined. Upon failure, /// it should contain an appropriate error message. /// </param> /// <returns> /// A standard SQLite return code. /// </returns> internal abstract SQLiteErrorCode DeclareVirtualTable(SQLiteModule module, string strSql, ref string error);
/// <summary> /// Calls the native SQLite core library in order to cleanup the resources /// associated with a module containing the implementation of a virtual table. /// </summary> /// <param name="module"> /// The module object previously passed to the <see cref="CreateModule" /> /// method. /// </param> /// <param name="flags"> /// The flags for the associated <see cref="SQLiteConnection" /> object instance. /// </param> internal abstract void DisposeModule(SQLiteModule module, SQLiteConnectionFlags flags);