From e27902c8a4ea85157679b593b717d6753c9106b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Menu?= Date: Tue, 7 Jan 2025 17:06:08 +0100 Subject: [PATCH] Don't crash the app if the LCP database cannot be opened --- Sources/Adapters/LCPSQLite/Database.swift | 28 ++++++++++--------- .../SQLiteLCPLicenseRepository.swift | 8 +++--- .../SQLiteLCPPassphraseRepository.swift | 20 ++++++------- TestApp/Sources/App/Readium.swift | 4 +-- 4 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Sources/Adapters/LCPSQLite/Database.swift b/Sources/Adapters/LCPSQLite/Database.swift index b679c0b3d..7d33f1417 100644 --- a/Sources/Adapters/LCPSQLite/Database.swift +++ b/Sources/Adapters/LCPSQLite/Database.swift @@ -9,22 +9,24 @@ import SQLite final class Database { /// Shared instance. - static let shared = Database() - - let connection: Connection - - private init() { + static let shared: Swift.Result = { do { - var url = try FileManager.default.url( - for: .libraryDirectory, - in: .userDomainMask, - appropriateFor: nil, create: true - ) - url.appendPathComponent("lcpdatabase.sqlite") - connection = try Connection(url.absoluteString) + return try .success(Database()) } catch { - fatalError("Error initializing db.") + return .failure(error) } + }() + + let connection: Connection + + private init() throws { + var url = try FileManager.default.url( + for: .libraryDirectory, + in: .userDomainMask, + appropriateFor: nil, create: true + ) + url.appendPathComponent("lcpdatabase.sqlite") + connection = try Connection(url.absoluteString) } } diff --git a/Sources/Adapters/LCPSQLite/SQLiteLCPLicenseRepository.swift b/Sources/Adapters/LCPSQLite/SQLiteLCPLicenseRepository.swift index 4db815e46..a08536768 100644 --- a/Sources/Adapters/LCPSQLite/SQLiteLCPLicenseRepository.swift +++ b/Sources/Adapters/LCPSQLite/SQLiteLCPLicenseRepository.swift @@ -17,17 +17,17 @@ public class LCPSQLiteLicenseRepository: LCPLicenseRepository { private let db: Connection - public init() { - db = Database.shared.connection + public init() throws { + db = try Database.shared.get().connection - _ = try? db.run(licenses.create(temporary: false, ifNotExists: true) { t in + try db.run(licenses.create(temporary: false, ifNotExists: true) { t in t.column(id, unique: true) t.column(printsLeft) t.column(copiesLeft) }) if db.userVersion == 0 { - _ = try? db.run(licenses.addColumn(registered, defaultValue: false)) + try db.run(licenses.addColumn(registered, defaultValue: false)) db.userVersion = 1 } if db.userVersion == 1 { diff --git a/Sources/Adapters/LCPSQLite/SQLiteLCPPassphraseRepository.swift b/Sources/Adapters/LCPSQLite/SQLiteLCPPassphraseRepository.swift index 856539688..7728bd20e 100644 --- a/Sources/Adapters/LCPSQLite/SQLiteLCPPassphraseRepository.swift +++ b/Sources/Adapters/LCPSQLite/SQLiteLCPPassphraseRepository.swift @@ -18,19 +18,15 @@ public class LCPSQLitePassphraseRepository: LCPPassphraseRepository, Loggable { private let db: Connection - public init() { - db = Database.shared.connection + public init() throws { + db = try Database.shared.get().connection - do { - try db.run(transactions.create(temporary: false, ifNotExists: true) { t in - t.column(licenseId) - t.column(provider) - t.column(userId) - t.column(passphrase) - }) - } catch { - log(.error, error) - } + try db.run(transactions.create(temporary: false, ifNotExists: true) { t in + t.column(licenseId) + t.column(provider) + t.column(userId) + t.column(passphrase) + }) } public func passphrase(for licenseID: LicenseDocument.ID) async throws -> LCPPassphraseHash? { diff --git a/TestApp/Sources/App/Readium.swift b/TestApp/Sources/App/Readium.swift index 05c546ace..2565a76a3 100644 --- a/TestApp/Sources/App/Readium.swift +++ b/TestApp/Sources/App/Readium.swift @@ -45,8 +45,8 @@ final class Readium { lazy var lcpService = LCPService( client: LCPClient(), - licenseRepository: LCPSQLiteLicenseRepository(), - passphraseRepository: LCPSQLitePassphraseRepository(), + licenseRepository: try! LCPSQLiteLicenseRepository(), + passphraseRepository: try! LCPSQLitePassphraseRepository(), assetRetriever: assetRetriever, httpClient: httpClient )