Example #1
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (_sqlite_stmt != null)
                    {
                        _sqlite_stmt.Dispose();
                        _sqlite_stmt = null;
                    }

                    _paramNames   = null;
                    _paramValues  = null;
                    _sql          = null;
                    _sqlStatement = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
Example #2
0
        /// <summary>
        /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
        /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
        /// as the connection (UTF-8 or UTF-16).
        /// </summary>
        /// <remarks>
        /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to
        /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
        /// </remarks>
        /// <param name="sqlbase">The base object on which the functions are to bind</param>
        /// <param name="flags">The flags associated with the parent connection object</param>
        /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
        internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase, SQLiteConnectionFlags flags)
        {
            SQLiteFunction        f;
            List <SQLiteFunction> lFunctions = new List <SQLiteFunction>();

            foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
            {
                f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType);

                f._base          = sqlbase;
                f._flags         = flags;
                f._InvokeFunc    = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
                f._StepFunc      = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
                f._FinalFunc     = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null;
                f._CompareFunc   = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;
                f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null;

                if (pr.FuncType != FunctionType.Collation)
                {
                    sqlbase.CreateFunction(pr.Name, pr.Arguments, (f is SQLiteFunctionEx), f._InvokeFunc, f._StepFunc, f._FinalFunc);
                }
                else
                {
                    sqlbase.CreateCollation(pr.Name, f._CompareFunc, f._CompareFunc16);
                }


                lFunctions.Add(f);
            }

            SQLiteFunction[] arFunctions = new SQLiteFunction[lFunctions.Count];
            lFunctions.CopyTo(arFunctions, 0);

            return(arFunctions);
        }
Example #3
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Internal proxy function that calls any registered application log
        /// event handlers.
        ///
        /// WARNING: This method is used more-or-less directly by native code,
        ///          do not modify its type signature.
        /// </summary>
        /// <param name="pUserData">
        /// The extra data associated with this message, if any.
        /// </param>
        /// <param name="errorCode">
        /// The error code associated with this message.
        /// </param>
        /// <param name="pMessage">
        /// The message string to be logged.
        /// </param>
        private static void LogCallback(
            IntPtr pUserData,
            int errorCode,
            IntPtr pMessage
            )
        {
            bool enabled;
            SQLiteLogEventHandler handlers;

            lock (syncRoot)
            {
                enabled = _enabled;

                if (_handlers != null)
                {
                    handlers = _handlers.Clone() as SQLiteLogEventHandler;
                }
                else
                {
                    handlers = null;
                }
            }

            if (enabled && (handlers != null))
            {
                handlers(null, new LogEventArgs(pUserData, errorCode,
                                                SQLiteBase.PtrToString(pMessage, -1), null));
            }
        }
Example #4
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (_sqlite_backup != null)
                    {
                        _sqlite_backup.Dispose();
                        _sqlite_backup = null;
                    }

                    _zSourceName = null;
                    _sourceDb    = IntPtr.Zero;
                    _zDestName   = null;
                    _destDb      = IntPtr.Zero;
                    _sql         = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
        /// <summary>
        /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
        /// someone closes the connection while a DataReader is open.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);

            IDisposable disp;

            foreach (KeyValuePair <long, object> kv in _contextDataList)
            {
                disp = kv.Value as IDisposable;
                if (disp != null)
                {
                    disp.Dispose();
                }
            }
            _contextDataList.Clear();

            _InvokeFunc      = null;
            _StepFunc        = null;
            _FinalFunc       = null;
            _CompareFunc     = null;
            _base            = null;
            _contextDataList = null;

            GC.SuppressFinalize(this);
        }
Example #6
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (_sqlite_blob != null)
                    {
                        _sqlite_blob.Dispose();
                        _sqlite_blob = null;
                    }

                    _sql = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
Example #7
0
        internal SQLiteStatement(SQLiteBase sqlbase, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous)
        {
            this._sql          = sqlbase;
            this._sqlite_stmt  = stmt;
            this._sqlStatement = strCommand;
            int num  = 0;
            int num2 = this._sql.Bind_ParamCount(this);

            if (num2 > 0)
            {
                if (previous != null)
                {
                    num = previous._unnamedParameters;
                }
                this._paramNames  = new string[num2];
                this._paramValues = new SQLiteParameter[num2];
                for (int i = 0; i < num2; i++)
                {
                    string str = this._sql.Bind_ParamName(this, i + 1);
                    if (string.IsNullOrEmpty(str))
                    {
                        str = string.Format(CultureInfo.InvariantCulture, ";{0}", new object[] { num });
                        num++;
                        this._unnamedParameters++;
                    }
                    this._paramNames[i]  = str;
                    this._paramValues[i] = null;
                }
            }
        }
