Пример #1
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 = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
            nCmdStart++;
            _unnamedParameters++;
          }
          _paramNames[x] = s;
          _paramValues[x] = null;
        }
      }
    }
Пример #2
0
        /// <summary>
        /// Builds an array of prepared statements for each complete SQL statement in the command text
        /// </summary>
        internal SQLiteStatement BuildNextCommand()
        {
            SQLiteStatement stmt = null;

            try
            {
                if ((_cnn != null) && (_cnn._sql != null))
                {
                    if (_statementList == null)
                    {
                        _remainingText = _commandText;
                    }

                    stmt = _cnn._sql.Prepare(_cnn, _remainingText, (_statementList == null) ? null : _statementList[_statementList.Count - 1], (uint)(_commandTimeout * 1000), out _remainingText);

                    if (stmt != null)
                    {
                        stmt._command = this;

                        if (_statementList == null)
                        {
                            _statementList = new List <SQLiteStatement>();
                        }

                        _statementList.Add(stmt);

                        _parameterCollection.MapParameters(stmt);
                        stmt.BindParameters();
                    }
                }
                return(stmt);
            }
            catch (Exception)
            {
                if (stmt != null)
                {
                    if ((_statementList != null) && _statementList.Contains(stmt))
                    {
                        _statementList.Remove(stmt);
                    }

                    stmt.Dispose();
                }

                // If we threw an error compiling the statement, we cannot continue on so set the remaining text to null.
                _remainingText = null;

                throw;
            }
        }
Пример #3
0
        internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
        {
            if (_datetimeFormat == SQLiteDateFormats.Ticks)
            {
                return(ToDateTime(GetInt64(stmt, index), _datetimeKind));
            }
            else if (_datetimeFormat == SQLiteDateFormats.JulianDay)
            {
                return(ToDateTime(GetDouble(stmt, index), _datetimeKind));
            }
            else if (_datetimeFormat == SQLiteDateFormats.UnixEpoch)
            {
                return(ToDateTime(GetInt32(stmt, index), _datetimeKind));
            }

            return(ToDateTime(GetText(stmt, index)));
        }
Пример #4
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());
            }
        }
Пример #5
0
        internal override string ColumnName(SQLiteStatement stmt, int index)
        {
#if !SQLITE_STANDARD
            int    len;
            IntPtr p = UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len);
#else
            IntPtr p = UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index);
#endif
            if (p == IntPtr.Zero)
            {
                throw new SQLiteException(SQLiteErrorCode.NoMem, GetLastError());
            }
#if !SQLITE_STANDARD
            return(UTF16ToString(p, len));
#else
            return(UTF16ToString(p, -1));
#endif
        }
Пример #6
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        private void DisposeStatements()
        {
            if (_statementList == null)
            {
                return;
            }

            int x = _statementList.Count;

            for (int n = 0; n < x; n++)
            {
                SQLiteStatement stmt = _statementList[n];
                if (stmt == null)
                {
                    continue;
                }
                stmt.Dispose();
            }

            _statementList = null;
        }
Пример #7
0
    internal override string ColumnTableName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_table_name16(stmt._sqlite_stmt, index), -1);
#endif
    }
Пример #8
0
    internal override string ColumnName(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      IntPtr p = UnsafeNativeMethods.sqlite3_column_name16_interop(stmt._sqlite_stmt, index, out len);
#else
      IntPtr p = UnsafeNativeMethods.sqlite3_column_name16(stmt._sqlite_stmt, index);
#endif
      if (p == IntPtr.Zero)
        throw new SQLiteException(SQLiteErrorCode.NoMem, GetLastError());
#if !SQLITE_STANDARD
      return UTF16ToString(p, len);
#else
      return UTF16ToString(p, -1);
#endif
    }
Пример #9
0
 internal override TypeAffinity ColumnAffinity(SQLiteStatement stmt, int index)
 {
   return UnsafeNativeMethods.sqlite3_column_type(stmt._sqlite_stmt, index);
 }
