diff --git a/Library/Database/Databse.swift b/Library/Database/Database.swift similarity index 88% rename from Library/Database/Databse.swift rename to Library/Database/Database.swift index c179201..9049d37 100644 --- a/Library/Database/Databse.swift +++ b/Library/Database/Database.swift @@ -30,6 +30,9 @@ enum Database { t.add(column: "autoUpdateInterval", .integer).notNull().defaults(to: 0) } } + migrator.registerMigration("fix_cellular_typo") { db in + try db.execute(sql: "UPDATE preferences SET name = 'exclude_cellular_services' WHERE name = 'exclude_celluar_services'") + } try migrator.migrate(database) return database } catch { diff --git a/Library/Database/ShadredPreferences+Database.swift b/Library/Database/SharedPreferences+Database.swift similarity index 75% rename from Library/Database/ShadredPreferences+Database.swift rename to Library/Database/SharedPreferences+Database.swift index 8013001..a2b9345 100644 --- a/Library/Database/ShadredPreferences+Database.swift +++ b/Library/Database/SharedPreferences+Database.swift @@ -4,7 +4,7 @@ import GRDB extension SharedPreferences { public class Preference { - private let name: String + let name: String private let defaultValue: T init(_ name: String, defaultValue: T) { @@ -43,7 +43,11 @@ extension SharedPreferences { else { return nil } - return try BinaryDecoder().decode(from: item.data) + if T.self == String.self { + return String(data: item.data, encoding: .utf8) as? T + } else { + return try BinaryDecoder().decode(from: item.data) + } } private nonisolated static func write(_ name: String, _ value: (some Codable)?) async throws { @@ -52,9 +56,22 @@ extension SharedPreferences { try Item.deleteOne(db, id: name) } } else { - let data = try BinaryEncoder().encode(value) + let data: Data + if let stringValue = value as? String { + data = stringValue.data(using: .utf8)! + } else { + data = try BinaryEncoder().encode(value) + } try await Database.sharedWriter.write { db in - try Item(name: name, data: data).insert(db) + try Item(name: name, data: data).save(db) + } + } + } + + nonisolated static func batchDelete(_ names: [String]) async throws { + try await Database.sharedWriter.write { db in + for name in names { + try Item.deleteOne(db, id: name) } } } diff --git a/Library/Database/SharedPreferences.swift b/Library/Database/SharedPreferences.swift index 6ad27c1..feffbb4 100644 --- a/Library/Database/SharedPreferences.swift +++ b/Library/Database/SharedPreferences.swift @@ -1,8 +1,6 @@ import Foundation public enum SharedPreferences { - public static let language = Preference("language", defaultValue: "") - public static let selectedProfileID = Preference("selected_profile_id", defaultValue: -1) #if os(macOS) @@ -23,20 +21,25 @@ public enum SharedPreferences { public static let includeAllNetworks = Preference("include_all_networks", defaultValue: false) public static let excludeAPNs = Preference("exclude_apns", defaultValue: true) public static let excludeLocalNetworks = Preference("exclude_local_networks", defaultValue: excludeLocalNetworksByDefault) - public static let excludeCellularServices = Preference("exclude_celluar_services", defaultValue: true) + public static let excludeCellularServices = Preference("exclude_cellular_services", defaultValue: true) public static let enforceRoutes = Preference("enforce_routes", defaultValue: false) #endif public static func resetPacketTunnel() async { - await ignoreMemoryLimit.set(nil) #if !os(tvOS) - await includeAllNetworks.set(nil) - await excludeAPNs.set(nil) - await excludeLocalNetworks.set(nil) - await excludeCellularServices.set(nil) - await enforceRoutes.set(nil) + let names = [ + ignoreMemoryLimit.name, + includeAllNetworks.name, + excludeAPNs.name, + excludeLocalNetworks.name, + excludeCellularServices.name, + enforceRoutes.name, + ] + #else + let names = [ignoreMemoryLimit.name] #endif + try? await batchDelete(names) } public static let maxLogLines = Preference("max_log_lines", defaultValue: 300) @@ -47,8 +50,7 @@ public enum SharedPreferences { public static let startedByUser = Preference("started_by_user", defaultValue: false) public static func resetMacOS() async { - await showMenuBarExtra.set(nil) - await menuBarExtraInBackground.set(nil) + try? await batchDelete([showMenuBarExtra.name, menuBarExtraInBackground.name]) } #endif @@ -59,8 +61,8 @@ public enum SharedPreferences { public static let systemProxyEnabled = Preference("system_proxy_enabled", defaultValue: true) #if os(tvOS) - public static let commandServerPort = Preference("tv_command_server_port", defaultValue: 0) - public static let commandServerSecret = Preference("tv_command_server_secret", defaultValue: "") + public static let commandServerPort = Preference("command_server_port", defaultValue: 0) + public static let commandServerSecret = Preference("command_server_secret", defaultValue: "") #endif // Profile Override @@ -70,9 +72,7 @@ public enum SharedPreferences { public static let excludeAPNsRoute = Preference("exclude_apple_push_notification_services", defaultValue: false) public static func resetProfileOverride() async { - await excludeDefaultRoute.set(nil) - await autoRouteUseSubRangesByDefault.set(nil) - await excludeAPNsRoute.set(nil) + try? await batchDelete([excludeDefaultRoute.name, autoRouteUseSubRangesByDefault.name, excludeAPNsRoute.name]) } // Connections Filter @@ -85,7 +85,7 @@ public enum SharedPreferences { public static let alwaysOn = Preference("always_on", defaultValue: false) public static func resetOnDemandRules() async { - await alwaysOn.set(nil) + try? await batchDelete([alwaysOn.name]) } // Core