CutBox.app

Coverage Report

Created: 2024-03-12 03:40

.../Source/App/Services/History/Migration/HistoryStoreMigration_1_6_x.swift
Line
Count
Source (jump to first uncovered line)
1
//
2
//  HistoryStoreMigration_1_6_x.swift
3
//  CutBox
4
//
5
//  Created by Jason Milkins on 21/8/23.
6
//  Copyright © 2023 ocodo. All rights reserved.
7
//
8
9
import Foundation
10
11
/// Migrate Cutbox historyStore to 1.6.0 (internal use)
12
///
13
/// The migration applies timestamps from 30 days ago
14
/// when an item is missing one.  Timestamps are sequential to
15
/// avoid any possible collision issue. NO ROLLBACK.
16
///
17
/// Note: The offset of 30 days ago is default, and can be overridden.
18
///
19
/// The instance method `applyTimestampsToLegacyItems(offset: TimeInterval)`
20
/// perfoms the migration. Use `migrationRequired: Bool` to avoid running
21
/// an unnecessary migration.
22
class HistoryStoreMigration_1_6_x {
23
    private var defaults: UserDefaults
24
25
88
    init(defaults: UserDefaults = UserDefaults.standard) {
26
88
        self.defaults = defaults
27
88
    }
28
29
    /// Is there a historyStore and does it have legacy items?
30
86
    var isMigrationRequired: Bool {
31
86
        return hasLegacyItems
32
86
    }
33
34
    /// Does historyStore contain items without timestamps?
35
86
    private var hasLegacyItems: Bool {
36
86
        if let historyStore = defaults
37
86
            .array(forKey: Constants.kHistoryStoreKey) as? [[String: String]] {
38
3
            let test = historyStore
39
13
                .contains { $0["timestamp"] == nil }
40
3
            return test
41
83
        } else {
42
83
            return false
43
83
        }
44
0
    }
45
46
    /// Apply sequential ISO8601 timestamps to the legacy items
47
    /// - offset: seconds ago (default 30 days) to start setting timestamps
48
    /// Note: TimeStamps are applied approximately one-second apart
49
4
    func applyTimestampsToLegacyItems(offset: TimeInterval = -2592000.0) {
50
4
        var idx = 0.0
51
4
        let historyStore = defaults
52
4
            .array(forKey: Constants.kHistoryStoreKey) as? [[String: String]]
53
4
        var migratedHistoryStore: [[String: String]] = []
54
4
55
28
        historyStore?.forEach { var item = $0
56
28
            if !item.keys.contains(Constants.kTimestampKey) {
57
19
                let timestamp = iso8601Timestamp(fromDate: Date(timeIntervalSinceNow: offset + idx))
58
19
                idx += 1
59
19
                item[Constants.kTimestampKey] = timestamp
60
28
            }
61
28
            migratedHistoryStore.append(item)
62
28
        }
63
4
64
4
        self.defaults.set(migratedHistoryStore, forKey: Constants.kHistoryStoreKey)
65
4
    }
66
}