# 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

    }