Skip to content

Commit 948e911

Browse files
committed
Merge branch 'development'
2 parents 6884bf1 + 85b781b commit 948e911

File tree

16 files changed

+164
-402
lines changed

16 files changed

+164
-402
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
88
#### 5.x Releases
99

1010
<!-- - [Next Release](#next-release) -->
11-
- `5.0.x` Releases - [5.0.0](#500) | [5.0.1](#501)
11+
12+
- `5.0.x` Releases - [5.0.0](#500) | [5.0.1](#501) | [5.0.2](#502)
1213
- `5.0.0` Betas - [5.0.0-beta](#500-beta) | [5.0.0-beta.2](#500-beta2) | [5.0.0-beta.3](#500-beta3) | [5.0.0-beta.4](#500-beta4) | [5.0.0-beta.5](#500-beta5) | [5.0.0-beta.6](#500-beta6) | [5.0.0-beta.7](#500-beta7) | [5.0.0-beta.8](#500-beta8) | [5.0.0-beta.9](#500-beta9) | [5.0.0-beta.10](#500-beta10) | [5.0.0-beta.11](#500-beta11)
1314

1415

@@ -68,6 +69,14 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
6869
- [0.110.0](#01100), ...
6970

7071

72+
## 5.0.2
73+
74+
Released October 6, 2020 &bull; [diff](https://github.com/groue/GRDB.swift/compare/v5.0.1...v5.0.2)
75+
76+
- **Fixed**: [#844](https://github.com/groue/GRDB.swift/issues/844): Fix a crash in the demo app
77+
- **Fixed**: [#847](https://github.com/groue/GRDB.swift/issues/847): Remove dependency on SQLITE_ENABLE_SNAPSHOT
78+
79+
7180
## 5.0.1
7281

7382
Released September 27, 2020 &bull; [diff](https://github.com/groue/GRDB.swift/compare/v5.0.0...v5.0.1)

Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS.xcodeproj/xcshareddata/xcschemes/GRDBDemoiOS.xcscheme

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
</Testables>
3232
</TestAction>
3333
<LaunchAction
34-
buildConfiguration = "Release"
34+
buildConfiguration = "Debug"
3535
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
3636
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
3737
launchStyle = "0"

Documentation/DemoApps/GRDBDemoiOS/GRDBDemoiOS/ViewControllers/PlayerListViewController.swift

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,16 @@ class PlayerListViewController: UITableViewController {
1616
private var playerOrdering: PlayerOrdering = .byScore {
1717
didSet {
1818
configureOrderingBarButtonItem()
19-
configureTableView()
19+
configureDataSourceContent()
2020
}
2121
}
2222

2323
override func viewDidLoad() {
2424
super.viewDidLoad()
2525
configureToolbar()
2626
configureNavigationItem()
27-
configureTableView()
27+
configureDataSource()
28+
configureDataSourceContent()
2829
}
2930

3031
override func viewWillAppear(_ animated: Bool) {
@@ -79,7 +80,7 @@ class PlayerListViewController: UITableViewController {
7980
})
8081
}
8182

82-
private func configureTableView() {
83+
private func configureDataSource() {
8384
dataSource = PlayerDataSource(tableView: tableView) { (tableView, indexPath, player) in
8485
let cell = tableView.dequeueReusableCell(withIdentifier: "Player", for: indexPath)
8586
if player.name.isEmpty {
@@ -92,26 +93,28 @@ class PlayerListViewController: UITableViewController {
9293
}
9394
dataSource.defaultRowAnimation = .fade
9495
tableView.dataSource = dataSource
95-
96+
}
97+
98+
private func configureDataSourceContent() {
9699
switch playerOrdering {
97100
case .byName:
98101
playersCancellable = AppDatabase.shared.observePlayersOrderedByName(
99102
onError: { error in fatalError("Unexpected error: \(error)") },
100103
onChange: { [weak self] players in
101104
guard let self = self else { return }
102-
self.updateTableView(with: players)
105+
self.updateDataSourceContent(with: players)
103106
})
104107
case .byScore:
105108
playersCancellable = AppDatabase.shared.observePlayersOrderedByScore(
106109
onError: { error in fatalError("Unexpected error: \(error)") },
107110
onChange: { [weak self] players in
108111
guard let self = self else { return }
109-
self.updateTableView(with: players)
112+
self.updateDataSourceContent(with: players)
110113
})
111114
}
112115
}
113116

114-
private func updateTableView(with players: [Player]) {
117+
private func updateDataSourceContent(with players: [Player]) {
115118
var snapshot = NSDiffableDataSourceSnapshot<Int, Player>()
116119
snapshot.appendSections([0])
117120
snapshot.appendItems(players, toSection: 0)

GRDB.swift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'GRDB.swift'
3-
s.version = '5.0.1'
3+
s.version = '5.0.2'
44

55
s.license = { :type => 'MIT', :file => 'LICENSE' }
66
s.summary = 'A toolkit for SQLite databases, with a focus on application development.'

GRDB/Core/Database.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -488,18 +488,17 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
488488

489489
// MARK: - Snapshots
490490

491-
/// Returns a snapshot that must be freed with `grdb_snapshot_free`.
491+
#if SQLITE_ENABLE_SNAPSHOT
492+
/// Returns a snapshot that must be freed with `sqlite3_snapshot_free`.
492493
///
493494
/// See https://www.sqlite.org/c3ref/snapshot.html
494495
func takeVersionSnapshot() throws -> UnsafeMutablePointer<sqlite3_snapshot> {
495496
var snapshot: UnsafeMutablePointer<sqlite3_snapshot>?
496497
let code = withUnsafeMutablePointer(to: &snapshot) {
497-
grdb_snapshot_get(sqliteConnection, "main", $0)
498+
sqlite3_snapshot_get(sqliteConnection, "main", $0)
498499
}
499500
guard code == SQLITE_OK else {
500-
// Don't grab `lastErrorMessage`, because grdb_snapshot_get may be a
501-
// shim that does not call the missing sqlite3_snapshot_get.
502-
throw DatabaseError(resultCode: code)
501+
throw DatabaseError(resultCode: code, message: lastErrorMessage)
503502
}
504503
if let snapshot = snapshot {
505504
return snapshot
@@ -511,12 +510,13 @@ public final class Database: CustomStringConvertible, CustomDebugStringConvertib
511510
func wasChanged(since initialSnapshot: UnsafeMutablePointer<sqlite3_snapshot>) throws -> Bool {
512511
let secondSnapshot = try takeVersionSnapshot()
513512
defer {
514-
grdb_snapshot_free(secondSnapshot)
513+
sqlite3_snapshot_free(secondSnapshot)
515514
}
516-
let cmp = grdb_snapshot_cmp(initialSnapshot, secondSnapshot)
515+
let cmp = sqlite3_snapshot_cmp(initialSnapshot, secondSnapshot)
517516
assert(cmp <= 0, "Unexpected snapshot ordering")
518517
return cmp < 0
519518
}
519+
#endif
520520

521521
// MARK: - Authorizer
522522

GRDB/Core/DatabasePool.swift

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@ extension DatabasePool: DatabaseReader {
874874
//
875875
// 3. Install the transaction observer.
876876

877+
#if SQLITE_ENABLE_SNAPSHOT
877878
if scheduler.immediateInitialValue() {
878879
do {
879880
let initialSnapshot = try makeSnapshot()
@@ -904,10 +905,36 @@ extension DatabasePool: DatabaseReader {
904905
}
905906
}
906907
}
908+
#else
909+
if scheduler.immediateInitialValue() {
910+
do {
911+
let initialValue = try read(observer.fetchInitialValue)
912+
onChange(initialValue)
913+
addObserver(observer: observer)
914+
} catch {
915+
observer.complete()
916+
observation.events.didFail?(error)
917+
}
918+
} else {
919+
_weakAsyncRead { [weak self] dbResult in
920+
guard let self = self, let dbResult = dbResult else { return }
921+
if observer.isCompleted { return }
922+
923+
do {
924+
let initialValue = try observer.fetchInitialValue(dbResult.get())
925+
observer.notifyChange(initialValue)
926+
self.addObserver(observer: observer)
927+
} catch {
928+
observer.notifyErrorAndComplete(error)
929+
}
930+
}
931+
}
932+
#endif
907933

908934
return observer
909935
}
910936

937+
#if SQLITE_ENABLE_SNAPSHOT
911938
// Support for _addConcurrent(observation:)
912939
private func add<Reducer: ValueReducer>(
913940
observer: ValueObserver<Reducer>,
@@ -924,20 +951,11 @@ extension DatabasePool: DatabaseReader {
924951
// database versions. It prevents database checkpointing,
925952
// and keeps versions (`sqlite3_snapshot`) valid
926953
// and comparable.
927-
let fetchNeeded: Bool = withExtendedLifetime(initialSnapshot) {
928-
// Version is nil if SQLite is not compiled with
929-
// SQLITE_ENABLE_SNAPSHOT, or if the DatabaseSnaphot
930-
// could not grab its version. In this case, we don't
931-
// care, and just fetch a fresh value.
954+
let fetchNeeded: Bool = try withExtendedLifetime(initialSnapshot) {
932955
guard let initialVersion = initialSnapshot.version else {
933956
return true
934957
}
935-
do {
936-
return try db.wasChanged(since: initialVersion)
937-
} catch {
938-
// ignore: we'll just re-fetch
939-
return true
940-
}
958+
return try db.wasChanged(since: initialVersion)
941959
}
942960

943961
if fetchNeeded {
@@ -956,6 +974,27 @@ extension DatabasePool: DatabaseReader {
956974
}
957975
}
958976
}
977+
#else
978+
// Support for _addConcurrent(observation:)
979+
private func addObserver<Reducer: ValueReducer>(observer: ValueObserver<Reducer>) {
980+
_weakAsyncWriteWithoutTransaction { db in
981+
guard let db = db else { return }
982+
if observer.isCompleted { return }
983+
984+
do {
985+
observer.events.databaseDidChange?()
986+
if let value = try observer.fetchValue(db) {
987+
observer.notifyChange(value)
988+
}
989+
990+
// Now we can start observation
991+
db.add(transactionObserver: observer, extent: .observerLifetime)
992+
} catch {
993+
observer.notifyErrorAndComplete(error)
994+
}
995+
}
996+
}
997+
#endif
959998
}
960999

9611000
extension DatabasePool {

GRDB/Core/DatabaseSnapshot.swift

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ public class DatabaseSnapshot: DatabaseReader {
1414
serializedDatabase.configuration
1515
}
1616

17-
/// Not nil iff SQLite was compiled with `SQLITE_ENABLE_SNAPSHOT`.
17+
#if SQLITE_ENABLE_SNAPSHOT
18+
// Support for ValueObservation in DatabasePool
1819
private(set) var version: UnsafeMutablePointer<sqlite3_snapshot>?
20+
#endif
1921

2022
init(path: String, configuration: Configuration = Configuration(), defaultLabel: String, purpose: String) throws {
2123
var configuration = DatabasePool.readerConfiguration(configuration)
@@ -41,17 +43,22 @@ public class DatabaseSnapshot: DatabaseReader {
4143
// Acquire snapshot isolation
4244
try db.internalCachedSelectStatement(sql: "SELECT rootpage FROM sqlite_master LIMIT 1").makeCursor().next()
4345

44-
// Support for ValueObservation in DatabasePool
46+
#if SQLITE_ENABLE_SNAPSHOT
47+
// We must expect an error: https://www.sqlite.org/c3ref/snapshot_get.html
48+
// > At least one transaction must be written to it first.
4549
version = try? db.takeVersionSnapshot()
50+
#endif
4651
}
4752
}
4853

4954
deinit {
5055
// Leave snapshot isolation
5156
serializedDatabase.reentrantSync { db in
57+
#if SQLITE_ENABLE_SNAPSHOT
5258
if let version = version {
53-
grdb_snapshot_free(version)
59+
sqlite3_snapshot_free(version)
5460
}
61+
#endif
5562
try? db.commit()
5663
}
5764
}

Makefile

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ test_framework_GRDBOSX_maxSwift:
129129
-scheme GRDBOSX \
130130
SWIFT_VERSION=$(MAX_SWIFT_VERSION) \
131131
'OTHER_SWIFT_FLAGS=$(inherited) -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_PREUPDATE_HOOK' \
132-
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1 GRDB_SQLITE_ENABLE_SNAPSHOT=1' \
132+
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1' \
133133
$(TEST_ACTIONS) \
134134
$(XCPRETTY)
135135

@@ -140,7 +140,7 @@ ifdef MIN_SWIFT_VERSION
140140
-scheme GRDBOSX \
141141
SWIFT_VERSION=$(MIN_SWIFT_VERSION) \
142142
'OTHER_SWIFT_FLAGS=$(inherited) -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_PREUPDATE_HOOK' \
143-
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1 GRDB_SQLITE_ENABLE_SNAPSHOT=1' \
143+
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1' \
144144
$(TEST_ACTIONS) \
145145
$(XCPRETTY)
146146
endif
@@ -164,7 +164,7 @@ test_framework_GRDBiOS_maxTarget_maxSwift:
164164
-destination $(MAX_IOS_DESTINATION) \
165165
SWIFT_VERSION=$(MAX_SWIFT_VERSION) \
166166
'OTHER_SWIFT_FLAGS=$(inherited) -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_PREUPDATE_HOOK' \
167-
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1 GRDB_SQLITE_ENABLE_SNAPSHOT=1' \
167+
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1' \
168168
$(TEST_ACTIONS) \
169169
$(XCPRETTY)
170170

@@ -176,7 +176,7 @@ ifdef MIN_SWIFT_VERSION
176176
-destination $(MAX_IOS_DESTINATION) \
177177
SWIFT_VERSION=$(MIN_SWIFT_VERSION) \
178178
'OTHER_SWIFT_FLAGS=$(inherited) -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_PREUPDATE_HOOK' \
179-
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1 GRDB_SQLITE_ENABLE_SNAPSHOT=1' \
179+
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1' \
180180
$(TEST_ACTIONS) \
181181
$(XCPRETTY)
182182
endif
@@ -200,7 +200,7 @@ test_framework_GRDBtvOS_maxTarget_maxSwift:
200200
-destination $(MAX_TVOS_DESTINATION) \
201201
SWIFT_VERSION=$(MAX_SWIFT_VERSION) \
202202
'OTHER_SWIFT_FLAGS=$(inherited) -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_PREUPDATE_HOOK' \
203-
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1 GRDB_SQLITE_ENABLE_SNAPSHOT=1' \
203+
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1' \
204204
$(TEST_ACTIONS) \
205205
$(XCPRETTY)
206206

@@ -212,7 +212,7 @@ ifdef MIN_SWIFT_VERSION
212212
-destination $(MAX_TVOS_DESTINATION) \
213213
SWIFT_VERSION=$(MIN_SWIFT_VERSION) \
214214
'OTHER_SWIFT_FLAGS=$(inherited) -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_PREUPDATE_HOOK' \
215-
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1 GRDB_SQLITE_ENABLE_SNAPSHOT=1' \
215+
'GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GRDB_SQLITE_ENABLE_PREUPDATE_HOOK=1' \
216216
$(TEST_ACTIONS) \
217217
$(XCPRETTY)
218218
endif
@@ -388,10 +388,11 @@ SQLiteCustom: SQLiteCustom/src/sqlite3.h
388388
echo '/* Makefile generated */' > SQLiteCustom/GRDBCustomSQLite-USER.h
389389
echo '#define SQLITE_ENABLE_PREUPDATE_HOOK' >> SQLiteCustom/GRDBCustomSQLite-USER.h
390390
echo '#define SQLITE_ENABLE_FTS5' >> SQLiteCustom/GRDBCustomSQLite-USER.h
391+
echo '#define SQLITE_ENABLE_SNAPSHOT' >> SQLiteCustom/GRDBCustomSQLite-USER.h
391392
echo '// Makefile generated' > SQLiteCustom/GRDBCustomSQLite-USER.xcconfig
392-
echo 'CUSTOM_OTHER_SWIFT_FLAGS = -D SQLITE_ENABLE_PREUPDATE_HOOK -D SQLITE_ENABLE_FTS5' >> SQLiteCustom/GRDBCustomSQLite-USER.xcconfig
393+
echo 'CUSTOM_OTHER_SWIFT_FLAGS = -D SQLITE_ENABLE_PREUPDATE_HOOK -D SQLITE_ENABLE_FTS5 -D SQLITE_ENABLE_SNAPSHOT' >> SQLiteCustom/GRDBCustomSQLite-USER.xcconfig
393394
echo '// Makefile generated' > SQLiteCustom/src/SQLiteLib-USER.xcconfig
394-
echo 'CUSTOM_SQLLIBRARY_CFLAGS = -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_FTS5' >> SQLiteCustom/src/SQLiteLib-USER.xcconfig
395+
echo 'CUSTOM_SQLLIBRARY_CFLAGS = -DSQLITE_ENABLE_PREUPDATE_HOOK -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_SNAPSHOT' >> SQLiteCustom/src/SQLiteLib-USER.xcconfig
395396

396397
# Makes sure the SQLiteCustom/src submodule has been downloaded
397398
SQLiteCustom/src/sqlite3.h:
@@ -408,8 +409,8 @@ ifdef JAZZY
408409
--author 'Gwendal Roué' \
409410
--author_url https://github.com/groue \
410411
--github_url https://github.com/groue/GRDB.swift \
411-
--github-file-prefix https://github.com/groue/GRDB.swift/tree/v5.0.1 \
412-
--module-version 5.0.1 \
412+
--github-file-prefix https://github.com/groue/GRDB.swift/tree/v5.0.2 \
413+
--module-version 5.0.2 \
413414
--module GRDB \
414415
--root-url http://groue.github.io/GRDB.swift/docs/5.0/ \
415416
--output Documentation/Reference \

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
---
1313

14-
**Latest release**: September 27, 2020 • version 5.0.1[CHANGELOG](CHANGELOG.md)[Migrating From GRDB 4 to GRDB 5](Documentation/GRDB5MigrationGuide.md)
14+
**Latest release**: October 6, 2020 • version 5.0.2[CHANGELOG](CHANGELOG.md)[Migrating From GRDB 4 to GRDB 5](Documentation/GRDB5MigrationGuide.md)
1515

1616
**Requirements**: iOS 10.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+ &bull; Swift 5.2+ / Xcode 11.4+
1717

1818
| Swift version | GRDB version |
1919
| -------------- | ----------------------------------------------------------- |
20-
| **Swift 5.2+** | **v5.0.1** |
20+
| **Swift 5.2+** | **v5.0.2** |
2121
| Swift 5.1 | [v4.14.0](https://github.com/groue/GRDB.swift/tree/v4.14.0) |
2222
| Swift 5 | [v4.14.0](https://github.com/groue/GRDB.swift/tree/v4.14.0) |
2323
| Swift 4.2 | [v4.14.0](https://github.com/groue/GRDB.swift/tree/v4.14.0) |

0 commit comments

Comments
 (0)