A Mac app for working with Mongo databases.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

146 lines
4.0 KiB

//
// Node.swift
// MongoView
//
// Created by Shadowfacts on 1/9/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import Foundation
import MongoSwift
class Node {
let key: Key?
let value: BSON
lazy private(set) var children: [Node] = {
switch value {
case let .array(array):
return array.enumerated().map { (index, val) in
Node(key: .index(index), value: val)
}
case let .document(doc):
return doc.map { (key, val) in
Node(key: .name(key), value: val)
}
default:
return []
}
}()
var numberOfChildren: Int {
children.count
}
var hasChildren: Bool {
numberOfChildren > 0
}
init(key: Key? = nil, value: BSON) {
self.key = key
self.value = value
}
convenience init(document: Document) {
if case let .objectId(id) = document["_id"] {
self.init(key: .objectId(id), value: .document(document))
} else {
self.init(key: nil, value: .document(document))
}
}
}
extension Node {
enum Key {
case index(Int)
case name(String)
case objectId(ObjectId)
}
}
extension Node {
static let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.locale = .current
formatter.setLocalizedDateFormatFromTemplate("yyyy-MM-dd HH:mm:ss ZZ")
return formatter
}()
var keyString: String {
switch key {
case nil:
return ""
case let .index(index):
return index.description
case let .name(name):
return name
case let .objectId(id):
return id.description
}
}
var valueString: String {
switch value {
case let .double(value):
return value.description
case let .string(value):
return value
case let .document(doc):
return "(\(doc.count) field\(doc.count == 1 ? "" : "s"))"
case let .array(array):
return "(\(array.count) element\(array.count == 1 ? "" : "s"))"
case let .binary(value):
switch Binary.Subtype(rawValue: value.subtype) {
case nil:
return "(unknown binary data)"
case .generic:
return "(generic binary data)"
case .function:
return "(function binary data)"
case .binaryDeprecated:
return "(binary data)"
case .uuidDeprecated:
fallthrough
case .uuid:
return try! UUID(from: value).description
case .md5:
return "(MD5 binary data)"
case .userDefined:
return "(user defined binary data)"
}
case .undefined:
return "undefined"
case let .objectId(value):
return value.description
case let .bool(value):
return value.description
case let .datetime(value):
return value.description
case .null:
return "null"
case let .regex(value):
return try! NSRegularExpression(from: value).description
case let .dbPointer(value):
return "\(value.ref)(\(value.id))"
case let .symbol(value):
return value.description
case let .code(value):
return value.code
case let .codeWithScope(value):
return value.code
case let .int32(value):
return value.description
case let .timestamp(value):
let date = Date(timeIntervalSince1970: TimeInterval(value.timestamp))
return Node.dateFormatter.string(from: date)
case let .int64(value):
return value.description
case let .decimal128(value):
return value.description
case .minKey:
return "(min key)"
case .maxKey:
return "(max key)"
}
}
}