add swiftUI code

This commit is contained in:
zeus
2025-01-22 14:09:10 +08:00
parent 68e7b7347c
commit 8a99853829
2531 changed files with 486215 additions and 0 deletions
@@ -0,0 +1,144 @@
//: To run this playground:
//:
//: - Open GRDB.xcworkspace
//: - Select the GRDB scheme: menu Product > Scheme > GRDB
//: - Build: menu Product > Build
//: - Select the playground in the Playgrounds Group
//: - Run the playground
import GRDB
//: Open a database connection
var configuration = Configuration()
configuration.prepareDatabase { db in
db.trace { print("SQL> \($0)") }
}
let dbQueue = try DatabaseQueue(configuration: configuration)
//: Use a migrator to define the database schema
var migrator = DatabaseMigrator()
migrator.registerMigration("createLibrary") { db in
try db.create(table: "author") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
}
try db.create(table: "book") { t in
t.autoIncrementedPrimaryKey("id")
t.column("title", .text).notNull()
t.belongsTo("author", onDelete: .cascade).notNull()
}
}
try migrator.migrate(dbQueue)
//: Define Record types
struct Author: Codable, FetchableRecord, MutablePersistableRecord {
var id: Int64?
var name: String
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
struct Book: Codable, FetchableRecord, MutablePersistableRecord {
var id: Int64?
var authorId: Int64
var title: String
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
//: Define Associations
extension Author {
static let books = hasMany(Book.self)
var books: QueryInterfaceRequest<Book> { request(for: Author.books) }
}
extension Book {
static let author = belongsTo(Author.self)
var author: QueryInterfaceRequest<Author> { request(for: Book.author) }
}
//: Populate the database
print("----------")
print("Populate the database")
try dbQueue.write { db in
var melville = Author(id: nil, name: "Hermann Melville")
try melville.insert(db)
var mobyDick = Book(id: nil, authorId: melville.id!, title: "Moby-Dick")
try mobyDick.insert(db)
var genet = Author(id: nil, name: "Jean Genet")
try genet.insert(db)
var querelle = Book(id: nil, authorId: genet.id!, title: "Querelle de Brest")
try querelle.insert(db)
var lesBonnes = Book(id: nil, authorId: genet.id!, title: "Les Bonnes")
try lesBonnes.insert(db)
}
//: Fetch author information
print("----------")
print("Fetch author information")
struct AuthorInfo {
var author: Author
var books: [Book]
}
let authorId = 2
let authorInfo: AuthorInfo? = try dbQueue.read { db in
guard let author = try Author.fetchOne(db, key: authorId) else { return nil }
let books = try author.books.fetchAll(db)
return AuthorInfo(author: author, books: books)
}
if let authorInfo {
print("\(authorInfo.author.name) has written:")
for book in authorInfo.books {
print("- \(book.title)")
}
}
//: Fetch book information
print("----------")
print("Fetch book information")
struct BookInfo: FetchableRecord, Codable {
var book: Book
var author: Author
}
let bookId = 1
let bookInfo: BookInfo? = try dbQueue.read { db in
let request = Book
.filter(key: bookId)
.including(required: Book.author)
return try BookInfo.fetchOne(db, request)
}
if let bookInfo {
print("\(bookInfo.book.title) was written by \(bookInfo.author.name)")
}
//: Fetch all authorships
print("----------")
print("Fetch all authorships")
struct Authorship: Decodable, FetchableRecord {
var book: Book
var author: Author
}
let authorships: [Authorship] = try dbQueue.read { db in
let request = Book.including(required: Book.author)
return try Authorship.fetchAll(db, request)
}
for authorship in authorships {
print("\(authorship.book.title) was written by \(authorship.author.name)")
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos' buildActiveScheme='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>
@@ -0,0 +1,46 @@
// To run this playground, select and build the GRDB scheme.
import GRDB
var configuration = Configuration()
configuration.prepareDatabase { db in
db.trace { print("SQL> \($0)") }
}
let dbQueue = try DatabaseQueue(configuration: configuration)
struct Player: Codable, FetchableRecord, MutablePersistableRecord {
var id: Int64?
var name: String
var score: Int
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
try dbQueue.write { db in
try db.create(table: "player") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
t.column("score", .integer).notNull()
}
do {
var player = Player(id: nil, name: "Arthur", score: 100)
try player.insert(db)
player = Player(id: nil, name: "Barbara", score: 100)
try player.insert(db)
}
do {
let players = try Player.fetchAll(db)
for player in players {
print(player)
}
}
do {
let count = try Player.fetchCount(db)
print(count)
}
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos' buildActiveScheme='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>
@@ -0,0 +1,136 @@
//: To run this playground:
//:
//: - Open GRDB.xcworkspace
//: - Select the GRDB scheme: menu Product > Scheme > GRDB
//: - Build: menu Product > Build
//: - Select the playground in the Playgrounds Group
//: - Run the playground
//:
//: Tour
//: ======
//:
//: This playground is a quick tour of GRDB.
import GRDB
import CoreLocation
//: Open a connection to the database
// Open an in-memory database that logs all SQL statements
var configuration = Configuration()
configuration.prepareDatabase { db in
db.trace { print("SQL> \($0)") }
}
let dbQueue = try DatabaseQueue(configuration: configuration)
//: Execute SQL queries
try dbQueue.inDatabase { db in
try db.execute(sql: """
CREATE TABLE place (
id INTEGER PRIMARY KEY,
title TEXT,
favorite BOOLEAN NOT NULL,
latitude DOUBLE NOT NULL,
longitude DOUBLE NOT NULL
)
""")
try db.execute(sql: """
INSERT INTO place (title, favorite, latitude, longitude)
VALUES (?, ?, ?, ?)
""", arguments: ["Paris", true, 48.85341, 2.3488])
let parisId = db.lastInsertedRowID
}
//: Fetch database rows and values
try! dbQueue.inDatabase { db in
let rows = try Row.fetchCursor(db, sql: "SELECT * FROM place")
while let row = try rows.next() {
let title: String = row["title"]
let favorite: Bool = row["favorite"]
let coordinate = CLLocationCoordinate2D(
latitude: row["latitude"],
longitude: row["longitude"])
print("Fetched", title, favorite, coordinate)
}
let placeCount = try Int.fetchOne(db, sql: "SELECT COUNT(*) FROM place")! // Int
let placeTitles = try String.fetchAll(db, sql: "SELECT title FROM place") // [String]
}
//: Insert and fetch records
struct Place {
var id: Int64?
var title: String?
var favorite: Bool
var coordinate: CLLocationCoordinate2D
}
// Adopt FetchableRecord
extension Place : FetchableRecord {
init(row: Row) {
id = row["id"]
title = row["title"]
favorite = row["favorite"]
coordinate = CLLocationCoordinate2DMake(
row["latitude"],
row["longitude"])
}
}
// Adopt TableRecord
extension Place : TableRecord {
static let databaseTableName = "place"
}
// Adopt MutablePersistableRecord
extension Place : MutablePersistableRecord {
func encode(to container: inout PersistenceContainer) throws {
container["id"] = id
container["title"] = title
container["favorite"] = favorite
container["latitude"] = coordinate.latitude
container["longitude"] = coordinate.longitude
}
mutating func didInsert(_ inserted: InsertionSuccess) {
id = inserted.rowID
}
}
try dbQueue.inDatabase { db in
var berlin = Place(
id: nil,
title: "Berlin",
favorite: false,
coordinate: CLLocationCoordinate2DMake(52.52437, 13.41053))
try berlin.insert(db)
berlin.id // some value
berlin.favorite = true
try berlin.update(db)
// Fetch from SQL
let places = try Place.fetchAll(db, sql: "SELECT * FROM place") // [Place]
//: Avoid SQL with the query interface:
let title = Column("title")
let favorite = Column("favorite")
berlin = try Place.filter(title == "Berlin").fetchOne(db)! // Place
let paris = try Place.fetchOne(db, key: 1) // Place?
let favoritePlaces = try Place // [Place]
.filter(favorite == true)
.order(title)
.fetchAll(db)
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' display-mode='raw' buildActiveScheme='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>
@@ -0,0 +1,84 @@
//: To run this playground:
//:
//: - Open GRDB.xcworkspace
//: - Select the GRDB scheme: menu Product > Scheme > GRDB
//: - Build: menu Product > Build
//: - Select the playground in the Playgrounds Group
//: - Run the playground
import GRDB
// Create the database
let dbQueue = try DatabaseQueue() // Memory database
var migrator = DatabaseMigrator()
migrator.registerMigration("createPerson") { db in
try db.create(table: "person") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
}
}
migrator.registerMigration("createPet") { db in
try db.create(table: "pet") { t in
t.autoIncrementedPrimaryKey("id")
t.column("name", .text).notNull()
t.belongsTo("owner", inTable: "person", onDelete: .cascade)
}
}
try! migrator.migrate(dbQueue)
//
class TableChangeObserver : NSObject, TransactionObserver {
private var changedTableNames: Set<String> = []
func observes(eventsOfKind eventKind: DatabaseEventKind) -> Bool { true }
func databaseDidChange(with event: DatabaseEvent) {
changedTableNames.insert(event.tableName)
}
func databaseDidCommit(_ db: Database) {
print("Changed table(s): \(changedTableNames.joined(separator: ", "))")
changedTableNames = []
}
func databaseDidRollback(_ db: Database) {
changedTableNames = []
}
}
let observer = TableChangeObserver()
dbQueue.add(transactionObserver: observer)
//
print("-- Changes without transaction")
try dbQueue.inDatabase { db in
try db.execute(sql: "INSERT INTO person (name) VALUES (?)", arguments: ["Arthur"])
let arthurId = db.lastInsertedRowID
try db.execute(sql: "INSERT INTO person (name) VALUES (?)", arguments: ["Barbara"])
try db.execute(sql: "INSERT INTO pet (ownerId, name) VALUES (?, ?)", arguments: [arthurId, "Barbara"])
try db.execute(sql: "DELETE FROM person WHERE id = ?", arguments: [arthurId])
}
print("-- Rollbacked changes")
try dbQueue.inTransaction { db in
try db.execute(sql: "INSERT INTO person (name) VALUES ('Arthur')")
try db.execute(sql: "INSERT INTO person (name) VALUES ('Barbara')")
return .rollback
}
print("-- Changes wrapped in a transaction")
try dbQueue.write { db in
try db.execute(sql: "DELETE FROM person")
try db.execute(sql: "INSERT INTO person (name) VALUES (?)", arguments: ["Arthur"])
let arthurId = db.lastInsertedRowID
try db.execute(sql: "INSERT INTO person (name) VALUES (?)", arguments: ["Barbara"])
try db.execute(sql: "INSERT INTO pet (ownerId, name) VALUES (?, ?)", arguments: [arthurId, "Barbara"])
try db.execute(sql: "DELETE FROM person WHERE id = ?", arguments: [arthurId])
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx' display-mode='rendered' buildActiveScheme='true'>
<timeline fileName='timeline.xctimeline'/>
</playground>