Skip to content

Commit

Permalink
Merge pull request #955 from steipete/peter/query-base
Browse files Browse the repository at this point in the history
Ensure Query can be updated
  • Loading branch information
groue authored Apr 10, 2021
2 parents e017edd + c34615c commit 28bddb0
Show file tree
Hide file tree
Showing 9 changed files with 287 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
567C3E792520BB650011F6E9 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E752520BB650011F6E9 /* Localizable.stringsdict */; };
567C3E7A2520BB650011F6E9 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 567C3E772520BB650011F6E9 /* LaunchScreen.storyboard */; };
56B6D1092619EC1B003CC455 /* PlayerRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B6D1082619EC1B003CC455 /* PlayerRequest.swift */; };
78E2F9E6261EEC22005D1F7F /* GRDBCombineDemoUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E2F9E5261EEC22005D1F7F /* GRDBCombineDemoUITests.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -100,6 +101,13 @@
remoteGlobalIDString = 56E5D7C91B4D3FED00430942;
remoteInfo = GRDBiOS;
};
78E2F9E8261EEC22005D1F7F /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 567C3E0E2520B6DE0011F6E9 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 567C3E152520B6DE0011F6E9;
remoteInfo = GRDBCombineDemo;
};
/* End PBXContainerItemProxy section */

