/// <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;
        }
      }
    }
예제 #2
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;
            }
        }
예제 #3
0
        internal override void Bind_DateTime(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, DateTime dt)
        {
            switch (_datetimeFormat)
            {
            case SQLiteDateFormats.Ticks:
            case SQLiteDateFormats.JulianDay:
            case SQLiteDateFormats.UnixEpoch:
            {
                base.Bind_DateTime(stmt, flags, index, dt);
                break;
            }

            default:
            {
#if !PLATFORM_COMPACTFRAMEWORK
                if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
                {
                    SQLiteStatementHandle handle =
                        (stmt != null) ? stmt._sqlite_stmt : null;

                    LogBind(handle, index, dt);
                }
#endif

                Bind_Text(stmt, flags, index, ToString(dt));
                break;
            }
            }
        }
예제 #4
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;
                }
            }
        }
예제 #5
0
파일: SQLiteBase.cs 프로젝트: bdcliang/BD
 internal static void FinalizeStatement(SQLiteStatementHandle stmt)
 {
     lock (_lock)
     {
         int errorCode = UnsafeNativeMethods.sqlite3_finalize_interop((IntPtr)stmt);
         if (errorCode > 0)
         {
             throw new SQLiteException(errorCode, null);
         }
     }
 }
예제 #6
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;
 }
예제 #7
0
        /// <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;
        }
예제 #8
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());
                }
            }
        }
예제 #9
0
        internal static void FinalizeStatement(SQLiteStatementHandle stmt)
        {
            lock (_lock)
            {
#if !SQLITE_STANDARD
                int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
#else
                int n = UnsafeNativeMethods.sqlite3_finalize(stmt);
#endif
                if (n > 0)
                {
                    throw new SQLiteException(n, null);
                }
            }
        }
예제 #10
0
        internal override void Bind_Text(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, string value)
        {
            SQLiteStatementHandle handle = stmt._sqlite_stmt;

#if !PLATFORM_COMPACTFRAMEWORK
            if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
            {
                LogBind(handle, index, value);
            }
#endif

            SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_text16(handle, index, value, value.Length * 2, (IntPtr)(-1));
            if (n != SQLiteErrorCode.Ok)
            {
                throw new SQLiteException(n, GetLastError());
            }
        }
예제 #11
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;
                }
            }
        }
 /// <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;
 }
예제 #13
0
    protected static void LogBind(SQLiteStatementHandle handle, int index, DateTime value)
    {
        IntPtr handleIntPtr = handle;

        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
            CultureInfo.CurrentCulture,
            "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
            handleIntPtr, index, typeof(DateTime), FormatDateTime(value)));
    }
예제 #14
0
    protected static void LogBind(SQLiteStatementHandle handle, int index, byte[] value)
    {
        IntPtr handleIntPtr = handle;

        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
            CultureInfo.CurrentCulture,
            "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
            handleIntPtr, index, typeof(Byte[]), (value != null) ? ToHexadecimalString(value) : "<null>"));
    }
    ///////////////////////////////////////////////////////////////////////////////////////////////

    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;
        }
    }
    protected static void LogBind(SQLiteStatementHandle handle, int index)
    {
        IntPtr handleIntPtr = handle;

        SQLiteLog.LogMessage(String.Format(
            CultureInfo.CurrentCulture,
            "Binding statement {0} paramter #{1} as NULL...",
            handleIntPtr, index));
    }
예제 #17
0
    protected static void LogBind(SQLiteStatementHandle handle, int index, byte[] value)
    {
        //IntPtr handleIntPtr = handle;

        //SQLiteLog.LogMessage(0, String.Format(
        //    "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
        //    handleIntPtr, index, typeof(Byte[]), (value != null) ? ToHexadecimalString(value) : "<null>"));
    }
예제 #18
0
    internal static void FinalizeStatement(SQLiteStatementHandle stmt)
    {
      lock (_lock)
      {
#if !SQLITE_STANDARD
        int n = UnsafeNativeMethods.sqlite3_finalize_interop(stmt);
#else
      int n = UnsafeNativeMethods.sqlite3_finalize(stmt);
#endif
        if (n > 0) throw new SQLiteException(n, null);
      }
    }
예제 #19
0
    protected static void LogBind(SQLiteStatementHandle handle, int index, DateTime value)
    {
        //IntPtr handleIntPtr = handle;

        //SQLiteLog.LogMessage(0, String.Format(
        //    "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
        //    handleIntPtr, index, typeof(DateTime), FormatDateTime(value)));
    }
예제 #20
0
    protected static void LogBind(SQLiteStatementHandle handle, int index, ValueType value)
    {
        //IntPtr handleIntPtr = handle;

        //SQLiteLog.LogMessage(0, String.Format(
        //    "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
        //    handleIntPtr, index, value.GetType(), value));
    }
예제 #21
0
    protected static void LogBind(SQLiteStatementHandle handle, int index)
    {
        //IntPtr handleIntPtr = handle;

        //SQLiteLog.LogMessage(0, String.Format(
        //    "Binding statement {0} paramter #{1} as NULL...",
        //    handleIntPtr, index));
    }
