diff --git a/Example/Assets/Plugins/Android/libs/arm64-v8a/libsqlite3.so b/Example/Assets/Plugins/Android/libs/arm64-v8a/libsqlite3.so
new file mode 100644
index 0000000..1e2ce2d
Binary files /dev/null and b/Example/Assets/Plugins/Android/libs/arm64-v8a/libsqlite3.so differ
diff --git a/Example/Assets/Plugins/Android/libs/armeabi-v7a/libsqlite3.so b/Example/Assets/Plugins/Android/libs/armeabi-v7a/libsqlite3.so
index d69ba56..2c6e2bf 100644
Binary files a/Example/Assets/Plugins/Android/libs/armeabi-v7a/libsqlite3.so and b/Example/Assets/Plugins/Android/libs/armeabi-v7a/libsqlite3.so differ
diff --git a/Example/Assets/Plugins/Android/libs/x86/libsqlite3.so b/Example/Assets/Plugins/Android/libs/x86/libsqlite3.so
index d4d1203..9d08844 100644
Binary files a/Example/Assets/Plugins/Android/libs/x86/libsqlite3.so and b/Example/Assets/Plugins/Android/libs/x86/libsqlite3.so differ
diff --git a/Example/Assets/Plugins/WSA.meta b/Example/Assets/Plugins/WSA.meta
new file mode 100644
index 0000000..474c5be
--- /dev/null
+++ b/Example/Assets/Plugins/WSA.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3e1310ff5b122f347a943bad24333d4f
+folderAsset: yes
+timeCreated: 1507670483
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/WSA/ARM.meta b/Example/Assets/Plugins/WSA/ARM.meta
new file mode 100644
index 0000000..925ac45
--- /dev/null
+++ b/Example/Assets/Plugins/WSA/ARM.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d5a4eb770a3e85941bd12132039ab956
+folderAsset: yes
+timeCreated: 1507670500
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/WSA/ARM/sqlite3.dll b/Example/Assets/Plugins/WSA/ARM/sqlite3.dll
new file mode 100644
index 0000000..53aea09
Binary files /dev/null and b/Example/Assets/Plugins/WSA/ARM/sqlite3.dll differ
diff --git a/Example/Assets/Plugins/WSA/ARM/sqlite3.dll.meta b/Example/Assets/Plugins/WSA/ARM/sqlite3.dll.meta
new file mode 100644
index 0000000..af757b5
--- /dev/null
+++ b/Example/Assets/Plugins/WSA/ARM/sqlite3.dll.meta
@@ -0,0 +1,126 @@
+fileFormatVersion: 2
+guid: 0268b9f97df6a83468be4b296cf6af28
+timeCreated: 1507670500
+licenseType: Pro
+PluginImporter:
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ data:
+ first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude WindowsStoreApps: 0
+ data:
+ first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ data:
+ first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ data:
+ first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ data:
+ first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ data:
+ first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ data:
+ first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ data:
+ first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 1
+ settings:
+ CPU: ARM
+ DontProcess: False
+ PlaceholderPath:
+ SDK: AnySDK
+ ScriptingBackend: AnyScriptingBackend
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/WSA/x64.meta b/Example/Assets/Plugins/WSA/x64.meta
new file mode 100644
index 0000000..83b0b9d
--- /dev/null
+++ b/Example/Assets/Plugins/WSA/x64.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e14810dc75ddd4e4f9bb7b92989cb58b
+folderAsset: yes
+timeCreated: 1507670500
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/WSA/x64/sqlite3.dll b/Example/Assets/Plugins/WSA/x64/sqlite3.dll
new file mode 100644
index 0000000..63096c1
Binary files /dev/null and b/Example/Assets/Plugins/WSA/x64/sqlite3.dll differ
diff --git a/Example/Assets/Plugins/WSA/x64/sqlite3.dll.meta b/Example/Assets/Plugins/WSA/x64/sqlite3.dll.meta
new file mode 100644
index 0000000..51ab767
--- /dev/null
+++ b/Example/Assets/Plugins/WSA/x64/sqlite3.dll.meta
@@ -0,0 +1,126 @@
+fileFormatVersion: 2
+guid: 1e46d058e8bdac745970fdfabe7e67ce
+timeCreated: 1507670500
+licenseType: Pro
+PluginImporter:
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ data:
+ first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude WindowsStoreApps: 0
+ data:
+ first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ data:
+ first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ data:
+ first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ data:
+ first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ data:
+ first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ data:
+ first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ data:
+ first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 1
+ settings:
+ CPU: X64
+ DontProcess: False
+ PlaceholderPath:
+ SDK: AnySDK
+ ScriptingBackend: AnyScriptingBackend
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/WSA/x86.meta b/Example/Assets/Plugins/WSA/x86.meta
new file mode 100644
index 0000000..7587a2b
--- /dev/null
+++ b/Example/Assets/Plugins/WSA/x86.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 9f579691124bfd24a81afafa4c8a09c1
+folderAsset: yes
+timeCreated: 1507670500
+licenseType: Pro
+DefaultImporter:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/WSA/x86/sqlite3.dll b/Example/Assets/Plugins/WSA/x86/sqlite3.dll
new file mode 100644
index 0000000..6667321
Binary files /dev/null and b/Example/Assets/Plugins/WSA/x86/sqlite3.dll differ
diff --git a/Example/Assets/Plugins/WSA/x86/sqlite3.dll.meta b/Example/Assets/Plugins/WSA/x86/sqlite3.dll.meta
new file mode 100644
index 0000000..963467f
--- /dev/null
+++ b/Example/Assets/Plugins/WSA/x86/sqlite3.dll.meta
@@ -0,0 +1,126 @@
+fileFormatVersion: 2
+guid: a0bb909f5b8441e48a1632aef3d543a4
+timeCreated: 1507670500
+licenseType: Pro
+PluginImporter:
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ data:
+ first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude WindowsStoreApps: 0
+ data:
+ first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ data:
+ first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ data:
+ first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ data:
+ first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ data:
+ first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ data:
+ first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ data:
+ first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ data:
+ first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 1
+ settings:
+ CPU: X86
+ DontProcess: False
+ PlaceholderPath:
+ SDK: AnySDK
+ ScriptingBackend: AnyScriptingBackend
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Example/Assets/Plugins/x64/sqlite3.dll b/Example/Assets/Plugins/x64/sqlite3.dll
old mode 100644
new mode 100755
diff --git a/Example/Assets/Plugins/x86/sqlite3.dll b/Example/Assets/Plugins/x86/sqlite3.dll
old mode 100644
new mode 100755
index 4cd5a11..d48a7ef
Binary files a/Example/Assets/Plugins/x86/sqlite3.dll and b/Example/Assets/Plugins/x86/sqlite3.dll differ
diff --git a/Example/Assets/Scripts/DataService.cs b/Example/Assets/Scripts/DataService.cs
index 872f598..558ada1 100644
--- a/Example/Assets/Scripts/DataService.cs
+++ b/Example/Assets/Scripts/DataService.cs
@@ -42,6 +42,11 @@ public DataService(string DatabaseName){
var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName; // this is the path to your StreamingAssets in iOS
// then save to Application.persistentDataPath
File.Copy(loadDb, filepath);
+
+#elif UNITY_STANDALONE_OSX
+ var loadDb = Application.dataPath + "/Resources/Data/StreamingAssets/" + DatabaseName; // this is the path to your StreamingAssets in iOS
+ // then save to Application.persistentDataPath
+ File.Copy(loadDb, filepath);
#else
var loadDb = Application.dataPath + "/StreamingAssets/" + DatabaseName; // this is the path to your StreamingAssets in iOS
// then save to Application.persistentDataPath
diff --git a/Example/Assets/Scripts/SQLite.cs b/Example/Assets/Scripts/SQLite.cs
index 0ddd103..18ce6c3 100644
--- a/Example/Assets/Scripts/SQLite.cs
+++ b/Example/Assets/Scripts/SQLite.cs
@@ -77,7 +77,7 @@ protected NotNullConstraintViolationException (SQLite3.Result r, string message,
{
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;
}
}
@@ -109,16 +109,16 @@ public enum SQLiteOpenFlags {
ProtectionNone = 0x00400000
}
- [Flags]
- public enum CreateFlags
- {
- None = 0,
- ImplicitPK = 1, // create a primary key for field called 'Id' (Orm.ImplicitPkName)
- ImplicitIndex = 2, // create an index for fields ending in 'Id' (Orm.ImplicitIndexSuffix)
- AllImplicit = 3, // do both above
+ [Flags]
+ public enum CreateFlags
+ {
+ None = 0,
+ ImplicitPK = 1, // create a primary key for field called 'Id' (Orm.ImplicitPkName)
+ ImplicitIndex = 2, // create an index for fields ending in 'Id' (Orm.ImplicitIndexSuffix)
+ AllImplicit = 3, // do both above
- AutoIncPK = 4 // force PK field to be auto inc
- }
+ AutoIncPK = 4 // force PK field to be auto inc
+ }
///
/// Represents an open connection to a SQLite database.
@@ -130,7 +130,7 @@ public partial class SQLiteConnection : IDisposable
private Dictionary _mappings = null;
private Dictionary _tables = null;
private System.Diagnostics.Stopwatch _sw;
- private long _elapsedMilliseconds = 0;
+ private TimeSpan _elapsed = default(TimeSpan);
private int _transactionDepth = 0;
private Random _rand = new Random ();
@@ -140,9 +140,47 @@ public partial class SQLiteConnection : IDisposable
public string DatabasePath { get; private set; }
- public bool TimeExecution { get; set; }
+ // Dictionary of synchronization objects.
+ //
+ // To prevent database disruption, a database file must be accessed *synchronously*.
+ // For the purpose we create synchronous objects for each database file and store in the
+ // static dictionary to share it among all connections.
+ // The key of the dictionary is database file path and its value is an object to be used
+ // by lock() statement.
+ //
+ // Use case:
+ // - database file lock is done implicitly and automatically.
+ // - To prepend deadlock, application may lock a database file explicity by either way:
+ // - RunInTransaction(Action) locks the database during the transaction (for insert/update)
+ // - RunInDatabaseLock(Action) similarly locks the database but no transaction (for query)
+ private static Dictionary syncObjects = new Dictionary();
+
+ #region debug tracing
public bool Trace { get; set; }
+ public bool TimeExecution { get; set; }
+
+ public delegate void TraceHandler (string message);
+ public event TraceHandler TraceEvent;
+
+ internal void InvokeTrace (string message)
+ {
+ if (TraceEvent != null) {
+ TraceEvent(message);
+ }
+ }
+
+ public delegate void TimeExecutionHandler (TimeSpan executionTime, TimeSpan totalExecutionTime);
+ public event TimeExecutionHandler TimeExecutionEvent;
+
+ internal void InvokeTimeExecution(TimeSpan executionTime, TimeSpan totalExecutionTime)
+ {
+ if (TimeExecutionEvent != null) {
+ TimeExecutionEvent(executionTime, totalExecutionTime);
+ }
+ }
+
+ #endregion
public bool StoreDateTimeAsTicks { get; private set; }
@@ -181,6 +219,7 @@ public SQLiteConnection (string databasePath, SQLiteOpenFlags openFlags, bool st
throw new ArgumentException ("Must be specified", "databasePath");
DatabasePath = databasePath;
+ mayCreateSyncObject(databasePath);
#if NETFX_CORE
SQLite3.SetDirectory(/*temp directory type*/2, Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
@@ -189,7 +228,7 @@ public SQLiteConnection (string databasePath, SQLiteOpenFlags openFlags, bool st
Sqlite3DatabaseHandle handle;
#if SILVERLIGHT || USE_CSHARP_SQLITE
- var r = SQLite3.Open (databasePath, out handle, (int)openFlags, IntPtr.Zero);
+ var r = SQLite3.Open (databasePath, out handle, (int)openFlags, IntPtr.Zero);
#else
// open using the byte[]
// in the case where the path may include Unicode
@@ -217,14 +256,27 @@ static SQLiteConnection ()
}
}
- public void EnableLoadExtension(int onoff)
- {
- SQLite3.Result r = SQLite3.EnableLoadExtension(Handle, onoff);
+ void mayCreateSyncObject(string databasePath)
+ {
+ if (!syncObjects.ContainsKey(databasePath)) {
+ syncObjects[databasePath] = new object();
+ }
+ }
+
+ ///
+ /// Gets the synchronous object, to be lock the database file for updating.
+ ///
+ /// The sync object.
+ public object SyncObject { get { return syncObjects[DatabasePath];} }
+
+ public void EnableLoadExtension(int onoff)
+ {
+ SQLite3.Result r = SQLite3.EnableLoadExtension(Handle, onoff);
if (r != SQLite3.Result.OK) {
string msg = SQLite3.GetErrmsg (Handle);
throw SQLiteException.New (r, msg);
}
- }
+ }
static byte[] GetNullTerminatedUtf8 (string s)
{
@@ -238,7 +290,9 @@ static byte[] GetNullTerminatedUtf8 (string s)
/// Used to list some code that we want the MonoTouch linker
/// to see, but that we never want to actually execute.
///
+ #pragma warning disable 649
static bool _preserveDuringLinkMagic;
+ #pragma warning restore 649
///
/// Sets a busy handler to sleep the specified amount of time when a table is locked.
@@ -270,14 +324,14 @@ public IEnumerable TableMappings {
///
/// The type whose mapping to the database is returned.
///
- ///
+ ///
/// Optional flags allowing implicit PK and indexes based on naming conventions
///
///
/// 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)
{
if (_mappings == null) {
_mappings = new Dictionary ();
@@ -349,11 +403,11 @@ public int CreateTable(CreateFlags createFlags = CreateFlags.None)
/// later access this schema by calling GetMapping.
///
/// Type to reflect to a database table.
- /// Optional flags allowing implicit PK and indexes based on naming conventions.
+ /// Optional flags allowing implicit PK and indexes based on naming conventions.
///
/// The number of entries added to the database schema.
///
- public int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None)
+ public int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None)
{
if (_tables == null) {
_tables = new Dictionary ();
@@ -404,92 +458,102 @@ public int CreateTable(Type ty, CreateFlags createFlags = CreateFlags.None)
foreach (var indexName in indexes.Keys) {
var index = indexes[indexName];
- var columns = index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray();
- count += CreateIndex(indexName, index.TableName, columns, index.Unique);
+ string[] columnNames = new string[index.Columns.Count];
+ if (index.Columns.Count == 1) {
+ columnNames[0] = index.Columns[0].ColumnName;
+ } else {
+ index.Columns.Sort((lhs, rhs) => {
+ return lhs.Order - rhs.Order;
+ });
+ for (int i = 0, end = index.Columns.Count; i < end; ++i) {
+ columnNames[i] = index.Columns[i].ColumnName;
+ }
+ }
+ count += CreateIndex(indexName, index.TableName, columnNames, index.Unique);
}
return count;
}
- ///
- /// Creates an index for the specified table and columns.
- ///
- /// Name of the index to create
- /// Name of the database table
- /// An array of column names to index
- /// Whether the index should be unique
- 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);
- }
-
- ///
- /// Creates an index for the specified table and column.
- ///
- /// Name of the index to create
- /// Name of the database table
- /// Name of the column to index
- /// Whether the index should be unique
- public int CreateIndex(string indexName, string tableName, string columnName, bool unique = false)
- {
- return CreateIndex(indexName, tableName, new string[] { columnName }, unique);
- }
-
- ///
- /// Creates an index for the specified table and column.
- ///
- /// Name of the database table
- /// Name of the column to index
- /// Whether the index should be unique
- public int CreateIndex(string tableName, string columnName, bool unique = false)
- {
- return CreateIndex(tableName + "_" + columnName, tableName, columnName, unique);
- }
-
- ///
- /// Creates an index for the specified table and columns.
- ///
- /// Name of the database table
- /// An array of column names to index
- /// Whether the index should be unique
- public int CreateIndex(string tableName, string[] columnNames, bool unique = false)
- {
- return CreateIndex(tableName + "_" + string.Join ("_", columnNames), tableName, columnNames, unique);
- }
-
- ///
- /// Creates an index for the specified object property.
- /// e.g. CreateIndex(c => c.Name);
- ///
- /// Type to reflect to a database table.
- /// Property to index
- /// Whether the index should be unique
- public void CreateIndex(Expression> property, bool unique = false)
- {
- MemberExpression mx;
- if (property.Body.NodeType == ExpressionType.Convert)
- {
- mx = ((UnaryExpression)property.Body).Operand as MemberExpression;
- }
- 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");
- }
-
- var propName = propertyInfo.Name;
-
- var map = GetMapping();
- var colName = map.FindColumnWithPropertyName(propName).Name;
-
- CreateIndex(map.TableName, colName, unique);
- }
+ ///
+ /// Creates an index for the specified table and columns.
+ ///
+ /// Name of the index to create
+ /// Name of the database table
+ /// An array of column names to index
+ /// Whether the index should be unique
+ 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);
+ }
+
+ ///
+ /// Creates an index for the specified table and column.
+ ///
+ /// Name of the index to create
+ /// Name of the database table
+ /// Name of the column to index
+ /// Whether the index should be unique
+ public int CreateIndex(string indexName, string tableName, string columnName, bool unique = false)
+ {
+ return CreateIndex(indexName, tableName, new string[] { columnName }, unique);
+ }
+
+ ///
+ /// Creates an index for the specified table and column.
+ ///
+ /// Name of the database table
+ /// Name of the column to index
+ /// Whether the index should be unique
+ public int CreateIndex(string tableName, string columnName, bool unique = false)
+ {
+ return CreateIndex(tableName + "_" + columnName, tableName, columnName, unique);
+ }
+
+ ///
+ /// Creates an index for the specified table and columns.
+ ///
+ /// Name of the database table
+ /// An array of column names to index
+ /// Whether the index should be unique
+ public int CreateIndex(string tableName, string[] columnNames, bool unique = false)
+ {
+ return CreateIndex(tableName + "_" + string.Join ("_", columnNames), tableName, columnNames, unique);
+ }
+
+ ///
+ /// Creates an index for the specified object property.
+ /// e.g. CreateIndex(c => c.Name);
+ ///
+ /// Type to reflect to a database table.
+ /// Property to index
+ /// Whether the index should be unique
+ public void CreateIndex(Expression> property, bool unique = false)
+ {
+ MemberExpression mx;
+ if (property.Body.NodeType == ExpressionType.Convert)
+ {
+ mx = ((UnaryExpression)property.Body).Operand as MemberExpression;
+ }
+ 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");
+ }
+
+ var propName = propertyInfo.Name;
+
+ var map = GetMapping();
+ var colName = map.FindColumnWithPropertyName(propName).Name;
+
+ CreateIndex(map.TableName, colName, unique);
+ }
public class ColumnInfo
{
@@ -611,8 +675,8 @@ public int Execute (string query, params object[] args)
if (TimeExecution) {
_sw.Stop ();
- _elapsedMilliseconds += _sw.ElapsedMilliseconds;
- Debug.WriteLine (string.Format ("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0));
+ _elapsed += _sw.Elapsed;
+ this.InvokeTimeExecution (_sw.Elapsed, _elapsed);
}
return r;
@@ -634,8 +698,8 @@ public T ExecuteScalar (string query, params object[] args)
if (TimeExecution) {
_sw.Stop ();
- _elapsedMilliseconds += _sw.ElapsedMilliseconds;
- Debug.WriteLine (string.Format ("Finished in {0} ms ({1:0.0} s total)", _sw.ElapsedMilliseconds, _elapsedMilliseconds / 1000.0));
+ _elapsed += _sw.Elapsed;
+ this.InvokeTimeExecution (_sw.Elapsed, _elapsed);
}
return r;
@@ -769,21 +833,21 @@ public IEnumerable