Пример #10
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 ((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));
      }

      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
#if USE_PREPARE_V2
            n = UnsafeNativeMethods.sqlite3_prepare_v2(_sql, psql, b.Length - 1, out stmt, out ptr);
#else
            n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, out stmt, out ptr);
#endif
            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))
            {
              if (statementHandle != null) statementHandle.Dispose();
              statementHandle = new SQLiteStatementHandle(_sql, stmt);
            }
          }

          if (statementHandle != null)
          {
            SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
              SQLiteConnectionEventType.NewCriticalHandle, null, null,
              null, null, statementHandle, strSql, new object[] { cnn,
              strSql, previous, timeoutMS }));
          }

          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 || NET_451) && !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)DenverDBFactory.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();
      }
    }
Пример #11
0
    internal override bool Step(SQLiteStatement stmt)
    {
      SQLiteErrorCode n;
      Random rnd = null;
      uint starttick = (uint)Environment.TickCount;
      uint timeout = (uint)(stmt._command._commandTimeout * 1000);

      while (true)
      {
        n = UnsafeNativeMethods.sqlite3_step(stmt._sqlite_stmt);

        if (n == SQLiteErrorCode.Row) return true;
        if (n == SQLiteErrorCode.Done) return false;

        if (n != SQLiteErrorCode.Ok)
        {
          SQLiteErrorCode r;

          // An error occurred, attempt to reset the statement.  If the reset worked because the
          // schema has changed, re-try the step again.  If it errored our because the database
          // is locked, then keep retrying until the command timeout occurs.
          r = Reset(stmt);

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

          else if ((r == SQLiteErrorCode.Locked || r == SQLiteErrorCode.Busy) && stmt._command != null)
          {
            // 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 > timeout)
            {
              throw new SQLiteException(r, GetLastError());
            }
            else
            {
              // Otherwise sleep for a random amount of time up to 150ms
              System.Threading.Thread.Sleep(rnd.Next(1, 150));
            }
          }
        }
      }
    }
Пример #12
0
 internal override uint GetUInt32(SQLiteStatement stmt, int index)
 {
   return unchecked((uint)GetInt32(stmt, index));
 }
Пример #13
0
 internal override int GetInt32(SQLiteStatement stmt, int index)
 {
   return UnsafeNativeMethods.sqlite3_column_int(stmt._sqlite_stmt, index);
 }
Пример #14
0
 internal override ushort GetUInt16(SQLiteStatement stmt, int index)
 {
   return unchecked((ushort)(GetInt32(stmt, index) & ushort.MaxValue));
 }
Пример #15
0
 internal override byte GetByte(SQLiteStatement stmt, int index)
 {
   return unchecked((byte)(GetInt32(stmt, index) & byte.MaxValue));
 }
Пример #16
0
    internal override int ColumnIndex(SQLiteStatement stmt, string columnName)
    {
      int x = ColumnCount(stmt);

      for (int n = 0; n < x; n++)
      {
        if (String.Compare(columnName, ColumnName(stmt, n), StringComparison.OrdinalIgnoreCase) == 0)
          return n;
      }
      return -1;
    }
Пример #17
0
    internal override string ColumnType(SQLiteStatement stmt, int index, out TypeAffinity nAffinity)
    {
      int len;
#if !SQLITE_STANDARD
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype_interop(stmt._sqlite_stmt, index, out len);
#else
      len = -1;
      IntPtr p = UnsafeNativeMethods.sqlite3_column_decltype(stmt._sqlite_stmt, index);
#endif
      nAffinity = ColumnAffinity(stmt, index);

      if (p != IntPtr.Zero) return UTF8ToString(p, len);
      else
      {
        string[] ar = stmt.TypeDefinitions;
        if (ar != null)
        {
          if (index < ar.Length && ar[index] != null)
            return ar[index];
        }
        return String.Empty;

        //switch (nAffinity)
        //{
        //  case TypeAffinity.Int64:
        //    return "BIGINT";
        //  case TypeAffinity.Double:
        //    return "DOUBLE";
        //  case TypeAffinity.Blob:
        //    return "BLOB";
        //  default:
        //    return "TEXT";
        //}
      }
    }
