Browse Source

Use filter documents intead of shelling out to mongo every time

master
Shadowfacts 3 months ago
parent
commit
83cfba74a8
Signed by: Shadowfacts <me@shadowfacts.net> GPG Key ID: 94A5AB95422746E5

+ 4
- 0
MongoView.xcodeproj/project.pbxproj View File

@@ -12,6 +12,7 @@
12 12
 		D60C863F23CA2E2100C9DB8E /* ServerConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D60C863D23CA2E2100C9DB8E /* ServerConnectViewController.swift */; };
13 13
 		D60C864023CA2E2100C9DB8E /* ServerConnectViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D60C863E23CA2E2100C9DB8E /* ServerConnectViewController.xib */; };
14 14
 		D62408C12438CF550020E09F /* JavaScriptEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62408C02438CF550020E09F /* JavaScriptEditorView.swift */; };
15
+		D624090F243903E90020E09F /* ExtendedJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = D624090E243903E90020E09F /* ExtendedJSON.swift */; };
15 16
 		D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63CDEBD23C837DC0012D658 /* AppDelegate.swift */; };
16 17
 		D63CDEC023C837DD0012D658 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEBF23C837DD0012D658 /* Assets.xcassets */; };
17 18
 		D63CDEC323C837DD0012D658 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D63CDEC123C837DD0012D658 /* MainMenu.xib */; };
@@ -86,6 +87,7 @@
86 87
 		D60C863D23CA2E2100C9DB8E /* ServerConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConnectViewController.swift; sourceTree = "<group>"; };
87 88
 		D60C863E23CA2E2100C9DB8E /* ServerConnectViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ServerConnectViewController.xib; sourceTree = "<group>"; };
88 89
 		D62408C02438CF550020E09F /* JavaScriptEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JavaScriptEditorView.swift; sourceTree = "<group>"; };
90
+		D624090E243903E90020E09F /* ExtendedJSON.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtendedJSON.swift; sourceTree = "<group>"; };
89 91
 		D63CDEBA23C837DC0012D658 /* MongoView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MongoView.app; sourceTree = BUILT_PRODUCTS_DIR; };
90 92
 		D63CDEBD23C837DC0012D658 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
91 93
 		D63CDEBF23C837DD0012D658 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
@@ -204,6 +206,7 @@
204 206
 				D63CDF3423C838190012D658 /* MongoController.swift */,
205 207
 				D63CDF3323C838190012D658 /* Node.swift */,
206 208
 				D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */,
209
+				D624090E243903E90020E09F /* ExtendedJSON.swift */,
207 210
 				D6A7D0A22435880700B46857 /* Synax Highlighting */,
208 211
 				D60C863B23CA2DD600C9DB8E /* Windows */,
209 212
 				D60C863C23CA2DDD00C9DB8E /* View Controllers */,
