From fdfa0c872458fa898d5f386aac0792fd00465e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matu=CC=81s=CC=8C=20Tomlein?= Date: Tue, 30 Jan 2024 19:11:33 +0100 Subject: [PATCH] Add internal queue wrappers for the event store --- .../Core/Emitter/EmitterControllerImpl.swift | 2 +- .../EmitterControllerIQWrapper.swift | 4 ++ .../InternalQueue/EventStoreIQWrapper.swift | 52 +++++++++++++++++++ .../Controllers/EmitterController.swift | 2 +- .../TestEmitterConfiguration.swift | 21 ++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 Sources/Core/InternalQueue/EventStoreIQWrapper.swift diff --git a/Sources/Core/Emitter/EmitterControllerImpl.swift b/Sources/Core/Emitter/EmitterControllerImpl.swift index eb5c07e35..51ee2a835 100644 --- a/Sources/Core/Emitter/EmitterControllerImpl.swift +++ b/Sources/Core/Emitter/EmitterControllerImpl.swift @@ -132,7 +132,7 @@ class EmitterControllerImpl: Controller, EmitterController { } } - var eventStore: EventStore? { + var eventStore: EventStore { return emitter.eventStore } diff --git a/Sources/Core/InternalQueue/EmitterControllerIQWrapper.swift b/Sources/Core/InternalQueue/EmitterControllerIQWrapper.swift index 290daaa74..d7713b772 100644 --- a/Sources/Core/InternalQueue/EmitterControllerIQWrapper.swift +++ b/Sources/Core/InternalQueue/EmitterControllerIQWrapper.swift @@ -85,6 +85,10 @@ class EmitterControllerIQWrapper: EmitterController { get { return InternalQueue.sync { controller.maxEventStoreAge } } set { InternalQueue.sync { controller.maxEventStoreAge = newValue } } } + + var eventStore: EventStore { + get { return InternalQueue.sync { EventStoreIQWrapper(eventStore: controller.eventStore) } } + } // MARK: - Methods diff --git a/Sources/Core/InternalQueue/EventStoreIQWrapper.swift b/Sources/Core/InternalQueue/EventStoreIQWrapper.swift new file mode 100644 index 000000000..8b584789a --- /dev/null +++ b/Sources/Core/InternalQueue/EventStoreIQWrapper.swift @@ -0,0 +1,52 @@ +// Copyright (c) 2013-present Snowplow Analytics Ltd. All rights reserved. +// +// This program is licensed to you under the Apache License Version 2.0, +// and you may not use this file except in compliance with the Apache License +// Version 2.0. You may obtain a copy of the Apache License Version 2.0 at +// http://www.apache.org/licenses/LICENSE-2.0. +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the Apache License Version 2.0 is distributed on +// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the Apache License Version 2.0 for the specific +// language governing permissions and limitations there under. + +import Foundation + +class EventStoreIQWrapper: NSObject, EventStore { + + private let eventStore: EventStore + + public init(eventStore: EventStore) { + self.eventStore = eventStore + } + + func addEvent(_ payload: Payload) { + InternalQueue.sync { eventStore.addEvent(payload) } + } + + func removeEvent(withId storeId: Int64) -> Bool { + return InternalQueue.sync { eventStore.removeEvent(withId: storeId) } + } + + func removeEvents(withIds storeIds: [Int64]) -> Bool { + return InternalQueue.sync { eventStore.removeEvents(withIds: storeIds) } + } + + func removeAllEvents() -> Bool { + return InternalQueue.sync { eventStore.removeAllEvents() } + } + + func count() -> UInt { + return InternalQueue.sync { eventStore.count() } + } + + func emittableEvents(withQueryLimit queryLimit: UInt) -> [EmitterEvent] { + return InternalQueue.sync { eventStore.emittableEvents(withQueryLimit: queryLimit) } + } + + func removeOldEvents(maxSize: Int64, maxAge: TimeInterval) { + return InternalQueue.sync { eventStore.removeOldEvents(maxSize: maxSize, maxAge: maxAge) } + } + +} diff --git a/Sources/Snowplow/Controllers/EmitterController.swift b/Sources/Snowplow/Controllers/EmitterController.swift index d146163bd..da9acb0b1 100644 --- a/Sources/Snowplow/Controllers/EmitterController.swift +++ b/Sources/Snowplow/Controllers/EmitterController.swift @@ -23,7 +23,7 @@ public protocol EmitterController: EmitterConfigurationProtocol { var isSending: Bool { get } /// The EventStore being used by the emitter. @objc - var eventStore: EventStore? { get } + var eventStore: EventStore { get } @objc func flush() /// Pause emitting events. diff --git a/Tests/Configurations/TestEmitterConfiguration.swift b/Tests/Configurations/TestEmitterConfiguration.swift index 6c32d5571..f2f320057 100644 --- a/Tests/Configurations/TestEmitterConfiguration.swift +++ b/Tests/Configurations/TestEmitterConfiguration.swift @@ -80,6 +80,27 @@ class TestEmitterConfiguration: XCTestCase { XCTAssertEqual(0, tracker.emitter?.dbCount) } + func testAllowsAccessToTheEventStore() { + let networkConnection = MockNetworkConnection(requestOption: .post, statusCode: 200) + let networkConfig = NetworkConfiguration(networkConnection: networkConnection) + + let tracker = createTracker(networkConfig: networkConfig, emitterConfig: EmitterConfiguration()) + + tracker.emitter?.pause() + for i in 0..<10 { + _ = tracker.track(Structured(category: "cat", action: "act").value(NSNumber(value: i))) + } + Thread.sleep(forTimeInterval: 0.5) + + XCTAssertEqual(10, tracker.emitter?.dbCount) + XCTAssertEqual(10, tracker.emitter?.eventStore.count()) + + XCTAssertTrue(tracker.emitter?.eventStore.removeAllEvents() ?? false) + + XCTAssertEqual(0, tracker.emitter?.dbCount) + XCTAssertEqual(0, tracker.emitter?.eventStore.count()) + } + private func createTracker(networkConfig: NetworkConfiguration, emitterConfig: EmitterConfiguration) -> TrackerController { let trackerConfig = TrackerConfiguration() trackerConfig.installAutotracking = false