From 95e2d53dd90d3e88c632fe00fc429e6dd13bff23 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 16 Jul 2015 18:27:59 +0300 Subject: [PATCH] no message --- Postbox/Postbox.swift | 82 ++++++++++++++++++++++++--------- PostboxTests/PostboxTests.swift | 52 ++++++++++++--------- 2 files changed, 89 insertions(+), 45 deletions(-) diff --git a/Postbox/Postbox.swift b/Postbox/Postbox.swift index b5a6f87549..4fd0ae69a8 100644 --- a/Postbox/Postbox.swift +++ b/Postbox/Postbox.swift @@ -2,25 +2,27 @@ import Foundation import SwiftSignalKit -public final class Postbox { - static let PeerTagGeneral = 0 +public class Modifier { + private unowned var postbox: Postbox - public class Modifier { - private unowned var postbox: Postbox - - private init(postbox: Postbox) { - self.postbox = postbox - } - - public func addMessages(messages: [Message], medias: [Media]) { - self.postbox.addMessages(messages, medias: medias) - } - - public func deleteMessagesWithIds(ids: [MessageId]) { - self.postbox.deleteMessagesWithIds(ids) - } + private init(postbox: Postbox) { + self.postbox = postbox } + public func addMessages(messages: [Message], medias: [Media]) { + self.postbox.addMessages(messages, medias: medias) + } + + public func deleteMessagesWithIds(ids: [MessageId]) { + self.postbox.deleteMessagesWithIds(ids) + } + + public func setState(state: Coding) { + self.postbox.setState(state) + } +} + +public final class Postbox { private let basePath: String private let messageNamespaces: [MessageId.Namespace] @@ -29,6 +31,7 @@ public final class Postbox { private var peerMessageViews: [PeerId : Bag<(MutableMessageView, Pipe)>] = [:] private var peerViews: Bag<(MutablePeerView, Pipe)> = Bag() + private var statePipe: Pipe = Pipe() public init(basePath: String, messageNamespaces: [MessageId.Namespace]) { self.basePath = basePath @@ -53,7 +56,7 @@ public final class Postbox { private func createSchema() { //state - self.database.execute("CREATE TABLE state (data BLOB)") + self.database.execute("CREATE TABLE state (id INTEGER, data BLOB)") //peer_messages self.database.execute("CREATE TABLE peer_messages (peerId INTEGER, namespace INTEGER, id INTEGER, data BLOB, associatedMediaIds BLOB, timestamp INTEGER, PRIMARY KEY(peerId, namespace, id))") @@ -311,6 +314,34 @@ public final class Postbox { return ids } + private func setState(state: Coding) { + let encoder = Encoder() + encoder.encodeRootObject(state) + let blob = Blob(data: encoder.makeData()) + self.database.prepareCached("INSERT OR REPLACE INTO state (id, data) VALUES (?, ?)").run(Int64(0), blob) + } + + public func state() -> Signal { + return Signal { subscriber in + let disposable = MetaDisposable() + self.queue.dispatch { + for row in self.database.prepareCached("SELECT data FROM state WHERE id = ?").run(Int64(0)) { + let data = (row[0] as! Blob).data + let buffer = ReadBuffer(memory: UnsafeMutablePointer(data.bytes), length: data.length, freeWhenDone: false) + let decoder = Decoder(buffer: buffer) + if let state = decoder.decodeRootObject() as? State { + subscriber.putNext(state) + } + break + } + disposable.set(self.statePipe.signal().start(next: { next in + subscriber.putNext(next) + })) + } + return disposable + } + } + private func addMessages(messages: [Message], medias: [Media]) { let messageInsertStatement = self.database.prepare("INSERT INTO peer_messages (peerId, namespace, id, data, associatedMediaIds, timestamp) VALUES (?, ?, ?, ?, ?, ?)") let peerMediaInsertStatement = self.database.prepare("INSERT INTO peer_media (peerId, mediaNamespace, messageNamespace, messageId) VALUES (?, ?, ?, ?)") @@ -596,7 +627,6 @@ public final class Postbox { } } - for (namespace, messageIds) in messageIdsByNamespace { var queryString = "DELETE FROM peer_messages WHERE peerId = ? AND namespace = ? AND id IN (" var first = true @@ -671,11 +701,17 @@ public final class Postbox { } } - public func modify(f: Modifier -> Void) { - self.queue.dispatch { - self.database.transaction() - f(Modifier(postbox: self)) - self.database.commit() + public func modify(f: Modifier -> T) -> Signal { + return Signal { subscriber in + self.queue.dispatch { + self.database.transaction() + let result = f(Modifier(postbox: self)) + self.database.commit() + + subscriber.putNext(result) + subscriber.putCompletion() + } + return EmptyDisposable } } diff --git a/PostboxTests/PostboxTests.swift b/PostboxTests/PostboxTests.swift index 6b1fca9f4c..effe0caeaa 100644 --- a/PostboxTests/PostboxTests.swift +++ b/PostboxTests/PostboxTests.swift @@ -93,6 +93,14 @@ class TestMedia: Media { } } +class EmptyState: Coding { + required init(decoder: Decoder) { + } + + func encode(encoder: Encoder) { + } +} + class PostboxTests: XCTestCase { override func setUp() { @@ -113,8 +121,8 @@ class PostboxTests: XCTestCase { let basePath = "/tmp/postboxtest" NSFileManager.defaultManager().removeItemAtPath(basePath, error: nil) - let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespace]) - postbox.modify { state in + let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespace]) + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 0 ..< 10 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) @@ -122,27 +130,27 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() postbox._dumpTables() - postbox.modify { state in + (postbox.modify { state -> Void in var messageIds: [MessageId] = [] for i in 0 ..< 5 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) messageIds.append(messageId) } state.deleteMessagesWithIds(messageIds) - } + }).start() postbox._dumpTables(); - postbox.modify { state in + (postbox.modify { state -> Void in var messageIds: [MessageId] = [] for i in 0 ..< 10 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) messageIds.append(messageId) } state.deleteMessagesWithIds(messageIds) - } + }).start() postbox._dumpTables(); } @@ -602,9 +610,9 @@ class PostboxTests: XCTestCase { let basePath = "/tmp/postboxtest" NSFileManager.defaultManager().removeItemAtPath(basePath, error: nil) - let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespace]) + let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespace]) - postbox.modify { state in + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 0 ..< 10 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) @@ -612,13 +620,13 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() postbox.tailMessageViewForPeerId(otherId, count: 4).start(next: { next in println(next) }) - postbox.modify { state in + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 10 ..< 15 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) @@ -626,7 +634,7 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() postbox._sync() } @@ -642,9 +650,9 @@ class PostboxTests: XCTestCase { let basePath = "/tmp/postboxtest" NSFileManager.defaultManager().removeItemAtPath(basePath, error: nil) - let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespaceCloud, messageNamespaceLocal]) + let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespaceCloud, messageNamespaceLocal]) - postbox.modify { state in + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 0 ..< 10 { let messageId = MessageId(peerId: otherId, namespace: messageNamespaceCloud, id: Int32(i + 1)) @@ -657,14 +665,14 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() var i = 1000 postbox.aroundMessageViewForPeerId(otherId, id: MessageId(peerId: otherId, namespace: messageNamespaceCloud, id: Int32(i + 1)), count: 3).start(next: { next in println(next) }) - postbox.modify { state in + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 10 ..< 15 { let messageId = MessageId(peerId: otherId, namespace: messageNamespaceCloud, id: Int32(i + 1)) @@ -672,7 +680,7 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() postbox._sync() } @@ -783,9 +791,9 @@ class PostboxTests: XCTestCase { let basePath = "/tmp/postboxtest" NSFileManager.defaultManager().removeItemAtPath(basePath, error: nil) - let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespace]) + let postbox = Postbox(basePath: basePath, messageNamespaces: [messageNamespace]) - postbox.modify { state in + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 0 ..< 10 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) @@ -793,7 +801,7 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() postbox.tailPeerView(3).start(next: { next in println(next) @@ -803,7 +811,7 @@ class PostboxTests: XCTestCase { println(next) }) - postbox.modify { state in + (postbox.modify { state -> Void in let testMedia = TestMedia(id: MediaId(namespace: TestMediaNamespace.Test.rawValue, id: 1)) for i in 10 ..< 15 { let messageId = MessageId(peerId: otherId, namespace: messageNamespace, id: Int32(i + 1)) @@ -811,7 +819,7 @@ class PostboxTests: XCTestCase { state.addMessages([message, message], medias: [testMedia]) } return - } + }).start() postbox._sync() }