Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
groue committed Sep 20, 2020
2 parents ba253dc + 5119c06 commit 1ea4a44
Show file tree
Hide file tree
Showing 44 changed files with 371 additions and 269 deletions.
10 changes: 7 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:

#### 5.x Releases

- `5.0.x` Releases - [5.0.0](#500)
- `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)


Expand Down Expand Up @@ -70,9 +71,12 @@ GRDB adheres to [Semantic Versioning](https://semver.org/), with one exception:
- [0.110.0](#01100), ...


<!--
## Next Release
-->
## 5.0.0

Released September 20, 2020 &bull; [diff](https://github.com/groue/GRDB.swift/compare/v5.0.0-beta.11...v5.0.0)

- **Fixed**: [#838](https://github.com/groue/GRDB.swift/issues/838): Have indexed colums inherit the `ifNotExists` flag from table creation.


## 5.0.0-beta.11

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
563F3E7724A78BD700982CF8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 563F3E7624A78BD700982CF8 /* Assets.xcassets */; };
563F3E7A24A78BD700982CF8 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 563F3E7924A78BD700982CF8 /* Preview Assets.xcassets */; };
563F3E7D24A78BD700982CF8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 563F3E7B24A78BD700982CF8 /* LaunchScreen.storyboard */; };
5651F47D24A8837800727C9D /* GRDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5651F47124A8835B00727C9D /* GRDB.framework */; };
5651F47F24A884B200727C9D /* World.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5651F47E24A884B200727C9D /* World.swift */; };
5651F48124A8856300727C9D /* PlayerList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5651F48024A8856300727C9D /* PlayerList.swift */; };
5651F48324A885AF00727C9D /* PlayerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5651F48224A885AF00727C9D /* PlayerListViewModel.swift */; };
5651F48524A8905100727C9D /* PlayerEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5651F48424A8905100727C9D /* PlayerEditor.swift */; };
5651F48724A8909F00727C9D /* PlayerFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5651F48624A8909F00727C9D /* PlayerFormViewModel.swift */; };
566148C9251791570083D8B8 /* GRDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5651F47124A8835B00727C9D /* GRDB.framework */; };
566148CA251791570083D8B8 /* GRDB.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5651F47124A8835B00727C9D /* GRDB.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
5678066124A8A4E400606BC6 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 5678066324A8A4E400606BC6 /* Localizable.stringsdict */; };
5678066524A8B7DD00606BC6 /* PlayerCreationSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5678066424A8B7DD00606BC6 /* PlayerCreationSheet.swift */; };
56AAFD4724A78F9A0077EADB /* AppDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56AAFD4524A78F9A0077EADB /* AppDatabase.swift */; };
Expand Down Expand Up @@ -82,15 +82,22 @@
remoteGlobalIDString = AAA4DDD4230F262000C74B15;
remoteInfo = GRDBtvOSTests;
};
5651F47A24A8836B00727C9D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5651F45F24A8835B00727C9D /* GRDB.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 56E5D7C91B4D3FED00430942;
remoteInfo = GRDBiOS;
};
/* End PBXContainerItemProxy section */

/* Begin PBXCopyFilesBuildPhase section */
566148CB251791570083D8B8 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
566148CA251791570083D8B8 /* GRDB.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
563F3E6D24A78BD400982CF8 /* GRDBCombineDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GRDBCombineDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
563F3E7024A78BD400982CF8 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
Expand All @@ -100,7 +107,6 @@
563F3E7C24A78BD700982CF8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
563F3E7E24A78BD700982CF8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5651F45F24A8835B00727C9D /* GRDB.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GRDB.xcodeproj; path = ../../../GRDB.xcodeproj; sourceTree = "<group>"; };
5651F47E24A884B200727C9D /* World.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = World.swift; sourceTree = "<group>"; };
5651F48024A8856300727C9D /* PlayerList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerList.swift; sourceTree = "<group>"; };
5651F48224A885AF00727C9D /* PlayerListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerListViewModel.swift; sourceTree = "<group>"; };
5651F48424A8905100727C9D /* PlayerEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerEditor.swift; sourceTree = "<group>"; };
Expand All @@ -117,7 +123,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5651F47D24A8837800727C9D /* GRDB.framework in Frameworks */,
566148C9251791570083D8B8 /* GRDB.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -158,7 +164,6 @@
563F3E7224A78BD400982CF8 /* SceneDelegate.swift */,
56AAFD4524A78F9A0077EADB /* AppDatabase.swift */,
56AAFD4624A78F9A0077EADB /* Player.swift */,
5651F47E24A884B200727C9D /* World.swift */,
56248FEF24A8F3DD009C144A /* ViewModels */,
56B1B12524A8DA1000D7FB31 /* Views */,
563F3E7824A78BD700982CF8 /* Preview Content */,
Expand Down Expand Up @@ -237,11 +242,11 @@
563F3E6924A78BD400982CF8 /* Sources */,
563F3E6A24A78BD400982CF8 /* Frameworks */,
563F3E6B24A78BD400982CF8 /* Resources */,
566148CB251791570083D8B8 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
5651F47B24A8836B00727C9D /* PBXTargetDependency */,
);
name = GRDBCombineDemo;
productName = GRDBCombineDemo;
Expand All @@ -255,7 +260,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1150;
LastUpgradeCheck = 1150;
LastUpgradeCheck = 1200;
ORGANIZATIONNAME = "Gwendal Roué";
TargetAttributes = {
563F3E6C24A78BD400982CF8 = {
Expand Down Expand Up @@ -365,7 +370,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5651F47F24A884B200727C9D /* World.swift in Sources */,
5651F48324A885AF00727C9D /* PlayerListViewModel.swift in Sources */,
56B1B13024A8E9A700D7FB31 /* PlayerForm.swift in Sources */,
5678066524A8B7DD00606BC6 /* PlayerCreationSheet.swift in Sources */,
Expand All @@ -381,14 +385,6 @@
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
5651F47B24A8836B00727C9D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = GRDBiOS;
targetProxy = 5651F47A24A8836B00727C9D /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
563F3E7B24A78BD700982CF8 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
Expand Down Expand Up @@ -435,6 +431,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -495,6 +492,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -536,7 +534,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemo;
PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemo2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
Expand All @@ -556,7 +554,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemo;
PRODUCT_BUNDLE_IDENTIFIER = com.github.groue.GRDBCombineDemo2;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import GRDB
/// It applies the pratices recommended at
/// https://github.com/groue/GRDB.swift/blob/master/Documentation/GoodPracticesForDesigningRecordTypes.md
final class AppDatabase {
/// The shared AppDatabase
static var shared: AppDatabase!

private let dbQueue: DatabaseQueue

/// Creates an AppDatabase and make sure the database schema is ready.
Expand Down Expand Up @@ -125,19 +128,15 @@ extension AppDatabase {
func playersOrderedByNamePublisher() -> AnyPublisher<[Player], Error> {
ValueObservation
.tracking(Player.all().orderedByName().fetchAll)
// Use the .immediate scheduling so that views do not have to wait
// until the players are loaded.
.publisher(in: dbQueue, scheduling: .immediate)
.publisher(in: dbQueue)
.eraseToAnyPublisher()
}

/// Returns a publisher that tracks changes in players ordered by score
func playersOrderedByScorePublisher() -> AnyPublisher<[Player], Error> {
ValueObservation
.tracking(Player.all().orderedByScore().fetchAll)
// Use the .immediate scheduling so that views do not have to wait
// until the players are loaded.
.publisher(in: dbQueue, scheduling: .immediate)
.publisher(in: dbQueue)
.eraseToAnyPublisher()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
try database.createRandomPlayersIfEmpty()

// Expose it to the rest of the application
Current.database = { database }
AppDatabase.shared = database
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).

// Create the SwiftUI view that provides the window contents.
let viewModel = PlayerListViewModel(database: Current.database())
let viewModel = PlayerListViewModel(database: AppDatabase.shared)
let rootView = PlayerList(viewModel: viewModel)

// Use a UIHostingController as window root view controller.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ final class PlayerListViewModel: ObservableObject {
case byName
}

struct PlayerList {
var players: [Player]
var animatedChanges: Bool
}

/// The list ordering
@Published var ordering: Ordering = .byScore

/// The players in the list
@Published var players: [Player] = []
@Published var playerList = PlayerList(players: [], animatedChanges: false)

/// The view model that edits a new player
let newPlayerViewModel: PlayerFormViewModel
Expand All @@ -24,9 +29,19 @@ final class PlayerListViewModel: ObservableObject {
init(database: AppDatabase) {
self.database = database
newPlayerViewModel = PlayerFormViewModel(database: database, player: .new())
playersCancellable = playersPublisher(in: database).sink { [weak self] players in
self?.players = players
}
playersCancellable = playersPublisher(in: database)
.scan(nil) { (previousList: PlayerList?, players: [Player]) in
if previousList == nil {
// Do not animate first view update
return PlayerList(players: players, animatedChanges: false)
} else {
return PlayerList(players: players, animatedChanges: true)
}
}
.compactMap { $0 }
.sink { [weak self] playerList in
self?.playerList = playerList
}
}

// MARK: - Players List Management
Expand All @@ -39,7 +54,7 @@ final class PlayerListViewModel: ObservableObject {

func deletePlayers(atOffsets offsets: IndexSet) {
// Eventual error presentation is left as an exercise for the reader.
let playerIDs = offsets.compactMap { players[$0].id }
let playerIDs = offsets.compactMap { playerList.players[$0].id }
try! database.deletePlayers(ids: playerIDs)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,3 @@ struct PlayerCreationSheet_Previews: PreviewProvider {
}
}
#endif

Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ struct PlayerEditor: View {

var body: some View {
PlayerForm(viewModel: viewModel)
.onDisappear(perform: {
// Ignore validation errors
try? self.viewModel.savePlayer()
})
.onDisappear(perform: {
// Ignore validation errors
try? self.viewModel.savePlayer()
})
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct PlayerList: View {
playerList
toolbar
}
.navigationBarTitle(Text("\(viewModel.players.count) Players"))
.navigationBarTitle(Text("\(viewModel.playerList.players.count) Players"))
.navigationBarItems(
leading: HStack {
EditButton()
Expand All @@ -26,16 +26,18 @@ struct PlayerList: View {

private var playerList: some View {
List {
ForEach(viewModel.players) { player in
ForEach(viewModel.playerList.players) { player in
NavigationLink(destination: self.editionView(for: player)) {
PlayerRow(player: player)
.animation(nil)
}
}
.onDelete(perform: { offsets in
self.viewModel.deletePlayers(atOffsets: offsets)
})
}
.listStyle(PlainListStyle())
.animation(viewModel.playerList.animatedChanges ? .default : nil)
}

private var toolbar: some View {
Expand All @@ -52,7 +54,7 @@ struct PlayerList: View {
action: viewModel.stressTest,
label: { Image(systemName: "tornado").imageScale(.large) })
}

.padding()
}

Expand Down Expand Up @@ -92,7 +94,7 @@ struct PlayerList: View {
// Make sure we do not edit a previously created player.
self.viewModel.newPlayerViewModel.editNewPlayer()
self.newPlayerIsPresented = true
},
},
label: { Image(systemName: "plus").imageScale(.large) })
.sheet(
isPresented: $newPlayerIsPresented,
Expand All @@ -105,7 +107,7 @@ struct PlayerList: View {
viewModel: self.viewModel.newPlayerViewModel,
dismissAction: {
self.newPlayerIsPresented = false
})
})
}
}

Expand Down
11 changes: 0 additions & 11 deletions Documentation/DemoApps/GRDBCombineDemo/GRDBCombineDemo/World.swift

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
56B0361C1E8D9F38003B6DA4 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B0361A1E8D9F38003B6DA4 /* Player.swift */; };
56B036231E8D9F4C003B6DA4 /* PlayerEditionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B0361F1E8D9F4C003B6DA4 /* PlayerEditionViewController.swift */; };
56B036241E8D9F4C003B6DA4 /* PlayerListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B036201E8D9F4C003B6DA4 /* PlayerListViewController.swift */; };
56FE6F1E24A90CC500711EDF /* World.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56FE6F1D24A90CC500711EDF /* World.swift */; };
56FE6F2624A90CE400711EDF /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56FE6F2524A90CE400711EDF /* SceneDelegate.swift */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -185,7 +184,6 @@
56B0361F1E8D9F4C003B6DA4 /* PlayerEditionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerEditionViewController.swift; sourceTree = "<group>"; };
56B036201E8D9F4C003B6DA4 /* PlayerListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlayerListViewController.swift; sourceTree = "<group>"; };
56B036261E8D9F79003B6DA4 /* GRDB.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = GRDB.xcodeproj; path = ../../../GRDB.xcodeproj; sourceTree = "<group>"; };
56FE6F1D24A90CC500711EDF /* World.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = World.swift; sourceTree = "<group>"; };
56FE6F2524A90CE400711EDF /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -281,7 +279,6 @@
56FE6F2524A90CE400711EDF /* SceneDelegate.swift */,
56B036191E8D9F38003B6DA4 /* AppDatabase.swift */,
56B0361A1E8D9F38003B6DA4 /* Player.swift */,
56FE6F1D24A90CC500711EDF /* World.swift */,
56FE6F4F24A9114200711EDF /* ViewControllers */,
56FE6F4E24A9112900711EDF /* Resources */,
56FE6F5124A9118000711EDF /* Support */,
Expand Down Expand Up @@ -534,7 +531,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
56FE6F1E24A90CC500711EDF /* World.swift in Sources */,
56FE6F2624A90CE400711EDF /* SceneDelegate.swift in Sources */,
56B0361C1E8D9F38003B6DA4 /* Player.swift in Sources */,
56B0361B1E8D9F38003B6DA4 /* AppDatabase.swift in Sources */,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1ea4a44

Please sign in to comment.