Put in the sqlite locker code for windows and unix

This commit is contained in:
Lars Brubaker 2015-09-23 17:50:08 -07:00
parent 9d988fcafe
commit a42c286d05
2 changed files with 250 additions and 208 deletions

View file

@ -281,10 +281,13 @@ namespace SQLiteUnix
/// <param name="ty">Type to reflect to a database table.</param>
public int DropTable(Type ty)
{
TableMapping map = GetMapping(ty);
var query = string.Format("drop table if exists \"{0}\"", map.TableName);
lock (locker)
{
TableMapping map = GetMapping(ty);
var query = string.Format("drop table if exists \"{0}\"", map.TableName);
return Execute(query);
return Execute(query);
}
}
/// <summary>
@ -313,71 +316,74 @@ namespace SQLiteUnix
/// </returns>
public int CreateTable(Type ty)
{
if (_tables == null)
lock (locker)
{
_tables = new Dictionary<string, TableMapping>();
}
TableMapping map;
if (!_tables.TryGetValue(ty.FullName, out map))
{
map = GetMapping(ty);
_tables.Add(ty.FullName, map);
}
var query = "create table if not exists \"" + map.TableName + "\"(\n";
var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks));
var decl = string.Join(",\n", decls.ToArray());
query += decl;
query += ")";
var count = Execute(query);
if (count == 0)
{ //Possible bug: This always seems to return 0?
// Table already exists, migrate it
MigrateTable(map);
}
var indexes = new Dictionary<string, IndexInfo>();
foreach (var c in map.Columns)
{
foreach (var i in c.Indices)
if (_tables == null)
{
var iname = i.Name ?? map.TableName + "_" + c.Name;
IndexInfo iinfo;
if (!indexes.TryGetValue(iname, out iinfo))
{
iinfo = new IndexInfo
{
IndexName = iname,
TableName = map.TableName,
Unique = i.Unique,
Columns = new List<IndexedColumn>()
};
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");
iinfo.Columns.Add(new IndexedColumn
{
Order = i.Order,
ColumnName = c.Name
});
_tables = new Dictionary<string, TableMapping>();
}
}
TableMapping map;
if (!_tables.TryGetValue(ty.FullName, out map))
{
map = GetMapping(ty);
_tables.Add(ty.FullName, map);
}
var query = "create table if not exists \"" + map.TableName + "\"(\n";
foreach (var indexName in indexes.Keys)
{
var index = indexes[indexName];
const string sqlFormat = "create {3} index if not exists \"{0}\" on \"{1}\"(\"{2}\")";
var columns = String.Join("\",\"", index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray());
var sql = String.Format(sqlFormat, indexName, index.TableName, columns, index.Unique ? "unique" : "");
count += Execute(sql);
}
var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks));
var decl = string.Join(",\n", decls.ToArray());
query += decl;
query += ")";
return count;
var count = Execute(query);
if (count == 0)
{ //Possible bug: This always seems to return 0?
// Table already exists, migrate it
MigrateTable(map);
}
var indexes = new Dictionary<string, IndexInfo>();
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
{
IndexName = iname,
TableName = map.TableName,
Unique = i.Unique,
Columns = new List<IndexedColumn>()
};
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");
iinfo.Columns.Add(new IndexedColumn
{
Order = i.Order,
ColumnName = c.Name
});
}
}
foreach (var indexName in indexes.Keys)
{
var index = indexes[indexName];
const string sqlFormat = "create {3} index if not exists \"{0}\" on \"{1}\"(\"{2}\")";
var columns = String.Join("\",\"", index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray());
var sql = String.Format(sqlFormat, indexName, index.TableName, columns, index.Unique ? "unique" : "");
count += Execute(sql);
}
return count;
}
}
public class ColumnInfo
@ -521,28 +527,31 @@ namespace SQLiteUnix
public T ExecuteScalar<T>(string query, params object[] args)
{
var cmd = CreateCommand(query, args);
if (TimeExecution)
lock (locker)
{
if (_sw == null)
var cmd = CreateCommand(query, args);
if (TimeExecution)
{
_sw = new System.Diagnostics.Stopwatch();
if (_sw == null)
{
_sw = new System.Diagnostics.Stopwatch();
}
_sw.Reset();
_sw.Start();
}
_sw.Reset();
_sw.Start();
var r = cmd.ExecuteScalar<T>();
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));
}
return r;
}
var r = cmd.ExecuteScalar<T>();
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));
}
return r;
}
/// <summary>
@ -657,7 +666,10 @@ namespace SQLiteUnix
/// </returns>
public ITableQuery<T> Table<T>() where T : new()
{
return new SQLiteUnix.TableQuery<T>(this);
lock (locker)
{
return new SQLiteUnix.TableQuery<T>(this);
}
}
/// <summary>
@ -970,16 +982,19 @@ namespace SQLiteUnix
/// </param>
public void RunInTransaction(Action action)
{
try
lock (locker)
{
var savePoint = SaveTransactionPoint();
action();
Release(savePoint);
}
catch (Exception)
{
Rollback();
throw;
try
{
var savePoint = SaveTransactionPoint();
action();
Release(savePoint);
}
catch (Exception)
{
Rollback();
throw;
}
}
}
@ -994,15 +1009,18 @@ namespace SQLiteUnix
/// </returns>
public int InsertAll(System.Collections.IEnumerable objects)
{
var c = 0;
RunInTransaction(() =>
lock (locker)
{
foreach (var r in objects)
var c = 0;
RunInTransaction(() =>
{
c += Insert(r);
}
});
return c;
foreach (var r in objects)
{
c += Insert(r);
}
});
return c;
}
}
/// <summary>
@ -1304,14 +1322,17 @@ namespace SQLiteUnix
/// </returns>
public int Delete(object objectToDelete)
{
var map = GetMapping(objectToDelete.GetType());
var pk = map.PK;
if (pk == null)
lock (locker)
{
throw new NotSupportedException("Cannot delete " + map.TableName + ": it has no PK");
var map = GetMapping(objectToDelete.GetType());
var pk = map.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);
return Execute(q, pk.GetValue(objectToDelete));
}
var q = string.Format("delete from \"{0}\" where \"{1}\" = ?", map.TableName, pk.Name);
return Execute(q, pk.GetValue(objectToDelete));
}
/// <summary>

