Skip to content

Instantly share code, notes, and snippets.

@mbalex99
Created June 22, 2023 20:53
Show Gist options
  • Save mbalex99/b52ff09a376db18bcf243a91265d4f5e to your computer and use it in GitHub Desktop.
Save mbalex99/b52ff09a376db18bcf243a91265d4f5e to your computer and use it in GitHub Desktop.
How to Do SQL-like JOINs in Ditto
class DittoManager {
let ditto: Ditto
static let shared = DittoManager()
init() {
ditto = Ditto(identity: .onlinePlayground(appID: "e23ffe6b-70d1-4246-83a8-94cbd7a79a8d", token: "f058ac2a-4576-4af1-96f2-c4788d848cf8"))
try! ditto.startSync()
}
func users() -> AnyPublisher<[User], Never> {
return self.ditto.store["users"]
.findAll()
.sort("emailVerified", direction: .descending)
.liveQueryPublisher()
.map({ $0.documents.map{ User.fromDittoDocument($0) } })
.eraseToAnyPublisher()
}
func sessions(userId: String? = nil) -> AnyPublisher<[Session], Never> {
guard let userId = userId else {
return self.ditto.store["sessions"].findAll()
.sort("expires", direction: .ascending)
.liveQueryPublisher()
.map({ $0.documents.map({ Session.fromDittoDocument($0 )}) })
.eraseToAnyPublisher()
}
return self.ditto.store["sessions"]
.find("userId == $args.userId", args: ["userId": userId])
.sort("expires", direction: .ascending)
.liveQueryPublisher()
.map({ $0.documents.map({ Session.fromDittoDocument($0 )}) })
.eraseToAnyPublisher()
}
func userWithSessions(userId: String) -> AnyPublisher<UserWithSessions, Never> {
let user = users()
.compactMap({ $0.filter({ $0._id == userId }).first })
.eraseToAnyPublisher()
return user.combineLatest(sessions(userId: userId))
.map({ user, sessions in
return UserWithSessions(user: user, sessions: sessions)
})
.eraseToAnyPublisher()
}
}
import Foundation
import DittoSwift
var isoDateFormatter: ISO8601DateFormatter {
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
return formatter
}
struct User: Hashable, Equatable {
var _id: String
var email: String
/**
* The date when the email was verified
*/
var emailVerified: Date?
static func fromDittoDocument(_ document: DittoDocument) -> Self {
var emailVerified: Date? = nil
if let emailVerifiedISOString = document["emailVerified"].string {
emailVerified = isoDateFormatter.date(from: emailVerifiedISOString)
}
return User(_id: document["_id"].stringValue, email: document["email"].stringValue, emailVerified: emailVerified)
}
}
extension User: Identifiable {
var id: String {
return _id
}
}
struct Session: Equatable, Hashable {
var _id: String
var expires: Date?
var sessionToken: String
var userId: String
static func fromDittoDocument(_ document: DittoDocument) -> Self {
var expires: Date? = nil
if let expiresVerifiedISOString = document["expires"].string {
expires = isoDateFormatter.date(from: expiresVerifiedISOString)
}
return Session(
_id: document["_id"].stringValue,
expires: expires,
sessionToken: document["sessionToken"].stringValue,
userId: document["userId"].stringValue
)
}
}
extension Session: Identifiable {
var id: String {
return _id
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment