Esempio n. 1
0
 public static void BindFunction(SQLiteConnection connection, SQLiteFunction function)
 {
     var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast<SQLiteFunctionAttribute>().ToArray();
     if (attributes.Length == 0)
     {
         throw new InvalidOperationException("SQLiteFunction doesn't have SQLiteFunctionAttribute");
     }
     connection.BindFunction(attributes[0], function);
 }
Esempio n. 2
0
        internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool)
        {
            if (_sql != null)
            {
                return;
            }

            _usePool = usePool;
            if (usePool)
            {
                _fileName = strFilename;
                _sql      = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);
            }

            if (_sql == null)
            {
                IntPtr db;

#if !SQLITE_STANDARD
                int n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), (int)openFlags, out db);
#else
                if ((openFlags & SQLiteOpenFlagsEnum.Create) == 0 && System.IO.File.Exists(strFilename) == false)
                {
                    throw new SQLiteException((int)SQLiteErrorCode.CantOpen, strFilename);
                }

                int n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db);
#endif

#if DEBUG && !NET_COMPACT_20
                Trace.WriteLine(String.Format("Open: {0}", db));
#endif

                if (n > 0)
                {
                    throw new SQLiteException(n, null);
                }

                _sql = db;
            }
            _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags);
        }
Esempio n. 3
0
        internal override CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context)
        {
#if !SQLITE_STANDARD
            CollationSequence seq = new CollationSequence();
            int    len;
            int    type;
            int    enc;
            IntPtr p = UnsafeNativeMethods.sqlite3_context_collseq(context, out type, out enc, out len);

            if (p != null)
            {
                seq.Name = UTF8ToString(p, len);
            }
            seq.Type     = (CollationTypeEnum)type;
            seq._func    = func;
            seq.Encoding = (CollationEncodingEnum)enc;

            return(seq);
#else
            throw new NotImplementedException();
#endif
        }
Esempio n. 4
0
 internal override void Open(string strFilename, SQLiteOpenFlagsEnum flags, int maxPoolSize, bool usePool)
 {
     if (base._sql == null)
     {
         base._usePool = usePool;
         if (usePool)
         {
             base._fileName = strFilename;
             base._sql      = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out this._poolVersion);
         }
         if (base._sql == null)
         {
             IntPtr ptr;
             int    errorCode = UnsafeNativeMethods.sqlite3_open16_interop(SQLiteConvert.ToUTF8(strFilename), (int)flags, out ptr);
             if (errorCode > 0)
             {
                 throw new SQLiteException(errorCode, null);
             }
             base._sql = ptr;
         }
         base._functionsArray = SQLiteFunction.BindFunctions(this);
     }
 }
 /// <summary>
 /// This function binds a user-defined functions to the connection.
 /// </summary>
 /// <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 abstract void BindFunction(SQLiteFunctionAttribute functionAttribute, SQLiteFunction function, SQLiteConnectionFlags flags);
    /// <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);
        }
    }
Esempio n. 7
0
    /// <summary>
    /// Creates a <see cref="SQLiteFunction" /> instance based on the specified
    /// <see cref="SQLiteFunctionAttribute" />.
    /// </summary>
    /// <param name="functionAttribute">
    /// The <see cref="SQLiteFunctionAttribute" /> containing the metadata about
    /// the function to create.
    /// </param>
    /// <param name="function">
    /// The created function -OR- null if the function could not be created.
    /// </param>
    /// <returns>
    /// Non-zero if the function was created; otherwise, zero.
    /// </returns>
    private static bool CreateFunction(
        SQLiteFunctionAttribute functionAttribute,
        out SQLiteFunction function
        )
    {
        if (functionAttribute == null)
        {
            function = null;
            return false;
        }
        else if ((functionAttribute.Callback1 != null) ||
                (functionAttribute.Callback2 != null))
        {
            function = new SQLiteDelegateFunction(
                functionAttribute.Callback1,
                functionAttribute.Callback2);

            return true;
        }
        else if (functionAttribute.InstanceType != null)
        {
            function = (SQLiteFunction)Activator.CreateInstance(
                functionAttribute.InstanceType);

            return true;
        }
        else
        {
            function = null;
            return false;
        }
    }