Пример #18
0
        /// <summary>
        /// This function does all the nasty work at determining what keys need to be returned for
        /// a given statement.
        /// </summary>
        /// <param name="cnn"></param>
        /// <param name="reader"></param>
        /// <param name="stmt"></param>
        internal SQLiteKeyReader(SQLiteConnection cnn, SQLiteDataReader reader, SQLiteStatement stmt)
        {
            Dictionary <string, int>            catalogs = new Dictionary <string, int>();
            Dictionary <string, List <string> > tables   = new Dictionary <string, List <string> >();
            List <string>  list;
            List <KeyInfo> keys = new List <KeyInfo>();

            // Record the statement so we can use it later for sync'ing
            _stmt = stmt;

            // Fetch all the attached databases on this connection
            using (DataTable tbl = cnn.GetSchema("Catalogs"))
            {
                foreach (DataRow row in tbl.Rows)
                {
                    catalogs.Add((string)row["CATALOG_NAME"], Convert.ToInt32(row["ID"], CultureInfo.InvariantCulture));
                }
            }

            // Fetch all the unique tables and catalogs used by the current statement
            using (DataTable schema = reader.GetSchemaTable(false, false))
            {
                foreach (DataRow row in schema.Rows)
                {
                    // Check if column is backed to a table
                    if (row[SchemaTableOptionalColumn.BaseCatalogName] == DBNull.Value)
                    {
                        continue;
                    }

                    // Record the unique table so we can look up its keys
                    string catalog = (string)row[SchemaTableOptionalColumn.BaseCatalogName];
                    string table   = (string)row[SchemaTableColumn.BaseTableName];

                    if (tables.ContainsKey(catalog) == false)
                    {
                        list = new List <string>();
                        tables.Add(catalog, list);
                    }
                    else
                    {
                        list = tables[catalog];
                    }

                    if (list.Contains(table) == false)
                    {
                        list.Add(table);
                    }
                }

                // For each catalog and each table, query the indexes for the table.
                // Find a primary key index if there is one.  If not, find a unique index instead
                foreach (KeyValuePair <string, List <string> > pair in tables)
                {
                    for (int i = 0; i < pair.Value.Count; i++)
                    {
                        string  table        = pair.Value[i];
                        DataRow preferredRow = null;
                        using (DataTable tbl = cnn.GetSchema("Indexes", new string[] { pair.Key, null, table }))
                        {
                            // Loop twice.  The first time looking for a primary key index,
                            // the second time looking for a unique index
                            for (int n = 0; n < 2 && preferredRow == null; n++)
                            {
                                foreach (DataRow row in tbl.Rows)
                                {
                                    if (n == 0 && (bool)row["PRIMARY_KEY"] == true)
                                    {
                                        preferredRow = row;
                                        break;
                                    }
                                    else if (n == 1 && (bool)row["UNIQUE"] == true)
                                    {
                                        preferredRow = row;
                                        break;
                                    }
                                }
                            }
                            if (preferredRow == null) // Unable to find any suitable index for this table so remove it
                            {
                                pair.Value.RemoveAt(i);
                                i--;
                            }
                            else // We found a usable index, so fetch the necessary table details
                            {
                                using (DataTable tblTables = cnn.GetSchema("Tables", new string[] { pair.Key, null, table }))
                                {
                                    // Find the root page of the table in the current statement and get the cursor that's iterating it
                                    int database = catalogs[pair.Key];
                                    int rootPage = Convert.ToInt32(tblTables.Rows[0]["TABLE_ROOTPAGE"], CultureInfo.InvariantCulture);
                                    int cursor   = stmt._sql.GetCursorForTable(stmt, database, rootPage);

                                    // Now enumerate the members of the index we're going to use
                                    using (DataTable indexColumns = cnn.GetSchema("IndexColumns", new string[] { pair.Key, null, table, (string)preferredRow["INDEX_NAME"] }))
                                    {
                                        KeyQuery query = null;

                                        List <string> cols = new List <string>();
                                        for (int x = 0; x < indexColumns.Rows.Count; x++)
                                        {
                                            bool addKey = true;
                                            // If the column in the index already appears in the query, skip it
                                            foreach (DataRow row in schema.Rows)
                                            {
                                                if (row.IsNull(SchemaTableColumn.BaseColumnName))
                                                {
                                                    continue;
                                                }

                                                if ((string)row[SchemaTableColumn.BaseColumnName] == (string)indexColumns.Rows[x]["COLUMN_NAME"] &&
                                                    (string)row[SchemaTableColumn.BaseTableName] == table &&
                                                    (string)row[SchemaTableOptionalColumn.BaseCatalogName] == pair.Key)
                                                {
                                                    indexColumns.Rows.RemoveAt(x);
                                                    x--;
                                                    addKey = false;
                                                    break;
                                                }
                                            }
                                            if (addKey == true)
                                            {
                                                cols.Add((string)indexColumns.Rows[x]["COLUMN_NAME"]);
                                            }
                                        }

                                        // If the index is not a rowid alias, record all the columns
                                        // needed to make up the unique index and construct a SQL query for it
                                        if ((string)preferredRow["INDEX_NAME"] != "sqlite_master_PK_" + table)
                                        {
                                            // Whatever remains of the columns we need that make up the index that are not
                                            // already in the query need to be queried separately, so construct a subquery
                                            if (cols.Count > 0)
                                            {
                                                string[] querycols = new string[cols.Count];
                                                cols.CopyTo(querycols);
                                                query = new KeyQuery(cnn, pair.Key, table, querycols);
                                            }
                                        }

                                        // Create a KeyInfo struct for each column of the index
                                        for (int x = 0; x < indexColumns.Rows.Count; x++)
                                        {
                                            string  columnName = (string)indexColumns.Rows[x]["COLUMN_NAME"];
                                            KeyInfo key        = new KeyInfo();

                                            key.rootPage     = rootPage;
                                            key.cursor       = cursor;
                                            key.database     = database;
                                            key.databaseName = pair.Key;
                                            key.tableName    = table;
                                            key.columnName   = columnName;
                                            key.query        = query;
                                            key.column       = x;

                                            keys.Add(key);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Now we have all the additional columns we have to return in order to support
            // CommandBehavior.KeyInfo
            _keyInfo = new KeyInfo[keys.Count];
            keys.CopyTo(_keyInfo);
        }
Пример #19
0
    internal override string Bind_ParamName(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index)
    {
        SQLiteStatementHandle handle = stmt._sqlite_stmt;
        string name;

#if !SQLITE_STANDARD
        int len;
        name = UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name_interop(handle, index, out len), len);
#else
        name = UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(handle, index), -1);
#endif

        if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
        {
            IntPtr handleIntPtr = handle;

            SQLiteLog.LogMessage(String.Format(
                CultureInfo.CurrentCulture,
                "Statement {0} paramter #{1} name is {{{2}}}.",
                handleIntPtr, index, name));
        }

        return name;
    }
Пример #20
0
    internal override long GetInt64(SQLiteStatement stmt, int index)
    {
      long value;
#if !PLATFORM_COMPACTFRAMEWORK
      value = UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index);
#elif !SQLITE_STANDARD
      UnsafeNativeMethods.sqlite3_column_int64_interop(stmt._sqlite_stmt, index, out value);
#else
      throw new NotImplementedException();
#endif
      return value;
    }
Пример #21
0
    internal override SQLiteErrorCode Reset(SQLiteStatement stmt)
    {
      SQLiteErrorCode n;

#if !SQLITE_STANDARD
      n = UnsafeNativeMethods.sqlite3_reset_interop(stmt._sqlite_stmt);
#else
      n = UnsafeNativeMethods.sqlite3_reset(stmt._sqlite_stmt);
#endif

      // If the schema changed, try and re-prepare it
      if (n == SQLiteErrorCode.Schema)
      {
        // Recreate a dummy statement
        string str;
        using (SQLiteStatement tmp = Prepare(null, stmt._sqlStatement, null, (uint)(stmt._command._commandTimeout * 1000), out str))
        {
          // Finalize the existing statement
          stmt._sqlite_stmt.Dispose();
          // Reassign a new statement pointer to the old statement and clear the temporary one
          stmt._sqlite_stmt = tmp._sqlite_stmt;
          tmp._sqlite_stmt = null;

          // Reapply parameters
          stmt.BindParameters();
        }
        return SQLiteErrorCode.Unknown; // Reset was OK, with schema change
      }
      else if (n == SQLiteErrorCode.Locked || n == SQLiteErrorCode.Busy)
        return n;

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

      return n; // We reset OK, no schema changes
    }
Пример #22
0
 internal override ulong GetUInt64(SQLiteStatement stmt, int index)
 {
   return unchecked((ulong)GetInt64(stmt, index));
 }
Пример #23
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 = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
                        nCmdStart++;
                        _unnamedParameters++;
                    }
                    _paramNames[x]  = s;
                    _paramValues[x] = null;
                }
            }
        }
Пример #24
0
    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
      if (_datetimeFormat == SQLiteDateFormats.Ticks)
        return ToDateTime(GetInt64(stmt, index), _datetimeKind);
      else if (_datetimeFormat == SQLiteDateFormats.JulianDay)
        return ToDateTime(GetDouble(stmt, index), _datetimeKind);
      else if (_datetimeFormat == SQLiteDateFormats.UnixEpoch)
        return ToDateTime(GetInt32(stmt, index), _datetimeKind);

#if !SQLITE_STANDARD
      int len;
      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return ToDateTime(UnsafeNativeMethods.sqlite3_column_text(stmt._sqlite_stmt, index),
        UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index));
