Index: System.Data.SQLite/SQLite3.cs
==================================================================
--- System.Data.SQLite/SQLite3.cs
+++ System.Data.SQLite/SQLite3.cs
@@ -84,11 +84,11 @@
protected SQLiteFunction[] _functionsArray;
///
/// The modules created using this connection.
///
- protected Dictionary _modules;
+ protected Dictionary _modules;
///////////////////////////////////////////////////////////////////////////////////////////////
internal SQLite3(
SQLiteDateFormats fmt,
@@ -139,13 +139,13 @@
// release unmanaged resources here...
//////////////////////////////////////
if (_modules != null)
{
- foreach (KeyValuePair pair in _modules)
+ foreach (KeyValuePair pair in _modules)
{
- SQLiteModuleBase module = pair.Value;
+ SQLiteModule module = pair.Value;
if (module == null)
continue;
module.Dispose();
@@ -1576,11 +1576,11 @@
/// module containing the implementation of a virtual table.
///
///
/// The module object to be used when creating the native disposable module.
///
- internal override void CreateModule(SQLiteModuleBase module)
+ internal override void CreateModule(SQLiteModule module)
{
if (module == null)
throw new ArgumentNullException("module");
if (_sql == null)
@@ -1601,11 +1601,11 @@
if (UnsafeNativeMethods.sqlite3_create_disposable_module(
_sql, pName, ref nativeModule, IntPtr.Zero,
null) != IntPtr.Zero)
{
if (_modules == null)
- _modules = new Dictionary();
+ _modules = new Dictionary();
_modules.Add(module.Name, module);
}
else
{
@@ -1628,11 +1628,11 @@
///
///
/// The module object previously passed to the
/// method.
///
- internal override void DisposeModule(SQLiteModuleBase module)
+ internal override void DisposeModule(SQLiteModule module)
{
if (module == null)
throw new ArgumentNullException("module");
module.Dispose();
@@ -1661,11 +1661,11 @@
///
///
/// A standard SQLite return code.
///
internal override SQLiteErrorCode DeclareVirtualTable(
- SQLiteModuleBase module,
+ SQLiteModule module,
string strSql,
ref string error
)
{
if (_sql == null)
Index: System.Data.SQLite/SQLiteBase.cs
==================================================================
--- System.Data.SQLite/SQLiteBase.cs
+++ System.Data.SQLite/SQLiteBase.cs
@@ -216,21 +216,21 @@
/// module containing the implementation of a virtual table.
///
///
/// The module object to be used when creating the native disposable module.
///
- internal abstract void CreateModule(SQLiteModuleBase module);
+ internal abstract void CreateModule(SQLiteModule module);
///
/// Calls the native SQLite core library in order to cleanup the resources
/// associated with a module containing the implementation of a virtual table.
///
///
/// The module object previously passed to the
/// method.
///
- internal abstract void DisposeModule(SQLiteModuleBase module);
+ internal abstract void DisposeModule(SQLiteModule module);
///
/// Calls the native SQLite core library in order to declare a virtual table
/// in response to a call into the xCreate or xConnect virtual table methods.
///
@@ -247,11 +247,11 @@
/// it should contain an appropriate error message.
///
///
/// A standard SQLite return code.
///
- internal abstract SQLiteErrorCode DeclareVirtualTable(SQLiteModuleBase module, string strSql, ref string error);
+ internal abstract SQLiteErrorCode DeclareVirtualTable(SQLiteModule module, string strSql, ref string error);
///
/// Enables or disabled extension loading by SQLite.
///
///
Index: System.Data.SQLite/SQLiteConnection.cs
==================================================================
--- System.Data.SQLite/SQLiteConnection.cs
+++ System.Data.SQLite/SQLiteConnection.cs
@@ -1731,11 +1731,11 @@
///
///
/// The module object to be used when creating the disposable module.
///
public void CreateModule(
- SQLiteModuleBase module
+ SQLiteModule module
)
{
CheckDisposed();
if (_sql == null)
ADDED System.Data.SQLite/SQLiteModule.cs
Index: System.Data.SQLite/SQLiteModule.cs
==================================================================
--- /dev/null
+++ System.Data.SQLite/SQLiteModule.cs
@@ -0,0 +1,3549 @@
+/********************************************************
+ * ADO.NET 2.0 Data Provider for SQLite Version 3.X
+ * Written by Joe Mistachkin (joe@mistachkin.com)
+ *
+ * Released to the public domain, use at your own risk!
+ ********************************************************/
+
+using System.Collections.Generic;
+using System.Globalization;
+using System.Runtime.InteropServices;
+using System.Text;
+
+#if TRACK_MEMORY_BYTES
+using System.Threading;
+#endif
+
+namespace System.Data.SQLite
+{
+ #region SQLiteContext Helper Class
+ public sealed class SQLiteContext
+ {
+ #region Private Data
+ private IntPtr pContext;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Constructors
+ internal SQLiteContext(IntPtr pContext)
+ {
+ this.pContext = pContext;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Methods
+ public void SetNull()
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_null(pContext);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetDouble(double value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+#if !PLATFORM_COMPACTFRAMEWORK
+ UnsafeNativeMethods.sqlite3_result_double(pContext, value);
+#elif !SQLITE_STANDARD
+ UnsafeNativeMethods.sqlite3_result_double_interop(pContext, ref value);
+#else
+ throw new NotImplementedException();
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetInt(int value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_int(pContext, value);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetInt64(long value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+#if !PLATFORM_COMPACTFRAMEWORK
+ UnsafeNativeMethods.sqlite3_result_int64(pContext, value);
+#elif !SQLITE_STANDARD
+ UnsafeNativeMethods.sqlite3_result_int64_interop(pContext, ref value);
+#else
+ throw new NotImplementedException();
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetString(string value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ byte[] bytes = SQLiteString.GetUtf8BytesFromString(value);
+
+ if (bytes == null)
+ throw new ArgumentNullException("value");
+
+ UnsafeNativeMethods.sqlite3_result_text(
+ pContext, bytes, bytes.Length, (IntPtr)(-1));
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetError(string value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ byte[] bytes = SQLiteString.GetUtf8BytesFromString(value);
+
+ if (bytes == null)
+ throw new ArgumentNullException("value");
+
+ UnsafeNativeMethods.sqlite3_result_error(
+ pContext, bytes, bytes.Length);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetErrorCode(SQLiteErrorCode value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_error_code(pContext, value);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetErrorTooBig()
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_error_toobig(pContext);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetErrorNoMemory()
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_error_nomem(pContext);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetBlob(byte[] value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ if (value == null)
+ throw new ArgumentNullException("value");
+
+ UnsafeNativeMethods.sqlite3_result_blob(
+ pContext, value, value.Length, (IntPtr)(-1));
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetZeroBlob(int value)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_zeroblob(pContext, value);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public void SetValue(IntPtr pValue)
+ {
+ if (pContext == IntPtr.Zero)
+ throw new InvalidOperationException();
+
+ UnsafeNativeMethods.sqlite3_result_value(pContext, pValue);
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteValue Helper Class
+ public sealed class SQLiteValue
+ {
+ #region Private Data
+ private IntPtr pValue;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Constructors
+ internal SQLiteValue(IntPtr pValue)
+ {
+ this.pValue = pValue;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Methods
+ private void PreventNativeAccess()
+ {
+ pValue = IntPtr.Zero;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private bool persisted;
+ public bool Persisted
+ {
+ get { return persisted; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private object value;
+ public object Value
+ {
+ get
+ {
+ if (!persisted)
+ {
+ throw new InvalidOperationException(
+ "value was not persisted");
+ }
+
+ return value;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Methods
+ public TypeAffinity GetTypeAffinity()
+ {
+ if (pValue == IntPtr.Zero) return TypeAffinity.None;
+ return UnsafeNativeMethods.sqlite3_value_type(pValue);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public int GetBytes()
+ {
+ if (pValue == IntPtr.Zero) return 0;
+ return UnsafeNativeMethods.sqlite3_value_bytes(pValue);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public int GetInt()
+ {
+ if (pValue == IntPtr.Zero) return default(int);
+ return UnsafeNativeMethods.sqlite3_value_int(pValue);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public long GetInt64()
+ {
+ if (pValue == IntPtr.Zero) return default(long);
+
+#if !PLATFORM_COMPACTFRAMEWORK
+ return UnsafeNativeMethods.sqlite3_value_int64(pValue);
+#elif !SQLITE_STANDARD
+ long value;
+ UnsafeNativeMethods.sqlite3_value_int64_interop(pValue, out value);
+ return value;
+#else
+ throw new NotImplementedException();
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public double GetDouble()
+ {
+ if (pValue == IntPtr.Zero) return default(double);
+
+#if !PLATFORM_COMPACTFRAMEWORK
+ return UnsafeNativeMethods.sqlite3_value_double(pValue);
+#elif !SQLITE_STANDARD
+ double value;
+ UnsafeNativeMethods.sqlite3_value_double_interop(pValue, out value);
+ return value;
+#else
+ throw new NotImplementedException();
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public string GetString()
+ {
+ if (pValue == IntPtr.Zero) return null;
+ return SQLiteString.StringFromUtf8IntPtr(pValue, GetBytes());
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public byte[] GetBlob()
+ {
+ if (pValue == IntPtr.Zero) return null;
+ return SQLiteMarshal.BytesFromIntPtr(pValue, GetBytes());
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public bool Persist()
+ {
+ switch (GetTypeAffinity())
+ {
+ case TypeAffinity.Uninitialized:
+ {
+ value = null;
+ PreventNativeAccess();
+ return (persisted = true);
+ }
+ case TypeAffinity.Int64:
+ {
+ value = GetInt64();
+ PreventNativeAccess();
+ return (persisted = true);
+ }
+ case TypeAffinity.Double:
+ {
+ value = GetDouble();
+ PreventNativeAccess();
+ return (persisted = true);
+ }
+ case TypeAffinity.Text:
+ {
+ value = GetString();
+ PreventNativeAccess();
+ return (persisted = true);
+ }
+ case TypeAffinity.Blob:
+ {
+ value = GetBytes();
+ PreventNativeAccess();
+ return (persisted = true);
+ }
+ case TypeAffinity.Null:
+ {
+ value = DBNull.Value;
+ PreventNativeAccess();
+ return (persisted = true);
+ }
+ default:
+ {
+ return false;
+ }
+ }
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndexConstraintOp Enumeration
+ /* [Flags()] */
+ public enum SQLiteIndexConstraintOp : byte
+ {
+ EqualTo = 2,
+ GreaterThan = 4,
+ LessThanOrEqualTo = 8,
+ LessThan = 16,
+ GreaterThanOrEqualTo = 32,
+ Match = 64
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndexConstraint Helper Class
+ public sealed class SQLiteIndexConstraint
+ {
+ #region Internal Constructors
+ internal SQLiteIndexConstraint(
+ UnsafeNativeMethods.sqlite3_index_constraint constraint
+ )
+ : this(constraint.iColumn, constraint.op, constraint.usable,
+ constraint.iTermOffset)
+ {
+ // do nothing.
+ }
+ #endregion
+
+ //////////////////////////////////////////////////////////////////////
+
+ #region Private Constructors
+ private SQLiteIndexConstraint(
+ int iColumn,
+ SQLiteIndexConstraintOp op,
+ byte usable,
+ int iTermOffset
+ )
+ {
+ this.iColumn = iColumn;
+ this.op = op;
+ this.usable = usable;
+ this.iTermOffset = iTermOffset;
+ }
+ #endregion
+
+ //////////////////////////////////////////////////////////////////////
+
+ #region Public Fields
+ public int iColumn;
+
+ //////////////////////////////////////////////////////////////////////
+
+ public SQLiteIndexConstraintOp op;
+
+ //////////////////////////////////////////////////////////////////////
+
+ public byte usable;
+
+ //////////////////////////////////////////////////////////////////////
+
+ public int iTermOffset;
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndexOrderBy Helper Class
+ public sealed class SQLiteIndexOrderBy
+ {
+ #region Internal Constructors
+ internal SQLiteIndexOrderBy(
+ UnsafeNativeMethods.sqlite3_index_orderby orderBy
+ )
+ : this(orderBy.iColumn, orderBy.desc)
+ {
+ // do nothing.
+ }
+ #endregion
+
+ //////////////////////////////////////////////////////////////////////
+
+ #region Private Constructors
+ private SQLiteIndexOrderBy(
+ int iColumn,
+ byte desc
+ )
+ {
+ this.iColumn = iColumn;
+ this.desc = desc;
+ }
+ #endregion
+
+ //////////////////////////////////////////////////////////////////////
+
+ #region Public Fields
+ public int iColumn; /* Column number */
+
+ //////////////////////////////////////////////////////////////////////
+
+ public byte desc; /* True for DESC. False for ASC. */
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndexConstraintUsage Helper Class
+ public sealed class SQLiteIndexConstraintUsage
+ {
+ #region Internal Constructors
+ internal SQLiteIndexConstraintUsage(
+ UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage
+ )
+ : this(constraintUsage.argvIndex, constraintUsage.omit)
+ {
+ // do nothing.
+ }
+ #endregion
+
+ //////////////////////////////////////////////////////////////////////
+
+ #region Private Constructors
+ private SQLiteIndexConstraintUsage(
+ int argvIndex,
+ byte omit
+ )
+ {
+ this.argvIndex = argvIndex;
+ this.omit = omit;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Fields
+ public int argvIndex;
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public byte omit;
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndexInputs Helper Class
+ public sealed class SQLiteIndexInputs
+ {
+ #region Internal Constructors
+ internal SQLiteIndexInputs(int nConstraint, int nOrderBy)
+ {
+ constraints = new SQLiteIndexConstraint[nConstraint];
+ orderBys = new SQLiteIndexOrderBy[nOrderBy];
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private SQLiteIndexConstraint[] constraints;
+ public SQLiteIndexConstraint[] Constraints
+ {
+ get { return constraints; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteIndexOrderBy[] orderBys;
+ public SQLiteIndexOrderBy[] OrderBys
+ {
+ get { return orderBys; }
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndexOutputs Helper Class
+ public sealed class SQLiteIndexOutputs
+ {
+ #region Internal Constructors
+ internal SQLiteIndexOutputs(int nConstraint)
+ {
+ constraintUsages = new SQLiteIndexConstraintUsage[nConstraint];
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private SQLiteIndexConstraintUsage[] constraintUsages;
+ public SQLiteIndexConstraintUsage[] ConstraintUsages
+ {
+ get { return constraintUsages; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private int indexNumber;
+ public int IndexNumber
+ {
+ get { return indexNumber; }
+ set { indexNumber = value; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private string indexString;
+ public string IndexString
+ {
+ get { return indexString; }
+ set { indexString = value; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private int needToFreeIndexString;
+ public int NeedToFreeIndexString
+ {
+ get { return needToFreeIndexString; }
+ set { needToFreeIndexString = value; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private int orderByConsumed;
+ public int OrderByConsumed
+ {
+ get { return orderByConsumed; }
+ set { orderByConsumed = value; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private double estimatedCost;
+ public double EstimatedCost
+ {
+ get { return estimatedCost; }
+ set { estimatedCost = value; }
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndex Helper Class
+ public sealed class SQLiteIndex
+ {
+ #region Internal Constructors
+ internal SQLiteIndex(
+ int nConstraint,
+ int nOrderBy
+ )
+ {
+ inputs = new SQLiteIndexInputs(nConstraint, nOrderBy);
+ outputs = new SQLiteIndexOutputs(nConstraint);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private SQLiteIndexInputs inputs;
+ public SQLiteIndexInputs Inputs
+ {
+ get { return inputs; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteIndexOutputs outputs;
+ public SQLiteIndexOutputs Outputs
+ {
+ get { return outputs; }
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteVirtualTable Base Class
+ /* NOT SEALED */
+ public class SQLiteVirtualTable : ISQLiteNativeHandle, IDisposable
+ {
+ #region Private Constants
+ private const int ModuleNameIndex = 0;
+ private const int DatabaseNameIndex = 1;
+ private const int TableNameIndex = 2;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Constructors
+ public SQLiteVirtualTable(
+ string[] arguments
+ )
+ {
+ this.arguments = arguments;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private string[] arguments;
+ public virtual string[] Arguments
+ {
+ get { CheckDisposed(); return arguments; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public virtual string ModuleName
+ {
+ get
+ {
+ CheckDisposed();
+
+ string[] arguments = Arguments;
+
+ if ((arguments != null) &&
+ (arguments.Length > ModuleNameIndex))
+ {
+ return arguments[ModuleNameIndex];
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public virtual string DatabaseName
+ {
+ get
+ {
+ CheckDisposed();
+
+ string[] arguments = Arguments;
+
+ if ((arguments != null) &&
+ (arguments.Length > DatabaseNameIndex))
+ {
+ return arguments[DatabaseNameIndex];
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public virtual string TableName
+ {
+ get
+ {
+ CheckDisposed();
+
+ string[] arguments = Arguments;
+
+ if ((arguments != null) &&
+ (arguments.Length > TableNameIndex))
+ {
+ return arguments[TableNameIndex];
+ }
+ else
+ {
+ return null;
+ }
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Methods
+ public virtual bool Rename(
+ string name
+ )
+ {
+ CheckDisposed();
+
+ if ((arguments != null) &&
+ (arguments.Length > TableNameIndex))
+ {
+ arguments[TableNameIndex] = name;
+ return true;
+ }
+
+ return false;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteNativeHandle Members
+ private IntPtr nativeHandle;
+ public virtual IntPtr NativeHandle
+ {
+ get { CheckDisposed(); return nativeHandle; }
+ internal set { nativeHandle = value; }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ {
+ throw new ObjectDisposedException(
+ typeof(SQLiteVirtualTable).Name);
+ }
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteVirtualTableCursor Base Class
+ /* NOT SEALED */
+ public class SQLiteVirtualTableCursor : ISQLiteNativeHandle, IDisposable
+ {
+ #region Public Constructors
+ public SQLiteVirtualTableCursor(
+ SQLiteVirtualTable table
+ )
+ {
+ this.table = table;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private SQLiteVirtualTable table;
+ public virtual SQLiteVirtualTable Table
+ {
+ get { CheckDisposed(); return table; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private int indexNumber;
+ public virtual int IndexNumber
+ {
+ get { CheckDisposed(); return indexNumber; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private string indexString;
+ public virtual string IndexString
+ {
+ get { CheckDisposed(); return indexString; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteValue[] values;
+ public virtual SQLiteValue[] Values
+ {
+ get { CheckDisposed(); return values; }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Protected Methods
+ protected virtual int TryPersistValues(
+ SQLiteValue[] values
+ )
+ {
+ int result = 0;
+
+ if (values != null)
+ {
+ foreach (SQLiteValue value in values)
+ {
+ if (value == null)
+ continue;
+
+ if (value.Persist())
+ result++;
+ }
+ }
+
+ return result;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Methods
+ public virtual void Filter(
+ int indexNumber,
+ string indexString,
+ SQLiteValue[] values
+ )
+ {
+ CheckDisposed();
+
+ if ((values != null) &&
+ (TryPersistValues(values) != values.Length))
+ {
+ throw new SQLiteException(SQLiteErrorCode.Error,
+ "failed to persist one or more values");
+ }
+
+ this.indexNumber = indexNumber;
+ this.indexString = indexString;
+ this.values = values;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteNativeHandle Members
+ private IntPtr nativeHandle;
+ public virtual IntPtr NativeHandle
+ {
+ get { CheckDisposed(); return nativeHandle; }
+ internal set { nativeHandle = value; }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ {
+ throw new ObjectDisposedException(
+ typeof(SQLiteVirtualTableCursor).Name);
+ }
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteVirtualTableCursor()
+ {
+ Dispose(false);
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteNativeHandle Interface
+ public interface ISQLiteNativeHandle
+ {
+ IntPtr NativeHandle { get; }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteNativeModule Interface
+ public interface ISQLiteNativeModule
+ {
+ SQLiteErrorCode xCreate(
+ IntPtr pDb,
+ IntPtr pAux,
+ int argc,
+ IntPtr[] argv,
+ ref IntPtr pVtab,
+ ref IntPtr pError
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xConnect(
+ IntPtr pDb,
+ IntPtr pAux,
+ int argc,
+ IntPtr[] argv,
+ ref IntPtr pVtab,
+ ref IntPtr pError
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xBestIndex(
+ IntPtr pVtab,
+ IntPtr pIndex
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xDisconnect(
+ IntPtr pVtab
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xDestroy(
+ IntPtr pVtab
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xOpen(
+ IntPtr pVtab,
+ ref IntPtr pCursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xClose(
+ IntPtr pCursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xFilter(
+ IntPtr pCursor,
+ int idxNum,
+ IntPtr idxStr,
+ int argc,
+ IntPtr[] argv
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xNext(
+ IntPtr pCursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ int xEof(
+ IntPtr pCursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xColumn(
+ IntPtr pCursor,
+ IntPtr pContext,
+ int index
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xRowId(
+ IntPtr pCursor,
+ ref long rowId
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xUpdate(
+ IntPtr pVtab,
+ int nData,
+ IntPtr apData,
+ ref long rowId
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xBegin(
+ IntPtr pVtab
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xSync(
+ IntPtr pVtab
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xCommit(
+ IntPtr pVtab
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xRollback(
+ IntPtr pVtab
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ int xFindFunction(
+ IntPtr pVtab,
+ int nArg,
+ IntPtr zName,
+ ref SQLiteCallback callback,
+ ref IntPtr pClientData
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xRename(
+ IntPtr pVtab,
+ IntPtr zNew
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xSavepoint(
+ IntPtr pVtab,
+ int iSavepoint
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xRelease(
+ IntPtr pVtab,
+ int iSavepoint
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode xRollbackTo(
+ IntPtr pVtab,
+ int iSavepoint
+ );
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteManagedModule Interface
+ public interface ISQLiteManagedModule
+ {
+ bool Declared { get; }
+ string Name { get; }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Create(
+ SQLiteConnection connection, /* in */
+ IntPtr pClientData, /* in */
+ string[] arguments, /* in */
+ ref SQLiteVirtualTable table, /* out */
+ ref string error /* out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Connect(
+ SQLiteConnection connection, /* in */
+ IntPtr pClientData, /* in */
+ string[] arguments, /* in */
+ ref SQLiteVirtualTable table, /* out */
+ ref string error /* out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode BestIndex(
+ SQLiteVirtualTable table, /* in */
+ SQLiteIndex index /* in, out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Disconnect(
+ SQLiteVirtualTable table /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Destroy(
+ SQLiteVirtualTable table /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Open(
+ SQLiteVirtualTable table, /* in */
+ ref SQLiteVirtualTableCursor cursor /* out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Close(
+ SQLiteVirtualTableCursor cursor /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Filter(
+ SQLiteVirtualTableCursor cursor, /* in */
+ int indexNumber, /* in */
+ string indexString, /* in */
+ SQLiteValue[] values /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Next(
+ SQLiteVirtualTableCursor cursor /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ bool Eof(
+ SQLiteVirtualTableCursor cursor /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Column(
+ SQLiteVirtualTableCursor cursor, /* in */
+ SQLiteContext context, /* in */
+ int index /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode RowId(
+ SQLiteVirtualTableCursor cursor, /* in */
+ ref long rowId /* out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Update(
+ SQLiteVirtualTable table, /* in */
+ SQLiteValue[] values, /* in */
+ ref long rowId /* in, out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Begin(
+ SQLiteVirtualTable table /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Sync(
+ SQLiteVirtualTable table /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Commit(
+ SQLiteVirtualTable table /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Rollback(
+ SQLiteVirtualTable table /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ bool FindFunction(
+ SQLiteVirtualTable table, /* in */
+ int argumentCount, /* in */
+ string name, /* in */
+ ref SQLiteFunction function, /* out */
+ ref IntPtr pClientData /* out */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Rename(
+ SQLiteVirtualTable table, /* in */
+ string newName /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Savepoint(
+ SQLiteVirtualTable table, /* in */
+ int savepoint /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode Release(
+ SQLiteVirtualTable table, /* in */
+ int savepoint /* in */
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ SQLiteErrorCode RollbackTo(
+ SQLiteVirtualTable table, /* in */
+ int savepoint /* in */
+ );
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteMemory Static Class
+ internal static class SQLiteMemory
+ {
+ #region Private Data
+#if TRACK_MEMORY_BYTES
+#if PLATFORM_COMPACTFRAMEWORK
+ private static object syncRoot = new object();
+#endif
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private static int bytesAllocated;
+ private static int maximumBytesAllocated;
+#endif
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Memory Allocation Helper Methods
+ public static IntPtr Allocate(int size)
+ {
+ IntPtr pMemory = UnsafeNativeMethods.sqlite3_malloc(size);
+
+#if TRACK_MEMORY_BYTES
+ if (pMemory != IntPtr.Zero)
+ {
+ int blockSize = Size(pMemory);
+
+ if (blockSize > 0)
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ Interlocked.Add(ref bytesAllocated, blockSize);
+ Interlocked.Add(ref maximumBytesAllocated, blockSize);
+#else
+ lock (syncRoot)
+ {
+ bytesAllocated += blockSize;
+ maximumBytesAllocated += blockSize;
+ }
+#endif
+ }
+ }
+#endif
+
+ return pMemory;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static int Size(IntPtr pMemory)
+ {
+#if !SQLITE_STANDARD
+ return UnsafeNativeMethods.sqlite3_malloc_size_interop(pMemory);
+#else
+ return 0;
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static void Free(IntPtr pMemory)
+ {
+#if TRACK_MEMORY_BYTES
+ if (pMemory != IntPtr.Zero)
+ {
+ int blockSize = Size(pMemory);
+
+ if (blockSize > 0)
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ Interlocked.Add(ref bytesAllocated, -blockSize);
+#else
+ lock (syncRoot)
+ {
+ bytesAllocated -= blockSize;
+ }
+#endif
+ }
+ }
+#endif
+
+ UnsafeNativeMethods.sqlite3_free(pMemory);
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteString Static Class
+ internal static class SQLiteString
+ {
+ #region Private Constants
+ private static int ThirtyBits = 0x3fffffff;
+ private static readonly Encoding Utf8Encoding = Encoding.UTF8;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region UTF-8 Encoding Helper Methods
+ public static byte[] GetUtf8BytesFromString(
+ string value
+ )
+ {
+ if (value == null)
+ return null;
+
+ return Utf8Encoding.GetBytes(value);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static string GetStringFromUtf8Bytes(
+ byte[] bytes
+ )
+ {
+ if (bytes == null)
+ return null;
+
+#if !PLATFORM_COMPACTFRAMEWORK
+ return Utf8Encoding.GetString(bytes);
+#else
+ return Utf8Encoding.GetString(bytes, 0, bytes.Length);
+#endif
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region UTF-8 String Helper Methods
+ public static int ProbeForUtf8ByteLength(
+ IntPtr pValue,
+ int limit
+ )
+ {
+ int length = 0;
+
+ if (pValue != IntPtr.Zero)
+ {
+ do
+ {
+ if (Marshal.ReadByte(pValue, length) == 0)
+ break;
+
+ if (length >= limit)
+ break;
+
+ length++;
+ } while (true);
+ }
+
+ return length;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static string StringFromUtf8IntPtr(
+ IntPtr pValue
+ )
+ {
+ return StringFromUtf8IntPtr(pValue,
+ ProbeForUtf8ByteLength(pValue, ThirtyBits));
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static string StringFromUtf8IntPtr(
+ IntPtr pValue,
+ int length
+ )
+ {
+ if (pValue == IntPtr.Zero)
+ return null;
+
+ if (length > 0)
+ {
+ byte[] bytes = new byte[length];
+
+ Marshal.Copy(pValue, bytes, 0, length);
+
+ return GetStringFromUtf8Bytes(bytes);
+ }
+
+ return String.Empty;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static IntPtr Utf8IntPtrFromString(
+ string value
+ )
+ {
+ if (value == null)
+ return IntPtr.Zero;
+
+ IntPtr result = IntPtr.Zero;
+ byte[] bytes = GetUtf8BytesFromString(value);
+
+ if (bytes == null)
+ return IntPtr.Zero;
+
+ int length = bytes.Length;
+
+ result = SQLiteMemory.Allocate(length + 1);
+
+ if (result == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ Marshal.Copy(bytes, 0, result, length);
+ Marshal.WriteByte(result, length, 0);
+
+ return result;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region UTF-8 String Array Helper Methods
+ public static string[] StringArrayFromUtf8IntPtrArray(
+ IntPtr[] pValues
+ )
+ {
+ if (pValues == null)
+ return null;
+
+ string[] result = new string[pValues.Length];
+
+ for (int index = 0; index < result.Length; index++)
+ result[index] = StringFromUtf8IntPtr(pValues[index]);
+
+ return result;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static IntPtr[] Utf8IntPtrArrayFromStringArray(
+ string[] values
+ )
+ {
+ if (values == null)
+ return null;
+
+ IntPtr[] result = new IntPtr[values.Length];
+
+ for (int index = 0; index < result.Length; index++)
+ result[index] = Utf8IntPtrFromString(values[index]);
+
+ return result;
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteMarshal Static Class
+ internal static class SQLiteMarshal
+ {
+ #region IntPtr Helper Methods
+ public static IntPtr IntPtrForOffset(
+ IntPtr pointer,
+ int offset
+ )
+ {
+ return new IntPtr(pointer.ToInt64() + offset);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Marshal Read Helper Methods
+ public static int ReadInt32(
+ IntPtr pointer,
+ int offset
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ return Marshal.ReadInt32(pointer, offset);
+#else
+ return Marshal.ReadInt32(IntPtrForOffset(pointer, offset));
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static double ReadDouble(
+ IntPtr pointer,
+ int offset
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ return BitConverter.Int64BitsToDouble(Marshal.ReadInt64(
+ pointer, offset));
+#else
+ return BitConverter.ToDouble(BitConverter.GetBytes(
+ Marshal.ReadInt64(IntPtrForOffset(pointer, offset))), 0);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static IntPtr ReadIntPtr(
+ IntPtr pointer,
+ int offset
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ return Marshal.ReadIntPtr(pointer, offset);
+#else
+ return Marshal.ReadIntPtr(IntPtrForOffset(pointer, offset));
+#endif
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Marshal Write Helper Methods
+ public static void WriteInt32(
+ IntPtr pointer,
+ int offset,
+ int value
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ Marshal.WriteInt32(pointer, offset, value);
+#else
+ Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value);
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static void WriteDouble(
+ IntPtr pointer,
+ int offset,
+ double value
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ Marshal.WriteInt64(pointer, offset,
+ BitConverter.DoubleToInt64Bits(value));
+#else
+ Marshal.WriteInt64(IntPtrForOffset(pointer, offset),
+ BitConverter.ToInt64(BitConverter.GetBytes(value), 0));
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static void WriteIntPtr(
+ IntPtr pointer,
+ int offset,
+ IntPtr value
+ )
+ {
+#if !PLATFORM_COMPACTFRAMEWORK
+ Marshal.WriteIntPtr(pointer, offset, value);
+#else
+ Marshal.WriteIntPtr(IntPtrForOffset(pointer, offset), value);
+#endif
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Byte Array Helper Methods
+ public static byte[] BytesFromIntPtr(
+ IntPtr pValue,
+ int length
+ )
+ {
+ if (pValue == IntPtr.Zero)
+ return null;
+
+ if (length == 0)
+ return new byte[0];
+
+ byte[] result = new byte[length];
+
+ Marshal.Copy(pValue, result, 0, length);
+
+ return result;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static IntPtr BytesToIntPtr(
+ byte[] value
+ )
+ {
+ if (value == null)
+ return IntPtr.Zero;
+
+ int length = value.Length;
+
+ if (length == 0)
+ return IntPtr.Zero;
+
+ IntPtr result = SQLiteMemory.Allocate(length);
+
+ if (result == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ Marshal.Copy(value, 0, result, length);
+
+ return result;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region SQLiteValue Helper Methods
+ public static SQLiteValue[] ValueArrayFromSizeAndIntPtr(
+ int nData,
+ IntPtr apData
+ )
+ {
+ if (nData < 0)
+ return null;
+
+ if (apData == IntPtr.Zero)
+ return null;
+
+ SQLiteValue[] result = new SQLiteValue[nData];
+
+ for (int index = 0, offset = 0;
+ index < result.Length;
+ index++, offset += IntPtr.Size)
+ {
+ IntPtr pData = ReadIntPtr(apData, offset);
+
+ result[index] = (pData != IntPtr.Zero) ?
+ new SQLiteValue(pData) : null;
+ }
+
+ return result;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static SQLiteValue[] ValueArrayFromIntPtrArray(
+ IntPtr[] values
+ )
+ {
+ if (values == null)
+ return null;
+
+ SQLiteValue[] result = new SQLiteValue[values.Length];
+
+ for (int index = 0; index < result.Length; index++)
+ result[index] = new SQLiteValue(values[index]);
+
+ return result;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region SQLiteIndex Helper Methods
+ public static void IndexFromIntPtr(
+ IntPtr pIndex,
+ ref SQLiteIndex index
+ )
+ {
+ if (pIndex == IntPtr.Zero)
+ return;
+
+ int offset = 0;
+
+ int nConstraint = ReadInt32(pIndex, offset);
+
+ offset += sizeof(int);
+
+ IntPtr pConstraint = ReadIntPtr(pIndex, offset);
+
+ offset += IntPtr.Size;
+
+ int nOrderBy = ReadInt32(pIndex, offset);
+
+ index = new SQLiteIndex(nConstraint, nOrderBy);
+
+ offset += sizeof(int);
+
+ IntPtr pOrderBy = ReadIntPtr(pIndex, offset);
+
+ offset += IntPtr.Size;
+
+ IntPtr pConstraintUsage = ReadIntPtr(pIndex, offset);
+
+ offset += IntPtr.Size;
+
+ index.Outputs.IndexNumber = ReadInt32(pIndex, offset);
+
+ offset += sizeof(int);
+
+ index.Outputs.IndexString = SQLiteString.StringFromUtf8IntPtr(
+ IntPtrForOffset(pIndex, offset));
+
+ offset += IntPtr.Size;
+
+ index.Outputs.NeedToFreeIndexString = ReadInt32(pIndex, offset);
+
+ offset += sizeof(int);
+
+ index.Outputs.OrderByConsumed = ReadInt32(pIndex, offset);
+
+ offset += sizeof(int);
+
+ index.Outputs.EstimatedCost = ReadDouble(pIndex, offset);
+
+ int sizeOfConstraintType = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_index_constraint));
+
+ for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
+ {
+ UnsafeNativeMethods.sqlite3_index_constraint constraint =
+ new UnsafeNativeMethods.sqlite3_index_constraint();
+
+ Marshal.PtrToStructure(IntPtrForOffset(pConstraint,
+ iConstraint * sizeOfConstraintType), constraint);
+
+ index.Inputs.Constraints[iConstraint] =
+ new SQLiteIndexConstraint(constraint);
+ }
+
+ int sizeOfOrderByType = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_index_orderby));
+
+ for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++)
+ {
+ UnsafeNativeMethods.sqlite3_index_orderby orderBy =
+ new UnsafeNativeMethods.sqlite3_index_orderby();
+
+ Marshal.PtrToStructure(IntPtrForOffset(pOrderBy,
+ iOrderBy * sizeOfOrderByType), orderBy);
+
+ index.Inputs.OrderBys[iOrderBy] =
+ new SQLiteIndexOrderBy(orderBy);
+ }
+
+ int sizeOfConstraintUsageType = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_index_constraint_usage));
+
+ for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
+ {
+ UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage =
+ new UnsafeNativeMethods.sqlite3_index_constraint_usage();
+
+ Marshal.PtrToStructure(IntPtrForOffset(pConstraintUsage,
+ iConstraint * sizeOfConstraintUsageType), constraintUsage);
+
+ index.Outputs.ConstraintUsages[iConstraint] =
+ new SQLiteIndexConstraintUsage(constraintUsage);
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public static void IndexToIntPtr(
+ SQLiteIndex index,
+ IntPtr pIndex
+ )
+ {
+ if ((index == null) || (index.Inputs == null) ||
+ (index.Inputs.Constraints == null) ||
+ (index.Inputs.OrderBys == null) || (index.Outputs == null) ||
+ (index.Outputs.ConstraintUsages == null))
+ {
+ return;
+ }
+
+ if (pIndex == IntPtr.Zero)
+ return;
+
+ int offset = 0;
+
+ int nConstraint = ReadInt32(pIndex, offset);
+
+ if (nConstraint != index.Inputs.Constraints.Length)
+ return;
+
+ if (nConstraint != index.Outputs.ConstraintUsages.Length)
+ return;
+
+ offset += sizeof(int);
+
+ IntPtr pConstraint = ReadIntPtr(pIndex, offset);
+
+ offset += IntPtr.Size;
+
+ int nOrderBy = ReadInt32(pIndex, offset);
+
+ offset += sizeof(int);
+
+ IntPtr pOrderBy = ReadIntPtr(pIndex, offset);
+
+ offset += IntPtr.Size;
+
+ IntPtr pConstraintUsage = ReadIntPtr(pIndex, offset);
+
+ int sizeOfConstraintType = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_index_constraint));
+
+ for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
+ {
+ UnsafeNativeMethods.sqlite3_index_constraint constraint =
+ new UnsafeNativeMethods.sqlite3_index_constraint(
+ index.Inputs.Constraints[iConstraint]);
+
+ Marshal.StructureToPtr(
+ constraint, IntPtrForOffset(pConstraint,
+ iConstraint * sizeOfConstraintType), false);
+
+ index.Inputs.Constraints[iConstraint] =
+ new SQLiteIndexConstraint(constraint);
+ }
+
+ int sizeOfOrderByType = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_index_orderby));
+
+ for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++)
+ {
+ UnsafeNativeMethods.sqlite3_index_orderby orderBy =
+ new UnsafeNativeMethods.sqlite3_index_orderby(
+ index.Inputs.OrderBys[iOrderBy]);
+
+ Marshal.StructureToPtr(
+ orderBy, IntPtrForOffset(pOrderBy,
+ iOrderBy * sizeOfOrderByType), false);
+
+ index.Inputs.OrderBys[iOrderBy] =
+ new SQLiteIndexOrderBy(orderBy);
+ }
+
+ int sizeOfConstraintUsageType = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_index_constraint_usage));
+
+ for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
+ {
+ UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage =
+ new UnsafeNativeMethods.sqlite3_index_constraint_usage(
+ index.Outputs.ConstraintUsages[iConstraint]);
+
+ Marshal.StructureToPtr(
+ constraintUsage, IntPtrForOffset(pConstraintUsage,
+ iConstraint * sizeOfConstraintUsageType), false);
+
+ index.Outputs.ConstraintUsages[iConstraint] =
+ new SQLiteIndexConstraintUsage(constraintUsage);
+ }
+ }
+ #endregion
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ #region SQLiteModule Base Class
+ /* NOT SEALED */
+ public abstract class SQLiteModule :
+ ISQLiteManagedModule, /*ISQLiteNativeModule,*/ IDisposable
+ {
+ #region Private Constants
+ private const double DefaultCost = double.MaxValue;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Data
+ private UnsafeNativeMethods.sqlite3_module nativeModule;
+ private Dictionary tables;
+ private Dictionary cursors;
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Internal Methods
+ internal UnsafeNativeMethods.sqlite3_module GetNativeModule()
+ {
+ return nativeModule;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ internal UnsafeNativeMethods.sqlite3_module CreateNativeModule()
+ {
+ return CreateNativeModule(CreateNativeModuleImpl());
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Constructors
+ public SQLiteModule(string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ this.name = name;
+ this.tables = new Dictionary();
+ this.cursors = new Dictionary();
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Private Methods
+ private UnsafeNativeMethods.sqlite3_module CreateNativeModule(
+ ISQLiteNativeModule module
+ )
+ {
+ nativeModule = new UnsafeNativeMethods.sqlite3_module();
+ nativeModule.iVersion = 2;
+
+ if (module != null)
+ {
+ nativeModule.xCreate = new UnsafeNativeMethods.xCreate(
+ module.xCreate);
+
+ nativeModule.xConnect = new UnsafeNativeMethods.xConnect(
+ module.xConnect);
+
+ nativeModule.xBestIndex = new UnsafeNativeMethods.xBestIndex(
+ module.xBestIndex);
+
+ nativeModule.xDisconnect = new UnsafeNativeMethods.xDisconnect(
+ module.xDisconnect);
+
+ nativeModule.xDestroy = new UnsafeNativeMethods.xDestroy(
+ module.xDestroy);
+
+ nativeModule.xOpen = new UnsafeNativeMethods.xOpen(
+ module.xOpen);
+
+ nativeModule.xClose = new UnsafeNativeMethods.xClose(
+ module.xClose);
+
+ nativeModule.xFilter = new UnsafeNativeMethods.xFilter(
+ module.xFilter);
+
+ nativeModule.xNext = new UnsafeNativeMethods.xNext(
+ module.xNext);
+
+ nativeModule.xEof = new UnsafeNativeMethods.xEof(module.xEof);
+
+ nativeModule.xColumn = new UnsafeNativeMethods.xColumn(
+ module.xColumn);
+
+ nativeModule.xRowId = new UnsafeNativeMethods.xRowId(
+ module.xRowId);
+
+ nativeModule.xUpdate = new UnsafeNativeMethods.xUpdate(
+ module.xUpdate);
+
+ nativeModule.xBegin = new UnsafeNativeMethods.xBegin(
+ module.xBegin);
+
+ nativeModule.xSync = new UnsafeNativeMethods.xSync(
+ module.xSync);
+
+ nativeModule.xCommit = new UnsafeNativeMethods.xCommit(
+ module.xCommit);
+
+ nativeModule.xRollback = new UnsafeNativeMethods.xRollback(
+ module.xRollback);
+
+ nativeModule.xFindFunction = new UnsafeNativeMethods.xFindFunction(
+ module.xFindFunction);
+
+ nativeModule.xRename = new UnsafeNativeMethods.xRename(
+ module.xRename);
+
+ nativeModule.xSavepoint = new UnsafeNativeMethods.xSavepoint(
+ module.xSavepoint);
+
+ nativeModule.xRelease = new UnsafeNativeMethods.xRelease(
+ module.xRelease);
+
+ nativeModule.xRollbackTo = new UnsafeNativeMethods.xRollbackTo(
+ module.xRollbackTo);
+ }
+ else
+ {
+ nativeModule.xCreate = new UnsafeNativeMethods.xCreate(
+ xCreate);
+
+ nativeModule.xConnect = new UnsafeNativeMethods.xConnect(
+ xConnect);
+
+ nativeModule.xBestIndex = new UnsafeNativeMethods.xBestIndex(
+ xBestIndex);
+
+ nativeModule.xDisconnect = new UnsafeNativeMethods.xDisconnect(
+ xDisconnect);
+
+ nativeModule.xDestroy = new UnsafeNativeMethods.xDestroy(
+ xDestroy);
+
+ nativeModule.xOpen = new UnsafeNativeMethods.xOpen(xOpen);
+ nativeModule.xClose = new UnsafeNativeMethods.xClose(xClose);
+
+ nativeModule.xFilter = new UnsafeNativeMethods.xFilter(
+ xFilter);
+
+ nativeModule.xNext = new UnsafeNativeMethods.xNext(xNext);
+ nativeModule.xEof = new UnsafeNativeMethods.xEof(xEof);
+
+ nativeModule.xColumn = new UnsafeNativeMethods.xColumn(
+ xColumn);
+
+ nativeModule.xRowId = new UnsafeNativeMethods.xRowId(xRowId);
+
+ nativeModule.xUpdate = new UnsafeNativeMethods.xUpdate(
+ xUpdate);
+
+ nativeModule.xBegin = new UnsafeNativeMethods.xBegin(xBegin);
+ nativeModule.xSync = new UnsafeNativeMethods.xSync(xSync);
+
+ nativeModule.xCommit = new UnsafeNativeMethods.xCommit(
+ xCommit);
+
+ nativeModule.xRollback = new UnsafeNativeMethods.xRollback(
+ xRollback);
+
+ nativeModule.xFindFunction = new UnsafeNativeMethods.xFindFunction(
+ xFindFunction);
+
+ nativeModule.xRename = new UnsafeNativeMethods.xRename(
+ xRename);
+
+ nativeModule.xSavepoint = new UnsafeNativeMethods.xSavepoint(
+ xSavepoint);
+
+ nativeModule.xRelease = new UnsafeNativeMethods.xRelease(
+ xRelease);
+
+ nativeModule.xRollbackTo = new UnsafeNativeMethods.xRollbackTo(
+ xRollbackTo);
+ }
+
+ return nativeModule;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Protected Members
+ #region Module Helper Methods
+ protected virtual ISQLiteNativeModule CreateNativeModuleImpl()
+ {
+ return null; /* NOTE: Use built-in defaults. */
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Native Table Helper Methods
+ protected virtual IntPtr AllocateTable()
+ {
+ int size = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_vtab));
+
+ return SQLiteMemory.Allocate(size);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual void ZeroTable(
+ IntPtr pVtab
+ )
+ {
+ if (pVtab == IntPtr.Zero)
+ return;
+
+ int offset = 0;
+
+ SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero);
+
+ offset += IntPtr.Size;
+
+ SQLiteMarshal.WriteInt32(pVtab, offset, 0);
+
+ offset += sizeof(int);
+
+ SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual void FreeTable(
+ IntPtr pVtab
+ )
+ {
+ SetTableError(pVtab, null);
+ SQLiteMemory.Free(pVtab);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Native Cursor Helper Methods
+ protected virtual IntPtr AllocateCursor()
+ {
+ int size = Marshal.SizeOf(typeof(
+ UnsafeNativeMethods.sqlite3_vtab_cursor));
+
+ return SQLiteMemory.Allocate(size);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual void FreeCursor(
+ IntPtr pCursor
+ )
+ {
+ SQLiteMemory.Free(pCursor);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Table Lookup Methods
+ protected virtual IntPtr TableFromCursor(
+ IntPtr pCursor
+ )
+ {
+ if (pCursor == IntPtr.Zero)
+ return IntPtr.Zero;
+
+ return Marshal.ReadIntPtr(pCursor);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual SQLiteVirtualTable TableFromIntPtr(
+ IntPtr pVtab
+ )
+ {
+ if (pVtab == IntPtr.Zero)
+ {
+ SetTableError(pVtab, "invalid native table");
+ return null;
+ }
+
+ SQLiteVirtualTable table;
+
+ if ((tables != null) &&
+ tables.TryGetValue(pVtab, out table))
+ {
+ return table;
+ }
+
+ SetTableError(pVtab, String.Format(
+ CultureInfo.CurrentCulture,
+ "managed table for {0} not found", pVtab));
+
+ return null;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual IntPtr TableToIntPtr(
+ SQLiteVirtualTable table
+ )
+ {
+ if ((table == null) || (tables == null))
+ return IntPtr.Zero;
+
+ IntPtr pVtab = IntPtr.Zero;
+ bool success = false;
+
+ try
+ {
+ pVtab = AllocateTable();
+
+ if (pVtab != IntPtr.Zero)
+ {
+ ZeroTable(pVtab);
+ table.NativeHandle = pVtab;
+ tables.Add(pVtab, table);
+ success = true;
+ }
+ }
+ finally
+ {
+ if (!success && (pVtab != IntPtr.Zero))
+ {
+ FreeTable(pVtab);
+ pVtab = IntPtr.Zero;
+ }
+ }
+
+ return pVtab;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Cursor Lookup Methods
+ protected virtual SQLiteVirtualTableCursor CursorFromIntPtr(
+ IntPtr pVtab,
+ IntPtr pCursor
+ )
+ {
+ if (pCursor == IntPtr.Zero)
+ {
+ SetTableError(pVtab, "invalid native cursor");
+ return null;
+ }
+
+ SQLiteVirtualTableCursor cursor;
+
+ if ((cursors != null) &&
+ cursors.TryGetValue(pCursor, out cursor))
+ {
+ return cursor;
+ }
+
+ SetTableError(pVtab, String.Format(
+ CultureInfo.CurrentCulture,
+ "managed cursor for {0} not found", pCursor));
+
+ return null;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual IntPtr CursorToIntPtr(
+ SQLiteVirtualTableCursor cursor
+ )
+ {
+ if ((cursor == null) || (cursors == null))
+ return IntPtr.Zero;
+
+ IntPtr pCursor = IntPtr.Zero;
+ bool success = false;
+
+ try
+ {
+ pCursor = AllocateCursor();
+
+ if (pCursor != IntPtr.Zero)
+ {
+ cursor.NativeHandle = pCursor;
+ cursors.Add(pCursor, cursor);
+ success = true;
+ }
+ }
+ finally
+ {
+ if (!success && (pCursor != IntPtr.Zero))
+ {
+ FreeCursor(pCursor);
+ pCursor = IntPtr.Zero;
+ }
+ }
+
+ return pCursor;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Table Declaration Helper Methods
+ protected virtual SQLiteErrorCode DeclareTable(
+ SQLiteConnection connection,
+ string sql,
+ ref string error
+ )
+ {
+ if (connection == null)
+ {
+ error = "invalid connection";
+ return SQLiteErrorCode.Error;
+ }
+
+ SQLiteBase sqliteBase = connection._sql;
+
+ if (sqliteBase == null)
+ {
+ error = "connection has invalid handle";
+ return SQLiteErrorCode.Error;
+ }
+
+ return sqliteBase.DeclareVirtualTable(this, sql, ref error);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Error Handling Helper Methods
+ protected virtual bool SetTableError(
+ IntPtr pVtab,
+ string error
+ )
+ {
+ try
+ {
+ if (LogErrors)
+ {
+ SQLiteLog.LogMessage(SQLiteErrorCode.Error,
+ String.Format(CultureInfo.CurrentCulture,
+ "Virtual table error: {0}", error)); /* throw */
+ }
+ }
+ catch
+ {
+ // do nothing.
+ }
+
+ if (pVtab == IntPtr.Zero)
+ return false;
+
+ int offset = IntPtr.Size + sizeof(int);
+ IntPtr pError = SQLiteMarshal.ReadIntPtr(pVtab, offset);
+
+ if (pError != IntPtr.Zero)
+ {
+ SQLiteMemory.Free(pError); pError = IntPtr.Zero;
+ SQLiteMarshal.WriteIntPtr(pVtab, offset, pError);
+ }
+
+ if (error == null)
+ return true;
+
+ bool success = false;
+
+ try
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(error);
+ SQLiteMarshal.WriteIntPtr(pVtab, offset, pError);
+ success = true;
+ }
+ finally
+ {
+ if (!success && (pError != IntPtr.Zero))
+ {
+ SQLiteMemory.Free(pError);
+ pError = IntPtr.Zero;
+ }
+ }
+
+ return success;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual bool SetTableError(
+ SQLiteVirtualTable table,
+ string error
+ )
+ {
+ if (table == null)
+ return false;
+
+ IntPtr pVtab = table.NativeHandle;
+
+ if (pVtab == IntPtr.Zero)
+ return false;
+
+ return SetTableError(pVtab, error);
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual bool SetCursorError(
+ SQLiteVirtualTableCursor cursor,
+ string error
+ )
+ {
+ if (cursor == null)
+ return false;
+
+ IntPtr pCursor = cursor.NativeHandle;
+
+ if (pCursor == IntPtr.Zero)
+ return false;
+
+ IntPtr pVtab = TableFromCursor(pCursor);
+
+ if (pVtab == IntPtr.Zero)
+ return false;
+
+ return SetTableError(pVtab, error);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Index Handling Helper Methods
+ protected virtual bool SetDefaultEstimatedCost(
+ SQLiteIndex index
+ )
+ {
+ if ((index == null) || (index.Outputs == null))
+ return false;
+
+ index.Outputs.EstimatedCost = DefaultCost;
+ return true;
+ }
+ #endregion
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Public Properties
+ private bool logErrors;
+ public virtual bool LogErrors
+ {
+ get { CheckDisposed(); return logErrors; }
+ set { CheckDisposed(); logErrors = value; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private bool logExceptions;
+ public virtual bool LogExceptions
+ {
+ get { CheckDisposed(); return logExceptions; }
+ set { CheckDisposed(); logExceptions = value; }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteNativeModule Members
+ private SQLiteErrorCode xCreate(
+ IntPtr pDb,
+ IntPtr pAux,
+ int argc,
+ IntPtr[] argv,
+ ref IntPtr pVtab,
+ ref IntPtr pError
+ )
+ {
+ try
+ {
+ string fileName = SQLiteString.StringFromUtf8IntPtr(
+ UnsafeNativeMethods.sqlite3_db_filename(pDb, IntPtr.Zero));
+
+ using (SQLiteConnection connection = new SQLiteConnection(
+ pDb, fileName, false))
+ {
+ SQLiteVirtualTable table = null;
+ string error = null;
+
+ if (Create(connection, pAux,
+ SQLiteString.StringArrayFromUtf8IntPtrArray(argv),
+ ref table, ref error) == SQLiteErrorCode.Ok)
+ {
+ if (table != null)
+ {
+ pVtab = TableToIntPtr(table);
+ return SQLiteErrorCode.Ok;
+ }
+ else
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(
+ "no table was created");
+ }
+ }
+ else
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(error);
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xConnect(
+ IntPtr pDb,
+ IntPtr pAux,
+ int argc,
+ IntPtr[] argv,
+ ref IntPtr pVtab,
+ ref IntPtr pError
+ )
+ {
+ try
+ {
+ string fileName = SQLiteString.StringFromUtf8IntPtr(
+ UnsafeNativeMethods.sqlite3_db_filename(pDb, IntPtr.Zero));
+
+ using (SQLiteConnection connection = new SQLiteConnection(
+ pDb, fileName, false))
+ {
+ SQLiteVirtualTable table = null;
+ string error = null;
+
+ if (Connect(connection, pAux,
+ SQLiteString.StringArrayFromUtf8IntPtrArray(argv),
+ ref table, ref error) == SQLiteErrorCode.Ok)
+ {
+ if (table != null)
+ {
+ pVtab = TableToIntPtr(table);
+ return SQLiteErrorCode.Ok;
+ }
+ else
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(
+ "no table was created");
+ }
+ }
+ else
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(error);
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ pError = SQLiteString.Utf8IntPtrFromString(e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xBestIndex(
+ IntPtr pVtab,
+ IntPtr pIndex
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ SQLiteIndex index = null;
+
+ SQLiteMarshal.IndexFromIntPtr(pIndex, ref index);
+
+ if (BestIndex(table, index) == SQLiteErrorCode.Ok)
+ {
+ SQLiteMarshal.IndexToIntPtr(index, pIndex);
+ return SQLiteErrorCode.Ok;
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xDisconnect(
+ IntPtr pVtab
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ if (Disconnect(table) == SQLiteErrorCode.Ok)
+ {
+ if (tables != null)
+ tables.Remove(pVtab);
+
+ return SQLiteErrorCode.Ok;
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ //
+ // NOTE: At this point, there is no way to report the error
+ // condition back to the caller; therefore, use the
+ // logging facility instead.
+ //
+ try
+ {
+ if (LogExceptions)
+ {
+ SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
+ String.Format(CultureInfo.CurrentCulture,
+ "Caught exception in \"xDisconnect\" method: {0}",
+ e)); /* throw */
+ }
+ }
+ catch
+ {
+ // do nothing.
+ }
+ }
+ finally
+ {
+ FreeTable(pVtab);
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xDestroy(
+ IntPtr pVtab
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ if (Destroy(table) == SQLiteErrorCode.Ok)
+ {
+ if (tables != null)
+ tables.Remove(pVtab);
+
+ return SQLiteErrorCode.Ok;
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ //
+ // NOTE: At this point, there is no way to report the error
+ // condition back to the caller; therefore, use the
+ // logging facility instead.
+ //
+ try
+ {
+ if (LogExceptions)
+ {
+ SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
+ String.Format(CultureInfo.CurrentCulture,
+ "Caught exception in \"xDestroy\" method: {0}",
+ e)); /* throw */
+ }
+ }
+ catch
+ {
+ // do nothing.
+ }
+ }
+ finally
+ {
+ FreeTable(pVtab);
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xOpen(
+ IntPtr pVtab,
+ ref IntPtr pCursor
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ SQLiteVirtualTableCursor cursor = null;
+
+ if (Open(table, ref cursor) == SQLiteErrorCode.Ok)
+ {
+ if (cursor != null)
+ {
+ pCursor = CursorToIntPtr(cursor);
+
+ if (pCursor != IntPtr.Zero)
+ {
+ return SQLiteErrorCode.Ok;
+ }
+ else
+ {
+ SetTableError(pVtab,
+ "no native cursor was created");
+ }
+ }
+ else
+ {
+ SetTableError(pVtab,
+ "no managed cursor was created");
+ }
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xClose(
+ IntPtr pCursor
+ )
+ {
+ IntPtr pVtab = IntPtr.Zero;
+
+ try
+ {
+ pVtab = TableFromCursor(pCursor);
+
+ SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
+ pVtab, pCursor);
+
+ if (cursor != null)
+ {
+ if (Close(cursor) == SQLiteErrorCode.Ok)
+ {
+ if (cursors != null)
+ cursors.Remove(pCursor);
+
+ return SQLiteErrorCode.Ok;
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+ finally
+ {
+ FreeCursor(pCursor);
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xFilter(
+ IntPtr pCursor,
+ int idxNum,
+ IntPtr idxStr,
+ int argc,
+ IntPtr[] argv
+ )
+ {
+ IntPtr pVtab = IntPtr.Zero;
+
+ try
+ {
+ pVtab = TableFromCursor(pCursor);
+
+ SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
+ pVtab, pCursor);
+
+ if (cursor != null)
+ {
+ if (Filter(cursor, idxNum,
+ SQLiteString.StringFromUtf8IntPtr(idxStr),
+ SQLiteMarshal.ValueArrayFromIntPtrArray(
+ argv)) == SQLiteErrorCode.Ok)
+ {
+ return SQLiteErrorCode.Ok;
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xNext(
+ IntPtr pCursor
+ )
+ {
+ IntPtr pVtab = IntPtr.Zero;
+
+ try
+ {
+ pVtab = TableFromCursor(pCursor);
+
+ SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
+ pVtab, pCursor);
+
+ if (cursor != null)
+ {
+ if (Next(cursor) == SQLiteErrorCode.Ok)
+ return SQLiteErrorCode.Ok;
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private int xEof(
+ IntPtr pCursor
+ )
+ {
+ IntPtr pVtab = IntPtr.Zero;
+
+ try
+ {
+ pVtab = TableFromCursor(pCursor);
+
+ SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
+ pVtab, pCursor);
+
+ if (cursor != null)
+ return Eof(cursor) ? 1 : 0;
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return 1;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xColumn(
+ IntPtr pCursor,
+ IntPtr pContext,
+ int index
+ )
+ {
+ IntPtr pVtab = IntPtr.Zero;
+
+ try
+ {
+ pVtab = TableFromCursor(pCursor);
+
+ SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
+ pVtab, pCursor);
+
+ if (cursor != null)
+ {
+ SQLiteContext context = new SQLiteContext(pContext);
+
+ return Column(cursor, context, index);
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xRowId(
+ IntPtr pCursor,
+ ref long rowId
+ )
+ {
+ IntPtr pVtab = IntPtr.Zero;
+
+ try
+ {
+ pVtab = TableFromCursor(pCursor);
+
+ SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
+ pVtab, pCursor);
+
+ if (cursor != null)
+ return RowId(cursor, ref rowId);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xUpdate(
+ IntPtr pVtab,
+ int nData,
+ IntPtr apData,
+ ref long rowId
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ SQLiteValue[] values =
+ SQLiteMarshal.ValueArrayFromSizeAndIntPtr(
+ nData, apData);
+
+ return Update(table, values, ref rowId);
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xBegin(
+ IntPtr pVtab
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return Begin(table);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xSync(
+ IntPtr pVtab
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return Sync(table);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xCommit(
+ IntPtr pVtab
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return Commit(table);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xRollback(
+ IntPtr pVtab
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return Rollback(table);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private int xFindFunction(
+ IntPtr pVtab,
+ int nArg,
+ IntPtr zName,
+ ref SQLiteCallback callback,
+ ref IntPtr pClientData
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ SQLiteFunction function = null;
+
+ if (FindFunction(
+ table, nArg,
+ SQLiteString.StringFromUtf8IntPtr(zName),
+ ref function, ref pClientData))
+ {
+ if (function != null)
+ {
+ callback = function.ScalarCallback;
+ return 1;
+ }
+ else
+ {
+ SetTableError(pVtab, "no function was created");
+ }
+ }
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return 0;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xRename(
+ IntPtr pVtab,
+ IntPtr zNew
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ {
+ return Rename(table,
+ SQLiteString.StringFromUtf8IntPtr(zNew));
+ }
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xSavepoint(
+ IntPtr pVtab,
+ int iSavepoint
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return Savepoint(table, iSavepoint);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xRelease(
+ IntPtr pVtab,
+ int iSavepoint
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return Release(table, iSavepoint);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private SQLiteErrorCode xRollbackTo(
+ IntPtr pVtab,
+ int iSavepoint
+ )
+ {
+ try
+ {
+ SQLiteVirtualTable table = TableFromIntPtr(pVtab);
+
+ if (table != null)
+ return RollbackTo(table, iSavepoint);
+ }
+ catch (Exception e) /* NOTE: Must catch ALL. */
+ {
+ SetTableError(pVtab, e.ToString());
+ }
+
+ return SQLiteErrorCode.Error;
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region ISQLiteManagedModule Members
+ private bool declared;
+ public virtual bool Declared
+ {
+ get { CheckDisposed(); return declared; }
+ internal set { declared = value; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ private string name;
+ public virtual string Name
+ {
+ get { CheckDisposed(); return name; }
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Create(
+ SQLiteConnection connection,
+ IntPtr pClientData,
+ string[] arguments,
+ ref SQLiteVirtualTable table,
+ ref string error
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Connect(
+ SQLiteConnection connection,
+ IntPtr pClientData,
+ string[] arguments,
+ ref SQLiteVirtualTable table,
+ ref string error
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode BestIndex(
+ SQLiteVirtualTable table,
+ SQLiteIndex index
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Disconnect(
+ SQLiteVirtualTable table
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Destroy(
+ SQLiteVirtualTable table
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Open(
+ SQLiteVirtualTable table,
+ ref SQLiteVirtualTableCursor cursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Close(
+ SQLiteVirtualTableCursor cursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Filter(
+ SQLiteVirtualTableCursor cursor,
+ int indexNumber,
+ string indexString,
+ SQLiteValue[] values
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Next(
+ SQLiteVirtualTableCursor cursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract bool Eof(
+ SQLiteVirtualTableCursor cursor
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Column(
+ SQLiteVirtualTableCursor cursor,
+ SQLiteContext context,
+ int index
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode RowId(
+ SQLiteVirtualTableCursor cursor,
+ ref long rowId
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Update(
+ SQLiteVirtualTable table,
+ SQLiteValue[] values,
+ ref long rowId
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Begin(
+ SQLiteVirtualTable table
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Sync(
+ SQLiteVirtualTable table
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Commit(
+ SQLiteVirtualTable table
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Rollback(
+ SQLiteVirtualTable table
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract bool FindFunction(
+ SQLiteVirtualTable table,
+ int argumentCount,
+ string name,
+ ref SQLiteFunction function,
+ ref IntPtr pClientData
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Rename(
+ SQLiteVirtualTable table,
+ string newName
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Savepoint(
+ SQLiteVirtualTable table,
+ int savepoint
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode Release(
+ SQLiteVirtualTable table,
+ int savepoint
+ );
+
+ ///////////////////////////////////////////////////////////////////////
+
+ public abstract SQLiteErrorCode RollbackTo(
+ SQLiteVirtualTable table,
+ int savepoint
+ );
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region IDisposable Members
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region IDisposable "Pattern" Members
+ private bool disposed;
+ private void CheckDisposed() /* throw */
+ {
+#if THROW_ON_DISPOSED
+ if (disposed)
+ {
+ throw new ObjectDisposedException(
+ typeof(SQLiteModule).Name);
+ }
+#endif
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposed)
+ {
+ //if (disposing)
+ //{
+ // ////////////////////////////////////
+ // // dispose managed resources here...
+ // ////////////////////////////////////
+ //}
+
+ //////////////////////////////////////
+ // release unmanaged resources here...
+ //////////////////////////////////////
+
+ try
+ {
+ UnsafeNativeMethods.sqlite3_dispose_module(
+ ref nativeModule);
+ }
+ catch (Exception e)
+ {
+ try
+ {
+ if (LogExceptions)
+ {
+ SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
+ String.Format(CultureInfo.CurrentCulture,
+ "Caught exception in \"Dispose\" method: {0}",
+ e)); /* throw */
+ }
+ }
+ catch
+ {
+ // do nothing.
+ }
+ }
+
+ disposed = true;
+ }
+ }
+ #endregion
+
+ ///////////////////////////////////////////////////////////////////////
+
+ #region Destructor
+ ~SQLiteModule()
+ {
+ Dispose(false);
+ }
+ #endregion
+ }
+ #endregion
+}
DELETED System.Data.SQLite/SQLiteModuleBase.cs
Index: System.Data.SQLite/SQLiteModuleBase.cs
==================================================================
--- System.Data.SQLite/SQLiteModuleBase.cs
+++ /dev/null
@@ -1,3549 +0,0 @@
-/********************************************************
- * ADO.NET 2.0 Data Provider for SQLite Version 3.X
- * Written by Joe Mistachkin (joe@mistachkin.com)
- *
- * Released to the public domain, use at your own risk!
- ********************************************************/
-
-using System.Collections.Generic;
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Text;
-
-#if TRACK_MEMORY_BYTES
-using System.Threading;
-#endif
-
-namespace System.Data.SQLite
-{
- #region SQLiteContext Helper Class
- public sealed class SQLiteContext
- {
- #region Private Data
- private IntPtr pContext;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Private Constructors
- internal SQLiteContext(IntPtr pContext)
- {
- this.pContext = pContext;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Methods
- public void SetNull()
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_null(pContext);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetDouble(double value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
-#if !PLATFORM_COMPACTFRAMEWORK
- UnsafeNativeMethods.sqlite3_result_double(pContext, value);
-#elif !SQLITE_STANDARD
- UnsafeNativeMethods.sqlite3_result_double_interop(pContext, ref value);
-#else
- throw new NotImplementedException();
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetInt(int value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_int(pContext, value);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetInt64(long value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
-#if !PLATFORM_COMPACTFRAMEWORK
- UnsafeNativeMethods.sqlite3_result_int64(pContext, value);
-#elif !SQLITE_STANDARD
- UnsafeNativeMethods.sqlite3_result_int64_interop(pContext, ref value);
-#else
- throw new NotImplementedException();
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetString(string value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- byte[] bytes = SQLiteString.GetUtf8BytesFromString(value);
-
- if (bytes == null)
- throw new ArgumentNullException("value");
-
- UnsafeNativeMethods.sqlite3_result_text(
- pContext, bytes, bytes.Length, (IntPtr)(-1));
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetError(string value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- byte[] bytes = SQLiteString.GetUtf8BytesFromString(value);
-
- if (bytes == null)
- throw new ArgumentNullException("value");
-
- UnsafeNativeMethods.sqlite3_result_error(
- pContext, bytes, bytes.Length);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetErrorCode(SQLiteErrorCode value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_error_code(pContext, value);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetErrorTooBig()
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_error_toobig(pContext);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetErrorNoMemory()
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_error_nomem(pContext);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetBlob(byte[] value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- if (value == null)
- throw new ArgumentNullException("value");
-
- UnsafeNativeMethods.sqlite3_result_blob(
- pContext, value, value.Length, (IntPtr)(-1));
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetZeroBlob(int value)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_zeroblob(pContext, value);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public void SetValue(IntPtr pValue)
- {
- if (pContext == IntPtr.Zero)
- throw new InvalidOperationException();
-
- UnsafeNativeMethods.sqlite3_result_value(pContext, pValue);
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteValue Helper Class
- public sealed class SQLiteValue
- {
- #region Private Data
- private IntPtr pValue;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Private Constructors
- internal SQLiteValue(IntPtr pValue)
- {
- this.pValue = pValue;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Private Methods
- private void PreventNativeAccess()
- {
- pValue = IntPtr.Zero;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private bool persisted;
- public bool Persisted
- {
- get { return persisted; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private object value;
- public object Value
- {
- get
- {
- if (!persisted)
- {
- throw new InvalidOperationException(
- "value was not persisted");
- }
-
- return value;
- }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Methods
- public TypeAffinity GetTypeAffinity()
- {
- if (pValue == IntPtr.Zero) return TypeAffinity.None;
- return UnsafeNativeMethods.sqlite3_value_type(pValue);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public int GetBytes()
- {
- if (pValue == IntPtr.Zero) return 0;
- return UnsafeNativeMethods.sqlite3_value_bytes(pValue);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public int GetInt()
- {
- if (pValue == IntPtr.Zero) return default(int);
- return UnsafeNativeMethods.sqlite3_value_int(pValue);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public long GetInt64()
- {
- if (pValue == IntPtr.Zero) return default(long);
-
-#if !PLATFORM_COMPACTFRAMEWORK
- return UnsafeNativeMethods.sqlite3_value_int64(pValue);
-#elif !SQLITE_STANDARD
- long value;
- UnsafeNativeMethods.sqlite3_value_int64_interop(pValue, out value);
- return value;
-#else
- throw new NotImplementedException();
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public double GetDouble()
- {
- if (pValue == IntPtr.Zero) return default(double);
-
-#if !PLATFORM_COMPACTFRAMEWORK
- return UnsafeNativeMethods.sqlite3_value_double(pValue);
-#elif !SQLITE_STANDARD
- double value;
- UnsafeNativeMethods.sqlite3_value_double_interop(pValue, out value);
- return value;
-#else
- throw new NotImplementedException();
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public string GetString()
- {
- if (pValue == IntPtr.Zero) return null;
- return SQLiteString.StringFromUtf8IntPtr(pValue, GetBytes());
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public byte[] GetBlob()
- {
- if (pValue == IntPtr.Zero) return null;
- return SQLiteMarshal.BytesFromIntPtr(pValue, GetBytes());
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public bool Persist()
- {
- switch (GetTypeAffinity())
- {
- case TypeAffinity.Uninitialized:
- {
- value = null;
- PreventNativeAccess();
- return (persisted = true);
- }
- case TypeAffinity.Int64:
- {
- value = GetInt64();
- PreventNativeAccess();
- return (persisted = true);
- }
- case TypeAffinity.Double:
- {
- value = GetDouble();
- PreventNativeAccess();
- return (persisted = true);
- }
- case TypeAffinity.Text:
- {
- value = GetString();
- PreventNativeAccess();
- return (persisted = true);
- }
- case TypeAffinity.Blob:
- {
- value = GetBytes();
- PreventNativeAccess();
- return (persisted = true);
- }
- case TypeAffinity.Null:
- {
- value = DBNull.Value;
- PreventNativeAccess();
- return (persisted = true);
- }
- default:
- {
- return false;
- }
- }
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndexConstraintOp Enumeration
- /* [Flags()] */
- public enum SQLiteIndexConstraintOp : byte
- {
- EqualTo = 2,
- GreaterThan = 4,
- LessThanOrEqualTo = 8,
- LessThan = 16,
- GreaterThanOrEqualTo = 32,
- Match = 64
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndexConstraint Helper Class
- public sealed class SQLiteIndexConstraint
- {
- #region Internal Constructors
- internal SQLiteIndexConstraint(
- UnsafeNativeMethods.sqlite3_index_constraint constraint
- )
- : this(constraint.iColumn, constraint.op, constraint.usable,
- constraint.iTermOffset)
- {
- // do nothing.
- }
- #endregion
-
- //////////////////////////////////////////////////////////////////////
-
- #region Private Constructors
- private SQLiteIndexConstraint(
- int iColumn,
- SQLiteIndexConstraintOp op,
- byte usable,
- int iTermOffset
- )
- {
- this.iColumn = iColumn;
- this.op = op;
- this.usable = usable;
- this.iTermOffset = iTermOffset;
- }
- #endregion
-
- //////////////////////////////////////////////////////////////////////
-
- #region Public Fields
- public int iColumn;
-
- //////////////////////////////////////////////////////////////////////
-
- public SQLiteIndexConstraintOp op;
-
- //////////////////////////////////////////////////////////////////////
-
- public byte usable;
-
- //////////////////////////////////////////////////////////////////////
-
- public int iTermOffset;
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndexOrderBy Helper Class
- public sealed class SQLiteIndexOrderBy
- {
- #region Internal Constructors
- internal SQLiteIndexOrderBy(
- UnsafeNativeMethods.sqlite3_index_orderby orderBy
- )
- : this(orderBy.iColumn, orderBy.desc)
- {
- // do nothing.
- }
- #endregion
-
- //////////////////////////////////////////////////////////////////////
-
- #region Private Constructors
- private SQLiteIndexOrderBy(
- int iColumn,
- byte desc
- )
- {
- this.iColumn = iColumn;
- this.desc = desc;
- }
- #endregion
-
- //////////////////////////////////////////////////////////////////////
-
- #region Public Fields
- public int iColumn; /* Column number */
-
- //////////////////////////////////////////////////////////////////////
-
- public byte desc; /* True for DESC. False for ASC. */
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndexConstraintUsage Helper Class
- public sealed class SQLiteIndexConstraintUsage
- {
- #region Internal Constructors
- internal SQLiteIndexConstraintUsage(
- UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage
- )
- : this(constraintUsage.argvIndex, constraintUsage.omit)
- {
- // do nothing.
- }
- #endregion
-
- //////////////////////////////////////////////////////////////////////
-
- #region Private Constructors
- private SQLiteIndexConstraintUsage(
- int argvIndex,
- byte omit
- )
- {
- this.argvIndex = argvIndex;
- this.omit = omit;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Fields
- public int argvIndex;
-
- ///////////////////////////////////////////////////////////////////////
-
- public byte omit;
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndexInputs Helper Class
- public sealed class SQLiteIndexInputs
- {
- #region Internal Constructors
- internal SQLiteIndexInputs(int nConstraint, int nOrderBy)
- {
- constraints = new SQLiteIndexConstraint[nConstraint];
- orderBys = new SQLiteIndexOrderBy[nOrderBy];
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private SQLiteIndexConstraint[] constraints;
- public SQLiteIndexConstraint[] Constraints
- {
- get { return constraints; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteIndexOrderBy[] orderBys;
- public SQLiteIndexOrderBy[] OrderBys
- {
- get { return orderBys; }
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndexOutputs Helper Class
- public sealed class SQLiteIndexOutputs
- {
- #region Internal Constructors
- internal SQLiteIndexOutputs(int nConstraint)
- {
- constraintUsages = new SQLiteIndexConstraintUsage[nConstraint];
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private SQLiteIndexConstraintUsage[] constraintUsages;
- public SQLiteIndexConstraintUsage[] ConstraintUsages
- {
- get { return constraintUsages; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private int indexNumber;
- public int IndexNumber
- {
- get { return indexNumber; }
- set { indexNumber = value; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private string indexString;
- public string IndexString
- {
- get { return indexString; }
- set { indexString = value; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private int needToFreeIndexString;
- public int NeedToFreeIndexString
- {
- get { return needToFreeIndexString; }
- set { needToFreeIndexString = value; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private int orderByConsumed;
- public int OrderByConsumed
- {
- get { return orderByConsumed; }
- set { orderByConsumed = value; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private double estimatedCost;
- public double EstimatedCost
- {
- get { return estimatedCost; }
- set { estimatedCost = value; }
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndex Helper Class
- public sealed class SQLiteIndex
- {
- #region Internal Constructors
- internal SQLiteIndex(
- int nConstraint,
- int nOrderBy
- )
- {
- inputs = new SQLiteIndexInputs(nConstraint, nOrderBy);
- outputs = new SQLiteIndexOutputs(nConstraint);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private SQLiteIndexInputs inputs;
- public SQLiteIndexInputs Inputs
- {
- get { return inputs; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteIndexOutputs outputs;
- public SQLiteIndexOutputs Outputs
- {
- get { return outputs; }
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteVirtualTable Base Class
- /* NOT SEALED */
- public class SQLiteVirtualTable : ISQLiteNativeHandle, IDisposable
- {
- #region Private Constants
- private const int ModuleNameIndex = 0;
- private const int DatabaseNameIndex = 1;
- private const int TableNameIndex = 2;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Constructors
- public SQLiteVirtualTable(
- string[] arguments
- )
- {
- this.arguments = arguments;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private string[] arguments;
- public virtual string[] Arguments
- {
- get { CheckDisposed(); return arguments; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public virtual string ModuleName
- {
- get
- {
- CheckDisposed();
-
- string[] arguments = Arguments;
-
- if ((arguments != null) &&
- (arguments.Length > ModuleNameIndex))
- {
- return arguments[ModuleNameIndex];
- }
- else
- {
- return null;
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public virtual string DatabaseName
- {
- get
- {
- CheckDisposed();
-
- string[] arguments = Arguments;
-
- if ((arguments != null) &&
- (arguments.Length > DatabaseNameIndex))
- {
- return arguments[DatabaseNameIndex];
- }
- else
- {
- return null;
- }
- }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public virtual string TableName
- {
- get
- {
- CheckDisposed();
-
- string[] arguments = Arguments;
-
- if ((arguments != null) &&
- (arguments.Length > TableNameIndex))
- {
- return arguments[TableNameIndex];
- }
- else
- {
- return null;
- }
- }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Methods
- public virtual bool Rename(
- string name
- )
- {
- CheckDisposed();
-
- if ((arguments != null) &&
- (arguments.Length > TableNameIndex))
- {
- arguments[TableNameIndex] = name;
- return true;
- }
-
- return false;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region ISQLiteNativeHandle Members
- private IntPtr nativeHandle;
- public virtual IntPtr NativeHandle
- {
- get { CheckDisposed(); return nativeHandle; }
- internal set { nativeHandle = value; }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region IDisposable Members
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region IDisposable "Pattern" Members
- private bool disposed;
- private void CheckDisposed() /* throw */
- {
-#if THROW_ON_DISPOSED
- if (disposed)
- {
- throw new ObjectDisposedException(
- typeof(SQLiteVirtualTable).Name);
- }
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual void Dispose(bool disposing)
- {
- if (!disposed)
- {
- //if (disposing)
- //{
- // ////////////////////////////////////
- // // dispose managed resources here...
- // ////////////////////////////////////
- //}
-
- //////////////////////////////////////
- // release unmanaged resources here...
- //////////////////////////////////////
-
- disposed = true;
- }
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteVirtualTableCursor Base Class
- /* NOT SEALED */
- public class SQLiteVirtualTableCursor : ISQLiteNativeHandle, IDisposable
- {
- #region Public Constructors
- public SQLiteVirtualTableCursor(
- SQLiteVirtualTable table
- )
- {
- this.table = table;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private SQLiteVirtualTable table;
- public virtual SQLiteVirtualTable Table
- {
- get { CheckDisposed(); return table; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private int indexNumber;
- public virtual int IndexNumber
- {
- get { CheckDisposed(); return indexNumber; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private string indexString;
- public virtual string IndexString
- {
- get { CheckDisposed(); return indexString; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteValue[] values;
- public virtual SQLiteValue[] Values
- {
- get { CheckDisposed(); return values; }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Protected Methods
- protected virtual int TryPersistValues(
- SQLiteValue[] values
- )
- {
- int result = 0;
-
- if (values != null)
- {
- foreach (SQLiteValue value in values)
- {
- if (value == null)
- continue;
-
- if (value.Persist())
- result++;
- }
- }
-
- return result;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Methods
- public virtual void Filter(
- int indexNumber,
- string indexString,
- SQLiteValue[] values
- )
- {
- CheckDisposed();
-
- if ((values != null) &&
- (TryPersistValues(values) != values.Length))
- {
- throw new SQLiteException(SQLiteErrorCode.Error,
- "failed to persist one or more values");
- }
-
- this.indexNumber = indexNumber;
- this.indexString = indexString;
- this.values = values;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region ISQLiteNativeHandle Members
- private IntPtr nativeHandle;
- public virtual IntPtr NativeHandle
- {
- get { CheckDisposed(); return nativeHandle; }
- internal set { nativeHandle = value; }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region IDisposable Members
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region IDisposable "Pattern" Members
- private bool disposed;
- private void CheckDisposed() /* throw */
- {
-#if THROW_ON_DISPOSED
- if (disposed)
- {
- throw new ObjectDisposedException(
- typeof(SQLiteVirtualTableCursor).Name);
- }
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual void Dispose(bool disposing)
- {
- if (!disposed)
- {
- //if (disposing)
- //{
- // ////////////////////////////////////
- // // dispose managed resources here...
- // ////////////////////////////////////
- //}
-
- //////////////////////////////////////
- // release unmanaged resources here...
- //////////////////////////////////////
-
- disposed = true;
- }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Destructor
- ~SQLiteVirtualTableCursor()
- {
- Dispose(false);
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region ISQLiteNativeHandle Interface
- public interface ISQLiteNativeHandle
- {
- IntPtr NativeHandle { get; }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region ISQLiteNativeModule Interface
- public interface ISQLiteNativeModule
- {
- SQLiteErrorCode xCreate(
- IntPtr pDb,
- IntPtr pAux,
- int argc,
- IntPtr[] argv,
- ref IntPtr pVtab,
- ref IntPtr pError
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xConnect(
- IntPtr pDb,
- IntPtr pAux,
- int argc,
- IntPtr[] argv,
- ref IntPtr pVtab,
- ref IntPtr pError
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xBestIndex(
- IntPtr pVtab,
- IntPtr pIndex
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xDisconnect(
- IntPtr pVtab
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xDestroy(
- IntPtr pVtab
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xOpen(
- IntPtr pVtab,
- ref IntPtr pCursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xClose(
- IntPtr pCursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xFilter(
- IntPtr pCursor,
- int idxNum,
- IntPtr idxStr,
- int argc,
- IntPtr[] argv
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xNext(
- IntPtr pCursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- int xEof(
- IntPtr pCursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xColumn(
- IntPtr pCursor,
- IntPtr pContext,
- int index
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xRowId(
- IntPtr pCursor,
- ref long rowId
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xUpdate(
- IntPtr pVtab,
- int nData,
- IntPtr apData,
- ref long rowId
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xBegin(
- IntPtr pVtab
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xSync(
- IntPtr pVtab
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xCommit(
- IntPtr pVtab
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xRollback(
- IntPtr pVtab
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- int xFindFunction(
- IntPtr pVtab,
- int nArg,
- IntPtr zName,
- ref SQLiteCallback callback,
- ref IntPtr pClientData
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xRename(
- IntPtr pVtab,
- IntPtr zNew
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xSavepoint(
- IntPtr pVtab,
- int iSavepoint
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xRelease(
- IntPtr pVtab,
- int iSavepoint
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode xRollbackTo(
- IntPtr pVtab,
- int iSavepoint
- );
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region ISQLiteManagedModule Interface
- public interface ISQLiteManagedModule
- {
- bool Declared { get; }
- string Name { get; }
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Create(
- SQLiteConnection connection, /* in */
- IntPtr pClientData, /* in */
- string[] arguments, /* in */
- ref SQLiteVirtualTable table, /* out */
- ref string error /* out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Connect(
- SQLiteConnection connection, /* in */
- IntPtr pClientData, /* in */
- string[] arguments, /* in */
- ref SQLiteVirtualTable table, /* out */
- ref string error /* out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode BestIndex(
- SQLiteVirtualTable table, /* in */
- SQLiteIndex index /* in, out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Disconnect(
- SQLiteVirtualTable table /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Destroy(
- SQLiteVirtualTable table /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Open(
- SQLiteVirtualTable table, /* in */
- ref SQLiteVirtualTableCursor cursor /* out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Close(
- SQLiteVirtualTableCursor cursor /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Filter(
- SQLiteVirtualTableCursor cursor, /* in */
- int indexNumber, /* in */
- string indexString, /* in */
- SQLiteValue[] values /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Next(
- SQLiteVirtualTableCursor cursor /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- bool Eof(
- SQLiteVirtualTableCursor cursor /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Column(
- SQLiteVirtualTableCursor cursor, /* in */
- SQLiteContext context, /* in */
- int index /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode RowId(
- SQLiteVirtualTableCursor cursor, /* in */
- ref long rowId /* out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Update(
- SQLiteVirtualTable table, /* in */
- SQLiteValue[] values, /* in */
- ref long rowId /* in, out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Begin(
- SQLiteVirtualTable table /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Sync(
- SQLiteVirtualTable table /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Commit(
- SQLiteVirtualTable table /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Rollback(
- SQLiteVirtualTable table /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- bool FindFunction(
- SQLiteVirtualTable table, /* in */
- int argumentCount, /* in */
- string name, /* in */
- ref SQLiteFunction function, /* out */
- ref IntPtr pClientData /* out */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Rename(
- SQLiteVirtualTable table, /* in */
- string newName /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Savepoint(
- SQLiteVirtualTable table, /* in */
- int savepoint /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode Release(
- SQLiteVirtualTable table, /* in */
- int savepoint /* in */
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- SQLiteErrorCode RollbackTo(
- SQLiteVirtualTable table, /* in */
- int savepoint /* in */
- );
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteMemory Static Class
- internal static class SQLiteMemory
- {
- #region Private Data
-#if TRACK_MEMORY_BYTES
-#if PLATFORM_COMPACTFRAMEWORK
- private static object syncRoot = new object();
-#endif
-
- ///////////////////////////////////////////////////////////////////////
-
- private static int bytesAllocated;
- private static int maximumBytesAllocated;
-#endif
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Memory Allocation Helper Methods
- public static IntPtr Allocate(int size)
- {
- IntPtr pMemory = UnsafeNativeMethods.sqlite3_malloc(size);
-
-#if TRACK_MEMORY_BYTES
- if (pMemory != IntPtr.Zero)
- {
- int blockSize = Size(pMemory);
-
- if (blockSize > 0)
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- Interlocked.Add(ref bytesAllocated, blockSize);
- Interlocked.Add(ref maximumBytesAllocated, blockSize);
-#else
- lock (syncRoot)
- {
- bytesAllocated += blockSize;
- maximumBytesAllocated += blockSize;
- }
-#endif
- }
- }
-#endif
-
- return pMemory;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static int Size(IntPtr pMemory)
- {
-#if !SQLITE_STANDARD
- return UnsafeNativeMethods.sqlite3_malloc_size_interop(pMemory);
-#else
- return 0;
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static void Free(IntPtr pMemory)
- {
-#if TRACK_MEMORY_BYTES
- if (pMemory != IntPtr.Zero)
- {
- int blockSize = Size(pMemory);
-
- if (blockSize > 0)
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- Interlocked.Add(ref bytesAllocated, -blockSize);
-#else
- lock (syncRoot)
- {
- bytesAllocated -= blockSize;
- }
-#endif
- }
- }
-#endif
-
- UnsafeNativeMethods.sqlite3_free(pMemory);
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteString Static Class
- internal static class SQLiteString
- {
- #region Private Constants
- private static int ThirtyBits = 0x3fffffff;
- private static readonly Encoding Utf8Encoding = Encoding.UTF8;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region UTF-8 Encoding Helper Methods
- public static byte[] GetUtf8BytesFromString(
- string value
- )
- {
- if (value == null)
- return null;
-
- return Utf8Encoding.GetBytes(value);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static string GetStringFromUtf8Bytes(
- byte[] bytes
- )
- {
- if (bytes == null)
- return null;
-
-#if !PLATFORM_COMPACTFRAMEWORK
- return Utf8Encoding.GetString(bytes);
-#else
- return Utf8Encoding.GetString(bytes, 0, bytes.Length);
-#endif
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region UTF-8 String Helper Methods
- public static int ProbeForUtf8ByteLength(
- IntPtr pValue,
- int limit
- )
- {
- int length = 0;
-
- if (pValue != IntPtr.Zero)
- {
- do
- {
- if (Marshal.ReadByte(pValue, length) == 0)
- break;
-
- if (length >= limit)
- break;
-
- length++;
- } while (true);
- }
-
- return length;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static string StringFromUtf8IntPtr(
- IntPtr pValue
- )
- {
- return StringFromUtf8IntPtr(pValue,
- ProbeForUtf8ByteLength(pValue, ThirtyBits));
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static string StringFromUtf8IntPtr(
- IntPtr pValue,
- int length
- )
- {
- if (pValue == IntPtr.Zero)
- return null;
-
- if (length > 0)
- {
- byte[] bytes = new byte[length];
-
- Marshal.Copy(pValue, bytes, 0, length);
-
- return GetStringFromUtf8Bytes(bytes);
- }
-
- return String.Empty;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static IntPtr Utf8IntPtrFromString(
- string value
- )
- {
- if (value == null)
- return IntPtr.Zero;
-
- IntPtr result = IntPtr.Zero;
- byte[] bytes = GetUtf8BytesFromString(value);
-
- if (bytes == null)
- return IntPtr.Zero;
-
- int length = bytes.Length;
-
- result = SQLiteMemory.Allocate(length + 1);
-
- if (result == IntPtr.Zero)
- return IntPtr.Zero;
-
- Marshal.Copy(bytes, 0, result, length);
- Marshal.WriteByte(result, length, 0);
-
- return result;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region UTF-8 String Array Helper Methods
- public static string[] StringArrayFromUtf8IntPtrArray(
- IntPtr[] pValues
- )
- {
- if (pValues == null)
- return null;
-
- string[] result = new string[pValues.Length];
-
- for (int index = 0; index < result.Length; index++)
- result[index] = StringFromUtf8IntPtr(pValues[index]);
-
- return result;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static IntPtr[] Utf8IntPtrArrayFromStringArray(
- string[] values
- )
- {
- if (values == null)
- return null;
-
- IntPtr[] result = new IntPtr[values.Length];
-
- for (int index = 0; index < result.Length; index++)
- result[index] = Utf8IntPtrFromString(values[index]);
-
- return result;
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteMarshal Static Class
- internal static class SQLiteMarshal
- {
- #region IntPtr Helper Methods
- public static IntPtr IntPtrForOffset(
- IntPtr pointer,
- int offset
- )
- {
- return new IntPtr(pointer.ToInt64() + offset);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Marshal Read Helper Methods
- public static int ReadInt32(
- IntPtr pointer,
- int offset
- )
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- return Marshal.ReadInt32(pointer, offset);
-#else
- return Marshal.ReadInt32(IntPtrForOffset(pointer, offset));
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static double ReadDouble(
- IntPtr pointer,
- int offset
- )
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- return BitConverter.Int64BitsToDouble(Marshal.ReadInt64(
- pointer, offset));
-#else
- return BitConverter.ToDouble(BitConverter.GetBytes(
- Marshal.ReadInt64(IntPtrForOffset(pointer, offset))), 0);
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static IntPtr ReadIntPtr(
- IntPtr pointer,
- int offset
- )
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- return Marshal.ReadIntPtr(pointer, offset);
-#else
- return Marshal.ReadIntPtr(IntPtrForOffset(pointer, offset));
-#endif
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Marshal Write Helper Methods
- public static void WriteInt32(
- IntPtr pointer,
- int offset,
- int value
- )
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- Marshal.WriteInt32(pointer, offset, value);
-#else
- Marshal.WriteInt32(IntPtrForOffset(pointer, offset), value);
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static void WriteDouble(
- IntPtr pointer,
- int offset,
- double value
- )
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- Marshal.WriteInt64(pointer, offset,
- BitConverter.DoubleToInt64Bits(value));
-#else
- Marshal.WriteInt64(IntPtrForOffset(pointer, offset),
- BitConverter.ToInt64(BitConverter.GetBytes(value), 0));
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static void WriteIntPtr(
- IntPtr pointer,
- int offset,
- IntPtr value
- )
- {
-#if !PLATFORM_COMPACTFRAMEWORK
- Marshal.WriteIntPtr(pointer, offset, value);
-#else
- Marshal.WriteIntPtr(IntPtrForOffset(pointer, offset), value);
-#endif
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Byte Array Helper Methods
- public static byte[] BytesFromIntPtr(
- IntPtr pValue,
- int length
- )
- {
- if (pValue == IntPtr.Zero)
- return null;
-
- if (length == 0)
- return new byte[0];
-
- byte[] result = new byte[length];
-
- Marshal.Copy(pValue, result, 0, length);
-
- return result;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static IntPtr BytesToIntPtr(
- byte[] value
- )
- {
- if (value == null)
- return IntPtr.Zero;
-
- int length = value.Length;
-
- if (length == 0)
- return IntPtr.Zero;
-
- IntPtr result = SQLiteMemory.Allocate(length);
-
- if (result == IntPtr.Zero)
- return IntPtr.Zero;
-
- Marshal.Copy(value, 0, result, length);
-
- return result;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region SQLiteValue Helper Methods
- public static SQLiteValue[] ValueArrayFromSizeAndIntPtr(
- int nData,
- IntPtr apData
- )
- {
- if (nData < 0)
- return null;
-
- if (apData == IntPtr.Zero)
- return null;
-
- SQLiteValue[] result = new SQLiteValue[nData];
-
- for (int index = 0, offset = 0;
- index < result.Length;
- index++, offset += IntPtr.Size)
- {
- IntPtr pData = ReadIntPtr(apData, offset);
-
- result[index] = (pData != IntPtr.Zero) ?
- new SQLiteValue(pData) : null;
- }
-
- return result;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static SQLiteValue[] ValueArrayFromIntPtrArray(
- IntPtr[] values
- )
- {
- if (values == null)
- return null;
-
- SQLiteValue[] result = new SQLiteValue[values.Length];
-
- for (int index = 0; index < result.Length; index++)
- result[index] = new SQLiteValue(values[index]);
-
- return result;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region SQLiteIndex Helper Methods
- public static void IndexFromIntPtr(
- IntPtr pIndex,
- ref SQLiteIndex index
- )
- {
- if (pIndex == IntPtr.Zero)
- return;
-
- int offset = 0;
-
- int nConstraint = ReadInt32(pIndex, offset);
-
- offset += sizeof(int);
-
- IntPtr pConstraint = ReadIntPtr(pIndex, offset);
-
- offset += IntPtr.Size;
-
- int nOrderBy = ReadInt32(pIndex, offset);
-
- index = new SQLiteIndex(nConstraint, nOrderBy);
-
- offset += sizeof(int);
-
- IntPtr pOrderBy = ReadIntPtr(pIndex, offset);
-
- offset += IntPtr.Size;
-
- IntPtr pConstraintUsage = ReadIntPtr(pIndex, offset);
-
- offset += IntPtr.Size;
-
- index.Outputs.IndexNumber = ReadInt32(pIndex, offset);
-
- offset += sizeof(int);
-
- index.Outputs.IndexString = SQLiteString.StringFromUtf8IntPtr(
- IntPtrForOffset(pIndex, offset));
-
- offset += IntPtr.Size;
-
- index.Outputs.NeedToFreeIndexString = ReadInt32(pIndex, offset);
-
- offset += sizeof(int);
-
- index.Outputs.OrderByConsumed = ReadInt32(pIndex, offset);
-
- offset += sizeof(int);
-
- index.Outputs.EstimatedCost = ReadDouble(pIndex, offset);
-
- int sizeOfConstraintType = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_index_constraint));
-
- for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
- {
- UnsafeNativeMethods.sqlite3_index_constraint constraint =
- new UnsafeNativeMethods.sqlite3_index_constraint();
-
- Marshal.PtrToStructure(IntPtrForOffset(pConstraint,
- iConstraint * sizeOfConstraintType), constraint);
-
- index.Inputs.Constraints[iConstraint] =
- new SQLiteIndexConstraint(constraint);
- }
-
- int sizeOfOrderByType = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_index_orderby));
-
- for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++)
- {
- UnsafeNativeMethods.sqlite3_index_orderby orderBy =
- new UnsafeNativeMethods.sqlite3_index_orderby();
-
- Marshal.PtrToStructure(IntPtrForOffset(pOrderBy,
- iOrderBy * sizeOfOrderByType), orderBy);
-
- index.Inputs.OrderBys[iOrderBy] =
- new SQLiteIndexOrderBy(orderBy);
- }
-
- int sizeOfConstraintUsageType = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_index_constraint_usage));
-
- for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
- {
- UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage =
- new UnsafeNativeMethods.sqlite3_index_constraint_usage();
-
- Marshal.PtrToStructure(IntPtrForOffset(pConstraintUsage,
- iConstraint * sizeOfConstraintUsageType), constraintUsage);
-
- index.Outputs.ConstraintUsages[iConstraint] =
- new SQLiteIndexConstraintUsage(constraintUsage);
- }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public static void IndexToIntPtr(
- SQLiteIndex index,
- IntPtr pIndex
- )
- {
- if ((index == null) || (index.Inputs == null) ||
- (index.Inputs.Constraints == null) ||
- (index.Inputs.OrderBys == null) || (index.Outputs == null) ||
- (index.Outputs.ConstraintUsages == null))
- {
- return;
- }
-
- if (pIndex == IntPtr.Zero)
- return;
-
- int offset = 0;
-
- int nConstraint = ReadInt32(pIndex, offset);
-
- if (nConstraint != index.Inputs.Constraints.Length)
- return;
-
- if (nConstraint != index.Outputs.ConstraintUsages.Length)
- return;
-
- offset += sizeof(int);
-
- IntPtr pConstraint = ReadIntPtr(pIndex, offset);
-
- offset += IntPtr.Size;
-
- int nOrderBy = ReadInt32(pIndex, offset);
-
- offset += sizeof(int);
-
- IntPtr pOrderBy = ReadIntPtr(pIndex, offset);
-
- offset += IntPtr.Size;
-
- IntPtr pConstraintUsage = ReadIntPtr(pIndex, offset);
-
- int sizeOfConstraintType = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_index_constraint));
-
- for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
- {
- UnsafeNativeMethods.sqlite3_index_constraint constraint =
- new UnsafeNativeMethods.sqlite3_index_constraint(
- index.Inputs.Constraints[iConstraint]);
-
- Marshal.StructureToPtr(
- constraint, IntPtrForOffset(pConstraint,
- iConstraint * sizeOfConstraintType), false);
-
- index.Inputs.Constraints[iConstraint] =
- new SQLiteIndexConstraint(constraint);
- }
-
- int sizeOfOrderByType = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_index_orderby));
-
- for (int iOrderBy = 0; iOrderBy < nOrderBy; iOrderBy++)
- {
- UnsafeNativeMethods.sqlite3_index_orderby orderBy =
- new UnsafeNativeMethods.sqlite3_index_orderby(
- index.Inputs.OrderBys[iOrderBy]);
-
- Marshal.StructureToPtr(
- orderBy, IntPtrForOffset(pOrderBy,
- iOrderBy * sizeOfOrderByType), false);
-
- index.Inputs.OrderBys[iOrderBy] =
- new SQLiteIndexOrderBy(orderBy);
- }
-
- int sizeOfConstraintUsageType = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_index_constraint_usage));
-
- for (int iConstraint = 0; iConstraint < nConstraint; iConstraint++)
- {
- UnsafeNativeMethods.sqlite3_index_constraint_usage constraintUsage =
- new UnsafeNativeMethods.sqlite3_index_constraint_usage(
- index.Outputs.ConstraintUsages[iConstraint]);
-
- Marshal.StructureToPtr(
- constraintUsage, IntPtrForOffset(pConstraintUsage,
- iConstraint * sizeOfConstraintUsageType), false);
-
- index.Outputs.ConstraintUsages[iConstraint] =
- new SQLiteIndexConstraintUsage(constraintUsage);
- }
- }
- #endregion
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////////
-
- #region SQLiteModule Base Class
- /* NOT SEALED */
- public abstract class SQLiteModuleBase :
- ISQLiteManagedModule, /*ISQLiteNativeModule,*/ IDisposable
- {
- #region Private Constants
- private const double DefaultCost = double.MaxValue;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Private Data
- private UnsafeNativeMethods.sqlite3_module nativeModule;
- private Dictionary tables;
- private Dictionary cursors;
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Internal Methods
- internal UnsafeNativeMethods.sqlite3_module GetNativeModule()
- {
- return nativeModule;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- internal UnsafeNativeMethods.sqlite3_module CreateNativeModule()
- {
- return CreateNativeModule(CreateNativeModuleImpl());
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Constructors
- public SQLiteModuleBase(string name)
- {
- if (name == null)
- throw new ArgumentNullException("name");
-
- this.name = name;
- this.tables = new Dictionary();
- this.cursors = new Dictionary();
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Private Methods
- private UnsafeNativeMethods.sqlite3_module CreateNativeModule(
- ISQLiteNativeModule module
- )
- {
- nativeModule = new UnsafeNativeMethods.sqlite3_module();
- nativeModule.iVersion = 2;
-
- if (module != null)
- {
- nativeModule.xCreate = new UnsafeNativeMethods.xCreate(
- module.xCreate);
-
- nativeModule.xConnect = new UnsafeNativeMethods.xConnect(
- module.xConnect);
-
- nativeModule.xBestIndex = new UnsafeNativeMethods.xBestIndex(
- module.xBestIndex);
-
- nativeModule.xDisconnect = new UnsafeNativeMethods.xDisconnect(
- module.xDisconnect);
-
- nativeModule.xDestroy = new UnsafeNativeMethods.xDestroy(
- module.xDestroy);
-
- nativeModule.xOpen = new UnsafeNativeMethods.xOpen(
- module.xOpen);
-
- nativeModule.xClose = new UnsafeNativeMethods.xClose(
- module.xClose);
-
- nativeModule.xFilter = new UnsafeNativeMethods.xFilter(
- module.xFilter);
-
- nativeModule.xNext = new UnsafeNativeMethods.xNext(
- module.xNext);
-
- nativeModule.xEof = new UnsafeNativeMethods.xEof(module.xEof);
-
- nativeModule.xColumn = new UnsafeNativeMethods.xColumn(
- module.xColumn);
-
- nativeModule.xRowId = new UnsafeNativeMethods.xRowId(
- module.xRowId);
-
- nativeModule.xUpdate = new UnsafeNativeMethods.xUpdate(
- module.xUpdate);
-
- nativeModule.xBegin = new UnsafeNativeMethods.xBegin(
- module.xBegin);
-
- nativeModule.xSync = new UnsafeNativeMethods.xSync(
- module.xSync);
-
- nativeModule.xCommit = new UnsafeNativeMethods.xCommit(
- module.xCommit);
-
- nativeModule.xRollback = new UnsafeNativeMethods.xRollback(
- module.xRollback);
-
- nativeModule.xFindFunction = new UnsafeNativeMethods.xFindFunction(
- module.xFindFunction);
-
- nativeModule.xRename = new UnsafeNativeMethods.xRename(
- module.xRename);
-
- nativeModule.xSavepoint = new UnsafeNativeMethods.xSavepoint(
- module.xSavepoint);
-
- nativeModule.xRelease = new UnsafeNativeMethods.xRelease(
- module.xRelease);
-
- nativeModule.xRollbackTo = new UnsafeNativeMethods.xRollbackTo(
- module.xRollbackTo);
- }
- else
- {
- nativeModule.xCreate = new UnsafeNativeMethods.xCreate(
- xCreate);
-
- nativeModule.xConnect = new UnsafeNativeMethods.xConnect(
- xConnect);
-
- nativeModule.xBestIndex = new UnsafeNativeMethods.xBestIndex(
- xBestIndex);
-
- nativeModule.xDisconnect = new UnsafeNativeMethods.xDisconnect(
- xDisconnect);
-
- nativeModule.xDestroy = new UnsafeNativeMethods.xDestroy(
- xDestroy);
-
- nativeModule.xOpen = new UnsafeNativeMethods.xOpen(xOpen);
- nativeModule.xClose = new UnsafeNativeMethods.xClose(xClose);
-
- nativeModule.xFilter = new UnsafeNativeMethods.xFilter(
- xFilter);
-
- nativeModule.xNext = new UnsafeNativeMethods.xNext(xNext);
- nativeModule.xEof = new UnsafeNativeMethods.xEof(xEof);
-
- nativeModule.xColumn = new UnsafeNativeMethods.xColumn(
- xColumn);
-
- nativeModule.xRowId = new UnsafeNativeMethods.xRowId(xRowId);
-
- nativeModule.xUpdate = new UnsafeNativeMethods.xUpdate(
- xUpdate);
-
- nativeModule.xBegin = new UnsafeNativeMethods.xBegin(xBegin);
- nativeModule.xSync = new UnsafeNativeMethods.xSync(xSync);
-
- nativeModule.xCommit = new UnsafeNativeMethods.xCommit(
- xCommit);
-
- nativeModule.xRollback = new UnsafeNativeMethods.xRollback(
- xRollback);
-
- nativeModule.xFindFunction = new UnsafeNativeMethods.xFindFunction(
- xFindFunction);
-
- nativeModule.xRename = new UnsafeNativeMethods.xRename(
- xRename);
-
- nativeModule.xSavepoint = new UnsafeNativeMethods.xSavepoint(
- xSavepoint);
-
- nativeModule.xRelease = new UnsafeNativeMethods.xRelease(
- xRelease);
-
- nativeModule.xRollbackTo = new UnsafeNativeMethods.xRollbackTo(
- xRollbackTo);
- }
-
- return nativeModule;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Protected Members
- #region Module Helper Methods
- protected virtual ISQLiteNativeModule CreateNativeModuleImpl()
- {
- return null; /* NOTE: Use built-in defaults. */
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Native Table Helper Methods
- protected virtual IntPtr AllocateTable()
- {
- int size = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_vtab));
-
- return SQLiteMemory.Allocate(size);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual void ZeroTable(
- IntPtr pVtab
- )
- {
- if (pVtab == IntPtr.Zero)
- return;
-
- int offset = 0;
-
- SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero);
-
- offset += IntPtr.Size;
-
- SQLiteMarshal.WriteInt32(pVtab, offset, 0);
-
- offset += sizeof(int);
-
- SQLiteMarshal.WriteIntPtr(pVtab, offset, IntPtr.Zero);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual void FreeTable(
- IntPtr pVtab
- )
- {
- SetTableError(pVtab, null);
- SQLiteMemory.Free(pVtab);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Native Cursor Helper Methods
- protected virtual IntPtr AllocateCursor()
- {
- int size = Marshal.SizeOf(typeof(
- UnsafeNativeMethods.sqlite3_vtab_cursor));
-
- return SQLiteMemory.Allocate(size);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual void FreeCursor(
- IntPtr pCursor
- )
- {
- SQLiteMemory.Free(pCursor);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Table Lookup Methods
- protected virtual IntPtr TableFromCursor(
- IntPtr pCursor
- )
- {
- if (pCursor == IntPtr.Zero)
- return IntPtr.Zero;
-
- return Marshal.ReadIntPtr(pCursor);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual SQLiteVirtualTable TableFromIntPtr(
- IntPtr pVtab
- )
- {
- if (pVtab == IntPtr.Zero)
- {
- SetTableError(pVtab, "invalid native table");
- return null;
- }
-
- SQLiteVirtualTable table;
-
- if ((tables != null) &&
- tables.TryGetValue(pVtab, out table))
- {
- return table;
- }
-
- SetTableError(pVtab, String.Format(
- CultureInfo.CurrentCulture,
- "managed table for {0} not found", pVtab));
-
- return null;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual IntPtr TableToIntPtr(
- SQLiteVirtualTable table
- )
- {
- if ((table == null) || (tables == null))
- return IntPtr.Zero;
-
- IntPtr pVtab = IntPtr.Zero;
- bool success = false;
-
- try
- {
- pVtab = AllocateTable();
-
- if (pVtab != IntPtr.Zero)
- {
- ZeroTable(pVtab);
- table.NativeHandle = pVtab;
- tables.Add(pVtab, table);
- success = true;
- }
- }
- finally
- {
- if (!success && (pVtab != IntPtr.Zero))
- {
- FreeTable(pVtab);
- pVtab = IntPtr.Zero;
- }
- }
-
- return pVtab;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Cursor Lookup Methods
- protected virtual SQLiteVirtualTableCursor CursorFromIntPtr(
- IntPtr pVtab,
- IntPtr pCursor
- )
- {
- if (pCursor == IntPtr.Zero)
- {
- SetTableError(pVtab, "invalid native cursor");
- return null;
- }
-
- SQLiteVirtualTableCursor cursor;
-
- if ((cursors != null) &&
- cursors.TryGetValue(pCursor, out cursor))
- {
- return cursor;
- }
-
- SetTableError(pVtab, String.Format(
- CultureInfo.CurrentCulture,
- "managed cursor for {0} not found", pCursor));
-
- return null;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual IntPtr CursorToIntPtr(
- SQLiteVirtualTableCursor cursor
- )
- {
- if ((cursor == null) || (cursors == null))
- return IntPtr.Zero;
-
- IntPtr pCursor = IntPtr.Zero;
- bool success = false;
-
- try
- {
- pCursor = AllocateCursor();
-
- if (pCursor != IntPtr.Zero)
- {
- cursor.NativeHandle = pCursor;
- cursors.Add(pCursor, cursor);
- success = true;
- }
- }
- finally
- {
- if (!success && (pCursor != IntPtr.Zero))
- {
- FreeCursor(pCursor);
- pCursor = IntPtr.Zero;
- }
- }
-
- return pCursor;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Table Declaration Helper Methods
- protected virtual SQLiteErrorCode DeclareTable(
- SQLiteConnection connection,
- string sql,
- ref string error
- )
- {
- if (connection == null)
- {
- error = "invalid connection";
- return SQLiteErrorCode.Error;
- }
-
- SQLiteBase sqliteBase = connection._sql;
-
- if (sqliteBase == null)
- {
- error = "connection has invalid handle";
- return SQLiteErrorCode.Error;
- }
-
- return sqliteBase.DeclareVirtualTable(this, sql, ref error);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Error Handling Helper Methods
- protected virtual bool SetTableError(
- IntPtr pVtab,
- string error
- )
- {
- try
- {
- if (LogErrors)
- {
- SQLiteLog.LogMessage(SQLiteErrorCode.Error,
- String.Format(CultureInfo.CurrentCulture,
- "Virtual table error: {0}", error)); /* throw */
- }
- }
- catch
- {
- // do nothing.
- }
-
- if (pVtab == IntPtr.Zero)
- return false;
-
- int offset = IntPtr.Size + sizeof(int);
- IntPtr pError = SQLiteMarshal.ReadIntPtr(pVtab, offset);
-
- if (pError != IntPtr.Zero)
- {
- SQLiteMemory.Free(pError); pError = IntPtr.Zero;
- SQLiteMarshal.WriteIntPtr(pVtab, offset, pError);
- }
-
- if (error == null)
- return true;
-
- bool success = false;
-
- try
- {
- pError = SQLiteString.Utf8IntPtrFromString(error);
- SQLiteMarshal.WriteIntPtr(pVtab, offset, pError);
- success = true;
- }
- finally
- {
- if (!success && (pError != IntPtr.Zero))
- {
- SQLiteMemory.Free(pError);
- pError = IntPtr.Zero;
- }
- }
-
- return success;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual bool SetTableError(
- SQLiteVirtualTable table,
- string error
- )
- {
- if (table == null)
- return false;
-
- IntPtr pVtab = table.NativeHandle;
-
- if (pVtab == IntPtr.Zero)
- return false;
-
- return SetTableError(pVtab, error);
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual bool SetCursorError(
- SQLiteVirtualTableCursor cursor,
- string error
- )
- {
- if (cursor == null)
- return false;
-
- IntPtr pCursor = cursor.NativeHandle;
-
- if (pCursor == IntPtr.Zero)
- return false;
-
- IntPtr pVtab = TableFromCursor(pCursor);
-
- if (pVtab == IntPtr.Zero)
- return false;
-
- return SetTableError(pVtab, error);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Index Handling Helper Methods
- protected virtual bool SetDefaultEstimatedCost(
- SQLiteIndex index
- )
- {
- if ((index == null) || (index.Outputs == null))
- return false;
-
- index.Outputs.EstimatedCost = DefaultCost;
- return true;
- }
- #endregion
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Public Properties
- private bool logErrors;
- public virtual bool LogErrors
- {
- get { CheckDisposed(); return logErrors; }
- set { CheckDisposed(); logErrors = value; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private bool logExceptions;
- public virtual bool LogExceptions
- {
- get { CheckDisposed(); return logExceptions; }
- set { CheckDisposed(); logExceptions = value; }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region ISQLiteNativeModule Members
- private SQLiteErrorCode xCreate(
- IntPtr pDb,
- IntPtr pAux,
- int argc,
- IntPtr[] argv,
- ref IntPtr pVtab,
- ref IntPtr pError
- )
- {
- try
- {
- string fileName = SQLiteString.StringFromUtf8IntPtr(
- UnsafeNativeMethods.sqlite3_db_filename(pDb, IntPtr.Zero));
-
- using (SQLiteConnection connection = new SQLiteConnection(
- pDb, fileName, false))
- {
- SQLiteVirtualTable table = null;
- string error = null;
-
- if (Create(connection, pAux,
- SQLiteString.StringArrayFromUtf8IntPtrArray(argv),
- ref table, ref error) == SQLiteErrorCode.Ok)
- {
- if (table != null)
- {
- pVtab = TableToIntPtr(table);
- return SQLiteErrorCode.Ok;
- }
- else
- {
- pError = SQLiteString.Utf8IntPtrFromString(
- "no table was created");
- }
- }
- else
- {
- pError = SQLiteString.Utf8IntPtrFromString(error);
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- pError = SQLiteString.Utf8IntPtrFromString(e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xConnect(
- IntPtr pDb,
- IntPtr pAux,
- int argc,
- IntPtr[] argv,
- ref IntPtr pVtab,
- ref IntPtr pError
- )
- {
- try
- {
- string fileName = SQLiteString.StringFromUtf8IntPtr(
- UnsafeNativeMethods.sqlite3_db_filename(pDb, IntPtr.Zero));
-
- using (SQLiteConnection connection = new SQLiteConnection(
- pDb, fileName, false))
- {
- SQLiteVirtualTable table = null;
- string error = null;
-
- if (Connect(connection, pAux,
- SQLiteString.StringArrayFromUtf8IntPtrArray(argv),
- ref table, ref error) == SQLiteErrorCode.Ok)
- {
- if (table != null)
- {
- pVtab = TableToIntPtr(table);
- return SQLiteErrorCode.Ok;
- }
- else
- {
- pError = SQLiteString.Utf8IntPtrFromString(
- "no table was created");
- }
- }
- else
- {
- pError = SQLiteString.Utf8IntPtrFromString(error);
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- pError = SQLiteString.Utf8IntPtrFromString(e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xBestIndex(
- IntPtr pVtab,
- IntPtr pIndex
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- SQLiteIndex index = null;
-
- SQLiteMarshal.IndexFromIntPtr(pIndex, ref index);
-
- if (BestIndex(table, index) == SQLiteErrorCode.Ok)
- {
- SQLiteMarshal.IndexToIntPtr(index, pIndex);
- return SQLiteErrorCode.Ok;
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xDisconnect(
- IntPtr pVtab
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- if (Disconnect(table) == SQLiteErrorCode.Ok)
- {
- if (tables != null)
- tables.Remove(pVtab);
-
- return SQLiteErrorCode.Ok;
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- //
- // NOTE: At this point, there is no way to report the error
- // condition back to the caller; therefore, use the
- // logging facility instead.
- //
- try
- {
- if (LogExceptions)
- {
- SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
- String.Format(CultureInfo.CurrentCulture,
- "Caught exception in \"xDisconnect\" method: {0}",
- e)); /* throw */
- }
- }
- catch
- {
- // do nothing.
- }
- }
- finally
- {
- FreeTable(pVtab);
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xDestroy(
- IntPtr pVtab
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- if (Destroy(table) == SQLiteErrorCode.Ok)
- {
- if (tables != null)
- tables.Remove(pVtab);
-
- return SQLiteErrorCode.Ok;
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- //
- // NOTE: At this point, there is no way to report the error
- // condition back to the caller; therefore, use the
- // logging facility instead.
- //
- try
- {
- if (LogExceptions)
- {
- SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
- String.Format(CultureInfo.CurrentCulture,
- "Caught exception in \"xDestroy\" method: {0}",
- e)); /* throw */
- }
- }
- catch
- {
- // do nothing.
- }
- }
- finally
- {
- FreeTable(pVtab);
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xOpen(
- IntPtr pVtab,
- ref IntPtr pCursor
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- SQLiteVirtualTableCursor cursor = null;
-
- if (Open(table, ref cursor) == SQLiteErrorCode.Ok)
- {
- if (cursor != null)
- {
- pCursor = CursorToIntPtr(cursor);
-
- if (pCursor != IntPtr.Zero)
- {
- return SQLiteErrorCode.Ok;
- }
- else
- {
- SetTableError(pVtab,
- "no native cursor was created");
- }
- }
- else
- {
- SetTableError(pVtab,
- "no managed cursor was created");
- }
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xClose(
- IntPtr pCursor
- )
- {
- IntPtr pVtab = IntPtr.Zero;
-
- try
- {
- pVtab = TableFromCursor(pCursor);
-
- SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
- pVtab, pCursor);
-
- if (cursor != null)
- {
- if (Close(cursor) == SQLiteErrorCode.Ok)
- {
- if (cursors != null)
- cursors.Remove(pCursor);
-
- return SQLiteErrorCode.Ok;
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
- finally
- {
- FreeCursor(pCursor);
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xFilter(
- IntPtr pCursor,
- int idxNum,
- IntPtr idxStr,
- int argc,
- IntPtr[] argv
- )
- {
- IntPtr pVtab = IntPtr.Zero;
-
- try
- {
- pVtab = TableFromCursor(pCursor);
-
- SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
- pVtab, pCursor);
-
- if (cursor != null)
- {
- if (Filter(cursor, idxNum,
- SQLiteString.StringFromUtf8IntPtr(idxStr),
- SQLiteMarshal.ValueArrayFromIntPtrArray(
- argv)) == SQLiteErrorCode.Ok)
- {
- return SQLiteErrorCode.Ok;
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xNext(
- IntPtr pCursor
- )
- {
- IntPtr pVtab = IntPtr.Zero;
-
- try
- {
- pVtab = TableFromCursor(pCursor);
-
- SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
- pVtab, pCursor);
-
- if (cursor != null)
- {
- if (Next(cursor) == SQLiteErrorCode.Ok)
- return SQLiteErrorCode.Ok;
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private int xEof(
- IntPtr pCursor
- )
- {
- IntPtr pVtab = IntPtr.Zero;
-
- try
- {
- pVtab = TableFromCursor(pCursor);
-
- SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
- pVtab, pCursor);
-
- if (cursor != null)
- return Eof(cursor) ? 1 : 0;
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return 1;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xColumn(
- IntPtr pCursor,
- IntPtr pContext,
- int index
- )
- {
- IntPtr pVtab = IntPtr.Zero;
-
- try
- {
- pVtab = TableFromCursor(pCursor);
-
- SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
- pVtab, pCursor);
-
- if (cursor != null)
- {
- SQLiteContext context = new SQLiteContext(pContext);
-
- return Column(cursor, context, index);
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xRowId(
- IntPtr pCursor,
- ref long rowId
- )
- {
- IntPtr pVtab = IntPtr.Zero;
-
- try
- {
- pVtab = TableFromCursor(pCursor);
-
- SQLiteVirtualTableCursor cursor = CursorFromIntPtr(
- pVtab, pCursor);
-
- if (cursor != null)
- return RowId(cursor, ref rowId);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xUpdate(
- IntPtr pVtab,
- int nData,
- IntPtr apData,
- ref long rowId
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- SQLiteValue[] values =
- SQLiteMarshal.ValueArrayFromSizeAndIntPtr(
- nData, apData);
-
- return Update(table, values, ref rowId);
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xBegin(
- IntPtr pVtab
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return Begin(table);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xSync(
- IntPtr pVtab
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return Sync(table);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xCommit(
- IntPtr pVtab
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return Commit(table);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xRollback(
- IntPtr pVtab
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return Rollback(table);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private int xFindFunction(
- IntPtr pVtab,
- int nArg,
- IntPtr zName,
- ref SQLiteCallback callback,
- ref IntPtr pClientData
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- SQLiteFunction function = null;
-
- if (FindFunction(
- table, nArg,
- SQLiteString.StringFromUtf8IntPtr(zName),
- ref function, ref pClientData))
- {
- if (function != null)
- {
- callback = function.ScalarCallback;
- return 1;
- }
- else
- {
- SetTableError(pVtab, "no function was created");
- }
- }
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return 0;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xRename(
- IntPtr pVtab,
- IntPtr zNew
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- {
- return Rename(table,
- SQLiteString.StringFromUtf8IntPtr(zNew));
- }
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xSavepoint(
- IntPtr pVtab,
- int iSavepoint
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return Savepoint(table, iSavepoint);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xRelease(
- IntPtr pVtab,
- int iSavepoint
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return Release(table, iSavepoint);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private SQLiteErrorCode xRollbackTo(
- IntPtr pVtab,
- int iSavepoint
- )
- {
- try
- {
- SQLiteVirtualTable table = TableFromIntPtr(pVtab);
-
- if (table != null)
- return RollbackTo(table, iSavepoint);
- }
- catch (Exception e) /* NOTE: Must catch ALL. */
- {
- SetTableError(pVtab, e.ToString());
- }
-
- return SQLiteErrorCode.Error;
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region ISQLiteManagedModule Members
- private bool declared;
- public virtual bool Declared
- {
- get { CheckDisposed(); return declared; }
- internal set { declared = value; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- private string name;
- public virtual string Name
- {
- get { CheckDisposed(); return name; }
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Create(
- SQLiteConnection connection,
- IntPtr pClientData,
- string[] arguments,
- ref SQLiteVirtualTable table,
- ref string error
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Connect(
- SQLiteConnection connection,
- IntPtr pClientData,
- string[] arguments,
- ref SQLiteVirtualTable table,
- ref string error
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode BestIndex(
- SQLiteVirtualTable table,
- SQLiteIndex index
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Disconnect(
- SQLiteVirtualTable table
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Destroy(
- SQLiteVirtualTable table
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Open(
- SQLiteVirtualTable table,
- ref SQLiteVirtualTableCursor cursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Close(
- SQLiteVirtualTableCursor cursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Filter(
- SQLiteVirtualTableCursor cursor,
- int indexNumber,
- string indexString,
- SQLiteValue[] values
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Next(
- SQLiteVirtualTableCursor cursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract bool Eof(
- SQLiteVirtualTableCursor cursor
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Column(
- SQLiteVirtualTableCursor cursor,
- SQLiteContext context,
- int index
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode RowId(
- SQLiteVirtualTableCursor cursor,
- ref long rowId
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Update(
- SQLiteVirtualTable table,
- SQLiteValue[] values,
- ref long rowId
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Begin(
- SQLiteVirtualTable table
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Sync(
- SQLiteVirtualTable table
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Commit(
- SQLiteVirtualTable table
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Rollback(
- SQLiteVirtualTable table
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract bool FindFunction(
- SQLiteVirtualTable table,
- int argumentCount,
- string name,
- ref SQLiteFunction function,
- ref IntPtr pClientData
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Rename(
- SQLiteVirtualTable table,
- string newName
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Savepoint(
- SQLiteVirtualTable table,
- int savepoint
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode Release(
- SQLiteVirtualTable table,
- int savepoint
- );
-
- ///////////////////////////////////////////////////////////////////////
-
- public abstract SQLiteErrorCode RollbackTo(
- SQLiteVirtualTable table,
- int savepoint
- );
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region IDisposable Members
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region IDisposable "Pattern" Members
- private bool disposed;
- private void CheckDisposed() /* throw */
- {
-#if THROW_ON_DISPOSED
- if (disposed)
- {
- throw new ObjectDisposedException(
- typeof(SQLiteModuleBase).Name);
- }
-#endif
- }
-
- ///////////////////////////////////////////////////////////////////////
-
- protected virtual void Dispose(bool disposing)
- {
- if (!disposed)
- {
- //if (disposing)
- //{
- // ////////////////////////////////////
- // // dispose managed resources here...
- // ////////////////////////////////////
- //}
-
- //////////////////////////////////////
- // release unmanaged resources here...
- //////////////////////////////////////
-
- try
- {
- UnsafeNativeMethods.sqlite3_dispose_module(
- ref nativeModule);
- }
- catch (Exception e)
- {
- try
- {
- if (LogExceptions)
- {
- SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
- String.Format(CultureInfo.CurrentCulture,
- "Caught exception in \"Dispose\" method: {0}",
- e)); /* throw */
- }
- }
- catch
- {
- // do nothing.
- }
- }
-
- disposed = true;
- }
- }
- #endregion
-
- ///////////////////////////////////////////////////////////////////////
-
- #region Destructor
- ~SQLiteModuleBase()
- {
- Dispose(false);
- }
- #endregion
- }
- #endregion
-}
Index: System.Data.SQLite/SQLiteModuleNoop.cs
==================================================================
--- System.Data.SQLite/SQLiteModuleNoop.cs
+++ System.Data.SQLite/SQLiteModuleNoop.cs
@@ -5,11 +5,11 @@
* Released to the public domain, use at your own risk!
********************************************************/
namespace System.Data.SQLite
{
- public class SQLiteModuleNoop : SQLiteModuleBase
+ public class SQLiteModuleNoop : SQLiteModule
{
#region Public Constructors
public SQLiteModuleNoop(
string name
)
Index: System.Data.SQLite/System.Data.SQLite.Files.targets
==================================================================
--- System.Data.SQLite/System.Data.SQLite.Files.targets
+++ System.Data.SQLite/System.Data.SQLite.Files.targets
@@ -41,11 +41,11 @@
-
+