SQLite.SQLiteConnection源代码

sqlite3数据库的使用 sqlit3 阅读详情

摘自编译后的.cs文件,版权归原作者所有:

// Decompiled with JetBrains decompiler
// Type: SQLite.SQLiteConnection
// Assembly: SQLite-net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6176266-E10E-4143-A13A-15E20E5B743C
// Assembly location: ...\packages\sqlite-net-pcl.1.4.118\lib\netstandard1.1\SQLite-net.dll

using SQLitePCL;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;

namespace SQLite
{
  /// <summary>Represents an open connection to a SQLite database.</summary>
  public class SQLiteConnection : IDisposable
  {
    private Random _rand = new Random();
    private bool _open;
    private TimeSpan _busyTimeout;
    private Dictionary<string, TableMapping> _mappings;
    private Dictionary<string, TableMapping> _tables;
    private Stopwatch _sw;
    private long _elapsedMilliseconds;
    private int _transactionDepth;
    internal static readonly sqlite3 NullHandle;

    public sqlite3 Handle { get; private set; }

    public string DatabasePath { get; private set; }

    public bool TimeExecution { get; set; }

    public bool Trace { get; set; }

    public Action<string> Tracer { get; set; }

    public bool StoreDateTimeAsTicks { get; private set; }

    static SQLiteConnection()
    {
      Batteries_V2.Init();
    }

    /// <summary>
    /// Constructs a new SQLiteConnection and opens a SQLite database specified by databasePath.
    /// </summary>
    /// <param name="databasePath">
    /// Specifies the path to the database file.
    /// </param>
    /// <param name="storeDateTimeAsTicks">
    /// Specifies whether to store DateTime properties as ticks (true) or strings (false). You
    /// absolutely do want to store them as Ticks in all new projects. The value of false is
    /// only here for backwards compatibility. There is a *significant* speed advantage, with no
    /// down sides, when setting storeDateTimeAsTicks = true.
    /// If you use DateTimeOffset properties, it will be always stored as ticks regardingless
    /// the storeDateTimeAsTicks parameter.
    /// </param>
    public SQLiteConnection(string databasePath, bool storeDateTimeAsTicks = true)
      : this(databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks)
    {
    }

    /// <summary>
    /// Constructs a new SQLiteConnection and opens a SQLite database specified by databasePath.
    /// </summary>
    /// <param name="databasePath">
    /// Specifies the path to the database file.
    /// </param>
    /// <param name="openFlags">
    /// Flags controlling how the connection should be opened.
    /// </param>
    /// <param name="storeDateTimeAsTicks">
    /// Specifies whether to store DateTime properties as ticks (true) or strings (false). You
    /// absolutely do want to store them as Ticks in all new projects. The value of false is
    /// only here for backwards compatibility. There is a *significant* speed advantage, with no
    /// down sides, when setting storeDateTimeAsTicks = true.
    /// If you use DateTimeOffset properties, it will be always stored as ticks regardingless
    /// the storeDateTimeAsTicks parameter.
    /// </param>
    public SQLiteConnection(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = true)
    {
      if (string.IsNullOrEmpty(databasePath))
        throw new ArgumentException("Must be specified", nameof (databasePath));
      this.DatabasePath = databasePath;
      sqlite3 db;
      SQLite3.Result r = SQLite3.Open(databasePath, out db, (int) openFlags, IntPtr.Zero);
      this.Handle = db;
      if (r != SQLite3.Result.OK)
        throw SQLiteException.New(r, string.Format("Could not open database file: {0} ({1})", new object[2]
        {
          (object) this.DatabasePath,
          (object) r
        }));
      this._open = true;
      this.StoreDateTimeAsTicks = storeDateTimeAsTicks;
      this.BusyTimeout = TimeSpan.FromSeconds(0.1);
      this.Tracer = (Action<string>) (line => {});
    }

    /// <summary>
    /// Sets a busy handler to sleep the specified amount of time when a table is locked.
    /// The handler will sleep multiple times until a total time of <see cref="P:SQLite.SQLiteConnection.BusyTimeout" /> has accumulated.
    /// </summary>
    public TimeSpan BusyTimeout
    {
      get
      {
        return this._busyTimeout;
      }
      set
      {
        this._busyTimeout = value;
        if (this.Handle == SQLiteConnection.NullHandle)
          return;
        int num = (int) SQLite3.BusyTimeout(this.Handle, (int) this._busyTimeout.TotalMilliseconds);
      }
    }

    /// <summary>
    /// Returns the mappings from types to tables that the connection
    /// currently understands.
    /// </summary>
    public IEnumerable<TableMapping> TableMappings
    {
      get
      {
        if (this._tables == null)
          return Enumerable.Empty<TableMapping>();
        return (IEnumerable<TableMapping>) this._tables.Values;
      }
    }

    /// <summary>
    /// Retrieves the mapping that is automatically generated for the given type.
    /// </summary>
    /// <param name="type">
    /// The type whose mapping to the database is returned.
    /// </param>
    /// <param name="createFlags">
    /// Optional flags allowing implicit PK and indexes based on naming conventions
    /// </param>
    /// <returns>
    /// The mapping represents the schema of the columns of the database and contains
    /// methods to set and get properties of objects.
    /// </returns>
    public TableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None)
    {
      if (this._mappings == null)
        this._mappings = new Dictionary<string, TableMapping>();
      TableMapping tableMapping;
      if (!this._mappings.TryGetValue(type.FullName, out tableMapping))
      {
        tableMapping = new TableMapping(type, createFlags);
        this._mappings[type.FullName] = tableMapping;
      }
      return tableMapping;
    }

    /// <summary>
    /// Retrieves the mapping that is automatically generated for the given type.
    /// </summary>
    /// <param name="createFlags">
    /// Optional flags allowing implicit PK and indexes based on naming conventions
    /// </param>
    /// <returns>
    /// The mapping represents the schema of the columns of the database and contains
    /// methods to set and get properties of objects.
    /// </returns>
    public TableMapping GetMapping<T>(CreateFlags createFlags = CreateFlags.None)
    {
      return this.GetMapping(typeof (T), createFlags);
    }

    /// <summary>
    /// Executes a "drop table" on the database.  This is non-recoverable.
    /// </summary>
    public int DropTable<T>()
    {
      return this.DropTable(this.GetMapping(typeof (T), CreateFlags.None));
    }

    /// <summary>
    /// Executes a "drop table" on the database.  This is non-recoverable.
    /// </summary>
    /// <param name="map">The TableMapping used to identify the table.</param>
    public int DropTable(TableMapping map)
    {
      return this.Execute(string.Format("drop table if exists \"{0}\"", new object[1]
      {
        (object) map.TableName
      }));
    }

    /// <summary>
    /// Executes a "create table if not exists" on the database. It also
    /// creates any specified indexes on the columns of the table. It uses
    /// a schema automatically generated from the specified type. You can
    /// later access this schema by calling GetMapping.
    /// </summary>
    /// <returns>The number of entries added to the database schema.</returns>
    public int CreateTable<T>(CreateFlags createFlags = CreateFlags.None)
    {
      return this.CreateTable(typeof (T), createFlags);
    }