#endif
    }
Пример #25
0
    internal override int Bind_ParamIndex(SQLiteStatement stmt, SQLiteConnectionFlags flags, string paramName)
    {
        SQLiteStatementHandle handle = stmt._sqlite_stmt;
        int index = UnsafeNativeMethods.sqlite3_bind_parameter_index(handle, ToUTF8(paramName));

        if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
        {
            IntPtr handleIntPtr = handle;

            SQLiteLog.LogMessage(String.Format(
                CultureInfo.CurrentCulture,
                "Statement {0} paramter index of name {{{1}}} is #{2}.",
                handleIntPtr, paramName, index));
        }

        return index;
    }
Пример #26
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());
    }
Пример #27
0
    internal override long GetBytes(SQLiteStatement stmt, int index, int nDataOffset, byte[] bDest, int nStart, int nLength)
    {
      int nlen = UnsafeNativeMethods.sqlite3_column_bytes(stmt._sqlite_stmt, index);

      // If no destination buffer, return the size needed.
      if (bDest == null) return nlen;

      int nCopied = nLength;

      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;

      if (nCopied > 0)
      {
        IntPtr ptr = UnsafeNativeMethods.sqlite3_column_blob(stmt._sqlite_stmt, index);

        Marshal.Copy((IntPtr)(ptr.ToInt64() + nDataOffset), bDest, nStart, nCopied);
      }
      else
      {
        nCopied = 0;
      }

      return nCopied;
    }
