| 1189 | } |
| 1190 | |
| 1191 | std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error) |
| 1192 | { |
| 1193 | bool exists; |
| 1194 | try { |
| 1195 | exists = fs::symlink_status(path).type() != fs::file_type::not_found; |
| 1196 | } catch (const fs::filesystem_error& e) { |
| 1197 | error = Untranslated(strprintf("Failed to access database path '%s': %s", fs::PathToString(path), fsbridge::get_filesystem_error_message(e))); |
| 1198 | status = DatabaseStatus::FAILED_BAD_PATH; |
| 1199 | return nullptr; |
| 1200 | } |
| 1201 | |
| 1202 | std::optional<DatabaseFormat> format; |
| 1203 | if (exists) { |
| 1204 | if (IsBDBFile(BDBDataFile(path))) { |
| 1205 | format = DatabaseFormat::BERKELEY; |
| 1206 | } |
| 1207 | if (IsSQLiteFile(SQLiteDataFile(path))) { |
| 1208 | if (format) { |
| 1209 | error = Untranslated(strprintf("Failed to load database path '%s'. Data is in ambiguous format.", fs::PathToString(path))); |
| 1210 | status = DatabaseStatus::FAILED_BAD_FORMAT; |
| 1211 | return nullptr; |
| 1212 | } |
| 1213 | format = DatabaseFormat::SQLITE; |
| 1214 | } |
| 1215 | } else if (options.require_existing) { |
| 1216 | error = Untranslated(strprintf("Failed to load database path '%s'. Path does not exist.", fs::PathToString(path))); |
| 1217 | status = DatabaseStatus::FAILED_NOT_FOUND; |
| 1218 | return nullptr; |
| 1219 | } |
| 1220 | |
| 1221 | if (!format && options.require_existing) { |
| 1222 | error = Untranslated(strprintf("Failed to load database path '%s'. Data is not in recognized format.", fs::PathToString(path))); |
| 1223 | status = DatabaseStatus::FAILED_BAD_FORMAT; |
| 1224 | return nullptr; |
| 1225 | } |
| 1226 | |
| 1227 | if (format && options.require_create) { |
| 1228 | error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", fs::PathToString(path))); |
| 1229 | status = DatabaseStatus::FAILED_ALREADY_EXISTS; |
| 1230 | return nullptr; |
| 1231 | } |
| 1232 | |
| 1233 | // A db already exists so format is set, but options also specifies the format, so make sure they agree |
| 1234 | if (format && options.require_format && format != options.require_format) { |
| 1235 | error = Untranslated(strprintf("Failed to load database path '%s'. Data is not in required format.", fs::PathToString(path))); |
| 1236 | status = DatabaseStatus::FAILED_BAD_FORMAT; |
| 1237 | return nullptr; |
| 1238 | } |
| 1239 | |
| 1240 | // Format is not set when a db doesn't already exist, so use the format specified by the options if it is set. |
| 1241 | if (!format && options.require_format) format = options.require_format; |
| 1242 | |
| 1243 | // If the format is not specified or detected, choose the default format based on what is available. We prefer BDB over SQLite for now. |
| 1244 | if (!format) { |
| 1245 | #ifdef USE_SQLITE |
| 1246 | format = DatabaseFormat::SQLITE; |
| 1247 | #endif |
| 1248 | #ifdef USE_BDB |
no test coverage detected