// // StorageService.swift // AutoCatCore // // Created by Selim Mustafaev on 22.06.2024. // Copyright © 2024 Selim Mustafaev. All rights reserved. // import Foundation import RealmSwift public actor StorageService: StorageServiceProtocol { let settingsService: SettingsServiceProtocol var realm: Realm! public init(settingsService: SettingsServiceProtocol, isTest: Bool = false) async throws { self.settingsService = settingsService realm = try await setup(isTest: isTest) } // Swift 6.0 and 6.1 crashes if this code is placed directly into init private func setup(isTest: Bool) async throws -> Realm { var realmConfig: Realm.Configuration if isTest { realmConfig = .defaultConfiguration realmConfig.inMemoryIdentifier = UUID().uuidString } else { realmConfig = Realm.Configuration( schemaVersion: 42, migrationBlock: { migration, oldSchemaVersion in } ) } return try await Realm.open(configuration: realmConfig) } public var dbFileURL: URL? { get async { realm.configuration.fileURL } } public var config: Realm.Configuration { realm.configuration } public func deleteAll() async throws { try await realm.asyncWrite { realm.deleteAll() } } @discardableResult public func updateVehicle(dto: VehicleDto, policy: DbUpdatePolicy) async throws -> Bool { let shouldUpdate = switch policy { case .always: true case .ifExists: realm.object(ofType: Vehicle.self, forPrimaryKey: dto.getNumber()) != nil } guard shouldUpdate else { return false } try await realm.asyncWrite { realm.add(Vehicle(dto: dto), update: .all) } return true } public func loadVehicle(number: String) async throws -> VehicleDto { if let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) { return vehicle.dto } else { throw StorageError.vehicleNotFound } } public func loadVehicles() async -> [VehicleDto] { realm.objects(Vehicle.self) .sorted(byKeyPath: "updatedDate", ascending: false) .map(\.shallowDto) } public func deleteVehicle(number: String) async throws { guard let vehicle = realm.object(ofType: Vehicle.self, forPrimaryKey: number) else { throw StorageError.vehicleNotFound } try await realm.asyncWrite { realm.delete(vehicle) } } }