@@ -348,6 +351,7 @@
348 351
 			files = (
349 352
 				D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */,
350 353
 				D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */,
354
+				D624090F243903E90020E09F /* ExtendedJSON.swift in Sources */,
351 355
 				D63CDF3823C8381A0012D658 /* MongoController.swift in Sources */,
352 356
 				D60C863923CA2DD100C9DB8E /* ServerConnectWindowController.swift in Sources */,
353 357
 				D63CDF3723C8381A0012D658 /* Node.swift in Sources */,

+ 2
- 10
MongoView/Base.lproj/MainMenu.xib View File

@@ -1,7 +1,7 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16085" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
2
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16096" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
3 3
     <dependencies>
4
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16085"/>
4
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16096"/>
5 5
     </dependencies>
6 6
     <objects>
7 7
         <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
@@ -368,14 +368,6 @@
368 368
                                     <action selector="refresh:" target="-1" id="S5L-sX-Z2j"/>
369 369
                                 </connections>
370 370
                             </menuItem>
371
-                            <menuItem title="Run Query" id="RSP-nH-a1I">
372
-                                <string key="keyEquivalent" base64-UTF8="YES">
373
-DQ
374
-</string>
375
-                                <connections>
376
-                                    <action selector="runQuery:" target="-1" id="jLo-qu-WjN"/>
377
-                                </connections>
378
-                            </menuItem>
379 371
                         </items>
380 372
                     </menu>
381 373
                 </menuItem>

+ 28
- 0
MongoView/ExtendedJSON.swift View File

@@ -0,0 +1,28 @@
1
+//
2
+//  ExtendedJSON.swift
3
+//  MongoView
4
+//
5
+//  Created by Shadowfacts on 4/4/20.
6
+//  Copyright © 2020 Shadowfacts. All rights reserved.
7
+//
8
+
9
+import Foundation
10
+import JavaScriptCore
11
+
12
+struct ExtendedJSON {
13
+    private init() {}
14
+    
15
+    private static let context: JSContext = {
16
+        let context = JSContext()!
17
+        let objectId: @convention(block) (String) -> [String: String] = { (id) in
18
+            return ["$oid": id]
19
+        }
20
+        context.setObject(objectId, forKeyedSubscript: "ObjectId" as NSString)
21
+        return context
22
+    }()
23
+    
24
+    static func normalize(_ string: String) -> String? {
25
+        return context.evaluateScript("JSON.stringify(\(string))")?.toString()
26
+    }
27
+    
28
+}

+ 2
- 6
MongoView/View Controllers/DatabaseViewController.swift View File

@@ -140,7 +140,7 @@ class DatabaseViewController: NSViewController {
140 140
             }
141 141
         } else if let collection = item as? DatabaseCollection {
142 142
             // only open a new window/tab if our own query has changed from the default, otherwise replace our query controller
143
-            if let queryViewController = queryViewController, queryViewController.hasQueryChanged {
143
+            if let queryViewController = queryViewController, queryViewController.hasFilterChanged {
144 144
                 (NSApplication.shared.delegate as! AppDelegate).newWindow(mongoController: mongoController, collection: collection)
145 145
             } else {
146 146
                 self.selectedCollection = collection
@@ -149,10 +149,6 @@ class DatabaseViewController: NSViewController {
149 149
         }
150 150
     }
151 151
 
152
-    @IBAction func runQuery(_ sender: Any) {
153
-        queryViewController?.runQuery()
154
-    }
155
-    
156 152
     @IBAction func refresh(_ sender: Any) {
157 153
         queryViewController?.refresh()
158 154
     }
@@ -160,7 +156,7 @@ class DatabaseViewController: NSViewController {
160 156
 
161 157
 extension DatabaseViewController: NSMenuItemValidation {
162 158
     func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
163
-        if menuItem.action == #selector(runQuery(_:)) || menuItem.action == #selector(refresh(_:)) {
159
+        if menuItem.action == #selector(refresh(_:)) {
164 160
             return queryViewController != nil
165 161
         }
166 162
         return true

+ 22
- 27
MongoView/View Controllers/QueryViewController.swift View File

@@ -12,19 +12,19 @@ import MongoSwift
12 12
 class QueryViewController: NSViewController {
13 13
 
14 14
     @IBOutlet weak var verticalSplitView: NSSplitView!
15
-    @IBOutlet var queryTextView: JavaScriptEditorView!
15
+    @IBOutlet var filterTextView: JavaScriptEditorView!
16 16
     @IBOutlet weak var outlineView: NSOutlineView!
17 17
     @IBOutlet weak var documentCountLabel: NSTextField!
18 18
     
19 19
     let mongoController: MongoController
20 20
     let collection: DatabaseCollection
21 21
     
22
-    var defaultQuery: String {
23
-        "db.getCollection('\(collection.name)').find({}).toArray()"
22
+    var defaultFilter: String {
23
+        "{}"
24 24
     }
25 25
     
26
-    var hasQueryChanged: Bool {
27
-        return queryTextView.string != defaultQuery
26
+    var hasFilterChanged: Bool {
27
+        return filterTextView.string != defaultFilter
28 28
     }
29 29
     
30 30
     var mostRecentQuery: String? = nil
@@ -50,9 +50,9 @@ class QueryViewController: NSViewController {
50 50
         verticalSplitView.delegate = self
51 51
         verticalSplitView.setHoldingPriority(.defaultHigh, forSubviewAt: 0)
52 52
         
53
-        queryTextView.font = .monospacedSystemFont(ofSize: 13, weight: .regular)
54
-        queryTextView.isAutomaticQuoteSubstitutionEnabled = false
55
-        queryTextView.string = defaultQuery
53
+        filterTextView.font = .monospacedSystemFont(ofSize: 13, weight: .regular)
54
+        filterTextView.isAutomaticQuoteSubstitutionEnabled = false
55
+        filterTextView.string = defaultFilter
56 56
 
57 57
         outlineView.dataSource = self
58 58
         outlineView.delegate = self
@@ -77,32 +77,27 @@ class QueryViewController: NSViewController {
77 77
     }
78 78
 
79 79
     func refresh(reload: Bool = true) {
80
-        if let query = mostRecentQuery {
81
-            let connStr = "\(mongoController.connectionString)/\(collection.database)"
82
-            
83
-            rootNodes = MongoEvaluator.eval(command: query, connectingTo: connStr).map {
84
-                Node(value: $0)
85
-            }
86
-            
87
-            title = query
88
-            documentCountLabel.stringValue = "\(rootNodes.count) result\(rootNodes.count == 1 ? "" : "s")"
80
+        let filterText = filterTextView.string.trimmingCharacters(in: .whitespacesAndNewlines)
81
+        let filter: Document
82
+        if !filterText.isEmpty,
83
+            let normalized = ExtendedJSON.normalize(filterText),
84
+            let doc = try? Document(fromJSON: normalized) {
85
+            filter = doc
89 86
         } else {
90
-            let documents = try! mongoController.collection(collection).find().all()
91
-            rootNodes = documents.map { Node(document: $0) }
92
-
93
-            title = "\(self.collection.database).\(self.collection.name)"
94
-            documentCountLabel.stringValue = "\(documents.count) document\(documents.count == 1 ? "" : "s")"
87
+            filter = [:]
95 88
         }
89
+        
90
+        let documents = try! mongoController.collection(collection).find(filter).all()
91
+        rootNodes = documents.map { Node(document: $0) }
92
+
93
+        title = "\(self.collection.database).\(self.collection.name)"
94
+        documentCountLabel.stringValue = "\(documents.count) document\(documents.count == 1 ? "" : "s")"
95
+        
96 96
         if reload {
97 97
             outlineView.reloadData()
98 98
         }
99 99
     }
100 100
     
101
-    func runQuery() {
102
-        mostRecentQuery = queryTextView.string
103
-        refresh()
104
-    }
105
-    
106 101
     func deleteRootNode(_ node: Node) {
107 102
         guard case let .document(doc) = node.value else { return }
108 103
         let alert = NSAlert()

+ 1
- 1
MongoView/View Controllers/QueryViewController.xib View File

@@ -8,8 +8,8 @@
8 8
         <customObject id="-2" userLabel="File's Owner" customClass="QueryViewController" customModule="MongoView" customModuleProvider="target">
9 9
             <connections>
10 10
                 <outlet property="documentCountLabel" destination="bwd-po-tUv" id="5Ip-AZ-nVc"/>
11
+                <outlet property="filterTextView" destination="f8D-lV-IMK" id="dq6-lR-LeP"/>
11 12
                 <outlet property="outlineView" destination="uu9-9q-MWr" id="BEH-jX-h0S"/>
12
-                <outlet property="queryTextView" destination="f8D-lV-IMK" id="dq6-lR-LeP"/>
13 13
                 <outlet property="verticalSplitView" destination="E3D-CM-hk3" id="3Ks-1t-OFW"/>
14 14
                 <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
15 15
             </connections>

Loading…
Cancel
Save