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.
 

166 lines
5.4 KiB

//
// QueryViewController.swift
// MongoView
//
// Created by Shadowfacts on 1/9/20.
// Copyright © 2020 Shadowfacts. All rights reserved.
//
import Cocoa
import MongoSwift
class QueryViewController: NSViewController {
@IBOutlet weak var verticalSplitView: NSSplitView!
@IBOutlet var queryTextView: NSTextView!
@IBOutlet weak var outlineView: NSOutlineView!
@IBOutlet weak var documentCountLabel: NSTextField!
let mongoController: MongoController
let collection: DatabaseCollection
var defaultQuery: String {
"db.getCollection('\(collection.name)').find({})"
}
var hasQueryChanged: Bool {
return queryTextView.string != defaultQuery
}
var rootNodes: [Node] = []
init(mongoController: MongoController, collection: DatabaseCollection) {
self.mongoController = mongoController
self.collection = collection
super.init(nibName: "QueryViewController", bundle: .main)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
let db = mongoController.client.db(collection.database)
let collection = db.collection(self.collection.name)
let documents = try! collection.find().all()
rootNodes = documents.map { Node(document: $0) }
verticalSplitView.delegate = self
verticalSplitView.setHoldingPriority(.defaultHigh, forSubviewAt: 0)
queryTextView.font = .monospacedSystemFont(ofSize: 13, weight: .regular)
queryTextView.isAutomaticQuoteSubstitutionEnabled = false
queryTextView.string = defaultQuery
outlineView.dataSource = self
outlineView.delegate = self
outlineView.target = self
outlineView.doubleAction = #selector(outlineCellDoubleClicked)
title = "\(self.collection.database).\(self.collection.name)"
documentCountLabel.stringValue = "\(documents.count) document\(documents.count == 1 ? "" : "s")"
}
override func viewWillAppear() {
super.viewWillAppear()
verticalSplitView.setPosition(80, ofDividerAt: 0)
}
override func viewDidAppear() {
super.viewDidAppear()
view.window!.makeFirstResponder(outlineView)
}
func runQuery() {
print("run query: \(queryTextView.string)")
// mongoController.db.runCommand(["eval": .code(Code(code: queryTextView.string))]).whenComplete { (res) in
// print(res)
// }
}
@objc func outlineCellDoubleClicked() {
if let item = outlineView.item(atRow: outlineView.clickedRow) {
if outlineView.isItemExpanded(item) {
outlineView.collapseItem(item)
} else {
outlineView.expandItem(item)
}
}
}
}
extension QueryViewController: NSSplitViewDelegate {
func splitView(_ splitView: NSSplitView, constrainSplitPosition proposedPosition: CGFloat, ofSubviewAt dividerIndex: Int) -> CGFloat {
return max(80, min(splitView.bounds.height / 2, proposedPosition))
}
}
extension QueryViewController: NSOutlineViewDataSource {
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
if item == nil {
return rootNodes.count
} else if let node = item as? Node {
return node.numberOfChildren
} else {
return 0
}
}
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
if let node = item as? Node {
return node.hasChildren
} else {
return false
}
}
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
if item == nil {
return rootNodes[index]
} else if let node = item as? Node {
return node.children[index]
} else {
fatalError("unreachable")
}
}
}
extension QueryViewController: NSOutlineViewDelegate {
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
guard let tableColumn = tableColumn,
let node = item as? Node else {
fatalError()
}
if tableColumn.identifier == .fieldNameColumn {
let cell = outlineView.makeView(withIdentifier: .fieldNameCell, owner: nil) as! NSTableCellView
cell.textField!.stringValue = node.keyString
cell.textField!.isEditable = false
return cell
} else if tableColumn.identifier == .fieldValueColumn {
let cell = outlineView.makeView(withIdentifier: .fieldValueCell, owner: nil) as! NSTableCellView
cell.textField!.stringValue = node.valueString
cell.textField!.isEditable = false
return cell
} else {
return nil
}
}
}
extension NSUserInterfaceItemIdentifier {
static let fieldNameColumn = NSUserInterfaceItemIdentifier(rawValue: "FieldNameCol")
static let fieldValueColumn = NSUserInterfaceItemIdentifier(rawValue: "FieldValueCol")
static let fieldNameCell = NSUserInterfaceItemIdentifier(rawValue: "FieldNameCell")
static let fieldValueCell = NSUserInterfaceItemIdentifier(rawValue: "FieldValueCell")
}