From eb26451cd724e7756711a45d09e2ebb3f8545770 Mon Sep 17 00:00:00 2001 From: Nicky Bondarenko Date: Fri, 5 Apr 2024 12:12:34 +0200 Subject: [PATCH] feat: add EventStorage --- Sources/Confidence/EventStorage.swift | 88 +++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 Sources/Confidence/EventStorage.swift diff --git a/Sources/Confidence/EventStorage.swift b/Sources/Confidence/EventStorage.swift new file mode 100644 index 00000000..a632efb7 --- /dev/null +++ b/Sources/Confidence/EventStorage.swift @@ -0,0 +1,88 @@ +import Foundation + +internal protocol EventStorage { + func startNewBatch() throws + func writeEvent(event: Event) throws + func batchReadyFiles() throws -> [URL] + func eventsFrom(fileURL: URL) throws -> [Event] +} + +internal class EventStorageImpl: EventStorage { + let DIRECTORY = "events" + let READYTOSENDEXTENSION = ".ready" + let encoder = JSONEncoder() + let decoder = JSONDecoder() + var folderURL: URL = URL(string: "")! + var fileURL: URL = URL(string: "")! + var currentBatch: [Event] = [] + + init() throws { + folderURL = URL(fileURLWithPath: try getFolderURL()) + fileURL = folderURL.appendingPathComponent("events-\(Date().currentTime)") + } + + func startNewBatch() throws { + let urlString = "\(fileURL)"+"\(READYTOSENDEXTENSION)" + let newPath = URL(fileURLWithPath: urlString) + try FileManager.default.moveItem(at: fileURL, to: newPath) + fileURL = folderURL.appendingPathComponent("events-\(Date().currentTime)") + currentBatch = [] + } + + func writeEvent(event: Event) throws { + currentBatch.append(event) + let data = try encoder.encode(currentBatch) + try data.write(to: fileURL, options: .atomic) + } + + func batchReadyFiles() throws -> [URL] { + var readyFilesList: [URL] = [] + let directoryContents = try FileManager.default.contentsOfDirectory(atPath: folderURL.absoluteString) + for file in directoryContents { + if file.hasSuffix(READYTOSENDEXTENSION) { + readyFilesList.append(URL(string: file)!) + } + } + return readyFilesList + } + + func eventsFrom(fileURL: URL) throws -> [Event] { + let data = try Data(contentsOf: fileURL) + let events = try decoder.decode([Event].self, from: data) + return events + } + + private func getFolderURL() throws -> String { + let rootFolderURL = try FileManager.default.url( + for: .cachesDirectory, + in: .userDomainMask, + appropriateFor: nil, + create: true + ) + var nestedFolderURL: String + if #available(iOS 16.0, *) { + nestedFolderURL = rootFolderURL.appending(path: DIRECTORY).absoluteString + } else { + nestedFolderURL = rootFolderURL.appendingPathComponent(DIRECTORY, isDirectory: true).absoluteString + } + return nestedFolderURL + } +} + +struct Event: Codable { + let eventDefinition: String + let eventTime: Date + // TODO: fix this to be ConfidenceValue + let payload: [String] + let context: [String] +} + + +extension Date { + var currentTime: String { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .short + return dateFormatter.string(from: self) + } +} +