119 lines
4.0 KiB
Swift
119 lines
4.0 KiB
Swift
import XCTest
|
|
import GRDB
|
|
|
|
final class JSONColumnTests: GRDBTestCase {
|
|
func test_JSONColumn_derived_from_CodingKey() throws {
|
|
#if GRDBCUSTOMSQLITE || GRDBCIPHER
|
|
// Prevent SQLCipher failures
|
|
guard sqlite3_libversion_number() >= 3038000 else {
|
|
throw XCTSkip("JSON support is not available")
|
|
}
|
|
#else
|
|
guard #available(iOS 16, macOS 10.15, tvOS 17, watchOS 9, *) else {
|
|
throw XCTSkip("JSON support is not available")
|
|
}
|
|
#endif
|
|
|
|
struct Player: Codable, TableRecord, FetchableRecord, PersistableRecord {
|
|
var id: Int64
|
|
var info: Data
|
|
|
|
enum CodingKeys: String, CodingKey {
|
|
case id
|
|
case info = "info_json"
|
|
}
|
|
|
|
enum Columns {
|
|
static let id = Column(CodingKeys.id)
|
|
static let info = JSONColumn(CodingKeys.info)
|
|
}
|
|
|
|
static let databaseSelection: [any SQLSelectable] = [Columns.id, Columns.info]
|
|
}
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "player") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.column("info_json", .jsonText)
|
|
}
|
|
|
|
try assertEqualSQL(db, Player.all(), """
|
|
SELECT "id", "info_json" FROM "player"
|
|
""")
|
|
}
|
|
}
|
|
|
|
func test_JSON_EXTRACT() throws {
|
|
#if GRDBCUSTOMSQLITE || GRDBCIPHER
|
|
// Prevent SQLCipher failures
|
|
guard sqlite3_libversion_number() >= 3038000 else {
|
|
throw XCTSkip("JSON_EXTRACT is not available")
|
|
}
|
|
#else
|
|
guard #available(iOS 16, macOS 10.15, tvOS 17, watchOS 9, *) else {
|
|
throw XCTSkip("JSON_EXTRACT is not available")
|
|
}
|
|
#endif
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "player") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.column("info", .jsonText)
|
|
}
|
|
|
|
let player = Table("player")
|
|
let info = JSONColumn("info")
|
|
|
|
try assertEqualSQL(db, player.select(info.jsonExtract(atPath: "$.score")), """
|
|
SELECT JSON_EXTRACT("info", '$.score') FROM "player"
|
|
""")
|
|
|
|
try assertEqualSQL(db, player.select(info.jsonExtract(atPaths: ["$.score", "$.bonus"])), """
|
|
SELECT JSON_EXTRACT("info", '$.score', '$.bonus') FROM "player"
|
|
""")
|
|
}
|
|
}
|
|
|
|
func test_extraction_operators() throws {
|
|
#if GRDBCUSTOMSQLITE || GRDBCIPHER
|
|
// Prevent SQLCipher failures
|
|
guard sqlite3_libversion_number() >= 3038000 else {
|
|
throw XCTSkip("JSON operators are not available")
|
|
}
|
|
#else
|
|
guard #available(iOS 16, macOS 13.2, tvOS 17, watchOS 9, *) else {
|
|
throw XCTSkip("JSON operators are not available")
|
|
}
|
|
#endif
|
|
|
|
let dbQueue = try makeDatabaseQueue()
|
|
try dbQueue.inDatabase { db in
|
|
try db.create(table: "player") { t in
|
|
t.autoIncrementedPrimaryKey("id")
|
|
t.column("info", .jsonText)
|
|
}
|
|
|
|
let player = Table("player")
|
|
let info = JSONColumn("info")
|
|
|
|
try assertEqualSQL(db, player.select(info["score"]), """
|
|
SELECT "info" ->> 'score' FROM "player"
|
|
""")
|
|
|
|
try assertEqualSQL(db, player.select(info["$.score"]), """
|
|
SELECT "info" ->> '$.score' FROM "player"
|
|
""")
|
|
|
|
try assertEqualSQL(db, player.select(info.jsonRepresentation(atPath: "score")), """
|
|
SELECT "info" -> 'score' FROM "player"
|
|
""")
|
|
|
|
try assertEqualSQL(db, player.select(info.jsonRepresentation(atPath: "$.score")), """
|
|
SELECT "info" -> '$.score' FROM "player"
|
|
""")
|
|
}
|
|
}
|
|
}
|