Example #8
0
        internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase)
        {
            List <SQLiteFunction> list = new List <SQLiteFunction>();

            foreach (SQLiteFunctionAttribute attribute in _registeredFunctions)
            {
                SQLiteFunction item = (SQLiteFunction)Activator.CreateInstance(attribute._instanceType);
                item._base          = sqlbase;
                item._InvokeFunc    = (attribute.FuncType == FunctionType.Scalar) ? new SQLiteCallback(item.ScalarCallback) : null;
                item._StepFunc      = (attribute.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(item.StepCallback) : null;
                item._FinalFunc     = (attribute.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(item.FinalCallback) : null;
                item._CompareFunc   = (attribute.FuncType == FunctionType.Collation) ? new SQLiteCollation(item.CompareCallback) : null;
                item._CompareFunc16 = (attribute.FuncType == FunctionType.Collation) ? new SQLiteCollation(item.CompareCallback16) : null;
                if (attribute.FuncType != FunctionType.Collation)
                {
                    sqlbase.CreateFunction(attribute.Name, attribute.Arguments, item is SQLiteFunctionEx, item._InvokeFunc, item._StepFunc, item._FinalFunc);
                }
                else
                {
                    sqlbase.CreateCollation(attribute.Name, item._CompareFunc, item._CompareFunc16);
                }
                list.Add(item);
            }
            SQLiteFunction[] array = new SQLiteFunction[list.Count];
            list.CopyTo(array, 0);
            return(array);
        }
    /// <summary>
    /// Initializes the statement and attempts to get all information about parameters in the statement
    /// </summary>
    /// <param name="sqlbase">The base SQLite object</param>
    /// <param name="flags">The flags associated with the parent connection object</param>
    /// <param name="stmt">The statement</param>
    /// <param name="strCommand">The command text for this statement</param>
    /// <param name="previous">The previous command in a multi-statement command</param>
    internal SQLiteStatement(SQLiteBase sqlbase, SQLiteConnectionFlags flags, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous)
    {
      _sql     = sqlbase;
      _sqlite_stmt = stmt;
      _sqlStatement  = strCommand;
      _flags = flags;

      // Determine parameters for this statement (if any) and prepare space for them.
      int nCmdStart = 0;
      int n = _sql.Bind_ParamCount(this, _flags);
      int x;
      string s;

      if (n > 0)
      {
        if (previous != null)
          nCmdStart = previous._unnamedParameters;

        _paramNames = new string[n];
        _paramValues = new SQLiteParameter[n];

        for (x = 0; x < n; x++)
        {
          s = _sql.Bind_ParamName(this, _flags, x + 1);
          if (String.IsNullOrEmpty(s))
          {
            s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
            nCmdStart++;
            _unnamedParameters++;
          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
    }
Example #10
0
        /// <summary>
        /// This function binds a user-defined functions to a connection.
        /// </summary>
        /// <param name="sqliteBase">
        /// The <see cref="SQLiteBase" /> object instance associated with the
        /// <see cref="SQLiteConnection" /> that the function should be bound to.
        /// </param>
        /// <param name="functionAttribute">
        /// The <see cref="SQLiteFunctionAttribute"/> object instance containing
        /// the metadata for the function to be bound.
        /// </param>
        /// <param name="function">
        /// The <see cref="SQLiteFunction"/> object instance that implements the
        /// function to be bound.
        /// </param>
        /// <param name="flags">
        /// The flags associated with the parent connection object.
        /// </param>
        internal static void BindFunction(
            SQLiteBase sqliteBase,
            SQLiteFunctionAttribute functionAttribute,
            SQLiteFunction function,
            SQLiteConnectionFlags flags
            )
        {
            if (sqliteBase == null)
            {
                throw new ArgumentNullException("sqliteBase");
            }

            if (functionAttribute == null)
            {
                throw new ArgumentNullException("functionAttribute");
            }

            if (function == null)
            {
                throw new ArgumentNullException("function");
            }

            FunctionType functionType = functionAttribute.FuncType;

            function._base  = sqliteBase;
            function._flags = flags;

            function._InvokeFunc = (functionType == FunctionType.Scalar) ?
                                   new SQLiteCallback(function.ScalarCallback) : null;

            function._StepFunc = (functionType == FunctionType.Aggregate) ?
                                 new SQLiteCallback(function.StepCallback) : null;

            function._FinalFunc = (functionType == FunctionType.Aggregate) ?
                                  new SQLiteFinalCallback(function.FinalCallback) : null;

            function._CompareFunc = (functionType == FunctionType.Collation) ?
                                    new SQLiteCollation(function.CompareCallback) : null;

            function._CompareFunc16 = (functionType == FunctionType.Collation) ?
                                      new SQLiteCollation(function.CompareCallback16) : null;

            string name = functionAttribute.Name;

            if (functionType != FunctionType.Collation)
            {
                bool needCollSeq = (function is SQLiteFunctionEx);

                sqliteBase.CreateFunction(
                    name, functionAttribute.Arguments, needCollSeq,
                    function._InvokeFunc, function._StepFunc,
                    function._FinalFunc);
            }
            else
            {
                sqliteBase.CreateCollation(
                    name, function._CompareFunc, function._CompareFunc16);
            }
        }
Example #11
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #region Private Constructors
        /// <summary>
        /// Initializes the blob.
        /// </summary>
        /// <param name="sqlbase">The base SQLite object.</param>
        /// <param name="blob">The blob handle.</param>
        private SQLiteBlob(
            SQLiteBase sqlbase,
            SQLiteBlobHandle blob
            )
        {
            _sql         = sqlbase;
            _sqlite_blob = blob;
        }
Example #12
0
 protected override bool ReleaseHandle()
 {
     try
     {
         SQLiteBase.CloseConnection(this);
     }
     catch (SQLiteException)
     {
     }
     return(true);
 }
        /// <summary>
        /// Disposes and finalizes the statement
        /// </summary>
        public void Dispose()
        {
            _sql.FinalizeStatement(this);

            _paramNames   = null;
            _paramValues  = null;
            _sql          = null;
            _sqlStatement = null;

            GC.SuppressFinalize(this);
        }
Example #14
0
 protected override bool ReleaseHandle()
 {
     try
     {
         SQLiteBase.FinalizeStatement(this);
     }
     catch (SQLiteException)
     {
     }
     return(true);
 }
Example #15
0
 public void Dispose()
 {
     if (this._sqlite_stmt != null)
     {
         this._sqlite_stmt.Dispose();
     }
     this._sqlite_stmt  = null;
     this._paramNames   = null;
     this._paramValues  = null;
     this._sql          = null;
     this._sqlStatement = null;
 }
Example #16
0
        /// <summary>
        /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
        /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
        /// as the connection (UTF-8 or UTF-16).
        /// </summary>
        /// <remarks>
        /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to
        /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
        /// </remarks>
        /// <param name="sqlbase">The base object on which the functions are to bind</param>
        /// <param name="flags">The flags associated with the parent connection object</param>
        /// <returns>Returns a logical list of functions which the connection should retain until it is closed.</returns>
        internal static IEnumerable <SQLiteFunction> BindFunctions(SQLiteBase sqlbase, SQLiteConnectionFlags flags)
        {
            List <SQLiteFunction> lFunctions = new List <SQLiteFunction>();

            foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
            {
                SQLiteFunction f = (SQLiteFunction)Activator.CreateInstance(pr.InstanceType);
                BindFunction(sqlbase, pr, f, flags);
                lFunctions.Add(f);
            }

            return(lFunctions);
        }
        /// <summary>
        /// Disposes and finalizes the statement
        /// </summary>
        public void Dispose()
        {
            if (_sqlite_stmt != null)
            {
                _sqlite_stmt.Dispose();
            }
            _sqlite_stmt = null;

            _paramNames   = null;
            _paramValues  = null;
            _sql          = null;
            _sqlStatement = null;
        }
Example #18
0
        /// <summary>
        /// This method resets all the prepared statements held by this instance
        /// back to their initial states, ready to be re-executed.
        /// </summary>
        /// <param name="clearBindings">
        /// Non-zero if the parameter bindings should be cleared as well.
        /// </param>
        /// <param name="ignoreErrors">
        /// If this is zero, a <see cref="SQLiteException" /> may be thrown for
        /// any unsuccessful return codes from the native library; otherwise, a
        /// <see cref="SQLiteException" /> will only be thrown if the connection
        /// or its state is invalid.
        /// </param>
        public void Reset(
            bool clearBindings,
            bool ignoreErrors
            )
        {
            CheckDisposed();
            SQLiteConnection.Check(_cnn);

            if (clearBindings && (_parameterCollection != null))
            {
                _parameterCollection.Unbind();
            }

            ClearDataReader();

            if (_statementList == null)
            {
                return;
            }

            SQLiteBase      sqlBase = _cnn._sql;
            SQLiteErrorCode rc;

            foreach (SQLiteStatement item in _statementList)
            {
                if (item == null)
                {
                    continue;
                }

                SQLiteStatementHandle stmt = item._sqlite_stmt;

                if (stmt == null)
                {
                    continue;
                }

                rc = sqlBase.Reset(item);

                if ((rc == SQLiteErrorCode.Ok) && clearBindings &&
                    (SQLite3.SQLiteVersionNumber >= 3003007))
                {
                    rc = UnsafeNativeMethods.sqlite3_clear_bindings(stmt);
                }

                if (!ignoreErrors && (rc != SQLiteErrorCode.Ok))
                {
                    throw new SQLiteException(rc, sqlBase.GetLastError());
                }
            }
        }
        /// <summary>
        /// Issued after the base connection is closed, this function cleans up all user-defined functions and disposes of them.
        /// </summary>
        /// <remarks>
        /// Cleaning up here is done mainly because of the interop wrapper.  It allocated memory to hold a reference to all the
        /// delegates, and now must free that memory.
        /// Freeing is done after the connection is closed to ensure no callbacks get hit after we've freed the cookie.
        /// </remarks>
        /// <param name="sqlbase">The base SQLite connection object</param>
        /// <param name="ar">An array of user-defined functions for this object</param>
        internal static void UnbindFunctions(SQLiteBase sqlbase, SQLiteFunction[] ar)
        {
            if (ar == null)
            {
                return;
            }

            int x = ar.Length;

            for (int n = 0; n < x; n++)
            {
                sqlbase.FreeFunction(ar[n]._interopCookie);
                ar[n].Dispose();
            }
        }
Example #20
0
 /// <summary>
 /// Initializes the backup.
 /// </summary>
 /// <param name="sqlbase">The base SQLite object.</param>
 /// <param name="backup">The backup handle.</param>
 /// <param name="destDb">The destination database for the backup.</param>
 /// <param name="zDestName">The destination database name for the backup.</param>
 /// <param name="sourceDb">The source database for the backup.</param>
 /// <param name="zSourceName">The source database name for the backup.</param>
 internal SQLiteBackup(
     SQLiteBase sqlbase,
     SQLiteBackupHandle backup,
     IntPtr destDb,
     byte[] zDestName,
     IntPtr sourceDb,
     byte[] zSourceName
     )
 {
     _sql           = sqlbase;
     _sqlite_backup = backup;
     _destDb        = destDb;
     _zDestName     = zDestName;
     _sourceDb      = sourceDb;
     _zSourceName   = zSourceName;
 }
Example #21
0
 internal override void Close()
 {
     if (this._sql != null)
     {
         if (this._usePool)
         {
             SQLiteBase.ResetConnection(this._sql);
             SQLiteConnectionPool.Add(this._fileName, this._sql, this._poolVersion);
         }
         else
         {
             this._sql.Dispose();
         }
     }
     this._sql = null;
 }
Example #22
0
 /// <summary>
 /// Initializes the backup.
 /// </summary>
 /// <param name="sqlbase">The base SQLite object.</param>
 /// <param name="backup">The backup handle.</param>
 /// <param name="destDb">The destination database for the backup.</param>
 /// <param name="zDestName">The destination database name for the backup.</param>
 /// <param name="sourceDb">The source database for the backup.</param>
 /// <param name="zSourceName">The source database name for the backup.</param>
 internal SQLiteBackup(
     SQLiteBase sqlbase,
     SQLiteBackupHandle backup,
     IntPtr destDb,
     byte[] zDestName,
     IntPtr sourceDb,
     byte[] zSourceName
     )
 {
     _sql = sqlbase;
     _sqlite_backup = backup;
     _destDb = destDb;
     _zDestName = zDestName;
     _sourceDb = sourceDb;
     _zSourceName = zSourceName;
 }
Example #23
0
 /// <summary>
 /// Constructs an instance of this class using the specified data-type
 /// conversion parameters.
 /// </summary>
 /// <param name="format">
 /// The DateTime format to be used when converting string values to a
 /// DateTime and binding DateTime parameters.
 /// </param>
 /// <param name="kind">
 /// The <see cref="DateTimeKind" /> to be used when creating DateTime
 /// values.
 /// </param>
 /// <param name="formatString">
 /// The format string to be used when parsing and formatting DateTime
 /// values.
 /// </param>
 /// <param name="utf16">
 /// Non-zero to create a UTF-16 data-type conversion context; otherwise,
 /// a UTF-8 data-type conversion context will be created.
 /// </param>
 protected SQLiteFunction(
     SQLiteDateFormats format,
     DateTimeKind kind,
     string formatString,
     bool utf16
     )
     : this()
 {
     if (utf16)
     {
         _base = new SQLite3_UTF16(format, kind, formatString, IntPtr.Zero, null, false);
     }
     else
     {
         _base = new SQLite3(format, kind, formatString, IntPtr.Zero, null, false);
     }
 }
Example #24
0
        // It isn't necessary to cleanup any functions we've registered.  If the connection
        // goes to the pool and is resurrected later, re-registered functions will overwrite the
        // previous functions.  The SQLiteFunctionCookieHandle will take care of freeing unmanaged
        // resources belonging to the previously-registered functions.
        internal override void Close()
        {
            if (_sql != null)
            {
                if (_usePool)
                {
                    SQLiteBase.ResetConnection(_sql);
                    SQLiteConnectionPool.Add(_fileName, _sql, _poolVersion);
                }
                else
                {
                    _sql.Dispose();
                }
            }

            _sql = null;
        }
Example #25
0
 protected virtual void Dispose(bool disposing)
 {
     if (disposing)
     {
         foreach (KeyValuePair <long, AggregateData> pair in this._contextDataList)
         {
             IDisposable disposable = pair.Value._data as IDisposable;
             if (disposable != null)
             {
                 disposable.Dispose();
             }
         }
         this._contextDataList.Clear();
         this._InvokeFunc      = null;
         this._StepFunc        = null;
         this._FinalFunc       = null;
         this._CompareFunc     = null;
         this._base            = null;
         this._contextDataList = null;
     }
 }
Example #26
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Placeholder for a user-defined disposal routine
        /// </summary>
        /// <param name="disposing">True if the object is being disposed explicitly</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    IDisposable disp;

                    foreach (KeyValuePair <IntPtr, AggregateData> kv in _contextDataList)
                    {
                        disp = kv.Value._data as IDisposable;
                        if (disp != null)
                        {
                            disp.Dispose();
                        }
                    }
                    _contextDataList.Clear();
                    _contextDataList = null;

                    _flags = SQLiteConnectionFlags.None;

                    _InvokeFunc  = null;
                    _StepFunc    = null;
                    _FinalFunc   = null;
                    _CompareFunc = null;
                    _base        = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
Example #27
0
        /// <summary>
        /// Returns the error message for the specified SQLite return code.
        /// </summary>
        /// <param name="errorCode">The SQLite return code.</param>
        /// <returns>The error message or null if it cannot be found.</returns>
        private static string GetErrorString(
            SQLiteErrorCode errorCode
            )
        {
#if !PLATFORM_COMPACTFRAMEWORK
            //
            // HACK: This must be done via reflection in order to prevent
            //       the RuntimeHelpers.PrepareDelegate method from over-
            //       eagerly attempting to locate the new (and optional)
            //       sqlite3_errstr() function in the SQLite core library
            //       because it happens to be in the static call graph for
            //       the AppDomain.DomainUnload event handler registered
            //       by the SQLiteLog class.
            //
            BindingFlags flags = BindingFlags.Static |
                                 BindingFlags.NonPublic | BindingFlags.InvokeMethod;

            return(typeof(SQLiteBase).InvokeMember("GetErrorString",
                                                   flags, null, null, new object[] { errorCode }) as string);
#else
            return(SQLiteBase.GetErrorString(errorCode));
#endif
        }
Example #28
0
        /// <summary>
        /// Initializes the statement and attempts to get all information about parameters in the statement
        /// </summary>
        /// <param name="sqlbase">The base SQLite object</param>
        /// <param name="flags">The flags associated with the parent connection object</param>
        /// <param name="stmt">The statement</param>
        /// <param name="strCommand">The command text for this statement</param>
        /// <param name="previous">The previous command in a multi-statement command</param>
        internal SQLiteStatement(SQLiteBase sqlbase, SQLiteConnectionFlags flags, SQLiteStatementHandle stmt, string strCommand, SQLiteStatement previous)
        {
            _sql          = sqlbase;
            _sqlite_stmt  = stmt;
            _sqlStatement = strCommand;
            _flags        = flags;

            // Determine parameters for this statement (if any) and prepare space for them.
            int    nCmdStart = 0;
            int    n         = _sql.Bind_ParamCount(this, _flags);
            int    x;
            string s;

            if (n > 0)
            {
                if (previous != null)
                {
                    nCmdStart = previous._unnamedParameters;
                }

                _paramNames  = new string[n];
                _paramValues = new SQLiteParameter[n];

                for (x = 0; x < n; x++)
                {
                    s = _sql.Bind_ParamName(this, _flags, x + 1);
                    if (String.IsNullOrEmpty(s))
                    {
                        s = HelperMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
                        nCmdStart++;
                        _unnamedParameters++;
                    }
                    _paramNames[x]  = s;
                    _paramValues[x] = null;
                }
            }
        }
Example #29
0
        /// <summary>
        /// Placeholder for a user-defined disposal routine
        /// </summary>
        /// <param name="disposing">True if the object is being disposed explicitly</param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                IDisposable disp;

                foreach (KeyValuePair <long, AggregateData> kv in _contextDataList)
                {
                    disp = kv.Value._data as IDisposable;
                    if (disp != null)
                    {
                        disp.Dispose();
                    }
                }
                _contextDataList.Clear();

                _InvokeFunc      = null;
                _StepFunc        = null;
                _FinalFunc       = null;
                _CompareFunc     = null;
                _base            = null;
                _contextDataList = null;
            }
        }
    /// <summary>
    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind</param>
    /// <param name="flags">The flags associated with the parent connection object</param>
    /// <returns>Returns a logical list of functions which the connection should retain until it is closed.</returns>
    internal static IEnumerable<SQLiteFunction> BindFunctions(SQLiteBase sqlbase, SQLiteConnectionFlags flags)
    {
        List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();

        foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
        {
            SQLiteFunction f = (SQLiteFunction)Activator.CreateInstance(pr.InstanceType);
            BindFunction(sqlbase, pr, f, flags);
            lFunctions.Add(f);
        }

        return lFunctions;
    }
 /// <summary>
 /// Constructs an instance of this class using the specified data-type
 /// conversion parameters.
 /// </summary>
 /// <param name="format">
 /// The DateTime format to be used when converting string values to a
 /// DateTime and binding DateTime parameters.
 /// </param>
 /// <param name="kind">
 /// The <see cref="DateTimeKind" /> to be used when creating DateTime
 /// values.
 /// </param>
 /// <param name="formatString">
 /// The format string to be used when parsing and formatting DateTime
 /// values.
 /// </param>
 /// <param name="utf16">
 /// Non-zero to create a UTF-16 data-type conversion context; otherwise,
 /// a UTF-8 data-type conversion context will be created.
 /// </param>
 protected SQLiteFunction(
     SQLiteDateFormats format,
     DateTimeKind kind,
     string formatString,
     bool utf16
     )
     : this()
 {
     if (utf16)
         _base = new SQLite3_UTF16(format, kind, formatString, IntPtr.Zero, null, false);
     else
         _base = new SQLite3(format, kind, formatString, IntPtr.Zero, null, false);
 }
Example #32
0
    /// <summary>
    /// Called by the SQLiteBase derived classes, this method unbinds all registered (known)
    /// functions -OR- all previously bound user-defined functions from a connection.
    /// </summary>
    /// <param name="sqlbase">The base object from which the functions are to be unbound.</param>
    /// <param name="flags">The flags associated with the parent connection object.</param>
    /// <param name="registered">
    /// Non-zero to unbind all registered (known) functions -OR- zero to unbind all functions
    /// currently bound to the connection.
    /// </param>
    /// <returns>Non-zero if all the specified user-defined functions were unbound.</returns>
    internal static bool UnbindAllFunctions(
        SQLiteBase sqlbase,
        SQLiteConnectionFlags flags,
        bool registered
        )
    {
        if (sqlbase == null)
            return false;

        IDictionary<SQLiteFunctionAttribute, SQLiteFunction> lFunctions =
            sqlbase.Functions;

        if (lFunctions == null)
            return false;

        bool result = true;

        if (registered)
        {
            foreach (KeyValuePair<SQLiteFunctionAttribute, object> pair
                    in _registeredFunctions)
            {
                SQLiteFunctionAttribute pr = pair.Key;

                if (pr == null)
                    continue;

                SQLiteFunction f;

                if (!lFunctions.TryGetValue(pr, out f) ||
                    (f == null) ||
                    !UnbindFunction(sqlbase, pr, f, flags))
                {
                    result = false;
                }
            }
        }
        else
        {
            //
            // NOTE: Need to use a copy of the function dictionary in this method
            //       because the dictionary is modified within the UnbindFunction
            //       method, which is called inside the loop.
            //
            lFunctions = new Dictionary<SQLiteFunctionAttribute, SQLiteFunction>(
                lFunctions);

            foreach (KeyValuePair<SQLiteFunctionAttribute, SQLiteFunction> pair
                    in lFunctions)
            {
                SQLiteFunctionAttribute pr = pair.Key;

                if (pr == null)
                    continue;

                SQLiteFunction f = pair.Value;

                if ((f == null) ||
                    !UnbindFunction(sqlbase, pr, f, flags))
                {
                    result = false;
                }
            }
        }

        return result;
    }
        /// <summary>
        /// Disposes and finalizes the statement
        /// </summary>
        public void Dispose()
        {
            _sql.FinalizeStatement(this);

              _paramNames = null;
              _paramValues = null;
              _sql = null;
              _sqlStatement = null;

              GC.SuppressFinalize(this);
        }
    /// <summary>
    /// Initializes the connection with a pre-existing native connection handle.
    /// </summary>
    /// <param name="db">
    /// The native connection handle to use.
    /// </param>
    /// <param name="fileName">
    /// The file name corresponding to the native connection handle.
    /// </param>
    /// <param name="ownHandle">
    /// Non-zero if this instance owns the native connection handle and
    /// should dispose of it when it is no longer needed.
    /// </param>
    internal SQLiteConnection(IntPtr db, string fileName, bool ownHandle)
        : this()
    {
        _sql = new SQLite3(
            SQLiteDateFormats.Default, DateTimeKind.Unspecified, null,
            db, fileName, ownHandle);

        _flags = SQLiteConnectionFlags.None;

        _connectionState = (db != IntPtr.Zero) ?
            ConnectionState.Open : ConnectionState.Closed;

        _connectionString = null; /* unknown */
    }
    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      if (_sql != null)
      {
        int x = _commandList.Count;
        for (int n = 0; n < x; n++)
        {
          _commandList[n].ClearCommands();
        }

        _sql.Close();
        _sql = null;
      }

      OnStateChange(ConnectionState.Closed);
    }
    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString" />.
    /// </summary>
    public override void Open()
    {
      CheckDisposed();

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.Opening, null, null, null, null, null));

      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      SortedList<string, string> opts = _parseViaFramework ?
          ParseConnectionStringViaFramework(_connectionString, false) :
          ParseConnectionString(_connectionString);

      OnChanged(this, new ConnectionEventArgs(
          SQLiteConnectionEventType.ConnectionString, null, null, null, _connectionString, opts));

      object enumValue;

      enumValue = TryParseEnum(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", DefaultFlags.ToString()), true);
      _flags = (enumValue is SQLiteConnectionFlags) ? (SQLiteConnectionFlags)enumValue : DefaultFlags;

      bool fullUri = false;
      string fileName;

      if (Convert.ToInt32(FindKey(opts, "Version", DefaultVersion.ToString()), CultureInfo.InvariantCulture) != DefaultVersion)
        throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, "Only SQLite Version {0} is supported at this time", DefaultVersion));

      fileName = FindKey(opts, "Data Source", DefaultDataSource);

      if (String.IsNullOrEmpty(fileName))
      {
        fileName = FindKey(opts, "Uri", DefaultUri);
        if (String.IsNullOrEmpty(fileName))
        {
          fileName = FindKey(opts, "FullUri", DefaultFullUri);
          if (String.IsNullOrEmpty(fileName))
            throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Data Source cannot be empty.  Use {0} to open an in-memory database", MemoryFileName));
          else
            fullUri = true;
        }
        else
          fileName = MapUriPath(fileName);
      }

      bool isMemory = (String.Compare(fileName, MemoryFileName, StringComparison.OrdinalIgnoreCase) == 0);

      if (!fullUri)
      {
        if (isMemory)
          fileName = MemoryFileName;
        else
        {
#if PLATFORM_COMPACTFRAMEWORK
          if (fileName.StartsWith("./") || fileName.StartsWith(".\\"))
            fileName = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);
#endif
          bool toFullPath = SQLiteConvert.ToBoolean(FindKey(opts, "ToFullPath", DefaultToFullPath.ToString()));
          fileName = ExpandFileName(fileName, toFullPath);
        }
      }

      try
      {
        bool usePooling = SQLiteConvert.ToBoolean(FindKey(opts, "Pooling", DefaultPooling.ToString()));
        int maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", DefaultMaxPoolSize.ToString()), CultureInfo.InvariantCulture);

        _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", DefaultConnectionTimeout.ToString()), CultureInfo.InvariantCulture);

        enumValue = TryParseEnum(typeof(IsolationLevel), FindKey(opts, "Default IsolationLevel", DefaultIsolationLevel.ToString()), true);
        _defaultIsolation = (enumValue is IsolationLevel) ? (IsolationLevel)enumValue : DefaultIsolationLevel;

        if (_defaultIsolation != IsolationLevel.Serializable && _defaultIsolation != IsolationLevel.ReadCommitted)
          throw new NotSupportedException("Invalid Default IsolationLevel specified");

        _baseSchemaName = FindKey(opts, "BaseSchemaName", DefaultBaseSchemaName);

        if (_sql == null)
        {
            enumValue = TryParseEnum(typeof(SQLiteDateFormats), FindKey(opts,
                "DateTimeFormat", DefaultDateTimeFormat.ToString()), true);

            SQLiteDateFormats dateFormat = (enumValue is SQLiteDateFormats) ?
                (SQLiteDateFormats)enumValue : DefaultDateTimeFormat;

            enumValue = TryParseEnum(typeof(DateTimeKind), FindKey(opts,
                "DateTimeKind", DefaultDateTimeKind.ToString()), true);

            DateTimeKind kind = (enumValue is DateTimeKind) ?
                (DateTimeKind)enumValue : DefaultDateTimeKind;

            //
            // NOTE: SQLite automatically sets the encoding of the database to
            //       UTF16 if called from sqlite3_open16().
            //
            if (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding",
                      DefaultUseUTF16Encoding.ToString())))
            {
                _sql = new SQLite3_UTF16(dateFormat, kind);
            }
            else
            {
                _sql = new SQLite3(dateFormat, kind);
            }
        }

        SQLiteOpenFlagsEnum flags = SQLiteOpenFlagsEnum.None;

        if (!SQLiteConvert.ToBoolean(FindKey(opts, "FailIfMissing", DefaultFailIfMissing.ToString())))
          flags |= SQLiteOpenFlagsEnum.Create;

        if (SQLiteConvert.ToBoolean(FindKey(opts, "Read Only", DefaultReadOnly.ToString())))
        {
          flags |= SQLiteOpenFlagsEnum.ReadOnly;
          // SQLite will return SQLITE_MISUSE on ReadOnly and Create
          flags &= ~SQLiteOpenFlagsEnum.Create;
        }
        else
        {
          flags |= SQLiteOpenFlagsEnum.ReadWrite;
        }

        if (fullUri)
            flags |= SQLiteOpenFlagsEnum.Uri;

        _sql.Open(fileName, _flags, flags, maxPoolSize, usePooling);

        _binaryGuid = SQLiteConvert.ToBoolean(FindKey(opts, "BinaryGUID", DefaultBinaryGUID.ToString()));

