damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit a07b78e47f090a059e2c3a9d425f9732e8d95b12
parent 4e447ddbed72e24a283c2a19d578bfb8eca2fd18
Author: William Casarin <jb55@jb55.com>
Date:   Mon,  4 Dec 2023 12:42:45 -0800

ndb: add safemode so we don't instantly crash on bad dbs

Fixes: https://github.com/damus-io/damus/issues/1741

Diffstat:
Mdamus/ContentView.swift | 15++++++++++++++-
Mdamus/TestData.swift | 2+-
Mdamus/Views/SaveKeysView.swift | 2+-
MdamusTests/ProfileViewTests.swift | 2+-
Mnostrdb/Ndb.swift | 27+++++++++++++++++++++------
Mnostrdb/Test/NdbTests.swift | 8++++----
6 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/damus/ContentView.swift b/damus/ContentView.swift @@ -602,7 +602,20 @@ struct ContentView: View { func connect() { // nostrdb - let ndb = try! Ndb()! + var mndb = Ndb() + if mndb == nil { + // try recovery + print("DB ISSUE! RECOVERING") + mndb = Ndb.safemode() + + // out of space or something?? maybe we need a in-memory fallback + if mndb == nil { + notify(.logout) + return + } + } + + guard let ndb = mndb else { return } let pool = RelayPool(ndb: ndb) let model_cache = RelayModelCache() diff --git a/damus/TestData.swift b/damus/TestData.swift @@ -64,7 +64,7 @@ var test_damus_state: DamusState = ({ } print("opening \(tempDir!)") - let ndb = try! Ndb(path: tempDir)! + let ndb = Ndb(path: tempDir)! let our_pubkey = test_pubkey let pool = RelayPool(ndb: ndb) let settings = UserSettingsStore() diff --git a/damus/Views/SaveKeysView.swift b/damus/Views/SaveKeysView.swift @@ -10,7 +10,7 @@ import Security struct SaveKeysView: View { let account: CreateAccountModel - let pool: RelayPool = RelayPool(ndb: try! Ndb()!) + let pool: RelayPool = RelayPool(ndb: Ndb()!) @State var pub_copied: Bool = false @State var priv_copied: Bool = false @State var loading: Bool = false diff --git a/damusTests/ProfileViewTests.swift b/damusTests/ProfileViewTests.swift @@ -27,7 +27,7 @@ final class ProfileViewTests: XCTestCase { let pk4 = Pubkey(hex: "cc590e46363d0fa66bb27081368d01f169b8ffc7c614629d4e9eef6c88b38670")! let pk5 = Pubkey(hex: "f2aa579bb998627e04a8f553842a09446360c9d708c6141dd119c479f6ab9d29")! - let ndb = try! Ndb(path: Ndb.db_path)! + let ndb = Ndb(path: Ndb.db_path)! let txn = NdbTxn(ndb: ndb) let damus_name = "17ldvg64:nq5mhr77" diff --git a/nostrdb/Ndb.swift b/nostrdb/Ndb.swift @@ -17,8 +17,25 @@ enum NdbSearchOrder { class Ndb { let ndb: ndb_t - let owns_db_file: Bool // Determines whether this class should be allowed to create or move the db file. - + + static func safemode() -> Ndb? { + guard let path = db_path ?? old_db_path else { return nil } + + // delete the database and start fresh + if Self.db_files_exist(path: path) { + let file_manager = FileManager.default + for db_file in db_files { + try? file_manager.removeItem(atPath: "\(path)/\(db_file)") + } + } + + guard let ndb = Ndb(path: path) else { + return nil + } + + return ndb + } + // NostrDB used to be stored on the app container's document directory static private var old_db_path: String? { guard let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.absoluteString else { @@ -42,7 +59,7 @@ class Ndb { Ndb(ndb: ndb_t(ndb: nil)) } - init?(path: String? = nil, owns_db_file: Bool = true) throws { + init?(path: String? = nil, owns_db_file: Bool = true) { var ndb_p: OpaquePointer? = nil let ingest_threads: Int32 = 4 @@ -66,7 +83,7 @@ class Ndb { } guard let path = path.map(remove_file_prefix) ?? Ndb.db_path else { - throw Errors.cannot_find_db_path + return nil } let ok = path.withCString { testdir in @@ -85,7 +102,6 @@ class Ndb { return nil } - self.owns_db_file = owns_db_file self.ndb = ndb_t(ndb: ndb_p) } @@ -127,7 +143,6 @@ class Ndb { } init(ndb: ndb_t) { - self.owns_db_file = true self.ndb = ndb } diff --git a/nostrdb/Test/NdbTests.swift b/nostrdb/Test/NdbTests.swift @@ -55,13 +55,13 @@ final class NdbTests: XCTestCase { func test_ndb_init() { do { - let ndb = try! Ndb(path: db_dir)! + let ndb = Ndb(path: db_dir)! let ok = ndb.process_events(test_wire_events) XCTAssertTrue(ok) } do { - let ndb = try! Ndb(path: db_dir)! + let ndb = Ndb(path: db_dir)! let id = NoteId(hex: "d12c17bde3094ad32f4ab862a6cc6f5c289cfe7d5802270bdf34904df585f349")! let txn = NdbTxn(ndb: ndb) let note = ndb.lookup_note_with_txn(id: id, txn: txn) @@ -83,13 +83,13 @@ final class NdbTests: XCTestCase { func test_ndb_seach() throws { do { - let ndb = try! Ndb(path: db_dir)! + let ndb = Ndb(path: db_dir)! let ok = ndb.process_events(test_wire_events) XCTAssertTrue(ok) } do { - let ndb = try! Ndb(path: db_dir)! + let ndb = Ndb(path: db_dir)! let note_ids = ndb.text_search(query: "barked") XCTAssertEqual(note_ids.count, 1) let expected_note_id = NoteId(hex: "b17a540710fe8495b16bfbaf31c6962c4ba8387f3284a7973ad523988095417e")!