/* Begin PBXCopyFilesBuildPhase section */
Expand Down Expand Up @@ -140,6 +148,9 @@
567C3E762520BB650011F6E9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
567C3E782520BB650011F6E9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
56B6D1082619EC1B003CC455 /* PlayerRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerRequest.swift; sourceTree = "<group>"; };
78E2F9E3261EEC22005D1F7F /* GRDBCombineDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GRDBCombineDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
78E2F9E5261EEC22005D1F7F /* GRDBCombineDemoUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRDBCombineDemoUITests.swift; sourceTree = "<group>"; };
78E2F9E7261EEC22005D1F7F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -158,6 +169,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
78E2F9E0261EEC22005D1F7F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
Expand Down Expand Up @@ -196,6 +214,7 @@
567C3E292520B7000011F6E9 /* GRDB.xcodeproj */,
567C3E182520B6DE0011F6E9 /* GRDBCombineDemo */,
56026C9925B8A7D000D1DF3F /* GRDBCombineDemoTests */,
78E2F9E4261EEC22005D1F7F /* GRDBCombineDemoUITests */,
567C3E172520B6DE0011F6E9 /* Products */,
567C3E4D2520B70E0011F6E9 /* Frameworks */,
);
Expand All @@ -206,6 +225,7 @@
children = (
567C3E162520B6DE0011F6E9 /* GRDBCombineDemo.app */,
56026C9825B8A7D000D1DF3F /* GRDBCombineDemoTests.xctest */,
78E2F9E3261EEC22005D1F7F /* GRDBCombineDemoUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
Expand Down Expand Up @@ -269,6 +289,15 @@
path = Views;
sourceTree = "<group>";
};
78E2F9E4261EEC22005D1F7F /* GRDBCombineDemoUITests */ = {
isa = PBXGroup;
children = (
78E2F9E5261EEC22005D1F7F /* GRDBCombineDemoUITests.swift */,
78E2F9E7261EEC22005D1F7F /* Info.plist */,
);
path = GRDBCombineDemoUITests;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -309,13 +338,31 @@
productReference = 567C3E162520B6DE0011F6E9 /* GRDBCombineDemo.app */;
productType = "com.apple.product-type.application";
};
78E2F9E2261EEC22005D1F7F /* GRDBCombineDemoUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 78E2F9F3261EEC22005D1F7F /* Build configuration list for PBXNativeTarget "GRDBCombineDemoUITests" */;
buildPhases = (
78E2F9DF261EEC22005D1F7F /* Sources */,
78E2F9E0261EEC22005D1F7F /* Frameworks */,
78E2F9E1261EEC22005D1F7F /* Resources */,
);
buildRules = (
);
dependencies = (
78E2F9E9261EEC22005D1F7F /* PBXTargetDependency */,
);
name = GRDBCombineDemoUITests;
productName = GRDBCombineDemoUITests;
productReference = 78E2F9E3261EEC22005D1F7F /* GRDBCombineDemoUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
567C3E0E2520B6DE0011F6E9 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 1230;
LastSwiftUpdateCheck = 1250;
LastUpgradeCheck = 1200;
TargetAttributes = {
56026C9725B8A7D000D1DF3F = {
Expand All @@ -325,6 +372,10 @@
567C3E152520B6DE0011F6E9 = {
CreatedOnToolsVersion = 12.0;
};
78E2F9E2261EEC22005D1F7F = {
CreatedOnToolsVersion = 12.5;
TestTargetID = 567C3E152520B6DE0011F6E9;
};
};
};
buildConfigurationList = 567C3E112520B6DE0011F6E9 /* Build configuration list for PBXProject "GRDBCombineDemo" */;
Expand All @@ -348,6 +399,7 @@
targets = (
567C3E152520B6DE0011F6E9 /* GRDBCombineDemo */,
56026C9725B8A7D000D1DF3F /* GRDBCombineDemoTests */,
78E2F9E2261EEC22005D1F7F /* GRDBCombineDemoUITests */,
);
};
/* End PBXProject section */
Expand Down Expand Up @@ -430,6 +482,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
78E2F9E1261EEC22005D1F7F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
Expand Down Expand Up @@ -461,6 +520,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
78E2F9DF261EEC22005D1F7F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
78E2F9E6261EEC22005D1F7F /* GRDBCombineDemoUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
Expand All @@ -474,6 +541,11 @@
name = GRDBiOS;
targetProxy = 567C3E512520B71C0011F6E9 /* PBXContainerItemProxy */;
};
78E2F9E9261EEC22005D1F7F /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 567C3E152520B6DE0011F6E9 /* GRDBCombineDemo */;
targetProxy = 78E2F9E8261EEC22005D1F7F /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin PBXVariantGroup section */
Expand Down Expand Up @@ -659,7 +731,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"GRDBCombineDemo/Preview Content\"";
DEVELOPMENT_TEAM = AMD8W895CT;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = GRDBCombineDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
Expand All @@ -681,7 +753,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_ASSET_PATHS = "\"GRDBCombineDemo/Preview Content\"";
DEVELOPMENT_TEAM = AMD8W895CT;
DEVELOPMENT_TEAM = "";
ENABLE_PREVIEWS = YES;
INFOPLIST_FILE = GRDBCombineDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
Expand All @@ -696,6 +768,44 @@
};
name = Release;
};
78E2F9EA261EEC22005D1F7F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = GRDBCombineDemoUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.groue.GRDBCombineDemoUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = GRDBCombineDemo;
};
name = Debug;
};
78E2F9EB261EEC22005D1F7F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = GRDBCombineDemoUITests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.groue.GRDBCombineDemoUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = GRDBCombineDemo;
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
Expand Down Expand Up @@ -726,6 +836,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
78E2F9F3261EEC22005D1F7F /* Build configuration list for PBXNativeTarget "GRDBCombineDemoUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
78E2F9EA261EEC22005D1F7F /* Debug */,
78E2F9EB261EEC22005D1F7F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 567C3E0E2520B6DE0011F6E9 /* Project object */;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@
ReferencedContainer = "container:GRDBCombineDemo.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "78E2F9E2261EEC22005D1F7F"
BuildableName = "GRDBCombineDemoUITests.xctest"
BlueprintName = "GRDBCombineDemoUITests"
ReferencedContainer = "container:GRDBCombineDemo.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,25 @@ extension AppDatabase {
}
}
}