#if INTEROP_CODEC
        string password = FindKey(opts, "Password", DefaultPassword);

        if (!String.IsNullOrEmpty(password))
          _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password));
        else if (_password != null)
          _sql.SetPassword(_password);

        _password = null;
#endif

        if (!fullUri)
          _dataSource = Path.GetFileNameWithoutExtension(fileName);
        else
          _dataSource = fileName;

        _version++;

        ConnectionState oldstate = _connectionState;
        _connectionState = ConnectionState.Open;

        try
        {
          string strValue;
          bool boolValue;

          strValue = FindKey(opts, "SetDefaults", DefaultSetDefaults.ToString());
          boolValue = SQLiteConvert.ToBoolean(strValue);

          if (boolValue)
          {
              using (SQLiteCommand cmd = CreateCommand())
              {
                  int intValue;

                  if (!fullUri && !isMemory)
                  {
                      strValue = FindKey(opts, "Page Size", DefaultPageSize.ToString());
                      intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture);
                      if (intValue != DefaultPageSize)
                      {
                          cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", intValue);
                          cmd.ExecuteNonQuery();
                      }
                  }

                  strValue = FindKey(opts, "Max Page Count", DefaultMaxPageCount.ToString());
                  intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture);
                  if (intValue != DefaultMaxPageCount)
                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", intValue);
                      cmd.ExecuteNonQuery();
                  }

                  strValue = FindKey(opts, "Legacy Format", DefaultLegacyFormat.ToString());
                  boolValue = SQLiteConvert.ToBoolean(strValue);
                  if (boolValue != DefaultLegacyFormat)
                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}", boolValue ? "ON" : "OFF");
                      cmd.ExecuteNonQuery();
                  }

                  strValue = FindKey(opts, "Synchronous", DefaultSynchronous.ToString());
                  enumValue = TryParseEnum(typeof(SQLiteSynchronousEnum), strValue, true);
                  if (!(enumValue is SQLiteSynchronousEnum) || ((SQLiteSynchronousEnum)enumValue != DefaultSynchronous))
                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", strValue);
                      cmd.ExecuteNonQuery();
                  }

                  strValue = FindKey(opts, "Cache Size", DefaultCacheSize.ToString());
                  intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture);
                  if (intValue != DefaultCacheSize)
                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", intValue);
                      cmd.ExecuteNonQuery();
                  }

                  strValue = FindKey(opts, "Journal Mode", DefaultJournalMode.ToString());
                  enumValue = TryParseEnum(typeof(SQLiteJournalModeEnum), strValue, true);
                  if (!(enumValue is SQLiteJournalModeEnum) || ((SQLiteJournalModeEnum)enumValue != DefaultJournalMode))
                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA journal_mode={0}", strValue);
                      cmd.ExecuteNonQuery();
                  }

                  strValue = FindKey(opts, "Foreign Keys", DefaultForeignKeys.ToString());
                  boolValue = Convert.ToBoolean(strValue, CultureInfo.InvariantCulture);
                  if (boolValue != DefaultForeignKeys)
                  {
                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA foreign_keys={0}", boolValue ? "ON" : "OFF");
                      cmd.ExecuteNonQuery();
                  }
              }
          }

          if (_commitHandler != null)
            _sql.SetCommitHook(_commitCallback);

          if (_updateHandler != null)
            _sql.SetUpdateHook(_updateCallback);

          if (_rollbackHandler != null)
            _sql.SetRollbackHook(_rollbackCallback);

