@@ -11,10 +11,35 @@ struct User: Codable, Identifiable, FetchableRecord, PersistableRecord {
1111 static var databaseTableName = " users "
1212
1313 enum Columns {
14+ static let id = Column ( CodingKeys . id)
1415 static let name = Column ( CodingKeys . name)
1516 }
1617}
1718
19+ struct Pet : Codable , Identifiable , FetchableRecord , PersistableRecord {
20+ var id : String
21+ var name : String
22+ var ownerId : String
23+
24+ static var databaseTableName = " pets "
25+
26+ enum CodingKeys : String , CodingKey {
27+ case id
28+ case name
29+ case ownerId = " owner_id "
30+ }
31+
32+ enum Columns {
33+ static let ownerId = Column ( CodingKeys . ownerId)
34+ }
35+
36+ static let user = belongsTo (
37+ User . self,
38+ key: " user " ,
39+ using: ForeignKey ( [ Columns . ownerId] , to: [ User . Columns. id] )
40+ )
41+ }
42+
1843final class GRDBTests : XCTestCase {
1944 private var database : PowerSyncDatabaseProtocol !
2045 private var schema : Schema !
@@ -24,7 +49,11 @@ final class GRDBTests: XCTestCase {
2449 try await super. setUp ( )
2550 schema = Schema ( tables: [
2651 Table ( name: " users " , columns: [
52+ . text( " name " )
53+ ] ) ,
54+ Table ( name: " pets " , columns: [
2755 . text( " name " ) ,
56+ . text( " owner_id " )
2857 ] )
2958 ] )
3059
@@ -99,6 +128,43 @@ final class GRDBTests: XCTestCase {
99128 XCTAssert ( grdbUserNames2 [ 1 ] . name == " another " )
100129 }
101130
131+ func testJoins( ) async throws {
132+ // Create users with the PowerSync SDK
133+ try await pool. write { database in
134+ let userId = UUID ( ) . uuidString
135+ try User (
136+ id: userId,
137+ name: " Bob "
138+ ) . insert ( database)
139+
140+ try Pet (
141+ id: UUID ( ) . uuidString,
142+ name: " Fido " ,
143+ ownerId: userId
144+ ) . insert ( database)
145+ }
146+
147+ struct PetWithUser : Decodable , FetchableRecord {
148+ struct PartialUser : Decodable {
149+ var name : String
150+ }
151+
152+ var pet : Pet // The base record
153+ var user : PartialUser // The partial associated record
154+ }
155+
156+ let petsWithUsers = try await pool. read { db in
157+ try Pet
158+ . including ( required: Pet . user)
159+ . asRequest ( of: PetWithUser . self)
160+ . fetchAll ( db)
161+ }
162+
163+ XCTAssert ( petsWithUsers. count == 1 )
164+ XCTAssert ( petsWithUsers [ 0 ] . pet. name == " Fido " )
165+ XCTAssert ( petsWithUsers [ 0 ] . user. name == " Bob " )
166+ }
167+
102168 func testPowerSyncUpdates( ) async throws {
103169 let expectation = XCTestExpectation ( description: " Watch changes " )
104170
0 commit comments