Пример #28
0
 internal override int ColumnCount(SQLiteStatement stmt)
 {
   return UnsafeNativeMethods.sqlite3_column_count(stmt._sqlite_stmt);
 }
Пример #29
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;
                }
        }
    }
Пример #30
0
    internal override long GetChars(SQLiteStatement stmt, int index, int nDataOffset, char[] bDest, int nStart, int nLength)
    {
      int nlen;
      int nCopied = nLength;

      string str = GetText(stmt, index);
      nlen = str.Length;

      if (bDest == null) return nlen;

      if (nCopied + nStart > bDest.Length) nCopied = bDest.Length - nStart;
      if (nCopied + nDataOffset > nlen) nCopied = nlen - nDataOffset;

      if (nCopied > 0)
        str.CopyTo(nDataOffset, bDest, nStart, nCopied);
      else nCopied = 0;

      return nCopied;
    }
Пример #31
0
    internal override DateTime GetDateTime(SQLiteStatement stmt, int index)
    {
      if (_datetimeFormat == SQLiteDateFormats.Ticks)
        return ToDateTime(GetInt64(stmt, index), _datetimeKind);
      else if (_datetimeFormat == SQLiteDateFormats.JulianDay)
        return ToDateTime(GetDouble(stmt, index), _datetimeKind);
      else if (_datetimeFormat == SQLiteDateFormats.UnixEpoch)
        return ToDateTime(GetInt32(stmt, index), _datetimeKind);

      return ToDateTime(GetText(stmt, index));
    }