#if !PLATFORM_COMPACTFRAMEWORK
          System.Transactions.Transaction transaction = Transactions.Transaction.Current;

          if (transaction != null &&
              SQLiteConvert.ToBoolean(FindKey(opts, "Enlist", DefaultEnlist.ToString())))
          {
              EnlistTransaction(transaction);
          }
#endif

          _connectionState = oldstate;

          StateChangeEventArgs eventArgs = null;
          OnStateChange(ConnectionState.Open, ref eventArgs);

          OnChanged(this, new ConnectionEventArgs(
              SQLiteConnectionEventType.Opened, eventArgs, null, null, null, null));
        }
        catch
        {
          _connectionState = oldstate;
          throw;
        }
      }
      catch (SQLiteException)
      {
        Close();
        throw;
      }
    }
    /// <summary>
    /// Placeholder for a user-defined disposal routine
    /// </summary>
    /// <param name="disposing">True if the object is being disposed explicitly</param>
    protected virtual void Dispose(bool disposing)
    {
      if (disposing)
      {
        IDisposable disp;

        foreach (KeyValuePair<long, AggregateData> kv in _contextDataList)
        {
          disp = kv.Value._data as IDisposable;
          if (disp != null)
            disp.Dispose();
        }
        _contextDataList.Clear();

        _InvokeFunc = null;
        _StepFunc = null;
        _FinalFunc = null;
        _CompareFunc = null;
        _base = null;
        _contextDataList = null;
      }
    }
 /// <summary>
 /// Disposes and finalizes the statement
 /// </summary>
 public void Dispose()
 {
   if (_sqlite_stmt != null)
   {
     _sqlite_stmt.Dispose();
   }
   _sqlite_stmt = null;
   
   _paramNames = null;
   _paramValues = null;
   _sql = null;
   _sqlStatement = null;
 }