예제 #22
0
    internal override SQLiteStatement Prepare(SQLiteConnection cnn, string strSql, SQLiteStatement previous, uint timeoutMS, out string strRemain)
    {
      if (!String.IsNullOrEmpty(strSql))
      {
        //
        // NOTE: SQLite does not support the concept of separate schemas
        //       in one database; therefore, remove the base schema name
        //       used to smooth integration with the base .NET Framework
        //       data classes.
        //
        string baseSchemaName = (cnn != null) ? cnn._baseSchemaName : null;

        if (!String.IsNullOrEmpty(baseSchemaName))
        {
          strSql = strSql.Replace(
              String.Format(CultureInfo.InvariantCulture,
              "[{0}].", baseSchemaName), String.Empty);

          strSql = strSql.Replace(
              String.Format(CultureInfo.InvariantCulture,
              "{0}.", baseSchemaName), String.Empty);
        }
      }

      SQLiteConnectionFlags flags =
          (cnn != null) ? cnn.Flags : SQLiteConnectionFlags.Default;

#if !PLATFORM_COMPACTFRAMEWORK
      if ((flags & SQLiteConnectionFlags.LogPrepare) == SQLiteConnectionFlags.LogPrepare)
      {
          if ((strSql == null) || (strSql.Length == 0) || (strSql.Trim().Length == 0))
              SQLiteLog.LogMessage("Preparing {<nothing>}...");
          else
              SQLiteLog.LogMessage(String.Format(
                  CultureInfo.CurrentCulture, "Preparing {{{0}}}...", strSql));
      }
#endif

      IntPtr stmt = IntPtr.Zero;
      IntPtr ptr = IntPtr.Zero;
      int len = 0;
      SQLiteErrorCode n = SQLiteErrorCode.Schema;
      int retries = 0;
      byte[] b = ToUTF8(strSql);
      string typedefs = null;
      SQLiteStatement cmd = null;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;

      GCHandle handle = GCHandle.Alloc(b, GCHandleType.Pinned);
      IntPtr psql = handle.AddrOfPinnedObject();
      SQLiteStatementHandle statementHandle = null;
      try
      {
        while ((n == SQLiteErrorCode.Schema || n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) && retries < 3)
        {
          try
          {
            // do nothing.
          }
          finally /* NOTE: Thread.Abort() protection. */
          {
#if !SQLITE_STANDARD
            n = UnsafeNativeMethods.sqlite3_prepare_interop(_sql, psql, b.Length - 1, out stmt, out ptr, out len);
#else
            n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr);
            len = -1;
#endif

#if !NET_COMPACT_20 && TRACE_STATEMENT
            Trace.WriteLine(String.Format("Prepare ({0}): {1}", n, stmt));
#endif

            if ((n == SQLiteErrorCode.Ok) && (stmt != IntPtr.Zero))
              statementHandle = new SQLiteStatementHandle(_sql, stmt);
          }

          if (n == SQLiteErrorCode.Schema)
            retries++;
          else if (n == SQLiteErrorCode.Error)
          {
            if (String.Compare(GetLastError(), "near \"TYPES\": syntax error", StringComparison.OrdinalIgnoreCase) == 0)
            {
              int pos = strSql.IndexOf(';');
              if (pos == -1) pos = strSql.Length - 1;

              typedefs = strSql.Substring(0, pos + 1);
              strSql = strSql.Substring(pos + 1);

              strRemain = "";

              while (cmd == null && strSql.Length > 0)
              {
                cmd = Prepare(cnn, strSql, previous, timeoutMS, out strRemain);
                strSql = strRemain;
              }

              if (cmd != null)
                cmd.SetTypes(typedefs);

              return cmd;
            }
#if (NET_35 || NET_40 || NET_45) && !PLATFORM_COMPACTFRAMEWORK
            else if (_buildingSchema == false && String.Compare(GetLastError(), 0, "no such table: TEMP.SCHEMA", 0, 26, StringComparison.OrdinalIgnoreCase) == 0)
            {
              strRemain = "";
              _buildingSchema = true;
              try
              {
                ISQLiteSchemaExtensions ext = ((IServiceProvider)SQLiteFactory.Instance).GetService(typeof(ISQLiteSchemaExtensions)) as ISQLiteSchemaExtensions;

                if (ext != null)
                  ext.BuildTempSchema(cnn);

                while (cmd == null && strSql.Length > 0)
                {
                  cmd = Prepare(cnn, strSql, previous, timeoutMS, out strRemain);
                  strSql = strRemain;
                }

                return cmd;
              }
              finally
              {
                _buildingSchema = false;
              }
            }
#endif
          }
          else if (n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy) // Locked -- delay a small amount before retrying
          {
            // Keep trying
            if (rnd == null) // First time we've encountered the lock
              rnd = new Random();

            // If we've exceeded the command's timeout, give up and throw an error
            if ((uint)Environment.TickCount - starttick > timeoutMS)
            {
              throw new SQLiteException(n, GetLastError());
            }
            else
            {
              // Otherwise sleep for a random amount of time up to 150ms
              System.Threading.Thread.Sleep(rnd.Next(1, 150));
            }
          }
        }

        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());

        strRemain = UTF8ToString(ptr, len);

        if (statementHandle != null) cmd = new SQLiteStatement(this, flags, statementHandle, strSql.Substring(0, strSql.Length - strRemain.Length), previous);

        return cmd;
      }
      finally
      {
        handle.Free();
      }
    }
예제 #23
0
    protected static void LogBind(SQLiteStatementHandle handle, int index, string value)
    {
        IntPtr handleIntPtr = handle;

        SQLiteLog.LogMessage(String.Format(
            "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
            handleIntPtr, index, typeof(String), (value != null) ? value : "<null>"));
    }