| 1295 | } |
| 1296 | |
| 1297 | std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error) |
| 1298 | { |
| 1299 | bool exists; |
| 1300 | try { |
| 1301 | exists = fs::symlink_status(path).type() != fs::file_type::not_found; |
| 1302 | } catch (const fs::filesystem_error& e) { |
| 1303 | error = Untranslated(strprintf("Failed to access database path '%s': %s", fs::PathToString(path), e.code().message())); |
| 1304 | status = DatabaseStatus::FAILED_BAD_PATH; |
| 1305 | return nullptr; |
| 1306 | } |
| 1307 | |
| 1308 | std::optional<DatabaseFormat> format; |
| 1309 | if (exists) { |
| 1310 | if (IsBDBFile(BDBDataFile(path))) { |
| 1311 | format = DatabaseFormat::BERKELEY_RO; |
| 1312 | } |
| 1313 | if (IsSQLiteFile(SQLiteDataFile(path))) { |
| 1314 | if (format) { |
| 1315 | error = Untranslated(strprintf("Failed to load database path '%s'. Data is in ambiguous format.", fs::PathToString(path))); |
| 1316 | status = DatabaseStatus::FAILED_BAD_FORMAT; |
| 1317 | return nullptr; |
| 1318 | } |
| 1319 | format = DatabaseFormat::SQLITE; |
| 1320 | } |
| 1321 | } else if (options.require_existing) { |
| 1322 | error = Untranslated(strprintf("Failed to load database path '%s'. Path does not exist.", fs::PathToString(path))); |
| 1323 | status = DatabaseStatus::FAILED_NOT_FOUND; |
| 1324 | return nullptr; |
| 1325 | } |
| 1326 | |
| 1327 | if (!format && options.require_existing) { |
| 1328 | error = Untranslated(strprintf("Failed to load database path '%s'. Data is not in recognized format.", fs::PathToString(path))); |
| 1329 | status = DatabaseStatus::FAILED_BAD_FORMAT; |
| 1330 | return nullptr; |
| 1331 | } |
| 1332 | |
| 1333 | if (format && options.require_create) { |
| 1334 | error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", fs::PathToString(path))); |
| 1335 | status = DatabaseStatus::FAILED_ALREADY_EXISTS; |
| 1336 | return nullptr; |
| 1337 | } |
| 1338 | |
| 1339 | // BERKELEY_RO can only be opened if require_format was set, which only occurs in migration. |
| 1340 | if (format && format == DatabaseFormat::BERKELEY_RO && (!options.require_format || options.require_format != DatabaseFormat::BERKELEY_RO)) { |
| 1341 | error = Untranslated(strprintf("Failed to open database path '%s'. The wallet appears to be a Legacy wallet, please use the wallet migration tool (migratewallet RPC or the GUI option).", fs::PathToString(path))); |
| 1342 | status = DatabaseStatus::FAILED_LEGACY_DISABLED; |
| 1343 | return nullptr; |
| 1344 | } |
| 1345 | |
| 1346 | // A db already exists so format is set, but options also specifies the format, so make sure they agree |
| 1347 | if (format && options.require_format && format != options.require_format) { |
| 1348 | error = Untranslated(strprintf("Failed to load database path '%s'. Data is not in required format.", fs::PathToString(path))); |
| 1349 | status = DatabaseStatus::FAILED_BAD_FORMAT; |
| 1350 | return nullptr; |
| 1351 | } |
| 1352 | |
| 1353 | // Format is not set when a db doesn't already exist, so use the format specified by the options if it is set. |
| 1354 | if (!format && options.require_format) format = options.require_format; |
no test coverage detected