Use filter documents intead of shelling out to mongo every time
This commit is contained in:
parent
9e258b71f4
commit
83cfba74a8
|
@ -12,6 +12,7 @@
|
|||
D60C863F23CA2E2100C9DB8E /* ServerConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60C863D23CA2E2100C9DB8E /* ServerConnectViewController.swift */; };
|
||||
D60C864023CA2E2100C9DB8E /* ServerConnectViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D60C863E23CA2E2100C9DB8E /* ServerConnectViewController.xib */; };
|
||||
D62408C12438CF550020E09F /* JavaScriptEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62408C02438CF550020E09F /* JavaScriptEditorView.swift */; };
|
||||
D624090F243903E90020E09F /* ExtendedJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = D624090E243903E90020E09F /* ExtendedJSON.swift */; };
|
||||
D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63CDEBD23C837DC0012D658 /* AppDelegate.swift */; };
|
||||
D63CDEC023C837DD0012D658 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEBF23C837DD0012D658 /* Assets.xcassets */; };
|
||||
D63CDEC323C837DD0012D658 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEC123C837DD0012D658 /* MainMenu.xib */; };
|
||||
|
@ -86,6 +87,7 @@
|
|||
D60C863D23CA2E2100C9DB8E /* ServerConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConnectViewController.swift; sourceTree = "<group>"; };
|
||||
D60C863E23CA2E2100C9DB8E /* ServerConnectViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ServerConnectViewController.xib; sourceTree = "<group>"; };
|
||||
D62408C02438CF550020E09F /* JavaScriptEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptEditorView.swift; sourceTree = "<group>"; };
|
||||
D624090E243903E90020E09F /* ExtendedJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedJSON.swift; sourceTree = "<group>"; };
|
||||
D63CDEBA23C837DC0012D658 /* MongoView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MongoView.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D63CDEBD23C837DC0012D658 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
D63CDEBF23C837DD0012D658 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
|
@ -204,6 +206,7 @@
|
|||
D63CDF3423C838190012D658 /* MongoController.swift */,
|
||||
D63CDF3323C838190012D658 /* Node.swift */,
|
||||
D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */,
|
||||
D624090E243903E90020E09F /* ExtendedJSON.swift */,
|
||||
D6A7D0A22435880700B46857 /* Synax Highlighting */,
|
||||
D60C863B23CA2DD600C9DB8E /* Windows */,
|
||||
D60C863C23CA2DDD00C9DB8E /* View Controllers */,
|
||||
|
@ -348,6 +351,7 @@
|
|||
files = (
|
||||
D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */,
|
||||
D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */,
|
||||
D624090F243903E90020E09F /* ExtendedJSON.swift in Sources */,
|
||||
D63CDF3823C8381A0012D658 /* MongoController.swift in Sources */,
|
||||
D60C863923CA2DD100C9DB8E /* ServerConnectWindowController.swift in Sources */,
|
||||
D63CDF3723C8381A0012D658 /* Node.swift in Sources */,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16085" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16085"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
|
@ -368,14 +368,6 @@
|
|||
<action selector="refresh:" target="-1" id="S5L-sX-Z2j"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Run Query" id="RSP-nH-a1I">
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
<connections>
|
||||
<action selector="runQuery:" target="-1" id="jLo-qu-WjN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// ExtendedJSON.swift
|
||||
// MongoView
|
||||
//
|
||||
// Created by Shadowfacts on 4/4/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import JavaScriptCore
|
||||
|
||||
struct ExtendedJSON {
|
||||
private init() {}
|
||||
|
||||
private static let context: JSContext = {
|
||||
let context = JSContext()!
|
||||
let objectId: @convention(block) (String) -> [String: String] = { (id) in
|
||||
return ["$oid": id]
|
||||
}
|
||||
context.setObject(objectId, forKeyedSubscript: "ObjectId" as NSString)
|
||||
return context
|
||||
}()
|
||||
|
||||
static func normalize(_ string: String) -> String? {
|
||||
return context.evaluateScript("JSON.stringify(\(string))")?.toString()
|
||||
}
|
||||
|
||||
}
|
|
@ -140,7 +140,7 @@ class DatabaseViewController: NSViewController {
|
|||
}
|
||||
} else if let collection = item as? DatabaseCollection {
|
||||
// only open a new window/tab if our own query has changed from the default, otherwise replace our query controller
|
||||
if let queryViewController = queryViewController, queryViewController.hasQueryChanged {
|
||||
if let queryViewController = queryViewController, queryViewController.hasFilterChanged {
|
||||
(NSApplication.shared.delegate as! AppDelegate).newWindow(mongoController: mongoController, collection: collection)
|
||||
} else {
|
||||
self.selectedCollection = collection
|
||||
|
@ -149,10 +149,6 @@ class DatabaseViewController: NSViewController {
|
|||
}
|
||||
}
|
||||
|
||||
@IBAction func runQuery(_ sender: Any) {
|
||||
queryViewController?.runQuery()
|
||||
}
|
||||
|
||||
@IBAction func refresh(_ sender: Any) {
|
||||
queryViewController?.refresh()
|
||||
}
|
||||
|
@ -160,7 +156,7 @@ class DatabaseViewController: NSViewController {
|
|||
|
||||
extension DatabaseViewController: NSMenuItemValidation {
|
||||
func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
|
||||
if menuItem.action == #selector(runQuery(_:)) || menuItem.action == #selector(refresh(_:)) {
|
||||
if menuItem.action == #selector(refresh(_:)) {
|
||||
return queryViewController != nil
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -12,19 +12,19 @@ import MongoSwift
|
|||
class QueryViewController: NSViewController {
|
||||
|
||||
@IBOutlet weak var verticalSplitView: NSSplitView!
|
||||
@IBOutlet var queryTextView: JavaScriptEditorView!
|
||||
@IBOutlet var filterTextView: JavaScriptEditorView!
|
||||
@IBOutlet weak var outlineView: NSOutlineView!
|
||||
@IBOutlet weak var documentCountLabel: NSTextField!
|
||||
|
||||
let mongoController: MongoController
|
||||
let collection: DatabaseCollection
|
||||
|
||||
var defaultQuery: String {
|
||||
"db.getCollection('\(collection.name)').find({}).toArray()"
|
||||
var defaultFilter: String {
|
||||
"{}"
|
||||
}
|
||||
|
||||
var hasQueryChanged: Bool {
|
||||
return queryTextView.string != defaultQuery
|
||||
var hasFilterChanged: Bool {
|
||||
return filterTextView.string != defaultFilter
|
||||
}
|
||||
|
||||
var mostRecentQuery: String? = nil
|
||||
|
@ -50,9 +50,9 @@ class QueryViewController: NSViewController {
|
|||
verticalSplitView.delegate = self
|
||||
verticalSplitView.setHoldingPriority(.defaultHigh, forSubviewAt: 0)
|
||||
|
||||
queryTextView.font = .monospacedSystemFont(ofSize: 13, weight: .regular)
|
||||
queryTextView.isAutomaticQuoteSubstitutionEnabled = false
|
||||
queryTextView.string = defaultQuery
|
||||
filterTextView.font = .monospacedSystemFont(ofSize: 13, weight: .regular)
|
||||
filterTextView.isAutomaticQuoteSubstitutionEnabled = false
|
||||
filterTextView.string = defaultFilter
|
||||
|
||||
outlineView.dataSource = self
|
||||
outlineView.delegate = self
|
||||
|
@ -77,32 +77,27 @@ class QueryViewController: NSViewController {
|
|||
}
|
||||
|
||||
func refresh(reload: Bool = true) {
|
||||
if let query = mostRecentQuery {
|
||||
let connStr = "\(mongoController.connectionString)/\(collection.database)"
|
||||
|
||||
rootNodes = MongoEvaluator.eval(command: query, connectingTo: connStr).map {
|
||||
Node(value: $0)
|
||||
let filterText = filterTextView.string.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let filter: Document
|
||||
if !filterText.isEmpty,
|
||||
let normalized = ExtendedJSON.normalize(filterText),
|
||||
let doc = try? Document(fromJSON: normalized) {
|
||||
filter = doc
|
||||
} else {
|
||||
filter = [:]
|
||||
}
|
||||
|
||||
title = query
|
||||
documentCountLabel.stringValue = "\(rootNodes.count) result\(rootNodes.count == 1 ? "" : "s")"
|
||||
} else {
|
||||
let documents = try! mongoController.collection(collection).find().all()
|
||||
let documents = try! mongoController.collection(collection).find(filter).all()
|
||||
rootNodes = documents.map { Node(document: $0) }
|
||||
|
||||
title = "\(self.collection.database).\(self.collection.name)"
|
||||
documentCountLabel.stringValue = "\(documents.count) document\(documents.count == 1 ? "" : "s")"
|
||||
}
|
||||
|
||||
if reload {
|
||||
outlineView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
func runQuery() {
|
||||
mostRecentQuery = queryTextView.string
|
||||
refresh()
|
||||
}
|
||||
|
||||
func deleteRootNode(_ node: Node) {
|
||||
guard case let .document(doc) = node.value else { return }
|
||||
let alert = NSAlert()
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
<customObject id="-2" userLabel="File's Owner" customClass="QueryViewController" customModule="MongoView" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="documentCountLabel" destination="bwd-po-tUv" id="5Ip-AZ-nVc"/>
|
||||
<outlet property="filterTextView" destination="f8D-lV-IMK" id="dq6-lR-LeP"/>
|
||||
<outlet property="outlineView" destination="uu9-9q-MWr" id="BEH-jX-h0S"/>
|
||||
<outlet property="queryTextView" destination="f8D-lV-IMK" id="dq6-lR-LeP"/>
|
||||
<outlet property="verticalSplitView" destination="E3D-CM-hk3" id="3Ks-1t-OFW"/>
|
||||
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
|
||||
</connections>
|
||||
|
|
Loading…
Reference in New Issue