Example #39
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        private void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (_sqlite_backup != null)
                    {
                        _sqlite_backup.Dispose();
                        _sqlite_backup = null;
                    }

                    _zSourceName = null;
                    _sourceDb = IntPtr.Zero;
                    _zDestName = null;
                    _destDb = IntPtr.Zero;
                    _sql = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
    /// Passes a shutdown request off to SQLite.
    public SQLiteErrorCode Shutdown()
    {
        CheckDisposed();

        // make sure we have an instance of the base class
        if (_sql == null)
        {
            SortedList<string, string> opts = _parseViaFramework ?
                ParseConnectionStringViaFramework(_connectionString, false) :
                ParseConnectionString(_connectionString);

            object enumValue;

            enumValue = TryParseEnum(typeof(SQLiteDateFormats), FindKey(opts,
                "DateTimeFormat", DefaultDateTimeFormat.ToString()), true);

            SQLiteDateFormats dateFormat = (enumValue is SQLiteDateFormats) ?
                (SQLiteDateFormats)enumValue : DefaultDateTimeFormat;

            enumValue = TryParseEnum(typeof(DateTimeKind), FindKey(opts,
                "DateTimeKind", DefaultDateTimeKind.ToString()), true);

            DateTimeKind kind = (enumValue is DateTimeKind) ?
                (DateTimeKind)enumValue : DefaultDateTimeKind;

            //
            // NOTE: SQLite automatically sets the encoding of the database to
            //       UTF16 if called from sqlite3_open16().
            //
            if (SQLiteConvert.ToBoolean(FindKey(opts,
                    "UseUTF16Encoding", DefaultUseUTF16Encoding.ToString())))
            {
                _sql = new SQLite3_UTF16(dateFormat, kind);
            }
            else
            {
                _sql = new SQLite3(dateFormat, kind);
            }
        }
        if (_sql != null) return _sql.Shutdown();
        throw new InvalidOperationException("Database connection not active.");
    }
Example #41
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Initializes the SQLite logging facilities.
        /// </summary>
        /// <param name="className">
        /// The name of the managed class that called this method.  This
        /// parameter may be null.
        /// </param>
        internal static void Initialize(
            string className
            )
        {
            //
            // NOTE: See if the logging subsystem has been totally disabled.
            //       If so, do nothing.
            //
            if (UnsafeNativeMethods.GetSettingValue(
                    "No_SQLiteLog", null) != null)
            {
                return;
            }

            ///////////////////////////////////////////////////////////////

            //
            // NOTE: Keep track of exactly how many times this method is
            //       called (i.e. per-AppDomain, of course).
            //
            Interlocked.Increment(ref _initializeCallCount);

            ///////////////////////////////////////////////////////////////

            //
            // NOTE: First, check if the managed logging subsystem is always
            //       supposed to at least attempt to initialize itself.  In
            //       order to do this, several fairly complex steps must be
            //       taken, including calling a P/Invoke (interop) method;
            //       therefore, by default, attempt to perform these steps
            //       once.
            //
            if (UnsafeNativeMethods.GetSettingValue(
                    "Initialize_SQLiteLog", null) == null)
            {
                if (Interlocked.Increment(ref _attemptedInitialize) > 1)
                {
                    Interlocked.Decrement(ref _attemptedInitialize);
                    return;
                }
            }

            ///////////////////////////////////////////////////////////////////

            //
            // BUFXIX: Cannot initialize the logging interface if the SQLite
            //         core library has already been initialized anywhere in
            //         the process (see ticket [2ce0870fad]).
            //
            if (SQLite3.StaticIsInitialized())
            {
                return;
            }

            ///////////////////////////////////////////////////////////////////

#if !PLATFORM_COMPACTFRAMEWORK
            //
            // BUGFIX: To avoid nasty situations where multiple AppDomains are
            //         attempting to initialize and/or shutdown what is really
            //         a shared native resource (i.e. the SQLite core library
            //         is loaded per-process and has only one logging callback,
            //         not one per-AppDomain, which it knows nothing about),
            //         prevent all non-default AppDomains from registering a
            //         log handler unless the "Force_SQLiteLog" environment
            //         variable is used to manually override this safety check.
            //
            if (!AppDomain.CurrentDomain.IsDefaultAppDomain() &&
                UnsafeNativeMethods.GetSettingValue("Force_SQLiteLog", null) == null)
            {
                return;
            }
#endif

            ///////////////////////////////////////////////////////////////////

            lock (syncRoot)
            {
#if !PLATFORM_COMPACTFRAMEWORK
                //
                // NOTE: Add an event handler for the DomainUnload event so
                //       that we can unhook our logging managed function
                //       pointer from the native SQLite code prior to it
                //       being invalidated.
                //
                // BUGFIX: Make sure this event handler is only added one
                //         time (per-AppDomain).
                //
                if (_domainUnload == null)
                {
                    _domainUnload = new EventHandler(DomainUnload);
                    AppDomain.CurrentDomain.DomainUnload += _domainUnload;
                }
#endif

                ///////////////////////////////////////////////////////////////

#if USE_INTEROP_DLL && INTEROP_LOG
                //
                // NOTE: Attempt to setup interop assembly log callback.
                //       This may fail, e.g. if the SQLite core library
                //       has somehow been initialized.  An exception will
                //       be raised in that case.
                //
                SQLiteErrorCode rc = SQLite3.ConfigureLogForInterop(
                    className);

                if (rc != SQLiteErrorCode.Ok)
                {
                    throw new SQLiteException(rc,
                                              "Failed to configure interop assembly logging.");
                }
#else
                //
                // NOTE: Create an instance of the SQLite wrapper class.
                //
                if (_sql == null)
                {
                    _sql = new SQLite3(
                        SQLiteDateFormats.Default, DateTimeKind.Unspecified,
                        null, IntPtr.Zero, null, false);
                }

                //
                // NOTE: Create a single "global" (i.e. per-process) callback
                //       to register with SQLite.  This callback will pass the
                //       event on to any registered handler.  We only want to
                //       do this once.
                //
                if (_callback == null)
                {
                    _callback = new SQLiteLogCallback(LogCallback);

                    SQLiteErrorCode rc = _sql.SetLogCallback(_callback);

                    if (rc != SQLiteErrorCode.Ok)
                    {
                        _callback = null; /* UNDO */

                        throw new SQLiteException(rc,
                                                  "Failed to configure managed assembly logging.");
                    }
                }
#endif

                ///////////////////////////////////////////////////////////////

                //
                // NOTE: Logging is enabled by default unless the configuration
                //       setting "Disable_SQLiteLog" is present.
                //
                if (UnsafeNativeMethods.GetSettingValue(
                        "Disable_SQLiteLog", null) == null)
                {
                    _enabled = true;
                }

                ///////////////////////////////////////////////////////////////

                //
                // NOTE: For now, always setup the default log event handler.
                //
                AddDefaultHandler();
            }
        }