View file

@ -291,10 +291,13 @@ namespace SQLiteWin32
/// <param name="ty">Type to reflect to a database table.</param>
public int DropTable(Type ty)
{
TableMapping map = GetMapping(ty);
var query = string.Format("drop table if exists \"{0}\"", map.TableName);
lock (locker)
{
TableMapping map = GetMapping(ty);
var query = string.Format("drop table if exists \"{0}\"", map.TableName);
return Execute(query);
return Execute(query);
}
}
/// <summary>
@ -323,71 +326,74 @@ namespace SQLiteWin32
/// </returns>
public int CreateTable(Type ty)
{
if (_tables == null)
lock (locker)
{
_tables = new Dictionary<string, TableMapping>();
}
TableMapping map;
if (!_tables.TryGetValue(ty.FullName, out map))
{
map = GetMapping(ty);
_tables.Add(ty.FullName, map);
}
var query = "create table if not exists \"" + map.TableName + "\"(\n";
var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks));
var decl = string.Join(",\n", decls.ToArray());
query += decl;
query += ")";
var count = Execute(query);
if (count == 0)
{ //Possible bug: This always seems to return 0?
// Table already exists, migrate it
MigrateTable(map);
}
var indexes = new Dictionary<string, IndexInfo>();
foreach (var c in map.Columns)
{
foreach (var i in c.Indices)
if (_tables == null)
{
var iname = i.Name ?? map.TableName + "_" + c.Name;
IndexInfo iinfo;
if (!indexes.TryGetValue(iname, out iinfo))
{
iinfo = new IndexInfo
{
IndexName = iname,
TableName = map.TableName,
Unique = i.Unique,
Columns = new List<IndexedColumn>()
};
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");
iinfo.Columns.Add(new IndexedColumn
{
Order = i.Order,
ColumnName = c.Name
});
_tables = new Dictionary<string, TableMapping>();
}
}
TableMapping map;
if (!_tables.TryGetValue(ty.FullName, out map))
{
map = GetMapping(ty);
_tables.Add(ty.FullName, map);
}
var query = "create table if not exists \"" + map.TableName + "\"(\n";
foreach (var indexName in indexes.Keys)
{
var index = indexes[indexName];
const string sqlFormat = "create {3} index if not exists \"{0}\" on \"{1}\"(\"{2}\")";
var columns = String.Join("\",\"", index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray());
var sql = String.Format(sqlFormat, indexName, index.TableName, columns, index.Unique ? "unique" : "");
count += Execute(sql);
}
var decls = map.Columns.Select(p => Orm.SqlDecl(p, StoreDateTimeAsTicks));
var decl = string.Join(",\n", decls.ToArray());
query += decl;
query += ")";
return count;
var count = Execute(query);
if (count == 0)
{ //Possible bug: This always seems to return 0?
// Table already exists, migrate it
MigrateTable(map);
}
var indexes = new Dictionary<string, IndexInfo>();
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
{
IndexName = iname,
TableName = map.TableName,
Unique = i.Unique,
Columns = new List<IndexedColumn>()
};
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");
iinfo.Columns.Add(new IndexedColumn
{
Order = i.Order,
ColumnName = c.Name
});
}
}
foreach (var indexName in indexes.Keys)
{
var index = indexes[indexName];
const string sqlFormat = "create {3} index if not exists \"{0}\" on \"{1}\"(\"{2}\")";
var columns = String.Join("\",\"", index.Columns.OrderBy(i => i.Order).Select(i => i.ColumnName).ToArray());
var sql = String.Format(sqlFormat, indexName, index.TableName, columns, index.Unique ? "unique" : "");
count += Execute(sql);
}
return count;
}
}
public class ColumnInfo
@ -531,28 +537,31 @@ namespace SQLiteWin32
public T ExecuteScalar<T>(string query, params object[] args)
{
var cmd = CreateCommand(query, args);
if (TimeExecution)
lock (locker)
{
if (_sw == null)
var cmd = CreateCommand(query, args);
if (TimeExecution)
{
_sw = new System.Diagnostics.Stopwatch();
if (_sw == null)
{
_sw = new System.Diagnostics.Stopwatch();
}
_sw.Reset();
_sw.Start();
}
_sw.Reset();
_sw.Start();
var r = cmd.ExecuteScalar<T>();
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));
}
return r;
}
var r = cmd.ExecuteScalar<T>();
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));
}
return r;
}
/// <summary>
@ -665,7 +674,10 @@ namespace SQLiteWin32
/// </returns>
public ITableQuery<T> Table<T>() where T : new()
{
return new TableQuery<T>(this);
lock (locker)
{
return new TableQuery<T>(this);
}
}
/// <summary>
@ -978,16 +990,19 @@ namespace SQLiteWin32
/// </param>
public void RunInTransaction(Action action)
{
try
lock (locker)
{
var savePoint = SaveTransactionPoint();
action();
Release(savePoint);
}
catch (Exception)
{
Rollback();
throw;
try
{
var savePoint = SaveTransactionPoint();
action();
Release(savePoint);
}
catch (Exception)
{
Rollback();
throw;
}
}
}
@ -1002,15 +1017,18 @@ namespace SQLiteWin32
/// </returns>
public int InsertAll(System.Collections.IEnumerable objects)
{
var c = 0;
RunInTransaction(() =>
lock (locker)
{
foreach (var r in objects)
var c = 0;
RunInTransaction(() =>
{
c += Insert(r);
}
});
return c;
foreach (var r in objects)
{
c += Insert(r);
}
});
return c;
}
}
/// <summary>
@ -1314,14 +1332,17 @@ namespace SQLiteWin32
/// </returns>
public int Delete(object objectToDelete)
{
var map = GetMapping(objectToDelete.GetType());
var pk = map.PK;
if (pk == null)
lock (locker)
{
throw new NotSupportedException("Cannot delete " + map.TableName + ": it has no PK");
var map = GetMapping(objectToDelete.GetType());
var pk = map.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);
return Execute(q, pk.GetValue(objectToDelete));
}
var q = string.Format("delete from \"{0}\" where \"{1}\" = ?", map.TableName, pk.Name);
return Execute(q, pk.GetValue(objectToDelete));
}
/// <summary>