Пример #32
0
 internal override bool IsNull(SQLiteStatement stmt, int index)
 {
   return (ColumnAffinity(stmt, index) == TypeAffinity.Null);
 }
Пример #33
0
    internal override string GetText(SQLiteStatement stmt, int index)
    {
#if !SQLITE_STANDARD
      int len;
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16_interop(stmt._sqlite_stmt, index, out len), len);
#else
      return UTF16ToString(UnsafeNativeMethods.sqlite3_column_text16(stmt._sqlite_stmt, index),
        UnsafeNativeMethods.sqlite3_column_bytes16(stmt._sqlite_stmt, index));
#endif
    }
Пример #34
0
    /// <summary>
    /// Helper function to retrieve a column of data from an active statement.
    /// </summary>
    /// <param name="stmt">The statement being step()'d through</param>
    /// <param name="flags">The flags associated with the connection.</param>
    /// <param name="index">The column index to retrieve</param>
    /// <param name="typ">The type of data contained in the column.  If Uninitialized, this function will retrieve the datatype information.</param>
    /// <returns>Returns the data in the column</returns>
    internal override object GetValue(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, SQLiteType typ)
    {
      TypeAffinity aff = typ.Affinity;
      if (aff == TypeAffinity.Null) return DBNull.Value;
      Type t = null;

      if (typ.Type != DbType.Object)
      {
        t = SQLiteConvert.SQLiteTypeToType(typ);
        aff = TypeToAffinity(t);
      }

      if ((flags & SQLiteConnectionFlags.GetAllAsText) == SQLiteConnectionFlags.GetAllAsText)
          return GetText(stmt, index);

      switch (aff)
      {
        case TypeAffinity.Blob:
          if (typ.Type == DbType.Guid && typ.Affinity == TypeAffinity.Text)
            return new Guid(GetText(stmt, index));

          int n = (int)GetBytes(stmt, index, 0, null, 0, 0);
          byte[] b = new byte[n];
          GetBytes(stmt, index, 0, b, 0, n);

          if (typ.Type == DbType.Guid && n == 16)
            return new Guid(b);

          return b;
        case TypeAffinity.DateTime:
          return GetDateTime(stmt, index);
        case TypeAffinity.Double:
          if (t == null) return GetDouble(stmt, index);
          return Convert.ChangeType(GetDouble(stmt, index), t, null);
        case TypeAffinity.Int64:
          if (t == null) return GetInt64(stmt, index);
          if (t == typeof(SByte)) return GetSByte(stmt, index);
          if (t == typeof(Byte)) return GetByte(stmt, index);
          if (t == typeof(Int16)) return GetInt16(stmt, index);
          if (t == typeof(UInt16)) return GetUInt16(stmt, index);
          if (t == typeof(Int32)) return GetInt32(stmt, index);
          if (t == typeof(UInt32)) return GetUInt32(stmt, index);
          if (t == typeof(UInt64)) return GetUInt64(stmt, index);
          return Convert.ChangeType(GetInt64(stmt, index), t, null);
        default:
          return GetText(stmt, index);
      }
    }