Example #42
0
    /// <summary>
    /// This function unbinds a user-defined functions from a connection.
    /// </summary>
    /// <param name="sqliteBase">
    /// The <see cref="SQLiteBase" /> object instance associated with the
    /// <see cref="SQLiteConnection" /> that the function should be bound to.
    /// </param>
    /// <param name="functionAttribute">
    /// The <see cref="SQLiteFunctionAttribute"/> object instance containing
    /// the metadata for the function to be bound.
    /// </param>
    /// <param name="function">
    /// The <see cref="SQLiteFunction"/> object instance that implements the
    /// function to be bound.
    /// </param>
    /// <param name="flags">
    /// The flags associated with the parent connection object.
    /// </param>
    /// <returns>Non-zero if the function was unbound.</returns>
    internal static bool UnbindFunction(
        SQLiteBase sqliteBase,
        SQLiteFunctionAttribute functionAttribute,
        SQLiteFunction function,
        SQLiteConnectionFlags flags /* NOT USED */
        )
    {
        if (sqliteBase == null)
            throw new ArgumentNullException("sqliteBase");

        if (functionAttribute == null)
            throw new ArgumentNullException("functionAttribute");

        if (function == null)
            throw new ArgumentNullException("function");

        FunctionType functionType = functionAttribute.FuncType;
        string name = functionAttribute.Name;

        if (functionType != FunctionType.Collation)
        {
            bool needCollSeq = (function is SQLiteFunctionEx);

            return sqliteBase.CreateFunction(
                name, functionAttribute.Arguments, needCollSeq,
                null, null, null, false) == SQLiteErrorCode.Ok;
        }
        else
        {
            return sqliteBase.CreateCollation(
                name, null, null, false) == SQLiteErrorCode.Ok;
        }
    }
    /// <summary>
    /// This function binds a user-defined functions to a connection.
    /// </summary>
    /// <param name="sqliteBase">
    /// The <see cref="SQLiteBase" /> object instance associated with the
    /// <see cref="SQLiteConnection" /> that the function should be bound to.
    /// </param>
    /// <param name="functionAttribute">
    /// The <see cref="SQLiteFunctionAttribute"/> object instance containing
    /// the metadata for the function to be bound.
    /// </param>
    /// <param name="function">
    /// The <see cref="SQLiteFunction"/> object instance that implements the
    /// function to be bound.
    /// </param>
    /// <param name="flags">
    /// The flags associated with the parent connection object.
    /// </param>
    internal static void BindFunction(
        SQLiteBase sqliteBase,
        SQLiteFunctionAttribute functionAttribute,
        SQLiteFunction function,
        SQLiteConnectionFlags flags
        )
    {
        if (sqliteBase == null)
            throw new ArgumentNullException("sqliteBase");

        if (functionAttribute == null)
            throw new ArgumentNullException("functionAttribute");

        if (function == null)
            throw new ArgumentNullException("function");

        FunctionType functionType = functionAttribute.FuncType;

        function._base = sqliteBase;
        function._flags = flags;

        function._InvokeFunc = (functionType == FunctionType.Scalar) ?
            new SQLiteCallback(function.ScalarCallback) : null;

        function._StepFunc = (functionType == FunctionType.Aggregate) ?
            new SQLiteCallback(function.StepCallback) : null;

        function._FinalFunc = (functionType == FunctionType.Aggregate) ?
            new SQLiteFinalCallback(function.FinalCallback) : null;

        function._CompareFunc = (functionType == FunctionType.Collation) ?
            new SQLiteCollation(function.CompareCallback) : null;

        function._CompareFunc16 = (functionType == FunctionType.Collation) ?
            new SQLiteCollation(function.CompareCallback16) : null;

        string name = functionAttribute.Name;

        if (functionType != FunctionType.Collation)
        {
            bool needCollSeq = (function is SQLiteFunctionEx);

            sqliteBase.CreateFunction(
                name, functionAttribute.Arguments, needCollSeq,
                function._InvokeFunc, function._StepFunc,
                function._FinalFunc);
        }
        else
        {
            sqliteBase.CreateCollation(
                name, function._CompareFunc, function._CompareFunc16);
        }
    }
        /// <summary>
        /// Issued after the base connection is closed, this function cleans up all user-defined functions and disposes of them.
        /// </summary>
        /// <remarks>
        /// Cleaning up here is done mainly because of the interop wrapper.  It allocated memory to hold a reference to all the
        /// delegates, and now must free that memory.
        /// Freeing is done after the connection is closed to ensure no callbacks get hit after we've freed the cookie.
        /// </remarks>
        /// <param name="sqlbase">The base SQLite connection object</param>
        /// <param name="ar">An array of user-defined functions for this object</param>
        internal static void UnbindFunctions(SQLiteBase sqlbase, SQLiteFunction[] ar)
        {
            if (ar == null) return;

              int x = ar.Length;
              for (int n = 0; n < x; n++)
              {
            sqlbase.FreeFunction(ar[n]._interopCookie);
            ar[n].Dispose();
              }
        }
Example #45
0
    /// <summary>
    /// Called by the SQLiteBase derived classes, this method binds all registered (known) user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind.</param>
    /// <param name="flags">The flags associated with the parent connection object.</param>
    /// <returns>Returns a logical list of functions which the connection should retain until it is closed.</returns>
    internal static IDictionary<SQLiteFunctionAttribute, SQLiteFunction> BindFunctions(
        SQLiteBase sqlbase,
        SQLiteConnectionFlags flags
        )
    {
        IDictionary<SQLiteFunctionAttribute, SQLiteFunction> lFunctions =
            new Dictionary<SQLiteFunctionAttribute, SQLiteFunction>();

        foreach (KeyValuePair<SQLiteFunctionAttribute, object> pair
                in _registeredFunctions)
        {
            SQLiteFunctionAttribute pr = pair.Key;

            if (pr == null)
                continue;

            SQLiteFunction f;

            if (CreateFunction(pr, out f))
            {
                BindFunction(sqlbase, pr, f, flags);
                lFunctions[pr] = f;
            }
            else
            {
                lFunctions[pr] = null;
            }
        }

        return lFunctions;
    }
        /// <summary>
        /// Disposes of any active contextData variables that were not automatically cleaned up.  Sometimes this can happen if
        /// someone closes the connection while a DataReader is open.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);

              IDisposable disp;

              foreach (KeyValuePair<long, object> kv in _contextDataList)
              {
            disp = kv.Value as IDisposable;
            if (disp != null)
              disp.Dispose();
              }
              _contextDataList.Clear();

              _InvokeFunc = null;
              _StepFunc = null;
              _FinalFunc = null;
              _CompareFunc = null;
              _base = null;
              _contextDataList = null;

              GC.SuppressFinalize(this);
        }
    ///////////////////////////////////////////////////////////////////////////////////////////////

    private void SetupSQLiteBase(SortedList<string, string> opts)
    {
        object enumValue;

        enumValue = TryParseEnum(
            typeof(SQLiteDateFormats), FindKey(opts, "DateTimeFormat",
            DefaultDateTimeFormat.ToString()), true);

        SQLiteDateFormats dateFormat = (enumValue is SQLiteDateFormats) ?
            (SQLiteDateFormats)enumValue : DefaultDateTimeFormat;

        enumValue = TryParseEnum(
            typeof(DateTimeKind), FindKey(opts, "DateTimeKind",
            DefaultDateTimeKind.ToString()), true);

        DateTimeKind kind = (enumValue is DateTimeKind) ?
            (DateTimeKind)enumValue : DefaultDateTimeKind;

        string dateTimeFormat = FindKey(opts, "DateTimeFormatString",
            DefaultDateTimeFormatString);

        //
        // NOTE: SQLite automatically sets the encoding of the database
        //       to UTF16 if called from sqlite3_open16().
        //
        if (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding",
                  DefaultUseUTF16Encoding.ToString())))
        {
            _sql = new SQLite3_UTF16(
                dateFormat, kind, dateTimeFormat, IntPtr.Zero, null,
                false);
        }
        else
        {
            _sql = new SQLite3(
                dateFormat, kind, dateTimeFormat, IntPtr.Zero, null,
                false);
        }
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Placeholder for a user-defined disposal routine
    /// </summary>
    /// <param name="disposing">True if the object is being disposed explicitly</param>
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                ////////////////////////////////////
                // dispose managed resources here...
                ////////////////////////////////////

                IDisposable disp;

                foreach (KeyValuePair<IntPtr, AggregateData> kv in _contextDataList)
                {
                    disp = kv.Value._data as IDisposable;
                    if (disp != null)
                        disp.Dispose();
                }
                _contextDataList.Clear();
                _contextDataList = null;

                _flags = SQLiteConnectionFlags.None;

                _InvokeFunc = null;
                _StepFunc = null;
                _FinalFunc = null;
                _CompareFunc = null;
                _base = null;
            }

            //////////////////////////////////////
            // release unmanaged resources here...
            //////////////////////////////////////

            disposed = true;
        }
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////

    private void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                ////////////////////////////////////
                // dispose managed resources here...
                ////////////////////////////////////

                if (_sqlite_stmt != null)
                {
                    _sqlite_stmt.Dispose();
                    _sqlite_stmt = null;
                }

                _paramNames = null;
                _paramValues = null;
                _sql = null;
                _sqlStatement = null;
            }

            //////////////////////////////////////
            // release unmanaged resources here...
            //////////////////////////////////////

            disposed = true;
        }
    }
    /// <summary>
    /// When the database connection is closed, all commands linked to this connection are automatically reset.
    /// </summary>
    public override void Close()
    {
      CheckDisposed();

      if (_sql != null)
      {
#if !PLATFORM_COMPACTFRAMEWORK
        if (_enlistment != null)
        {
          // If the connection is enlisted in a transaction scope and the scope is still active,
          // we cannot truly shut down this connection until the scope has completed.  Therefore make a 
          // hidden connection temporarily to hold open the connection until the scope has completed.
          SQLiteConnection cnn = new SQLiteConnection();
          cnn._sql = _sql;
          cnn._transactionLevel = _transactionLevel;
          cnn._enlistment = _enlistment;
          cnn._connectionState = _connectionState;
          cnn._version = _version;

          cnn._enlistment._transaction._cnn = cnn;
          cnn._enlistment._disposeConnection = true;

          _sql = null;
          _enlistment = null;
        }
#endif
        if (_sql != null)
        {
          _sql.Close();
          _sql = null;
        }
        _transactionLevel = 0;
      }
      OnStateChange(ConnectionState.Closed);
    }
Example #51
0
        /// <summary>
        /// Verifies that all SQL queries associated with the current command text
        /// can be successfully compiled.  A <see cref="SQLiteException" /> will be
        /// raised if any errors occur.
        /// </summary>
        public void VerifyOnly()
        {
            CheckDisposed();

            SQLiteConnection connection = _cnn;

            SQLiteConnection.Check(connection); /* throw */
            SQLiteBase sqlBase = connection._sql;

            if ((connection == null) || (sqlBase == null))
            {
                throw new SQLiteException("invalid or unusable connection");
            }

            List <SQLiteStatement> statements       = null;
            SQLiteStatement        currentStatement = null;

            try
            {
                string          text              = _commandText;
                uint            timeout           = (uint)(_commandTimeout * 1000);
                SQLiteStatement previousStatement = null;

                while ((text != null) && (text.Length > 0))
                {
                    currentStatement = sqlBase.Prepare(
                        connection, text, previousStatement, timeout,
                        ref text); /* throw */

                    previousStatement = currentStatement;

                    if (currentStatement != null)
                    {
                        if (statements == null)
                        {
                            statements = new List <SQLiteStatement>();
                        }

                        statements.Add(currentStatement);
                        currentStatement = null;
                    }

                    if (text == null)
                    {
                        continue;
                    }
                    text = text.Trim();
                }
            }
            finally
            {
                if (currentStatement != null)
                {
                    currentStatement.Dispose();
                    currentStatement = null;
                }

                if (statements != null)
                {
                    foreach (SQLiteStatement statement in statements)
                    {
                        if (statement == null)
                        {
                            continue;
                        }

                        statement.Dispose();
                    }

                    statements.Clear();
                    statements = null;
                }
            }
        }
    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
    /// </summary>
    public override void Open()
    {
      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      KeyValuePair<string, string>[] opts = ParseConnectionString();
      string fileName;

      if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
        throw new NotSupportedException("Only SQLite Version 3 is supported at this time");

      fileName = FindKey(opts, "Data Source", "");

      if (String.IsNullOrEmpty(fileName))
        throw new ArgumentException("Data Source cannot be empty.  Use :memory: to open an in-memory database");

      if (String.Compare(fileName, ":MEMORY:", true, CultureInfo.InvariantCulture) == 0)
        fileName = ":memory:";
#if PLATFORM_COMPACTFRAMEWORK
      else if (fileName.StartsWith(".\\"))
        fileName = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);
