mirror of https://github.com/oxen-io/session-ios
				
				
				
			
						commit
						cc49eca233
					
				| @ -0,0 +1,46 @@ | ||||
| // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. | ||||
| 
 | ||||
| import Foundation | ||||
| 
 | ||||
| @objc(SNOpenGroupServerIdLookup) | ||||
| public final class OpenGroupServerIdLookup: NSObject, NSCoding {    // NSObject/NSCoding conformance is needed for YapDatabase compatibility | ||||
|     @objc public let id: String | ||||
|     @objc public let serverId: UInt64 | ||||
|     @objc public let tsMessageId: String | ||||
|      | ||||
|     // MARK: - Initialization | ||||
|          | ||||
|     @objc public init(server: String, room: String, serverId: UInt64, tsMessageId: String) { | ||||
|         self.id = OpenGroupServerIdLookup.id(serverId: serverId, in: room, on: server) | ||||
|         self.serverId = serverId | ||||
|         self.tsMessageId = tsMessageId | ||||
| 
 | ||||
|         super.init() | ||||
|     } | ||||
| 
 | ||||
|     private override init() { preconditionFailure("Use init(blindedId:sessionId:) instead.") } | ||||
| 
 | ||||
|     // MARK: - Coding | ||||
|      | ||||
|     public required init?(coder: NSCoder) { | ||||
|         guard let id: String = coder.decodeObject(forKey: "id") as! String? else { return nil } | ||||
|         guard let serverId: UInt64 = coder.decodeObject(forKey: "serverId") as! UInt64? else { return nil } | ||||
|         guard let tsMessageId: String = coder.decodeObject(forKey: "tsMessageId") as! String? else { return nil } | ||||
| 
 | ||||
|         self.id = id | ||||
|         self.serverId = serverId | ||||
|         self.tsMessageId = tsMessageId | ||||
|     } | ||||
| 
 | ||||
|     public func encode(with coder: NSCoder) { | ||||
|         coder.encode(id, forKey: "id") | ||||
|         coder.encode(serverId, forKey: "serverId") | ||||
|         coder.encode(tsMessageId, forKey: "tsMessageId") | ||||
|     } | ||||
|      | ||||
|     // MARK: - Convenience | ||||
|      | ||||
|     static func id(serverId: UInt64, in room: String, on server: String) -> String { | ||||
|         return "\(server).\(room).\(serverId)" | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,44 @@ | ||||
| // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. | ||||
| import Foundation | ||||
| 
 | ||||
| // MARK: - Atomic<Value> | ||||
| /// The `Atomic<Value>` wrapper is a generic wrapper providing a thread-safe way to get and set a value | ||||
| /// | ||||
| /// A write-up on the need for this class and it's approach can be found here: | ||||
| /// https://www.vadimbulavin.com/swift-atomic-properties-with-property-wrappers/ | ||||
| /// there is also another approach which can be taken but it requires separate types for collections and results in | ||||
| /// a somewhat inconsistent interface between different `Atomic` wrappers | ||||
| @propertyWrapper | ||||
| public class Atomic<Value> { | ||||
|     private let queue: DispatchQueue = DispatchQueue(label: "io.oxen.\(UUID().uuidString)") | ||||
|     private var value: Value | ||||
| 
 | ||||
|     /// In order to change the value you **must** use the `mutate` function | ||||
|     public var wrappedValue: Value { | ||||
|         return queue.sync { return value } | ||||
|     } | ||||
| 
 | ||||
|     /// For more information see https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md#projections | ||||
|     public var projectedValue: Atomic<Value> { | ||||
|         return self | ||||
|     } | ||||
| 
 | ||||
|     // MARK: - Initialization | ||||
|     public init(_ initialValue: Value) { | ||||
|         self.value = initialValue | ||||
|     } | ||||
| 
 | ||||
|     // MARK: - Functions | ||||
|      | ||||
|     public func mutate(_ mutation: (inout Value) -> Void) { | ||||
|         return queue.sync { | ||||
|             mutation(&value) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| extension Atomic where Value: CustomDebugStringConvertible { | ||||
|     var debugDescription: String { | ||||
|         return value.debugDescription | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,48 @@ | ||||
| // Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. | ||||
| 
 | ||||
| import Foundation | ||||
| 
 | ||||
| @objc(SNOpenGroupServerIdLookupMigration) | ||||
| public class OpenGroupServerIdLookupMigration: OWSDatabaseMigration { | ||||
|     @objc | ||||
|     class func migrationId() -> String { | ||||
|         return "003" | ||||
|     } | ||||
| 
 | ||||
|     override public func runUp(completion: @escaping OWSDatabaseMigrationCompletion) { | ||||
|         self.doMigrationAsync(completion: completion) | ||||
|     } | ||||
| 
 | ||||
|     private func doMigrationAsync(completion: @escaping OWSDatabaseMigrationCompletion) { | ||||
|         var lookups: [OpenGroupServerIdLookup] = [] | ||||
|          | ||||
|         Storage.write(with: { transaction in | ||||
|             TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in | ||||
|                 guard let thread: TSGroupThread = object as? TSGroupThread else { return } | ||||
|                 guard let threadId: String = thread.uniqueId else { return } | ||||
|                 guard let openGroup: OpenGroupV2 = Storage.shared.getV2OpenGroup(for: threadId) else { return } | ||||
|                  | ||||
|                 thread.enumerateInteractions(with: transaction) { interaction, _ in | ||||
|                     guard let tsMessage: TSMessage = interaction as? TSMessage else { return } | ||||
|                     guard let tsMessageId: String = tsMessage.uniqueId else { return } | ||||
|                      | ||||
|                     lookups.append( | ||||
|                         OpenGroupServerIdLookup( | ||||
|                             server: openGroup.server, | ||||
|                             room: openGroup.room, | ||||
|                             serverId: tsMessage.openGroupServerMessageID, | ||||
|                             tsMessageId: tsMessageId | ||||
|                         ) | ||||
|                     ) | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             lookups.forEach { lookup in | ||||
|                 Storage.shared.addOpenGroupServerIdLookup(lookup, using: transaction) | ||||
|             } | ||||
|             self.save(with: transaction) // Intentionally capture self | ||||
|         }, completion: { | ||||
|             completion() | ||||
|         }) | ||||
|     } | ||||
| } | ||||
					Loading…
					
					
				
		Reference in New Issue