diff --git a/Runtime/SQLiteExtensions.cs b/Runtime/SQLiteExtensions.cs index e682b16..d8321f8 100644 --- a/Runtime/SQLiteExtensions.cs +++ b/Runtime/SQLiteExtensions.cs @@ -47,7 +47,7 @@ public enum DeserializeFlags : uint [DllImport(LibraryPath, EntryPoint = "sqlite3_deserialize", CallingConvention = CallingConvention.Cdecl)] public static extern Result Deserialize(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string zSchema, byte[] pData, long szDb, long szBuf, DeserializeFlags mFlags); - + [DllImport(LibraryPath, EntryPoint = "sqlite3_deserialize", CallingConvention = CallingConvention.Cdecl)] public static unsafe extern Result Deserialize(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string zSchema, void* pData, long szDb, long szBuf, DeserializeFlags mFlags); @@ -84,35 +84,35 @@ static SQLite3() public static class ISQLiteConnectionExtensions { - public static int Insert(this ISQLiteConnection connection, ref T obj) + public static int Insert(this ISQLiteConnection connection, ref T obj, string tableName = "") { object boxed = obj; - int result = connection.Insert(boxed); - obj = (T) boxed; + int result = connection.Insert(boxed, tableName); + obj = (T)boxed; return result; } - public static int Insert(this ISQLiteConnection connection, ref T obj, Type objType) + public static int Insert(this ISQLiteConnection connection, ref T obj, Type objType, string tableName = "") { object boxed = obj; - int result = connection.Insert(boxed, objType); - obj = (T) boxed; + int result = connection.Insert(boxed, objType, tableName); + obj = (T)boxed; return result; } - public static int Insert(this ISQLiteConnection connection, ref T obj, string extra) + public static int Insert(this ISQLiteConnection connection, ref T obj, string extra, string tableName = "") { object boxed = obj; - int result = connection.Insert(boxed, extra); - obj = (T) boxed; + int result = connection.Insert(boxed, extra, tableName); + obj = (T)boxed; return result; } - public static int Insert(this ISQLiteConnection connection, ref T obj, string extra, Type objType) + public static int Insert(this ISQLiteConnection connection, ref T obj, string extra, Type objType, string tableName = "") { object boxed = obj; - int result = connection.Insert(boxed, extra, objType); - obj = (T) boxed; + int result = connection.Insert(boxed, extra, objType, tableName); + obj = (T)boxed; return result; } } diff --git a/Runtime/sqlite-net/SQLite.cs b/Runtime/sqlite-net/SQLite.cs index 5136a69..ed850df 100644 --- a/Runtime/sqlite-net/SQLite.cs +++ b/Runtime/sqlite-net/SQLite.cs @@ -63,14 +63,14 @@ public class SQLiteException : Exception { public SQLite3.Result Result { get; private set; } - protected SQLiteException (SQLite3.Result r, string message) : base (message) + protected SQLiteException(SQLite3.Result r, string message) : base(message) { Result = r; } - public static SQLiteException New (SQLite3.Result r, string message) + public static SQLiteException New(SQLite3.Result r, string message) { - return new SQLiteException (r, message); + return new SQLiteException(r, message); } } @@ -78,35 +78,36 @@ public class NotNullConstraintViolationException : SQLiteException { public IEnumerable Columns { get; protected set; } - protected NotNullConstraintViolationException (SQLite3.Result r, string message) - : this (r, message, null, null) + protected NotNullConstraintViolationException(SQLite3.Result r, string message) + : this(r, message, null, null) { } - protected NotNullConstraintViolationException (SQLite3.Result r, string message, TableMapping mapping, object obj) - : base (r, message) + protected NotNullConstraintViolationException(SQLite3.Result r, string message, TableMapping mapping, object obj) + : base(r, message) { - if (mapping != null && obj != null) { + if (mapping != null && obj != null) + { this.Columns = from c in mapping.Columns - where c.IsNullable == false && c.GetValue (obj) == null + where c.IsNullable == false && c.GetValue(obj) == null select c; } } - public static new NotNullConstraintViolationException New (SQLite3.Result r, string message) + public static new NotNullConstraintViolationException New(SQLite3.Result r, string message) { - return new NotNullConstraintViolationException (r, message); + return new NotNullConstraintViolationException(r, message); } - public static NotNullConstraintViolationException New (SQLite3.Result r, string message, TableMapping mapping, object obj) + public static NotNullConstraintViolationException New(SQLite3.Result r, string message, TableMapping mapping, object obj) { - return new NotNullConstraintViolationException (r, message, mapping, obj); + return new NotNullConstraintViolationException(r, message, mapping, obj); } - public static NotNullConstraintViolationException New (SQLiteException exception, TableMapping mapping, object obj) + public static NotNullConstraintViolationException New(SQLiteException exception, TableMapping mapping, object obj) { - return new NotNullConstraintViolationException (exception.Result, exception.Message, mapping, obj); + return new NotNullConstraintViolationException(exception.Result, exception.Message, mapping, obj); } } @@ -177,105 +178,111 @@ public interface ISQLiteConnection : IDisposable event EventHandler TableChanged; - void Backup (string destinationDatabasePath, string databaseName = "main"); - void BeginTransaction (); - void Close (); - void Commit (); - SQLiteCommand CreateCommand (string cmdText, params object[] ps); - SQLiteCommand CreateCommand (string cmdText, Dictionary args); - int CreateIndex (string indexName, string tableName, string[] columnNames, bool unique = false); - int CreateIndex (string indexName, string tableName, string columnName, bool unique = false); - int CreateIndex (string tableName, string columnName, bool unique = false); - int CreateIndex (string tableName, string[] columnNames, bool unique = false); - int CreateIndex (Expression> property, bool unique = false); - CreateTableResult CreateTable (CreateFlags createFlags = CreateFlags.None); - CreateTableResult CreateTable (Type ty, CreateFlags createFlags = CreateFlags.None); - CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + void Backup(string destinationDatabasePath, string databaseName = "main"); + void BeginTransaction(); + void Close(); + void Commit(); + SQLiteCommand CreateCommand(string cmdText, params object[] ps); + SQLiteCommand CreateCommand(string cmdText, Dictionary args); + int CreateIndex(string indexName, string tableName, string[] columnNames, bool unique = false); + int CreateIndex(string indexName, string tableName, string columnName, bool unique = false); + int CreateIndex(string tableName, string columnName, bool unique = false); + int CreateIndex(string tableName, string[] columnNames, bool unique = false); + int CreateIndex(Expression> property, bool unique = false, string tableName = null); + CreateTableResult CreateTable(CreateFlags createFlags = CreateFlags.None); + CreateTableResult CreateTable(string tableName, CreateFlags createFlags = CreateFlags.None); + CreateTableResult CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None); + CreateTableResult CreateTable(Type ty, string tableName, CreateFlags createFlags = CreateFlags.None); + CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new(); - CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() where T3 : new(); - CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() where T3 : new() where T4 : new(); - CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() where T3 : new() where T4 : new() where T5 : new(); - CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None, params Type[] types); - IEnumerable DeferredQuery (string query, params object[] args) where T : new(); - IEnumerable DeferredQuery (TableMapping map, string query, params object[] args); - int Delete (object objectToDelete); - int Delete (object primaryKey); - int Delete (object primaryKey, TableMapping map); - int DeleteAll (); - int DeleteAll (TableMapping map); - int DropTable (); - int DropTable (TableMapping map); - void EnableLoadExtension (bool enabled); - void EnableWriteAheadLogging (); - int Execute (string query, params object[] args); - T ExecuteScalar (string query, params object[] args); - T Find (object pk) where T : new(); - object Find (object pk, TableMapping map); - T Find (Expression> predicate) where T : new(); - T FindWithQuery (string query, params object[] args) where T : new(); - object FindWithQuery (TableMapping map, string query, params object[] args); - T Get (object pk) where T : new(); - object Get (object pk, TableMapping map); - T Get (Expression> predicate) where T : new(); - TableMapping GetMapping (Type type, CreateFlags createFlags = CreateFlags.None); - TableMapping GetMapping (CreateFlags createFlags = CreateFlags.None); - List GetTableInfo (string tableName); - int Insert (object obj); - int Insert (object obj, Type objType); - int Insert (object obj, string extra); - int Insert (object obj, string extra, Type objType); - int InsertAll (IEnumerable objects, bool runInTransaction = true); - int InsertAll (IEnumerable objects, string extra, bool runInTransaction = true); - int InsertAll (IEnumerable objects, Type objType, bool runInTransaction = true); - int InsertOrReplace (object obj); - int InsertOrReplace (object obj, Type objType); - List Query (string query, params object[] args) where T : new(); - List Query (TableMapping map, string query, params object[] args); - List QueryScalars (string query, params object[] args); - void ReKey (string key); - void ReKey (byte[] key); - void Release (string savepoint); - void Rollback (); - void RollbackTo (string savepoint); - void RunInTransaction (Action action); - string SaveTransactionPoint (); - TableQuery Table () where T : new(); - int Update (object obj); - int Update (object obj, Type objType); - int UpdateAll (IEnumerable objects, bool runInTransaction = true); + CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None, params Type[] types); + IEnumerable DeferredQuery(string query, params object[] args) where T : new(); + IEnumerable DeferredQuery(TableMapping map, string query, params object[] args); + int Delete(object objectToDelete, string tableName = null); + int Delete(object primaryKey, string tableName = null); + int Delete(object primaryKey, TableMapping map); + int DeleteAll(string tableName = null); + int DeleteAll(TableMapping map); + int DropTable(string tableName = null); + int DropTable(TableMapping map); + void EnableLoadExtension(bool enabled); + void EnableWriteAheadLogging(); + int Execute(string query, params object[] args); + T ExecuteScalar(string query, params object[] args); + T Find(object pk, string tableName = null) where T : new(); + object Find(object pk, TableMapping map); + T Find(Expression> predicate, string tableName = null) where T : new(); + T FindWithQuery(string query, params object[] args) where T : new(); + T FindWithQuery(string tableName, string query, params object[] args) where T : new(); + object FindWithQuery(TableMapping map, string query, params object[] args); + T Get(object pk, string tableName = null) where T : new(); + object Get(object pk, TableMapping map); + T Get(Expression> predicate, string tableName = null) where T : new(); + TableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None); + TableMapping GetMapping(Type type, string tableName, CreateFlags createFlags = CreateFlags.None); + TableMapping GetMapping(CreateFlags createFlags = CreateFlags.None); + TableMapping GetMapping(string tableName, CreateFlags createFlags = CreateFlags.None); + List GetTableInfo(string tableName); + int Insert(object obj, string tableName = null); + int Insert(object obj, Type objType, string tableName = null); + int Insert(object obj, string extra, string tableName = null); + int Insert(object obj, string extra, Type objType, string tableName = null); + int InsertAll(IEnumerable objects, bool runInTransaction = true); + int InsertAll(IEnumerable objects, string extra, bool runInTransaction = true); + int InsertAll(IEnumerable objects, Type objType, bool runInTransaction = true); + int InsertOrReplace(object obj, string tableName = null); + int InsertOrReplace(object obj, Type objType, string tableName = null); + List Query(string query, params object[] args) where T : new(); + List Query(string tableName, string query, params object[] args) where T : new(); + List Query(TableMapping map, string query, params object[] args); + List QueryScalars(string query, params object[] args); + void ReKey(string key); + void ReKey(byte[] key); + void Release(string savepoint); + void Rollback(); + void RollbackTo(string savepoint); + void RunInTransaction(Action action); + string SaveTransactionPoint(); + TableQuery Table(string tableName = null) where T : new(); + int Update(object obj, string tableName = null); + int Update(object obj, Type objType, string tableName = null); + int UpdateAll(IEnumerable objects, bool runInTransaction = true); } /// /// An open connection to a SQLite database. /// - [Preserve (AllMembers = true)] + [Preserve(AllMembers = true)] public partial class SQLiteConnection : ISQLiteConnection { private bool _open; private TimeSpan _busyTimeout; - readonly static Dictionary _mappings = new Dictionary (); + readonly static Dictionary _mappings = new Dictionary(); private System.Diagnostics.Stopwatch _sw; private long _elapsedMilliseconds = 0; private int _transactionDepth = 0; - private Random _rand = new Random (); + private Random _rand = new Random(); public Sqlite3DatabaseHandle Handle { get; private set; } - static readonly Sqlite3DatabaseHandle NullHandle = default (Sqlite3DatabaseHandle); - static readonly Sqlite3BackupHandle NullBackupHandle = default (Sqlite3BackupHandle); + static readonly Sqlite3DatabaseHandle NullHandle = default(Sqlite3DatabaseHandle); + static readonly Sqlite3BackupHandle NullBackupHandle = default(Sqlite3BackupHandle); /// /// Gets the database path used by this connection. @@ -346,8 +353,8 @@ static SQLiteConnection () /// If you use DateTimeOffset properties, it will be always stored as ticks regardingless /// the storeDateTimeAsTicks parameter. /// - public SQLiteConnection (string databasePath, bool storeDateTimeAsTicks = true) - : this (new SQLiteConnectionString (databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks)) + public SQLiteConnection(string databasePath, bool storeDateTimeAsTicks = true) + : this(new SQLiteConnectionString(databasePath, SQLiteOpenFlags.ReadWrite | SQLiteOpenFlags.Create, storeDateTimeAsTicks)) { } @@ -368,8 +375,8 @@ public SQLiteConnection (string databasePath, bool storeDateTimeAsTicks = true) /// If you use DateTimeOffset properties, it will be always stored as ticks regardingless /// the storeDateTimeAsTicks parameter. /// - public SQLiteConnection (string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = true) - : this (new SQLiteConnectionString (databasePath, openFlags, storeDateTimeAsTicks)) + public SQLiteConnection(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks = true) + : this(new SQLiteConnectionString(databasePath, openFlags, storeDateTimeAsTicks)) { } @@ -379,16 +386,16 @@ public SQLiteConnection (string databasePath, SQLiteOpenFlags openFlags, bool st /// /// Details on how to find and open the database. /// - public SQLiteConnection (SQLiteConnectionString connectionString) + public SQLiteConnection(SQLiteConnectionString connectionString) { if (connectionString == null) - throw new ArgumentNullException (nameof (connectionString)); + throw new ArgumentNullException(nameof(connectionString)); if (connectionString.DatabasePath == null) - throw new InvalidOperationException ("DatabasePath must be specified"); + throw new InvalidOperationException("DatabasePath must be specified"); DatabasePath = connectionString.DatabasePath; - LibVersionNumber = SQLite3.LibVersionNumber (); + LibVersionNumber = SQLite3.LibVersionNumber(); #if NETFX_CORE SQLite3.SetDirectory(/*temp directory type*/2, Windows.Storage.ApplicationData.Current.TemporaryFolder.Path); @@ -402,13 +409,14 @@ public SQLiteConnection (SQLiteConnectionString connectionString) // open using the byte[] // in the case where the path may include Unicode // force open to using UTF-8 using sqlite3_open_v2 - var databasePathAsBytes = GetNullTerminatedUtf8 (connectionString.DatabasePath); - var r = SQLite3.Open (databasePathAsBytes, out handle, (int)connectionString.OpenFlags, connectionString.VfsName); + var databasePathAsBytes = GetNullTerminatedUtf8(connectionString.DatabasePath); + var r = SQLite3.Open(databasePathAsBytes, out handle, (int)connectionString.OpenFlags, connectionString.VfsName); #endif Handle = handle; - if (r != SQLite3.Result.OK) { - throw SQLiteException.New (r, String.Format ("Could not open database file: {0} ({1})", DatabasePath, r)); + if (r != SQLite3.Result.OK) + { + throw SQLiteException.New(r, String.Format("Could not open database file: {0} ({1})", DatabasePath, r)); } _open = true; @@ -417,20 +425,23 @@ public SQLiteConnection (SQLiteConnectionString connectionString) DateTimeStringFormat = connectionString.DateTimeStringFormat; DateTimeStyle = connectionString.DateTimeStyle; - BusyTimeout = TimeSpan.FromSeconds (1.0); - Tracer = line => Debug.WriteLine (line); + BusyTimeout = TimeSpan.FromSeconds(1.0); + Tracer = line => Debug.WriteLine(line); - connectionString.PreKeyAction?.Invoke (this); - if (connectionString.Key is string stringKey) { - SetKey (stringKey); + connectionString.PreKeyAction?.Invoke(this); + if (connectionString.Key is string stringKey) + { + SetKey(stringKey); } - else if (connectionString.Key is byte[] bytesKey) { - SetKey (bytesKey); + else if (connectionString.Key is byte[] bytesKey) + { + SetKey(bytesKey); } - else if (connectionString.Key != null) { - throw new InvalidOperationException ("Encryption keys must be strings or byte arrays"); + else if (connectionString.Key != null) + { + throw new InvalidOperationException("Encryption keys must be strings or byte arrays"); } - connectionString.PostKeyAction?.Invoke (this); + connectionString.PostKeyAction?.Invoke(this); } /// @@ -438,9 +449,9 @@ public SQLiteConnection (SQLiteConnectionString connectionString) /// by providing better concurrency and better disk IO performance than the normal /// journal mode. You only need to call this function once in the lifetime of the database. /// - public void EnableWriteAheadLogging () + public void EnableWriteAheadLogging() { - ExecuteScalar ("PRAGMA journal_mode=WAL"); + ExecuteScalar("PRAGMA journal_mode=WAL"); } /// @@ -448,12 +459,12 @@ public void EnableWriteAheadLogging () /// /// The quoted string. /// The unsafe string to quote. - public static string Quote (string unsafeString) + public static string Quote(string unsafeString) { // TODO: Doesn't call sqlite3_mprintf("%Q", u) because we're waiting on https://github.com/ericsink/SQLitePCL.raw/issues/153 if (unsafeString == null) return "NULL"; - var safe = unsafeString.Replace ("'", "''"); + var safe = unsafeString.Replace("'", "''"); return "'" + safe + "'"; } @@ -464,12 +475,12 @@ public static string Quote (string unsafeString) /// This only has an effect if you are using the SQLCipher nuget package. /// /// Encryption key plain text that is converted to the real encryption key using PBKDF2 key derivation - void SetKey (string key) + void SetKey(string key) { if (key == null) - throw new ArgumentNullException (nameof (key)); - var q = Quote (key); - ExecuteScalar ("pragma key = " + q); + throw new ArgumentNullException(nameof(key)); + var q = Quote(key); + ExecuteScalar("pragma key = " + q); } /// @@ -479,21 +490,21 @@ void SetKey (string key) /// This only has an effect if you are using the SQLCipher nuget package. /// /// 256-bit (32 byte) encryption key data - void SetKey (byte[] key) + void SetKey(byte[] key) { if (key == null) - throw new ArgumentNullException (nameof (key)); + throw new ArgumentNullException(nameof(key)); if (key.Length != 32 && key.Length != 48) - throw new ArgumentException ("Key must be 32 bytes (256-bit) or 48 bytes (384-bit)", nameof (key)); - var s = String.Join ("", key.Select (x => x.ToString ("X2"))); - ExecuteScalar ("pragma key = \"x'" + s + "'\""); + throw new ArgumentException("Key must be 32 bytes (256-bit) or 48 bytes (384-bit)", nameof(key)); + var s = String.Join("", key.Select(x => x.ToString("X2"))); + ExecuteScalar("pragma key = \"x'" + s + "'\""); } /// /// Change the encryption key for a SQLCipher database with "pragma rekey = ...". /// /// Encryption key plain text that is converted to the real encryption key using PBKDF2 key derivation - public void ReKey (string key) + public void ReKey(string key) { if (key == null) throw new ArgumentNullException(nameof(key)); @@ -505,12 +516,12 @@ public void ReKey (string key) /// Change the encryption key for a SQLCipher database. /// /// 256-bit (32 byte) or 384-bit (48 bytes) encryption key data - public void ReKey (byte[] key) + public void ReKey(byte[] key) { if (key == null) throw new ArgumentNullException(nameof(key)); if (key.Length != 32 && key.Length != 48) - throw new ArgumentException ("Key must be 32 bytes (256-bit) or 48 bytes (384-bit)", nameof (key)); + throw new ArgumentException("Key must be 32 bytes (256-bit) or 48 bytes (384-bit)", nameof(key)); var s = String.Join("", key.Select(x => x.ToString("X2"))); ExecuteScalar("pragma rekey = \"x'" + s + "'\""); } @@ -518,20 +529,21 @@ public void ReKey (byte[] key) /// /// Enable or disable extension loading. /// - public void EnableLoadExtension (bool enabled) + public void EnableLoadExtension(bool enabled) { - SQLite3.Result r = SQLite3.EnableLoadExtension (Handle, enabled ? 1 : 0); - if (r != SQLite3.Result.OK) { - string msg = SQLite3.GetErrmsg (Handle); - throw SQLiteException.New (r, msg); + SQLite3.Result r = SQLite3.EnableLoadExtension(Handle, enabled ? 1 : 0); + if (r != SQLite3.Result.OK) + { + string msg = SQLite3.GetErrmsg(Handle); + throw SQLiteException.New(r, msg); } } #if !USE_SQLITEPCL_RAW - static byte[] GetNullTerminatedUtf8 (string s) + static byte[] GetNullTerminatedUtf8(string s) { - var utf8Length = System.Text.Encoding.UTF8.GetByteCount (s); - var bytes = new byte [utf8Length + 1]; + var utf8Length = System.Text.Encoding.UTF8.GetByteCount(s); + var bytes = new byte[utf8Length + 1]; utf8Length = System.Text.Encoding.UTF8.GetBytes(s, 0, s.Length, bytes, 0); return bytes; } @@ -541,12 +553,15 @@ static byte[] GetNullTerminatedUtf8 (string s) /// 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 has accumulated. /// - public TimeSpan BusyTimeout { + public TimeSpan BusyTimeout + { get { return _busyTimeout; } - set { + set + { _busyTimeout = value; - if (Handle != NullHandle) { - SQLite3.BusyTimeout (Handle, (int)_busyTimeout.TotalMilliseconds); + if (Handle != NullHandle) + { + SQLite3.BusyTimeout(Handle, (int)_busyTimeout.TotalMilliseconds); } } } @@ -555,10 +570,13 @@ public TimeSpan BusyTimeout { /// Returns the mappings from types to tables that the connection /// currently understands. /// - public IEnumerable TableMappings { - get { - lock (_mappings) { - return new List (_mappings.Values); + public IEnumerable TableMappings + { + get + { + lock (_mappings) + { + return new List(_mappings.Values); } } } @@ -576,20 +594,29 @@ public IEnumerable TableMappings { /// The mapping represents the schema of the columns of the database and contains /// methods to set and get properties of objects. /// - public TableMapping GetMapping (Type type, CreateFlags createFlags = CreateFlags.None) + public TableMapping GetMapping(Type type, CreateFlags createFlags = CreateFlags.None) + { + return GetMapping(type, "", createFlags); + } + + public TableMapping GetMapping(Type type, string tableName, CreateFlags createFlags = CreateFlags.None) { TableMapping map; - var key = type.FullName; - lock (_mappings) { - if (_mappings.TryGetValue (key, out map)) { - if (createFlags != CreateFlags.None && createFlags != map.CreateFlags) { - map = new TableMapping (type, createFlags); + var key = string.IsNullOrEmpty(tableName) ? type.FullName : tableName; + lock (_mappings) + { + if (_mappings.TryGetValue(key, out map)) + { + if (createFlags != CreateFlags.None && createFlags != map.CreateFlags) + { + map = new TableMapping(type, createFlags, tableName); _mappings[key] = map; } } - else { - map = new TableMapping (type, createFlags); - _mappings.Add (key, map); + else + { + map = new TableMapping(type, createFlags, tableName); + _mappings.Add(key, map); } } return map; @@ -605,9 +632,14 @@ public TableMapping GetMapping (Type type, CreateFlags createFlags = CreateFlags /// The mapping represents the schema of the columns of the database and contains /// methods to set and get properties of objects. /// - public TableMapping GetMapping (CreateFlags createFlags = CreateFlags.None) + public TableMapping GetMapping(CreateFlags createFlags = CreateFlags.None) { - return GetMapping (typeof (T), createFlags); + return GetMapping(typeof(T), createFlags); + } + + public TableMapping GetMapping(string tableName, CreateFlags createFlags = CreateFlags.None) + { + return GetMapping(typeof(T), tableName, createFlags); } private struct IndexedColumn @@ -627,9 +659,9 @@ private struct IndexInfo /// /// Executes a "drop table" on the database. This is non-recoverable. /// - public int DropTable () + public int DropTable(string tableName = null) { - return DropTable (GetMapping (typeof (T))); + return DropTable(GetMapping(typeof(T), tableName)); } /// @@ -638,10 +670,10 @@ public int DropTable () /// /// The TableMapping used to identify the table. /// - public int DropTable (TableMapping map) + public int DropTable(TableMapping map) { - var query = string.Format ("drop table if exists \"{0}\"", map.TableName); - return Execute (query); + var query = string.Format("drop table if exists \"{0}\"", map.TableName); + return Execute(query); } /// @@ -653,9 +685,14 @@ public int DropTable (TableMapping map) /// /// Whether the table was created or migrated. /// - public CreateTableResult CreateTable (CreateFlags createFlags = CreateFlags.None) + public CreateTableResult CreateTable(CreateFlags createFlags = CreateFlags.None) + { + return CreateTable(typeof(T), createFlags); + } + + public CreateTableResult CreateTable(string tableName, CreateFlags createFlags = CreateFlags.None) { - return CreateTable (typeof (T), createFlags); + return CreateTable(typeof(T), tableName, createFlags); } /// @@ -669,21 +706,42 @@ public CreateTableResult CreateTable (CreateFlags createFlags = CreateFlags.N /// /// Whether the table was created or migrated. /// - public CreateTableResult CreateTable (Type ty, CreateFlags createFlags = CreateFlags.None) + public CreateTableResult CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None) + { + var map = GetMapping(ty, createFlags); + + // Present a nice error if no columns specified + if (map.Columns.Length == 0) + { + throw new Exception(string.Format("Cannot create a table without columns (does '{0}' have public properties?)", ty.FullName)); + } + + return CreateTable(map, createFlags); + } + + public CreateTableResult CreateTable(Type ty, string tableName, CreateFlags createFlags = CreateFlags.None) { - var map = GetMapping (ty, createFlags); + var map = GetMapping(ty, tableName, createFlags); // Present a nice error if no columns specified - if (map.Columns.Length == 0) { - throw new Exception (string.Format ("Cannot create a table without columns (does '{0}' have public properties?)", ty.FullName)); + if (map.Columns.Length == 0) + { + throw new Exception(string.Format("Cannot create a table without columns (does '{0}' have public properties?)", ty.FullName)); } + return CreateTable(map, createFlags); + } + + + private CreateTableResult CreateTable(TableMapping map, CreateFlags createFlags = CreateFlags.None) + { // Check if the table exists var result = CreateTableResult.Created; - var existingCols = GetTableInfo (map.TableName); + var existingCols = GetTableInfo(map.TableName); // Create or migrate it - if (existingCols.Count == 0) { + if (existingCols.Count == 0) + { // Facilitate virtual tables a.k.a. full-text search. bool fts3 = (createFlags & CreateFlags.FullTextSearch3) != 0; @@ -694,50 +752,58 @@ public CreateTableResult CreateTable (Type ty, CreateFlags createFlags = CreateF // Build query. var query = "create " + @virtual + "table if not exists \"" + map.TableName + "\" " + @using + "(\n"; - var decls = map.Columns.Select (p => Orm.SqlDecl (p, StoreDateTimeAsTicks, StoreTimeSpanAsTicks)); - var decl = string.Join (",\n", decls.ToArray ()); + var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks, StoreTimeSpanAsTicks)); + var decl = string.Join(",\n", decls.ToArray()); query += decl; query += ")"; - if (map.WithoutRowId) { + if (map.WithoutRowId) + { query += " without rowid"; } - Execute (query); + Execute(query); } - else { + else + { result = CreateTableResult.Migrated; - MigrateTable (map, existingCols); + MigrateTable(map, existingCols); } - var indexes = new Dictionary (); - foreach (var c in map.Columns) { - foreach (var i in c.Indices) { + var indexes = new Dictionary(); + foreach (var c in map.Columns) + { + foreach (var i in c.Indices) + { var iname = i.Name ?? map.TableName + "_" + c.Name; IndexInfo iinfo; - if (!indexes.TryGetValue (iname, out iinfo)) { - iinfo = new IndexInfo { + if (!indexes.TryGetValue(iname, out iinfo)) + { + iinfo = new IndexInfo + { IndexName = iname, TableName = map.TableName, Unique = i.Unique, - Columns = new List () + Columns = new List() }; - indexes.Add (iname, iinfo); + indexes.Add(iname, iinfo); } if (i.Unique != iinfo.Unique) - throw new Exception ("All the columns in an index must have the same value for their Unique property"); + throw new Exception("All the columns in an index must have the same value for their Unique property"); - iinfo.Columns.Add (new IndexedColumn { + iinfo.Columns.Add(new IndexedColumn + { Order = i.Order, ColumnName = c.Name }); } } - foreach (var indexName in indexes.Keys) { + foreach (var indexName in indexes.Keys) + { var index = indexes[indexName]; - var columns = index.Columns.OrderBy (i => i.Order).Select (i => i.ColumnName).ToArray (); - CreateIndex (indexName, index.TableName, columns, index.Unique); + var columns = index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray(); + CreateIndex(indexName, index.TableName, columns, index.Unique); } return result; @@ -752,11 +818,11 @@ public CreateTableResult CreateTable (Type ty, CreateFlags createFlags = CreateF /// /// Whether the table was created or migrated for each type. /// - public CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + public CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() { - return CreateTables (createFlags, typeof (T), typeof (T2)); + return CreateTables(createFlags, typeof(T), typeof(T2)); } /// @@ -768,12 +834,12 @@ public CreateTablesResult CreateTables (CreateFlags createFlags = CreateF /// /// Whether the table was created or migrated for each type. /// - public CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + public CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() where T3 : new() { - return CreateTables (createFlags, typeof (T), typeof (T2), typeof (T3)); + return CreateTables(createFlags, typeof(T), typeof(T2), typeof(T3)); } /// @@ -785,13 +851,13 @@ public CreateTablesResult CreateTables (CreateFlags createFlags = Cre /// /// Whether the table was created or migrated for each type. /// - public CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + public CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() where T3 : new() where T4 : new() { - return CreateTables (createFlags, typeof (T), typeof (T2), typeof (T3), typeof (T4)); + return CreateTables(createFlags, typeof(T), typeof(T2), typeof(T3), typeof(T4)); } /// @@ -803,14 +869,14 @@ public CreateTablesResult CreateTables (CreateFlags createFlags = /// /// Whether the table was created or migrated for each type. /// - public CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None) + public CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None) where T : new() where T2 : new() where T3 : new() where T4 : new() where T5 : new() { - return CreateTables (createFlags, typeof (T), typeof (T2), typeof (T3), typeof (T4), typeof (T5)); + return CreateTables(createFlags, typeof(T), typeof(T2), typeof(T3), typeof(T4), typeof(T5)); } /// @@ -822,11 +888,12 @@ public CreateTablesResult CreateTables (CreateFlags createFla /// /// Whether the table was created or migrated for each type. /// - public CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.None, params Type[] types) + public CreateTablesResult CreateTables(CreateFlags createFlags = CreateFlags.None, params Type[] types) { - var result = new CreateTablesResult (); - foreach (Type type in types) { - var aResult = CreateTable (type, createFlags); + var result = new CreateTablesResult(); + foreach (Type type in types) + { + var aResult = CreateTable(type, createFlags); result.Results[type] = aResult; } return result; @@ -840,11 +907,11 @@ public CreateTablesResult CreateTables (CreateFlags createFlags = CreateFlags.No /// An array of column names to index /// Whether the index should be unique /// Zero on success. - public int CreateIndex (string indexName, string tableName, string[] columnNames, bool unique = false) + public int CreateIndex(string indexName, string tableName, string[] columnNames, bool unique = false) { const string sqlFormat = "create {2} index if not exists \"{3}\" on \"{0}\"(\"{1}\")"; - var sql = String.Format (sqlFormat, tableName, string.Join ("\", \"", columnNames), unique ? "unique" : "", indexName); - return Execute (sql); + var sql = String.Format(sqlFormat, tableName, string.Join("\", \"", columnNames), unique ? "unique" : "", indexName); + return Execute(sql); } /// @@ -855,9 +922,9 @@ public int CreateIndex (string indexName, string tableName, string[] columnNames /// Name of the column to index /// Whether the index should be unique /// Zero on success. - public int CreateIndex (string indexName, string tableName, string columnName, bool unique = false) + public int CreateIndex(string indexName, string tableName, string columnName, bool unique = false) { - return CreateIndex (indexName, tableName, new string[] { columnName }, unique); + return CreateIndex(indexName, tableName, new string[] { columnName }, unique); } /// @@ -867,9 +934,9 @@ public int CreateIndex (string indexName, string tableName, string columnName, b /// Name of the column to index /// Whether the index should be unique /// Zero on success. - public int CreateIndex (string tableName, string columnName, bool unique = false) + public int CreateIndex(string tableName, string columnName, bool unique = false) { - return CreateIndex (tableName + "_" + columnName, tableName, columnName, unique); + return CreateIndex(tableName + "_" + columnName, tableName, columnName, unique); } /// @@ -879,9 +946,9 @@ public int CreateIndex (string tableName, string columnName, bool unique = false /// An array of column names to index /// Whether the index should be unique /// Zero on success. - public int CreateIndex (string tableName, string[] columnNames, bool unique = false) + public int CreateIndex(string tableName, string[] columnNames, bool unique = false) { - return CreateIndex (tableName + "_" + string.Join ("_", columnNames), tableName, columnNames, unique); + return CreateIndex(tableName + "_" + string.Join("_", columnNames), tableName, columnNames, unique); } /// @@ -892,34 +959,37 @@ public int CreateIndex (string tableName, string[] columnNames, bool unique = fa /// Property to index /// Whether the index should be unique /// Zero on success. - public int CreateIndex (Expression> property, bool unique = false) + public int CreateIndex(Expression> property, bool unique = false, string tableName = null) { MemberExpression mx; - if (property.Body.NodeType == ExpressionType.Convert) { + if (property.Body.NodeType == ExpressionType.Convert) + { mx = ((UnaryExpression)property.Body).Operand as MemberExpression; } - else { + else + { mx = (property.Body as MemberExpression); } var propertyInfo = mx.Member as PropertyInfo; - if (propertyInfo == null) { - throw new ArgumentException ("The lambda expression 'property' should point to a valid Property"); + if (propertyInfo == null) + { + throw new ArgumentException("The lambda expression 'property' should point to a valid Property"); } var propName = propertyInfo.Name; - var map = GetMapping (); - var colName = map.FindColumnWithPropertyName (propName).Name; + var map = GetMapping(tableName); + var colName = map.FindColumnWithPropertyName(propName).Name; - return CreateIndex (map.TableName, colName, unique); + return CreateIndex(map.TableName, colName, unique); } - [Preserve (AllMembers = true)] + [Preserve(AllMembers = true)] public class ColumnInfo { // public int cid { get; set; } - [Column ("name")] + [Column("name")] public string Name { get; set; } // [Column ("type")] @@ -931,7 +1001,7 @@ public class ColumnInfo // public int pk { get; set; } - public override string ToString () + public override string ToString() { return Name; } @@ -942,31 +1012,35 @@ public override string ToString () /// /// The columns contains in the table. /// Table name. - public List GetTableInfo (string tableName) + public List GetTableInfo(string tableName) { var query = "pragma table_info(\"" + tableName + "\")"; - return Query (query); + return Query(query); } - void MigrateTable (TableMapping map, List existingCols) + void MigrateTable(TableMapping map, List existingCols) { - var toBeAdded = new List (); + var toBeAdded = new List(); - foreach (var p in map.Columns) { + foreach (var p in map.Columns) + { var found = false; - foreach (var c in existingCols) { - found = (string.Compare (p.Name, c.Name, StringComparison.OrdinalIgnoreCase) == 0); + foreach (var c in existingCols) + { + found = (string.Compare(p.Name, c.Name, StringComparison.OrdinalIgnoreCase) == 0); if (found) break; } - if (!found) { - toBeAdded.Add (p); + if (!found) + { + toBeAdded.Add(p); } } - foreach (var p in toBeAdded) { - var addCol = "alter table \"" + map.TableName + "\" add column " + Orm.SqlDecl (p, StoreDateTimeAsTicks, StoreTimeSpanAsTicks); - Execute (addCol); + foreach (var p in toBeAdded) + { + var addCol = "alter table \"" + map.TableName + "\" add column " + Orm.SqlDecl(p, StoreDateTimeAsTicks, StoreTimeSpanAsTicks); + Execute(addCol); } } @@ -974,9 +1048,9 @@ void MigrateTable (TableMapping map, List existingCols) /// Creates a new SQLiteCommand. Can be overridden to provide a sub-class. /// /// - protected virtual SQLiteCommand NewCommand () + protected virtual SQLiteCommand NewCommand() { - return new SQLiteCommand (this); + return new SQLiteCommand(this); } /// @@ -992,15 +1066,16 @@ protected virtual SQLiteCommand NewCommand () /// /// A /// - public SQLiteCommand CreateCommand (string cmdText, params object[] ps) + public SQLiteCommand CreateCommand(string cmdText, params object[] ps) { if (!_open) - throw SQLiteException.New (SQLite3.Result.Error, "Cannot create commands from unopened database"); + throw SQLiteException.New(SQLite3.Result.Error, "Cannot create commands from unopened database"); - var cmd = NewCommand (); + var cmd = NewCommand(); cmd.CommandText = cmdText; - foreach (var o in ps) { - cmd.Bind (o); + foreach (var o in ps) + { + cmd.Bind(o); } return cmd; } @@ -1019,15 +1094,16 @@ public SQLiteCommand CreateCommand (string cmdText, params object[] ps) /// /// A /// - public SQLiteCommand CreateCommand (string cmdText, Dictionary args) + public SQLiteCommand CreateCommand(string cmdText, Dictionary args) { if (!_open) - throw SQLiteException.New (SQLite3.Result.Error, "Cannot create commands from unopened database"); + throw SQLiteException.New(SQLite3.Result.Error, "Cannot create commands from unopened database"); - SQLiteCommand cmd = NewCommand (); + SQLiteCommand cmd = NewCommand(); cmd.CommandText = cmdText; - foreach (var kv in args) { - cmd.Bind (kv.Key, kv.Value); + foreach (var kv in args) + { + cmd.Bind(kv.Key, kv.Value); } return cmd; } @@ -1049,24 +1125,27 @@ public SQLiteCommand CreateCommand (string cmdText, Dictionary a /// /// The number of rows modified in the database as a result of this execution. /// - public int Execute (string query, params object[] args) + public int Execute(string query, params object[] args) { - var cmd = CreateCommand (query, args); + var cmd = CreateCommand(query, args); - if (TimeExecution) { - if (_sw == null) { - _sw = new Stopwatch (); + if (TimeExecution) + { + if (_sw == null) + { + _sw = new Stopwatch(); } - _sw.Reset (); - _sw.Start (); + _sw.Reset(); + _sw.Start(); } - var r = cmd.ExecuteNonQuery (); + var r = cmd.ExecuteNonQuery(); - if (TimeExecution) { - _sw.Stop (); + if (TimeExecution) + { + _sw.Stop(); _elapsedMilliseconds += _sw.ElapsedMilliseconds; - Tracer?.Invoke (string.Format ("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0)); + Tracer?.Invoke(string.Format("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0)); } return r; @@ -1088,24 +1167,27 @@ public int Execute (string query, params object[] args) /// /// The number of rows modified in the database as a result of this execution. /// - public T ExecuteScalar (string query, params object[] args) + public T ExecuteScalar(string query, params object[] args) { - var cmd = CreateCommand (query, args); + var cmd = CreateCommand(query, args); - if (TimeExecution) { - if (_sw == null) { - _sw = new Stopwatch (); + if (TimeExecution) + { + if (_sw == null) + { + _sw = new Stopwatch(); } - _sw.Reset (); - _sw.Start (); + _sw.Reset(); + _sw.Start(); } - var r = cmd.ExecuteScalar (); + var r = cmd.ExecuteScalar(); - if (TimeExecution) { - _sw.Stop (); + if (TimeExecution) + { + _sw.Stop(); _elapsedMilliseconds += _sw.ElapsedMilliseconds; - Tracer?.Invoke (string.Format ("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0)); + Tracer?.Invoke(string.Format("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0)); } return r; @@ -1126,10 +1208,35 @@ public T ExecuteScalar (string query, params object[] args) /// /// An enumerable with one result for each row returned by the query. /// - public List Query (string query, params object[] args) where T : new() + public List Query(string query, params object[] args) where T : new() + { + var cmd = CreateCommand(query, args); + return cmd.ExecuteQuery(); + } + + /// + /// 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. + /// + /// + /// + /// The table name to use for the mapping. + /// + /// + /// The fully escaped SQL. + /// + /// + /// Arguments to substitute for the occurences of '?' in the query. + /// + /// + /// An enumerable with one result for each row returned by the query. + /// + public List Query(string tableName, string query, params object[] args) where T : new() { - var cmd = CreateCommand (query, args); - return cmd.ExecuteQuery (); + var cmd = CreateCommand(query, args); + return cmd.ExecuteQuery(tableName); } /// @@ -1146,10 +1253,10 @@ public T ExecuteScalar (string query, params object[] args) /// /// An enumerable with one result for the first column of each row returned by the query. /// - public List QueryScalars (string query, params object[] args) + public List QueryScalars(string query, params object[] args) { - var cmd = CreateCommand (query, args); - return cmd.ExecuteQueryScalars ().ToList (); + var cmd = CreateCommand(query, args); + return cmd.ExecuteQueryScalars().ToList(); } /// @@ -1170,10 +1277,10 @@ public List QueryScalars (string query, params object[] args) /// will call sqlite3_step on each call to MoveNext, so the database /// connection must remain open for the lifetime of the enumerator. /// - public IEnumerable DeferredQuery (string query, params object[] args) where T : new() + public IEnumerable DeferredQuery(string query, params object[] args) where T : new() { - var cmd = CreateCommand (query, args); - return cmd.ExecuteDeferredQuery (); + var cmd = CreateCommand(query, args); + return cmd.ExecuteDeferredQuery(); } /// @@ -1196,10 +1303,10 @@ public List QueryScalars (string query, params object[] args) /// /// An enumerable with one result for each row returned by the query. /// - public List Query (TableMapping map, string query, params object[] args) + public List Query(TableMapping map, string query, params object[] args) { - var cmd = CreateCommand (query, args); - return cmd.ExecuteQuery (map); + var cmd = CreateCommand(query, args); + return cmd.ExecuteQuery(map); } /// @@ -1225,10 +1332,10 @@ public List Query (TableMapping map, string query, params object[] args) /// will call sqlite3_step on each call to MoveNext, so the database /// connection must remain open for the lifetime of the enumerator. /// - public IEnumerable DeferredQuery (TableMapping map, string query, params object[] args) + public IEnumerable DeferredQuery(TableMapping map, string query, params object[] args) { - var cmd = CreateCommand (query, args); - return cmd.ExecuteDeferredQuery (map); + var cmd = CreateCommand(query, args); + return cmd.ExecuteDeferredQuery(map); } /// @@ -1238,9 +1345,9 @@ public IEnumerable DeferredQuery (TableMapping map, string query, params /// A queryable object that is able to translate Where, OrderBy, and Take /// queries into native SQL. /// - public TableQuery Table () where T : new() + public TableQuery Table(string tableName = null) where T : new() { - return new TableQuery (this); + return new TableQuery(this, tableName); } /// @@ -1255,10 +1362,10 @@ public IEnumerable DeferredQuery (TableMapping map, string query, params /// The object with the given primary key. Throws a not found exception /// if the object is not found. /// - public T Get (object pk) where T : new() + public T Get(object pk, string tableName = null) where T : new() { - var map = GetMapping (typeof (T)); - return Query (map.GetByPrimaryKeySql, pk).First (); + var map = GetMapping(typeof(T), tableName); + return Query(map.GetByPrimaryKeySql, pk).First(); } /// @@ -1276,9 +1383,9 @@ public IEnumerable DeferredQuery (TableMapping map, string query, params /// The object with the given primary key. Throws a not found exception /// if the object is not found. /// - public object Get (object pk, TableMapping map) + public object Get(object pk, TableMapping map) { - return Query (map, map.GetByPrimaryKeySql, pk).First (); + return Query(map, map.GetByPrimaryKeySql, pk).First(); } /// @@ -1292,9 +1399,9 @@ public object Get (object pk, TableMapping map) /// The object that matches the given predicate. Throws a not found exception /// if the object is not found. /// - public T Get (Expression> predicate) where T : new() + public T Get(Expression> predicate, string tableName = null) where T : new() { - return Table ().Where (predicate).First (); + return Table(tableName).Where(predicate).First(); } /// @@ -1309,10 +1416,10 @@ public object Get (object pk, TableMapping map) /// The object with the given primary key or null /// if the object is not found. /// - public T Find (object pk) where T : new() + public T Find(object pk, string tableName = null) where T : new() { - var map = GetMapping (typeof (T)); - return Query (map.GetByPrimaryKeySql, pk).FirstOrDefault (); + var map = GetMapping(tableName); + return Query(map.GetByPrimaryKeySql, pk).FirstOrDefault(); } /// @@ -1330,9 +1437,9 @@ public object Get (object pk, TableMapping map) /// The object with the given primary key or null /// if the object is not found. /// - public object Find (object pk, TableMapping map) + public object Find(object pk, TableMapping map) { - return Query (map, map.GetByPrimaryKeySql, pk).FirstOrDefault (); + return Query(map, map.GetByPrimaryKeySql, pk).FirstOrDefault(); } /// @@ -1346,15 +1453,37 @@ public object Find (object pk, TableMapping map) /// The object that matches the given predicate or null /// if the object is not found. /// - public T Find (Expression> predicate) where T : new() + public T Find(Expression> predicate, string tableName = null) where T : new() + { + return Table(tableName).Where(predicate).FirstOrDefault(); + } + + /// + /// Attempts to retrieve the first object that matches the query from the table + /// associated with the specified type. + /// + /// + /// The fully escaped SQL. + /// + /// + /// Arguments to substitute for the occurences of '?' in the query. + /// + /// + /// The object that matches the given predicate or null + /// if the object is not found. + /// + public T FindWithQuery(string query, params object[] args) where T : new() { - return Table ().Where (predicate).FirstOrDefault (); + return Query(query, args).FirstOrDefault(); } /// /// Attempts to retrieve the first object that matches the query from the table /// associated with the specified type. /// + /// /// + /// The name of the table. + /// /// /// The fully escaped SQL. /// @@ -1365,9 +1494,9 @@ public object Find (object pk, TableMapping map) /// The object that matches the given predicate or null /// if the object is not found. /// - public T FindWithQuery (string query, params object[] args) where T : new() + public T FindWithQuery(string tableName, string query, params object[] args) where T : new() { - return Query (query, args).FirstOrDefault (); + return Query(tableName, query, args).FirstOrDefault(); } /// @@ -1387,15 +1516,16 @@ public object Find (object pk, TableMapping map) /// The object that matches the given predicate or null /// if the object is not found. /// - public object FindWithQuery (TableMapping map, string query, params object[] args) + public object FindWithQuery(TableMapping map, string query, params object[] args) { - return Query (map, query, args).FirstOrDefault (); + return Query(map, query, args).FirstOrDefault(); } /// /// Whether has been called and the database is waiting for a . /// - public bool IsInTransaction { + public bool IsInTransaction + { get { return _transactionDepth > 0; } } @@ -1403,7 +1533,7 @@ public bool IsInTransaction { /// Begins a new transaction. Call to end the transaction. /// /// Throws if a transaction has already begun. - public void BeginTransaction () + public void BeginTransaction() { // The BEGIN command only works if the transaction stack is empty, // or in other words if there are no pending transactions. @@ -1411,38 +1541,45 @@ public void BeginTransaction () // then the command fails with an error. // Rather than crash with an error, we will just ignore calls to BeginTransaction // that would result in an error. - if (Interlocked.CompareExchange (ref _transactionDepth, 1, 0) == 0) { - try { - Execute ("begin transaction"); + if (Interlocked.CompareExchange(ref _transactionDepth, 1, 0) == 0) + { + try + { + Execute("begin transaction"); } - catch (Exception ex) { + catch (Exception ex) + { var sqlExp = ex as SQLiteException; - if (sqlExp != null) { + if (sqlExp != null) + { // It is recommended that applications respond to the errors listed below // by explicitly issuing a ROLLBACK command. // TODO: This rollback failsafe should be localized to all throw sites. - switch (sqlExp.Result) { + switch (sqlExp.Result) + { case SQLite3.Result.IOError: case SQLite3.Result.Full: case SQLite3.Result.Busy: case SQLite3.Result.NoMem: case SQLite3.Result.Interrupt: - RollbackTo (null, true); + RollbackTo(null, true); break; } } - else { + else + { // Call decrement and not VolatileWrite in case we've already // created a transaction point in SaveTransactionPoint since the catch. - Interlocked.Decrement (ref _transactionDepth); + Interlocked.Decrement(ref _transactionDepth); } throw; } } - else { + else + { // Calling BeginTransaction on an already open transaction is invalid - throw new InvalidOperationException ("Cannot begin a transaction while already in a transaction."); + throw new InvalidOperationException("Cannot begin a transaction while already in a transaction."); } } @@ -1455,32 +1592,37 @@ public void BeginTransaction () /// Call to end the transaction, committing all changes. /// /// A string naming the savepoint. - public string SaveTransactionPoint () + public string SaveTransactionPoint() { - int depth = Interlocked.Increment (ref _transactionDepth) - 1; - string retVal = "S" + _rand.Next (short.MaxValue) + "D" + depth; + int depth = Interlocked.Increment(ref _transactionDepth) - 1; + string retVal = "S" + _rand.Next(short.MaxValue) + "D" + depth; - try { - Execute ("savepoint " + retVal); + try + { + Execute("savepoint " + retVal); } - catch (Exception ex) { + catch (Exception ex) + { var sqlExp = ex as SQLiteException; - if (sqlExp != null) { + if (sqlExp != null) + { // It is recommended that applications respond to the errors listed below // by explicitly issuing a ROLLBACK command. // TODO: This rollback failsafe should be localized to all throw sites. - switch (sqlExp.Result) { + switch (sqlExp.Result) + { case SQLite3.Result.IOError: case SQLite3.Result.Full: case SQLite3.Result.Busy: case SQLite3.Result.NoMem: case SQLite3.Result.Interrupt: - RollbackTo (null, true); + RollbackTo(null, true); break; } } - else { - Interlocked.Decrement (ref _transactionDepth); + else + { + Interlocked.Decrement(ref _transactionDepth); } throw; @@ -1492,18 +1634,18 @@ public string SaveTransactionPoint () /// /// Rolls back the transaction that was begun by or . /// - public void Rollback () + public void Rollback() { - RollbackTo (null, false); + RollbackTo(null, false); } /// /// Rolls back the savepoint created by or SaveTransactionPoint. /// /// The name of the savepoint to roll back to, as returned by . If savepoint is null or empty, this method is equivalent to a call to - public void RollbackTo (string savepoint) + public void RollbackTo(string savepoint) { - RollbackTo (savepoint, false); + RollbackTo(savepoint, false); } /// @@ -1511,21 +1653,26 @@ public void RollbackTo (string savepoint) /// /// The name of the savepoint to roll back to, as returned by . If savepoint is null or empty, this method is equivalent to a call to /// true to avoid throwing exceptions, false otherwise - void RollbackTo (string savepoint, bool noThrow) + void RollbackTo(string savepoint, bool noThrow) { // Rolling back without a TO clause rolls backs all transactions // and leaves the transaction stack empty. - try { - if (String.IsNullOrEmpty (savepoint)) { - if (Interlocked.Exchange (ref _transactionDepth, 0) > 0) { - Execute ("rollback"); + try + { + if (String.IsNullOrEmpty(savepoint)) + { + if (Interlocked.Exchange(ref _transactionDepth, 0) > 0) + { + Execute("rollback"); } } - else { - DoSavePointExecute (savepoint, "rollback to "); + else + { + DoSavePointExecute(savepoint, "rollback to "); } } - catch (SQLiteException) { + catch (SQLiteException) + { if (!noThrow) throw; @@ -1541,21 +1688,26 @@ void RollbackTo (string savepoint, bool noThrow) /// The RELEASE command is like a COMMIT for a SAVEPOINT. /// /// The name of the savepoint to release. The string should be the result of a call to - public void Release (string savepoint) + public void Release(string savepoint) { - try { - DoSavePointExecute (savepoint, "release "); + try + { + DoSavePointExecute(savepoint, "release "); } - catch (SQLiteException ex) { - if (ex.Result == SQLite3.Result.Busy) { + catch (SQLiteException ex) + { + if (ex.Result == SQLite3.Result.Busy) + { // Force a rollback since most people don't know this function can fail // Don't call Rollback() since the _transactionDepth is 0 and it won't try // Calling rollback makes our _transactionDepth variable correct. // Writes to the database only happen at depth=0, so this failure will only happen then. - try { - Execute ("rollback"); + try + { + Execute("rollback"); } - catch { + catch + { // rollback can fail in all sorts of wonderful version-dependent ways. Let's just hope for the best } } @@ -1563,48 +1715,56 @@ public void Release (string savepoint) } } - void DoSavePointExecute (string savepoint, string cmd) + void DoSavePointExecute(string savepoint, string cmd) { // Validate the savepoint - int firstLen = savepoint.IndexOf ('D'); - if (firstLen >= 2 && savepoint.Length > firstLen + 1) { + int firstLen = savepoint.IndexOf('D'); + if (firstLen >= 2 && savepoint.Length > firstLen + 1) + { int depth; - if (Int32.TryParse (savepoint.Substring (firstLen + 1), out depth)) { + if (Int32.TryParse(savepoint.Substring(firstLen + 1), out depth)) + { // TODO: Mild race here, but inescapable without locking almost everywhere. - if (0 <= depth && depth < _transactionDepth) { + if (0 <= depth && depth < _transactionDepth) + { #if NETFX_CORE || USE_SQLITEPCL_RAW || NETCORE Volatile.Write (ref _transactionDepth, depth); #elif SILVERLIGHT _transactionDepth = depth; #else - Thread.VolatileWrite (ref _transactionDepth, depth); + Thread.VolatileWrite(ref _transactionDepth, depth); #endif - Execute (cmd + savepoint); + Execute(cmd + savepoint); return; } } } - throw new ArgumentException ("savePoint is not valid, and should be the result of a call to SaveTransactionPoint.", "savePoint"); + throw new ArgumentException("savePoint is not valid, and should be the result of a call to SaveTransactionPoint.", "savePoint"); } /// /// Commits the transaction that was begun by . /// - public void Commit () + public void Commit() { - if (Interlocked.Exchange (ref _transactionDepth, 0) != 0) { - try { - Execute ("commit"); + if (Interlocked.Exchange(ref _transactionDepth, 0) != 0) + { + try + { + Execute("commit"); } - catch { + catch + { // Force a rollback since most people don't know this function can fail // Don't call Rollback() since the _transactionDepth is 0 and it won't try // Calling rollback makes our _transactionDepth variable correct. - try { - Execute ("rollback"); + try + { + Execute("rollback"); } - catch { + catch + { // rollback can fail in all sorts of wonderful version-dependent ways. Let's just hope for the best } throw; @@ -1623,15 +1783,17 @@ public void Commit () /// of operations on the connection but should never call or /// . /// - public void RunInTransaction (Action action) + public void RunInTransaction(Action action) { - try { - var savePoint = SaveTransactionPoint (); - action (); - Release (savePoint); + try + { + var savePoint = SaveTransactionPoint(); + action(); + Release(savePoint); } - catch (Exception) { - Rollback (); + catch (Exception) + { + Rollback(); throw; } } @@ -1647,19 +1809,24 @@ public void RunInTransaction (Action action) /// /// The number of rows added to the table. /// - public int InsertAll (System.Collections.IEnumerable objects, bool runInTransaction = true) + public int InsertAll(System.Collections.IEnumerable objects, bool runInTransaction = true) { var c = 0; - if (runInTransaction) { - RunInTransaction (() => { - foreach (var r in objects) { - c += Insert (r); + if (runInTransaction) + { + RunInTransaction(() => + { + foreach (var r in objects) + { + c += Insert(r); } }); } - else { - foreach (var r in objects) { - c += Insert (r); + else + { + foreach (var r in objects) + { + c += Insert(r); } } return c; @@ -1680,19 +1847,24 @@ public int InsertAll (System.Collections.IEnumerable objects, bool runInTransact /// /// The number of rows added to the table. /// - public int InsertAll (System.Collections.IEnumerable objects, string extra, bool runInTransaction = true) + public int InsertAll(System.Collections.IEnumerable objects, string extra, bool runInTransaction = true) { var c = 0; - if (runInTransaction) { - RunInTransaction (() => { - foreach (var r in objects) { - c += Insert (r, extra); + if (runInTransaction) + { + RunInTransaction(() => + { + foreach (var r in objects) + { + c += Insert(r, extra); } }); } - else { - foreach (var r in objects) { - c += Insert (r, extra); + else + { + foreach (var r in objects) + { + c += Insert(r, extra); } } return c; @@ -1713,19 +1885,24 @@ public int InsertAll (System.Collections.IEnumerable objects, string extra, bool /// /// The number of rows added to the table. /// - public int InsertAll (System.Collections.IEnumerable objects, Type objType, bool runInTransaction = true) + public int InsertAll(System.Collections.IEnumerable objects, Type objType, bool runInTransaction = true) { var c = 0; - if (runInTransaction) { - RunInTransaction (() => { - foreach (var r in objects) { - c += Insert (r, objType); + if (runInTransaction) + { + RunInTransaction(() => + { + foreach (var r in objects) + { + c += Insert(r, objType); } }); } - else { - foreach (var r in objects) { - c += Insert (r, objType); + else + { + foreach (var r in objects) + { + c += Insert(r, objType); } } return c; @@ -1742,12 +1919,13 @@ public int InsertAll (System.Collections.IEnumerable objects, Type objType, bool /// /// The number of rows added to the table. /// - public int Insert (object obj) + public int Insert(object obj, string tableName = null) { - if (obj == null) { + if (obj == null) + { return 0; } - return Insert (obj, "", Orm.GetType (obj)); + return Insert(obj, "", Orm.GetType(obj), tableName); } /// @@ -1764,12 +1942,13 @@ public int Insert (object obj) /// /// The number of rows modified. /// - public int InsertOrReplace (object obj) + public int InsertOrReplace(object obj, string tableName = null) { - if (obj == null) { + if (obj == null) + { return 0; } - return Insert (obj, "OR REPLACE", Orm.GetType (obj)); + return Insert(obj, "OR REPLACE", Orm.GetType(obj), tableName); } /// @@ -1786,9 +1965,9 @@ public int InsertOrReplace (object obj) /// /// The number of rows added to the table. /// - public int Insert (object obj, Type objType) + public int Insert(object obj, Type objType, string tableName = null) { - return Insert (obj, "", objType); + return Insert(obj, "", objType, tableName); } /// @@ -1808,9 +1987,9 @@ public int Insert (object obj, Type objType) /// /// The number of rows modified. /// - public int InsertOrReplace (object obj, Type objType) + public int InsertOrReplace(object obj, Type objType, string tableName = null) { - return Insert (obj, "OR REPLACE", objType); + return Insert(obj, "OR REPLACE", objType, tableName); } /// @@ -1827,12 +2006,13 @@ public int InsertOrReplace (object obj, Type objType) /// /// The number of rows added to the table. /// - public int Insert (object obj, string extra) + public int Insert(object obj, string extra, string tableName = null) { - if (obj == null) { + if (obj == null) + { return 0; } - return Insert (obj, extra, Orm.GetType (obj)); + return Insert(obj, extra, Orm.GetType(obj), tableName); } /// @@ -1852,106 +2032,122 @@ public int Insert (object obj, string extra) /// /// The number of rows added to the table. /// - public int Insert (object obj, string extra, Type objType) + public int Insert(object obj, string extra, Type objType, string tableName = null) { - if (obj == null || objType == null) { + if (obj == null || objType == null) + { return 0; } - var map = GetMapping (objType); + var map = GetMapping(objType, tableName); - if (map.PK != null && map.PK.IsAutoGuid) { - if (map.PK.GetValue (obj).Equals (Guid.Empty)) { - map.PK.SetValue (obj, Guid.NewGuid ()); + if (map.PK != null && map.PK.IsAutoGuid) + { + if (map.PK.GetValue(obj).Equals(Guid.Empty)) + { + map.PK.SetValue(obj, Guid.NewGuid()); } } - var replacing = string.Compare (extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0; + var replacing = string.Compare(extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0; var cols = replacing ? map.InsertOrReplaceColumns : map.InsertColumns; var vals = new object[cols.Length]; - for (var i = 0; i < vals.Length; i++) { - vals[i] = cols[i].GetValue (obj); + for (var i = 0; i < vals.Length; i++) + { + vals[i] = cols[i].GetValue(obj); } - var insertCmd = GetInsertCommand (map, extra); + var insertCmd = GetInsertCommand(map, extra); int count; - lock (insertCmd) { + lock (insertCmd) + { // We lock here to protect the prepared statement returned via GetInsertCommand. // A SQLite prepared statement can be bound for only one operation at a time. - try { - count = insertCmd.ExecuteNonQuery (vals); + try + { + count = insertCmd.ExecuteNonQuery(vals); } - catch (SQLiteException ex) { - if (SQLite3.ExtendedErrCode (this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) { - throw NotNullConstraintViolationException.New (ex.Result, ex.Message, map, obj); + catch (SQLiteException ex) + { + if (SQLite3.ExtendedErrCode(this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) + { + throw NotNullConstraintViolationException.New(ex.Result, ex.Message, map, obj); } throw; } - if (map.HasAutoIncPK) { - var id = SQLite3.LastInsertRowid (Handle); - map.SetAutoIncPK (obj, id); + if (map.HasAutoIncPK) + { + var id = SQLite3.LastInsertRowid(Handle); + map.SetAutoIncPK(obj, id); } } if (count > 0) - OnTableChanged (map, NotifyTableChangedAction.Insert); + OnTableChanged(map, NotifyTableChangedAction.Insert); return count; } - readonly Dictionary, PreparedSqlLiteInsertCommand> _insertCommandMap = new Dictionary, PreparedSqlLiteInsertCommand> (); + readonly Dictionary, PreparedSqlLiteInsertCommand> _insertCommandMap = new Dictionary, PreparedSqlLiteInsertCommand>(); - PreparedSqlLiteInsertCommand GetInsertCommand (TableMapping map, string extra) + PreparedSqlLiteInsertCommand GetInsertCommand(TableMapping map, string extra) { PreparedSqlLiteInsertCommand prepCmd; - var key = Tuple.Create (map.MappedType.FullName, extra); + var key = Tuple.Create(map.TableName, extra); - lock (_insertCommandMap) { - if (_insertCommandMap.TryGetValue (key, out prepCmd)) { + lock (_insertCommandMap) + { + if (_insertCommandMap.TryGetValue(key, out prepCmd)) + { return prepCmd; } } - prepCmd = CreateInsertCommand (map, extra); + prepCmd = CreateInsertCommand(map, extra); - lock (_insertCommandMap) { - if (_insertCommandMap.TryGetValue (key, out var existing)) { - prepCmd.Dispose (); + lock (_insertCommandMap) + { + if (_insertCommandMap.TryGetValue(key, out var existing)) + { + prepCmd.Dispose(); return existing; } - _insertCommandMap.Add (key, prepCmd); + _insertCommandMap.Add(key, prepCmd); } return prepCmd; } - PreparedSqlLiteInsertCommand CreateInsertCommand (TableMapping map, string extra) + PreparedSqlLiteInsertCommand CreateInsertCommand(TableMapping map, string extra) { var cols = map.InsertColumns; string insertSql; - if (cols.Length == 0 && map.Columns.Length == 1 && map.Columns[0].IsAutoInc) { - insertSql = string.Format ("insert {1} into \"{0}\" default values", map.TableName, extra); + if (cols.Length == 0 && map.Columns.Length == 1 && map.Columns[0].IsAutoInc) + { + insertSql = string.Format("insert {1} into \"{0}\" default values", map.TableName, extra); } - else { - var replacing = string.Compare (extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0; + else + { + var replacing = string.Compare(extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0; - if (replacing) { + if (replacing) + { cols = map.InsertOrReplaceColumns; } - insertSql = string.Format ("insert {3} into \"{0}\"({1}) values ({2})", map.TableName, - string.Join (",", (from c in cols - select "\"" + c.Name + "\"").ToArray ()), - string.Join (",", (from c in cols - select "?").ToArray ()), extra); + insertSql = string.Format("insert {3} into \"{0}\"({1}) values ({2})", map.TableName, + string.Join(",", (from c in cols + select "\"" + c.Name + "\"").ToArray()), + string.Join(",", (from c in cols + select "?").ToArray()), extra); } - var insertCommand = new PreparedSqlLiteInsertCommand (this, insertSql); + var insertCommand = new PreparedSqlLiteInsertCommand(this, insertSql); return insertCommand; } @@ -1966,12 +2162,13 @@ PreparedSqlLiteInsertCommand CreateInsertCommand (TableMapping map, string extra /// /// The number of rows updated. /// - public int Update (object obj) + public int Update(object obj, string tableName = null) { - if (obj == null) { + if (obj == null) + { return 0; } - return Update (obj, Orm.GetType (obj)); + return Update(obj, Orm.GetType(obj), tableName); } /// @@ -1988,53 +2185,59 @@ public int Update (object obj) /// /// The number of rows updated. /// - public int Update (object obj, Type objType) + public int Update(object obj, Type objType, string tableName = null) { int rowsAffected = 0; - if (obj == null || objType == null) { + if (obj == null || objType == null) + { return 0; } - var map = GetMapping (objType); + var map = GetMapping(objType, tableName); var pk = map.PK; - if (pk == null) { - throw new NotSupportedException ("Cannot update " + map.TableName + ": it has no PK"); + if (pk == null) + { + throw new NotSupportedException("Cannot update " + map.TableName + ": it has no PK"); } var cols = from p in map.Columns where p != pk select p; var vals = from c in cols - select c.GetValue (obj); - var ps = new List (vals); - if (ps.Count == 0) { + select c.GetValue(obj); + var ps = new List(vals); + if (ps.Count == 0) + { // There is a PK but no accompanying data, // so reset the PK to make the UPDATE work. cols = map.Columns; vals = from c in cols - select c.GetValue (obj); - ps = new List (vals); + select c.GetValue(obj); + ps = new List(vals); } - ps.Add (pk.GetValue (obj)); - var q = string.Format ("update \"{0}\" set {1} where \"{2}\" = ? ", map.TableName, string.Join (",", (from c in cols - select "\"" + c.Name + "\" = ? ").ToArray ()), pk.Name); + ps.Add(pk.GetValue(obj)); + var q = string.Format("update \"{0}\" set {1} where \"{2}\" = ? ", map.TableName, string.Join(",", (from c in cols + select "\"" + c.Name + "\" = ? ").ToArray()), pk.Name); - try { - rowsAffected = Execute (q, ps.ToArray ()); + try + { + rowsAffected = Execute(q, ps.ToArray()); } - catch (SQLiteException ex) { + catch (SQLiteException ex) + { - if (ex.Result == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode (this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) { - throw NotNullConstraintViolationException.New (ex, map, obj); + if (ex.Result == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode(this.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) + { + throw NotNullConstraintViolationException.New(ex, map, obj); } throw; } if (rowsAffected > 0) - OnTableChanged (map, NotifyTableChangedAction.Update); + OnTableChanged(map, NotifyTableChangedAction.Update); return rowsAffected; } @@ -2051,19 +2254,24 @@ public int Update (object obj, Type objType) /// /// The number of rows modified. /// - public int UpdateAll (System.Collections.IEnumerable objects, bool runInTransaction = true) + public int UpdateAll(System.Collections.IEnumerable objects, bool runInTransaction = true) { var c = 0; - if (runInTransaction) { - RunInTransaction (() => { - foreach (var r in objects) { - c += Update (r); + if (runInTransaction) + { + RunInTransaction(() => + { + foreach (var r in objects) + { + c += Update(r); } }); } - else { - foreach (var r in objects) { - c += Update (r); + else + { + foreach (var r in objects) + { + c += Update(r); } } return c; @@ -2078,17 +2286,18 @@ public int UpdateAll (System.Collections.IEnumerable objects, bool runInTransact /// /// The number of rows deleted. /// - public int Delete (object objectToDelete) + public int Delete(object objectToDelete, string tableName = null) { - var map = GetMapping (Orm.GetType (objectToDelete)); + var map = GetMapping(Orm.GetType(objectToDelete), tableName); var pk = map.PK; - if (pk == null) { - throw new NotSupportedException ("Cannot delete " + map.TableName + ": it has no PK"); + if (pk == null) + { + throw new NotSupportedException("Cannot delete " + map.TableName + ": it has no PK"); } - var q = string.Format ("delete from \"{0}\" where \"{1}\" = ?", map.TableName, pk.Name); - var count = Execute (q, pk.GetValue (objectToDelete)); + var q = string.Format("delete from \"{0}\" where \"{1}\" = ?", map.TableName, pk.Name); + var count = Execute(q, pk.GetValue(objectToDelete)); if (count > 0) - OnTableChanged (map, NotifyTableChangedAction.Delete); + OnTableChanged(map, NotifyTableChangedAction.Delete); return count; } @@ -2104,9 +2313,9 @@ public int Delete (object objectToDelete) /// /// The type of object. /// - public int Delete (object primaryKey) + public int Delete(object primaryKey, string tableName = null) { - return Delete (primaryKey, GetMapping (typeof (T))); + return Delete(primaryKey, GetMapping(tableName)); } /// @@ -2121,16 +2330,17 @@ public int Delete (object primaryKey) /// /// The number of objects deleted. /// - public int Delete (object primaryKey, TableMapping map) + public int Delete(object primaryKey, TableMapping map) { var pk = map.PK; - if (pk == null) { - throw new NotSupportedException ("Cannot delete " + map.TableName + ": it has no PK"); + if (pk == null) + { + throw new NotSupportedException("Cannot delete " + map.TableName + ": it has no PK"); } - var q = string.Format ("delete from \"{0}\" where \"{1}\" = ?", map.TableName, pk.Name); - var count = Execute (q, primaryKey); + var q = string.Format("delete from \"{0}\" where \"{1}\" = ?", map.TableName, pk.Name); + var count = Execute(q, primaryKey); if (count > 0) - OnTableChanged (map, NotifyTableChangedAction.Delete); + OnTableChanged(map, NotifyTableChangedAction.Delete); return count; } @@ -2145,10 +2355,10 @@ public int Delete (object primaryKey, TableMapping map) /// /// The type of objects to delete. /// - public int DeleteAll () + public int DeleteAll(string tableName = null) { - var map = GetMapping (typeof (T)); - return DeleteAll (map); + var map = GetMapping(tableName); + return DeleteAll(map); } /// @@ -2162,12 +2372,12 @@ public int DeleteAll () /// /// The number of objects deleted. /// - public int DeleteAll (TableMapping map) + public int DeleteAll(TableMapping map) { - var query = string.Format ("delete from \"{0}\"", map.TableName); - var count = Execute (query); + var query = string.Format("delete from \"{0}\"", map.TableName); + var count = Execute(query); if (count > 0) - OnTableChanged (map, NotifyTableChangedAction.Delete); + OnTableChanged(map, NotifyTableChangedAction.Delete); return count; } @@ -2176,91 +2386,103 @@ public int DeleteAll (TableMapping map) /// /// Path to backup file. /// The name of the database to backup (usually "main"). - public void Backup (string destinationDatabasePath, string databaseName = "main") + public void Backup(string destinationDatabasePath, string databaseName = "main") { // Open the destination - var r = SQLite3.Open (destinationDatabasePath, out var destHandle); - if (r != SQLite3.Result.OK) { - throw SQLiteException.New (r, "Failed to open destination database"); + var r = SQLite3.Open(destinationDatabasePath, out var destHandle); + if (r != SQLite3.Result.OK) + { + throw SQLiteException.New(r, "Failed to open destination database"); } // Init the backup - var backup = SQLite3.BackupInit (destHandle, databaseName, Handle, databaseName); - if (backup == NullBackupHandle) { - SQLite3.Close (destHandle); - throw new Exception ("Failed to create backup"); + var backup = SQLite3.BackupInit(destHandle, databaseName, Handle, databaseName); + if (backup == NullBackupHandle) + { + SQLite3.Close(destHandle); + throw new Exception("Failed to create backup"); } // Perform it - SQLite3.BackupStep (backup, -1); - SQLite3.BackupFinish (backup); + SQLite3.BackupStep(backup, -1); + SQLite3.BackupFinish(backup); // Check for errors - r = SQLite3.GetResult (destHandle); + r = SQLite3.GetResult(destHandle); string msg = ""; - if (r != SQLite3.Result.OK) { - msg = SQLite3.GetErrmsg (destHandle); + if (r != SQLite3.Result.OK) + { + msg = SQLite3.GetErrmsg(destHandle); } // Close everything and report errors - SQLite3.Close (destHandle); - if (r != SQLite3.Result.OK) { - throw SQLiteException.New (r, msg); + SQLite3.Close(destHandle); + if (r != SQLite3.Result.OK) + { + throw SQLiteException.New(r, msg); } } - ~SQLiteConnection () + ~SQLiteConnection() { - Dispose (false); + Dispose(false); } - public void Dispose () + public void Dispose() { - Dispose (true); - GC.SuppressFinalize (this); + Dispose(true); + GC.SuppressFinalize(this); } - public void Close () + public void Close() { - Dispose (true); + Dispose(true); } - protected virtual void Dispose (bool disposing) + protected virtual void Dispose(bool disposing) { var useClose2 = LibVersionNumber >= 3007014; - if (_open && Handle != NullHandle) { - try { - if (disposing) { - lock (_insertCommandMap) { - foreach (var sqlInsertCommand in _insertCommandMap.Values) { - sqlInsertCommand.Dispose (); + if (_open && Handle != NullHandle) + { + try + { + if (disposing) + { + lock (_insertCommandMap) + { + foreach (var sqlInsertCommand in _insertCommandMap.Values) + { + sqlInsertCommand.Dispose(); } - _insertCommandMap.Clear (); + _insertCommandMap.Clear(); } - var r = useClose2 ? SQLite3.Close2 (Handle) : SQLite3.Close (Handle); - if (r != SQLite3.Result.OK) { - string msg = SQLite3.GetErrmsg (Handle); - throw SQLiteException.New (r, msg); + var r = useClose2 ? SQLite3.Close2(Handle) : SQLite3.Close(Handle); + if (r != SQLite3.Result.OK) + { + string msg = SQLite3.GetErrmsg(Handle); + throw SQLiteException.New(r, msg); } } - else { - var r = useClose2 ? SQLite3.Close2 (Handle) : SQLite3.Close (Handle); + else + { + var r = useClose2 ? SQLite3.Close2(Handle) : SQLite3.Close(Handle); } } - finally { + finally + { Handle = NullHandle; _open = false; } } } - void OnTableChanged (TableMapping table, NotifyTableChangedAction action) + void OnTableChanged(TableMapping table, NotifyTableChangedAction action) { var ev = TableChanged; if (ev != null) - ev (this, new NotifyTableChangedEventArgs (table, action)); + ev(this, new NotifyTableChangedEventArgs(table, action)); } public event EventHandler TableChanged; @@ -2271,7 +2493,7 @@ public class NotifyTableChangedEventArgs : EventArgs public TableMapping Table { get; private set; } public NotifyTableChangedAction Action { get; private set; } - public NotifyTableChangedEventArgs (TableMapping table, NotifyTableChangedAction action) + public NotifyTableChangedEventArgs(TableMapping table, NotifyTableChangedAction action) { Table = table; Action = action; @@ -2334,8 +2556,8 @@ public static bool IsInMemoryPath(string databasePath) /// If you use DateTimeOffset properties, it will be always stored as ticks regardingless /// the storeDateTimeAsTicks parameter. /// - public SQLiteConnectionString (string databasePath, bool storeDateTimeAsTicks = true) - : this (databasePath, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite, storeDateTimeAsTicks) + public SQLiteConnectionString(string databasePath, bool storeDateTimeAsTicks = true) + : this(databasePath, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite, storeDateTimeAsTicks) { } @@ -2365,8 +2587,8 @@ public SQLiteConnectionString (string databasePath, bool storeDateTimeAsTicks = /// /// Specifies the Virtual File System to use on the database. /// - public SQLiteConnectionString (string databasePath, bool storeDateTimeAsTicks, object key = null, Action preKeyAction = null, Action postKeyAction = null, string vfsName = null) - : this (databasePath, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite, storeDateTimeAsTicks, key, preKeyAction, postKeyAction, vfsName) + public SQLiteConnectionString(string databasePath, bool storeDateTimeAsTicks, object key = null, Action preKeyAction = null, Action postKeyAction = null, string vfsName = null) + : this(databasePath, SQLiteOpenFlags.Create | SQLiteOpenFlags.ReadWrite, storeDateTimeAsTicks, key, preKeyAction, postKeyAction, vfsName) { } @@ -2408,16 +2630,16 @@ public SQLiteConnectionString (string databasePath, bool storeDateTimeAsTicks, o /// only here for backwards compatibility. There is a *significant* speed advantage, with no /// down sides, when setting storeTimeSpanAsTicks = true. /// - public SQLiteConnectionString (string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks, object key = null, Action preKeyAction = null, Action postKeyAction = null, string vfsName = null, string dateTimeStringFormat = DateTimeSqliteDefaultFormat, bool storeTimeSpanAsTicks = true) + public SQLiteConnectionString(string databasePath, SQLiteOpenFlags openFlags, bool storeDateTimeAsTicks, object key = null, Action preKeyAction = null, Action postKeyAction = null, string vfsName = null, string dateTimeStringFormat = DateTimeSqliteDefaultFormat, bool storeTimeSpanAsTicks = true) { if (key != null && !((key is byte[]) || (key is string))) - throw new ArgumentException ("Encryption keys must be strings or byte arrays", nameof (key)); + throw new ArgumentException("Encryption keys must be strings or byte arrays", nameof(key)); - UniqueKey = string.Format ("{0}_{1:X8}", databasePath, (uint)openFlags); + UniqueKey = string.Format("{0}_{1:X8}", databasePath, (uint)openFlags); StoreDateTimeAsTicks = storeDateTimeAsTicks; StoreTimeSpanAsTicks = storeTimeSpanAsTicks; DateTimeStringFormat = dateTimeStringFormat; - DateTimeStyle = "o".Equals (DateTimeStringFormat, StringComparison.OrdinalIgnoreCase) || "r".Equals (DateTimeStringFormat, StringComparison.OrdinalIgnoreCase) ? System.Globalization.DateTimeStyles.RoundtripKind : System.Globalization.DateTimeStyles.None; + DateTimeStyle = "o".Equals(DateTimeStringFormat, StringComparison.OrdinalIgnoreCase) || "r".Equals(DateTimeStringFormat, StringComparison.OrdinalIgnoreCase) ? System.Globalization.DateTimeStyles.RoundtripKind : System.Globalization.DateTimeStyles.None; Key = key; PreKeyAction = preKeyAction; PostKeyAction = postKeyAction; @@ -2435,7 +2657,7 @@ public SQLiteConnectionString (string databasePath, SQLiteOpenFlags openFlags, b } } - [AttributeUsage (AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Class)] public class TableAttribute : Attribute { public string Name { get; set; } @@ -2447,71 +2669,72 @@ public class TableAttribute : Attribute /// public bool WithoutRowId { get; set; } - public TableAttribute (string name) + public TableAttribute(string name) { Name = name; } } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class ColumnAttribute : UnityEngine.Scripting.PreserveAttribute { public string Name { get; set; } - public ColumnAttribute (string name) + public ColumnAttribute(string name) { Name = name; } } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class PrimaryKeyAttribute : UnityEngine.Scripting.PreserveAttribute { } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class AutoIncrementAttribute : UnityEngine.Scripting.PreserveAttribute { } - [AttributeUsage (AttributeTargets.Property, AllowMultiple = true)] + [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] public class IndexedAttribute : UnityEngine.Scripting.PreserveAttribute { public string Name { get; set; } public int Order { get; set; } public virtual bool Unique { get; set; } - public IndexedAttribute () + public IndexedAttribute() { } - public IndexedAttribute (string name, int order) + public IndexedAttribute(string name, int order) { Name = name; Order = order; } } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class IgnoreAttribute : Attribute { } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class UniqueAttribute : IndexedAttribute { - public override bool Unique { + public override bool Unique + { get { return true; } set { /* throw? */ } } } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class MaxLengthAttribute : UnityEngine.Scripting.PreserveAttribute { public int Value { get; private set; } - public MaxLengthAttribute (int length) + public MaxLengthAttribute(int length) { Value = length; } @@ -2528,23 +2751,23 @@ public sealed class PreserveAttribute : System.Attribute /// "BINARY", "NOCASE", and "RTRIM" are supported. /// "BINARY" is the default. /// - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class CollationAttribute : UnityEngine.Scripting.PreserveAttribute { public string Value { get; private set; } - public CollationAttribute (string collation) + public CollationAttribute(string collation) { Value = collation; } } - [AttributeUsage (AttributeTargets.Property)] + [AttributeUsage(AttributeTargets.Property)] public class NotNullAttribute : UnityEngine.Scripting.PreserveAttribute { } - [AttributeUsage (AttributeTargets.Enum)] + [AttributeUsage(AttributeTargets.Enum)] public class StoreAsTextAttribute : UnityEngine.Scripting.PreserveAttribute { } @@ -2571,60 +2794,66 @@ public class TableMapping readonly Column[] _insertColumns; readonly Column[] _insertOrReplaceColumns; - public TableMapping (Type type, CreateFlags createFlags = CreateFlags.None) + public TableMapping(Type type, CreateFlags createFlags = CreateFlags.None, string tableName = null) { MappedType = type; CreateFlags = createFlags; - var typeInfo = type.GetTypeInfo (); + var typeInfo = type.GetTypeInfo(); #if ENABLE_IL2CPP var tableAttr = typeInfo.GetCustomAttribute (); #else var tableAttr = typeInfo.CustomAttributes - .Where (x => x.AttributeType == typeof (TableAttribute)) - .Select (x => (TableAttribute)Orm.InflateAttribute (x)) - .FirstOrDefault (); + .Where(x => x.AttributeType == typeof(TableAttribute)) + .Select(x => (TableAttribute)Orm.InflateAttribute(x)) + .FirstOrDefault(); #endif - TableName = (tableAttr != null && !string.IsNullOrEmpty (tableAttr.Name)) ? tableAttr.Name : MappedType.Name; + tableName = string.IsNullOrEmpty(tableName) ? MappedType.Name : tableName; + TableName = (tableAttr != null && !string.IsNullOrEmpty(tableAttr.Name)) ? tableAttr.Name : tableName; WithoutRowId = tableAttr != null ? tableAttr.WithoutRowId : false; var members = GetPublicMembers(type); var cols = new List(members.Count); - foreach(var m in members) + foreach (var m in members) { var ignore = m.IsDefined(typeof(IgnoreAttribute), true); - if(!ignore) + if (!ignore) cols.Add(new Column(m, createFlags)); } - Columns = cols.ToArray (); - foreach (var c in Columns) { - if (c.IsAutoInc && c.IsPK) { + Columns = cols.ToArray(); + foreach (var c in Columns) + { + if (c.IsAutoInc && c.IsPK) + { _autoPk = c; } - if (c.IsPK) { + if (c.IsPK) + { PK = c; } } HasAutoIncPK = _autoPk != null; - if (PK != null) { - GetByPrimaryKeySql = string.Format ("select * from \"{0}\" where \"{1}\" = ?", TableName, PK.Name); + if (PK != null) + { + GetByPrimaryKeySql = string.Format("select * from \"{0}\" where \"{1}\" = ?", TableName, PK.Name); } - else { + else + { // People should not be calling Get/Find without a PK - GetByPrimaryKeySql = string.Format ("select * from \"{0}\" limit 1", TableName); + GetByPrimaryKeySql = string.Format("select * from \"{0}\" limit 1", TableName); } - _insertColumns = Columns.Where (c => !c.IsAutoInc).ToArray (); - _insertOrReplaceColumns = Columns.ToArray (); + _insertColumns = Columns.Where(c => !c.IsAutoInc).ToArray(); + _insertOrReplaceColumns = Columns.ToArray(); } private IReadOnlyCollection GetPublicMembers(Type type) { - if(type.Name.StartsWith("ValueTuple`")) + if (type.Name.StartsWith("ValueTuple`")) return GetFieldsFromValueTuple(type); var members = new List(); @@ -2645,12 +2874,12 @@ from p in ti.DeclaredProperties select p); members.AddRange(newMembers); - foreach(var m in newMembers) + foreach (var m in newMembers) memberNames.Add(m.Name); type = ti.BaseType; } - while(type != typeof(object)); + while (type != typeof(object)); return members; } @@ -2661,7 +2890,7 @@ private IReadOnlyCollection GetFieldsFromValueTuple(Type type) var fields = type.GetFields(); // https://docs.microsoft.com/en-us/dotnet/api/system.valuetuple-8.rest - if(fields.Length >= 8) + if (fields.Length >= 8) throw new NotSupportedException("ValueTuple with more than 7 members not supported due to nesting; see https://docs.microsoft.com/en-us/dotnet/api/system.valuetuple-8.rest"); return fields; @@ -2669,37 +2898,42 @@ private IReadOnlyCollection GetFieldsFromValueTuple(Type type) public bool HasAutoIncPK { get; private set; } - public void SetAutoIncPK (object obj, long id) + public void SetAutoIncPK(object obj, long id) { - if (_autoPk != null) { - _autoPk.SetValue (obj, Convert.ChangeType (id, _autoPk.ColumnType, null)); + if (_autoPk != null) + { + _autoPk.SetValue(obj, Convert.ChangeType(id, _autoPk.ColumnType, null)); } } - public Column[] InsertColumns { - get { + public Column[] InsertColumns + { + get + { return _insertColumns; } } - public Column[] InsertOrReplaceColumns { - get { + public Column[] InsertOrReplaceColumns + { + get + { return _insertOrReplaceColumns; } } - public Column FindColumnWithPropertyName (string propertyName) + public Column FindColumnWithPropertyName(string propertyName) { - var exact = Columns.FirstOrDefault (c => c.PropertyName == propertyName); + var exact = Columns.FirstOrDefault(c => c.PropertyName == propertyName); return exact; } - public Column FindColumn (string columnName) + public Column FindColumn(string columnName) { - if(Method != MapMethod.ByName) + if (Method != MapMethod.ByName) throw new InvalidOperationException($"This {nameof(TableMapping)} is not mapped by name, but {Method}."); - var exact = Columns.FirstOrDefault (c => c.Name.ToLower () == columnName.ToLower ()); + var exact = Columns.FirstOrDefault(c => c.Name.ToLower() == columnName.ToLower()); return exact; } @@ -2730,75 +2964,76 @@ public class Column public bool StoreAsText { get; private set; } - public Column (MemberInfo member, CreateFlags createFlags = CreateFlags.None) + public Column(MemberInfo member, CreateFlags createFlags = CreateFlags.None) { _member = member; var memberType = GetMemberType(member); - var colAttr = member.CustomAttributes.FirstOrDefault (x => x.AttributeType == typeof (ColumnAttribute)); + var colAttr = member.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(ColumnAttribute)); #if ENABLE_IL2CPP var ca = member.GetCustomAttribute(typeof(ColumnAttribute)) as ColumnAttribute; Name = ca == null ? member.Name : ca.Name; #else Name = (colAttr != null && colAttr.ConstructorArguments.Count > 0) ? - colAttr.ConstructorArguments[0].Value?.ToString () : + colAttr.ConstructorArguments[0].Value?.ToString() : member.Name; #endif //If this type is Nullable then Nullable.GetUnderlyingType returns the T, otherwise it returns null, so get the actual type instead - ColumnType = Nullable.GetUnderlyingType (memberType) ?? memberType; - Collation = Orm.Collation (member); + ColumnType = Nullable.GetUnderlyingType(memberType) ?? memberType; + Collation = Orm.Collation(member); - IsPK = Orm.IsPK (member) || + IsPK = Orm.IsPK(member) || (((createFlags & CreateFlags.ImplicitPK) == CreateFlags.ImplicitPK) && - string.Compare (member.Name, Orm.ImplicitPkName, StringComparison.OrdinalIgnoreCase) == 0); + string.Compare(member.Name, Orm.ImplicitPkName, StringComparison.OrdinalIgnoreCase) == 0); - var isAuto = Orm.IsAutoInc (member) || (IsPK && ((createFlags & CreateFlags.AutoIncPK) == CreateFlags.AutoIncPK)); - IsAutoGuid = isAuto && ColumnType == typeof (Guid); + var isAuto = Orm.IsAutoInc(member) || (IsPK && ((createFlags & CreateFlags.AutoIncPK) == CreateFlags.AutoIncPK)); + IsAutoGuid = isAuto && ColumnType == typeof(Guid); IsAutoInc = isAuto && !IsAutoGuid; - Indices = Orm.GetIndices (member); - if (!Indices.Any () + Indices = Orm.GetIndices(member); + if (!Indices.Any() && !IsPK && ((createFlags & CreateFlags.ImplicitIndex) == CreateFlags.ImplicitIndex) - && Name.EndsWith (Orm.ImplicitIndexSuffix, StringComparison.OrdinalIgnoreCase) - ) { - Indices = new IndexedAttribute[] { new IndexedAttribute () }; + && Name.EndsWith(Orm.ImplicitIndexSuffix, StringComparison.OrdinalIgnoreCase) + ) + { + Indices = new IndexedAttribute[] { new IndexedAttribute() }; } - IsNullable = !(IsPK || Orm.IsMarkedNotNull (member)); - MaxStringLength = Orm.MaxStringLength (member); + IsNullable = !(IsPK || Orm.IsMarkedNotNull(member)); + MaxStringLength = Orm.MaxStringLength(member); - StoreAsText = memberType.GetTypeInfo ().CustomAttributes.Any (x => x.AttributeType == typeof (StoreAsTextAttribute)); + StoreAsText = memberType.GetTypeInfo().CustomAttributes.Any(x => x.AttributeType == typeof(StoreAsTextAttribute)); } - public Column (PropertyInfo member, CreateFlags createFlags = CreateFlags.None) + public Column(PropertyInfo member, CreateFlags createFlags = CreateFlags.None) : this((MemberInfo)member, createFlags) { } - public void SetValue (object obj, object val) + public void SetValue(object obj, object val) { - if(_member is PropertyInfo propy) + if (_member is PropertyInfo propy) { - if (val != null && ColumnType.GetTypeInfo ().IsEnum) - propy.SetValue (obj, Enum.ToObject (ColumnType, val)); + if (val != null && ColumnType.GetTypeInfo().IsEnum) + propy.SetValue(obj, Enum.ToObject(ColumnType, val)); else - propy.SetValue (obj, val); + propy.SetValue(obj, val); } - else if(_member is FieldInfo field) + else if (_member is FieldInfo field) { - if (val != null && ColumnType.GetTypeInfo ().IsEnum) - field.SetValue (obj, Enum.ToObject (ColumnType, val)); + if (val != null && ColumnType.GetTypeInfo().IsEnum) + field.SetValue(obj, Enum.ToObject(ColumnType, val)); else - field.SetValue (obj, val); + field.SetValue(obj, val); } else throw new InvalidProgramException("unreachable condition"); } - public object GetValue (object obj) + public object GetValue(object obj) { - if(_member is PropertyInfo propy) + if (_member is PropertyInfo propy) return propy.GetValue(obj); - else if(_member is FieldInfo field) + else if (_member is FieldInfo field) return field.GetValue(obj); else throw new InvalidProgramException("unreachable condition"); @@ -2806,7 +3041,7 @@ public object GetValue (object obj) private static Type GetMemberType(MemberInfo m) { - switch(m.MemberType) + switch (m.MemberType) { case MemberTypes.Property: return ((PropertyInfo)m).PropertyType; case MemberTypes.Field: return ((FieldInfo)m).FieldType; @@ -2824,19 +3059,22 @@ internal enum MapMethod class EnumCacheInfo { - public EnumCacheInfo (Type type) + public EnumCacheInfo(Type type) { - var typeInfo = type.GetTypeInfo (); + var typeInfo = type.GetTypeInfo(); IsEnum = typeInfo.IsEnum; - if (IsEnum) { - StoreAsText = typeInfo.CustomAttributes.Any (x => x.AttributeType == typeof (StoreAsTextAttribute)); + if (IsEnum) + { + StoreAsText = typeInfo.CustomAttributes.Any(x => x.AttributeType == typeof(StoreAsTextAttribute)); - if (StoreAsText) { - EnumValues = new Dictionary (); - foreach (object e in Enum.GetValues (type)) { - EnumValues[Convert.ToInt32 (e)] = e.ToString (); + if (StoreAsText) + { + EnumValues = new Dictionary(); + foreach (object e in Enum.GetValues(type)) + { + EnumValues[Convert.ToInt32(e)] = e.ToString(); } } } @@ -2851,19 +3089,21 @@ public EnumCacheInfo (Type type) static class EnumCache { - static readonly Dictionary Cache = new Dictionary (); + static readonly Dictionary Cache = new Dictionary(); - public static EnumCacheInfo GetInfo () + public static EnumCacheInfo GetInfo() { - return GetInfo (typeof (T)); + return GetInfo(typeof(T)); } - public static EnumCacheInfo GetInfo (Type type) + public static EnumCacheInfo GetInfo(Type type) { - lock (Cache) { + lock (Cache) + { EnumCacheInfo info = null; - if (!Cache.TryGetValue (type, out info)) { - info = new EnumCacheInfo (type); + if (!Cache.TryGetValue(type, out info)) + { + info = new EnumCacheInfo(type); Cache[type] = info; } @@ -2878,46 +3118,53 @@ public static class Orm public const string ImplicitPkName = "Id"; public const string ImplicitIndexSuffix = "Id"; - public static Type GetType (object obj) + public static Type GetType(object obj) { if (obj == null) - return typeof (object); + return typeof(object); var rt = obj as IReflectableType; if (rt != null) - return rt.GetTypeInfo ().AsType (); - return obj.GetType (); + return rt.GetTypeInfo().AsType(); + return obj.GetType(); } - public static string SqlDecl (TableMapping.Column p, bool storeDateTimeAsTicks, bool storeTimeSpanAsTicks) + public static string SqlDecl(TableMapping.Column p, bool storeDateTimeAsTicks, bool storeTimeSpanAsTicks) { - string decl = "\"" + p.Name + "\" " + SqlType (p, storeDateTimeAsTicks, storeTimeSpanAsTicks) + " "; + string decl = "\"" + p.Name + "\" " + SqlType(p, storeDateTimeAsTicks, storeTimeSpanAsTicks) + " "; - if (p.IsPK) { + if (p.IsPK) + { decl += "primary key "; } - if (p.IsAutoInc) { + if (p.IsAutoInc) + { decl += "autoincrement "; } - if (!p.IsNullable) { + if (!p.IsNullable) + { decl += "not null "; } - if (!string.IsNullOrEmpty (p.Collation)) { + if (!string.IsNullOrEmpty(p.Collation)) + { decl += "collate " + p.Collation + " "; } return decl; } - public static string SqlType (TableMapping.Column p, bool storeDateTimeAsTicks, bool storeTimeSpanAsTicks) + public static string SqlType(TableMapping.Column p, bool storeDateTimeAsTicks, bool storeTimeSpanAsTicks) { var clrType = p.ColumnType; - if (clrType == typeof (Boolean) || clrType == typeof (Byte) || clrType == typeof (UInt16) || clrType == typeof (SByte) || clrType == typeof (Int16) || clrType == typeof (Int32) || clrType == typeof (UInt32) || clrType == typeof (Int64) || clrType == typeof (UInt64)) { + if (clrType == typeof(Boolean) || clrType == typeof(Byte) || clrType == typeof(UInt16) || clrType == typeof(SByte) || clrType == typeof(Int16) || clrType == typeof(Int32) || clrType == typeof(UInt32) || clrType == typeof(Int64) || clrType == typeof(UInt64)) + { return "integer"; } - else if (clrType == typeof (Single) || clrType == typeof (Double) || clrType == typeof (Decimal)) { + else if (clrType == typeof(Single) || clrType == typeof(Double) || clrType == typeof(Decimal)) + { return "float"; } - else if (clrType == typeof (String) || clrType == typeof (StringBuilder) || clrType == typeof (Uri) || clrType == typeof (UriBuilder)) { + else if (clrType == typeof(String) || clrType == typeof(StringBuilder) || clrType == typeof(Uri) || clrType == typeof(UriBuilder)) + { int? len = p.MaxStringLength; if (len.HasValue) @@ -2925,127 +3172,139 @@ public static string SqlType (TableMapping.Column p, bool storeDateTimeAsTicks, return "varchar"; } - else if (clrType == typeof (TimeSpan)) { + else if (clrType == typeof(TimeSpan)) + { return storeTimeSpanAsTicks ? "bigint" : "time"; } - else if (clrType == typeof (DateTime)) { + else if (clrType == typeof(DateTime)) + { return storeDateTimeAsTicks ? "bigint" : "datetime"; } - else if (clrType == typeof (DateTimeOffset)) { + else if (clrType == typeof(DateTimeOffset)) + { return "bigint"; } - else if (clrType.GetTypeInfo ().IsEnum) { + else if (clrType.GetTypeInfo().IsEnum) + { if (p.StoreAsText) return "varchar"; else return "integer"; } - else if (clrType == typeof (byte[])) { + else if (clrType == typeof(byte[])) + { return "blob"; } - else if (clrType == typeof (Guid)) { + else if (clrType == typeof(Guid)) + { return "varchar(36)"; } - else { - throw new NotSupportedException ("Don't know about " + clrType); + else + { + throw new NotSupportedException("Don't know about " + clrType); } } - public static bool IsPK (MemberInfo p) + public static bool IsPK(MemberInfo p) { - return p.CustomAttributes.Any (x => x.AttributeType == typeof (PrimaryKeyAttribute)); + return p.CustomAttributes.Any(x => x.AttributeType == typeof(PrimaryKeyAttribute)); } - public static string Collation (MemberInfo p) + public static string Collation(MemberInfo p) { #if ENABLE_IL2CPP return (p.GetCustomAttribute ()?.Value) ?? ""; #else return (p.CustomAttributes - .Where (x => typeof (CollationAttribute) == x.AttributeType) - .Select (x => { + .Where(x => typeof(CollationAttribute) == x.AttributeType) + .Select(x => + { var args = x.ConstructorArguments; return args.Count > 0 ? ((args[0].Value as string) ?? "") : ""; }) - .FirstOrDefault ()) ?? ""; + .FirstOrDefault()) ?? ""; #endif } - public static bool IsAutoInc (MemberInfo p) + public static bool IsAutoInc(MemberInfo p) { - return p.CustomAttributes.Any (x => x.AttributeType == typeof (AutoIncrementAttribute)); + return p.CustomAttributes.Any(x => x.AttributeType == typeof(AutoIncrementAttribute)); } - public static FieldInfo GetField (TypeInfo t, string name) + public static FieldInfo GetField(TypeInfo t, string name) { - var f = t.GetDeclaredField (name); + var f = t.GetDeclaredField(name); if (f != null) return f; - return GetField (t.BaseType.GetTypeInfo (), name); + return GetField(t.BaseType.GetTypeInfo(), name); } - public static PropertyInfo GetProperty (TypeInfo t, string name) + public static PropertyInfo GetProperty(TypeInfo t, string name) { - var f = t.GetDeclaredProperty (name); + var f = t.GetDeclaredProperty(name); if (f != null) return f; - return GetProperty (t.BaseType.GetTypeInfo (), name); + return GetProperty(t.BaseType.GetTypeInfo(), name); } - public static object InflateAttribute (CustomAttributeData x) + public static object InflateAttribute(CustomAttributeData x) { var atype = x.AttributeType; - var typeInfo = atype.GetTypeInfo (); + var typeInfo = atype.GetTypeInfo(); #if ENABLE_IL2CPP var r = Activator.CreateInstance (x.AttributeType); #else - var args = x.ConstructorArguments.Select (a => a.Value).ToArray (); - var r = Activator.CreateInstance (x.AttributeType, args); - foreach (var arg in x.NamedArguments) { - if (arg.IsField) { - GetField (typeInfo, arg.MemberName).SetValue (r, arg.TypedValue.Value); + var args = x.ConstructorArguments.Select(a => a.Value).ToArray(); + var r = Activator.CreateInstance(x.AttributeType, args); + foreach (var arg in x.NamedArguments) + { + if (arg.IsField) + { + GetField(typeInfo, arg.MemberName).SetValue(r, arg.TypedValue.Value); } - else { - GetProperty (typeInfo, arg.MemberName).SetValue (r, arg.TypedValue.Value); + else + { + GetProperty(typeInfo, arg.MemberName).SetValue(r, arg.TypedValue.Value); } } #endif return r; } - public static IEnumerable GetIndices (MemberInfo p) + public static IEnumerable GetIndices(MemberInfo p) { #if ENABLE_IL2CPP return p.GetCustomAttributes (); #else - var indexedInfo = typeof (IndexedAttribute).GetTypeInfo (); + var indexedInfo = typeof(IndexedAttribute).GetTypeInfo(); return p.CustomAttributes - .Where (x => indexedInfo.IsAssignableFrom (x.AttributeType.GetTypeInfo ())) - .Select (x => (IndexedAttribute)InflateAttribute (x)); + .Where(x => indexedInfo.IsAssignableFrom(x.AttributeType.GetTypeInfo())) + .Select(x => (IndexedAttribute)InflateAttribute(x)); #endif } - public static int? MaxStringLength (MemberInfo p) + public static int? MaxStringLength(MemberInfo p) { #if ENABLE_IL2CPP return p.GetCustomAttribute ()?.Value; #else - var attr = p.CustomAttributes.FirstOrDefault (x => x.AttributeType == typeof (MaxLengthAttribute)); - if (attr != null) { - var attrv = (MaxLengthAttribute)InflateAttribute (attr); + var attr = p.CustomAttributes.FirstOrDefault(x => x.AttributeType == typeof(MaxLengthAttribute)); + if (attr != null) + { + var attrv = (MaxLengthAttribute)InflateAttribute(attr); return attrv.Value; } return null; #endif } - public static int? MaxStringLength (PropertyInfo p) => MaxStringLength((MemberInfo)p); + public static int? MaxStringLength(PropertyInfo p) => MaxStringLength((MemberInfo)p); - public static bool IsMarkedNotNull (MemberInfo p) + public static bool IsMarkedNotNull(MemberInfo p) { - return p.CustomAttributes.Any (x => x.AttributeType == typeof (NotNullAttribute)); + return p.CustomAttributes.Any(x => x.AttributeType == typeof(NotNullAttribute)); } } @@ -3056,53 +3315,58 @@ public partial class SQLiteCommand public string CommandText { get; set; } - public SQLiteCommand (SQLiteConnection conn) + public SQLiteCommand(SQLiteConnection conn) { _conn = conn; - _bindings = new List (); + _bindings = new List(); CommandText = ""; } - public int ExecuteNonQuery () + public int ExecuteNonQuery() { - if (_conn.Trace) { - _conn.Tracer?.Invoke ("Executing: " + this); + if (_conn.Trace) + { + _conn.Tracer?.Invoke("Executing: " + this); } var r = SQLite3.Result.OK; - var stmt = Prepare (); - r = SQLite3.Step (stmt); - Finalize (stmt); - if (r == SQLite3.Result.Done) { - int rowsAffected = SQLite3.Changes (_conn.Handle); + var stmt = Prepare(); + r = SQLite3.Step(stmt); + Finalize(stmt); + if (r == SQLite3.Result.Done) + { + int rowsAffected = SQLite3.Changes(_conn.Handle); return rowsAffected; } - else if (r == SQLite3.Result.Error) { - string msg = SQLite3.GetErrmsg (_conn.Handle); - throw SQLiteException.New (r, msg); + else if (r == SQLite3.Result.Error) + { + string msg = SQLite3.GetErrmsg(_conn.Handle); + throw SQLiteException.New(r, msg); } - else if (r == SQLite3.Result.Constraint) { - if (SQLite3.ExtendedErrCode (_conn.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) { - throw NotNullConstraintViolationException.New (r, SQLite3.GetErrmsg (_conn.Handle)); + else if (r == SQLite3.Result.Constraint) + { + if (SQLite3.ExtendedErrCode(_conn.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) + { + throw NotNullConstraintViolationException.New(r, SQLite3.GetErrmsg(_conn.Handle)); } } - throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle)); + throw SQLiteException.New(r, SQLite3.GetErrmsg(_conn.Handle)); } - public IEnumerable ExecuteDeferredQuery () + public IEnumerable ExecuteDeferredQuery(string tableName = null) { - return ExecuteDeferredQuery (_conn.GetMapping (typeof (T))); + return ExecuteDeferredQuery(_conn.GetMapping(tableName)); } - public List ExecuteQuery () + public List ExecuteQuery(string tableName = null) { - return ExecuteDeferredQuery (_conn.GetMapping (typeof (T))).ToList (); + return ExecuteDeferredQuery(_conn.GetMapping(tableName)).ToList(); } - public List ExecuteQuery (TableMapping map) + public List ExecuteQuery(TableMapping map) { - return ExecuteDeferredQuery (map).ToList (); + return ExecuteDeferredQuery(map).ToList(); } /// @@ -3115,254 +3379,310 @@ public List ExecuteQuery (TableMapping map) /// This can be overridden in combination with the /// method to hook into the life-cycle of objects. /// - protected virtual void OnInstanceCreated (object obj) + protected virtual void OnInstanceCreated(object obj) { // Can be overridden. } - public IEnumerable ExecuteDeferredQuery (TableMapping map) + public IEnumerable ExecuteDeferredQuery(TableMapping map) { - if (_conn.Trace) { - _conn.Tracer?.Invoke ("Executing Query: " + this); + if (_conn.Trace) + { + _conn.Tracer?.Invoke("Executing Query: " + this); } - var stmt = Prepare (); - try { - var cols = new TableMapping.Column[SQLite3.ColumnCount (stmt)]; - var fastColumnSetters = new Action[SQLite3.ColumnCount (stmt)]; + var stmt = Prepare(); + try + { + var cols = new TableMapping.Column[SQLite3.ColumnCount(stmt)]; + var fastColumnSetters = new Action[SQLite3.ColumnCount(stmt)]; if (map.Method == TableMapping.MapMethod.ByPosition) { Array.Copy(map.Columns, cols, Math.Min(cols.Length, map.Columns.Length)); } - else if (map.Method == TableMapping.MapMethod.ByName) { + else if (map.Method == TableMapping.MapMethod.ByName) + { MethodInfo getSetter = null; - if (typeof(T) != map.MappedType) { + if (typeof(T) != map.MappedType) + { getSetter = typeof(FastColumnSetter) - .GetMethod (nameof(FastColumnSetter.GetFastSetter), - BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod (map.MappedType); + .GetMethod(nameof(FastColumnSetter.GetFastSetter), + BindingFlags.NonPublic | BindingFlags.Static).MakeGenericMethod(map.MappedType); } - for (int i = 0; i < cols.Length; i++) { - var name = SQLite3.ColumnName16 (stmt, i); - cols[i] = map.FindColumn (name); + for (int i = 0; i < cols.Length; i++) + { + var name = SQLite3.ColumnName16(stmt, i); + cols[i] = map.FindColumn(name); if (!typeof(T).IsValueType && cols[i] != null) - if (getSetter != null) { - fastColumnSetters[i] = (Action)getSetter.Invoke(null, new object[]{ _conn, cols[i]}); + { + if (getSetter != null) + { + fastColumnSetters[i] = (Action)getSetter.Invoke(null, new object[] { _conn, cols[i] }); } - else { + else + { fastColumnSetters[i] = FastColumnSetter.GetFastSetter(_conn, cols[i]); } + } } } - while (SQLite3.Step (stmt) == SQLite3.Result.Row) { - var obj = Activator.CreateInstance (map.MappedType); - for (int i = 0; i < cols.Length; i++) { + while (SQLite3.Step(stmt) == SQLite3.Result.Row) + { + var obj = Activator.CreateInstance(map.MappedType); + for (int i = 0; i < cols.Length; i++) + { if (cols[i] == null) continue; - if (fastColumnSetters[i] != null) { - fastColumnSetters[i].Invoke (obj, stmt, i); + if (fastColumnSetters[i] != null) + { + fastColumnSetters[i].Invoke(obj, stmt, i); } - else { - var colType = SQLite3.ColumnType (stmt, i); - var val = ReadCol (stmt, i, colType, cols[i].ColumnType); - cols[i].SetValue (obj, val); + else + { + var colType = SQLite3.ColumnType(stmt, i); + var val = ReadCol(stmt, i, colType, cols[i].ColumnType); + cols[i].SetValue(obj, val); } } - OnInstanceCreated (obj); + OnInstanceCreated(obj); yield return (T)obj; } } - finally { - SQLite3.Finalize (stmt); + finally + { + SQLite3.Finalize(stmt); } } - public T ExecuteScalar () + public T ExecuteScalar() { - if (_conn.Trace) { - _conn.Tracer?.Invoke ("Executing Query: " + this); + if (_conn.Trace) + { + _conn.Tracer?.Invoke("Executing Query: " + this); } - T val = default (T); + T val = default(T); - var stmt = Prepare (); + var stmt = Prepare(); - try { - var r = SQLite3.Step (stmt); - if (r == SQLite3.Result.Row) { - var colType = SQLite3.ColumnType (stmt, 0); - var colval = ReadCol (stmt, 0, colType, typeof (T)); - if (colval != null) { + try + { + var r = SQLite3.Step(stmt); + if (r == SQLite3.Result.Row) + { + var colType = SQLite3.ColumnType(stmt, 0); + var colval = ReadCol(stmt, 0, colType, typeof(T)); + if (colval != null) + { val = (T)colval; } } - else if (r == SQLite3.Result.Done) { + else if (r == SQLite3.Result.Done) + { } - else { - throw SQLiteException.New (r, SQLite3.GetErrmsg (_conn.Handle)); + else + { + throw SQLiteException.New(r, SQLite3.GetErrmsg(_conn.Handle)); } } - finally { - Finalize (stmt); + finally + { + Finalize(stmt); } return val; } - public IEnumerable ExecuteQueryScalars () + public IEnumerable ExecuteQueryScalars() { - if (_conn.Trace) { - _conn.Tracer?.Invoke ("Executing Query: " + this); + if (_conn.Trace) + { + _conn.Tracer?.Invoke("Executing Query: " + this); } - var stmt = Prepare (); - try { - if (SQLite3.ColumnCount (stmt) < 1) { - throw new InvalidOperationException ("QueryScalars should return at least one column"); + var stmt = Prepare(); + try + { + if (SQLite3.ColumnCount(stmt) < 1) + { + throw new InvalidOperationException("QueryScalars should return at least one column"); } - while (SQLite3.Step (stmt) == SQLite3.Result.Row) { - var colType = SQLite3.ColumnType (stmt, 0); - var val = ReadCol (stmt, 0, colType, typeof (T)); - if (val == null) { - yield return default (T); + while (SQLite3.Step(stmt) == SQLite3.Result.Row) + { + var colType = SQLite3.ColumnType(stmt, 0); + var val = ReadCol(stmt, 0, colType, typeof(T)); + if (val == null) + { + yield return default(T); } - else { + else + { yield return (T)val; } } } - finally { - Finalize (stmt); + finally + { + Finalize(stmt); } } - public void Bind (string name, object val) + public void Bind(string name, object val) { - _bindings.Add (new Binding { + _bindings.Add(new Binding + { Name = name, Value = val }); } - public void Bind (object val) + public void Bind(object val) { - Bind (null, val); + Bind(null, val); } - public override string ToString () + public override string ToString() { var parts = new string[1 + _bindings.Count]; parts[0] = CommandText; var i = 1; - foreach (var b in _bindings) { - parts[i] = string.Format (" {0}: {1}", i - 1, b.Value); + foreach (var b in _bindings) + { + parts[i] = string.Format(" {0}: {1}", i - 1, b.Value); i++; } - return string.Join (Environment.NewLine, parts); + return string.Join(Environment.NewLine, parts); } - Sqlite3Statement Prepare () + Sqlite3Statement Prepare() { - var stmt = SQLite3.Prepare2 (_conn.Handle, CommandText); - BindAll (stmt); + var stmt = SQLite3.Prepare2(_conn.Handle, CommandText); + BindAll(stmt); return stmt; } - void Finalize (Sqlite3Statement stmt) + void Finalize(Sqlite3Statement stmt) { - SQLite3.Finalize (stmt); + SQLite3.Finalize(stmt); } - void BindAll (Sqlite3Statement stmt) + void BindAll(Sqlite3Statement stmt) { int nextIdx = 1; - foreach (var b in _bindings) { - if (b.Name != null) { - b.Index = SQLite3.BindParameterIndex (stmt, b.Name); + foreach (var b in _bindings) + { + if (b.Name != null) + { + b.Index = SQLite3.BindParameterIndex(stmt, b.Name); } - else { + else + { b.Index = nextIdx++; } - BindParameter (stmt, b.Index, b.Value, _conn.StoreDateTimeAsTicks, _conn.DateTimeStringFormat, _conn.StoreTimeSpanAsTicks); + BindParameter(stmt, b.Index, b.Value, _conn.StoreDateTimeAsTicks, _conn.DateTimeStringFormat, _conn.StoreTimeSpanAsTicks); } } - static IntPtr NegativePointer = new IntPtr (-1); + static IntPtr NegativePointer = new IntPtr(-1); - internal static void BindParameter (Sqlite3Statement stmt, int index, object value, bool storeDateTimeAsTicks, string dateTimeStringFormat, bool storeTimeSpanAsTicks) + internal static void BindParameter(Sqlite3Statement stmt, int index, object value, bool storeDateTimeAsTicks, string dateTimeStringFormat, bool storeTimeSpanAsTicks) { - if (value == null) { - SQLite3.BindNull (stmt, index); + if (value == null) + { + SQLite3.BindNull(stmt, index); } - else { - if (value is Int32) { - SQLite3.BindInt (stmt, index, (int)value); + else + { + if (value is Int32) + { + SQLite3.BindInt(stmt, index, (int)value); } - else if (value is String) { - SQLite3.BindText (stmt, index, (string)value, -1, NegativePointer); + else if (value is String) + { + SQLite3.BindText(stmt, index, (string)value, -1, NegativePointer); } - else if (value is Byte || value is UInt16 || value is SByte || value is Int16) { - SQLite3.BindInt (stmt, index, Convert.ToInt32 (value)); + else if (value is Byte || value is UInt16 || value is SByte || value is Int16) + { + SQLite3.BindInt(stmt, index, Convert.ToInt32(value)); } - else if (value is Boolean) { - SQLite3.BindInt (stmt, index, (bool)value ? 1 : 0); + else if (value is Boolean) + { + SQLite3.BindInt(stmt, index, (bool)value ? 1 : 0); } - else if (value is UInt32 || value is Int64 || value is UInt64) { - SQLite3.BindInt64 (stmt, index, Convert.ToInt64 (value)); + else if (value is UInt32 || value is Int64 || value is UInt64) + { + SQLite3.BindInt64(stmt, index, Convert.ToInt64(value)); } - else if (value is Single || value is Double || value is Decimal) { - SQLite3.BindDouble (stmt, index, Convert.ToDouble (value)); + else if (value is Single || value is Double || value is Decimal) + { + SQLite3.BindDouble(stmt, index, Convert.ToDouble(value)); } - else if (value is TimeSpan) { - if (storeTimeSpanAsTicks) { - SQLite3.BindInt64 (stmt, index, ((TimeSpan)value).Ticks); + else if (value is TimeSpan) + { + if (storeTimeSpanAsTicks) + { + SQLite3.BindInt64(stmt, index, ((TimeSpan)value).Ticks); } - else { - SQLite3.BindText (stmt, index, ((TimeSpan)value).ToString (), -1, NegativePointer); + else + { + SQLite3.BindText(stmt, index, ((TimeSpan)value).ToString(), -1, NegativePointer); } } - else if (value is DateTime) { - if (storeDateTimeAsTicks) { - SQLite3.BindInt64 (stmt, index, ((DateTime)value).Ticks); + else if (value is DateTime) + { + if (storeDateTimeAsTicks) + { + SQLite3.BindInt64(stmt, index, ((DateTime)value).Ticks); } - else { - SQLite3.BindText (stmt, index, ((DateTime)value).ToString (dateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture), -1, NegativePointer); + else + { + SQLite3.BindText(stmt, index, ((DateTime)value).ToString(dateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture), -1, NegativePointer); } } - else if (value is DateTimeOffset) { - SQLite3.BindInt64 (stmt, index, ((DateTimeOffset)value).UtcTicks); + else if (value is DateTimeOffset) + { + SQLite3.BindInt64(stmt, index, ((DateTimeOffset)value).UtcTicks); } - else if (value is byte[]) { - SQLite3.BindBlob (stmt, index, (byte[])value, ((byte[])value).Length, NegativePointer); + else if (value is byte[]) + { + SQLite3.BindBlob(stmt, index, (byte[])value, ((byte[])value).Length, NegativePointer); } - else if (value is Guid) { - SQLite3.BindText (stmt, index, ((Guid)value).ToString (), 72, NegativePointer); + else if (value is Guid) + { + SQLite3.BindText(stmt, index, ((Guid)value).ToString(), 72, NegativePointer); } - else if (value is Uri) { - SQLite3.BindText (stmt, index, ((Uri)value).ToString (), -1, NegativePointer); + else if (value is Uri) + { + SQLite3.BindText(stmt, index, ((Uri)value).ToString(), -1, NegativePointer); } - else if (value is StringBuilder) { - SQLite3.BindText (stmt, index, ((StringBuilder)value).ToString (), -1, NegativePointer); + else if (value is StringBuilder) + { + SQLite3.BindText(stmt, index, ((StringBuilder)value).ToString(), -1, NegativePointer); } - else if (value is UriBuilder) { - SQLite3.BindText (stmt, index, ((UriBuilder)value).ToString (), -1, NegativePointer); + else if (value is UriBuilder) + { + SQLite3.BindText(stmt, index, ((UriBuilder)value).ToString(), -1, NegativePointer); } - else { + else + { // Now we could possibly get an enum, retrieve cached info - var valueType = value.GetType (); - var enumInfo = EnumCache.GetInfo (valueType); - if (enumInfo.IsEnum) { - var enumIntValue = Convert.ToInt32 (value); + var valueType = value.GetType(); + var enumInfo = EnumCache.GetInfo(valueType); + if (enumInfo.IsEnum) + { + var enumIntValue = Convert.ToInt32(value); if (enumInfo.StoreAsText) - SQLite3.BindText (stmt, index, enumInfo.EnumValues[enumIntValue], -1, NegativePointer); + SQLite3.BindText(stmt, index, enumInfo.EnumValues[enumIntValue], -1, NegativePointer); else - SQLite3.BindInt (stmt, index, enumIntValue); + SQLite3.BindInt(stmt, index, enumIntValue); } - else { - throw new NotSupportedException ("Cannot store type: " + Orm.GetType (value)); + else + { + throw new NotSupportedException("Cannot store type: " + Orm.GetType(value)); } } } @@ -3377,115 +3697,148 @@ class Binding public int Index { get; set; } } - object ReadCol (Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clrType) + object ReadCol(Sqlite3Statement stmt, int index, SQLite3.ColType type, Type clrType) { - if (type == SQLite3.ColType.Null) { + if (type == SQLite3.ColType.Null) + { return null; } - else { - var clrTypeInfo = clrType.GetTypeInfo (); - if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition () == typeof (Nullable<>)) { + else + { + var clrTypeInfo = clrType.GetTypeInfo(); + if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>)) + { clrType = clrTypeInfo.GenericTypeArguments[0]; - clrTypeInfo = clrType.GetTypeInfo (); + clrTypeInfo = clrType.GetTypeInfo(); } - if (clrType == typeof (String)) { - return SQLite3.ColumnString (stmt, index); + if (clrType == typeof(String)) + { + return SQLite3.ColumnString(stmt, index); } - else if (clrType == typeof (Int32)) { - return (int)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(Int32)) + { + return (int)SQLite3.ColumnInt(stmt, index); } - else if (clrType == typeof (Boolean)) { - return SQLite3.ColumnInt (stmt, index) == 1; + else if (clrType == typeof(Boolean)) + { + return SQLite3.ColumnInt(stmt, index) == 1; } - else if (clrType == typeof (double)) { - return SQLite3.ColumnDouble (stmt, index); + else if (clrType == typeof(double)) + { + return SQLite3.ColumnDouble(stmt, index); } - else if (clrType == typeof (float)) { - return (float)SQLite3.ColumnDouble (stmt, index); + else if (clrType == typeof(float)) + { + return (float)SQLite3.ColumnDouble(stmt, index); } - else if (clrType == typeof (TimeSpan)) { - if (_conn.StoreTimeSpanAsTicks) { - return new TimeSpan (SQLite3.ColumnInt64 (stmt, index)); + else if (clrType == typeof(TimeSpan)) + { + if (_conn.StoreTimeSpanAsTicks) + { + return new TimeSpan(SQLite3.ColumnInt64(stmt, index)); } - else { - var text = SQLite3.ColumnString (stmt, index); + else + { + var text = SQLite3.ColumnString(stmt, index); TimeSpan resultTime; - if (!TimeSpan.TryParseExact (text, "c", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.TimeSpanStyles.None, out resultTime)) { - resultTime = TimeSpan.Parse (text); + if (!TimeSpan.TryParseExact(text, "c", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.TimeSpanStyles.None, out resultTime)) + { + resultTime = TimeSpan.Parse(text); } return resultTime; } } - else if (clrType == typeof (DateTime)) { - if (_conn.StoreDateTimeAsTicks) { - return new DateTime (SQLite3.ColumnInt64 (stmt, index)); + else if (clrType == typeof(DateTime)) + { + if (_conn.StoreDateTimeAsTicks) + { + return new DateTime(SQLite3.ColumnInt64(stmt, index)); } - else { - var text = SQLite3.ColumnString (stmt, index); + else + { + var text = SQLite3.ColumnString(stmt, index); DateTime resultDate; - if (!DateTime.TryParseExact (text, _conn.DateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture, _conn.DateTimeStyle, out resultDate)) { - resultDate = DateTime.Parse (text); + if (!DateTime.TryParseExact(text, _conn.DateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture, _conn.DateTimeStyle, out resultDate)) + { + resultDate = DateTime.Parse(text); } return resultDate; } } - else if (clrType == typeof (DateTimeOffset)) { - return new DateTimeOffset (SQLite3.ColumnInt64 (stmt, index), TimeSpan.Zero); + else if (clrType == typeof(DateTimeOffset)) + { + return new DateTimeOffset(SQLite3.ColumnInt64(stmt, index), TimeSpan.Zero); } - else if (clrTypeInfo.IsEnum) { - if (type == SQLite3.ColType.Text) { - var value = SQLite3.ColumnString (stmt, index); - return Enum.Parse (clrType, value.ToString (), true); + else if (clrTypeInfo.IsEnum) + { + if (type == SQLite3.ColType.Text) + { + var value = SQLite3.ColumnString(stmt, index); + return Enum.Parse(clrType, value.ToString(), true); } else - return SQLite3.ColumnInt (stmt, index); + return SQLite3.ColumnInt(stmt, index); } - else if (clrType == typeof (Int64)) { - return SQLite3.ColumnInt64 (stmt, index); + else if (clrType == typeof(Int64)) + { + return SQLite3.ColumnInt64(stmt, index); } - else if (clrType == typeof (UInt64)) { - return (ulong)SQLite3.ColumnInt64 (stmt, index); + else if (clrType == typeof(UInt64)) + { + return (ulong)SQLite3.ColumnInt64(stmt, index); } - else if (clrType == typeof (UInt32)) { - return (uint)SQLite3.ColumnInt64 (stmt, index); + else if (clrType == typeof(UInt32)) + { + return (uint)SQLite3.ColumnInt64(stmt, index); } - else if (clrType == typeof (decimal)) { - return (decimal)SQLite3.ColumnDouble (stmt, index); + else if (clrType == typeof(decimal)) + { + return (decimal)SQLite3.ColumnDouble(stmt, index); } - else if (clrType == typeof (Byte)) { - return (byte)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(Byte)) + { + return (byte)SQLite3.ColumnInt(stmt, index); } - else if (clrType == typeof (UInt16)) { - return (ushort)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(UInt16)) + { + return (ushort)SQLite3.ColumnInt(stmt, index); } - else if (clrType == typeof (Int16)) { - return (short)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(Int16)) + { + return (short)SQLite3.ColumnInt(stmt, index); } - else if (clrType == typeof (sbyte)) { - return (sbyte)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(sbyte)) + { + return (sbyte)SQLite3.ColumnInt(stmt, index); } - else if (clrType == typeof (byte[])) { - return SQLite3.ColumnByteArray (stmt, index); + else if (clrType == typeof(byte[])) + { + return SQLite3.ColumnByteArray(stmt, index); } - else if (clrType == typeof (Guid)) { - var text = SQLite3.ColumnString (stmt, index); - return new Guid (text); + else if (clrType == typeof(Guid)) + { + var text = SQLite3.ColumnString(stmt, index); + return new Guid(text); } - else if (clrType == typeof (Uri)) { - var text = SQLite3.ColumnString (stmt, index); - return new Uri (text); + else if (clrType == typeof(Uri)) + { + var text = SQLite3.ColumnString(stmt, index); + return new Uri(text); } - else if (clrType == typeof (StringBuilder)) { - var text = SQLite3.ColumnString (stmt, index); - return new StringBuilder (text); + else if (clrType == typeof(StringBuilder)) + { + var text = SQLite3.ColumnString(stmt, index); + return new StringBuilder(text); } - else if (clrType == typeof (UriBuilder)) { - var text = SQLite3.ColumnString (stmt, index); - return new UriBuilder (text); + else if (clrType == typeof(UriBuilder)) + { + var text = SQLite3.ColumnString(stmt, index); + return new UriBuilder(text); } - else { - throw new NotSupportedException ("Don't know how to read " + clrType); + else + { + throw new NotSupportedException("Don't know how to read " + clrType); } } } @@ -3507,156 +3860,208 @@ internal class FastColumnSetter /// /// If no fast setter is available for the requested column (enums in particular cause headache), then this function returns null. /// - internal static Action GetFastSetter (SQLiteConnection conn, TableMapping.Column column) + internal static Action GetFastSetter(SQLiteConnection conn, TableMapping.Column column) { Action fastSetter = null; Type clrType = column.PropertyInfo.PropertyType; - var clrTypeInfo = clrType.GetTypeInfo (); - if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition () == typeof (Nullable<>)) { + var clrTypeInfo = clrType.GetTypeInfo(); + if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>)) + { clrType = clrTypeInfo.GenericTypeArguments[0]; - clrTypeInfo = clrType.GetTypeInfo (); + clrTypeInfo = clrType.GetTypeInfo(); } - if (clrType == typeof (String)) { - fastSetter = CreateTypedSetterDelegate (column, (stmt, index) => { - return SQLite3.ColumnString (stmt, index); + if (clrType == typeof(String)) + { + fastSetter = CreateTypedSetterDelegate(column, (stmt, index) => + { + return SQLite3.ColumnString(stmt, index); }); } - else if (clrType == typeof (Int32)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index)=>{ - return SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(Int32)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return SQLite3.ColumnInt(stmt, index); }); } - else if (clrType == typeof (Boolean)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return SQLite3.ColumnInt (stmt, index) == 1; + else if (clrType == typeof(Boolean)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return SQLite3.ColumnInt(stmt, index) == 1; }); } - else if (clrType == typeof (double)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return SQLite3.ColumnDouble (stmt, index); + else if (clrType == typeof(double)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return SQLite3.ColumnDouble(stmt, index); }); } - else if (clrType == typeof (float)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (float) SQLite3.ColumnDouble (stmt, index); + else if (clrType == typeof(float)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (float)SQLite3.ColumnDouble(stmt, index); }); } - else if (clrType == typeof (TimeSpan)) { - if (conn.StoreTimeSpanAsTicks) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return new TimeSpan (SQLite3.ColumnInt64 (stmt, index)); + else if (clrType == typeof(TimeSpan)) + { + if (conn.StoreTimeSpanAsTicks) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return new TimeSpan(SQLite3.ColumnInt64(stmt, index)); }); } - else { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - var text = SQLite3.ColumnString (stmt, index); + else + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + var text = SQLite3.ColumnString(stmt, index); TimeSpan resultTime; - if (!TimeSpan.TryParseExact (text, "c", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.TimeSpanStyles.None, out resultTime)) { - resultTime = TimeSpan.Parse (text); + if (!TimeSpan.TryParseExact(text, "c", System.Globalization.CultureInfo.InvariantCulture, System.Globalization.TimeSpanStyles.None, out resultTime)) + { + resultTime = TimeSpan.Parse(text); } return resultTime; }); } } - else if (clrType == typeof (DateTime)) { - if (conn.StoreDateTimeAsTicks) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return new DateTime (SQLite3.ColumnInt64 (stmt, index)); + else if (clrType == typeof(DateTime)) + { + if (conn.StoreDateTimeAsTicks) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return new DateTime(SQLite3.ColumnInt64(stmt, index)); }); } - else { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - var text = SQLite3.ColumnString (stmt, index); + else + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + var text = SQLite3.ColumnString(stmt, index); DateTime resultDate; - if (!DateTime.TryParseExact (text, conn.DateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture, conn.DateTimeStyle, out resultDate)) { - resultDate = DateTime.Parse (text); + if (!DateTime.TryParseExact(text, conn.DateTimeStringFormat, System.Globalization.CultureInfo.InvariantCulture, conn.DateTimeStyle, out resultDate)) + { + resultDate = DateTime.Parse(text); } return resultDate; }); } } - else if (clrType == typeof (DateTimeOffset)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return new DateTimeOffset (SQLite3.ColumnInt64 (stmt, index), TimeSpan.Zero); + else if (clrType == typeof(DateTimeOffset)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return new DateTimeOffset(SQLite3.ColumnInt64(stmt, index), TimeSpan.Zero); }); } - else if (clrTypeInfo.IsEnum) { + else if (clrTypeInfo.IsEnum) + { // NOTE: Not sure of a good way (if any?) to do a strongly-typed fast setter like this for enumerated types -- for now, return null and column sets will revert back to the safe (but slow) Reflection-based method of column prop.Set() } - else if (clrType == typeof (Int64)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return SQLite3.ColumnInt64 (stmt, index); + else if (clrType == typeof(Int64)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return SQLite3.ColumnInt64(stmt, index); }); } else if (clrType == typeof(UInt64)) { - fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { return (ulong)SQLite3.ColumnInt64(stmt, index); }); } - else if (clrType == typeof (UInt32)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (uint)SQLite3.ColumnInt64 (stmt, index); + else if (clrType == typeof(UInt32)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (uint)SQLite3.ColumnInt64(stmt, index); }); } - else if (clrType == typeof (decimal)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (decimal)SQLite3.ColumnDouble (stmt, index); + else if (clrType == typeof(decimal)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (decimal)SQLite3.ColumnDouble(stmt, index); }); } - else if (clrType == typeof (Byte)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (byte)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(Byte)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (byte)SQLite3.ColumnInt(stmt, index); }); } - else if (clrType == typeof (UInt16)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (ushort)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(UInt16)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (ushort)SQLite3.ColumnInt(stmt, index); }); } - else if (clrType == typeof (Int16)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (short)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(Int16)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (short)SQLite3.ColumnInt(stmt, index); }); } - else if (clrType == typeof (sbyte)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - return (sbyte)SQLite3.ColumnInt (stmt, index); + else if (clrType == typeof(sbyte)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + return (sbyte)SQLite3.ColumnInt(stmt, index); }); } - else if (clrType == typeof (byte[])) { - fastSetter = CreateTypedSetterDelegate (column, (stmt, index) => { - return SQLite3.ColumnByteArray (stmt, index); + else if (clrType == typeof(byte[])) + { + fastSetter = CreateTypedSetterDelegate(column, (stmt, index) => + { + return SQLite3.ColumnByteArray(stmt, index); }); } - else if (clrType == typeof (Guid)) { - fastSetter = CreateNullableTypedSetterDelegate (column, (stmt, index) => { - var text = SQLite3.ColumnString (stmt, index); - return new Guid (text); + else if (clrType == typeof(Guid)) + { + fastSetter = CreateNullableTypedSetterDelegate(column, (stmt, index) => + { + var text = SQLite3.ColumnString(stmt, index); + return new Guid(text); }); } - else if (clrType == typeof (Uri)) { - fastSetter = CreateTypedSetterDelegate (column, (stmt, index) => { - var text = SQLite3.ColumnString (stmt, index); - return new Uri (text); + else if (clrType == typeof(Uri)) + { + fastSetter = CreateTypedSetterDelegate(column, (stmt, index) => + { + var text = SQLite3.ColumnString(stmt, index); + return new Uri(text); }); } - else if (clrType == typeof (StringBuilder)) { - fastSetter = CreateTypedSetterDelegate (column, (stmt, index) => { - var text = SQLite3.ColumnString (stmt, index); - return new StringBuilder (text); + else if (clrType == typeof(StringBuilder)) + { + fastSetter = CreateTypedSetterDelegate(column, (stmt, index) => + { + var text = SQLite3.ColumnString(stmt, index); + return new StringBuilder(text); }); } - else if (clrType == typeof (UriBuilder)) { - fastSetter = CreateTypedSetterDelegate (column, (stmt, index) => { - var text = SQLite3.ColumnString (stmt, index); - return new UriBuilder (text); + else if (clrType == typeof(UriBuilder)) + { + fastSetter = CreateTypedSetterDelegate(column, (stmt, index) => + { + var text = SQLite3.ColumnString(stmt, index); + return new UriBuilder(text); }); } - else { + else + { // NOTE: Will fall back to the slow setter method in the event that we are unable to create a fast setter delegate for a particular column type } return fastSetter; @@ -3672,28 +4077,31 @@ internal static Action GetFastSetter (SQLiteCo /// The column mapping that identifies the target member of the destination object /// A lambda that can be used to retrieve the column value at query-time /// A strongly-typed delegate - private static Action CreateNullableTypedSetterDelegate (TableMapping.Column column, Func getColumnValue) where ColumnMemberType : struct + private static Action CreateNullableTypedSetterDelegate(TableMapping.Column column, Func getColumnValue) where ColumnMemberType : struct { var clrTypeInfo = column.PropertyInfo.PropertyType.GetTypeInfo(); bool isNullable = false; - if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition () == typeof (Nullable<>)) { + if (clrTypeInfo.IsGenericType && clrTypeInfo.GetGenericTypeDefinition() == typeof(Nullable<>)) + { isNullable = true; } - if (isNullable) { - var setProperty = (Action)Delegate.CreateDelegate ( - typeof (Action), null, - column.PropertyInfo.GetSetMethod ()); + if (isNullable) + { + var setProperty = (Action)Delegate.CreateDelegate( + typeof(Action), null, + column.PropertyInfo.GetSetMethod()); - return (o, stmt, i) => { - var colType = SQLite3.ColumnType (stmt, i); + return (o, stmt, i) => + { + var colType = SQLite3.ColumnType(stmt, i); if (colType != SQLite3.ColType.Null) - setProperty.Invoke ((ObjectType)o, getColumnValue.Invoke (stmt, i)); + setProperty.Invoke((ObjectType)o, getColumnValue.Invoke(stmt, i)); }; } - return CreateTypedSetterDelegate (column, getColumnValue); + return CreateTypedSetterDelegate(column, getColumnValue); } /// @@ -3704,16 +4112,17 @@ private static Action CreateNullableTypedSetterDe /// The column mapping that identifies the target member of the destination object /// A lambda that can be used to retrieve the column value at query-time /// A strongly-typed delegate - private static Action CreateTypedSetterDelegate (TableMapping.Column column, Func getColumnValue) + private static Action CreateTypedSetterDelegate(TableMapping.Column column, Func getColumnValue) { - var setProperty = (Action)Delegate.CreateDelegate ( - typeof (Action), null, - column.PropertyInfo.GetSetMethod ()); + var setProperty = (Action)Delegate.CreateDelegate( + typeof(Action), null, + column.PropertyInfo.GetSetMethod()); - return (o, stmt, i) => { - var colType = SQLite3.ColumnType (stmt, i); + return (o, stmt, i) => + { + var colType = SQLite3.ColumnType(stmt, i); if (colType != SQLite3.ColType.Null) - setProperty.Invoke ((ObjectType)o, getColumnValue.Invoke (stmt, i)); + setProperty.Invoke((ObjectType)o, getColumnValue.Invoke(stmt, i)); }; } } @@ -3730,78 +4139,88 @@ class PreparedSqlLiteInsertCommand : IDisposable string CommandText; Sqlite3Statement Statement; - static readonly Sqlite3Statement NullStatement = default (Sqlite3Statement); + static readonly Sqlite3Statement NullStatement = default(Sqlite3Statement); - public PreparedSqlLiteInsertCommand (SQLiteConnection conn, string commandText) + public PreparedSqlLiteInsertCommand(SQLiteConnection conn, string commandText) { Connection = conn; CommandText = commandText; } - public int ExecuteNonQuery (object[] source) + public int ExecuteNonQuery(object[] source) { - if (Initialized && Statement == NullStatement) { - throw new ObjectDisposedException (nameof (PreparedSqlLiteInsertCommand)); + if (Initialized && Statement == NullStatement) + { + throw new ObjectDisposedException(nameof(PreparedSqlLiteInsertCommand)); } - if (Connection.Trace) { - Connection.Tracer?.Invoke ("Executing: " + CommandText); + if (Connection.Trace) + { + Connection.Tracer?.Invoke("Executing: " + CommandText); } var r = SQLite3.Result.OK; - if (!Initialized) { - Statement = SQLite3.Prepare2 (Connection.Handle, CommandText); + if (!Initialized) + { + Statement = SQLite3.Prepare2(Connection.Handle, CommandText); Initialized = true; } //bind the values. - if (source != null) { - for (int i = 0; i < source.Length; i++) { - SQLiteCommand.BindParameter (Statement, i + 1, source[i], Connection.StoreDateTimeAsTicks, Connection.DateTimeStringFormat, Connection.StoreTimeSpanAsTicks); + if (source != null) + { + for (int i = 0; i < source.Length; i++) + { + SQLiteCommand.BindParameter(Statement, i + 1, source[i], Connection.StoreDateTimeAsTicks, Connection.DateTimeStringFormat, Connection.StoreTimeSpanAsTicks); } } - r = SQLite3.Step (Statement); + r = SQLite3.Step(Statement); - if (r == SQLite3.Result.Done) { - int rowsAffected = SQLite3.Changes (Connection.Handle); - SQLite3.Reset (Statement); + if (r == SQLite3.Result.Done) + { + int rowsAffected = SQLite3.Changes(Connection.Handle); + SQLite3.Reset(Statement); return rowsAffected; } - else if (r == SQLite3.Result.Error) { - string msg = SQLite3.GetErrmsg (Connection.Handle); - SQLite3.Reset (Statement); - throw SQLiteException.New (r, msg); + else if (r == SQLite3.Result.Error) + { + string msg = SQLite3.GetErrmsg(Connection.Handle); + SQLite3.Reset(Statement); + throw SQLiteException.New(r, msg); } - else if (r == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode (Connection.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) { - SQLite3.Reset (Statement); - throw NotNullConstraintViolationException.New (r, SQLite3.GetErrmsg (Connection.Handle)); + else if (r == SQLite3.Result.Constraint && SQLite3.ExtendedErrCode(Connection.Handle) == SQLite3.ExtendedResult.ConstraintNotNull) + { + SQLite3.Reset(Statement); + throw NotNullConstraintViolationException.New(r, SQLite3.GetErrmsg(Connection.Handle)); } - else { - SQLite3.Reset (Statement); - throw SQLiteException.New (r, SQLite3.GetErrmsg (Connection.Handle)); + else + { + SQLite3.Reset(Statement); + throw SQLiteException.New(r, SQLite3.GetErrmsg(Connection.Handle)); } } - public void Dispose () + public void Dispose() { - Dispose (true); - GC.SuppressFinalize (this); + Dispose(true); + GC.SuppressFinalize(this); } - void Dispose (bool disposing) + void Dispose(bool disposing) { var s = Statement; Statement = NullStatement; Connection = null; - if (s != NullStatement) { - SQLite3.Finalize (s); + if (s != NullStatement) + { + SQLite3.Finalize(s); } } - ~PreparedSqlLiteInsertCommand () + ~PreparedSqlLiteInsertCommand() { - Dispose (false); + Dispose(false); } } @@ -3815,9 +4234,9 @@ public class CreateTablesResult { public Dictionary Results { get; private set; } - public CreateTablesResult () + public CreateTablesResult() { - Results = new Dictionary (); + Results = new Dictionary(); } } @@ -3849,25 +4268,26 @@ public class TableQuery : BaseTableQuery, IEnumerable Expression _selector; - TableQuery (SQLiteConnection conn, TableMapping table) + TableQuery(SQLiteConnection conn, TableMapping table) { Connection = conn; Table = table; } - public TableQuery (SQLiteConnection conn) + public TableQuery(SQLiteConnection conn, string tableName = null) { Connection = conn; - Table = Connection.GetMapping (typeof (T)); + Table = Connection.GetMapping(tableName); } - public TableQuery Clone () + public TableQuery Clone() { - var q = new TableQuery (Connection, Table); + var q = new TableQuery(Connection, Table); q._where = _where; q._deferred = _deferred; - if (_orderBys != null) { - q._orderBys = new List (_orderBys); + if (_orderBys != null) + { + q._orderBys = new List(_orderBys); } q._limit = _limit; q._offset = _offset; @@ -3883,63 +4303,66 @@ public TableQuery Clone () /// /// Filters the query based on a predicate. /// - public TableQuery Where (Expression> predExpr) + public TableQuery Where(Expression> predExpr) { - if (predExpr.NodeType == ExpressionType.Lambda) { + if (predExpr.NodeType == ExpressionType.Lambda) + { var lambda = (LambdaExpression)predExpr; var pred = lambda.Body; - var q = Clone (); - q.AddWhere (pred); + var q = Clone(); + q.AddWhere(pred); return q; } - else { - throw new NotSupportedException ("Must be a predicate"); + else + { + throw new NotSupportedException("Must be a predicate"); } } /// /// Delete all the rows that match this query. /// - public int Delete () + public int Delete() { - return Delete (null); + return Delete(null); } /// /// Delete all the rows that match this query and the given predicate. /// - public int Delete (Expression> predExpr) + public int Delete(Expression> predExpr) { if (_limit.HasValue || _offset.HasValue) - throw new InvalidOperationException ("Cannot delete with limits or offsets"); + throw new InvalidOperationException("Cannot delete with limits or offsets"); if (_where == null && predExpr == null) - throw new InvalidOperationException ("No condition specified"); + throw new InvalidOperationException("No condition specified"); var pred = _where; - if (predExpr != null && predExpr.NodeType == ExpressionType.Lambda) { + if (predExpr != null && predExpr.NodeType == ExpressionType.Lambda) + { var lambda = (LambdaExpression)predExpr; - pred = pred != null ? Expression.AndAlso (pred, lambda.Body) : lambda.Body; + pred = pred != null ? Expression.AndAlso(pred, lambda.Body) : lambda.Body; } - var args = new List (); + var args = new List(); var cmdText = "delete from \"" + Table.TableName + "\""; - var w = CompileExpr (pred, args); + var w = CompileExpr(pred, args); cmdText += " where " + w.CommandText; - var command = Connection.CreateCommand (cmdText, args.ToArray ()); + var command = Connection.CreateCommand(cmdText, args.ToArray()); - int result = command.ExecuteNonQuery (); + int result = command.ExecuteNonQuery(); return result; } /// /// Yields a given number of elements from the query and then skips the remainder. /// - public TableQuery Take (int n) + public TableQuery Take(int n) { - var q = Clone (); + var q = Clone(); q._limit = n; return q; } @@ -3947,9 +4370,9 @@ public TableQuery Take (int n) /// /// Skips a given number of elements from the query and then yields the remainder. /// - public TableQuery Skip (int n) + public TableQuery Skip(int n) { - var q = Clone (); + var q = Clone(); q._offset = n; return q; } @@ -3957,15 +4380,15 @@ public TableQuery Skip (int n) /// /// Returns the element at a given index /// - public T ElementAt (int index) + public T ElementAt(int index) { - return Skip (index).Take (1).First (); + return Skip(index).Take(1).First(); } bool _deferred; - public TableQuery Deferred () + public TableQuery Deferred() { - var q = Clone (); + var q = Clone(); q._deferred = true; return q; } @@ -3973,77 +4396,87 @@ public TableQuery Deferred () /// /// Order the query results according to a key. /// - public TableQuery OrderBy (Expression> orderExpr) + public TableQuery OrderBy(Expression> orderExpr) { - return AddOrderBy (orderExpr, true); + return AddOrderBy(orderExpr, true); } /// /// Order the query results according to a key. /// - public TableQuery OrderByDescending (Expression> orderExpr) + public TableQuery OrderByDescending(Expression> orderExpr) { - return AddOrderBy (orderExpr, false); + return AddOrderBy(orderExpr, false); } /// /// Order the query results according to a key. /// - public TableQuery ThenBy (Expression> orderExpr) + public TableQuery ThenBy(Expression> orderExpr) { - return AddOrderBy (orderExpr, true); + return AddOrderBy(orderExpr, true); } /// /// Order the query results according to a key. /// - public TableQuery ThenByDescending (Expression> orderExpr) + public TableQuery ThenByDescending(Expression> orderExpr) { - return AddOrderBy (orderExpr, false); + return AddOrderBy(orderExpr, false); } - TableQuery AddOrderBy (Expression> orderExpr, bool asc) + TableQuery AddOrderBy(Expression> orderExpr, bool asc) { - if (orderExpr.NodeType == ExpressionType.Lambda) { + if (orderExpr.NodeType == ExpressionType.Lambda) + { var lambda = (LambdaExpression)orderExpr; MemberExpression mem = null; var unary = lambda.Body as UnaryExpression; - if (unary != null && unary.NodeType == ExpressionType.Convert) { + if (unary != null && unary.NodeType == ExpressionType.Convert) + { mem = unary.Operand as MemberExpression; } - else { + else + { mem = lambda.Body as MemberExpression; } - if (mem != null && (mem.Expression.NodeType == ExpressionType.Parameter)) { - var q = Clone (); - if (q._orderBys == null) { - q._orderBys = new List (); + if (mem != null && (mem.Expression.NodeType == ExpressionType.Parameter)) + { + var q = Clone(); + if (q._orderBys == null) + { + q._orderBys = new List(); } - q._orderBys.Add (new Ordering { - ColumnName = Table.FindColumnWithPropertyName (mem.Member.Name).Name, + q._orderBys.Add(new Ordering + { + ColumnName = Table.FindColumnWithPropertyName(mem.Member.Name).Name, Ascending = asc }); return q; } - else { - throw new NotSupportedException ("Order By does not support: " + orderExpr); + else + { + throw new NotSupportedException("Order By does not support: " + orderExpr); } } - else { - throw new NotSupportedException ("Must be a predicate"); + else + { + throw new NotSupportedException("Must be a predicate"); } } - private void AddWhere (Expression pred) + private void AddWhere(Expression pred) { - if (_where == null) { + if (_where == null) + { _where = pred; } - else { - _where = Expression.AndAlso (_where, pred); + else + { + _where = Expression.AndAlso(_where, pred); } } @@ -4075,32 +4508,39 @@ private void AddWhere (Expression pred) // return q; //} - private SQLiteCommand GenerateCommand (string selectionList) + private SQLiteCommand GenerateCommand(string selectionList) { - if (_joinInner != null && _joinOuter != null) { - throw new NotSupportedException ("Joins are not supported."); + if (_joinInner != null && _joinOuter != null) + { + throw new NotSupportedException("Joins are not supported."); } - else { + else + { var cmdText = "select " + selectionList + " from \"" + Table.TableName + "\""; - var args = new List (); - if (_where != null) { - var w = CompileExpr (_where, args); + var args = new List(); + if (_where != null) + { + var w = CompileExpr(_where, args); cmdText += " where " + w.CommandText; } - if ((_orderBys != null) && (_orderBys.Count > 0)) { - var t = string.Join (", ", _orderBys.Select (o => "\"" + o.ColumnName + "\"" + (o.Ascending ? "" : " desc")).ToArray ()); + if ((_orderBys != null) && (_orderBys.Count > 0)) + { + var t = string.Join(", ", _orderBys.Select(o => "\"" + o.ColumnName + "\"" + (o.Ascending ? "" : " desc")).ToArray()); cmdText += " order by " + t; } - if (_limit.HasValue) { + if (_limit.HasValue) + { cmdText += " limit " + _limit.Value; } - if (_offset.HasValue) { - if (!_limit.HasValue) { + if (_offset.HasValue) + { + if (!_limit.HasValue) + { cmdText += " limit -1 "; } cmdText += " offset " + _offset.Value; } - return Connection.CreateCommand (cmdText, args.ToArray ()); + return Connection.CreateCommand(cmdText, args.ToArray()); } } @@ -4111,83 +4551,98 @@ class CompileResult public object Value { get; set; } } - private CompileResult CompileExpr (Expression expr, List queryArgs) + private CompileResult CompileExpr(Expression expr, List queryArgs) { - if (expr == null) { - throw new NotSupportedException ("Expression is NULL"); + if (expr == null) + { + throw new NotSupportedException("Expression is NULL"); } - else if (expr is BinaryExpression) { + else if (expr is BinaryExpression) + { var bin = (BinaryExpression)expr; // VB turns 'x=="foo"' into 'CompareString(x,"foo",true/false)==0', so we need to unwrap it // http://blogs.msdn.com/b/vbteam/archive/2007/09/18/vb-expression-trees-string-comparisons.aspx - if (bin.Left.NodeType == ExpressionType.Call) { + if (bin.Left.NodeType == ExpressionType.Call) + { var call = (MethodCallExpression)bin.Left; if (call.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && call.Method.Name == "CompareString") - bin = Expression.MakeBinary (bin.NodeType, call.Arguments[0], call.Arguments[1]); + bin = Expression.MakeBinary(bin.NodeType, call.Arguments[0], call.Arguments[1]); } - var leftr = CompileExpr (bin.Left, queryArgs); - var rightr = CompileExpr (bin.Right, queryArgs); + var leftr = CompileExpr(bin.Left, queryArgs); + var rightr = CompileExpr(bin.Right, queryArgs); //If either side is a parameter and is null, then handle the other side specially (for "is null"/"is not null") string text; if (leftr.CommandText == "?" && leftr.Value == null) - text = CompileNullBinaryExpression (bin, rightr); + text = CompileNullBinaryExpression(bin, rightr); else if (rightr.CommandText == "?" && rightr.Value == null) - text = CompileNullBinaryExpression (bin, leftr); + text = CompileNullBinaryExpression(bin, leftr); else - text = "(" + leftr.CommandText + " " + GetSqlName (bin) + " " + rightr.CommandText + ")"; + text = "(" + leftr.CommandText + " " + GetSqlName(bin) + " " + rightr.CommandText + ")"; return new CompileResult { CommandText = text }; } - else if (expr.NodeType == ExpressionType.Not) { + else if (expr.NodeType == ExpressionType.Not) + { var operandExpr = ((UnaryExpression)expr).Operand; - var opr = CompileExpr (operandExpr, queryArgs); + var opr = CompileExpr(operandExpr, queryArgs); object val = opr.Value; if (val is bool) val = !((bool)val); - return new CompileResult { + return new CompileResult + { CommandText = "NOT(" + opr.CommandText + ")", Value = val }; } - else if (expr.NodeType == ExpressionType.Call) { + else if (expr.NodeType == ExpressionType.Call) + { var call = (MethodCallExpression)expr; var args = new CompileResult[call.Arguments.Count]; - var obj = call.Object != null ? CompileExpr (call.Object, queryArgs) : null; + var obj = call.Object != null ? CompileExpr(call.Object, queryArgs) : null; - for (var i = 0; i < args.Length; i++) { - args[i] = CompileExpr (call.Arguments[i], queryArgs); + for (var i = 0; i < args.Length; i++) + { + args[i] = CompileExpr(call.Arguments[i], queryArgs); } var sqlCall = ""; - if (call.Method.Name == "Like" && args.Length == 2) { + if (call.Method.Name == "Like" && args.Length == 2) + { sqlCall = "(" + args[0].CommandText + " like " + args[1].CommandText + ")"; } - else if (call.Method.Name == "Contains" && args.Length == 2) { + else if (call.Method.Name == "Contains" && args.Length == 2) + { sqlCall = "(" + args[1].CommandText + " in " + args[0].CommandText + ")"; } - else if (call.Method.Name == "Contains" && args.Length == 1) { - if (call.Object != null && call.Object.Type == typeof (string)) { + else if (call.Method.Name == "Contains" && args.Length == 1) + { + if (call.Object != null && call.Object.Type == typeof(string)) + { sqlCall = "( instr(" + obj.CommandText + "," + args[0].CommandText + ") >0 )"; } - else { + else + { sqlCall = "(" + args[0].CommandText + " in " + obj.CommandText + ")"; } } - else if (call.Method.Name == "StartsWith" && args.Length >= 1) { + else if (call.Method.Name == "StartsWith" && args.Length >= 1) + { var startsWithCmpOp = StringComparison.CurrentCulture; - if (args.Length == 2) { + if (args.Length == 2) + { startsWithCmpOp = (StringComparison)args[1].Value; } - switch (startsWithCmpOp) { + switch (startsWithCmpOp) + { case StringComparison.Ordinal: case StringComparison.CurrentCulture: - sqlCall = "( substr(" + obj.CommandText + ", 1, " + args[0].Value.ToString ().Length + ") = " + args[0].CommandText + ")"; + sqlCall = "( substr(" + obj.CommandText + ", 1, " + args[0].Value.ToString().Length + ") = " + args[0].CommandText + ")"; break; case StringComparison.OrdinalIgnoreCase: case StringComparison.CurrentCultureIgnoreCase: @@ -4196,15 +4651,18 @@ private CompileResult CompileExpr (Expression expr, List queryArgs) } } - else if (call.Method.Name == "EndsWith" && args.Length >= 1) { + else if (call.Method.Name == "EndsWith" && args.Length >= 1) + { var endsWithCmpOp = StringComparison.CurrentCulture; - if (args.Length == 2) { + if (args.Length == 2) + { endsWithCmpOp = (StringComparison)args[1].Value; } - switch (endsWithCmpOp) { + switch (endsWithCmpOp) + { case StringComparison.Ordinal: case StringComparison.CurrentCulture: - sqlCall = "( substr(" + obj.CommandText + ", length(" + obj.CommandText + ") - " + args[0].Value.ToString ().Length + "+1, " + args[0].Value.ToString ().Length + ") = " + args[0].CommandText + ")"; + sqlCall = "( substr(" + obj.CommandText + ", length(" + obj.CommandText + ") - " + args[0].Value.ToString().Length + "+1, " + args[0].Value.ToString().Length + ") = " + args[0].CommandText + ")"; break; case StringComparison.OrdinalIgnoreCase: case StringComparison.CurrentCultureIgnoreCase: @@ -4212,72 +4670,90 @@ private CompileResult CompileExpr (Expression expr, List queryArgs) break; } } - else if (call.Method.Name == "Equals" && args.Length == 1) { + else if (call.Method.Name == "Equals" && args.Length == 1) + { sqlCall = "(" + obj.CommandText + " = (" + args[0].CommandText + "))"; } - else if (call.Method.Name == "ToLower") { + else if (call.Method.Name == "ToLower") + { sqlCall = "(lower(" + obj.CommandText + "))"; } - else if (call.Method.Name == "ToUpper") { + else if (call.Method.Name == "ToUpper") + { sqlCall = "(upper(" + obj.CommandText + "))"; } - else if (call.Method.Name == "Replace" && args.Length == 2) { + else if (call.Method.Name == "Replace" && args.Length == 2) + { sqlCall = "(replace(" + obj.CommandText + "," + args[0].CommandText + "," + args[1].CommandText + "))"; } - else if (call.Method.Name == "IsNullOrEmpty" && args.Length == 1) { + else if (call.Method.Name == "IsNullOrEmpty" && args.Length == 1) + { sqlCall = "(" + args[0].CommandText + " is null or" + args[0].CommandText + " ='' )"; } - else { - sqlCall = call.Method.Name.ToLower () + "(" + string.Join (",", args.Select (a => a.CommandText).ToArray ()) + ")"; + else + { + sqlCall = call.Method.Name.ToLower() + "(" + string.Join(",", args.Select(a => a.CommandText).ToArray()) + ")"; } return new CompileResult { CommandText = sqlCall }; } - else if (expr.NodeType == ExpressionType.Constant) { + else if (expr.NodeType == ExpressionType.Constant) + { var c = (ConstantExpression)expr; - queryArgs.Add (c.Value); - return new CompileResult { + queryArgs.Add(c.Value); + return new CompileResult + { CommandText = "?", Value = c.Value }; } - else if (expr.NodeType == ExpressionType.Convert) { + else if (expr.NodeType == ExpressionType.Convert) + { var u = (UnaryExpression)expr; var ty = u.Type; - var valr = CompileExpr (u.Operand, queryArgs); - return new CompileResult { + var valr = CompileExpr(u.Operand, queryArgs); + return new CompileResult + { CommandText = valr.CommandText, - Value = valr.Value != null ? ConvertTo (valr.Value, ty) : null + Value = valr.Value != null ? ConvertTo(valr.Value, ty) : null }; } - else if (expr.NodeType == ExpressionType.MemberAccess) { + else if (expr.NodeType == ExpressionType.MemberAccess) + { var mem = (MemberExpression)expr; var paramExpr = mem.Expression as ParameterExpression; - if (paramExpr == null) { + if (paramExpr == null) + { var convert = mem.Expression as UnaryExpression; - if (convert != null && convert.NodeType == ExpressionType.Convert) { + if (convert != null && convert.NodeType == ExpressionType.Convert) + { paramExpr = convert.Operand as ParameterExpression; } } - if (paramExpr != null) { + if (paramExpr != null) + { // // This is a column of our table, output just the column name // Need to translate it if that column name is mapped // - var columnName = Table.FindColumnWithPropertyName (mem.Member.Name).Name; + var columnName = Table.FindColumnWithPropertyName(mem.Member.Name).Name; return new CompileResult { CommandText = "\"" + columnName + "\"" }; } - else { + else + { object obj = null; - if (mem.Expression != null) { - var r = CompileExpr (mem.Expression, queryArgs); - if (r.Value == null) { - throw new NotSupportedException ("Member access failed to compile expression"); + if (mem.Expression != null) + { + var r = CompileExpr(mem.Expression, queryArgs); + if (r.Value == null) + { + throw new NotSupportedException("Member access failed to compile expression"); } - if (r.CommandText == "?") { - queryArgs.RemoveAt (queryArgs.Count - 1); + if (r.CommandText == "?") + { + queryArgs.RemoveAt(queryArgs.Count - 1); } obj = r.Value; } @@ -4287,60 +4763,70 @@ private CompileResult CompileExpr (Expression expr, List queryArgs) // object val = null; - if (mem.Member is PropertyInfo) { + if (mem.Member is PropertyInfo) + { var m = (PropertyInfo)mem.Member; - val = m.GetValue (obj, null); + val = m.GetValue(obj, null); } - else if (mem.Member is FieldInfo) { + else if (mem.Member is FieldInfo) + { var m = (FieldInfo)mem.Member; - val = m.GetValue (obj); + val = m.GetValue(obj); } - else { - throw new NotSupportedException ("MemberExpr: " + mem.Member.GetType ()); + else + { + throw new NotSupportedException("MemberExpr: " + mem.Member.GetType()); } // // Work special magic for enumerables // - if (val != null && val is System.Collections.IEnumerable && !(val is string) && !(val is System.Collections.Generic.IEnumerable)) { - var sb = new System.Text.StringBuilder (); - sb.Append ("("); + if (val != null && val is System.Collections.IEnumerable && !(val is string) && !(val is System.Collections.Generic.IEnumerable)) + { + var sb = new System.Text.StringBuilder(); + sb.Append("("); var head = ""; - foreach (var a in (System.Collections.IEnumerable)val) { - queryArgs.Add (a); - sb.Append (head); - sb.Append ("?"); + foreach (var a in (System.Collections.IEnumerable)val) + { + queryArgs.Add(a); + sb.Append(head); + sb.Append("?"); head = ","; } - sb.Append (")"); - return new CompileResult { - CommandText = sb.ToString (), + sb.Append(")"); + return new CompileResult + { + CommandText = sb.ToString(), Value = val }; } - else { - queryArgs.Add (val); - return new CompileResult { + else + { + queryArgs.Add(val); + return new CompileResult + { CommandText = "?", Value = val }; } } } - throw new NotSupportedException ("Cannot compile: " + expr.NodeType.ToString ()); + throw new NotSupportedException("Cannot compile: " + expr.NodeType.ToString()); } - static object ConvertTo (object obj, Type t) + static object ConvertTo(object obj, Type t) { - Type nut = Nullable.GetUnderlyingType (t); + Type nut = Nullable.GetUnderlyingType(t); - if (nut != null) { + if (nut != null) + { if (obj == null) return null; - return Convert.ChangeType (obj, nut); + return Convert.ChangeType(obj, nut); } - else { - return Convert.ChangeType (obj, t); + else + { + return Convert.ChangeType(obj, t); } } @@ -4349,7 +4835,7 @@ static object ConvertTo (object obj, Type t) /// /// The expression to compile /// The non-null parameter - private string CompileNullBinaryExpression (BinaryExpression expression, CompileResult parameter) + private string CompileNullBinaryExpression(BinaryExpression expression, CompileResult parameter) { if (expression.NodeType == ExpressionType.Equal) return "(" + parameter.CommandText + " is ?)"; @@ -4361,124 +4847,134 @@ private string CompileNullBinaryExpression (BinaryExpression expression, Compile || expression.NodeType == ExpressionType.LessThanOrEqual) return "(" + parameter.CommandText + " < ?)"; // always false else - throw new NotSupportedException ("Cannot compile Null-BinaryExpression with type " + expression.NodeType.ToString ()); + throw new NotSupportedException("Cannot compile Null-BinaryExpression with type " + expression.NodeType.ToString()); } - string GetSqlName (Expression expr) + string GetSqlName(Expression expr) { var n = expr.NodeType; if (n == ExpressionType.GreaterThan) return ">"; - else if (n == ExpressionType.GreaterThanOrEqual) { + else if (n == ExpressionType.GreaterThanOrEqual) + { return ">="; } - else if (n == ExpressionType.LessThan) { + else if (n == ExpressionType.LessThan) + { return "<"; } - else if (n == ExpressionType.LessThanOrEqual) { + else if (n == ExpressionType.LessThanOrEqual) + { return "<="; } - else if (n == ExpressionType.And) { + else if (n == ExpressionType.And) + { return "&"; } - else if (n == ExpressionType.AndAlso) { + else if (n == ExpressionType.AndAlso) + { return "and"; } - else if (n == ExpressionType.Or) { + else if (n == ExpressionType.Or) + { return "|"; } - else if (n == ExpressionType.OrElse) { + else if (n == ExpressionType.OrElse) + { return "or"; } - else if (n == ExpressionType.Equal) { + else if (n == ExpressionType.Equal) + { return "="; } - else if (n == ExpressionType.NotEqual) { + else if (n == ExpressionType.NotEqual) + { return "!="; } - else { - throw new NotSupportedException ("Cannot get SQL for: " + n); + else + { + throw new NotSupportedException("Cannot get SQL for: " + n); } } /// /// Execute SELECT COUNT(*) on the query /// - public int Count () + public int Count() { - return GenerateCommand ("count(*)").ExecuteScalar (); + return GenerateCommand("count(*)").ExecuteScalar(); } /// /// Execute SELECT COUNT(*) on the query with an additional WHERE clause. /// - public int Count (Expression> predExpr) + public int Count(Expression> predExpr) { - return Where (predExpr).Count (); + return Where(predExpr).Count(); } - public IEnumerator GetEnumerator () + public IEnumerator GetEnumerator() { if (!_deferred) - return GenerateCommand ("*").ExecuteQuery ().GetEnumerator (); + return GenerateCommand("*").ExecuteQuery(Table.TableName).GetEnumerator(); - return GenerateCommand ("*").ExecuteDeferredQuery ().GetEnumerator (); + return GenerateCommand("*").ExecuteDeferredQuery(Table.TableName).GetEnumerator(); } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { - return GetEnumerator (); + return GetEnumerator(); } /// /// Queries the database and returns the results as a List. /// - public List ToList () + public List ToList() { - return GenerateCommand ("*").ExecuteQuery (); + return GenerateCommand("*").ExecuteQuery(Table.TableName); } /// /// Queries the database and returns the results as an array. /// - public T[] ToArray () + public T[] ToArray() { - return GenerateCommand ("*").ExecuteQuery ().ToArray (); + return GenerateCommand("*").ExecuteQuery(Table.TableName).ToArray(); } /// /// Returns the first element of this query. /// - public T First () + public T First() { - var query = Take (1); - return query.ToList ().First (); + var query = Take(1); + return query.ToList().First(); } /// /// Returns the first element of this query, or null if no element is found. /// - public T FirstOrDefault () + public T FirstOrDefault() { - var query = Take (1); - return query.ToList ().FirstOrDefault (); + var query = Take(1); + return query.ToList().FirstOrDefault(); } /// /// Returns the first element of this query that matches the predicate. /// - public T First (Expression> predExpr) + public T First(Expression> predExpr) { - return Where (predExpr).First (); + return Where(predExpr).First(); } /// /// Returns the first element of this query that matches the predicate, or null /// if no element is found. /// - public T FirstOrDefault (Expression> predExpr) + public T FirstOrDefault(Expression> predExpr) { - return Where (predExpr).FirstOrDefault (); + return Where(predExpr).FirstOrDefault(); } } @@ -4583,182 +5079,183 @@ public enum ConfigOption : int #endif #if !USE_CSHARP_SQLITE && !USE_WP8_NATIVE_SQLITE && !USE_SQLITEPCL_RAW - [DllImport(LibraryPath, EntryPoint = "sqlite3_threadsafe", CallingConvention=CallingConvention.Cdecl)] - public static extern int Threadsafe (); + [DllImport(LibraryPath, EntryPoint = "sqlite3_threadsafe", CallingConvention = CallingConvention.Cdecl)] + public static extern int Threadsafe(); - [DllImport(LibraryPath, EntryPoint = "sqlite3_open", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Open ([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_open", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Open([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db); - [DllImport(LibraryPath, EntryPoint = "sqlite3_open_v2", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Open ([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db, int flags, [MarshalAs (UnmanagedType.LPStr)] string zvfs); + [DllImport(LibraryPath, EntryPoint = "sqlite3_open_v2", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Open([MarshalAs(UnmanagedType.LPStr)] string filename, out IntPtr db, int flags, [MarshalAs(UnmanagedType.LPStr)] string zvfs); [DllImport(LibraryPath, EntryPoint = "sqlite3_open_v2", CallingConvention = CallingConvention.Cdecl)] - public static extern Result Open(byte[] filename, out IntPtr db, int flags, [MarshalAs (UnmanagedType.LPStr)] string zvfs); + public static extern Result Open(byte[] filename, out IntPtr db, int flags, [MarshalAs(UnmanagedType.LPStr)] string zvfs); [DllImport(LibraryPath, EntryPoint = "sqlite3_open16", CallingConvention = CallingConvention.Cdecl)] public static extern Result Open16([MarshalAs(UnmanagedType.LPWStr)] string filename, out IntPtr db); - [DllImport(LibraryPath, EntryPoint = "sqlite3_enable_load_extension", CallingConvention=CallingConvention.Cdecl)] - public static extern Result EnableLoadExtension (IntPtr db, int onoff); + [DllImport(LibraryPath, EntryPoint = "sqlite3_enable_load_extension", CallingConvention = CallingConvention.Cdecl)] + public static extern Result EnableLoadExtension(IntPtr db, int onoff); - [DllImport(LibraryPath, EntryPoint = "sqlite3_close", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Close (IntPtr db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_close", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Close(IntPtr db); [DllImport(LibraryPath, EntryPoint = "sqlite3_close_v2", CallingConvention = CallingConvention.Cdecl)] public static extern Result Close2(IntPtr db); - [DllImport(LibraryPath, EntryPoint = "sqlite3_initialize", CallingConvention=CallingConvention.Cdecl)] + [DllImport(LibraryPath, EntryPoint = "sqlite3_initialize", CallingConvention = CallingConvention.Cdecl)] public static extern Result Initialize(); - [DllImport(LibraryPath, EntryPoint = "sqlite3_shutdown", CallingConvention=CallingConvention.Cdecl)] + [DllImport(LibraryPath, EntryPoint = "sqlite3_shutdown", CallingConvention = CallingConvention.Cdecl)] public static extern Result Shutdown(); - [DllImport(LibraryPath, EntryPoint = "sqlite3_config", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Config (ConfigOption option); + [DllImport(LibraryPath, EntryPoint = "sqlite3_config", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Config(ConfigOption option); #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN - [DllImport(LibraryPath, EntryPoint = "sqlite3_win32_set_directory", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Unicode)] - public static extern int SetDirectory (uint directoryType, string directoryPath); + [DllImport(LibraryPath, EntryPoint = "sqlite3_win32_set_directory", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] + public static extern int SetDirectory(uint directoryType, string directoryPath); #endif - [DllImport(LibraryPath, EntryPoint = "sqlite3_busy_timeout", CallingConvention=CallingConvention.Cdecl)] - public static extern Result BusyTimeout (IntPtr db, int milliseconds); + [DllImport(LibraryPath, EntryPoint = "sqlite3_busy_timeout", CallingConvention = CallingConvention.Cdecl)] + public static extern Result BusyTimeout(IntPtr db, int milliseconds); - [DllImport(LibraryPath, EntryPoint = "sqlite3_changes", CallingConvention=CallingConvention.Cdecl)] - public static extern int Changes (IntPtr db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_changes", CallingConvention = CallingConvention.Cdecl)] + public static extern int Changes(IntPtr db); - [DllImport(LibraryPath, EntryPoint = "sqlite3_prepare_v2", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Prepare2 (IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string sql, int numBytes, out IntPtr stmt, IntPtr pzTail); + [DllImport(LibraryPath, EntryPoint = "sqlite3_prepare_v2", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Prepare2(IntPtr db, [MarshalAs(UnmanagedType.LPStr)] string sql, int numBytes, out IntPtr stmt, IntPtr pzTail); #if NETFX_CORE [DllImport (LibraryPath, EntryPoint = "sqlite3_prepare_v2", CallingConvention = CallingConvention.Cdecl)] public static extern Result Prepare2 (IntPtr db, byte[] queryBytes, int numBytes, out IntPtr stmt, IntPtr pzTail); #endif - public static IntPtr Prepare2 (IntPtr db, string query) + public static IntPtr Prepare2(IntPtr db, string query) { IntPtr stmt; #if NETFX_CORE byte[] queryBytes = System.Text.UTF8Encoding.UTF8.GetBytes (query); var r = Prepare2 (db, queryBytes, queryBytes.Length, out stmt, IntPtr.Zero); #else - var r = Prepare2 (db, query, System.Text.UTF8Encoding.UTF8.GetByteCount (query), out stmt, IntPtr.Zero); + var r = Prepare2(db, query, System.Text.UTF8Encoding.UTF8.GetByteCount(query), out stmt, IntPtr.Zero); #endif - if (r != Result.OK) { - throw SQLiteException.New (r, GetErrmsg (db)); + if (r != Result.OK) + { + throw SQLiteException.New(r, GetErrmsg(db)); } return stmt; } - [DllImport(LibraryPath, EntryPoint = "sqlite3_step", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Step (IntPtr stmt); + [DllImport(LibraryPath, EntryPoint = "sqlite3_step", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Step(IntPtr stmt); - [DllImport(LibraryPath, EntryPoint = "sqlite3_reset", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Reset (IntPtr stmt); + [DllImport(LibraryPath, EntryPoint = "sqlite3_reset", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Reset(IntPtr stmt); - [DllImport(LibraryPath, EntryPoint = "sqlite3_finalize", CallingConvention=CallingConvention.Cdecl)] - public static extern Result Finalize (IntPtr stmt); + [DllImport(LibraryPath, EntryPoint = "sqlite3_finalize", CallingConvention = CallingConvention.Cdecl)] + public static extern Result Finalize(IntPtr stmt); - [DllImport(LibraryPath, EntryPoint = "sqlite3_last_insert_rowid", CallingConvention=CallingConvention.Cdecl)] - public static extern long LastInsertRowid (IntPtr db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_last_insert_rowid", CallingConvention = CallingConvention.Cdecl)] + public static extern long LastInsertRowid(IntPtr db); - [DllImport(LibraryPath, EntryPoint = "sqlite3_errmsg16", CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr Errmsg (IntPtr db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_errmsg16", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr Errmsg(IntPtr db); - public static string GetErrmsg (IntPtr db) + public static string GetErrmsg(IntPtr db) { - return Marshal.PtrToStringUni (Errmsg (db)); + return Marshal.PtrToStringUni(Errmsg(db)); } - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_parameter_index", CallingConvention=CallingConvention.Cdecl)] - public static extern int BindParameterIndex (IntPtr stmt, [MarshalAs(UnmanagedType.LPStr)] string name); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_parameter_index", CallingConvention = CallingConvention.Cdecl)] + public static extern int BindParameterIndex(IntPtr stmt, [MarshalAs(UnmanagedType.LPStr)] string name); - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_null", CallingConvention=CallingConvention.Cdecl)] - public static extern int BindNull (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_null", CallingConvention = CallingConvention.Cdecl)] + public static extern int BindNull(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_int", CallingConvention=CallingConvention.Cdecl)] - public static extern int BindInt (IntPtr stmt, int index, int val); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_int", CallingConvention = CallingConvention.Cdecl)] + public static extern int BindInt(IntPtr stmt, int index, int val); - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_int64", CallingConvention=CallingConvention.Cdecl)] - public static extern int BindInt64 (IntPtr stmt, int index, long val); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_int64", CallingConvention = CallingConvention.Cdecl)] + public static extern int BindInt64(IntPtr stmt, int index, long val); - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_double", CallingConvention=CallingConvention.Cdecl)] - public static extern int BindDouble (IntPtr stmt, int index, double val); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_double", CallingConvention = CallingConvention.Cdecl)] + public static extern int BindDouble(IntPtr stmt, int index, double val); - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_text16", CallingConvention=CallingConvention.Cdecl, CharSet = CharSet.Unicode)] - public static extern int BindText (IntPtr stmt, int index, [MarshalAs(UnmanagedType.LPWStr)] string val, int n, IntPtr free); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_text16", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] + public static extern int BindText(IntPtr stmt, int index, [MarshalAs(UnmanagedType.LPWStr)] string val, int n, IntPtr free); - [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_blob", CallingConvention=CallingConvention.Cdecl)] - public static extern int BindBlob (IntPtr stmt, int index, byte[] val, int n, IntPtr free); + [DllImport(LibraryPath, EntryPoint = "sqlite3_bind_blob", CallingConvention = CallingConvention.Cdecl)] + public static extern int BindBlob(IntPtr stmt, int index, byte[] val, int n, IntPtr free); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_count", CallingConvention=CallingConvention.Cdecl)] - public static extern int ColumnCount (IntPtr stmt); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_count", CallingConvention = CallingConvention.Cdecl)] + public static extern int ColumnCount(IntPtr stmt); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_name", CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr ColumnName (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_name", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr ColumnName(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_name16", CallingConvention=CallingConvention.Cdecl)] - static extern IntPtr ColumnName16Internal (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_name16", CallingConvention = CallingConvention.Cdecl)] + static extern IntPtr ColumnName16Internal(IntPtr stmt, int index); public static string ColumnName16(IntPtr stmt, int index) { return Marshal.PtrToStringUni(ColumnName16Internal(stmt, index)); } - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_type", CallingConvention=CallingConvention.Cdecl)] - public static extern ColType ColumnType (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_type", CallingConvention = CallingConvention.Cdecl)] + public static extern ColType ColumnType(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_int", CallingConvention=CallingConvention.Cdecl)] - public static extern int ColumnInt (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_int", CallingConvention = CallingConvention.Cdecl)] + public static extern int ColumnInt(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_int64", CallingConvention=CallingConvention.Cdecl)] - public static extern long ColumnInt64 (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_int64", CallingConvention = CallingConvention.Cdecl)] + public static extern long ColumnInt64(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_double", CallingConvention=CallingConvention.Cdecl)] - public static extern double ColumnDouble (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_double", CallingConvention = CallingConvention.Cdecl)] + public static extern double ColumnDouble(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_text", CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr ColumnText (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_text", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr ColumnText(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_text16", CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr ColumnText16 (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_text16", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr ColumnText16(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_blob", CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr ColumnBlob (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_blob", CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr ColumnBlob(IntPtr stmt, int index); - [DllImport(LibraryPath, EntryPoint = "sqlite3_column_bytes", CallingConvention=CallingConvention.Cdecl)] - public static extern int ColumnBytes (IntPtr stmt, int index); + [DllImport(LibraryPath, EntryPoint = "sqlite3_column_bytes", CallingConvention = CallingConvention.Cdecl)] + public static extern int ColumnBytes(IntPtr stmt, int index); - public static string ColumnString (IntPtr stmt, int index) + public static string ColumnString(IntPtr stmt, int index) { - return Marshal.PtrToStringUni (SQLite3.ColumnText16 (stmt, index)); + return Marshal.PtrToStringUni(SQLite3.ColumnText16(stmt, index)); } - public static byte[] ColumnByteArray (IntPtr stmt, int index) + public static byte[] ColumnByteArray(IntPtr stmt, int index) { - int length = ColumnBytes (stmt, index); + int length = ColumnBytes(stmt, index); var result = new byte[length]; if (length > 0) - Marshal.Copy (ColumnBlob (stmt, index), result, 0, length); + Marshal.Copy(ColumnBlob(stmt, index), result, 0, length); return result; } - [DllImport (LibraryPath, EntryPoint = "sqlite3_errcode", CallingConvention = CallingConvention.Cdecl)] - public static extern Result GetResult (Sqlite3DatabaseHandle db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_errcode", CallingConvention = CallingConvention.Cdecl)] + public static extern Result GetResult(Sqlite3DatabaseHandle db); - [DllImport (LibraryPath, EntryPoint = "sqlite3_extended_errcode", CallingConvention = CallingConvention.Cdecl)] - public static extern ExtendedResult ExtendedErrCode (IntPtr db); + [DllImport(LibraryPath, EntryPoint = "sqlite3_extended_errcode", CallingConvention = CallingConvention.Cdecl)] + public static extern ExtendedResult ExtendedErrCode(IntPtr db); - [DllImport (LibraryPath, EntryPoint = "sqlite3_libversion_number", CallingConvention = CallingConvention.Cdecl)] - public static extern int LibVersionNumber (); + [DllImport(LibraryPath, EntryPoint = "sqlite3_libversion_number", CallingConvention = CallingConvention.Cdecl)] + public static extern int LibVersionNumber(); - [DllImport (LibraryPath, EntryPoint = "sqlite3_backup_init", CallingConvention = CallingConvention.Cdecl)] - public static extern Sqlite3BackupHandle BackupInit (Sqlite3DatabaseHandle destDb, [MarshalAs (UnmanagedType.LPStr)] string destName, Sqlite3DatabaseHandle sourceDb, [MarshalAs (UnmanagedType.LPStr)] string sourceName); + [DllImport(LibraryPath, EntryPoint = "sqlite3_backup_init", CallingConvention = CallingConvention.Cdecl)] + public static extern Sqlite3BackupHandle BackupInit(Sqlite3DatabaseHandle destDb, [MarshalAs(UnmanagedType.LPStr)] string destName, Sqlite3DatabaseHandle sourceDb, [MarshalAs(UnmanagedType.LPStr)] string sourceName); - [DllImport (LibraryPath, EntryPoint = "sqlite3_backup_step", CallingConvention = CallingConvention.Cdecl)] - public static extern Result BackupStep (Sqlite3BackupHandle backup, int numPages); + [DllImport(LibraryPath, EntryPoint = "sqlite3_backup_step", CallingConvention = CallingConvention.Cdecl)] + public static extern Result BackupStep(Sqlite3BackupHandle backup, int numPages); - [DllImport (LibraryPath, EntryPoint = "sqlite3_backup_finish", CallingConvention = CallingConvention.Cdecl)] - public static extern Result BackupFinish (Sqlite3BackupHandle backup); + [DllImport(LibraryPath, EntryPoint = "sqlite3_backup_finish", CallingConvention = CallingConvention.Cdecl)] + public static extern Result BackupFinish(Sqlite3BackupHandle backup); #else public static Result Open (string filename, out Sqlite3DatabaseHandle db) {