#endif
      try
      {
        bool bUTF16 = (Convert.ToBoolean(FindKey(opts, "UseUTF16Encoding", "False"), CultureInfo.InvariantCulture) == true);
        SQLiteDateFormats dateFormat = String.Compare(FindKey(opts, "DateTimeFormat", "ISO8601"), "ticks", true, CultureInfo.InvariantCulture) == 0 ? SQLiteDateFormats.Ticks : SQLiteDateFormats.ISO8601;

        if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
          _sql = new SQLite3_UTF16(dateFormat);
        else
          _sql = new SQLite3(dateFormat);

        fileName = ExpandFileName(fileName);

        try
        {
          if (IO.File.Exists(fileName) == false)
            throw new IO.FileNotFoundException(String.Format(CultureInfo.CurrentCulture, "Unable to locate file \"{0}\", creating new database.", fileName));
        }
        catch
        {
        }

        _sql.Open(fileName);

        string password = FindKey(opts, "Password", null);

        if (String.IsNullOrEmpty(password) == false)
          _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password));
        else if (_password != null)
          _sql.SetPassword(_password);
        _password = null;

        _dataSource = System.IO.Path.GetFileNameWithoutExtension(fileName);

        OnStateChange(ConnectionState.Open);

        using (SQLiteCommand cmd = CreateCommand())
        {
          string defValue;

          defValue = FindKey(opts, "Synchronous", "Normal");
          if (String.Compare(defValue, "Normal", true, CultureInfo.InvariantCulture) != 0)
          {
            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Synchronous={0}", defValue);
            cmd.ExecuteNonQuery();
          }

          defValue = FindKey(opts, "Cache Size", "2000");
          if (Convert.ToInt32(defValue) != 2000)
          {
            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Cache_Size={0}", defValue);
            cmd.ExecuteNonQuery();
          }

          if (fileName != ":memory:")
          {
            defValue = FindKey(opts, "Page Size", "1024");
            if (Convert.ToInt32(defValue) != 1024)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA Page_Size={0}", defValue);
              cmd.ExecuteNonQuery();
            }
          }
        }

#if !PLATFORM_COMPACTFRAMEWORK
        if (FindKey(opts, "Enlist", "Y").ToUpper()[0] == 'Y' && Transactions.Transaction.Current != null)
          EnlistTransaction(Transactions.Transaction.Current);
#endif
      }
      catch (SQLiteException)
      {
        OnStateChange(ConnectionState.Broken);
        throw;
      }
    }
    /// Passes a shutdown request off to SQLite.
    public int Shutdown()
    {
        CheckDisposed();

        // make sure we have an instance of the base class
        if (_sql == null)
        {
            SortedList<string, string> opts = ParseConnectionString(_connectionString);

            bool bUTF16 = (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", Boolean.FalseString)) == true);
            SQLiteDateFormats dateFormat = (SQLiteDateFormats)Enum.Parse(typeof(SQLiteDateFormats),
                                                                         FindKey(opts, "DateTimeFormat", "ISO8601"),
                                                                         true);

            DateTimeKind kind = (DateTimeKind)Enum.Parse(typeof(DateTimeKind),
                FindKey(opts, "DateTimeKind", "Unspecified"), true);

            if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
                _sql = new SQLite3_UTF16(dateFormat, kind);
            else
                _sql = new SQLite3(dateFormat, kind);
        }
        if (_sql != null) return _sql.Shutdown();
        throw new InvalidOperationException("Database connection not active.");
    }
Example #54
0
        /// <summary>
        /// Initializes the SQLite logging facilities.
        /// </summary>
        public static void Initialize()
        {
            //
            // BUFXIX: We cannot initialize the logging interface if the SQLite
            //         core library has already been initialized anywhere in
            //         the process (see ticket [2ce0870fad]).
            //
            if (SQLite3.StaticIsInitialized())
                return;

            //
            // BUGFIX: To avoid nasty situations where multiple AppDomains are
            //         attempting to initialize and/or shutdown what is really
            //         a shared native resource (i.e. the SQLite core library
            //         is loaded per-process and has only one logging callback,
            //         not one per-AppDomain, which it knows nothing about),
            //         prevent all non-default AppDomains from registering a
            //         log handler unless the "Force_SQLiteLog" environment
            //         variable is used to manually override this safety check.
            //
            if (!AppDomain.CurrentDomain.IsDefaultAppDomain() &&
                Environment.GetEnvironmentVariable("Force_SQLiteLog") == null)
            {
                return;
            }

            lock (syncRoot)
            {
                //
                // NOTE: Add an event handler for the DomainUnload event so
                //       that we can unhook our logging managed function
                //       pointer from the native SQLite code prior to it
                //       being invalidated.
                //
                // BUGFIX: Make sure this event handler is only added one
                //         time (per-AppDomain).
                //
                if (_domainUnload == null)
                {
                    _domainUnload = new EventHandler(DomainUnload);
                    AppDomain.CurrentDomain.DomainUnload += _domainUnload;
                }

                //
                // NOTE: Create an instance of the SQLite wrapper class.
                //
                if (_sql == null)
                    _sql = new SQLite3(SQLiteDateFormats.Default,
                        DateTimeKind.Unspecified);

                //
                // NOTE: Create a single "global" (i.e. per-process) callback
                //       to register with SQLite.  This callback will pass the
                //       event on to any registered handler.  We only want to
                //       do this once.
                //
                if (_callback == null)
                {
                    _callback = new SQLiteLogCallback(LogCallback);

                    int rc = _sql.SetLogCallback(_callback);

                    if (rc != 0)
                        throw new SQLiteException(rc,
                            "Failed to initialize logging.");
                }

                //
                // NOTE: Logging is enabled by default.
                //
                _enabled = true;

                //
                // NOTE: For now, always setup the default log event handler.
                //
                AddDefaultHandler();
            }
        }
    /// <summary>
    /// Opens the connection using the parameters found in the <see cref="ConnectionString">ConnectionString</see>
    /// </summary>
    public override void Open()
    {
      CheckDisposed();

      if (_connectionState != ConnectionState.Closed)
        throw new InvalidOperationException();

      Close();

      SortedList<string, string> opts = ParseConnectionString(_connectionString);

      _flags = (SQLiteConnectionFlags)Enum.Parse(typeof(SQLiteConnectionFlags), FindKey(opts, "Flags", "Default"), true);

      string fileName;

      if (Convert.ToInt32(FindKey(opts, "Version", "3"), CultureInfo.InvariantCulture) != 3)
        throw new NotSupportedException("Only SQLite Version 3 is supported at this time");

      fileName = FindKey(opts, "Data Source", "");

      if (String.IsNullOrEmpty(fileName))
      {
        fileName = FindKey(opts, "Uri", "");
        if (String.IsNullOrEmpty(fileName))
          throw new ArgumentException("Data Source cannot be empty.  Use :memory: to open an in-memory database");
        else
          fileName = MapUriPath(fileName);
      }

      if (String.Compare(fileName, ":MEMORY:", StringComparison.OrdinalIgnoreCase) == 0)
        fileName = ":memory:";
      else
      {
#if PLATFORM_COMPACTFRAMEWORK
       if (fileName.StartsWith("./") || fileName.StartsWith(".\\"))
         fileName = Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().GetName().CodeBase) + fileName.Substring(1);
#endif
       fileName = ExpandFileName(fileName);
      }
      try
      {
        bool usePooling = (SQLiteConvert.ToBoolean(FindKey(opts, "Pooling", Boolean.FalseString)) == true);
        int maxPoolSize = Convert.ToInt32(FindKey(opts, "Max Pool Size", "100"), CultureInfo.InvariantCulture);

        _defaultTimeout = Convert.ToInt32(FindKey(opts, "Default Timeout", "30"), CultureInfo.CurrentCulture);

        _defaultIsolation = (IsolationLevel)Enum.Parse(typeof(IsolationLevel), FindKey(opts, "Default IsolationLevel", "Serializable"), true);
        if (_defaultIsolation != IsolationLevel.Serializable && _defaultIsolation != IsolationLevel.ReadCommitted)
          throw new NotSupportedException("Invalid Default IsolationLevel specified");

        _baseSchemaName = FindKey(opts, "BaseSchemaName", DefaultBaseSchemaName);

        //string temp = FindKey(opts, "DateTimeFormat", "ISO8601");
        //if (String.Compare(temp, "ticks", StringComparison.OrdinalIgnoreCase) == 0) dateFormat = SQLiteDateFormats.Ticks;
        //else if (String.Compare(temp, "julianday", StringComparison.OrdinalIgnoreCase) == 0) dateFormat = SQLiteDateFormats.JulianDay;

        if (_sql == null)
        {
          bool bUTF16 = (SQLiteConvert.ToBoolean(FindKey(opts, "UseUTF16Encoding", Boolean.FalseString)) == true);
          SQLiteDateFormats dateFormat = (SQLiteDateFormats)Enum.Parse(typeof(SQLiteDateFormats),
                                                                       FindKey(opts, "DateTimeFormat", "ISO8601"),
                                                                       true);

          DateTimeKind kind = (DateTimeKind)Enum.Parse(typeof(DateTimeKind),
              FindKey(opts, "DateTimeKind", "Unspecified"), true);

          if (bUTF16) // SQLite automatically sets the encoding of the database to UTF16 if called from sqlite3_open16()
            _sql = new SQLite3_UTF16(dateFormat, kind);
          else
            _sql = new SQLite3(dateFormat, kind);
        }

        SQLiteOpenFlagsEnum flags = SQLiteOpenFlagsEnum.None;

        if (SQLiteConvert.ToBoolean(FindKey(opts, "FailIfMissing", Boolean.FalseString)) == false)
          flags |= SQLiteOpenFlagsEnum.Create;

        if (SQLiteConvert.ToBoolean(FindKey(opts, "Read Only", Boolean.FalseString)) == true)
        {
          flags |= SQLiteOpenFlagsEnum.ReadOnly;
          // SQLite will return SQLITE_MISUSE on ReadOnly and Create
          flags &= ~SQLiteOpenFlagsEnum.Create;
        }
        else
        {
          flags |= SQLiteOpenFlagsEnum.ReadWrite;
        }

        _sql.Open(fileName, _flags, flags, maxPoolSize, usePooling);

        _binaryGuid = (SQLiteConvert.ToBoolean(FindKey(opts, "BinaryGUID", Boolean.TrueString)) == true);

        string password = FindKey(opts, "Password", null);

        if (String.IsNullOrEmpty(password) == false)
          _sql.SetPassword(System.Text.UTF8Encoding.UTF8.GetBytes(password));
        else if (_password != null)
          _sql.SetPassword(_password);
        _password = null;

        _dataSource = Path.GetFileNameWithoutExtension(fileName);

        _version++;

        ConnectionState oldstate = _connectionState;
        _connectionState = ConnectionState.Open;
        try
        {
          using (SQLiteCommand cmd = CreateCommand())
          {
            string defValue;

            if (fileName != ":memory:")
            {
              defValue = FindKey(opts, "Page Size", "1024");
              if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 1024)
              {
                cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", defValue);
                cmd.ExecuteNonQuery();
              }
            }

            defValue = FindKey(opts, "Max Page Count", "0");
            if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 0)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Legacy Format", Boolean.FalseString);
            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}", SQLiteConvert.ToBoolean(defValue) == true ? "ON" : "OFF");
            cmd.ExecuteNonQuery();

            defValue = FindKey(opts, "Synchronous", "Normal");
            if (String.Compare(defValue, "Full", StringComparison.OrdinalIgnoreCase) != 0)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Cache Size", "2000");
            if (Convert.ToInt32(defValue, CultureInfo.InvariantCulture) != 2000)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Journal Mode", "Default");
            if (String.Compare(defValue, "Default", StringComparison.OrdinalIgnoreCase) != 0)
            {
              cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA journal_mode={0}", defValue);
              cmd.ExecuteNonQuery();
            }

            defValue = FindKey(opts, "Foreign Keys", Boolean.FalseString);
            cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA foreign_keys={0}", SQLiteConvert.ToBoolean(defValue) == true ? "ON" : "OFF");
            cmd.ExecuteNonQuery();
          }

          if (_commitHandler != null)
            _sql.SetCommitHook(_commitCallback);

          if (_updateHandler != null)
            _sql.SetUpdateHook(_updateCallback);

          if (_rollbackHandler != null)
            _sql.SetRollbackHook(_rollbackCallback);