Пример #35
0
    internal override int GetCursorForTable(SQLiteStatement stmt, int db, int rootPage)
    {
#if !SQLITE_STANDARD
      return UnsafeNativeMethods.sqlite3_table_cursor_interop(stmt._sqlite_stmt, db, rootPage);
#else
      return -1;
#endif
    }
Пример #36
0
    internal override long GetRowIdForCursor(SQLiteStatement stmt, int cursor)
    {
#if !SQLITE_STANDARD
      long rowid;
      SQLiteErrorCode rc = UnsafeNativeMethods.sqlite3_cursor_rowid_interop(stmt._sqlite_stmt, cursor, out rowid);
      if (rc == SQLiteErrorCode.Ok) return rowid;

      return 0;
#else
      return 0;
#endif
    }
Пример #37
0
        /// <summary>
        /// This function attempts to map all parameters in the collection to all statements in a Command.
        /// Since named parameters may span multiple statements, this function makes sure all statements are bound
        /// to the same named parameter.  Unnamed parameters are bound in sequence.
        /// </summary>
        internal void MapParameters(SQLiteStatement activeStatement)
        {
            if (_unboundFlag == false || _parameterList.Count == 0 || _command._statementList == null)
            {
                return;
            }

            int             nUnnamed = 0;
            string          s;
            int             n;
            int             y = -1;
            SQLiteStatement stmt;

            foreach (SQLiteParameter p in _parameterList)
            {
                y++;
                s = p.ParameterName;
                if (s == null)
                {
                    s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
                    nUnnamed++;
                }

                int  x;
                bool isMapped = false;

                if (activeStatement == null)
                {
                    x = _command._statementList.Count;
                }
                else
                {
                    x = 1;
                }

                stmt = activeStatement;
                for (n = 0; n < x; n++)
                {
                    isMapped = false;
                    if (stmt == null)
                    {
                        stmt = _command._statementList[n];
                    }
                    if (stmt._paramNames != null)
                    {
                        if (stmt.MapParameter(s, p) == true)
                        {
                            isMapped = true;
                        }
                    }
                    stmt = null;
                }

                // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map
                // the parameter by its index in the collection
                if (isMapped == false)
                {
                    s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);

                    stmt = activeStatement;
                    for (n = 0; n < x; n++)
                    {
                        if (stmt == null)
                        {
                            stmt = _command._statementList[n];
                        }
                        if (stmt._paramNames != null)
                        {
                            if (stmt.MapParameter(s, p) == true)
                            {
                                isMapped = true;
                            }
                        }
                        stmt = null;
                    }
                }
            }
            if (activeStatement == null)
            {
                _unboundFlag = false;
            }
        }
Пример #38
0
    internal override int Bind_ParamCount(SQLiteStatement stmt, SQLiteConnectionFlags flags)
    {
        SQLiteStatementHandle handle = stmt._sqlite_stmt;
        int value = UnsafeNativeMethods.sqlite3_bind_parameter_count(handle);

        if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
        {
            IntPtr handleIntPtr = handle;

            SQLiteLog.LogMessage(String.Format(
                CultureInfo.CurrentCulture,
                "Statement {0} paramter count is {1}.",
                handleIntPtr, value));
        }

        return value;
    }