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:
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")!