#if !PLATFORM_COMPACTFRAMEWORK
          if (Transactions.Transaction.Current != null && SQLiteConvert.ToBoolean(FindKey(opts, "Enlist", Boolean.TrueString)) == true)
            EnlistTransaction(Transactions.Transaction.Current);
#endif

          _connectionState = oldstate;
          OnStateChange(ConnectionState.Open);
        }
        catch
        {
          _connectionState = oldstate;
          throw;
        }
      }
      catch (SQLiteException)
      {
        Close();
        throw;
      }
    }
Example #56
0
        /// <summary>
        /// Initializes the SQLite logging facilities.
        /// </summary>
        public static void Initialize()
        {
            //
            // BUFXIX: We cannot initialize the logging interface if the SQLite
            //         core library has already been initialized anywhere in
            //         the process (see ticket [2ce0870fad]).
            //
            if (SQLite3.StaticIsInitialized())
            {
                return;
            }

            //
            // BUGFIX: To avoid nasty situations where multiple AppDomains are
            //         attempting to initialize and/or shutdown what is really
            //         a shared native resource (i.e. the SQLite core library
            //         is loaded per-process and has only one logging callback,
            //         not one per-AppDomain, which it knows nothing about),
            //         prevent all non-default AppDomains from registering a
            //         log handler unless the "Force_SQLiteLog" environment
            //         variable is used to manually override this safety check.
            //
            if (!AppDomain.CurrentDomain.IsDefaultAppDomain() &&
                Environment.GetEnvironmentVariable("Force_SQLiteLog") == null)
            {
                return;
            }

            lock (syncRoot)
            {
                //
                // NOTE: Add an event handler for the DomainUnload event so
                //       that we can unhook our logging managed function
                //       pointer from the native SQLite code prior to it
                //       being invalidated.
                //
                // BUGFIX: Make sure this event handler is only added one
                //         time (per-AppDomain).
                //
                if (_domainUnload == null)
                {
                    _domainUnload = new EventHandler(DomainUnload);
                    AppDomain.CurrentDomain.DomainUnload += _domainUnload;
                }

                //
                // NOTE: Create an instance of the SQLite wrapper class.
                //
                if (_sql == null)
                {
                    _sql = new SQLite3(SQLiteDateFormats.Default,
                                       DateTimeKind.Unspecified);
                }

                //
                // NOTE: Create a single "global" (i.e. per-process) callback
                //       to register with SQLite.  This callback will pass the
                //       event on to any registered handler.  We only want to
                //       do this once.
                //
                if (_callback == null)
                {
                    _callback = new SQLiteLogCallback(LogCallback);

                    SQLiteErrorCode rc = _sql.SetLogCallback(_callback);

                    if (rc != SQLiteErrorCode.Ok)
                    {
                        throw new SQLiteException(rc,
                                                  "Failed to initialize logging.");
                    }
                }

                //
                // NOTE: Logging is enabled by default.
                //
                _enabled = true;

                //
                // NOTE: For now, always setup the default log event handler.
                //
                AddDefaultHandler();
            }
        }
    /// <summary>
    /// Called by SQLiteBase derived classes, this function binds all user-defined functions to a connection.
    /// It is done this way so that all user-defined functions will access the database using the same encoding scheme
    /// as the connection (UTF-8 or UTF-16).
    /// </summary>
    /// <remarks>
    /// The wrapper functions that interop with SQLite will create a unique cookie value, which internally is a pointer to
    /// all the wrapped callback functions.  The interop function uses it to map CDecl callbacks to StdCall callbacks.
    /// </remarks>
    /// <param name="sqlbase">The base object on which the functions are to bind</param>
    /// <param name="flags">The flags associated with the parent connection object</param>
    /// <returns>Returns an array of functions which the connection object should retain until the connection is closed.</returns>
    internal static SQLiteFunction[] BindFunctions(SQLiteBase sqlbase, SQLiteConnectionFlags flags)
    {
      SQLiteFunction f;
      List<SQLiteFunction> lFunctions = new List<SQLiteFunction>();

      foreach (SQLiteFunctionAttribute pr in _registeredFunctions)
      {
        f = (SQLiteFunction)Activator.CreateInstance(pr._instanceType);

        f._base = sqlbase;
        f._flags = flags;
        f._InvokeFunc = (pr.FuncType == FunctionType.Scalar) ? new SQLiteCallback(f.ScalarCallback) : null;
        f._StepFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteCallback(f.StepCallback) : null;
        f._FinalFunc = (pr.FuncType == FunctionType.Aggregate) ? new SQLiteFinalCallback(f.FinalCallback) : null;
        f._CompareFunc = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback) : null;
        f._CompareFunc16 = (pr.FuncType == FunctionType.Collation) ? new SQLiteCollation(f.CompareCallback16) : null;

        if (pr.FuncType != FunctionType.Collation)
          sqlbase.CreateFunction(pr.Name, pr.Arguments, (f is SQLiteFunctionEx), f._InvokeFunc, f._StepFunc, f._FinalFunc);
        else
          sqlbase.CreateCollation(pr.Name, f._CompareFunc, f._CompareFunc16);


        lFunctions.Add(f);
      }

      SQLiteFunction[] arFunctions = new SQLiteFunction[lFunctions.Count];
      lFunctions.CopyTo(arFunctions, 0);

      return arFunctions;
    }
    /// <summary>
    /// Initializes the connection with the specified connection string
    /// </summary>
    /// <param name="connectionString">The connection string to use on the connection</param>
    public SQLiteConnection(string connectionString)
    {
      _sql = null;
      _connectionState = ConnectionState.Closed;
      _connectionString = "";
      _transactionLevel = 0;
      _commandList = new List<SQLiteCommand>();

      if (connectionString != null)
        ConnectionString = connectionString;
    }