You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Documentation/CustomSQLiteBuilds.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ GRDB builds SQLite with [swiftlyfalling/SQLiteLib](https://github.com/swiftlyfal
21
21
22
22
2. Choose your [extra compilation options](https://www.sqlite.org/compile.html). For example, `SQLITE_ENABLE_FTS5`, `SQLITE_ENABLE_PREUPDATE_HOOK`.
23
23
24
-
It is recommended that you enable the `SQLITE_ENABLE_SNAPSHOT` option. It allows GRDB to optimize [ValueObservation](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/valueobservation) when you use a [Database Pool](../README.md#database-pools).
24
+
It is recommended that you enable the `SQLITE_ENABLE_SNAPSHOT` option. It allows GRDB to optimize [ValueObservation](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/valueobservation) when you use a [Database Pool](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool).
25
25
26
26
3. Create a folder named `GRDBCustomSQLite` somewhere in your project directory.
Copy file name to clipboardExpand all lines: Documentation/WhyAdoptGRDB.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -154,11 +154,11 @@ See [Database Observation](https://swiftpackageindex.com/groue/grdb.swift/docume
154
154
155
155
### Non-blocking database reads
156
156
157
-
GRDB ships with two ways to access databases, [database queues](../README.md#database-queues) and [pools](../README.md#database-pools).
157
+
GRDB ships with two ways to access databases, [database queues](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasequeue) and [pools](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool).
158
158
159
159
Database queues look a lot like FMDB's [FMDatabaseQueue](https://github.com/ccgus/fmdb#using-fmdatabasequeue-and-thread-safety): they serialize database accesses in a serial dispatch queue. There is never more than one thread that is accessing the database. This means that a long running database transaction that happens in a background thread, such as the synchronization of your local database from a remote server, can block your UI. As long as the queue is busy, the main thread can't fetch the values it wants to display on screen.
160
160
161
-
[Database pools](../README.md#database-pools) can lift these unwanted locks. With database pools, reads are generally non-blocking, unless the maximum number of concurrent reads has been reached (and this maximum number can be configured).
161
+
[Database pools](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool) can lift these unwanted locks. With database pools, reads are generally non-blocking, unless the maximum number of concurrent reads has been reached (and this maximum number can be configured).
@@ -70,7 +70,7 @@ Programming tools for both database beginners and SQLite experts:
70
70
- [Records](#records): Fetching and persistence methods for your custom structs and class hierarchies.
71
71
- [Query Interface](#the-query-interface): A swift way to avoid the SQL language.
72
72
- [Associations]: Relations and joins between record types.
73
-
- [WAL Mode Support](#database-pools): Extra performance for multi-threaded applications.
73
+
- [WAL Mode Support](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool): Extra performance for multi-threaded applications.
74
74
- [Migrations]: Transform your database as your application evolves.
75
75
- [Database Observation]: Observe database changes and transactions.
76
76
- [Full-Text Search]
@@ -428,7 +428,7 @@ GRDB offers two libraries, `GRDB` and `GRDB-dynamic`. Pick only one. When in dou
428
428
Database Connections
429
429
====================
430
430
431
-
GRDB provides two classes for accessing SQLite databases: `DatabaseQueue` and `DatabasePool`:
431
+
GRDB provides two classes for accessing SQLite databases: [`DatabaseQueue`] and [`DatabasePool`]:
432
432
433
433
```swift
434
434
import GRDB
@@ -444,137 +444,7 @@ The differences are:
444
444
- Database pools open your SQLite database in the [WAL mode](https://www.sqlite.org/wal.html) (unless read-only).
445
445
- Database queues support [in-memory databases](https://www.sqlite.org/inmemorydb.html).
446
446
447
-
**If you are not sure, choose DatabaseQueue.** You will always be able to switch to DatabasePool later.
448
-
449
-
- [Database Queues](#database-queues)
450
-
- [Database Pools](#database-pools)
451
-
452
-
453
-
## Database Queues
454
-
455
-
**Open a database queue** with the path to a database file:
456
-
457
-
```swift
458
-
import GRDB
459
-
460
-
let dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")
461
-
let inMemoryDBQueue = try DatabaseQueue()
462
-
```
463
-
464
-
SQLite creates the database file if it does not already exist. The connection is closed when the database queue gets deinitialized.
465
-
466
-
**A database queue can be used from any thread.** The `write` and `read` methods are synchronous, and block the current thread until your database statements are executed in a protected dispatch queue:
467
-
468
-
```swift
469
-
// Modify the database:
470
-
try dbQueue.write { db in
471
-
try db.create(table: "place") { ... }
472
-
try Place(...).insert(db)
473
-
}
474
-
475
-
// Read values:
476
-
try dbQueue.read { db in
477
-
let places = try Place.fetchAll(db)
478
-
let placeCount = try Place.fetchCount(db)
479
-
}
480
-
```
481
-
482
-
Database access methods can return values:
483
-
484
-
```swift
485
-
let placeCount = try dbQueue.read { db in
486
-
try Place.fetchCount(db)
487
-
}
488
-
489
-
let newPlaceCount = try dbQueue.write { db -> Int in
490
-
try Place(...).insert(db)
491
-
return try Place.fetchCount(db)
492
-
}
493
-
```
494
-
495
-
See the [Concurrency] guide for asynchronous database accesses.
496
-
497
-
**A database queue serializes accesses to the database**, which means that there is never more than one thread that uses the database.
498
-
499
-
- When you don't need to modify the database, prefer the `read` method. It prevents any modification to the database.
500
-
501
-
- The `write` method wraps your database statements in a transaction that commits if and only if no error occurs. On the first unhandled error, all changes are reverted, the whole transaction is rollbacked, and the error is rethrown.
502
-
503
-
When precise transaction handling is required, see [Transactions and Savepoints].
504
-
505
-
**A database queue needs your application to follow rules in order to deliver its safety guarantees.** Please refer to the [Concurrency] guide.
506
-
507
-
See [Database Configuration] for DatabaseQueue options.
508
-
509
-
> :bulb: **Tip**: see the [Demo Applications] for sample code.
510
-
511
-
512
-
## Database Pools
513
-
514
-
**A database pool allows concurrent database accesses.**
515
-
516
-
```swift
517
-
import GRDB
518
-
let dbPool = try DatabasePool(path: "/path/to/database.sqlite")
519
-
```
520
-
521
-
SQLite creates the database file if it does not already exist. The connection is closed when the database pool gets deinitialized.
522
-
523
-
> **Note**: unless read-only, a database pool opens your database in the SQLite "WAL mode". The WAL mode does not fit all situations. Please have a look at https://www.sqlite.org/wal.html.
524
-
525
-
**A database pool can be used from any thread.** The `write` and `read` methods are synchronous, and block the current thread until your database statements are executed in a protected dispatch queue:
526
-
527
-
```swift
528
-
// Modify the database:
529
-
try dbPool.write { db in
530
-
try db.create(table: "place") { ... }
531
-
try Place(...).insert(db)
532
-
}
533
-
534
-
// Read values:
535
-
try dbPool.read { db in
536
-
let places = try Place.fetchAll(db)
537
-
let placeCount = try Place.fetchCount(db)
538
-
}
539
-
```
540
-
541
-
Database access methods can return values:
542
-
543
-
```swift
544
-
let placeCount = try dbPool.read { db in
545
-
try Place.fetchCount(db)
546
-
}
547
-
548
-
let newPlaceCount = try dbPool.write { db -> Int in
549
-
try Place(...).insert(db)
550
-
return try Place.fetchCount(db)
551
-
}
552
-
```
553
-
554
-
See the [Concurrency] guide for asynchronous database accesses.
555
-
556
-
**Database pools allow several threads to access the database at the same time:**
557
-
558
-
- When you don't need to modify the database, prefer the `read` method, because several threads can perform reads in parallel.
559
-
560
-
Reads are generally non-blocking, unless the maximum number of concurrent reads has been reached. In this case, a read has to wait for another read to complete. That maximum number can be [configured](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/configuration).
561
-
562
-
- Reads are guaranteed an immutable view of the last committed state of the database, regardless of concurrent writes. This kind of isolation is called [snapshot isolation](https://sqlite.org/isolation.html).
563
-
564
-
- Unlike reads, writes are serialized. There is never more than a single thread that is writing into the database.
565
-
566
-
- The `write` method wraps your database statements in a transaction that commits if and only if no error occurs. On the first unhandled error, all changes are reverted, the whole transaction is rollbacked, and the error is rethrown.
567
-
568
-
When precise transaction handling is required, see [Transactions and Savepoints].
569
-
570
-
- Database pools can take [snapshots](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasesnapshot) of the database.
571
-
572
-
**A database pool needs your application to follow rules in order to deliver its safety guarantees.** See the [Concurrency] guide for more details about database pools, how they differ from database queues, and advanced use cases.
573
-
574
-
See [Database Configuration] for DatabasePool options.
575
-
576
-
> :bulb: **Tip**: see the [Demo Applications] for sample code.
577
-
447
+
**If you are not sure, choose `DatabaseQueue`.** You will always be able to switch to `DatabasePool` later.
578
448
579
449
580
450
SQLite API
@@ -1729,7 +1599,7 @@ When the same query will be used several times in the lifetime of your applicati
1729
1599
1730
1600
**Don't cache statements yourself.**
1731
1601
1732
-
> **Note**: This is because you don't have the necessary tools. Statements are tied to specific SQLite connections and dispatch queues which you don't manage yourself, especially when you use [database pools](#database-pools). A change in the database schema [may, or may not](https://www.sqlite.org/compile.html#max_schema_retry) invalidate a statement.
1602
+
> **Note**: This is because you don't have the necessary tools. Statements are tied to specific SQLite connections and dispatch queues which you don't manage yourself, especially when you use [database pools]. A change in the database schema [may, or may not](https://www.sqlite.org/compile.html#max_schema_retry) invalidate a statement.
1733
1603
1734
1604
Instead, use the `cachedStatement` method. GRDB does all the hard caching and [memory management](#memory-management) stuff for you:
1735
1605
@@ -5709,15 +5579,15 @@ See [SQLCipher 4.0.0 Release](https://www.zetetic.net/blog/2018/11/30/sqlcipher-
5709
5579
5710
5580
**You can change the passphrase** of an already encrypted database.
5711
5581
5712
-
When you use a [database queue](#database-queues), open the database with the old passphrase, and then apply the new passphrase:
5582
+
When you use a [database queue](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasequeue), open the database with the old passphrase, and then apply the new passphrase:
5713
5583
5714
5584
```swift
5715
5585
try dbQueue.write { db in
5716
5586
try db.changePassphrase("newSecret")
5717
5587
}
5718
5588
```
5719
5589
5720
-
When you use a [database pool](#database-pools), make sure that no concurrent read can happen by changing the passphrase within the `barrierWriteWithoutTransaction` block. You must also ensure all future reads open a new database connection by calling the `invalidateReadOnlyConnections` method:
5590
+
When you use a [database pool](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool), make sure that no concurrent read can happen by changing the passphrase within the `barrierWriteWithoutTransaction` block. You must also ensure all future reads open a new database connection by calling the `invalidateReadOnlyConnections` method:
5721
5591
5722
5592
```swift
5723
5593
try dbPool.barrierWriteWithoutTransaction { db in
@@ -5865,7 +5735,7 @@ config.prepareDatabase { db in
5865
5735
let dbQueue = try DatabaseQueue(path: dbPath, configuration: config)
5866
5736
```
5867
5737
5868
-
For the same reason, [database pools](#database-pools), which open SQLite connections on demand, may fail at any time as soon as the passphrase becomes unavailable:
5738
+
For the same reason, [database pools], which open SQLite connections on demand, may fail at any time as soon as the passphrase becomes unavailable:
5869
5739
5870
5740
```swift
5871
5741
// Success if and only if the passphrase is available
The `backup` method blocks the current thread until the destination database contains the same contents as the source database.
5901
5771
5902
-
When the source is a [database pool](#database-pools), concurrent writes can happen during the backup. Those writes may, or may not, be reflected in the backup, but they won't trigger any error.
5772
+
When the source is a [database pool](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool), concurrent writes can happen during the backup. Those writes may, or may not, be reflected in the backup, but they won't trigger any error.
**The iOS operating system likes applications that do not consume much memory.**
6414
6284
6415
-
[Database queues](#database-queues) and [pools](#database-pools) automatically free non-essential memory when the application receives a memory warning, and when the application enters background.
6285
+
[Database queues] and [pools](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool) automatically free non-essential memory when the application receives a memory warning, and when the application enters background.
6416
6286
6417
6287
You can opt out of this automatic memory management:
6418
6288
@@ -6429,7 +6299,7 @@ let dbQueue = try DatabaseQueue(path: dbPath, configuration: config) // or Datab
6429
6299
6430
6300
Data protection can be enabled [globally](https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/AddingCapabilities/AddingCapabilities.html#//apple_ref/doc/uid/TP40012582-CH26-SW30) for all files created by an application.
6431
6301
6432
-
You can also explicitly protect a database, by configuring its enclosing *directory*. This will not only protect the database file, but also all [temporary files](https://www.sqlite.org/tempfiles.html) created by SQLite (including the persistent `.shm` and `.wal` files created by [database pools](#database-pools)).
6302
+
You can also explicitly protect a database, by configuring its enclosing *directory*. This will not only protect the database file, but also all [temporary files](https://www.sqlite.org/tempfiles.html) created by SQLite (including the persistent `.shm` and `.wal` files created by [database pools]).
6433
6303
6434
6304
For example, to explicitly use [complete](https://developer.apple.com/reference/foundation/fileprotectiontype/1616200-complete) protection:
6435
6305
@@ -7046,6 +6916,14 @@ This chapter has [moved](https://swiftpackageindex.com/groue/grdb.swift/document
7046
6916
7047
6917
This chapter has [moved](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/configuration).
7048
6918
6919
+
#### Database Queues
6920
+
6921
+
This chapter has [moved](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasequeue).
6922
+
6923
+
#### Database Pools
6924
+
6925
+
This chapter has [moved](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/databasepool).
6926
+
7049
6927
#### Database Snapshots
7050
6928
7051
6929
This chapter has [moved](https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/concurrency).
@@ -7173,4 +7051,8 @@ This chapter has been superseded by [ValueObservation] and [DatabaseRegionObserv
7173
7051
[Persistence Methods]: #persistence-methods
7174
7052
[persistence methods]: #persistence-methods
7175
7053
[RecordError]: #recorderror
7176
-
[Transactions and Savepoints]: https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/transactions
7054
+
[Transactions and Savepoints]: https://swiftpackageindex.com/groue/grdb.swift/documentation/grdb/transactions
0 commit comments