添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
活泼的泡面  ·  How should I handle ...·  1 周前    · 
满身肌肉的冲锋衣  ·  Query Language - ...·  1 周前    · 
豪气的荔枝  ·  Hibernate Community • ...·  1 周前    · 
想出家的萝卜  ·  Spring WebFlux ...·  47 分钟前    · 
卖萌的青椒  ·  artifactory - ...·  1 年前    · 
任性的盒饭  ·  python - How to ...·  1 年前    · 
会开车的烈马  ·  正则删除空行-掘金·  2 年前    · 

Hi all
~2 years experienced dev, new to Swift and GRDB

I am trying to setup a GRDB stack onto my app
My app is a dictionnary that will rely on a static database (basically all the words and translations) that will weigh ~200MB

I tried to follow the best practices as shown in the Demo Apps, and I ended up with an AppDatabase class that I call at the launch of my app and that handles the initialization of my database (run migrations + populates it). But it seems to me that it always run the migrations + the populateDb function at the launch of the app. This is not what I expect as it will take a lot of time for my app to open everytime...
I guess I could also preload an already existing database, but I am not sure...

Would I still be able to rely on the GRDB associationRelationships like hasMany, belongsTo like in my examples below ?
Could you give me the best practice to handle such matter ?

Here are my files that I simplified for this example, my database schema is way bigger and complex than that:

// Migration_01_CreateTables.swift // GRDBPlayground // Created by Léos on 28/07/2024. import GRDB struct Migration_01_CreateTables { static func performMigration ( migrator : inout DatabaseMigrator ) { migrator . registerMigration ( " CreateTables " ) { db in // Create wordboxes table try db . create ( table : " wordboxes " ) { t in t . autoIncrementedPrimaryKey ( " id " ) t . column ( " name " , . text ) . notNull ( ) // Create translations table try db . create ( table : " translations " ) { t in t . autoIncrementedPrimaryKey ( " id " ) t . column ( " wordboxID " , . integer ) . notNull ( ) . references ( " wordboxes " ) t . column ( " text " , . text ) . notNull ( ) // models.swift // GRDBPlayground // Created by Léos on 27/07/2024. import Foundation import GRDB enum Language : String { case english = " en " case french = " fr " struct Translation : Codable { var id : Int64 ? var wordboxID : Int64 ? var text : String extension Translation : FetchableRecord , MutablePersistableRecord { static var databaseTableName : String { return " translations " enum Columns : String , ColumnExpression { case id , wordboxID , text static let wordbox = belongsTo ( WordBox . self ) var wordbox : QueryInterfaceRequest < WordBox > { return request ( for : Translation . wordbox ) mutating func didInsert ( with rowID : Int64 , for column : String ? ) { id = rowID struct WordBox : Codable { var id : Int64 ? var name : String extension WordBox : FetchableRecord , MutablePersistableRecord { static var databaseTableName : String { return " wordboxes " enum Columns : String , ColumnExpression { case id , name static let translations = hasMany ( Translation . self ) var translations : QueryInterfaceRequest < Translation > { return request ( for : WordBox . translations ) mutating func didInsert ( with rowID : Int64 , for column : String ? ) { id = rowID // AppDatabase.swift // GRDBPlayground // Created by Léos on 27/07/2024. import Foundation import GRDB import os . log struct AppDatabase { private let dbWriter : any DatabaseWriter init ( _ dbWriter : any DatabaseWriter ) throws { self . dbWriter = dbWriter try migrator . migrate ( dbWriter ) private static let sqlLogger = OSLog ( subsystem : Bundle . main . bundleIdentifier! , category : " SQL " ) public static func makeConfiguration ( _ base : Configuration = Configuration ( ) ) -> Configuration { var config = base if ProcessInfo . processInfo . environment [ " SQL_TRACE " ] != nil { config . prepareDatabase { db in db . trace { os_log ( " %{public}@ " , log : sqlLogger , type : . debug , String ( describing : $0 ) ) #if DEBUG config . publicStatementArguments = true #endif return config private var migrator : DatabaseMigrator { var migrator = DatabaseMigrator ( ) #if DEBUG migrator . eraseDatabaseOnSchemaChange = true #endif // Register migrations Migration_01_CreateTables . performMigration ( migrator : & migrator ) return migrator extension AppDatabase { static let shared = makeShared ( ) private static func makeShared ( ) -> AppDatabase { do { let fileManager = FileManager . default let appSupportURL = try fileManager . url ( for : . applicationSupportDirectory , in : . userDomainMask , appropriateFor : nil , create : true ) let directoryURL = appSupportURL . appendingPathComponent ( " Database " , isDirectory : true ) try fileManager . createDirectory ( at : directoryURL , withIntermediateDirectories : true ) let databaseURL = directoryURL . appendingPathComponent ( " db.sqlite " ) NSLog ( " Database stored at \( databaseURL . path ) " ) let dbPool = try DatabasePool ( path : databaseURL . path , configuration : AppDatabase . makeConfiguration ( ) let appDatabase = try AppDatabase ( dbPool ) // Populate the database if it is empty // try appDatabase.populate() return appDatabase } catch { fatalError ( " Unresolved error \( error ) " ) extension AppDatabase { var reader : DatabaseReader { dbWriter // GRDBPlaygroundApp.swift // GRDBPlayground // Created by Léos on 27/07/2024. import SwiftUI @ main struct GRDBPlaygroundApp : App { init ( ) { // Initialize the shared database instance _ = AppDatabase . shared var body : some Scene { WindowGroup { ContentView ( ) . environment ( \ . appDatabase , AppDatabase . shared ) struct AppDatabaseKey : EnvironmentKey { static let defaultValue : AppDatabase = AppDatabase . shared extension EnvironmentValues { var appDatabase : AppDatabase { get { self [ AppDatabaseKey . self ] } set { self [ AppDatabaseKey . self ] = newValue }