Esempio n. 8
0
        internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool)
        {
            //
            // NOTE: If the database connection is currently open, attempt to
            //       close it now.  This must be done because the file name or
            //       other parameters that may impact the underlying database
            //       connection may have changed.
            //
            if (_sql != null)
            {
                Close(true);
            }

            //
            // NOTE: If the connection was not closed successfully, throw an
            //       exception now.
            //
            if (_sql != null)
            {
                throw new SQLiteException("connection handle is still active");
            }

            _usePool  = usePool;
            _fileName = strFilename;

            if (usePool)
            {
                _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);

#if !NET_COMPACT_20 && TRACE_CONNECTION
                Trace.WriteLine(String.Format("Open16 (Pool): {0}", (_sql != null) ? _sql.ToString() : "<null>"));
#endif
            }

            if (_sql == null)
            {
                try
                {
                    // do nothing.
                }
                finally /* NOTE: Thread.Abort() protection. */
                {
                    IntPtr          db = IntPtr.Zero;
                    SQLiteErrorCode n;

#if !SQLITE_STANDARD
                    if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions)
                    {
                        n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), openFlags, ref db);
                    }
                    else
#endif
                    {
                        //
                        // NOTE: This flag check is designed to enforce the constraint that opening
                        //       a database file that does not already exist requires specifying the
                        //       "Create" flag, even when a native API is used that does not accept
                        //       a flags parameter.
                        //
                        if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename))
                        {
                            throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename);
                        }

                        n = UnsafeNativeMethods.sqlite3_open16(strFilename, ref db);
                    }

#if !NET_COMPACT_20 && TRACE_CONNECTION
                    Trace.WriteLine(String.Format("Open16: {0}", db));
#endif

                    if (n != SQLiteErrorCode.Ok)
                    {
                        throw new SQLiteException(n, null);
                    }
                    _sql = new SQLiteConnectionHandle(db, true);
                }
                lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }

                SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
                                               SQLiteConnectionEventType.NewCriticalHandle, null, null,
                                               null, null, _sql, strFilename, new object[] { strFilename,
                                                                                             connectionFlags, openFlags, maxPoolSize, usePool }));
            }

            // Bind functions to this connection.  If any previous functions of the same name
            // were already bound, then the new bindings replace the old.
            if ((connectionFlags & SQLiteConnectionFlags.NoBindFunctions) != SQLiteConnectionFlags.NoBindFunctions)
            {
                if (_functions == null)
                {
                    _functions = new List <SQLiteFunction>();
                }

                _functions.AddRange(new List <SQLiteFunction>(SQLiteFunction.BindFunctions(this, connectionFlags)));
            }

            SetTimeout(0);
            GC.KeepAlive(_sql);
        }
Esempio n. 9
0
 internal abstract CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context);
    ///////////////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Attempts to bind the specified <see cref="SQLiteFunction" /> object
    /// instance to this connection.
    /// </summary>
    /// <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>
    public void BindFunction(
        SQLiteFunctionAttribute functionAttribute,
        SQLiteFunction function
        )
    {
        CheckDisposed();

        if (_sql == null)
            throw new InvalidOperationException(
                "Database connection not valid for binding functions.");

        _sql.BindFunction(functionAttribute, function, _flags);
    }
Esempio n. 11
0
        internal override void Open(string strFilename, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool)
        {
            if (_sql != null)
            {
                return;
            }

            _usePool  = usePool;
            _fileName = strFilename;

            if (usePool)
            {
                _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);

#if !NET_COMPACT_20 && TRACE_CONNECTION
                Trace.WriteLine(String.Format("Open16 (Pool): {0}", (_sql != null) ? _sql.ToString() : "<null>"));
#endif
            }

            if (_sql == null)
            {
                try
                {
                    // do nothing.
                }
                finally /* NOTE: Thread.Abort() protection. */
                {
                    IntPtr          db;
                    SQLiteErrorCode n;

#if !SQLITE_STANDARD
                    if ((connectionFlags & SQLiteConnectionFlags.NoExtensionFunctions) != SQLiteConnectionFlags.NoExtensionFunctions)
                    {
                        n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), openFlags, out db);
                    }
                    else