static let uiTestPlayers = [
Player(id: nil, name: "Arthur", score: 5),
Player(id: nil, name: "Barbara", score: 6),
Player(id: nil, name: "Craig", score: 8),
Player(id: nil, name: "David", score: 4),
Player(id: nil, name: "Elena", score: 1),
Player(id: nil, name: "Frederik", score: 2),
Player(id: nil, name: "Gilbert", score: 7),
Player(id: nil, name: "Henriette", score: 3)]

func createPlayersForUITests() throws {
try dbWriter.write { db in
try AppDatabase.uiTestPlayers.forEach { player in
var mutablePlayer = player
try mutablePlayer.save(db)
}
}
}

/// Support for `createRandomPlayersIfEmpty()` and `refreshPlayers()`.
private func createRandomPlayers(_ db: Database) throws {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ extension AppDatabase {

private static func makeShared() -> AppDatabase {
do {
// Create a folder for storing the SQLite database, as well as
// Pick a folder for storing the SQLite database, as well as
// the various temporary files created during normal database
// operations (https://sqlite.org/tempfiles.html).
let fileManager = FileManager()
let folderURL = try fileManager
.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("database", isDirectory: true)

// Support for tests: delete the database if requested
if CommandLine.arguments.contains("-reset") {
try? fileManager.removeItem(at: folderURL)
}

// Create the database folder if needed
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true)

// Connect to a database on disk
Expand All @@ -23,8 +30,14 @@ extension AppDatabase {
// Create the AppDatabase
let appDatabase = try AppDatabase(dbPool)

// Populate the database if it is empty, for better demo purpose.
try appDatabase.createRandomPlayersIfEmpty()
// Prepare the database with test fixtures if requested
if CommandLine.arguments.contains("-fixedTestData") {
try appDatabase.createPlayersForUITests()
} else {
// Otherwise, populate the database if it is empty, for better
// demo purpose.
try appDatabase.createRandomPlayersIfEmpty()
}

return appDatabase
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ struct Query<Query: Queryable>: DynamicProperty {
var projectedValue: Binding<Query> {
Binding(
get: { core.query ?? baseQuery },
set: { core.query = $0 })
set: {
core.usesBaseQuery = false
core.query = $0
})
}

init(_ query: Query) {
Expand All @@ -52,13 +55,14 @@ struct Query<Query: Queryable>: DynamicProperty {
fatalError("Attempting to use @Query without any database in the environment")
}
// Feed core with necessary information, and make sure tracking has started
if core.query == nil { core.query = baseQuery }
if core.usesBaseQuery { core.query = baseQuery }
core.startTrackingIfNecessary(in: databaseReader)
}

private class Core: ObservableObject {
private(set) var value: Query.Value?
var databaseReader: DatabaseReader?
var usesBaseQuery = true
var query: Query? {
willSet {
if query != newValue {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ struct AppView: View {

/// Tracks the presentation of the player creation sheet.
@State private var newPlayerIsPresented = false

// If you want to define the query on initialization, you will prefer:
//
// @Query<PlayerRequest> private var players: [Player]
//
// init(initialOrdering: PlayerRequest.Ordering) {
// _players = Query(PlayerRequest(ordering: initialOrdering))
// }

var body: some View {
NavigationView {
Expand Down Expand Up @@ -42,6 +50,7 @@ struct AppView: View {
Button(
action: { newPlayerIsPresented = true },
label: { Image(systemName: "plus") })
.accessibility(label: Text("New Player"))
.sheet(
isPresented: $newPlayerIsPresented,
content: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ struct PlayerFormView: View {
var body: some View {
List {
TextField("Name", text: $name)
.accessibility(label: Text("Player Name"))
TextField("Score", text: $score).keyboardType(.numberPad)
.accessibility(label: Text("Player Score"))
}
.listStyle(InsetGroupedListStyle())
}
Expand Down
Loading

0 comments on commit 28bddb0

Please sign in to comment.