Skip to content

Commit 7621a8e

Browse files
committed
Remove dependency on sqlitePCL platforms, so now it can use SQLCypher
1 parent ff5685f commit 7621a8e

6 files changed

Lines changed: 98 additions & 60 deletions

File tree

README.md

Lines changed: 92 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,30 @@ Add this package to your netstandard project:
44

55
[![NuGet](https://img.shields.io/nuget/v/sqlite-net2.svg)](https://www.nuget.org/packages/sqlite-net2/)
66

7-
And call this function in your executable projects (.net, ios, android, uwp, mac, ...):
7+
Also add one of the https://github.com/ericsink/SQLitePCL.raw package of your choice to the netstandard project:
8+
- SQLitePCLRaw.bundle_e_sqlite3 for a normal database file
9+
- SQLitePCLRaw.bundle_e_sqlcipher for a crypted database file
10+
11+
And call this statup function in each of your platform projects:
812

913
```
1014
SQLitePCL.Batteries_V2.Init()
1115
```
1216

17+
For a simple key/value store based on sqlite, or a drop-in replacement (alternative) to the unstable Akavache, check https://github.com/softlion/KeyValueLite
1318

14-
See https://github.com/ericsink/SQLitePCL.raw/ for more information on how to use SQLitePCL.raw
15-
16-
If you search a simple key value store based on sqlite, alternative to Akavache, check https://github.com/softlion/KeyValueLite
19+
# Features
1720

18-
# Changes
19-
20-
* Netstandard 2.0 only
21+
* Netstandard 2+
2122
* Uses SQLitePCLRaw for sqlite raw communication
22-
* Requires SQLitePCL.raw v2, make sure to read the release notes on the SQLitePCL project page
23+
* Compatible with SQLitePCLRaw standard and cypher
24+
* Stable and used in tons of apps
2325

24-
# New Features compared to oysteinkrog
26+
# Other Features (compared to oysteinkrog)
2527

26-
Multiple primary key support
28+
* Multiple primary key support
2729
Ex:
28-
30+
```
2931
public class PrivacyGroupItem
3032
{
3133
[PrimaryKey]
@@ -36,85 +38,126 @@ If you search a simple key value store based on sqlite, alternative to Akavache,
3638
}
3739
3840
db.Delete<PrivacyGroupItem>(groupId, contactId);
41+
```
3942

40-
41-
Projections now have the expected result type
43+
* Projections now have the expected result type
4244
Ex: `IEnumerable<int> ids = from pgi in db.Table<PrivacyGroupItem>() where pgi.PrivacyGroupId == groupId select pgi.ContactId;`
4345

44-
New method to query simple types (ie: string, ...) as Query<T> can query only complex types (ie: T must be a class/stuct with a default constructor)
46+
* New method to query simple types (ie: string, ...) as Query<T> can query only complex types (ie: T must be a class/stuct with a default constructor)
4547
Signature: `IEnumerable<T> ExecuteSimpleQuery<T>(string query, params object[] args)`
4648
Usage: `ExecuteSimpleQuery<string>("select 'drop table ' || name || ';' from sqlite_master where type = 'table'")`
4749

50+
* No asynchronous API. Use Task.Run() if you want asynchronous calls.
51+
Note that while SQLitePCLRaw states that the database can be accessed by mutiple threads simultaneously, experience proves that you should always prevent multithread access, otherwise rare random crash occur. You can use `SemaphoreSlim` to serialize calls.
52+
53+
* Another trick
54+
Use transactions! In sqlite they speed up all queries a lot.
55+
4856
# Original Fork
4957

5058
https://github.com/praeclarum/sqlite-net
5159

52-
# Examples
60+
# Usage
5361

54-
Please consult the source code (see unit tests) for more examples.
62+
Note: see unit tests for more examples.
5563

56-
The library contains simple attributes that you can use to control the construction of tables. In a simple stock program, you might use:
64+
## Define the database schema using a code first approach.
5765

58-
public class Stock
66+
```csharp
67+
public class DbStock
5968
{
6069
[PrimaryKey, AutoIncrement]
6170
public int Id { get; set; }
71+
6272
[MaxLength(8)]
6373
public string Symbol { get; set; }
6474
}
6575

66-
public class Valuation
76+
public class DbValuation
6777
{
6878
[PrimaryKey, AutoIncrement]
6979
public int Id { get; set; }
70-
[Indexed]
80+
81+
[Indexed()]
7182
public int StockId { get; set; }
83+
84+
[Indexed("Stock",1)] //This defines an index with multiple keys
7285
public DateTime Time { get; set; }
86+
87+
[Indexed("Stock",2)]
7388
public decimal Price { get; set; }
7489
}
90+
```
91+
92+
## Create the schema
93+
94+
```csharp
95+
var dbFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
96+
dbFilePath = Path.Combine(dbFilePath, "store.db3");
97+
var exists = File.Exists(dbFilePath);
98+
var isFirstInit = !exists;
99+
100+
if (isFirstInit)
101+
{
102+
//Make sure folder exists
103+
var folderPath = Path.GetDirectoryName(dbFilePath);
104+
Directory.CreateDirectory(folderPath);
105+
File.CreateText(dbFilePath).Dispose();
106+
}
75107

76-
Once you've defined the objects in your model you have a choice of APIs. You can use the "synchronous API" where calls
77-
block one at a time, or you can use the "asynchronous API" where calls do not block. You may care to use the asynchronous
78-
API for mobile applications in order to increase reponsiveness.
108+
db = new SQLiteConnection(dbFilePath);
79109

80-
Both APIs are explained in the two sections below.
110+
if (isFirstInit)
111+
{
112+
//Create schema
113+
db.CreateTable<DbStock>();
114+
db.CreateTable<DbValuation>();
115+
//You may store your schema version using Xamarin Essentials
116+
//Xamarin.Essentials.Preferences.Set("DbVersion", 1);
117+
}
118+
```
81119

82-
## Synchronous API
120+
## Read, Add, Update, Delete rows in tables
83121

84-
Once you have defined your entity, you can automatically generate tables in your database by calling `CreateTable`:
122+
Simple add, update and delete:
85123

86-
var db = new SQLiteConnection(sqlitePlatform, "foofoo");
87-
db.CreateTable<Stock>();
88-
db.CreateTable<Valuation>();
124+
```csharp
125+
var stock = new DbStock() { Symbol = "EUR" };
126+
db.Insert(stock);
127+
stock.Symbol = "USD";
128+
db.Update(stock);
129+
db.Delete(stock);
130+
131+
db.DeleteAll(allStocks);
89132

90-
You can insert rows in the database using `Insert`. If the table contains an auto-incremented primary key, then the value for that key will be available to you after the insert:
133+
//Delete by id
134+
db.DeleteIn<DbDay>(new[] {1, 2, 3});
91135

92-
public static void AddStock(SQLiteConnection db, string symbol) {
93-
var s = db.Insert(new Stock() {
94-
Symbol = symbol
95-
});
96-
Console.WriteLine("{0} == {1}", s.Symbol, s.Id);
97-
}
136+
```
98137

99-
Similar methods exist for `Update` and `Delete`.
138+
After the Insert call, stock.Id will be set, because Id has the AutoIncrement attribute.
100139

101-
The most straightforward way to query for data is using the `Table` method. This can take predicates for constraining via WHERE clauses and/or adding ORDER BY clauses:
140+
Simple query using LINQ. Most linq operators work:
102141

103-
var conn = new SQLiteConnection(sqlitePlatform, "foofoo");
104-
var query = conn.Table<Stock>().Where(v => v.Symbol.StartsWith("A"));
142+
```csharp
143+
var stocksStartingWithA = db.Table<DbStock>()
144+
.Where(stock => stock.Symbol.StartsWith("A"))
145+
.OrderBy(stock => stock.Symbol)
146+
.ToList();
105147

106-
foreach (var stock in query)
107-
Debug.WriteLine("Stock: " + stock.Symbol);
148+
var allStocks = db.Table<DbStock>().ToList();
149+
```
108150

109-
You can also query the database at a low-level using the `Query` method:
151+
Advanced queries using SQL:
110152

111-
public static IEnumerable<Valuation> QueryValuations (SQLiteConnection db, Stock stock)
112-
{
113-
return db.Query<Valuation> ("select * from Valuation where StockId = ?", stock.Id);
114-
}
153+
```csharp
154+
var dbValuation = db.Query<DbValuation> ("select * from DbValuation where StockId = ?", stock.Id);
155+
db.Execute("delete * from DbValuation where StockId = ?", stock.Id);
156+
```
115157

116-
The generic parameter to the `Query` method specifies the type of object to create for each row. It can be one of your table classes, or any other class whose public properties match the column returned by the query. For instance, we could rewrite the above query as:
158+
The T in `db.Query<T>` specifies the object to create for each row. It can be a table class, or any other class whose public properties match the query columns.
117159

160+
```csharp
118161
public class Val {
119162
public decimal Money { get; set; }
120163
public DateTime Date { get; set; }
@@ -123,9 +166,4 @@ The generic parameter to the `Query` method specifies the type of object to crea
123166
{
124167
return db.Query<Val> ("select 'Price' as 'Money', 'Time' as 'Date' from Valuation where StockId = ?", stock.Id);
125168
}
126-
127-
You can perform low-level updates of the database using the `Execute` method.
128-
129-
## Asynchronous API
130-
131-
The asynchronous API has been removed, as it was only wrapping synchronous methods in Task.Run(), which has nasty side effects as multiple Tasks are queued. Use your own Task.Run to achieve the same effect.
169+
```

SQLite.Net.Tests/SQLite.Net2.Tests.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp2.2</TargetFramework>
4+
<TargetFramework>netcoreapp3.1</TargetFramework>
55

66
<IsPackable>false</IsPackable>
77
</PropertyGroup>
@@ -12,7 +12,8 @@
1212
<PrivateAssets>all</PrivateAssets>
1313
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1414
</PackageReference>
15-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
15+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
16+
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.3" />
1617
</ItemGroup>
1718

1819
<ItemGroup>

SQLite.Net.sln

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{5BD976
1414
LICENSE.txt = LICENSE.txt
1515
nuget\pack.ps1 = nuget\pack.ps1
1616
README.md = README.md
17-
nuget\sqlite-net2.nuspec = nuget\sqlite-net2.nuspec
1817
EndProjectSection
1918
EndProject
2019
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SQLite.Net2", "src\SQLite.Net\SQLite.Net2.csproj", "{FE454822-5982-4327-AE8D-26819659DC9A}"

examples/Stocks/Stocks.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
</ItemGroup>
8181
<ItemGroup>
8282
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3">
83-
<Version>2.0.2</Version>
83+
<Version>2.0.3</Version>
8484
</PackageReference>
8585
</ItemGroup>
8686
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

nuget/pack.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ if ($IsMacOS) {
66
$msbuild = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild -property installationPath
77
$msbuild = join-path $msbuild 'MSBuild\Current\Bin\MSBuild.exe'
88
}
9-
$version="2.0.2"
9+
$version="2.0.3"
1010
$versionSuffix=""
1111

1212
#####################

src/SQLite.Net/SQLite.Net2.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
</PropertyGroup>
4646

4747
<ItemGroup>
48-
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.0.2" />
48+
<PackageReference Include="SQLitePCLRaw.core" Version="2.0.3" />
4949
<None Include="..\..\LICENSE.md" Pack="true" PackagePath="" />
5050
</ItemGroup>
5151

0 commit comments

Comments
 (0)