forked from duckduckgo/iOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBookmarksStateValidation.swift
More file actions
104 lines (85 loc) · 3.57 KB
/
BookmarksStateValidation.swift
File metadata and controls
104 lines (85 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// BookmarksStateValidation.swift
// DuckDuckGo
//
// Copyright © 2024 DuckDuckGo. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
import CoreData
import Bookmarks
import Persistence
public protocol BookmarksStateValidation {
func validateInitialState(context: NSManagedObjectContext,
validationError: BookmarksStateValidator.ValidationError) -> Bool
func validateBookmarksStructure(context: NSManagedObjectContext)
}
public class BookmarksStateValidator: BookmarksStateValidation {
enum Constants {
static let bookmarksDBIsInitialized = "bookmarksDBIsInitialized"
}
public enum ValidationError {
case bookmarksStructureLost
case bookmarksStructureNotRecovered
case bookmarksStructureBroken(additionalParams: [String: String])
case validatorError(Error)
}
let keyValueStore: KeyValueStoring
let errorHandler: (ValidationError) -> Void
public init(keyValueStore: KeyValueStoring,
errorHandler: @escaping (ValidationError) -> Void) {
self.keyValueStore = keyValueStore
self.errorHandler = errorHandler
}
public func validateInitialState(context: NSManagedObjectContext,
validationError: ValidationError) -> Bool {
guard keyValueStore.object(forKey: Constants.bookmarksDBIsInitialized) != nil else { return true }
let fetch = BookmarkEntity.fetchRequest()
do {
let count = try context.count(for: fetch)
if count == 0 {
errorHandler(validationError)
return false
}
} catch {
errorHandler(.validatorError(error))
}
return true
}
public func validateBookmarksStructure(context: NSManagedObjectContext) {
let isMarkedAsInitialized = keyValueStore.object(forKey: Constants.bookmarksDBIsInitialized) != nil
if isMarkedAsInitialized == false {
keyValueStore.set(true, forKey: Constants.bookmarksDBIsInitialized)
}
let rootUUIDs = [BookmarkEntity.Constants.rootFolderID,
FavoritesFolderID.unified.rawValue,
FavoritesFolderID.mobile.rawValue,
FavoritesFolderID.desktop.rawValue]
let request = BookmarkEntity.fetchRequest()
request.predicate = NSPredicate(format: "%K IN %@", #keyPath(BookmarkEntity.uuid), rootUUIDs)
do {
let roots = try context.fetch(request)
if roots.count != rootUUIDs.count {
var additionalParams = [String: String]()
for uuid in rootUUIDs {
additionalParams[uuid] = "\(roots.filter({ $0.uuid == uuid }).count)"
}
additionalParams["is-marked-as-initialized"] = isMarkedAsInitialized ? "true" : "false"
errorHandler(.bookmarksStructureBroken(additionalParams: additionalParams))
}
} catch {
errorHandler(.validatorError(error))
}
}
}