Skip to content

Commit 0997f34

Browse files
authored
Merge pull request #451 from nickmshelley/connection-pool
Implement connection pool.
2 parents 9e71e30 + 66b61dd commit 0997f34

File tree

8 files changed

+578
-58
lines changed

8 files changed

+578
-58
lines changed

Documentation/Index.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- [Read-Only Databases](#read-only-databases)
1212
- [In-Memory Databases](#in-memory-databases)
1313
- [Thread-Safety](#thread-safety)
14+
- [Connection Pools](#connection-pools)
1415
- [Building Type-Safe SQL](#building-type-safe-sql)
1516
- [Expressions](#expressions)
1617
- [Compound Expressions](#compound-expressions)
@@ -251,7 +252,7 @@ Every Connection comes equipped with its own serial queue for statement executio
251252

252253
If you maintain multiple connections for a single database, consider setting a timeout (in seconds) and/or a busy handler:
253254

254-
```swift
255+
``` swift
255256
db.busyTimeout = 5
256257

257258
db.busyHandler({ tries in
@@ -265,6 +266,33 @@ db.busyHandler({ tries in
265266
> _Note:_ The default timeout is 0, so if you see `database is locked` errors, you may be trying to access the same database simultaneously from multiple connections.
266267

267268

269+
### Connection Pools
270+
271+
Connection pools use SQLite WAL mode to allow concurrent reads and writes, which can increase performance. Connection pools are created similar to connections:
272+
273+
``` swift
274+
let pool = try ConnectionPool("path/to/db.sqlite3")
275+
```
276+
277+
Writes are done inside of a readWrite block:
278+
279+
``` swift
280+
pool.readWrite { connection in
281+
try connection.run(users.insert(email <- "[email protected]", name <- "Alice"))
282+
}
283+
```
284+
285+
Reads are done inside of a read block:
286+
287+
``` swift
288+
pool.read { connection in
289+
for user in try connection.prepare(users) {
290+
print("id: \(user[id]), email: \(user[email]), name: \(user[name])")
291+
}
292+
}
293+
```
294+
295+
268296
## Building Type-Safe SQL
269297

270298
SQLite.swift comes with a typed expression layer that directly maps [Swift types](https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/SwiftStandardLibraryReference/) to their [SQLite counterparts](https://www.sqlite.org/datatype3.html).

SQLite.xcodeproj/project.pbxproj

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@
4646
03A65E941C6BB3030062603F /* ValueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B331C3F142E00AE3E12 /* ValueTests.swift */; };
4747
03A65E951C6BB3030062603F /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247B161C3F127200AE3E12 /* TestHelpers.swift */; };
4848
03A65E971C6BB3210062603F /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 03A65E961C6BB3210062603F /* libsqlite3.tbd */; };
49+
AA780B3D1CC201A700E0E95E /* ConnectionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3B1CC201A700E0E95E /* ConnectionPool.swift */; };
50+
AA780B3E1CC201A700E0E95E /* Dispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3C1CC201A700E0E95E /* Dispatcher.swift */; };
51+
AA780B411CC202C800E0E95E /* ConnectionPoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3F1CC202B000E0E95E /* ConnectionPoolTests.swift */; };
52+
AA780B421CC202C900E0E95E /* ConnectionPoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3F1CC202B000E0E95E /* ConnectionPoolTests.swift */; };
53+
AA780B431CC202CA00E0E95E /* ConnectionPoolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3F1CC202B000E0E95E /* ConnectionPoolTests.swift */; };
54+
AA780B441CC202F300E0E95E /* ConnectionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3B1CC201A700E0E95E /* ConnectionPool.swift */; };
55+
AA780B451CC202F300E0E95E /* Dispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3C1CC201A700E0E95E /* Dispatcher.swift */; };
56+
AA780B461CC202F400E0E95E /* ConnectionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3B1CC201A700E0E95E /* ConnectionPool.swift */; };
57+
AA780B471CC202F400E0E95E /* Dispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3C1CC201A700E0E95E /* Dispatcher.swift */; };
58+
AA780B481CC202F500E0E95E /* ConnectionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3B1CC201A700E0E95E /* ConnectionPool.swift */; };
59+
AA780B491CC202F500E0E95E /* Dispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA780B3C1CC201A700E0E95E /* Dispatcher.swift */; };
4960
19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1730E4390C775C25677D1 /* FTS5.swift */; };
5061
19A171E6FA242F72A308C594 /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; };
5162
19A17254FBA7894891F7297B /* FTS5Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19A1721B8984686B9963B45D /* FTS5Tests.swift */; };
@@ -170,25 +181,28 @@
170181
39548A6D1CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
171182
39548A6F1CA63C740003E3B5 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = "<group>"; };
172183
A121AC451CA35C79005A31D1 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
184+
AA780B3B1CC201A700E0E95E /* ConnectionPool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ConnectionPool.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
185+
AA780B3C1CC201A700E0E95E /* Dispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Dispatcher.swift; sourceTree = "<group>"; };
186+
AA780B3F1CC202B000E0E95E /* ConnectionPoolTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionPoolTests.swift; sourceTree = "<group>"; };
173187
EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
174188
EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = "<group>"; };
175189
EE247AD81C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
176190
EE247ADD1C3F04ED00AE3E12 /* SQLiteTests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SQLiteTests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
177191
EE247AE41C3F04ED00AE3E12 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
178192
EE247AEE1C3F06E900AE3E12 /* Blob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Blob.swift; sourceTree = "<group>"; };
179-
EE247AEF1C3F06E900AE3E12 /* Connection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Connection.swift; sourceTree = "<group>"; };
193+
EE247AEF1C3F06E900AE3E12 /* Connection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Connection.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
180194
EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fts3_tokenizer.h; sourceTree = "<group>"; };
181195
EE247AF11C3F06E900AE3E12 /* SQLite-Bridging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SQLite-Bridging.m"; sourceTree = "<group>"; };
182-
EE247AF21C3F06E900AE3E12 /* Statement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Statement.swift; sourceTree = "<group>"; };
196+
EE247AF21C3F06E900AE3E12 /* Statement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Statement.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
183197
EE247AF31C3F06E900AE3E12 /* Value.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Value.swift; sourceTree = "<group>"; };
184-
EE247AF51C3F06E900AE3E12 /* FTS4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FTS4.swift; sourceTree = "<group>"; };
198+
EE247AF51C3F06E900AE3E12 /* FTS4.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = FTS4.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
185199
EE247AF61C3F06E900AE3E12 /* R*Tree.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "R*Tree.swift"; sourceTree = "<group>"; };
186200
EE247AF71C3F06E900AE3E12 /* Foundation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Foundation.swift; sourceTree = "<group>"; };
187201
EE247AF81C3F06E900AE3E12 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
188202
EE247AFA1C3F06E900AE3E12 /* AggregateFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctions.swift; sourceTree = "<group>"; };
189203
EE247AFB1C3F06E900AE3E12 /* Collation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Collation.swift; sourceTree = "<group>"; };
190204
EE247AFC1C3F06E900AE3E12 /* CoreFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreFunctions.swift; sourceTree = "<group>"; };
191-
EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFunctions.swift; sourceTree = "<group>"; };
205+
EE247AFD1C3F06E900AE3E12 /* CustomFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CustomFunctions.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
192206
EE247AFE1C3F06E900AE3E12 /* Expression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expression.swift; sourceTree = "<group>"; };
193207
EE247AFF1C3F06E900AE3E12 /* Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = "<group>"; };
194208
EE247B001C3F06E900AE3E12 /* Query.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Query.swift; sourceTree = "<group>"; };
@@ -198,7 +212,7 @@
198212
EE247B181C3F134A00AE3E12 /* SetterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetterTests.swift; sourceTree = "<group>"; };
199213
EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AggregateFunctionsTests.swift; sourceTree = "<group>"; };
200214
EE247B1B1C3F137700AE3E12 /* BlobTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlobTests.swift; sourceTree = "<group>"; };
201-
EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionTests.swift; sourceTree = "<group>"; };
215+
EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ConnectionTests.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
202216
EE247B1E1C3F137700AE3E12 /* CoreFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreFunctionsTests.swift; sourceTree = "<group>"; };
203217
EE247B1F1C3F137700AE3E12 /* CustomFunctionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomFunctionsTests.swift; sourceTree = "<group>"; };
204218
EE247B201C3F137700AE3E12 /* ExpressionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpressionTests.swift; sourceTree = "<group>"; };
@@ -398,6 +412,7 @@
398412
EE247AE11C3F04ED00AE3E12 /* SQLiteTests */ = {
399413
isa = PBXGroup;
400414
children = (
415+
AA780B3F1CC202B000E0E95E /* ConnectionPoolTests.swift */,
401416
EE247B1A1C3F137700AE3E12 /* AggregateFunctionsTests.swift */,
402417
EE247B1B1C3F137700AE3E12 /* BlobTests.swift */,
403418
EE247B1D1C3F137700AE3E12 /* ConnectionTests.swift */,
@@ -422,6 +437,8 @@
422437
EE247AED1C3F06E900AE3E12 /* Core */ = {
423438
isa = PBXGroup;
424439
children = (
440+
AA780B3B1CC201A700E0E95E /* ConnectionPool.swift */,
441+
AA780B3C1CC201A700E0E95E /* Dispatcher.swift */,
425442
EE91808D1C46E5230038162A /* SQLite-Bridging.h */,
426443
EE247AEE1C3F06E900AE3E12 /* Blob.swift */,
427444
EE247AEF1C3F06E900AE3E12 /* Connection.swift */,
@@ -792,9 +809,11 @@
792809
03A65E741C6BB2DA0062603F /* Helpers.swift in Sources */,
793810
03A65E831C6BB2FB0062603F /* Operators.swift in Sources */,
794811
03A65E851C6BB2FB0062603F /* Schema.swift in Sources */,
812+
AA780B471CC202F400E0E95E /* Dispatcher.swift in Sources */,
795813
03A65E841C6BB2FB0062603F /* Query.swift in Sources */,
796814
03A65E7C1C6BB2F70062603F /* FTS4.swift in Sources */,
797815
03A65E771C6BB2E60062603F /* Connection.swift in Sources */,
816+
AA780B461CC202F400E0E95E /* ConnectionPool.swift in Sources */,
798817
03A65E7E1C6BB2FB0062603F /* AggregateFunctions.swift in Sources */,
799818
19A17EC0D68BA8C03288ADF7 /* FTS5.swift in Sources */,
800819
);
@@ -805,6 +824,7 @@
805824
buildActionMask = 2147483647;
806825
files = (
807826
03A65E881C6BB3030062603F /* BlobTests.swift in Sources */,
827+
AA780B431CC202CA00E0E95E /* ConnectionPoolTests.swift in Sources */,
808828
03A65E901C6BB3030062603F /* R*TreeTests.swift in Sources */,
809829
03A65E941C6BB3030062603F /* ValueTests.swift in Sources */,
810830
03A65E8F1C6BB3030062603F /* QueryTests.swift in Sources */,
@@ -827,6 +847,8 @@
827847
isa = PBXSourcesBuildPhase;
828848
buildActionMask = 2147483647;
829849
files = (
850+
AA780B491CC202F500E0E95E /* Dispatcher.swift in Sources */,
851+
AA780B481CC202F500E0E95E /* ConnectionPool.swift in Sources */,
830852
);
831853
runOnlyForDeploymentPostprocessing = 0;
832854
};
@@ -848,9 +870,11 @@
848870
EE247B081C3F06E900AE3E12 /* Value.swift in Sources */,
849871
EE247B121C3F06E900AE3E12 /* Operators.swift in Sources */,
850872
EE247B141C3F06E900AE3E12 /* Schema.swift in Sources */,
873+
AA780B3E1CC201A700E0E95E /* Dispatcher.swift in Sources */,
851874
EE247B131C3F06E900AE3E12 /* Query.swift in Sources */,
852875
EE247B061C3F06E900AE3E12 /* SQLite-Bridging.m in Sources */,
853876
EE247B071C3F06E900AE3E12 /* Statement.swift in Sources */,
877+
AA780B3D1CC201A700E0E95E /* ConnectionPool.swift in Sources */,
854878
EE247B0D1C3F06E900AE3E12 /* AggregateFunctions.swift in Sources */,
855879
19A1717B10CC941ACB5533D6 /* FTS5.swift in Sources */,
856880
);
@@ -861,6 +885,7 @@
861885
buildActionMask = 2147483647;
862886
files = (
863887
EE247B261C3F137700AE3E12 /* CoreFunctionsTests.swift in Sources */,
888+
AA780B411CC202C800E0E95E /* ConnectionPoolTests.swift in Sources */,
864889
EE247B291C3F137700AE3E12 /* FTS4Tests.swift in Sources */,
865890
EE247B191C3F134A00AE3E12 /* SetterTests.swift in Sources */,
866891
EE247B311C3F141E00AE3E12 /* SchemaTests.swift in Sources */,
@@ -897,9 +922,11 @@
897922
EE247B641C3F3FDB00AE3E12 /* Helpers.swift in Sources */,
898923
EE247B721C3F3FEC00AE3E12 /* Operators.swift in Sources */,
899924
EE247B741C3F3FEC00AE3E12 /* Schema.swift in Sources */,
925+
AA780B451CC202F300E0E95E /* Dispatcher.swift in Sources */,
900926
EE247B731C3F3FEC00AE3E12 /* Query.swift in Sources */,
901927
EE247B6B1C3F3FEC00AE3E12 /* FTS4.swift in Sources */,
902928
EE247B661C3F3FEC00AE3E12 /* Connection.swift in Sources */,
929+
AA780B441CC202F300E0E95E /* ConnectionPool.swift in Sources */,
903930
EE247B6D1C3F3FEC00AE3E12 /* AggregateFunctions.swift in Sources */,
904931
19A1750CEE9B05267995CF3D /* FTS5.swift in Sources */,
905932
);
@@ -910,6 +937,7 @@
910937
buildActionMask = 2147483647;
911938
files = (
912939
EE247B561C3F3FC700AE3E12 /* CoreFunctionsTests.swift in Sources */,
940+
AA780B421CC202C900E0E95E /* ConnectionPoolTests.swift in Sources */,
913941
EE247B5A1C3F3FC700AE3E12 /* OperatorsTests.swift in Sources */,
914942
EE247B541C3F3FC700AE3E12 /* BlobTests.swift in Sources */,
915943
EE247B5D1C3F3FC700AE3E12 /* SchemaTests.swift in Sources */,

0 commit comments

Comments
 (0)