diff --git a/Sources/Pulse/LoggerStore/LoggerStore+Configuration.swift b/Sources/Pulse/LoggerStore/LoggerStore+Configuration.swift index 4674b281f..e3a8b45bb 100644 --- a/Sources/Pulse/LoggerStore/LoggerStore+Configuration.swift +++ b/Sources/Pulse/LoggerStore/LoggerStore+Configuration.swift @@ -39,6 +39,13 @@ extension LoggerStore { /// Opens store in a readonly mode. It won't perform sweeps and will /// disallow any other modifications. public static let readonly = Options(rawValue: 1 << 3) + + /// Logs are not persistent on the device storage and new log file is created on each app session. + /// Core Data is configured with container type as `NSInMemoryStoreType + /// + /// - warning: This options is not recommended for general use. Use it only when persistent logs do not suite + /// your use case, eg. for security reasons you can not store user logs on device storage + public static let inMemory = Options(rawValue: 1 << 4) } /// The store configuration. diff --git a/Sources/Pulse/LoggerStore/LoggerStore.swift b/Sources/Pulse/LoggerStore/LoggerStore.swift index d174afcc7..4e3bbc3a0 100644 --- a/Sources/Pulse/LoggerStore/LoggerStore.swift +++ b/Sources/Pulse/LoggerStore/LoggerStore.swift @@ -167,7 +167,7 @@ public final class LoggerStore: @unchecked Sendable, Identifiable { self.manifest = .init(storeId: info.storeId, version: try Version(string: info.storeVersion)) } - self.container = LoggerStore.makeContainer(databaseURL: databaseURL) + self.container = LoggerStore.makeContainer(databaseURL: databaseURL, options: options) try container.loadStore() self.backgroundContext = container.newBackgroundContext() @@ -245,10 +245,11 @@ public final class LoggerStore: @unchecked Sendable, Identifiable { self.configuration = .init() } - private static func makeContainer(databaseURL: URL) -> NSPersistentContainer { + private static func makeContainer(databaseURL: URL, options: Options) -> NSPersistentContainer { let container = NSPersistentContainer(name: databaseURL.lastPathComponent, managedObjectModel: Self.model) let store = NSPersistentStoreDescription(url: databaseURL) store.setValue("DELETE" as NSString, forPragmaNamed: "journal_mode") + store.type = options.contains(.inMemory) ? NSInMemoryStoreType : NSSQLiteStoreType container.persistentStoreDescriptions = [store] return container } diff --git a/Tests/PulseTests/LoggerStoreTests.swift b/Tests/PulseTests/LoggerStoreTests.swift index aa009bb7e..f89491c76 100644 --- a/Tests/PulseTests/LoggerStoreTests.swift +++ b/Tests/PulseTests/LoggerStoreTests.swift @@ -44,6 +44,23 @@ final class LoggerStoreTests: LoggerStoreBaseTests { try? secondStore.destroy() } + func testInitCreateInMemoryStore() throws { + // GIVEN + let storeURL = directory.url.appending(filename: UUID().uuidString) + let options: LoggerStore.Options = [.create, .synchronous, .inMemory] + + // WHEN + let store = try LoggerStore(storeURL: storeURL, options: options) + populate(store: store) + + // THEN data is NOT persisted + let databaseURL = storeURL.appending(filename: "logs.sqlite") + XCTAssertFalse(FileManager.default.fileExists(atPath: databaseURL.path)) + + // CLEANUP + try? store.destroy() + } + func testInitCreateStoreIntermediateDirectoryMissing() throws { // GIVEN let storeURL = directory.url