mirror of https://github.com/SixLabors/ImageSharp
26 changed files with 1171 additions and 232 deletions
@ -0,0 +1 @@ |
|||
ce0491dcbe39702bf25fb616f76e1b149f670688 |
|||
@ -0,0 +1,486 @@ |
|||
//
|
|||
// Copyright (c) 2012 Krueger Systems, Inc.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
// of this software and associated documentation files (the "Software"), to deal
|
|||
// in the Software without restriction, including without limitation the rights
|
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the Software is
|
|||
// furnished to do so, subject to the following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included in
|
|||
// all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
// THE SOFTWARE.
|
|||
//
|
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Expressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace SQLite |
|||
{ |
|||
public partial class SQLiteAsyncConnection |
|||
{ |
|||
SQLiteConnectionString _connectionString; |
|||
|
|||
public SQLiteAsyncConnection (string databasePath, bool storeDateTimeAsTicks = false) |
|||
{ |
|||
_connectionString = new SQLiteConnectionString (databasePath, storeDateTimeAsTicks); |
|||
} |
|||
|
|||
SQLiteConnectionWithLock GetConnection () |
|||
{ |
|||
return SQLiteConnectionPool.Shared.GetConnection (_connectionString); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTableAsync<T> () |
|||
where T : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2> () |
|||
where T : new () |
|||
where T2 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3> () |
|||
where T : new () |
|||
where T2 : new () |
|||
where T3 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4> () |
|||
where T : new () |
|||
where T2 : new () |
|||
where T3 : new () |
|||
where T4 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4, T5> () |
|||
where T : new () |
|||
where T2 : new () |
|||
where T3 : new () |
|||
where T4 : new () |
|||
where T5 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4), typeof (T5)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync (params Type[] types) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
CreateTablesResult result = new CreateTablesResult (); |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
foreach (Type type in types) { |
|||
int aResult = conn.CreateTable (type); |
|||
result.Results[type] = aResult; |
|||
} |
|||
} |
|||
return result; |
|||
}); |
|||
} |
|||
|
|||
public Task<int> DropTableAsync<T> () |
|||
where T : new () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.DropTable<T> (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> InsertAsync (object item) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Insert (item); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> UpdateAsync (object item) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Update (item); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> DeleteAsync (object item) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Delete (item); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> GetAsync<T>(object pk) |
|||
where T : new() |
|||
{ |
|||
return Task.Factory.StartNew(() => |
|||
{ |
|||
var conn = GetConnection(); |
|||
using (conn.Lock()) |
|||
{ |
|||
return conn.Get<T>(pk); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FindAsync<T> (object pk) |
|||
where T : new () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Find<T> (pk); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> GetAsync<T> (Expression<Func<T, bool>> predicate) |
|||
where T : new() |
|||
{ |
|||
return Task.Factory.StartNew(() => |
|||
{ |
|||
var conn = GetConnection(); |
|||
using (conn.Lock()) |
|||
{ |
|||
return conn.Get<T> (predicate); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FindAsync<T> (Expression<Func<T, bool>> predicate) |
|||
where T : new () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Find<T> (predicate); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> ExecuteAsync (string query, params object[] args) |
|||
{ |
|||
return Task<int>.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Execute (query, args); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> InsertAllAsync (IEnumerable items) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.InsertAll (items); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
[Obsolete("Will cause a deadlock if any call in action ends up in a different thread. Use RunInTransactionAsync(Action<SQLiteConnection>) instead.")] |
|||
public Task RunInTransactionAsync (Action<SQLiteAsyncConnection> action) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = this.GetConnection (); |
|||
using (conn.Lock ()) { |
|||
conn.BeginTransaction (); |
|||
try { |
|||
action (this); |
|||
conn.Commit (); |
|||
} |
|||
catch (Exception) { |
|||
conn.Rollback (); |
|||
throw; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task RunInTransactionAsync(Action<SQLiteConnection> action) |
|||
{ |
|||
return Task.Factory.StartNew(() => |
|||
{ |
|||
var conn = this.GetConnection(); |
|||
using (conn.Lock()) |
|||
{ |
|||
conn.BeginTransaction(); |
|||
try |
|||
{ |
|||
action(conn); |
|||
conn.Commit(); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
conn.Rollback(); |
|||
throw; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Table<T> () |
|||
where T : new () |
|||
{ |
|||
//
|
|||
// This isn't async as the underlying connection doesn't go out to the database
|
|||
// until the query is performed. The Async methods are on the query iteself.
|
|||
//
|
|||
var conn = GetConnection (); |
|||
return new AsyncTableQuery<T> (conn.Table<T> ()); |
|||
} |
|||
|
|||
public Task<T> ExecuteScalarAsync<T> (string sql, params object[] args) |
|||
{ |
|||
return Task<T>.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
var command = conn.CreateCommand (sql, args); |
|||
return command.ExecuteScalar<T> (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<List<T>> QueryAsync<T> (string sql, params object[] args) |
|||
where T : new () |
|||
{ |
|||
return Task<List<T>>.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Query<T> (sql, args); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
//
|
|||
// TODO: Bind to AsyncConnection.GetConnection instead so that delayed
|
|||
// execution can still work after a Pool.Reset.
|
|||
//
|
|||
public class AsyncTableQuery<T> |
|||
where T : new () |
|||
{ |
|||
TableQuery<T> _innerQuery; |
|||
|
|||
public AsyncTableQuery (TableQuery<T> innerQuery) |
|||
{ |
|||
_innerQuery = innerQuery; |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Where (Expression<Func<T, bool>> predExpr) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.Where (predExpr)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Skip (int n) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.Skip (n)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Take (int n) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.Take (n)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> OrderBy<U> (Expression<Func<T, U>> orderExpr) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.OrderBy<U> (orderExpr)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> OrderByDescending<U> (Expression<Func<T, U>> orderExpr) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.OrderByDescending<U> (orderExpr)); |
|||
} |
|||
|
|||
public Task<List<T>> ToListAsync () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.ToList (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> CountAsync () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.Count (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> ElementAtAsync (int index) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.ElementAt (index); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FirstAsync () |
|||
{ |
|||
return Task<T>.Factory.StartNew(() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.First (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FirstOrDefaultAsync () |
|||
{ |
|||
return Task<T>.Factory.StartNew(() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.FirstOrDefault (); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
public class CreateTablesResult |
|||
{ |
|||
public Dictionary<Type, int> Results { get; private set; } |
|||
|
|||
internal CreateTablesResult () |
|||
{ |
|||
this.Results = new Dictionary<Type, int> (); |
|||
} |
|||
} |
|||
|
|||
class SQLiteConnectionPool |
|||
{ |
|||
class Entry |
|||
{ |
|||
public SQLiteConnectionString ConnectionString { get; private set; } |
|||
public SQLiteConnectionWithLock Connection { get; private set; } |
|||
|
|||
public Entry (SQLiteConnectionString connectionString) |
|||
{ |
|||
ConnectionString = connectionString; |
|||
Connection = new SQLiteConnectionWithLock (connectionString); |
|||
} |
|||
|
|||
public void OnApplicationSuspended () |
|||
{ |
|||
Connection.Dispose (); |
|||
Connection = null; |
|||
} |
|||
} |
|||
|
|||
readonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry> (); |
|||
readonly object _entriesLock = new object (); |
|||
|
|||
static readonly SQLiteConnectionPool _shared = new SQLiteConnectionPool (); |
|||
|
|||
/// <summary>
|
|||
/// Gets the singleton instance of the connection tool.
|
|||
/// </summary>
|
|||
public static SQLiteConnectionPool Shared |
|||
{ |
|||
get |
|||
{ |
|||
return _shared; |
|||
} |
|||
} |
|||
|
|||
public SQLiteConnectionWithLock GetConnection (SQLiteConnectionString connectionString) |
|||
{ |
|||
lock (_entriesLock) { |
|||
Entry entry; |
|||
string key = connectionString.ConnectionString; |
|||
|
|||
if (!_entries.TryGetValue (key, out entry)) { |
|||
entry = new Entry (connectionString); |
|||
_entries[key] = entry; |
|||
} |
|||
|
|||
return entry.Connection; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Closes all connections managed by this pool.
|
|||
/// </summary>
|
|||
public void Reset () |
|||
{ |
|||
lock (_entriesLock) { |
|||
foreach (var entry in _entries.Values) { |
|||
entry.OnApplicationSuspended (); |
|||
} |
|||
_entries.Clear (); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Call this method when the application is suspended.
|
|||
/// </summary>
|
|||
/// <remarks>Behaviour here is to close any open connections.</remarks>
|
|||
public void ApplicationSuspended () |
|||
{ |
|||
Reset (); |
|||
} |
|||
} |
|||
|
|||
class SQLiteConnectionWithLock : SQLiteConnection |
|||
{ |
|||
readonly object _lockPoint = new object (); |
|||
|
|||
public SQLiteConnectionWithLock (SQLiteConnectionString connectionString) |
|||
: base (connectionString.DatabasePath, connectionString.StoreDateTimeAsTicks) |
|||
{ |
|||
} |
|||
|
|||
public IDisposable Lock () |
|||
{ |
|||
return new LockWrapper (_lockPoint); |
|||
} |
|||
|
|||
private class LockWrapper : IDisposable |
|||
{ |
|||
object _lockPoint; |
|||
|
|||
public LockWrapper (object lockPoint) |
|||
{ |
|||
_lockPoint = lockPoint; |
|||
Monitor.Enter (_lockPoint); |
|||
} |
|||
|
|||
public void Dispose () |
|||
{ |
|||
Monitor.Exit (_lockPoint); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,7 +1,8 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<packages> |
|||
<package id="Csharp-Sqlite" version="3.7.7.1" targetFramework="net40" /> |
|||
<package id="Microsoft.Bcl" version="1.0.16-rc" targetFramework="net40" /> |
|||
<package id="Microsoft.Bcl.Async" version="1.0.14-rc" targetFramework="net40" /> |
|||
<package id="Microsoft.Bcl.Build" version="1.0.0-rc" targetFramework="net40" /> |
|||
<package id="SQLitex64" version="1.0.66" targetFramework="net40" /> |
|||
<package id="sqlite-net" version="1.0.7" targetFramework="net40" /> |
|||
</packages> |
|||
@ -0,0 +1 @@ |
|||
81fffff68e71d82a09d8c6a345ce69410f351786 |
|||
@ -0,0 +1,21 @@ |
|||
<?xml version="1.0"?> |
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> |
|||
<metadata> |
|||
<id>Csharp-Sqlite</id> |
|||
<version>3.7.7.1</version> |
|||
<title>C#-SqLite Unofficial Package</title> |
|||
<authors>noah.hart</authors> |
|||
<owners>noah.hart</owners> |
|||
<projectUrl>http://code.google.com/p/csharp-sqlite/</projectUrl> |
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
|||
<description>C#-SQLite is an independent reimplementation of the SQLite software library version 3.7.7.1.</description> |
|||
<releaseNotes /> |
|||
<copyright /> |
|||
<language /> |
|||
<tags>Sqlite</tags> |
|||
<references> |
|||
<reference file="Community.CsharpSqlite.dll" /> |
|||
<reference file="Community.CsharpSqlite.SQLiteClient.dll" /> |
|||
</references> |
|||
</metadata> |
|||
</package> |
|||
Binary file not shown.
@ -0,0 +1 @@ |
|||
703605507a2c2a90fa7b826aaf2cf7c78a7243b7 |
|||
Binary file not shown.
@ -0,0 +1 @@ |
|||
2e6a85ddf4ce868ed48de14c2be21ee94f689b78 |
|||
Binary file not shown.
@ -0,0 +1 @@ |
|||
ab181a987d0059a31c26ee3891a01c40d43019a0 |
|||
@ -1 +0,0 @@ |
|||
aff828512d1afca48fa5d6824429359562199078 |
|||
@ -1,23 +0,0 @@ |
|||
<?xml version="1.0"?> |
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> |
|||
<metadata> |
|||
<id>SQLitex64</id> |
|||
<version>1.0.66</version> |
|||
<title>SQLitex64</title> |
|||
<authors>Amir Barylko</authors> |
|||
<owners>Amir Barylko</owners> |
|||
<projectUrl>http://www.sqlite.org/</projectUrl> |
|||
<iconUrl>http://www.sqlite.org/images/sqlite370_banner.gif</iconUrl> |
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
|||
<description>Provides both (32 and 64 bit) assemblies needed to use SQLite. |
|||
The current package only provides 32 bit.</description> |
|||
<summary>SQLite 64 bit and 32 bit assemblies</summary> |
|||
<releaseNotes /> |
|||
<copyright /> |
|||
<language /> |
|||
<tags>SQLite</tags> |
|||
<references> |
|||
<reference file="System.Data.SQLite.DLL" /> |
|||
</references> |
|||
</metadata> |
|||
</package> |
|||
@ -1 +0,0 @@ |
|||
aa398bbec1a567de55f984959d200900b794372a |
|||
@ -1 +0,0 @@ |
|||
6f07d5e7ab41a0f791f07d5407f10edb4b716a02 |
|||
@ -1 +0,0 @@ |
|||
aa398bbec1a567de55f984959d200900b794372a |
|||
@ -0,0 +1 @@ |
|||
d2856e3733eb6c7d85057c37ae415e54c8bf2386 |
|||
@ -0,0 +1,486 @@ |
|||
//
|
|||
// Copyright (c) 2012 Krueger Systems, Inc.
|
|||
//
|
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|||
// of this software and associated documentation files (the "Software"), to deal
|
|||
// in the Software without restriction, including without limitation the rights
|
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|||
// copies of the Software, and to permit persons to whom the Software is
|
|||
// furnished to do so, subject to the following conditions:
|
|||
//
|
|||
// The above copyright notice and this permission notice shall be included in
|
|||
// all copies or substantial portions of the Software.
|
|||
//
|
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
// THE SOFTWARE.
|
|||
//
|
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Linq.Expressions; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace SQLite |
|||
{ |
|||
public partial class SQLiteAsyncConnection |
|||
{ |
|||
SQLiteConnectionString _connectionString; |
|||
|
|||
public SQLiteAsyncConnection (string databasePath, bool storeDateTimeAsTicks = false) |
|||
{ |
|||
_connectionString = new SQLiteConnectionString (databasePath, storeDateTimeAsTicks); |
|||
} |
|||
|
|||
SQLiteConnectionWithLock GetConnection () |
|||
{ |
|||
return SQLiteConnectionPool.Shared.GetConnection (_connectionString); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTableAsync<T> () |
|||
where T : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2> () |
|||
where T : new () |
|||
where T2 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3> () |
|||
where T : new () |
|||
where T2 : new () |
|||
where T3 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4> () |
|||
where T : new () |
|||
where T2 : new () |
|||
where T3 : new () |
|||
where T4 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4, T5> () |
|||
where T : new () |
|||
where T2 : new () |
|||
where T3 : new () |
|||
where T4 : new () |
|||
where T5 : new () |
|||
{ |
|||
return CreateTablesAsync (typeof (T), typeof (T2), typeof (T3), typeof (T4), typeof (T5)); |
|||
} |
|||
|
|||
public Task<CreateTablesResult> CreateTablesAsync (params Type[] types) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
CreateTablesResult result = new CreateTablesResult (); |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
foreach (Type type in types) { |
|||
int aResult = conn.CreateTable (type); |
|||
result.Results[type] = aResult; |
|||
} |
|||
} |
|||
return result; |
|||
}); |
|||
} |
|||
|
|||
public Task<int> DropTableAsync<T> () |
|||
where T : new () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.DropTable<T> (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> InsertAsync (object item) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Insert (item); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> UpdateAsync (object item) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Update (item); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> DeleteAsync (object item) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Delete (item); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> GetAsync<T>(object pk) |
|||
where T : new() |
|||
{ |
|||
return Task.Factory.StartNew(() => |
|||
{ |
|||
var conn = GetConnection(); |
|||
using (conn.Lock()) |
|||
{ |
|||
return conn.Get<T>(pk); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FindAsync<T> (object pk) |
|||
where T : new () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Find<T> (pk); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> GetAsync<T> (Expression<Func<T, bool>> predicate) |
|||
where T : new() |
|||
{ |
|||
return Task.Factory.StartNew(() => |
|||
{ |
|||
var conn = GetConnection(); |
|||
using (conn.Lock()) |
|||
{ |
|||
return conn.Get<T> (predicate); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FindAsync<T> (Expression<Func<T, bool>> predicate) |
|||
where T : new () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Find<T> (predicate); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> ExecuteAsync (string query, params object[] args) |
|||
{ |
|||
return Task<int>.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Execute (query, args); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> InsertAllAsync (IEnumerable items) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.InsertAll (items); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
[Obsolete("Will cause a deadlock if any call in action ends up in a different thread. Use RunInTransactionAsync(Action<SQLiteConnection>) instead.")] |
|||
public Task RunInTransactionAsync (Action<SQLiteAsyncConnection> action) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
var conn = this.GetConnection (); |
|||
using (conn.Lock ()) { |
|||
conn.BeginTransaction (); |
|||
try { |
|||
action (this); |
|||
conn.Commit (); |
|||
} |
|||
catch (Exception) { |
|||
conn.Rollback (); |
|||
throw; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task RunInTransactionAsync(Action<SQLiteConnection> action) |
|||
{ |
|||
return Task.Factory.StartNew(() => |
|||
{ |
|||
var conn = this.GetConnection(); |
|||
using (conn.Lock()) |
|||
{ |
|||
conn.BeginTransaction(); |
|||
try |
|||
{ |
|||
action(conn); |
|||
conn.Commit(); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
conn.Rollback(); |
|||
throw; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Table<T> () |
|||
where T : new () |
|||
{ |
|||
//
|
|||
// This isn't async as the underlying connection doesn't go out to the database
|
|||
// until the query is performed. The Async methods are on the query iteself.
|
|||
//
|
|||
var conn = GetConnection (); |
|||
return new AsyncTableQuery<T> (conn.Table<T> ()); |
|||
} |
|||
|
|||
public Task<T> ExecuteScalarAsync<T> (string sql, params object[] args) |
|||
{ |
|||
return Task<T>.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
var command = conn.CreateCommand (sql, args); |
|||
return command.ExecuteScalar<T> (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<List<T>> QueryAsync<T> (string sql, params object[] args) |
|||
where T : new () |
|||
{ |
|||
return Task<List<T>>.Factory.StartNew (() => { |
|||
var conn = GetConnection (); |
|||
using (conn.Lock ()) { |
|||
return conn.Query<T> (sql, args); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
//
|
|||
// TODO: Bind to AsyncConnection.GetConnection instead so that delayed
|
|||
// execution can still work after a Pool.Reset.
|
|||
//
|
|||
public class AsyncTableQuery<T> |
|||
where T : new () |
|||
{ |
|||
TableQuery<T> _innerQuery; |
|||
|
|||
public AsyncTableQuery (TableQuery<T> innerQuery) |
|||
{ |
|||
_innerQuery = innerQuery; |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Where (Expression<Func<T, bool>> predExpr) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.Where (predExpr)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Skip (int n) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.Skip (n)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> Take (int n) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.Take (n)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> OrderBy<U> (Expression<Func<T, U>> orderExpr) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.OrderBy<U> (orderExpr)); |
|||
} |
|||
|
|||
public AsyncTableQuery<T> OrderByDescending<U> (Expression<Func<T, U>> orderExpr) |
|||
{ |
|||
return new AsyncTableQuery<T> (_innerQuery.OrderByDescending<U> (orderExpr)); |
|||
} |
|||
|
|||
public Task<List<T>> ToListAsync () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.ToList (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<int> CountAsync () |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.Count (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> ElementAtAsync (int index) |
|||
{ |
|||
return Task.Factory.StartNew (() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.ElementAt (index); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FirstAsync () |
|||
{ |
|||
return Task<T>.Factory.StartNew(() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.First (); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
public Task<T> FirstOrDefaultAsync () |
|||
{ |
|||
return Task<T>.Factory.StartNew(() => { |
|||
using (((SQLiteConnectionWithLock)_innerQuery.Connection).Lock ()) { |
|||
return _innerQuery.FirstOrDefault (); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
public class CreateTablesResult |
|||
{ |
|||
public Dictionary<Type, int> Results { get; private set; } |
|||
|
|||
internal CreateTablesResult () |
|||
{ |
|||
this.Results = new Dictionary<Type, int> (); |
|||
} |
|||
} |
|||
|
|||
class SQLiteConnectionPool |
|||
{ |
|||
class Entry |
|||
{ |
|||
public SQLiteConnectionString ConnectionString { get; private set; } |
|||
public SQLiteConnectionWithLock Connection { get; private set; } |
|||
|
|||
public Entry (SQLiteConnectionString connectionString) |
|||
{ |
|||
ConnectionString = connectionString; |
|||
Connection = new SQLiteConnectionWithLock (connectionString); |
|||
} |
|||
|
|||
public void OnApplicationSuspended () |
|||
{ |
|||
Connection.Dispose (); |
|||
Connection = null; |
|||
} |
|||
} |
|||
|
|||
readonly Dictionary<string, Entry> _entries = new Dictionary<string, Entry> (); |
|||
readonly object _entriesLock = new object (); |
|||
|
|||
static readonly SQLiteConnectionPool _shared = new SQLiteConnectionPool (); |
|||
|
|||
/// <summary>
|
|||
/// Gets the singleton instance of the connection tool.
|
|||
/// </summary>
|
|||
public static SQLiteConnectionPool Shared |
|||
{ |
|||
get |
|||
{ |
|||
return _shared; |
|||
} |
|||
} |
|||
|
|||
public SQLiteConnectionWithLock GetConnection (SQLiteConnectionString connectionString) |
|||
{ |
|||
lock (_entriesLock) { |
|||
Entry entry; |
|||
string key = connectionString.ConnectionString; |
|||
|
|||
if (!_entries.TryGetValue (key, out entry)) { |
|||
entry = new Entry (connectionString); |
|||
_entries[key] = entry; |
|||
} |
|||
|
|||
return entry.Connection; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Closes all connections managed by this pool.
|
|||
/// </summary>
|
|||
public void Reset () |
|||
{ |
|||
lock (_entriesLock) { |
|||
foreach (var entry in _entries.Values) { |
|||
entry.OnApplicationSuspended (); |
|||
} |
|||
_entries.Clear (); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Call this method when the application is suspended.
|
|||
/// </summary>
|
|||
/// <remarks>Behaviour here is to close any open connections.</remarks>
|
|||
public void ApplicationSuspended () |
|||
{ |
|||
Reset (); |
|||
} |
|||
} |
|||
|
|||
class SQLiteConnectionWithLock : SQLiteConnection |
|||
{ |
|||
readonly object _lockPoint = new object (); |
|||
|
|||
public SQLiteConnectionWithLock (SQLiteConnectionString connectionString) |
|||
: base (connectionString.DatabasePath, connectionString.StoreDateTimeAsTicks) |
|||
{ |
|||
} |
|||
|
|||
public IDisposable Lock () |
|||
{ |
|||
return new LockWrapper (_lockPoint); |
|||
} |
|||
|
|||
private class LockWrapper : IDisposable |
|||
{ |
|||
object _lockPoint; |
|||
|
|||
public LockWrapper (object lockPoint) |
|||
{ |
|||
_lockPoint = lockPoint; |
|||
Monitor.Enter (_lockPoint); |
|||
} |
|||
|
|||
public void Dispose () |
|||
{ |
|||
Monitor.Exit (_lockPoint); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
Binary file not shown.
@ -0,0 +1,20 @@ |
|||
<?xml version="1.0"?> |
|||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> |
|||
<metadata> |
|||
<id>sqlite-net</id> |
|||
<version>1.0.7</version> |
|||
<title>sqlite-net</title> |
|||
<authors>Frank Krueger</authors> |
|||
<owners>Frank Krueger</owners> |
|||
<licenseUrl>https://github.com/praeclarum/sqlite-net/blob/master/license.md</licenseUrl> |
|||
<projectUrl>https://github.com/praeclarum/sqlite-net</projectUrl> |
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
|||
<description>sqlite-net is an open source, minimal library to allow .NET and Mono applications to store data in SQLite databases. It is written in C# 3.0 and is meant to be simply compiled in with your projects. It was first designed to work with MonoTouch on the iPhone, but should work in any other CLI environment.</description> |
|||
<summary>A .NET client library to access SQLite embedded database files in a LINQ manner.</summary> |
|||
<releaseNotes>v1.0.7: Update with commits through 06-FEB-2013.</releaseNotes> |
|||
<copyright /> |
|||
<language /> |
|||
<tags>sqlite sql monotouch database metro winrt</tags> |
|||
<references /> |
|||
</metadata> |
|||
</package> |
|||
Loading…
Reference in new issue