    /// <summary>
    /// Executes a "create table if not exists" on the database. It also
    /// creates any specified indexes on the columns of the table. It uses
    /// a schema automatically generated from the specified type. You can
    /// later access this schema by calling GetMapping.
    /// </summary>
    /// <param name="ty">Type to reflect to a database table.</param>
    /// <param name="createFlags">Optional flags allowing implicit PK and indexes based on naming conventions.</param>
    /// <returns>The number of entries added to the database schema.</returns>
    public int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None)
    {
      if (this._tables == null)
        this._tables = new Dictionary<string, TableMapping>();
      TableMapping mapping;
      if (!this._tables.TryGetValue(ty.FullName, out mapping))
      {
        mapping = this.GetMapping(ty, createFlags);
        this._tables.Add(ty.FullName, mapping);
      }
      if (mapping.Columns.Length == 0)
        throw new Exception(string.Format("Cannot create a table with zero columns (does '{0}' have public properties?)", new object[1]
        {
          (object) ty.FullName
        }));
      bool flag1 = (uint) (createFlags & CreateFlags.FullTextSearch3) > 0U;
      bool flag2 = (uint) (createFlags & CreateFlags.FullTextSearch4) > 0U;
      string str1 = flag1 | flag2 ? "virtual " : string.Empty;
      string str2 = flag1 ? "using fts3 " : (flag2 ? "using fts4 " : string.Empty);
      int num = this.Execute("create " + str1 + "table if not exists \"" + mapping.TableName + "\" " + str2 + "(\n" + string.Join(",\n", ((IEnumerable<TableMapping.Column>) mapping.Columns).Select<TableMapping.Column, string>((Func<TableMapping.Column, string>) (p => Orm.SqlDecl(p, this.StoreDateTimeAsTicks))).ToArray<string>()) + ")");
      if (num == 0)
        this.MigrateTable(mapping);
      Dictionary<string, SQLiteConnection.IndexInfo> dictionary = new Dictionary<string, SQLiteConnection.IndexInfo>();
      foreach (TableMapping.Column column in mapping.Columns)
      {
        foreach (IndexedAttribute index in column.Indices)
        {
          string key = index.Name ?? mapping.TableName + "_" + column.Name;
          SQLiteConnection.IndexInfo indexInfo;
          if (!dictionary.TryGetValue(key, out indexInfo))
          {
            indexInfo = new SQLiteConnection.IndexInfo()
            {
              IndexName = key,
              TableName = mapping.TableName,
              Unique = index.Unique,
              Columns = new List<SQLiteConnection.IndexedColumn>()
            };
            dictionary.Add(key, indexInfo);
          }
          if (index.Unique != indexInfo.Unique)
            throw new Exception("All the columns in an index must have the same value for their Unique property");
          indexInfo.Columns.Add(new SQLiteConnection.IndexedColumn()
          {
            Order = index.Order,
            ColumnName = column.Name
          });
        }
      }
      foreach (string key in dictionary.Keys)
      {
        SQLiteConnection.IndexInfo indexInfo = dictionary[key];
        string[] array = indexInfo.Columns.OrderBy<SQLiteConnection.IndexedColumn, int>((Func<SQLiteConnection.IndexedColumn, int>) (i => i.Order)).Select<SQLiteConnection.IndexedColumn, string>((Func<SQLiteConnection.IndexedColumn, string>) (i => i.ColumnName)).ToArray<string>();
        num += this.CreateIndex(key, indexInfo.TableName, array, indexInfo.Unique);
      }
      return num;
    }

    /// <summary>Creates an index for the specified table and columns.</summary>
    /// <param name="indexName">Name of the index to create</param>
    /// <param name="tableName">Name of the database table</param>
    /// <param name="columnNames">An array of column names to index</param>
    /// <param name="unique">Whether the index should be unique</param>
    public int CreateIndex(string indexName, string tableName, string[] columnNames, bool unique = false)
    {
      return this.Execute(string.Format("create {2} index if not exists \"{3}\" on \"{0}\"(\"{1}\")", (object) tableName, (object) string.Join("\", \"", columnNames), unique ? (object) nameof (unique) : (object) "", (object) indexName));
    }

    /// <summary>Creates an index for the specified table and column.</summary>
    /// <param name="indexName">Name of the index to create</param>
    /// <param name="tableName">Name of the database table</param>
    /// <param name="columnName">Name of the column to index</param>
    /// <param name="unique">Whether the index should be unique</param>
    public int CreateIndex(string indexName, string tableName, string columnName, bool unique = false)
    {
      return this.CreateIndex(indexName, tableName, new string[1]
      {
        columnName
      }, (unique ? 1 : 0) != 0);
    }

    /// <summary>Creates an index for the specified table and column.</summary>
    /// <param name="tableName">Name of the database table</param>
    /// <param name="columnName">Name of the column to index</param>
    /// <param name="unique">Whether the index should be unique</param>
    public int CreateIndex(string tableName, string columnName, bool unique = false)
    {
      return this.CreateIndex(tableName + "_" + columnName, tableName, columnName, unique);
    }

    /// <summary>Creates an index for the specified table and columns.</summary>
    /// <param name="tableName">Name of the database table</param>
    /// <param name="columnNames">An array of column names to index</param>
    /// <param name="unique">Whether the index should be unique</param>
    public int CreateIndex(string tableName, string[] columnNames, bool unique = false)
    {
      return this.CreateIndex(tableName + "_" + string.Join("_", columnNames), tableName, columnNames, unique);
    }

    /// <summary>
    /// Creates an index for the specified object property.
    /// e.g. CreateIndex<Client>(c => c.Name);
    /// </summary>
    /// <typeparam name="T">Type to reflect to a database table.</typeparam>
    /// <param name="property">Property to index</param>
    /// <param name="unique">Whether the index should be unique</param>
    public void CreateIndex<T>(Expression<Func<T, object>> property, bool unique = false)
    {
      PropertyInfo member = (property.Body.NodeType != ExpressionType.Convert ? property.Body as MemberExpression : ((UnaryExpression) property.Body).Operand as MemberExpression).Member as PropertyInfo;
      if ((object) member == null)
        throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
      string name1 = member.Name;
      TableMapping mapping = this.GetMapping<T>(CreateFlags.None);
      string name2 = mapping.FindColumnWithPropertyName(name1).Name;
      this.CreateIndex(mapping.TableName, name2, unique);
    }

    public List<SQLiteConnection.ColumnInfo> GetTableInfo(string tableName)
    {
      return this.Query<SQLiteConnection.ColumnInfo>("pragma table_info(\"" + tableName + "\")");
    }

    private void MigrateTable(TableMapping map)
    {
      List<SQLiteConnection.ColumnInfo> tableInfo = this.GetTableInfo(map.TableName);
      List<TableMapping.Column> columnList = new List<TableMapping.Column>();
      foreach (TableMapping.Column column in map.Columns)
      {
        bool flag = false;
        foreach (SQLiteConnection.ColumnInfo columnInfo in tableInfo)
        {
          flag = string.Compare(column.Name, columnInfo.Name, StringComparison.OrdinalIgnoreCase) == 0;
          if (flag)
            break;
        }
        if (!flag)
          columnList.Add(column);
      }
      foreach (TableMapping.Column p in columnList)
        this.Execute("alter table \"" + map.TableName + "\" add column " + Orm.SqlDecl(p, this.StoreDateTimeAsTicks));
    }

    /// <summary>
    /// Creates a new SQLiteCommand. Can be overridden to provide a sub-class.
    /// </summary>
    /// <seealso cref="M:SQLite.SQLiteCommand.OnInstanceCreated(System.Object)" />
    protected virtual SQLiteCommand NewCommand()
    {
      return new SQLiteCommand(this);
    }

    /// <summary>
    /// Creates a new SQLiteCommand given the command text with arguments. Place a '?'
    /// in the command text for each of the arguments.
    /// </summary>
    /// <param name="cmdText">The fully escaped SQL.</param>
    /// <param name="ps">
    /// Arguments to substitute for the occurences of '?' in the command text.
    /// </param>
    /// <returns>
    /// A <see cref="T:SQLite.SQLiteCommand" />
    /// </returns>
    public SQLiteCommand CreateCommand(string cmdText, params object[] ps)
    {
      if (!this._open)
        throw SQLiteException.New(SQLite3.Result.Error, "Cannot create commands from unopened database");
      SQLiteCommand sqLiteCommand = this.NewCommand();
      sqLiteCommand.CommandText = cmdText;
      foreach (object p in ps)
        sqLiteCommand.Bind(p);
      return sqLiteCommand;
    }

    /// <summary>
    /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
    /// in the command text for each of the arguments and then executes that command.
    /// Use this method instead of Query when you don't expect rows back. Such cases include
    /// INSERTs, UPDATEs, and DELETEs.
    /// You can set the Trace or TimeExecution properties of the connection
    /// to profile execution.
    /// </summary>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// The number of rows modified in the database as a result of this execution.
    /// </returns>
    public int Execute(string query, params object[] args)
    {
      SQLiteCommand command = this.CreateCommand(query, args);
      if (this.TimeExecution)
      {
        if (this._sw == null)
          this._sw = new Stopwatch();
        this._sw.Reset();
        this._sw.Start();
      }
      int num = command.ExecuteNonQuery();
      if (this.TimeExecution)
      {
        this._sw.Stop();
        this._elapsedMilliseconds += this._sw.ElapsedMilliseconds;
      }
      return num;
    }

    public T ExecuteScalar<T>(string query, params object[] args)
    {
      SQLiteCommand command = this.CreateCommand(query, args);
      if (this.TimeExecution)
      {
        if (this._sw == null)
          this._sw = new Stopwatch();
        this._sw.Reset();
        this._sw.Start();
      }
      T obj = command.ExecuteScalar<T>();
      if (this.TimeExecution)
      {
        this._sw.Stop();
        this._elapsedMilliseconds += this._sw.ElapsedMilliseconds;
      }
      return obj;
    }

    /// <summary>
    /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
    /// in the command text for each of the arguments and then executes that command.
    /// It returns each row of the result using the mapping automatically generated for
    /// the given type.
    /// </summary>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// An enumerable with one result for each row returned by the query.
    /// </returns>
    public List<T> Query<T>(string query, params object[] args) where T : new()
    {
      return this.CreateCommand(query, args).ExecuteQuery<T>();
    }

    /// <summary>
    /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
    /// in the command text for each of the arguments and then executes that command.
    /// It returns each row of the result using the mapping automatically generated for
    /// the given type.
    /// </summary>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// An enumerable with one result for each row returned by the query.
    /// The enumerator will call sqlite3_step on each call to MoveNext, so the database
    /// connection must remain open for the lifetime of the enumerator.
    /// </returns>
    public IEnumerable<T> DeferredQuery<T>(string query, params object[] args) where T : new()
    {
      return this.CreateCommand(query, args).ExecuteDeferredQuery<T>();
    }

    /// <summary>
    /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
    /// in the command text for each of the arguments and then executes that command.
    /// It returns each row of the result using the specified mapping. This function is
    /// only used by libraries in order to query the database via introspection. It is
    /// normally not used.
    /// </summary>
    /// <param name="map">
    /// A <see cref="T:SQLite.TableMapping" /> to use to convert the resulting rows
    /// into objects.
    /// </param>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// An enumerable with one result for each row returned by the query.
    /// </returns>
    public List<object> Query(TableMapping map, string query, params object[] args)
    {
      return this.CreateCommand(query, args).ExecuteQuery<object>(map);
    }

    /// <summary>
    /// Creates a SQLiteCommand given the command text (SQL) with arguments. Place a '?'
    /// in the command text for each of the arguments and then executes that command.
    /// It returns each row of the result using the specified mapping. This function is
    /// only used by libraries in order to query the database via introspection. It is
    /// normally not used.
    /// </summary>
    /// <param name="map">
    /// A <see cref="T:SQLite.TableMapping" /> to use to convert the resulting rows
    /// into objects.
    /// </param>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// An enumerable with one result for each row returned by the query.
    /// The enumerator will call sqlite3_step on each call to MoveNext, so the database
    /// connection must remain open for the lifetime of the enumerator.
    /// </returns>
    public IEnumerable<object> DeferredQuery(TableMapping map, string query, params object[] args)
    {
      return this.CreateCommand(query, args).ExecuteDeferredQuery<object>(map);
    }

    /// <summary>
    /// Returns a queryable interface to the table represented by the given type.
    /// </summary>
    /// <returns>
    /// A queryable object that is able to translate Where, OrderBy, and Take
    /// queries into native SQL.
    /// </returns>
    public TableQuery<T> Table<T>() where T : new()
    {
      return new TableQuery<T>(this);
    }

    /// <summary>
    /// Attempts to retrieve an object with the given primary key from the table
    /// associated with the specified type. Use of this method requires that
    /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).
    /// </summary>
    /// <param name="pk">The primary key.</param>
    /// <returns>
    /// The object with the given primary key. Throws a not found exception
    /// if the object is not found.
    /// </returns>
    public T Get<T>(object pk) where T : new()
    {
      return this.Query<T>(this.GetMapping(typeof (T), CreateFlags.None).GetByPrimaryKeySql, pk).First<T>();
    }

    /// <summary>
    /// Attempts to retrieve an object with the given primary key from the table
    /// associated with the specified type. Use of this method requires that
    /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).
    /// </summary>
    /// <param name="pk">The primary key.</param>
    /// <param name="map">The TableMapping used to identify the table.</param>
    /// <returns>
    /// The object with the given primary key. Throws a not found exception
    /// if the object is not found.
    /// </returns>
    public object Get(object pk, TableMapping map)
    {
      return this.Query(map, map.GetByPrimaryKeySql, pk).First<object>();
    }

    /// <summary>
    /// Attempts to retrieve the first object that matches the predicate from the table
    /// associated with the specified type.
    /// </summary>
    /// <param name="predicate">A predicate for which object to find.</param>
    /// <returns>
    /// The object that matches the given predicate. Throws a not found exception
    /// if the object is not found.
    /// </returns>
    public T Get<T>(Expression<Func<T, bool>> predicate) where T : new()
    {
      return this.Table<T>().Where(predicate).First();
    }

    /// <summary>
    /// Attempts to retrieve an object with the given primary key from the table
    /// associated with the specified type. Use of this method requires that
    /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).
    /// </summary>
    /// <param name="pk">The primary key.</param>
    /// <returns>
    /// The object with the given primary key or null
    /// if the object is not found.
    /// </returns>
    public T Find<T>(object pk) where T : new()
    {
      return this.Query<T>(this.GetMapping(typeof (T), CreateFlags.None).GetByPrimaryKeySql, pk).FirstOrDefault<T>();
    }

    /// <summary>
    /// Attempts to retrieve an object with the given primary key from the table
    /// associated with the specified type. Use of this method requires that
    /// the given type have a designated PrimaryKey (using the PrimaryKeyAttribute).
    /// </summary>
    /// <param name="pk">The primary key.</param>
    /// <param name="map">The TableMapping used to identify the table.</param>
    /// <returns>
    /// The object with the given primary key or null
    /// if the object is not found.
    /// </returns>
    public object Find(object pk, TableMapping map)
    {
      return this.Query(map, map.GetByPrimaryKeySql, pk).FirstOrDefault<object>();
    }

    /// <summary>
    /// Attempts to retrieve the first object that matches the predicate from the table
    /// associated with the specified type.
    /// </summary>
    /// <param name="predicate">A predicate for which object to find.</param>
    /// <returns>
    /// The object that matches the given predicate or null
    /// if the object is not found.
    /// </returns>
    public T Find<T>(Expression<Func<T, bool>> predicate) where T : new()
    {
      return this.Table<T>().Where(predicate).FirstOrDefault();
    }

    /// <summary>
    /// Attempts to retrieve the first object that matches the query from the table
    /// associated with the specified type.
    /// </summary>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// The object that matches the given predicate or null
    /// if the object is not found.
    /// </returns>
    public T FindWithQuery<T>(string query, params object[] args) where T : new()
    {
      return this.Query<T>(query, args).FirstOrDefault<T>();
    }

    /// <summary>
    /// Attempts to retrieve the first object that matches the query from the table
    /// associated with the specified type.
    /// </summary>
    /// <param name="map">The TableMapping used to identify the table.</param>
    /// <param name="query">The fully escaped SQL.</param>
    /// <param name="args">
    /// Arguments to substitute for the occurences of '?' in the query.
    /// </param>
    /// <returns>
    /// The object that matches the given predicate or null
    /// if the object is not found.
    /// </returns>
    public object FindWithQuery(TableMapping map, string query, params object[] args)
    {
      return this.Query(map, query, args).FirstOrDefault<object>();
    }

    /// <summary>
    /// Whether <see cref="M:SQLite.SQLiteConnection.BeginTransaction" /> has been called and the database is waiting for a <see cref="M:SQLite.SQLiteConnection.Commit" />.
    /// </summary>
    public bool IsInTransaction
    {
      get
      {
        return this._transactionDepth > 0;
      }
    }

    /// <summary>
    /// Begins a new transaction. Call <see cref="M:SQLite.SQLiteConnection.Commit" /> to end the transaction.
    /// </summary>
    /// <example cref="T:System.InvalidOperationException">Throws if a transaction has already begun.</example>
    public void BeginTransaction()
    {
      if (Interlocked.CompareExchange(ref this._transactionDepth, 1, 0) != 0)
        throw new InvalidOperationException("Cannot begin a transaction while already in a transaction.");
      try
      {
        this.Execute("begin transaction");
      }
      catch (Exception ex)
      {
        SQLiteException sqLiteException = ex as SQLiteException;
        if (sqLiteException != null)
        {
          switch (sqLiteException.Result)
          {
            case SQLite3.Result.Busy:
            case SQLite3.Result.NoMem:
            case SQLite3.Result.Interrupt:
            case SQLite3.Result.IOError:
            case SQLite3.Result.Full:
              this.RollbackTo((string) null, true);
              break;
          }
        }
        else
          Interlocked.Decrement(ref this._transactionDepth);
        throw;
      }
    }

    /// <summary>
    /// Creates a savepoint in the database at the current point in the transaction timeline.
    /// Begins a new transaction if one is not in progress.
    /// 
    /// Call <see cref="M:SQLite.SQLiteConnection.RollbackTo(System.String)" /> to undo transactions since the returned savepoint.
    /// Call <see cref="M:SQLite.SQLiteConnection.Release(System.String)" /> to commit transactions after the savepoint returned here.
    /// Call <see cref="M:SQLite.SQLiteConnection.Commit" /> to end the transaction, committing all changes.
    /// </summary>
    /// <returns>A string naming the savepoint.</returns>
    public string SaveTransactionPoint()
    {
      string str = "S" + (object) this._rand.Next((int) short.MaxValue) + "D" + (object) (Interlocked.Increment(ref this._transactionDepth) - 1);
      try
      {
        this.Execute("savepoint " + str);
      }
      catch (Exception ex)
      {
        SQLiteException sqLiteException = ex as SQLiteException;
        if (sqLiteException != null)
        {
          switch (sqLiteException.Result)
          {
            case SQLite3.Result.Busy:
            case SQLite3.Result.NoMem:
            case SQLite3.Result.Interrupt:
            case SQLite3.Result.IOError:
            case SQLite3.Result.Full:
              this.RollbackTo((string) null, true);
              break;
          }
        }
        else
          Interlocked.Decrement(ref this._transactionDepth);
        throw;
      }
      return str;
    }

    /// <summary>
    /// Rolls back the transaction that was begun by <see cref="M:SQLite.SQLiteConnection.BeginTransaction" /> or <see cref="M:SQLite.SQLiteConnection.SaveTransactionPoint" />.
    /// </summary>
    public void Rollback()
    {
      this.RollbackTo((string) null, false);
    }

    /// <summary>
    /// Rolls back the savepoint created by <see cref="M:SQLite.SQLiteConnection.BeginTransaction" /> or SaveTransactionPoint.
    /// </summary>
    /// <param name="savepoint">The name of the savepoint to roll back to, as returned by <see cref="M:SQLite.SQLiteConnection.SaveTransactionPoint" />.  If savepoint is null or empty, this method is equivalent to a call to <see cref="M:SQLite.SQLiteConnection.Rollback" /></param>
    public void RollbackTo(string savepoint)
    {
      this.RollbackTo(savepoint, false);
    }

    /// <summary>
    /// Rolls back the transaction that was begun by <see cref="M:SQLite.SQLiteConnection.BeginTransaction" />.
    /// </summary>
    /// <param name="savepoint">The name of the savepoint to roll back to, as returned by <see cref="M:SQLite.SQLiteConnection.SaveTransactionPoint" />.  If savepoint is null or empty, this method is equivalent to a call to <see cref="M:SQLite.SQLiteConnection.Rollback" /></param>
    /// <param name="noThrow">true to avoid throwing exceptions, false otherwise</param>
    private void RollbackTo(string savepoint, bool noThrow)
    {
      try
      {
        if (string.IsNullOrEmpty(savepoint))
        {
          if (Interlocked.Exchange(ref this._transactionDepth, 0) <= 0)
            return;
          this.Execute("rollback");
        }
        else
          this.DoSavePointExecute(savepoint, "rollback to ");
      }
      catch (SQLiteException ex)
      {
        if (noThrow)
          return;
        throw;
      }
    }

    /// <summary>
    /// Releases a savepoint returned from <see cref="M:SQLite.SQLiteConnection.SaveTransactionPoint" />.  Releasing a savepoint
    ///    makes changes since that savepoint permanent if the savepoint began the transaction,
    ///    or otherwise the changes are permanent pending a call to <see cref="M:SQLite.SQLiteConnection.Commit" />.
    /// 
    /// The RELEASE command is like a COMMIT for a SAVEPOINT.
    /// </summary>
    /// <param name="savepoint">The name of the savepoint to release.  The string should be the result of a call to <see cref="M:SQLite.SQLiteConnection.SaveTransactionPoint" /></param>
    public void Release(string savepoint)
    {
      this.DoSavePointExecute(savepoint, "release ");
    }

    private void DoSavePointExecute(string savepoint, string cmd)
    {
      int num = savepoint.IndexOf('D');
      int result;
      if (num < 2 || savepoint.Length <= num + 1 || (!int.TryParse(savepoint.Substring(num + 1), out result) || 0 > result) || result >= this._transactionDepth)
        throw new ArgumentException("savePoint is not valid, and should be the result of a call to SaveTransactionPoint.", "savePoint");
      Volatile.Write(ref this._transactionDepth, result);
      this.Execute(cmd + savepoint);
    }

    /// <summary>
    /// Commits the transaction that was begun by <see cref="M:SQLite.SQLiteConnection.BeginTransaction" />.
    /// </summary>
    public void Commit()
    {
      if (Interlocked.Exchange(ref this._transactionDepth, 0) == 0)
        return;
      this.Execute("commit");
    }

    /// <summary>
    /// Executes <paramref name="action" /> within a (possibly nested) transaction by wrapping it in a SAVEPOINT. If an
    /// exception occurs the whole transaction is rolled back, not just the current savepoint. The exception
    /// is rethrown.
    /// </summary>
    /// <param name="action">
    /// The <see cref="T:System.Action" /> to perform within a transaction. <paramref name="action" /> can contain any number
    /// of operations on the connection but should never call <see cref="M:SQLite.SQLiteConnection.BeginTransaction" /> or
    /// <see cref="M:SQLite.SQLiteConnection.Commit" />.
    /// </param>
    public void RunInTransaction(Action action)
    {
      try
      {
        string savepoint = this.SaveTransactionPoint();
        action();
        this.Release(savepoint);
      }
      catch (Exception ex)
      {
        this.Rollback();
        throw;
      }
    }

    /// <summary>Inserts all specified objects.</summary>
    /// <param name="objects">
    /// An <see cref="T:System.Collections.IEnumerable" /> of the objects to insert.
    /// <param name="runInTransaction" />
    /// A boolean indicating if the inserts should be wrapped in a transaction.
    /// </param>
    /// <returns>The number of rows added to the table.</returns>
    public int InsertAll(IEnumerable objects, bool runInTransaction = true)
    {
      int c = 0;
      if (runInTransaction)
      {
        this.RunInTransaction((Action) (() =>
        {
          foreach (object obj in objects)
            c += this.Insert(obj);
        }));
      }
      else
      {
        foreach (object obj in objects)
          c += this.Insert(obj);
      }
      return c;
    }

    /// <summary>Inserts all specified objects.</summary>
    /// <param name="objects">
    /// An <see cref="T:System.Collections.IEnumerable" /> of the objects to insert.
    /// </param>
    /// <param name="extra">
    /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ...
    /// </param>
    /// <param name="runInTransaction">
    /// A boolean indicating if the inserts should be wrapped in a transaction.
    /// </param>
    /// <returns>The number of rows added to the table.</returns>
    public int InsertAll(IEnumerable objects, string extra, bool runInTransaction = true)
    {
      int c = 0;
      if (runInTransaction)
      {
        this.RunInTransaction((Action) (() =>
        {
          foreach (object obj in objects)
            c += this.Insert(obj, extra);
        }));
      }
      else
      {
        foreach (object obj in objects)
          c += this.Insert(obj);
      }
      return c;
    }

    /// <summary>Inserts all specified objects.</summary>
    /// <param name="objects">
    /// An <see cref="T:System.Collections.IEnumerable" /> of the objects to insert.
    /// </param>
    /// <param name="objType">The type of object to insert.</param>
    /// <param name="runInTransaction">
    /// A boolean indicating if the inserts should be wrapped in a transaction.
    /// </param>
    /// <returns>The number of rows added to the table.</returns>
    public int InsertAll(IEnumerable objects, Type objType, bool runInTransaction = true)
    {
      int c = 0;
      if (runInTransaction)
      {
        this.RunInTransaction((Action) (() =>
        {
          foreach (object obj in objects)
            c += this.Insert(obj, objType);
        }));
      }
      else
      {
        foreach (object obj in objects)
          c += this.Insert(obj, objType);
      }
      return c;
    }

    /// <summary>
    /// Inserts the given object and retrieves its
    /// auto incremented primary key if it has one.
    /// </summary>
    /// <param name="obj">The object to insert.</param>
    /// <returns>The number of rows added to the table.</returns>
    public int Insert(object obj)
    {
      if (obj == null)
        return 0;
      return this.Insert(obj, "", Orm.GetType(obj));
    }

    /// <summary>
    /// Inserts the given object and retrieves its
    /// auto incremented primary key if it has one.
    /// If a UNIQUE constraint violation occurs with
    /// some pre-existing object, this function deletes
    /// the old object.
    /// </summary>
    /// <param name="obj">The object to insert.</param>
    /// <returns>The number of rows modified.</returns>
    public int InsertOrReplace(object obj)
    {
      if (obj == null)
        return 0;
      return this.Insert(obj, "OR REPLACE", Orm.GetType(obj));
    }

    /// <summary>
    /// Inserts the given object and retrieves its
    /// auto incremented primary key if it has one.
    /// </summary>
    /// <param name="obj">The object to insert.</param>
    /// <param name="objType">The type of object to insert.</param>
    /// <returns>The number of rows added to the table.</returns>
    public int Insert(object obj, Type objType)
    {
      return this.Insert(obj, "", objType);
    }

    /// <summary>
    /// Inserts the given object and retrieves its
    /// auto incremented primary key if it has one.
    /// If a UNIQUE constraint violation occurs with
    /// some pre-existing object, this function deletes
    /// the old object.
    /// </summary>
    /// <param name="obj">The object to insert.</param>
    /// <param name="objType">The type of object to insert.</param>
    /// <returns>The number of rows modified.</returns>
    public int InsertOrReplace(object obj, Type objType)
    {
      return this.Insert(obj, "OR REPLACE", objType);
    }

    /// <summary>
    /// Inserts the given object and retrieves its
    /// auto incremented primary key if it has one.
    /// </summary>
    /// <param name="obj">The object to insert.</param>
    /// <param name="extra">
    /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ...
    /// </param>
    /// <returns>The number of rows added to the table.</returns>
    public int Insert(object obj, string extra)
    {
      if (obj == null)
        return 0;
      return this.Insert(obj, extra, Orm.GetType(obj));
    }

    /// <summary>
    /// Inserts the given object and retrieves its
    /// auto incremented primary key if it has one.
    /// </summary>
    /// <param name="obj">The object to insert.</param>
    /// <param name="extra">
    /// Literal SQL code that gets placed into the command. INSERT {extra} INTO ...
    /// </param>
    /// <param name="objType">The type of object to insert.</param>
    /// <returns>The number of rows added to the table.</returns>
    public int Insert(object obj, string extra, Type objType)
    {
      if (obj == null || (object) objType == null)
        return 0;
      TableMapping mapping = this.GetMapping(objType, CreateFlags.None);
      if (mapping.PK != null && mapping.PK.IsAutoGuid && mapping.PK.GetValue(obj).Equals((object) Guid.Empty))
        mapping.PK.SetValue(obj, (object) Guid.NewGuid());
      TableMapping.Column[] columnArray = string.Compare(extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0 ? mapping.InsertOrReplaceColumns : mapping.InsertColumns;
      object[] source = new object[columnArray.Length];
      for (int index = 0; index < source.Length; ++index)
        source[index] = columnArray[index].GetValue(obj);
      PreparedSqlLiteInsertCommand insertCommand = mapping.GetInsertCommand(this, extra);
      int num;
      lock (insertCommand)
      {
        try
        {
          num = insertCommand.ExecuteNonQuery(source);
        }
        catch (SQLiteException ex)
        {
          if (SQLite3.ExtendedErrCode(this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull)
            throw NotNullConstraintViolationException.New(ex.Result, ex.Message, mapping, obj);
          throw;
        }
        if (mapping.HasAutoIncPK)
        {
          long id = SQLite3.LastInsertRowid(this.Handle);
          mapping.SetAutoIncPK(obj, id);
        }
      }
      if (num > 0)
        this.OnTableChanged(mapping, NotifyTableChangedAction.Insert);
      return num;
    }

    /// <summary>
    /// Updates all of the columns of a table using the specified object
    /// except for its primary key.
    /// The object is required to have a primary key.
    /// </summary>
    /// <param name="obj">
    /// The object to update. It must have a primary key designated using the PrimaryKeyAttribute.
    /// </param>
    /// <returns>The number of rows updated.</returns>
    public int Update(object obj)
    {
      if (obj == null)
        return 0;
      return this.Update(obj, Orm.GetType(obj));
    }

    /// <summary>
    /// Updates all of the columns of a table using the specified object
    /// except for its primary key.
    /// The object is required to have a primary key.
    /// </summary>
    /// <param name="obj">
    /// The object to update. It must have a primary key designated using the PrimaryKeyAttribute.
    /// </param>
    /// <param name="objType">The type of object to insert.</param>
    /// <returns>The number of rows updated.</returns>
    public int Update(object obj, Type objType)
    {
      if (obj == null || (object) objType == null)
        return 0;
      TableMapping mapping = this.GetMapping(objType, CreateFlags.None);
      TableMapping.Column pk = mapping.PK;
      if (pk == null)
        throw new NotSupportedException("Cannot update " + mapping.TableName + ": it has no PK");
      IEnumerable<TableMapping.Column> source = ((IEnumerable<TableMapping.Column>) mapping.Columns).Where<TableMapping.Column>((Func<TableMapping.Column, bool>) (p => p != pk));
      List<object> objectList = new List<object>(source.Select<TableMapping.Column, object>((Func<TableMapping.Column, object>) (c => c.GetValue(obj))));
      objectList.Add(pk.GetValue(obj));
      string query = string.Format("update \"{0}\" set {1} where {2} = ? ", new object[3]
      {
        (object) mapping.TableName,
        (object) string.Join(",", source.Select<TableMapping.Column, string>((Func<TableMapping.Column, string>) (c => "\"" + c.Name + "\" = ? ")).ToArray<string>()),
        (object) pk.Name
      });
      int num;
      try
      {
        num = this.Execute(query, objectList.ToArray());
      }
      catch (SQLiteException ex)
      {
        if (ex.Result == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode(this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull)
          throw NotNullConstraintViolationException.New(ex, mapping, obj);
        throw ex;
      }
      if (num > 0)
        this.OnTableChanged(mapping, NotifyTableChangedAction.Update);
      return num;
    }

    /// <summary>Updates all specified objects.</summary>
    /// <param name="objects">
    /// An <see cref="T:System.Collections.IEnumerable" /> of the objects to insert.
    /// </param>
    /// <param name="runInTransaction">
    /// A boolean indicating if the inserts should be wrapped in a transaction
    /// </param>
    /// <returns>The number of rows modified.</returns>
    public int UpdateAll(IEnumerable objects, bool runInTransaction = true)
    {
      int c = 0;
      if (runInTransaction)
      {
        this.RunInTransaction((Action) (() =>
        {
          foreach (object obj in objects)
            c += this.Update(obj);
        }));
      }
      else
      {
        foreach (object obj in objects)
          c += this.Update(obj);
      }
      return c;
    }

    /// <summary>
    /// Deletes the given object from the database using its primary key.
    /// </summary>
    /// <param name="objectToDelete">
    /// The object to delete. It must have a primary key designated using the PrimaryKeyAttribute.
    /// </param>
    /// <returns>The number of rows deleted.</returns>
    public int Delete(object objectToDelete)
    {
      TableMapping mapping = this.GetMapping(Orm.GetType(objectToDelete), CreateFlags.None);
      TableMapping.Column pk = mapping.PK;
      if (pk == null)
        throw new NotSupportedException("Cannot delete " + mapping.TableName + ": it has no PK");
      int num = this.Execute(string.Format("delete from \"{0}\" where \"{1}\" = ?", new object[2]
      {
        (object) mapping.TableName,
        (object) pk.Name
      }), pk.GetValue(objectToDelete));
      if (num > 0)
        this.OnTableChanged(mapping, NotifyTableChangedAction.Delete);
      return num;
    }

    /// <summary>Deletes the object with the specified primary key.</summary>
    /// <param name="primaryKey">The primary key of the object to delete.</param>
    /// <returns>The number of objects deleted.</returns>
    /// <typeparam name="T">The type of object.</typeparam>
    public int Delete<T>(object primaryKey)
    {
      return this.Delete(primaryKey, this.GetMapping(typeof (T), CreateFlags.None));
    }

    /// <summary>Deletes the object with the specified primary key.</summary>
    /// <param name="primaryKey">The primary key of the object to delete.</param>
    /// <param name="map">The TableMapping used to identify the table.</param>
    /// <returns>The number of objects deleted.</returns>
    public int Delete(object primaryKey, TableMapping map)
    {
      TableMapping.Column pk = map.PK;
      if (pk == null)
        throw new NotSupportedException("Cannot delete " + map.TableName + ": it has no PK");
      int num = this.Execute(string.Format("delete from \"{0}\" where \"{1}\" = ?", new object[2]
      {
        (object) map.TableName,
        (object) pk.Name
      }), primaryKey);
      if (num > 0)
        this.OnTableChanged(map, NotifyTableChangedAction.Delete);
      return num;
    }

    /// <summary>
    /// Deletes all the objects from the specified table.
    /// WARNING WARNING: Let me repeat. It deletes ALL the objects from the
    /// specified table. Do you really want to do that?
    /// </summary>
    /// <returns>The number of objects deleted.</returns>
    /// <typeparam name="T">The type of objects to delete.</typeparam>
    public int DeleteAll<T>()
    {
      return this.DeleteAll(this.GetMapping(typeof (T), CreateFlags.None));
    }

    /// <summary>
    /// Deletes all the objects from the specified table.
    /// WARNING WARNING: Let me repeat. It deletes ALL the objects from the
    /// specified table. Do you really want to do that?
    /// </summary>
    /// <param name="map">The TableMapping used to identify the table.</param>
    /// <returns>The number of objects deleted.</returns>
    public int DeleteAll(TableMapping map)
    {
      int num = this.Execute(string.Format("delete from \"{0}\"", new object[1]
      {
        (object) map.TableName
      }));
      if (num > 0)
        this.OnTableChanged(map, NotifyTableChangedAction.Delete);
      return num;
    }

    ~SQLiteConnection()
    {
      this.Dispose(false);
    }

    public void Dispose()
    {
      this.Dispose(true);
      GC.SuppressFinalize((object) this);
    }

    public void Close()
    {
      this.Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (!this._open)
        return;
      if (this.Handle == SQLiteConnection.NullHandle)
        return;
      try
      {
        if (disposing)
        {
          if (this._mappings != null)
          {
            foreach (TableMapping tableMapping in this._mappings.Values)
              tableMapping.Dispose();
          }
          SQLite3.Result r = SQLite3.Close2(this.Handle);
          if (r != SQLite3.Result.OK)
          {
            string errmsg = SQLite3.GetErrmsg(this.Handle);
            throw SQLiteException.New(r, errmsg);
          }
        }
        else
        {
          int num = (int) SQLite3.Close2(this.Handle);
        }
      }
      finally
      {
        this.Handle = SQLiteConnection.NullHandle;
        this._open = false;
      }
    }

    private void OnTableChanged(TableMapping table, NotifyTableChangedAction action)
    {
      // ISSUE: reference to a compiler-generated field
      EventHandler<NotifyTableChangedEventArgs> tableChanged = this.TableChanged;
      if (tableChanged == null)
        return;
      tableChanged((object) this, new NotifyTableChangedEventArgs(table, action));
    }

    public event EventHandler<NotifyTableChangedEventArgs> TableChanged;

    private struct IndexedColumn
    {
      public int Order;
      public string ColumnName;
    }

    private struct IndexInfo
    {
      public string IndexName;
      public string TableName;
      public bool Unique;
      public List<SQLiteConnection.IndexedColumn> Columns;
    }

    public class ColumnInfo
    {
      [Column("name")]
      public string Name { get; set; }

      public int notnull { get; set; }

      public override string ToString()
      {
        return this.Name;
      }
    }
  }
}

Unity----SQLite数据库的连接使用 1.简介: 数据库:电子化的文件柜,用户进行增删查改 SQLite:轻量级数据库,设计目标为嵌入式,占用资源低(以文件的形式存在应用中),支持主流的操作系统, 2.使用SQLite生成DataBase,为后缀sqlite的文件 使用sql语句对数据库进行操作 3.unity读SQLite文件 ①把建立好的SQLite数据库文件放到Unity工程的Assets的streamingAssets(到时候可以使用Application.streamingAssetsPathz读到此文件) ②导入dll文件,sql 阅读详情

相关推荐

C# Sqlite 操作

sqlite作为轻量级数据库,非常方便本地数据存储和移动端数据存储。 c#操作Sqlite,需要引用命名空间:System.Data.Sqlite; 其方法与普通的SqlServer引用System.Data.SqlClient名称空间类似。只是System.Data.Sqlite;没有继承到微软的程序集中。需要安装,方法如下: PM> install-package System.D...

qq_26657857的博客 872

SQLite入门与分析(一)

 1、SQLite介绍   自几十年前出现的商业应用程序以来,数据库就成为软件应用程序的主要组成部分。正与数据库管理系统非常关键一样,它们也变得非常庞大,并占用了相当多的系统资源,增加了管理的复杂性。随着软件应用程序逐渐模块模块化,一种新型数据库会比大型复杂的传统数据库管理系统更适应。嵌入式数据库直接在应用程序进程中运行,提供了零配置(zero-configuration)运行模式,并且资

Gezhengzhong的专栏 3503

STM32 USB AUDIO实战指南——从零构建音频设备

本文详细介绍了如何使用STM32F407构建USB音频设备,从硬件准备到软件配置,再到音频播放和录制功能的实现。通过STM32CubeMX配置和实战代码示例,帮助开发者快速掌握USB Audio Class规范,实现低延迟、高质量的音频传输,适用于语音交互、音乐播放等多种场景。

weixin_42549037的博客 485

SQLite操作类Sqlite Dot Net即SQLite.SQLiteConnection的常用方法

sss

a_dev的专栏 6415

COMSOL报错调试总结(不定期更新)

COMSOL报错调试总结1. 可定位错误1.1 除零错误1.2 未定义变量值1.3 边界条件/材料属性等缺失2. 难定位错误2.1. 装配期间内存不足 官方给的案例总是非常完美,运行流畅,结果完美。但是自己做模型时候就总是报错,而且不像自己coding的程序那样可以明确定位哪里出了bug。这里把我碰到的一些报错问题以及调试方法记录下来~ 部分来源于以下参考来源: http://wap.sciencenet.cn/blog-1467490-1118453.html?mobile=1 1. 可定位错误 以下错误

jessica0307的博客 8万+

Verilog实现FIR滤波器

1、FIR滤波器简介 不追究FIR滤波器的深层含义,我们只关注如何实现;可以看出,FIR滤波器的本质就是延迟、系数相乘与求和,如下图: 2、设计 基于以上分析,按照三级流水实现FIR滤波器设计:信号延迟-系数相乘-求和 `timescale 1ns / 1ps module fir( input clk, input rst_n, input [3:0]din, output reg [9:0]dout ); // data reg reg [3:0]din1; reg [3:.

CLL_caicai的博客 1万+

SQLite数据库操作

一、SQLiteConnection 1、创建db数据库文件 strDBPath = "E:\\xxx.db"; SQLiteConnection.CreateFile(strDBPath); 2、打开数据库链接 SQLiteConnection ipConn = new SQLiteConnection(); SQLiteConnectionStringBuilder con

Tweeenty的专栏 932

使用Simulink对氢燃料电池与锂电池的混合储能系统进行建模

本文介绍了基于Simulink的氢燃料电池与锂电池混合储能系统建模与协同控制方法。系统通过氢燃料电池提供稳定能源,锂电池实现快速响应,结合DC-DC变换器和负载管理器实现动态调控。详细阐述了从模型创建、关键模块配置到控制器设计的完整流程,重点说明了功率分配算法和充放电控制策略的实现。通过仿真分析验证了系统在不同负载条件下的性能表现,包括响应速度、工作效率和稳定性等指标。该方案为新能源混合储能系统的设计与优化提供了实用指导,有助于提升系统可靠性和延长电池寿命。

amy_mhd的博客 315

Linux设备驱动开发全流程解析:从字符设备到设备树与I2C

在嵌入式Linux开发中,设备驱动是连接内核与硬件的关键桥梁,其本质是通过标准接口管理硬件复杂度。理解字符设备框架、设备树描述与总线驱动模型,是掌握驱动开发的核心路径。设备树(Device Tree)用于描述硬件拓扑,让内核自动匹配platform_driver;而I2C等真实总线驱动则涉及client与adapter的协同,配合设备树节点完成外设访问。本文从交叉编译环境搭建、字符设备骨架实现,到设备树配置、I2C/EMIO驱动实战,再到动态调试与性能调优,系统梳理了一套完整可落地的开发流程。同时探讨了fi

keke1314520的博客 549

PCIe-Orders set Blocks之symbol对齐

有序集的使用场合很多,如在链路link阶段,进入polling后,便开始有序集的发送。一个 Ordered Set Block 包含一个同步头,后跟一个有序集。多通道链路的所有 Lane 必须同时传输相同的有序集,而且有序集的第一个符号定义了有序集的类型。但在PCIE中,8GT/s及以上的速率,采用的是128b/130b编码。128-bit是想要传输的payload,实际会传输130-bit,多出来的2-bit就是sync header。Block有两种,通过Sync header区分:10b:表示data

weixin_44700185的博客 813

倍福控制第三方伺服走CSV模式--以汇川伺服为例

在使用TwinCAT软件控制标准CiA402协议的EtherCAT伺服时使用TwinCAT软件NC自带的运动控制指令控制伺服,此时伺服驱动器一般工作在CSP/CSV/CST模式。最常见伺服驱动器工作在CSP模式,轨迹规划运行在TwinCAT软件,位置环速度环电流环运行在伺服驱动器中。该模式下速度波动较大,需要极度平稳的速度需要采用CSV模式。本文讲述的是伺服驱动器工作在CSV模式,此时轨迹规划和位置环均运行在TwinCAT软件,速度环电流环运行在伺服驱动器中。为了简化文字描述,本文采用图文结合的方式介绍伺服

weixin_41883890的博客 4849

Sqlite DateTime 类型 读取和写入格式 注意的问题

今天遇到个问题. 首先插入一个DataTime格式的数据:string sql="insert into [table] (date_time) values('" + date_time.ToString() + "'"; 执行如上命令.插入没有报告错误. 但是,我又用一条命令读取时: string sql="select * from [table]; ..... IDataRea...

keke1314520的博客 102

论文阅读:ICLR 2026 Breaking and Fixing Defenses Against Control-Flow Hijacking in Multi-Agent Systems

该论文首先系统阐述了控制流劫持攻击的核心机理。此类攻击通过操纵多智能体系统的编排机制,诱导系统执行非安全操作,进而实现敏感信息窃取。攻击者将恶意指令伪装成环境错误信息,借助可信代理传递至系统编排器,利用"困惑副手"漏洞绕过传统安全防线。该论文指出,现有防御方案如LlamaFirewall所依赖的对齐检查机制存在根本性局限——安全目标与功能需求之间存在不可调和的内在冲突。该论文的核心贡献体现在攻防两个维度。

CSPhD-winston的博客 495

sqlite关于时间的处理

今天遇到个问题. 首先插入一个DataTime格式的数据: string sql="insert into [table] (date_time) values('" + date_time.ToString() + "'"; 执行如上命令.插入没有报告错误. 但是,我又用一条命令读取时: string sql="select * from [table]; ..... IDataReader ...

weixin_30797027的博客 141

C#上位机通信层封装:西门子S7NetPlus库的优雅使用

支持S7-1200/1500(机架号0,槽号1)、S7-300/400(机架号/槽号需根据实际配置);支持位(Bit)、字节(Byte)、字(Word)、双字(DWord)、浮点数(Float/Double)等数据类型的读写;支持DB块、输入寄存器(I)、输出寄存器(Q)、内存寄存器(M)、定时器(T)、计数器(C)的操作;轻量无依赖,兼容.NET 5+。首先定义核心枚举和常量,统一规范参数类型,避免硬编码。/// 西门子PLC型号(对应不同的机架/槽号默认配置)

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1086

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Xamarin之SQLITE操作经验总结

android使用Sqlite做本地存储非常常见(打个比方就像是浏览器要做本地存储使用LocalStorage,貌似不是很恰当,大概就是这个意思)。SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。如果不是很熟悉Sqlite,建议花点时间看看鸟巢 sqlite...

Andrewniu的博客 2291

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

c#操作轻型数据库SQLite

SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两

ghevinn欢迎您光临 1869

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Unity Android集成SqlSuager:解决SqliteConnection类型初始化异常

在移动应用开发中,本地数据库是数据持久化的核心技术之一。SQLite作为轻量级嵌入式数据库引擎,因其零配置、无服务器和跨平台特性,被广泛应用于移动端数据存储场景。其工作原理是通过C语言编写的原生库提供数据操作接口,上层应用通过封装库进行调用。在Unity引擎的跨平台开发中,特别是使用IL2CPP编译后端时,托管代码需要通过P/Invoke机制调用原生库,这涉及到复杂的**原生插件加载机制**和**平台调用**过程。当原生库文件缺失、位置不当或版本不匹配时,就会出现类型初始化失败异常。本文针对Unity An

weixin_34293911的博客 362

c# 给Sqlite数据库设置密码

System.Data.SQLite中的SQLiteConnection类提供了一个ChangePassword的方法,这个方法并非来自其父类DbConnection,而是在SQLiteConnection类中定义的。不禁让人感叹,这个开源驱动做的真不错。 using System; using System.Collections.Generic; using System.Linq; usin...

gangli_8的博客 5484

Sqlite数据库加密加密

Sqlite数据库加密。(C#连接加密的Sqlite数据库的方法) 参考地址[1]: https://www.jb51.net/article/120279.htm sqlite破解安装包下载: https://download.csdn.net/download/yinchoushi8780/11170781 一、数据库加密 对数据加密分两种,一种是对数据库本身进行加密,另一种是对数据表中的数据...

江河键行的博客 9741

android sqlite开关,Android - “SQLite.SQLiteConnection”的类型初始值设定项引发异常。 ---> System.DllNotFoundException:...

但是这个开关后,创建一个新的SQLiteConnection我得到以下异常时:为“SQLite.SQLiteConnection”的类型初始值引发异常。 ---> System.DllNotFoundException:e_sqlite3完整例外:Xamarin引起:android.runtime.JavaProxyThrowable: System.TypeInitializationE...

weixin_29964507的博客 1101

[Unity错误解决]InvalidProgramException:Invalid IL code in Mono.Data.Sqlite.SqliteConnection

Unity想使用Sqlite数据库 需要导入System.Data.dll,Mono.Data.Sqlite.dll,sqlite3.dll 到Project-Assets文件夹下。 报错:InvalidProgramException: Invalid IL code in Mono.Data.Sqlite.SqliteConnection:CreateCommand (): IL_0000:...

HelloWorld, GraspWorld! 2826

C# SQLite

C# SQLite 教程展示了如何在 C# 中编写 SQLite 数据库。 SQLite SQLite 是一个嵌入式关系数据库引擎。它是一个自包含、无服务器、零配置和事务性 SQL 数据库引擎。SQLite 实现了 SQL 的大部分 SQL-92 标准。SQLite 引擎不是一个独立的进程。相反,它是静态或动态链接到应用程序中的。SQLite 数据库是单个普通磁盘文件,可以位于目录层次结构中的任何位置。 ADO.NET ADO.NET是.NET 框架的重要组成部分。它是一种统一对关系数据

allway2的博客 1万+
上一篇: 用C#写一个灵活的要素Feature属性Properties质检WebAPI接口(四)
下一篇: SQLite操作类Sqlite Dot Net即SQLite.SQLiteConnection的常用方法
acngiser
博客等级 码龄15年 118粉丝 214原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值