#endif
                    {
                        //
                        // NOTE: This flag check is designed to enforce the constraint that opening
                        //       a database file that does not already exist requires specifying the
                        //       "Create" flag, even when a native API is used that does not accept
                        //       a flags parameter.
                        //
                        if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename))
                        {
                            throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename);
                        }

                        n = UnsafeNativeMethods.sqlite3_open16(strFilename, out db);
                    }

#if !NET_COMPACT_20 && TRACE_CONNECTION
                    Trace.WriteLine(String.Format("Open16: {0}", db));
#endif

                    if (n != SQLiteErrorCode.Ok)
                    {
                        throw new SQLiteException(n, null);
                    }
                    _sql = new SQLiteConnectionHandle(db);
                }
                lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }
            }
            _functionsArray = SQLiteFunction.BindFunctions(this, connectionFlags);
            SetTimeout(0);
            GC.KeepAlive(_sql);
        }
Esempio n. 12
0
 /// <summary>
 /// This function binds a user-defined functions to the connection.
 /// </summary>
 /// <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 abstract void BindFunction(SQLiteFunctionAttribute functionAttribute, SQLiteFunction function, SQLiteConnectionFlags flags);
    /// <summary>
    /// This function binds a user-defined function to the connection.
    /// </summary>
    /// <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 override void BindFunction(
        SQLiteFunctionAttribute functionAttribute,
        SQLiteFunction function,
        SQLiteConnectionFlags flags
        )
    {
        SQLiteFunction.BindFunction(this, functionAttribute, function, flags);

        if (_functions == null)
            _functions = new List<SQLiteFunction>();

        _functions.Add(function);
    }
Esempio n. 14
0
    /// <summary>
    /// This function binds a user-defined function to the connection.
    /// </summary>
    /// <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 override void BindFunction(
        SQLiteFunctionAttribute functionAttribute,
        SQLiteFunction function,
        SQLiteConnectionFlags flags
        )
    {
        if (functionAttribute == null)
            throw new ArgumentNullException("functionAttribute");

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

        SQLiteFunction.BindFunction(this, functionAttribute, function, flags);

        if (_functions == null)
            _functions = new Dictionary<SQLiteFunctionAttribute, SQLiteFunction>();

        _functions[functionAttribute] = function;
    }
Esempio n. 15
0
        /// <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();
              }
        }
Esempio n. 16
0
 internal abstract CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context);
Esempio n. 17
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </summary>
        /// <param name="table">
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </param>
        /// <param name="argumentCount">
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </param>
        /// <param name="name">
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </param>
        /// <param name="function">
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </param>
        /// <param name="pClientData">
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </param>
        /// <returns>
        /// See the <see cref="ISQLiteManagedModule.FindFunction" /> method.
        /// </returns>
        public override bool FindFunction(
            SQLiteVirtualTable table,
            int argumentCount,
            string name,
            ref SQLiteFunction function,
            ref IntPtr pClientData
            )
        {
            CheckDisposed();

            return ResultCodeToFindFunctionResult(GetMethodResultCode(
                "FindFunction"));
        }
