Skip to content

Commit

Permalink
feature(SabyApplePreference): add item version feature
Browse files Browse the repository at this point in the history
  • Loading branch information
0xWOF committed May 24, 2024
1 parent 5e033af commit 4caff72
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 22 deletions.
19 changes: 12 additions & 7 deletions Source/ApplePreference/Implement/FileValuePreference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import SabySafe
import SabyConcurrency
import SabyJSON

private let STORAGE_VERSION = "Version1"

public final class FileValuePreference<Value: Codable>: ValuePreference {
typealias Context = FileValuePreferenceContext

Expand All @@ -20,11 +22,11 @@ public final class FileValuePreference<Value: Codable>: ValuePreference {

let encoder = JSONEncoder.acceptingNonConfirmingFloat()

public init(directoryURL: URL, fileName: String, migration: @escaping () throws -> Void) {
public init(directoryURL: URL, storageName: String, migration: @escaping () throws -> Void) {
self.contextLoad = {
try Context.load(
directoryURL: directoryURL,
fileName: fileName,
storageName: storageName,
migration: migration
)
}
Expand Down Expand Up @@ -80,16 +82,16 @@ extension FileValuePreference {

struct FileValuePreferenceContext<Value: Codable> {
let url: URL
let value: Atomic<Value?>
let value: Atomic<FileValuePreferenceItemVersion1<Value>?>

private init(url: URL, value: Atomic<Value?>) {
private init(url: URL, value: Atomic<FileValuePreferenceItemVersion1<Value>?>) {
self.url = url
self.value = value
}

static func load(
directoryURL: URL,
fileName: String,
storageName: String,
migration: () throws -> Void
) throws -> FileValuePreferenceContext {
try migration()
Expand All @@ -108,7 +110,7 @@ struct FileValuePreferenceContext<Value: Codable> {
)
}

let url = directoryURL.appendingPathComponent(fileName)
let url = directoryURL.appendingPathComponent(storageName).appendingPathExtension(STORAGE_VERSION)
if !fileManager.fileExists(atPath: url.path) {
return FileValuePreferenceContext(
url: url,
Expand All @@ -119,7 +121,7 @@ struct FileValuePreferenceContext<Value: Codable> {
guard
let data = try? Data(contentsOf: url),
let value = try? decoder.decode(
Value?.self,
FileValuePreferenceItemVersion1<Value>?.self,
from: data
)
else {
Expand All @@ -135,3 +137,6 @@ struct FileValuePreferenceContext<Value: Codable> {
)
}
}

// Must not be modified. Write new ItemVersion and write migration logic instead.
typealias FileValuePreferenceItemVersion1<Value: Codable> = Value
14 changes: 7 additions & 7 deletions Source/ApplePreference/Preference.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
import Foundation

public protocol Preference {
/// ``init(directoryURL:fileName:migration:)``
/// ``init(directoryURL:storageName:migration:)``
/// execute migration and then create or load preference from
/// `{Directory url}/{File name}` path.
init(directoryURL: URL, fileName: String, migration: @escaping () throws -> Void)
/// `{Directory url}/{Storage name}/{Version name}` path.
init(directoryURL: URL, storageName: String, migration: @escaping () throws -> Void)
}

extension Preference {
/// ``init(directoryName:fileName:)`` create or load storage from
/// `{Directory url}/{File name}` path.
public init(directoryURL: URL, fileName: String) {
self.init(directoryURL: directoryURL, fileName: fileName, migration: {})
/// ``init(directoryName:storageName:)`` create or load storage from
/// `{Directory url}/{Storage name}/{Version name}` path.
public init(directoryURL: URL, storageName: String) {
self.init(directoryURL: directoryURL, storageName: storageName, migration: {})
}
}

Expand Down
2 changes: 1 addition & 1 deletion Source/AppleStorage/Implement/CoreDataArrayStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ public enum CoreDataArrayStorageError: Error {
case requestResultNotFound
}

// Must not be modified. Write ItemVersion2 and write migration logic instead.
// Must not be modified. Write new ItemVersion and write migration logic instead.
@objc(SabyCoreDataArrayStorageItemVersion1)
final class SabyCoreDataArrayStorageItemVersion1: NSManagedObject {
@NSManaged var key: UUID
Expand Down
2 changes: 1 addition & 1 deletion Source/AppleStorage/Implement/FileArrayStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public enum FileArrayStorageError: Error {
case libraryDirectoryNotFound
}

// Must not be modified. Write ItemVersion2 and write migration logic instead.
// Must not be modified. Write new ItemVersion and write migration logic instead.
struct FileArrayStorageItemVersion1<Value: Codable>: Codable {
let key: UUID
let value: Value
Expand Down
2 changes: 1 addition & 1 deletion Source/AppleStorage/Implement/FileDictionaryStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,5 @@ struct FileDictionaryStorageContext<Key: Hashable & Codable, Value: Codable> {
}
}

// Must not be modified. Write ItemVersion2 and write migration logic instead.
// Must not be modified. Write new ItemVersion and write migration logic instead.
typealias FileDictionaryStorageItemVersion1<Key: Hashable & Codable, Value: Codable> = [Key: Value]
2 changes: 1 addition & 1 deletion Source/AppleStorage/Implement/FileValueStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,5 @@ struct FileValueStorageContext<Value: Codable> {
}
}

// Must not be modified. Write ItemVersion2 and write migration logic instead.
// Must not be modified. Write new ItemVersion and write migration logic instead.
typealias FileValueStorageItemVersion1<Value: Codable> = Value
8 changes: 4 additions & 4 deletions Test/ApplePreference/FileValuePreferenceTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ final class FileValuePreferenceTest: XCTestCase {
fileprivate let testCount = 500
fileprivate var preference: FileValuePreference<DummyItem>!
fileprivate let directoryURL = FileManager.default.temporaryDirectory
fileprivate var fileName: String!
fileprivate var storageName: String!

fileprivate var testObjects: [DummyItem] {
var result: [DummyItem] = []
Expand All @@ -29,15 +29,15 @@ final class FileValuePreferenceTest: XCTestCase {
}

override func setUpWithError() throws {
fileName = UUID().uuidString
storageName = UUID().uuidString
preference = FileValuePreference<DummyItem>(
directoryURL: directoryURL,
fileName: fileName
storageName: storageName
)
}

override func tearDownWithError() throws {
let fileURL = directoryURL.appendingPathComponent(fileName)
let fileURL = directoryURL.appendingPathComponent(storageName)

if FileManager.default.fileExists(atPath: fileURL.absoluteString) {
try FileManager.default.removeItem(at: fileURL)
Expand Down

0 comments on commit 4caff72

Please sign in to comment.