another.im-ios/AnotherIM/AppData/Services/Database.swift

81 lines
2.5 KiB
Swift
Raw Permalink Normal View History

2024-06-19 15:15:27 +00:00
import Combine
import Foundation
import GRDB
import SwiftUI
// MARK: - Models protocol
typealias DBStorable = Codable & FetchableRecord & Identifiable & PersistableRecord & TableRecord
// MARK: - Database init
final class Database {
static let shared = Database()
let dbQueue: DatabaseQueue
2024-10-04 15:58:04 +00:00
private var dbPath: String
2024-06-19 15:15:27 +00:00
private init() {
do {
// Create db folder if not exists
let fileManager = FileManager.default
let appSupportURL = try fileManager.url(
for: .applicationSupportDirectory, in: .userDomainMask,
appropriateFor: nil, create: true
)
2024-10-31 11:55:02 +00:00
let directoryURL = appSupportURL.appendingPathComponent("anotherim", isDirectory: true)
2024-06-19 15:15:27 +00:00
try fileManager.createDirectory(at: directoryURL, withIntermediateDirectories: true)
// Open or create the database
let databaseURL = directoryURL.appendingPathComponent("db.sqlite")
dbQueue = try DatabaseQueue(path: databaseURL.path, configuration: Database.config)
2024-10-04 15:58:04 +00:00
dbPath = databaseURL.path
2024-06-19 15:15:27 +00:00
// Some debug info
#if DEBUG
print("Database path: \(databaseURL.path)")
#endif
// Apply migrations
try Database.migrator.migrate(dbQueue)
2024-06-19 15:15:27 +00:00
} catch {
fatalError("Database initialization failed: \(error)")
}
}
}
// MARK: - Config
private extension Database {
static let config: Configuration = {
var config = Configuration()
#if DEBUG
2024-10-23 15:13:18 +00:00
// verbose and debugging in DEBUG builds only.
config.publicStatementArguments = true
config.prepareDatabase { db in
db.trace { print("SQL> \($0)\n") }
}
2024-06-19 15:15:27 +00:00
#endif
return config
}()
}
2024-10-04 15:58:04 +00:00
// MARK: - flush all data for debug
#if DEBUG
extension Database {
func flushAllData() {
do {
2024-10-07 16:58:02 +00:00
try dbQueue.write { db in
// Fetch all table names
let tables = try String.fetchAll(db, sql: """
SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%';
""")
// Generate and execute DELETE statements for each table
for table in tables {
try db.execute(sql: "DELETE FROM \(table);")
}
}
2024-10-04 15:58:04 +00:00
} catch {
2024-10-07 16:58:02 +00:00
print("Error flushing all data: \(error)")
2024-10-04 15:58:04 +00:00
}
}
}
#endif