Esempio n. 18
0
        ///////////////////////////////////////////////////////////////////////

        #region Function Lookup Methods
        /// <summary>
        /// Deterimines the key that should be used to identify and store the
        /// <see cref="SQLiteFunction" /> object instance for the virtual table
        /// (i.e. to be returned via the
        /// <see cref="ISQLiteNativeModule.xFindFunction" /> method).
        /// </summary>
        /// <param name="argumentCount">
        /// The number of arguments to the virtual table function.
        /// </param>
        /// <param name="name">
        /// The name of the virtual table function.
        /// </param>
        /// <param name="function">
        /// The <see cref="SQLiteFunction" /> object instance associated with
        /// this virtual table function.
        /// </param>
        /// <returns>
        /// The string that should be used to identify and store the virtual
        /// table function instance.  This method cannot return null.  If null
        /// is returned from this method, the behavior is undefined.
        /// </returns>
        protected virtual string GetFunctionKey(
            int argumentCount,
            string name,
            SQLiteFunction function
            )
        {
            return UnsafeNativeMethods.StringFormat(
                CultureInfo.InvariantCulture,
                "{0}:{1}", argumentCount, name);
        }
Esempio n. 19
0
        internal override void Open(string strFilename, string vfsName, SQLiteConnectionFlags connectionFlags, SQLiteOpenFlagsEnum openFlags, int maxPoolSize, bool usePool)
        {
            //
            // NOTE: If the database connection is currently open, attempt to
            //       close it now.  This must be done because the file name or
            //       other parameters that may impact the underlying database
            //       connection may have changed.
            //
            if (_sql != null)
            {
                Close(false);
            }

            //
            // NOTE: If the connection was not closed successfully, throw an
            //       exception now.
            //
            if (_sql != null)
            {
                throw new SQLiteException("connection handle is still active");
            }

            _usePool  = usePool;
            _fileName = strFilename;
            _flags    = connectionFlags;

            if (usePool)
            {
                _sql = SQLiteConnectionPool.Remove(strFilename, maxPoolSize, out _poolVersion);

                SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
                                               SQLiteConnectionEventType.OpenedFromPool, null, null,
                                               null, null, _sql, strFilename, new object[] {
                    typeof(SQLite3_UTF16), strFilename, vfsName,
                    connectionFlags, openFlags, maxPoolSize, usePool,
                    _poolVersion
                }));

#if !NET_COMPACT_20 && TRACE_CONNECTION
                Trace.WriteLine(HelperMethods.StringFormat(
                                    CultureInfo.CurrentCulture,
                                    "Open16 (Pool): {0}",
                                    HandleToString()));
#endif
            }

            if (_sql == null)
            {
                try
                {
                    // do nothing.
                }
                finally /* NOTE: Thread.Abort() protection. */
                {
                    IntPtr          db = IntPtr.Zero;
                    SQLiteErrorCode n;

                    int extFuncs = HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoExtensionFunctions) ? 0 : 1;

#if !SQLITE_STANDARD
                    if ((vfsName != null) || (extFuncs != 0))
                    {
                        n = UnsafeNativeMethods.sqlite3_open16_interop(ToUTF8(strFilename), ToUTF8(vfsName), openFlags, extFuncs, ref db);
                    }
                    else
#endif
                    {
                        //
                        // NOTE: This flag check is designed to enforce the constraint that opening
                        //       a database file that does not already exist requires specifying the
                        //       "Create" flag, even when a native API is used that does not accept
                        //       a flags parameter.
                        //
                        if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename))
                        {
                            throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename);
                        }

                        if (vfsName != null)
                        {
                            throw new SQLiteException(SQLiteErrorCode.CantOpen, HelperMethods.StringFormat(
                                                          CultureInfo.CurrentCulture,
                                                          "cannot open using UTF-16 and VFS \"{0}\": need interop assembly", vfsName));
                        }

                        n = UnsafeNativeMethods.sqlite3_open16(strFilename, ref db);
                    }

#if !NET_COMPACT_20 && TRACE_CONNECTION
                    Trace.WriteLine(HelperMethods.StringFormat(
                                        CultureInfo.CurrentCulture,
                                        "Open16: {0}", db));
