diff --git a/MongoView.xcodeproj/project.pbxproj b/MongoView.xcodeproj/project.pbxproj index a7df9f4..4ae7d03 100644 --- a/MongoView.xcodeproj/project.pbxproj +++ b/MongoView.xcodeproj/project.pbxproj @@ -40,6 +40,7 @@ D63CDF4123C839010012D658 /* QueryViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D63CDF3F23C839010012D658 /* QueryViewController.xib */; }; D63CDF4423C970C50012D658 /* DatabaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63CDF4223C970C50012D658 /* DatabaseViewController.swift */; }; D63CDF4523C970C50012D658 /* DatabaseViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D63CDF4323C970C50012D658 /* DatabaseViewController.xib */; }; + D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -92,6 +93,7 @@ D63CDF3F23C839010012D658 /* QueryViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = QueryViewController.xib; sourceTree = ""; }; D63CDF4223C970C50012D658 /* DatabaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseViewController.swift; sourceTree = ""; }; D63CDF4323C970C50012D658 /* DatabaseViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DatabaseViewController.xib; sourceTree = ""; }; + D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MongoEvaluator.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -161,6 +163,7 @@ D63CDEBD23C837DC0012D658 /* AppDelegate.swift */, D63CDF3423C838190012D658 /* MongoController.swift */, D63CDF3323C838190012D658 /* Node.swift */, + D6D4665223CB730C00F13B1B /* MongoEvaluator.swift */, D60C863B23CA2DD600C9DB8E /* Windows */, D60C863C23CA2DDD00C9DB8E /* View Controllers */, D63CDEBF23C837DD0012D658 /* Assets.xcassets */, @@ -264,6 +267,7 @@ buildActionMask = 2147483647; files = ( D63CDEBE23C837DC0012D658 /* AppDelegate.swift in Sources */, + D6D4665323CB730C00F13B1B /* MongoEvaluator.swift in Sources */, D63CDF3823C8381A0012D658 /* MongoController.swift in Sources */, D60C863923CA2DD100C9DB8E /* ServerConnectWindowController.swift in Sources */, D63CDF3723C8381A0012D658 /* Node.swift in Sources */, diff --git a/MongoView/MongoEvaluator.swift b/MongoView/MongoEvaluator.swift new file mode 100644 index 0000000..82b4424 --- /dev/null +++ b/MongoView/MongoEvaluator.swift @@ -0,0 +1,84 @@ +// +// MongoEvaluator.swift +// MongoView +// +// Created by Shadowfacts on 1/12/20. +// Copyright © 2020 Shadowfacts. All rights reserved. +// + +import Foundation +import JavaScriptCore +import MongoSwift + +struct MongoEvaluator { + + static let context: JSContext = { + let context = JSContext()! + let date: @convention(block) (JSValue) -> Dictionary = { (input) in + ["$date": input] + } + let functions: [NSString: @convention(block) (JSValue) -> Dictionary] = [ + "ObjectId": { (input) in + ["$oid": input] + }, + "NumberLong": { (input) in + ["$numberLong": input] + }, + "NumberInt": { (input) in + ["$numberInt": input] + }, + "NumberDecimal": { (input) in + ["$numberDecimal": input] + }, + "Date": date, + "ISODate": date, + ] + functions.forEach { (key, value) in + context.setObject(value, forKeyedSubscript: key) + } + let dbRef: @convention(block) (String, String) -> Dictionary = { (ref, id) in + ["$ref": ref, "$id": ["$oid": id]] + } + context.setObject(dbRef, forKeyedSubscript: "DBRef" as NSString) + return context + }() + + static func parse(shellJSON: String) -> Document? { + guard !shellJSON.isEmpty, + let result = context.evaluateScript("JSON.stringify(\(shellJSON))") else { + return nil + } + do { + return try Document(fromJSON: result.toString()) + } catch { + print("Unable to parse Document: \(error)") + return nil + } + } + + static func eval(command: String, connectingTo connStr: String) -> [Document] { + print("Running command \"\(command)\" against \(connStr)") + + let mongoOutputPipe = Pipe() + + let mongoProcess = Process() + mongoProcess.launchPath = "/usr/local/bin/mongo" + mongoProcess.arguments = [connStr, "--quiet", "--norc", "--eval", command] + mongoProcess.standardOutput = mongoOutputPipe + mongoProcess.launch() + + let mongoOutputHandle = mongoOutputPipe.fileHandleForReading + + var strs = [String]() + var data: Data! + repeat { + data = mongoOutputHandle.availableData + strs.append(String(data: data, encoding: .utf8)!) + } while (data.count > 0) + mongoOutputHandle.closeFile() + + let lines = strs.joined(separator: "").components(separatedBy: "\n") + return lines.compactMap(parse(shellJSON:)) + } + +} diff --git a/MongoView/MongoView.entitlements b/MongoView/MongoView.entitlements index 625af03..0c67376 100644 --- a/MongoView/MongoView.entitlements +++ b/MongoView/MongoView.entitlements @@ -1,12 +1,5 @@ - - com.apple.security.app-sandbox - - com.apple.security.files.user-selected.read-only - - com.apple.security.network.client - - + diff --git a/MongoView/View Controllers/QueryViewController.swift b/MongoView/View Controllers/QueryViewController.swift index d100ac8..7517169 100644 --- a/MongoView/View Controllers/QueryViewController.swift +++ b/MongoView/View Controllers/QueryViewController.swift @@ -81,10 +81,13 @@ class QueryViewController: NSViewController { } func runQuery() { - print("run query: \(queryTextView.string)") -// mongoController.db.runCommand(["eval": .code(Code(code: queryTextView.string))]).whenComplete { (res) in -// print(res) -// } + let query = queryTextView.string + let connStr = "\(mongoController.connectionString)/\(collection.database)" + + rootNodes = MongoEvaluator.eval(command: query, connectingTo: connStr).map { + Node(document: $0) + } + outlineView.reloadData() } @objc func outlineCellDoubleClicked() {