Skip to content

Commit

Permalink
Merge branch 'praeclarum:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Pythonic-Rainbow authored Jan 20, 2024
2 parents d9b8795 + e8a24a8 commit f37574f
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
jobs:
build:

runs-on: macOS-10.14
runs-on: macOS-latest

steps:

Expand Down
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<VersionPrefix>1.8</VersionPrefix>
<VersionSuffix></VersionSuffix>
<VersionPrefix>1.9</VersionPrefix>
<VersionSuffix>beta</VersionSuffix>

<PackageIcon>Logo-low.png</PackageIcon>
<PackageProjectUrl>https://github.com/praeclarum/sqlite-net</PackageProjectUrl>
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Use one of these packages:
| [![NuGet Package](https://img.shields.io/nuget/v/sqlite-net-pcl.svg)](https://www.nuget.org/packages/sqlite-net-pcl) | [sqlite-net-pcl](https://www.nuget.org/packages/sqlite-net-pcl) | .NET Standard Library |
| [![NuGet Package with Encryption](https://img.shields.io/nuget/v/sqlite-net-sqlcipher.svg)](https://www.nuget.org/packages/sqlite-net-sqlcipher) | [sqlite-net-sqlcipher](https://www.nuget.org/packages/sqlite-net-sqlcipher) | With Encryption Support |
| [![NuGet Package using P/Invoke](https://img.shields.io/nuget/v/sqlite-net-static.svg)](https://www.nuget.org/packages/sqlite-net-static) | [sqlite-net-static](https://www.nuget.org/packages/sqlite-net-static) | Special version that uses P/Invokes to platform-provided sqlite3 |
| [![NuGet Package without a SQLitePCLRaw bundle](https://img.shields.io/nuget/v/sqlite-net-base.svg)](https://www.nuget.org/packages/sqlite-net-base) | [sqlite-net-base](https://www.nuget.org/packages/sqlite-net-base) | wothout a SQLitePCLRaw bundle so you can choose your own provider |

SQLite-net is an open source, minimal library to allow .NET, .NET Core, and Mono applications to store data in
[SQLite 3 databases](http://www.sqlite.org). It was first designed to work with [Xamarin.iOS](http://xamarin.com),
Expand All @@ -33,7 +34,7 @@ Install [sqlite-net-pcl](https://www.nuget.org/packages/sqlite-net-pcl) from NuG

## Source Installation

SQLite-net is all contained in 1 file (I know, so cool right?) and is easy to add to your project. Just add [SQLite.cs](https://github.com/praeclarum/sqlite-net/blob/master/src/SQLite.cs) to your project, and you're ready to start creating tables.
SQLite-net is all contained in 1 file (I know, so cool right?) and is easy to add to your project. Just add [SQLite.cs](https://github.com/praeclarum/sqlite-net/blob/master/src/SQLite.cs) to your project, and you're ready to start creating tables. An asynchronous implementation can be found in [SQLiteAsync.cs](https://github.com/praeclarum/sqlite-net/blob/master/src/SQLiteAsync.cs).

## Please Contribute!

Expand Down
2 changes: 1 addition & 1 deletion nuget/SQLite-net-base/SQLite-net-base.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<DocumentationFile>bin\Debug\netstandard2.0\SQLite-net.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SQLitePCLRaw.core" Version="2.0.4" />
<PackageReference Include="SQLitePCLRaw.core" Version="2.1.2" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\src\SQLite.cs">
Expand Down
2 changes: 1 addition & 1 deletion nuget/SQLite-net-sqlcipher/SQLite-net-sqlcipher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<DocumentationFile>bin\Debug\netstandard2.0\SQLite-net.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.0.4" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.2" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\src\SQLite.cs">
Expand Down
2 changes: 1 addition & 1 deletion nuget/SQLite-net-std/SQLite-net-std.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<DocumentationFile>bin\Debug\netstandard2.0\SQLite-net.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.0.4" />
<PackageReference Include="SQLitePCLRaw.bundle_green" Version="2.1.2" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\src\SQLite.cs">
Expand Down
100 changes: 99 additions & 1 deletion src/SQLite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,109 @@ public enum CreateFlags
FullTextSearch4 = 0x200
}

public interface ISQLiteConnection
{
Sqlite3DatabaseHandle Handle { get; }
string DatabasePath { get; }
int LibVersionNumber { get; }
bool TimeExecution { get; set; }
bool Trace { get; set; }
Action<string> Tracer { get; set; }
bool StoreDateTimeAsTicks { get; }
bool StoreTimeSpanAsTicks { get; }
string DateTimeStringFormat { get; }
TimeSpan BusyTimeout { get; set; }
IEnumerable<TableMapping> TableMappings { get; }
bool IsInTransaction { get; }

event EventHandler<NotifyTableChangedEventArgs> 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<string, object> 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<T> (Expression<Func<T, object>> property, bool unique = false);
CreateTableResult CreateTable<T> (CreateFlags createFlags = CreateFlags.None);
CreateTableResult CreateTable (Type ty, CreateFlags createFlags = CreateFlags.None);
CreateTablesResult CreateTables<T, T2> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new();
CreateTablesResult CreateTables<T, T2, T3> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new()
where T3 : new();
CreateTablesResult CreateTables<T, T2, T3, T4> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new()
where T3 : new()
where T4 : new();
CreateTablesResult CreateTables<T, T2, T3, T4, T5> (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<T> DeferredQuery<T> (string query, params object[] args) where T : new();
IEnumerable<object> DeferredQuery (TableMapping map, string query, params object[] args);
int Delete (object objectToDelete);
int Delete<T> (object primaryKey);
int Delete (object primaryKey, TableMapping map);
int DeleteAll<T> ();
int DeleteAll (TableMapping map);
void Dispose ();
int DropTable<T> ();
int DropTable (TableMapping map);
void EnableLoadExtension (bool enabled);
void EnableWriteAheadLogging ();
int Execute (string query, params object[] args);
T ExecuteScalar<T> (string query, params object[] args);
T Find<T> (object pk) where T : new();
object Find (object pk, TableMapping map);
T Find<T> (Expression<Func<T, bool>> predicate) where T : new();
T FindWithQuery<T> (string query, params object[] args) where T : new();
object FindWithQuery (TableMapping map, string query, params object[] args);
T Get<T> (object pk) where T : new();
object Get (object pk, TableMapping map);
T Get<T> (Expression<Func<T, bool>> predicate) where T : new();
TableMapping GetMapping (Type type, CreateFlags createFlags = CreateFlags.None);
TableMapping GetMapping<T> (CreateFlags createFlags = CreateFlags.None);
List<SQLiteConnection.ColumnInfo> 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<T> Query<T> (string query, params object[] args) where T : new();
List<object> Query (TableMapping map, string query, params object[] args);
List<T> QueryScalars<T> (string query, params object[] args);
void Release (string savepoint);
void Rollback ();
void RollbackTo (string savepoint);
void RunInTransaction (Action action);
string SaveTransactionPoint ();
TableQuery<T> Table<T> () where T : new();
int Update (object obj);
int Update (object obj, Type objType);
int UpdateAll (IEnumerable objects, bool runInTransaction = true);
}

/// <summary>
/// An open connection to a SQLite database.
/// </summary>
[Preserve (AllMembers = true)]
public partial class SQLiteConnection : IDisposable
, ISQLiteConnection
{
private bool _open;
private TimeSpan _busyTimeout;
Expand Down Expand Up @@ -1894,7 +1992,7 @@ public int Update (object obj, Type objType)
}
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);
select "\"" + c.Name + "\" = ? ").ToArray ()), pk.Name);

try {
rowsAffected = Execute (q, ps.ToArray ());
Expand Down
93 changes: 91 additions & 2 deletions src/SQLiteAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,101 @@
using System.Threading;
using System.Threading.Tasks;

#pragma warning disable 1591 // XML Doc Comments

namespace SQLite
{
public interface ISQLiteAsyncConnection
{
string DatabasePath { get; }
int LibVersionNumber { get; }
string DateTimeStringFormat { get; }
bool StoreDateTimeAsTicks { get; }
bool StoreTimeSpanAsTicks { get; }
bool Trace { get; set; }
Action<string> Tracer { get; set; }
bool TimeExecution { get; set; }
IEnumerable<TableMapping> TableMappings { get; }

Task BackupAsync (string destinationDatabasePath, string databaseName = "main");
Task CloseAsync ();
Task<int> CreateIndexAsync (string tableName, string columnName, bool unique = false);
Task<int> CreateIndexAsync (string indexName, string tableName, string columnName, bool unique = false);
Task<int> CreateIndexAsync (string tableName, string[] columnNames, bool unique = false);
Task<int> CreateIndexAsync (string indexName, string tableName, string[] columnNames, bool unique = false);
Task<int> CreateIndexAsync<T> (Expression<Func<T, object>> property, bool unique = false);
Task<CreateTableResult> CreateTableAsync<T> (CreateFlags createFlags = CreateFlags.None) where T : new();
Task<CreateTableResult> CreateTableAsync (Type ty, CreateFlags createFlags = CreateFlags.None);
Task<CreateTablesResult> CreateTablesAsync<T, T2> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new();
Task<CreateTablesResult> CreateTablesAsync<T, T2, T3> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new()
where T3 : new();
Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new()
where T3 : new()
where T4 : new();
Task<CreateTablesResult> CreateTablesAsync<T, T2, T3, T4, T5> (CreateFlags createFlags = CreateFlags.None)
where T : new()
where T2 : new()
where T3 : new()
where T4 : new()
where T5 : new();
Task<CreateTablesResult> CreateTablesAsync (CreateFlags createFlags = CreateFlags.None, params Type[] types);
Task<IEnumerable<T>> DeferredQueryAsync<T> (string query, params object[] args) where T : new();
Task<IEnumerable<object>> DeferredQueryAsync (TableMapping map, string query, params object[] args);
Task<int> DeleteAllAsync<T> ();
Task<int> DeleteAllAsync (TableMapping map);
Task<int> DeleteAsync (object objectToDelete);
Task<int> DeleteAsync<T> (object primaryKey);
Task<int> DeleteAsync (object primaryKey, TableMapping map);
Task<int> DropTableAsync<T> () where T : new();
Task<int> DropTableAsync (TableMapping map);
Task EnableLoadExtensionAsync (bool enabled);
Task EnableWriteAheadLoggingAsync ();
Task<int> ExecuteAsync (string query, params object[] args);
Task<T> ExecuteScalarAsync<T> (string query, params object[] args);
Task<T> FindAsync<T> (object pk) where T : new();
Task<object> FindAsync (object pk, TableMapping map);
Task<T> FindAsync<T> (Expression<Func<T, bool>> predicate) where T : new();
Task<T> FindWithQueryAsync<T> (string query, params object[] args) where T : new();
Task<object> FindWithQueryAsync (TableMapping map, string query, params object[] args);
Task<T> GetAsync<T> (object pk) where T : new();
Task<object> GetAsync (object pk, TableMapping map);
Task<T> GetAsync<T> (Expression<Func<T, bool>> predicate) where T : new();
TimeSpan GetBusyTimeout ();
SQLiteConnectionWithLock GetConnection ();
Task<TableMapping> GetMappingAsync (Type type, CreateFlags createFlags = CreateFlags.None);
Task<TableMapping> GetMappingAsync<T> (CreateFlags createFlags = CreateFlags.None) where T : new();
Task<List<SQLiteConnection.ColumnInfo>> GetTableInfoAsync (string tableName);
Task<int> InsertAllAsync (IEnumerable objects, bool runInTransaction = true);
Task<int> InsertAllAsync (IEnumerable objects, string extra, bool runInTransaction = true);
Task<int> InsertAllAsync (IEnumerable objects, Type objType, bool runInTransaction = true);
Task<int> InsertAsync (object obj);
Task<int> InsertAsync (object obj, Type objType);
Task<int> InsertAsync (object obj, string extra);
Task<int> InsertAsync (object obj, string extra, Type objType);
Task<int> InsertOrReplaceAsync (object obj);
Task<int> InsertOrReplaceAsync (object obj, Type objType);
Task<List<T>> QueryAsync<T> (string query, params object[] args) where T : new();
Task<List<object>> QueryAsync (TableMapping map, string query, params object[] args);
Task<List<T>> QueryScalarsAsync<T> (string query, params object[] args);
Task RunInTransactionAsync (Action<SQLiteConnection> action);
Task SetBusyTimeoutAsync (TimeSpan value);
AsyncTableQuery<T> Table<T> () where T : new();
Task<int> UpdateAllAsync (IEnumerable objects, bool runInTransaction = true);
Task<int> UpdateAsync (object obj);
Task<int> UpdateAsync (object obj, Type objType);
}

/// <summary>
/// A pooled asynchronous connection to a SQLite database.
/// </summary>
public partial class SQLiteAsyncConnection
: ISQLiteAsyncConnection
{
readonly SQLiteConnectionString _connectionString;

Expand Down Expand Up @@ -143,7 +232,7 @@ public Task EnableWriteAheadLoggingAsync ()
/// Whether to store DateTime properties as ticks (true) or strings (false).
/// </summary>
public bool StoreDateTimeAsTicks => GetConnection ().StoreDateTimeAsTicks;

/// <summary>
/// Whether to store TimeSpan properties as ticks (true) or strings (false).
/// </summary>
Expand Down Expand Up @@ -460,7 +549,7 @@ public Task<int> CreateIndexAsync<T> (Expression<Func<T, object>> property, bool
}

/// <summary>
/// Inserts the given object and (and updates its
/// Inserts the given object and (and updates its
/// auto incremented primary key if it has one).
/// </summary>
/// <param name="obj">
Expand Down
23 changes: 23 additions & 0 deletions tests/SQLite.Tests/DeleteTest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Threading.Tasks;

#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
Expand Down Expand Up @@ -36,6 +37,17 @@ SQLiteConnection CreateDb ()
return db;
}

async Task<SQLiteAsyncConnection> CreateDbAsync ()
{
var db = new SQLiteAsyncConnection (new SQLiteConnectionString (TestPath.GetTempFileName ()));
await db.CreateTableAsync<TestTable> ();
var items = from i in Enumerable.Range (0, Count)
select new TestTable { Datum = 1000+i, Test = "Hello World" };
await db.InsertAllAsync (items);
Assert.AreEqual (Count, await db.Table<TestTable> ().CountAsync ());
return db;
}

[Test]
public void DeleteEntityOne ()
{
Expand All @@ -47,6 +59,17 @@ public void DeleteEntityOne ()
Assert.AreEqual (Count - 1, db.Table<TestTable> ().Count ());
}

[Test]
public async Task DeleteEntityOneAsync ()
{
var db = await CreateDbAsync ();

var r = await db.DeleteAsync (await db.GetAsync<TestTable> (1));

Assert.AreEqual (1, r);
Assert.AreEqual (Count - 1, await db.Table<TestTable> ().CountAsync ());
}

[Test]
public void DeletePKOne ()
{
Expand Down
35 changes: 35 additions & 0 deletions tests/SQLite.Tests/DropTableTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Text;
using SQLite;
using System.Threading.Tasks;

#if NETFX_CORE
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
Expand Down Expand Up @@ -37,6 +38,14 @@ public TestDb () : base(TestPath.GetTempFileName ())
}
}

public class TestDbAsync : SQLiteAsyncConnection
{
public TestDbAsync () : base(TestPath.GetTempFileName ())
{
Trace = true;
}
}

[Test]
public void CreateInsertDrop ()
{
Expand All @@ -57,5 +66,31 @@ public void CreateInsertDrop ()

ExceptionAssert.Throws<SQLiteException>(() => db.Table<Product> ().Count ());
}

[Test]
public async Task CreateInsertDropAsync ()
{
var db = new TestDbAsync ();

await db.CreateTableAsync<Product> ();

await db.InsertAsync (new Product {
Name = "Hello",
Price = 16,
});

var n = await db.Table<Product> ().CountAsync ();

Assert.AreEqual (1, n);

await db.DropTableAsync<Product> ();

try {
await db.Table<Product> ().CountAsync ();
Assert.Fail ("Should have thrown");
} catch (SQLiteException) {
// Expected
}
}
}
}

0 comments on commit f37574f

Please sign in to comment.