#endif

                    if (n != SQLiteErrorCode.Ok)
                    {
                        throw new SQLiteException(n, null);
                    }
                    _sql = new SQLiteConnectionHandle(db, true);
                }
                lock (_sql) { /* HACK: Force the SyncBlock to be "created" now. */ }

                SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
                                               SQLiteConnectionEventType.NewCriticalHandle, null,
                                               null, null, null, _sql, strFilename, new object[] {
                    typeof(SQLite3_UTF16), strFilename, vfsName,
                    connectionFlags, openFlags, maxPoolSize, usePool
                }));
            }

            // Bind functions to this connection.  If any previous functions of the same name
            // were already bound, then the new bindings replace the old.
            if (!HelperMethods.HasFlags(connectionFlags, SQLiteConnectionFlags.NoBindFunctions))
            {
                if (_functions == null)
                {
                    _functions = new Dictionary <SQLiteFunctionAttribute, SQLiteFunction>();
                }

                foreach (KeyValuePair <SQLiteFunctionAttribute, SQLiteFunction> pair
                         in SQLiteFunction.BindFunctions(this, connectionFlags))
                {
                    _functions[pair.Key] = pair.Value;
                }
            }

            SetTimeout(0);
            GC.KeepAlive(_sql);
        }
Esempio n. 20
0
    internal override CollationSequence GetCollationSequence(SQLiteFunction func, IntPtr context)
    {
#if !SQLITE_STANDARD
      CollationSequence seq = new CollationSequence();
      int len;
      int type;
      int enc;
      IntPtr p = UnsafeNativeMethods.sqlite3_context_collseq(context, out type, out enc, out len);

      if (p != null) seq.Name = UTF8ToString(p, len);
      seq.Type = (CollationTypeEnum)type;
      seq._func = func;
      seq.Encoding = (CollationEncodingEnum)enc;

      return seq;
#else
      throw new NotImplementedException();
#endif
    }
        ///////////////////////////////////////////////////////////////////////

        #region Function Lookup Methods
        /// <summary>
        /// Deterimines the key that should be used to identify and store the
        /// <see cref="SQLiteFunction" /> object instance for the virtual table
        /// (i.e. to be returned via the
        /// <see cref="ISQLiteNativeModule.xFindFunction" /> method).
        /// </summary>
        /// <param name="argumentCount">
        /// The number of arguments to the virtual table function.
        /// </param>
        /// <param name="name">
        /// The name of the virtual table function.
        /// </param>
        /// <param name="function">
        /// The <see cref="SQLiteFunction" /> object instance associated with
        /// this virtual table function.
        /// </param>
        /// <returns>
        /// The string that should be used to identify and store the virtual
        /// table function instance.  This method cannot return null.  If null
        /// is returned from this method, the behavior is undefined.
        /// </returns>
        protected virtual string GetFunctionKey(
            int argumentCount,
            string name,
            SQLiteFunction function
            )
        {
            return String.Format("{0}:{1}", argumentCount, name);
        }
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        /// This method is called in response to the
        /// <see cref="ISQLiteNativeModule.xFindFunction" /> method.
        /// </summary>
        /// <param name="table">
        /// The <see cref="SQLiteVirtualTable" /> object instance associated
        /// with this virtual table.
        /// </param>
        /// <param name="argumentCount">
        /// The number of arguments to the function being sought.
        /// </param>
        /// <param name="name">
        /// The name of the function being sought.
        /// </param>
        /// <param name="function">
        /// Upon success, this parameter must be modified to contain the
        /// <see cref="SQLiteFunction" /> object instance responsible for
        /// implementing the specified function.
        /// </param>
        /// <param name="pClientData">
        /// Upon success, this parameter must be modified to contain the
        /// native user-data pointer associated with
        /// <paramref name="function" />.
        /// </param>
        /// <returns>
        /// Non-zero if the specified function was found; zero otherwise.
        /// </returns>
        public abstract bool FindFunction(
            SQLiteVirtualTable table,
            int argumentCount,
            string name,
            ref SQLiteFunction function,
            ref IntPtr pClientData
            );
Esempio n. 23
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;
    }
Esempio n. 24
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;
        }
    }