Compare commits

...
392 Commits
Author SHA1 Message Date
Gokhan Simsek 86509495f3 Update changelog for v1.4.2 2020-10-20 16:58:18 +03:00
Gokhan Simsek 086e6b7d21 Update version to 1.4.2 2020-10-20 11:11:13 +03:00
Gokhan Simsek f47afbddc8 #1694: Attempt to fix broken paging in DocumentDB 2020-10-20 11:07:22 +03:00
Gokhan Simsek 14f545ff45 Adding trimmed results 2020-09-27 22:02:26 +03:00
Gökhan Şimşek bf09a3d9c6 Update build_scan-build 2020-09-27 18:55:55 +03:00
Gökhan Şimşek 93cadb5a6b Update configure_scan-build 2020-09-27 18:55:20 +03:00
Gökhan Şimşek 0dd68201f6 Update CHANGELOG 2020-09-15 15:38:43 +03:00
Gökhan Şimşek ba646c4ac0 Update README.md 2020-09-11 11:04:17 +03:00
Gökhan Şimşek 46c50d2aa7 Update README.md 2020-09-11 11:01:48 +03:00
Gokhan Simsek 122dbd953c Generate cmake error when BUILD_NUMBER is empty 2020-09-09 18:23:41 +03:00
Gokhan Simsek a0c7666e4e Import from 1.4.0 2020-09-09 17:31:03 +03:00
Gokhan Simsek 4185b0b19a Patch 1.4.1 2020-09-09 17:30:52 +03:00
Gokhan Simsek a9478b95cc Minor change 2020-09-09 17:14:19 +03:00
Gokhan Simsek c68933f445 #1766: Adding native styles for Windows and macOS 2020-09-09 12:00:18 +03:00
Gokhan Simsek e7dd60c036 #1761 #1768 #1771: macOS: Forcing light mode 2020-09-09 11:58:21 +03:00
Gokhan Simsek 17ca161e55 Minor UI fix 2020-09-09 11:32:39 +03:00
Gokhan Simsek e66f627407 #1766: Windows: Attempt to fix broken native theme 2020-09-09 11:32:20 +03:00
Gokhan Simsek c39312356e AboutDialog: Adding build number 2020-09-09 10:45:18 +03:00
Gökhan Şimşek ac8afdd98f Update CHANGELOG 2020-09-04 16:38:33 +03:00
Gokhan Simsek 21e067937a Linux: Adding libstdc++ shared lib 2020-09-04 11:02:38 +03:00
Gokhan Simsek 12e54ccda9 #1757: Disabling IPv6 due to unexpected behaviors 2020-09-03 14:12:14 +03:00
Gokhan Simsek e658a7b293 Adding clang-tidy results 2020-08-31 11:51:33 +03:00
Gökhan Şimşek 49478e873d Update README.md 2020-08-28 10:13:47 +03:00
Gökhan Şimşek 30efcb2a68 Update README.md 2020-08-27 14:37:01 +03:00
Gökhan Şimşek 7866fde20d Update README.md 2020-08-27 14:32:00 +03:00
Gökhan Şimşek 30e903eec0 Update README.md 2020-08-27 14:28:00 +03:00
Gökhan Şimşek d9dedd37ee Update README.md 2020-08-27 14:26:58 +03:00
Gökhan Şimşek 61d4ea742f Update README.md 2020-08-27 14:26:20 +03:00
Gökhan Şimşek 02594f4dea Update README.md 2020-08-27 14:25:36 +03:00
Gokhan Simsek a61e33cad9 macOS: Adding scan-build output 2020-08-24 09:21:12 +03:00
Gokhan Simsek 347edc4b62 Windows: Adding visual studio RunCodeAnalysis script and some of its results with various rules 2020-08-21 18:16:49 +03:00
Gokhan Simsek 728f29152f macOS: Adding scan-build scripts 2020-08-21 17:21:12 +03:00
Gökhan Şimşek fdde4da323 Update BuildRobo3TOnWindows.md 2020-08-18 11:58:30 +03:00
Gökhan Şimşek 31bcd3609b Update BuildRobo3TOnMacAndLinux.md 2020-08-18 11:56:56 +03:00
Gokhan Simsek ef4b8cd27b Update Bar: Minor change 2020-08-18 10:07:44 +03:00
Gokhan Simsek dcfc524ad7 Spell check 2020-08-18 10:07:29 +03:00
Gokhan Simsek 5c161325bb MainWindow: Updating endpoint URL for updates bar 2020-08-16 13:27:05 +03:00
Gokhan Simsek cd02e61710 WelcomeTab: Updating image and content URLs 2020-08-16 11:53:38 +03:00
Gökhan Şimşek 1ee2e7cd9d Update CHANGELOG 2020-08-12 10:38:26 +03:00
Gokhan Simsek a92edc9fa7 Small update 2020-08-12 09:54:56 +03:00
Gokhan Simsek 3eb03362a4 #1714, #1653: Attempt to fix previously broken IPv6 support 2020-08-07 16:31:37 +03:00
Gokhan Simsek aaf9794491 Minor change 2020-08-07 16:26:20 +03:00
Gokhan Simsek ffe519248f Linux: Run from install dir 2020-08-07 12:08:56 +03:00
Gokhan Simsek ecdc0164ee Changing URL for updates and minor refactoring 2020-08-07 12:07:49 +03:00
Gokhan Simsek 2dd7dccaca Minor change 2020-08-04 12:13:05 +03:00
Gokhan Simsek d5780a018a Adding debugLog() function 2020-08-04 12:12:53 +03:00
Gokhan Simsek 7a8b4413fc Adding user controlled debugMode flag into config file 2020-08-04 12:11:59 +03:00
Gokhan Simsek b598062db6 WelcomeTab: Decreasing header font sizes 2020-08-04 10:00:42 +03:00
Gokhan Simsek 78187f9d6d #1685: Adding feature (config file flag) "disableHttpsFeatures", removing "useHttps". 2020-07-31 15:50:11 +03:00
Gokhan Simsek e6c070d469 #1685: Changing all HTTP post/request to HTTPS. 2020-07-31 15:48:09 +03:00
Gökhan Şimşek 750fd9d500 Update BuildRobo3TOnWindows.md 2020-07-30 15:07:51 +03:00
Gökhan Şimşek 9f5e755037 Update BuildRobo3TOnMacAndLinux.md 2020-07-30 15:07:24 +03:00
Gökhan Şimşek f43e7e3665 Update RuntimeDependencies.md 2020-07-30 14:12:22 +03:00
Gökhan Şimşek fc35ae44dd Update BuildRobo3TOnWindows.md 2020-07-27 20:13:33 +03:00
Gökhan Şimşek 805842ae96 Update BuildRobo3TOnWindows.md 2020-07-27 20:10:45 +03:00
Gokhan Simsek fc925444d8 #1696: Attempt to fix the problem when connected with a user defined on a non-admin auth. db, only auth db is shown 2020-07-17 18:47:49 +03:00
Gokhan Simsek 6163b7f7e3 Adding vectorContains() generic helper function 2020-07-15 15:26:24 +03:00
Gokhan Simsek 2dcbc0f5e9 Using manuallyVisibleDbs whether there is an exception or not 2020-07-15 15:25:02 +03:00
Gokhan Simsek 3c05095538 Code review of all Robo 1.4 changes 2020-07-15 10:24:51 +03:00
Gokhan Simsek 27c2bddc5c Adding dependencies into About dialog 2020-07-14 14:55:22 +03:00
Gokhan Simsek 2303d8a547 Minor change 2020-07-14 14:45:23 +03:00
Gökhan Şimşek 03a125e02d Update README.md 2020-07-14 09:59:57 +03:00
Gokhan Simsek 04f4fb4281 Adding esprima info 2020-07-14 09:59:15 +03:00
Gokhan Simsek fd66b3561c Minor refactoring 2020-07-14 09:50:54 +03:00
Gokhan Simsek cb4514e72c Minor change 2020-07-08 16:35:43 +03:00
Gokhan Simsek 27a4ec14c7 Attempt to fix cropped From SRV button text for Win 10 HiDPI 2020-07-08 16:35:18 +03:00
Gökhan Şimşek aa3ebd1f7f Update BuildRobo3TOnMacAndLinux.md 2020-07-08 10:13:43 +03:00
Gokhan Simsek f459a4aacb Merge branch 'master' of https://github.com/Studio3T/robomongo 2020-07-06 18:12:19 +03:00
Gökhan Şimşek 418b47ba3c Update BuildRobo3TOnMacAndLinux.md 2020-07-06 18:05:16 +03:00
Gokhan Simsek 393d09df0d SSH: Adding supported keys info text 2020-07-06 17:41:36 +03:00
Gökhan Şimşek 115d4b582a Update BuildRobo3TOnMacAndLinux.md 2020-07-06 17:39:32 +03:00
Gökhan Şimşek 1c5663dd83 Update RuntimeDependencies.md 2020-07-06 17:37:44 +03:00
Gokhan Simsek 8050e638a9 Open connection settings window relative to parent (connections window) and remember its size 2020-07-02 17:10:48 +03:00
Gökhan Şimşek eb58b93173 Update RuntimeDependencies.md 2020-07-01 10:20:07 +03:00
Gökhan Şimşek 99486802ef Update RuntimeDependencies.md 2020-07-01 10:18:46 +03:00
Gokhan Simsek 6c52d4df9b Updating build diagram 2020-06-30 18:36:39 +03:00
Gokhan Simsek 269e47a249 Disabling a warning 2020-06-30 12:18:59 +03:00
Gökhan Şimşek 5753989b79 Update BuildRobo3TOnMacAndLinux.md 2020-06-30 10:48:04 +03:00
Gokhan Simsek 466be55df4 Updating build diagram 2020-06-30 10:01:01 +03:00
Gökhan Şimşek 74f30b87ad Update BuildRobo3TOnWindows.md 2020-06-29 16:41:23 +03:00
Gökhan Şimşek 63d70483aa Update BuildRobo3TOnMacAndLinux.md 2020-06-29 16:31:14 +03:00
Gokhan Simsek 6b0eaecdf1 #1719, #1530, #1590: For Windows, macOS: Upgrading libssh2 to latest version (v1.9.0) which adds support for ECDSA and ED25519 keys. 2020-06-29 12:12:29 +03:00
Gokhan Simsek 9049457543 Adding version number for third-party libs 2020-06-25 11:48:48 +03:00
Gokhan Simsek f6ac157993 #1728: Removing an obsolete function which caused crash when Users folder expanded and minor refactoring 2020-06-24 17:45:45 +03:00
Gokhan Simsek e7cd0b65d6 Minor refactoring 2020-06-23 10:07:37 +03:00
Gokhan Simsek 8b8b0a1b8c Adding more logging and minor refactoring 2020-06-23 10:03:27 +03:00
Gokhan Simsek 8dae0b7973 Minor change 2020-06-19 11:10:15 +03:00
Gokhan Simsek d1d54c50d7 Adding function sendLog() 2020-06-19 10:24:55 +03:00
Gokhan Simsek 4f82013a55 Minor refactoring 2020-06-18 15:48:19 +03:00
Gokhan Simsek 3a5159b060 Adding APP version into connect function and some refactoring 2020-06-18 14:23:38 +03:00
Gokhan Simsek 617f2d5669 Refactoring 2020-06-18 13:50:25 +03:00
Gokhan Simsek 3d02aa687e Adding logging for scope reset 2020-06-18 11:54:27 +03:00
Gokhan Simsek 3bcd0a8509 #1686 #1628: Attempt to fix these two cases which seems to have the same root cause 2020-06-18 10:28:22 +03:00
Gokhan Simsek c240ab4e8e Updating reconnect handling for failed ExecuteScriptRequest 2020-06-18 09:46:56 +03:00
Gokhan Simsek 8e2d47f793 Fixing logging of failed ping events 2020-06-16 14:07:17 +03:00
Gokhan Simsek 3c993deedf Minor change/fix 2020-06-16 09:33:25 +03:00
Gokhan Simsek 82d7116664 Minor UI changes 2020-06-16 09:33:00 +03:00
Gokhan Simsek 015cea9c07 Making QMessageBox window usage generic 2020-06-15 16:09:03 +03:00
Gokhan Simsek 359c5b3c81 Remove ASCII characters '\t', '\n', '\v', '\f', '\r', and ' ' from msg string 2020-06-15 11:22:51 +03:00
Gokhan Simsek 5c3312179c Updating error handling of failing listdatabase command 2020-06-15 11:16:34 +03:00
Gokhan Simsek 70d5c19a43 Minor refactoring 2020-06-14 18:55:45 +03:00
Gokhan Simsek 9f62c44460 #1696 #1368 #389: Adding feature "Manually specify visible databases" into connection settings auth. tab 2020-06-14 18:55:16 +03:00
Gokhan Simsek 542fd12343 Attempt to fix a bug seen when Collections folder refreshed and replica set is unreachable 2020-06-11 09:16:44 +03:00
Gokhan Simsek 0763be425c Updating code due to the fact that getReplicaSetInfo() may throw now 2020-06-11 09:15:35 +03:00
Gokhan Simsek 6b3c983e67 Minor renaming 2020-06-10 14:05:26 +03:00
Gokhan Simsek 638c7b2fbe Minor refactoring 2020-06-10 13:46:16 +03:00
Gokhan Simsek a55b7c8069 Showing error and hint to the user for the case where Robo fails to get the list of databases 2020-06-10 11:46:30 +03:00
Gokhan Simsek 318fc6d676 Renaming to AddEditIndexDialog 2020-06-09 17:00:18 +03:00
Gokhan Simsek 705a55e49f Adding warning dialog for Edit Index 2020-06-09 16:45:15 +03:00
Gokhan Simsek 39aba89186 Minor change 2020-06-09 14:25:06 +03:00
Gokhan Simsek f7bbbee464 Minor renaming 2020-06-09 14:20:54 +03:00
Gokhan Simsek 48dbd9f7d9 Fix drop index error handling and logging 2020-06-09 14:16:25 +03:00
Gokhan Simsek 1b8ed947f3 Adding new event AddEditIndexResponse 2020-06-09 11:48:00 +03:00
Gokhan Simsek cb3ff65d05 Renaming to DropCollectionIndexResponse 2020-06-09 09:48:33 +03:00
Gokhan Simsek d32581084d Code refactoring 2020-06-08 18:14:34 +03:00
Gokhan Simsek 950b25236c Renaming ExplorerCollectionIndexesTreeItem to ExplorerCollectionIndexItem 2020-06-08 18:01:00 +03:00
Gokhan Simsek fecdbc8658 Renaming ExplorerCollectionDirIndexesTreeItem to ExplorerCollectionIndexesDir 2020-06-08 16:54:22 +03:00
Gokhan Simsek 1e8932b390 Removing unused code 2020-06-08 14:24:57 +03:00
Gokhan Simsek 28ae1d81a8 #1692: Try to recover(create) the dropped (old) index when the creation of new index fails 2020-06-08 14:00:34 +03:00
Gokhan Simsek d7ad941d1e #1692: Renaming to IndexInfo 2020-06-08 10:52:08 +03:00
Gokhan Simsek 0ebbf9ab33 #1692: Renaming and cleaning unused code 2020-06-08 10:50:12 +03:00
Gokhan Simsek 7c4282688a #1692: Removing unsupported "drop duplicates" option 2020-06-07 18:01:13 +03:00
Gokhan Simsek e892601440 #1692: Ceate & edit index: Fix for not working "text weights" 2020-06-07 17:18:01 +03:00
Gokhan Simsek dbda800374 #1692: Re-writing buggy create & edit index, removing dependency to old index data (oldInfo) 2020-06-07 16:44:45 +03:00
Gokhan Simsek ba0f5edfea #1692: First changes to get create & edit index work with MongoDB 4.2 2020-06-05 18:08:35 +03:00
Gokhan Simsek 5953c9cccb Minor change 2020-06-04 16:57:12 +03:00
Gokhan Simsek ba95dddf12 Minor changes 2020-06-01 14:36:23 +03:00
Gokhan Simsek 10371accfb Removing "Optional" string from "Set Name" label due to confusions reported by users 2020-06-01 10:30:57 +03:00
Gokhan Simsek 815d6c1286 Try to get the last error for all connections 2020-06-01 10:23:59 +03:00
Gokhan Simsek c00c0cb387 Removing unused class 2020-05-29 10:35:24 +03:00
Gokhan Simsek c8433a884b Additional change for previous commit 2020-05-29 10:34:56 +03:00
Gokhan Simsek 7f2aad3593 Renaming SSL to TLS 2020-05-28 16:40:19 +03:00
Gokhan Simsek cfedd020b9 Deleting no longer working code 2020-05-28 10:09:54 +03:00
Gokhan Simsek 116f5b5c54 Fix for Robo failing give error and got stuck connecting gif for unreachable Mongo Atlas connections 2020-05-27 09:22:54 +03:00
Gokhan Simsek 5b3b3fdf84 First working connection to Mongo Atlas 2020-05-22 09:34:27 +03:00
Gokhan Simsek 84bc19f71f Adding Program Architecture.jpg 2020-05-21 09:22:43 +03:00
Gokhan Simsek a8ddba48b7 Fix macOS and ubuntu build error for previous commit 2020-05-20 12:22:47 +03:00
Gokhan Simsek fac8d9dcab Refactoring App::_servers into unique_ptr 2020-05-20 10:47:01 +03:00
Gokhan Simsek f561dc7191 Need to delete server first since its address is taken from shell 2020-05-18 16:57:34 +03:00
Gokhan Simsek 116014918b Fix linux packaging error 2020-05-18 12:57:50 +03:00
Gokhan Simsek 0d9543a0d8 Adding config. file path of version 1.3.1 2020-05-18 12:35:27 +03:00
Gokhan Simsek f75f210675 Update duplicateCollection() 2020-05-15 11:47:12 +03:00
Gokhan Simsek cbc3c93fae Cleaning getFunctions() 2020-05-15 11:01:19 +03:00
Gokhan Simsek f2f91d23a9 Refactoring App::closeShell() function 2020-05-14 15:24:20 +03:00
Gokhan Simsek a976a59ce2 Windows: Adding script to automate installing debug dlls 2020-05-14 10:36:28 +03:00
Gokhan Simsek 87f07c6509 Fix for broken script engine and removing _dbAuth due to mongo commit 82e05d6: SERVER-39128 Avoid double-authentication 2020-05-13 11:07:31 +03:00
Gokhan Simsek 04c369cdf8 Minor fix for clang warning 2020-05-11 17:27:07 +03:00
Gokhan Simsek 9c1d4ac2fc Forgotten if defines for previous commit 2020-05-11 17:13:06 +03:00
Gokhan Simsek 391b45fba1 Linux: Suppressing a warning from qscintilla library 2020-05-11 17:02:30 +03:00
Gökhan Şimşek 7184e02207 Update BuildRobo3TOnWindows.md 2020-05-11 12:16:24 +03:00
Gökhan Şimşek 96693edb8b MongoDB 4.2: Update build doc. for macOS & Ubuntu 2020-05-08 18:16:57 +03:00
Gökhan Şimşek 6eb2f24bb1 MongoDB 4.2: Update build doc. for Windows 2020-05-08 15:46:28 +03:00
Gokhan Simsek 1dc8f1b30a Ubuntu: Adding roboshell build objects 2020-05-08 11:04:04 +03:00
Gokhan Simsek 8d20980aa9 macOS and Ubuntu: Disabling sprintf format warnings for external code 2020-05-07 16:52:39 +03:00
Gokhan Simsek a01868c49c macOS and Ubuntu: Disabling warning unused return value. This source file comes from mongo. 2020-05-07 15:09:15 +03:00
Gokhan Simsek 0764d25df4 Ubuntu: Adding -lcurl 2020-05-07 11:32:03 +03:00
Gokhan Simsek 44906870e4 macOS: First version builds with roboshell-v4.2 2020-05-06 13:46:23 +03:00
Gokhan Simsek 6ec34a9936 First version builds with roboshell-v4.2 and connects to local MongoDB version 4.2 server on Windows 2020-04-30 21:46:48 +03:00
Gökhan Şimşek 2b72077225 Create cppcheck_output_Apr2019 2019-04-12 17:12:22 +03:00
Gökhan Şimşek 0d1627d243 Update BuildRobo3TOnWindows.md 2019-04-04 09:52:46 +03:00
Gökhan Şimşek 63d288d85f Update BuildRobo3TOnMacAndLinux.md 2019-04-04 09:43:34 +03:00
Gokhan Simsek fb4aaa54ad Adding Welcome_Tab.jpg 2019-04-03 12:24:32 +03:00
Gokhan Simsek 7419c4060e WelcomeTab: Enabling using of HTTPS for RSS download for Linux 2019-03-22 10:20:47 +03:00
Gokhan Simsek be89b5c12a WelcomeTab: Final UI adjustments 2019-03-22 10:20:05 +03:00
Gökhan Şimşek e34f24e183 Update README.md 2019-03-18 16:19:13 +03:00
Gökhan Şimşek 0a98ba0487 Update README.md 2019-03-18 16:18:00 +03:00
Gökhan Şimşek 5a70800a31 Update README.md 2019-03-18 16:14:35 +03:00
Gokhan Simsek bbc0eb8d6f Updating changelog for version 1.3 2019-03-18 15:47:23 +03:00
Gokhan Simsek 8a1cca4198 #731: Making SSL "pemPassphrase" encrypted as well in config file 2019-03-16 15:06:50 +03:00
Gokhan Simsek 3f2ef3b8b5 Code comments refactoring 2019-03-16 14:37:40 +03:00
Gokhan Simsek 2e31e70881 Making SSH "passphrase" in config file encrypted 2019-03-16 14:37:10 +03:00
Gokhan Simsek 8e8d655e66 Creating config. folder tree and file before everything 2019-03-13 17:18:15 +03:00
Gokhan Simsek d138308fce Adding beta config. file path and disabling beta version 2019-03-13 16:10:30 +03:00
Gokhan Simsek 7ed61ccbb6 Code review between commits 2e371d2 and 8f00817: Minor refactorings 2019-03-13 15:40:19 +03:00
Gokhan Simsek 29a91f4730 Code review between commits 2e371d2 and 8f00817: Minor comment only changes 2019-03-13 15:39:33 +03:00
Gokhan Simsek 8f00817927 Minor UI fix for Windows 2019-03-13 09:28:19 +03:00
Gokhan Simsek 0696b8d073 Adding horizontal line for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-12 12:12:59 +03:00
Gokhan Simsek de247b3b5b Linux UI refactoring for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-12 12:06:12 +03:00
Gokhan Simsek 0dfe32f594 MacOS UI refactoring for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-12 10:28:29 +03:00
Gokhan Simsek 5d3f2cd6fa Windows UI refactoring for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-12 10:16:34 +03:00
Gokhan Simsek 8c48d6a90f Adding error handling and logging for initKey() #731 2019-03-07 14:40:26 +03:00
Gokhan Simsek a58c15aee3 Adding random key generation and save/load from local key file for #731 2019-03-07 09:15:06 +03:00
Gokhan Simsek f27efd7af0 Linux UI adjustments for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-06 09:33:04 +03:00
Gokhan Simsek 6882dff4fc MacOS UI adjustments for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-05 16:56:54 +03:00
Gokhan Simsek 230eb927a0 Adding SSL tab and Advanced tab changes for new feature: Support DNS SRV based MongoDB connections #1588 2019-03-04 17:09:44 +03:00
Gokhan Simsek 365a067755 First changes for New Feature: Support DNS SRV based MongoDB connections #1588 2019-03-04 14:30:03 +03:00
Gokhan Simsek b2751af4e3 Fixing alignment problem of Default Database text in connection settings dialog 2019-03-04 09:45:30 +03:00
Gokhan Simsek f83772efb9 First code changes for #1588: New Feature: Support DNS SRV based MongoDB connections. And some UI size and alignment updates 2019-03-01 17:16:37 +03:00
Gokhan Simsek 23b23e0e86 Tabbed output feature: Close tab on middle mouse button 2019-02-27 11:03:28 +03:00
Gokhan Simsek 98d6871300 Tabbed output feature: Fixing some visual issues for MacOS 2019-02-26 17:57:02 +03:00
Gokhan Simsek 21978735a1 #1591 #1403: Tabbed output feature: Adding tooltip to show full statement on tab hover 2019-02-26 15:58:08 +03:00
Gokhan Simsek d3a3d8b6ef Some refactoring and fixing bug related to button "maximize output" 2019-02-26 15:54:38 +03:00
Gokhan Simsek 97af0e28fc #1591 #1403: Tabbed output feature: Some style changes for all platforms 2019-02-26 11:22:47 +03:00
Gokhan Simsek 7c68547dfa Minor correction 2019-02-26 09:42:25 +03:00
Gokhan Simsek 7d30c12fb7 Minor refactoring 2019-02-26 09:36:57 +03:00
Gokhan Simsek 0f551b6d25 #1591 #1403: Tabbed output feature: Visual adjustments for MacOS 2019-02-26 09:36:32 +03:00
Gokhan Simsek 198803dee0 #1591 #1403: Tabbed output feature: Setting tab title to short query string 2019-02-23 17:26:50 +03:00
Gokhan Simsek 1d9d6941ec New feature tabbed output window for query results more than 2. #1591 #1403. 2019-02-23 15:20:11 +03:00
Gokhan Simsek 3deba89063 Unit tests for RoboCrypt basic functionality 2019-02-22 12:45:02 +03:00
Gokhan Simsek 4d93a94ef6 Updating configuration summary 2019-02-21 17:51:16 +03:00
Gokhan Simsek 8b34c228e7 Updating configuration summary 2019-02-21 17:46:52 +03:00
Gokhan Simsek 7d2bfd702c Robo 1.3: To silence CMake warning: "Policy CMP0071 is not set: Let AUTOMOC and AUTOUIC process GENERATED files." 2019-02-21 17:46:28 +03:00
Gokhan Simsek 09d42500e6 Linux: Updating unit test cmake file - linking is still not working 2019-02-21 15:15:01 +03:00
Gökhan Şimşek 51f0f94a37 Update BuildRobo3TOnMacAndLinux.md 2019-02-21 12:08:55 +03:00
Gokhan Simsek 293564be75 Windows: Need to install Qt DLLs for robo_unit_tests exe 2019-02-21 11:53:32 +03:00
Gokhan Simsek 4917f8df79 Adding RoboCrypt unit test file and major refactoring of robo unit tests cmake file 2019-02-21 10:02:01 +03:00
Gokhan Simsek 0def5df6c8 More changes for #731: Minor changes 2019-02-20 09:41:04 +03:00
Gokhan Simsek 83696b3a99 Updating run_tests script 2019-02-19 17:59:05 +03:00
Gokhan Simsek 7a2c7f83aa Refactoring unit test cmake file and disabling unit testing for Linux 2019-02-19 17:52:19 +03:00
Gokhan Simsek 2547311ef4 Attempt to fix #731: Robomongo stores passwords in plain text 2019-02-19 10:52:46 +03:00
Gokhan Simsek 5eea6e491a #1554: Changes for support for creating version 4 UUID 2019-02-19 10:27:14 +03:00
Gokhan Simsek 57984545ab Putting uuidhelpers.js back in order to modify it 2019-02-19 10:26:17 +03:00
Gokhan Simsek d19c51c517 Minor refactorings 2019-02-18 22:58:54 +03:00
Gokhan Simsek 94860b6995 Adding schematics 2019-02-18 18:30:53 +03:00
Gokhan Simsek 43c1cea1d2 Minor renaming 2019-02-18 09:33:34 +03:00
Gokhan Simsek 3b188a9970 Minor refactorings and minor fix 2019-02-18 09:09:24 +03:00
Gokhan Simsek e1066e203f Changes to correctly capture error message for replica set connections 2019-02-13 20:09:15 +03:00
Gokhan Simsek e74d67db3a Fix for #1529: Pagination does not work when the aggregation queries have dotted fields 2019-02-13 15:46:56 +03:00
Gokhan Simsek e759173e46 Adding googletest into cmake config summary 2019-02-12 08:38:21 +03:00
Gokhan Simsek f1875f09aa Windows: googletest more changes 2019-02-11 15:22:51 +03:00
Gokhan Simsek fbf2506f86 Linux: Partly working version of unit tests 2019-02-11 05:53:24 -05:00
Gokhan Simsek 315db7e8fa MacOS: Completely working version of unit tests 2019-02-10 11:32:30 +03:00
Gokhan Simsek 75a89b8859 Minor change 2019-02-10 00:58:04 +03:00
Gokhan Simsek 6d151f33ad Windows: Completely working version of unit tests 2019-02-10 00:56:59 +03:00
Gokhan Simsek bd801281db Fix for broken features "Update Documents" and "Duplicate query in new tab" - they should not execute any script. 2019-02-08 10:24:52 +03:00
Gokhan Simsek eba49439ac Fixing UI issue where Functions folder freezing with "Functions..." when fails to refresh 2019-02-07 08:51:35 +03:00
Gokhan Simsek bc64d09a8f Removing unused parameter "overwrite" for create user action 2019-02-07 08:49:20 +03:00
Gokhan Simsek 68bfc679df #638 #1041: Adding View User functionality instead of Edit User 2019-02-06 18:36:34 +03:00
Gokhan Simsek 82f090f517 Attempt to fix #638 #1041: Updating drop user code 2019-02-06 15:26:47 +03:00
Gokhan Simsek d58043149b Attempt to fix #638 #1041: MongoClient getUsers() updated and so in UI database explorer previously not visible users are now visible. And removing unused MongoUser code. 2019-02-05 23:04:41 +03:00
Gokhan Simsek 690586b655 Attemp to fix #638 #1041: View users code updated. And UI change: Disabling user source and password mutual exclusivity. 2019-02-02 18:35:37 +03:00
Gokhan Simsek f6d37904d5 Attemp to fix #638 #1041: Create user code updated 2019-02-02 18:32:57 +03:00
Gokhan Simsek b50677ac11 Minor refactoring 2019-02-01 22:53:45 +03:00
Gokhan Simsek 509062e478 Showing error string from Mongo for connection failures 2019-02-01 09:14:18 +03:00
Gokhan Simsek fa930c94ed To prevent the problem where sometimes refresh tab query can be earlier than the main CRUD operation when the local servers are used 2019-01-19 20:46:37 +03:00
Gokhan Simsek 545331f8e6 Attempt to fix #1581: For remove document(s) ops showing progress bar and disabling context menu while waiting operation to finish 2019-01-19 20:43:29 +03:00
Gokhan Simsek 15c5868274 Attempt to fix #1581: For insert document ops showing progress bar and disabling context menu while waiting operation to finish 2019-01-19 18:11:04 +03:00
Gokhan Simsek eca6cc16cc Attempt to fix #1581: For edit document ops showing progress bar and disabling context menu while waiting for edit op to finish 2019-01-19 17:19:41 +03:00
Gokhan Simsek 2340149f25 #1603: Attempt to fix major connection problems seen with the second edit/add/remove doc. operation after MongoDB 4.0 upgrade 2019-01-19 17:06:08 +03:00
kathrynvargas d9abb535fa Update README.md 2019-01-18 12:21:22 +01:00
Gokhan Simsek 6682ddce52 Changes needed after upgrading mongo version from 4.0.4 to 4.0.5 2019-01-14 22:25:11 +03:00
Gokhan Simsek 49207c04ff Disabling google test temporarily 2019-01-14 22:24:10 +03:00
Gokhan Simsek 735ca6e1d5 Seting CMAKE_OSX_DEPLOYMENT_TARGET 10.11 2019-01-04 11:31:23 +03:00
Gokhan Simsek 071bec0924 First working version with dummy unit tests 2019-01-04 09:44:47 +03:00
Gokhan Simsek 1ae1466cad Adding googletest-1.8.1 2019-01-04 09:44:05 +03:00
Gökhan Şimşek 270d8f7035 Create .travis.yml 2019-01-02 10:21:30 +03:00
Gökhan Şimşek b162d24b86 Update BuildRobo3TOnMacAndLinux.md 2018-12-30 23:40:09 +03:00
Gökhan Şimşek 650277f8f6 Update BuildRobo3TOnMacAndLinux.md 2018-12-30 23:39:12 +03:00
Gökhan Şimşek a1d230ba9c Update BuildRobo3TOnMacAndLinux.md 2018-12-30 21:13:09 +03:00
Gokhan Simsek 8d8169d5b6 #1569: Adding support for SCRAM-SHA-256 auth mechanism 2018-12-29 11:40:10 +03:00
Gokhan Simsek 696aa2d67f Fix for application crash when adding index with invalid JSON 2018-12-28 11:28:33 +03:00
Gokhan Simsek 12c94c9908 Forgotten change for 2 previous commit cb48b0b 2018-12-28 10:00:14 +03:00
Gokhan Simsek 25c1fdc365 Attemp to fix #1547: Crash when right click on existing results plus a new long running query 2018-12-27 11:03:29 +03:00
Gokhan Simsek cb48b0bfa6 Removing the uuidhelpers.js due to the fact that it breaks the usage of new feature UUID() without parameter and seems that it is not needed anymore. 2018-12-27 10:58:36 +03:00
Gokhan Simsek 27f825527e Fix for #1551: Robo 3T the input space causes connection failure 2018-12-19 23:30:40 +03:00
Gokhan Simsek 1cec948022 #1568: Adding confirm dialog for 'Repair Database' action 2018-12-19 22:25:07 +03:00
Gokhan Simsek 7a0fd3f165 Windows: Adding generic SDK Lib path 2018-12-19 13:18:40 +03:00
Gökhan Şimşek 4071a83ab9 Update README.md 2018-12-19 12:38:18 +03:00
Gokhan Simsek 8078ccc8db Importan fix: Catching exception instead of runtime_error in MongoWorker. This fixes crash problem when creating db with a string which contains whitespace. 2018-12-19 12:14:53 +03:00
Gokhan Simsek 47bb0619b6 Ubuntu: First version which builds, runs and connects to localhost (linked to robo-shell-4.0.4 commit 9db1ab) 2018-12-11 01:50:15 -05:00
Gokhan Simsek 8e06a1e78d Project version change to 1.3.0 Beta 2018-12-10 16:41:43 +03:00
Gökhan Şimşek b296874fc4 Update BuildRobo3TOnMacAndLinux.md 2018-12-09 12:20:39 +03:00
Gökhan Şimşek c7ef849905 Update BuildRobo3TOnMacAndLinux.md 2018-12-09 12:14:11 +03:00
Gökhan Şimşek ec917a651b Update BuildRobo3TOnMacAndLinux.md 2018-12-09 12:13:29 +03:00
Gökhan Şimşek a403b33eae Update RuntimeDependencies.md 2018-12-09 10:06:17 +03:00
Gökhan Şimşek 359cb93566 Update BuildRobo3TOnWindows.md 2018-12-06 17:04:07 +03:00
Gökhan Şimşek 367cc8dd08 Update BuildRobo3TOnMacAndLinux.md 2018-12-06 15:09:48 +03:00
Gökhan Şimşek 6d647c9985 Update BuildRobo3TOnWindows.md 2018-12-06 15:09:43 +03:00
Gokhan Simsek 15e95777f2 First version which builds, runs and connects to localhost on MacOS (linked to robo-shell-4.0.4 commit 9db1ab) 2018-12-06 11:45:36 +03:00
Gokhan Simsek 5dd5019f57 First version which connects to localhost on Windows linked to robo-shell-4.0.4 commit 9db1ab 2018-12-05 21:28:42 +03:00
Gökhan Şimşek f56ff4f5f2 Update BuildRobo3TOnMacAndLinux.md 2018-11-23 16:48:46 +03:00
Gökhan Şimşek b13951e2a3 Update BuildRobo3TOnWindows.md 2018-11-23 15:04:53 +03:00
Gökhan Şimşek eb1e895c0c Update BuildRobo3TOnWindows.md 2018-11-23 11:30:10 +03:00
Gökhan Şimşek 9caacc088b Update BuildRobo3TOnWindows.md 2018-11-19 16:29:50 +03:00
Gökhan Şimşek 7543f5ea09 Update BuildRobo3TOnWindows.md 2018-11-14 22:02:43 +03:00
Gökhan Şimşek 2e371d2d12 Update README.md 2018-02-22 12:11:23 +02:00
Tomasz Naumowicz 290b73d981 Changelog for version 1.2, updated the release date. 2018-02-19 16:12:08 +01:00
Tomasz Naumowicz 92ac5d97e5 Update README.md for 1.2 version 2018-02-19 12:56:07 +01:00
Gökhan Şimşek ac84129ef8 Update README.md 2018-02-09 13:36:00 +03:00
Gökhan Şimşek 3e50a6500c Update README.md for 1.2 version 2018-02-08 11:24:04 +03:00
Gokhan Simsek c90f3250bf Changelog for version 1.2 2018-02-08 11:06:42 +03:00
Gokhan Simsek e29c577104 Code Review: Between this commit and commit f48cffd, minor changes. 2018-02-07 17:31:44 +03:00
Gokhan Simsek d08643b0c0 Using PROJECT_VERSION as URL directory for image.png and content.txt 2018-02-07 17:30:22 +03:00
Gokhan Simsek 94535d7e38 Minor enhancement: Detect scientific notation with case insensitively 2018-02-05 13:17:02 +03:00
Gokhan Simsek 3ed6f17f28 Enabling Eula dialog form page for Linux which was previously disabled due to crashes 2018-02-05 13:07:07 +03:00
Gokhan Simsek e593403f2e Send the set of unique db version strings within call-home data with checkUpdates() function instead of sending in MongoServer. 2018-02-02 17:06:21 +03:00
Gokhan Simsek bf94b75960 Feature: Save a set of unique db version strings connected in config file and send this data to remote server only when we connect to a new unique db version. 2018-02-02 16:37:00 +03:00
Gokhan Simsek b263bd476a Adding phone and company into UI. Adding phone, company, os and timezone fields into JSON document that is sent to server. 2018-02-02 12:39:54 +03:00
Gokhan Simsek 1fbbde21be Adding feature to be able to find and import anonymousID from newer config files whose paths are unknown to current (this) version 2018-02-01 13:23:41 +03:00
Gokhan Simsek e4ed721fd0 Fixing trailing zero issue for small double values and minor refactoring. 2018-01-31 14:21:07 +03:00
Gokhan Simsek 62d7bda1e2 Double check this is an aggregate call 2018-01-30 17:22:50 +03:00
Gokhan Simsek dcd1d96b28 Reverting back to original solution, disabling trailing zeros for scientific format values, disabling scientific format for frequently used e+15 and e+16 values. 2018-01-30 16:29:10 +03:00
Gokhan Simsek 229cdc8c4e Removing redundant copy assignment operator 2018-01-29 11:00:03 +03:00
Gokhan Simsek 79cbc8784d Adding split results view with resultIndex support for aggregate. 2018-01-22 18:00:35 +03:00
Gokhan Simsek 36295161f5 Cleaning code for aggregate feature 2018-01-20 18:47:48 +03:00
Gokhan Simsek 1e2987500d First working version of aggregate with captured parameters and using $skip and $limit for paging 2018-01-19 10:07:48 +03:00
Gokhan Simsek 8bc0b134d2 Attempt to fix macOS not visible tab close button. Upgrading close tab icons image quality. Better tab icon-text alignment for macOS. More visible tab text by allowing more text space. 2018-01-11 22:41:02 +03:00
Gokhan Simsek 1c64d27da9 Removing manually maintained qzipreader class and adding qzip folder as a more permanent solution 2018-01-09 12:57:43 +03:00
Gokhan Simsek ceb7e2fbe6 Updating version from 1.2.0-Beta to 1.2.1 2018-01-09 12:47:51 +03:00
Gokhan Simsek 657e1bfd54 Double confirm if statement is an aggregate query by firstly checking query output and secondly by checking if the statement itself contains "aggregate(" string. 2018-01-03 15:12:00 +03:00
Gokhan Simsek b3c07a05a3 Cleaning last character of aggregate query in order to run/get "_batch" element and array slice 2018-01-03 12:46:28 +03:00
Gokhan Simsek 44574cd14f #1058: First working version of aggregate queries fix 2018-01-03 12:10:48 +03:00
Gokhan Simsek b48dc0b907 #1155, #1447: Attempt to fix double type issues: scientific format problems, incorrect value representation for 15 digit precision, -Infinity problem. 2017-12-24 20:43:43 +03:00
Gokhan Simsek 8a15ca9a66 #1282, #1093: Disabling editing if query has projection 2017-12-20 13:31:04 +03:00
Gokhan Simsek 95d1b3f49a Minor refactoring 2017-12-19 08:42:04 +03:00
Gökhan Şimşek 67cd8a2a33 Update CHANGELOG 2017-12-18 19:56:29 +02:00
Gokhan Simsek 3d2f8b8fd1 An attempt to fix some SSH connection failures by changing the order of key exchange methods. This change still fixes the previous problem reported in ticket #1090. 2017-12-18 20:39:52 +03:00
Gokhan Simsek 2fc8a2a921 Changes for 1.2 Beta release 2017-12-18 20:34:39 +03:00
Gokhan Simsek e77b16d0fe Updating application string to "robo3t" which was seen as "Robomongo" in mongodb log. And one more string related change. 2017-12-13 20:29:09 +03:00
Gokhan Simsek c83bd6e1dd Using HTTP instead of HTTPS in the case of program crashes or abnormal exit due to HTTPS usage in EulaDialog form submit or WelcomeTab. 2017-12-13 16:12:29 +03:00
Gokhan Simsek 3c93f1fcaa Removing duplicate patch file. Updating settings manager with new Qt version 2017-12-06 11:00:55 +03:00
Gokhan Simsek 4f425b9604 Attempt to solve build problem on MacOS High Sierra with QScintilla patch 2017-12-05 10:12:26 +03:00
Gokhan Simsek e2bc0ad7b3 Merge commit 'e13d41cabecfdc966a030d2b5fdb23a2d9bde9a5' 2017-12-05 10:09:26 +03:00
Gokhan Simsek d399bcc6cd #1454: Code change to fix the problem "Cannot load list of indexes" error in the related ticket. Solution is to use non-throwing mongo::BSONObj getField* functions instead of throwing BsonUtils functions. 2017-12-04 16:48:58 +03:00
Gokhan Simsek 5167c65ae3 Changing project version to Robo 1.2. Adding latest config. file into auto import list. 2017-12-04 09:39:13 +03:00
Dor Fire e13d41cabe Reverted header version change 2017-10-19 21:31:29 +03:00
Dor Fire da526f9d8e Added precision=3 to query time formatting 2017-10-19 21:27:25 +03:00
Dor Fire facaec61d9 Fixed QT lib path 2017-07-10 10:15:39 +03:00
Dor Fire 993e6898f3 Added QScintilla patch and build note 2017-07-10 10:15:23 +03:00
Gökhan Simsek f48cffdb2c Adding how to build/clean Robo Shell and Robo 3T in debug mode for Mac and Linux 2017-07-04 16:37:17 +03:00
Gökhan Simsek 74ce2ea6f8 Adding how to build/clean Robo Shell and Robo 3T in debug mode 2017-07-04 15:32:21 +03:00
Gökhan Simsek 2d358bfb9e Update README.md 2017-07-04 11:31:26 +03:00
Gökhan Simsek a826e5ad2f Update BuildRobo3TOnMacAndLinux.md 2017-06-27 12:39:58 +03:00
Gökhan Simsek 1a75ff2746 Update BuildingRobomongoOnWindows.md 2017-06-27 12:32:57 +03:00
Gökhan Simsek 5b3b3fca48 Update BuildingRobomongo.md 2017-06-27 12:32:42 +03:00
Gökhan Simsek 4011f621eb Update BuildingMongoDB.md 2017-06-27 12:32:12 +03:00
Gökhan Simsek 35d7cd00cf Update BuildRobo3TOnMacAndLinux.md 2017-06-27 12:26:14 +03:00
Gökhan Simsek 9074e23b18 Rename BuildRobo3TOnWindows to BuildRobo3TOnWindows.md 2017-06-27 12:24:45 +03:00
Gökhan Simsek 03fbda9043 Rename BuildRobo3TOnMacAndLinux to BuildRobo3TOnMacAndLinux.md 2017-06-27 12:24:16 +03:00
Gökhan Simsek eee5edf45d Update and rename BuildRobo3TShell to BuildRobo3TShell.md 2017-06-27 12:23:43 +03:00
Gökhan Simsek 1e7df0abca Adding new document for "Building Robo 3T Shell" 2017-06-27 12:22:02 +03:00
Gökhan Simsek e690a54b06 Build Doc Robo 3T (Mac OS X and Linux) for MongoDB3.4 2017-06-27 12:15:30 +03:00
Gökhan Simsek bcf510df3d Update BuildRobo3TOnWindows 2017-06-27 12:13:09 +03:00
Gökhan Simsek a85a1feba0 Build Doc Robo 3T (Windows) for MongoDB3.4 2017-06-27 12:06:40 +03:00
Gökhan Simsek b8a4da7efc Update README.md 2017-06-19 10:36:02 +03:00
Gökhan Simsek 02c156e41e Update README.md 2017-06-19 10:34:54 +03:00
Gökhan Simsek ea77f76415 Update README.md
version 1.1 changes
2017-06-19 10:30:22 +03:00
Gokhan Simsek c93c6b0276 WelcomTab: Fixing a problem where main header text gets hidden at first launch 2017-06-14 11:42:51 +03:00
Gokhan Simsek 36dbc07baf Fixing wrong return type 2017-06-14 10:38:44 +03:00
Gokhan Simsek ff5d70590b WelcomeTab: Fix for the problem where image was shown very big at first launch 2017-06-14 10:21:39 +03:00
Gokhan Simsek 388075378f Adding functionality to import UUID from old config files. 2017-06-14 09:36:45 +03:00
Gokhan Simsek 82612e5cd4 Fixing problem Welcome Tab not loading from cache properly 2017-06-13 10:53:11 +03:00
Gokhan Simsek b03527a7ad Change log for version 1.1 2017-06-12 11:05:54 +03:00
Gokhan Simsek 01633ee08e Fixing minor text issues with change shell timeout dialog 2017-06-12 11:05:11 +03:00
Gokhan Simsek b9b454be9c Adding C++14 support for MAC and Linux compilers 2017-06-12 09:41:05 +03:00
Gokhan Simsek 2d021c80d3 Adding support for import connections from version 1.1.0-Beta 2017-06-12 09:40:22 +03:00
Gokhan Simsek 0a1819eec2 #1373: Fix for dmg installer icons are not aligned problem for MAC 2017-06-08 10:31:00 +03:00
Gokhan Simsek 90f6794e7d WelcomeTab: Updating URL folder for picture and text to '3' for new version 1.1.0. 2017-06-08 09:45:28 +03:00
Gokhan Simsek 92d2e9e031 #1369, #1349: Fix to prevent MAC OS Sierra crash related to updates notification bar height calculation 2017-06-07 18:09:11 +03:00
Gokhan Simsek c5d88c244d Minor text change for menu item "Change Shell Timeout" 2017-06-07 18:04:09 +03:00
Gokhan Simsek 0fcc30e22b Changing config file folder name to robo-3t and config file name to robo3t.json 2017-06-07 18:03:21 +03:00
Gökhan Simsek e31414b610 Update README.md 2017-06-06 13:08:45 +03:00
Gökhan Simsek 744d693d90 Update README.md 2017-06-06 13:05:26 +03:00
Gokhan Simsek d62d1f46e4 Enabling SSH and SSL options to be enabled at the same time 2017-05-23 09:57:32 +03:00
Gokhan Simsek 615c370e51 Attempt to fix "Add, Edit and Drop Function" operations which were not working with Atlas 3.4 free cluster 2017-05-23 09:46:45 +03:00
Gokhan Simsek bc8bb0b03a LoadFunctions: Adding secondary way to get functions list with script engine due to a problem where empty functions list returned by client getFunctions() function for Atlas 3.4 cluster 2017-05-23 09:08:35 +03:00
Gokhan Simsek 700967baca To fix MAC build error 2017-05-22 14:00:47 +03:00
Gökhan Simsek 70ad4a7035 Update README.md 2017-05-22 10:49:46 +03:00
Gokhan Simsek 4f29fd3790 Additional changes related to rebranding 2017-05-20 13:50:20 +03:00
Gokhan Simsek 5785ee2bc2 #1106: Adding ChangeShellTimoeutDialog and functionality to be able to change shell timeout ("shellTimeoutSec") at program run time (and save into config file), effective immediately on all existing/new tabs and persistent after program restart. 2017-05-20 13:49:27 +03:00
Gokhan Simsek 0584da0611 To fix a bunch of "macro redefinition" build warnings 2017-05-19 18:18:15 +03:00
Gokhan Simsek 164fdeeb92 #1106: Attempt to detect and inform user about popular problem where the long lasting scripts were ending prematurely and silently due to shell timeout reached ("shellTimeoutSec" parameter in config file) 2017-05-19 18:16:22 +03:00
Gokhan Simsek 5d97f9db15 Rebranding to "Robo 3T" 2017-05-19 15:22:29 +03:00
Gokhan Simsek 968a4fe04b Refactoring and simplifying import connections code to make it much easier to maintain for the next releases 2017-05-16 16:24:45 +03:00
Gokhan Simsek e2c5b44408 Adding new error message retriever/handler for drop database and drop collection operations which has been broken after 3.4 transition 2017-05-16 16:06:39 +03:00
Gokhan Simsek 5bcb75019a Cleaning of todos in code and some minor refactoring 2017-05-16 16:02:43 +03:00
Gokhan Simsek 1733a525e0 Change to fix "error on loading indexes" problem (Due to 3.4 API change, dbname is needed to be added manually while creating mongo namespace strings i.e. db1.coll1) 2017-05-15 17:53:56 +03:00
Gokhan Simsek fba5585f77 #1348: Making "View Document" operation non-modal (not blocking) again 2017-05-15 12:12:43 +03:00
Gokhan Simsek e1227bf0f8 Adding installation of required run time dependencies for Ubuntu 2017-05-12 10:32:39 +03:00
Gokhan Simsek 5349d34513 Minor typo on cmake project version 2017-05-11 16:14:38 +03:00
Gokhan Simsek 465599701c Adding "-beta" into cmake project version 2017-05-11 16:05:19 +03:00
Gokhan Simsek e91c13cbf8 Minor change on CHANGELOG for 1.1.0 Beta 2017-05-11 14:46:41 +03:00
Gokhan Simsek 604d89c2c6 WelcomeTab: Updating URLs to version '2' which corresponds to 1.1.0 Beta. 2017-05-11 14:46:02 +03:00
Gökhan Simsek 19f42ecfd1 Update README.md 2017-05-11 14:23:55 +03:00
Gökhan Simsek 0d55c20c26 Update CHANGELOG
Version 1.1 Beta changes
2017-05-11 14:19:43 +03:00
Gökhan Simsek 26d4b91251 Update README.md
Updating in-progress section
2017-05-10 18:14:22 +03:00
Gokhan Simsek 6836254234 Adding import connections capability from 1.0.0 to 1.1.0 2017-05-10 17:58:12 +03:00
Gokhan Simsek 5162291f9d Adding "Beta" string into main window title 2017-05-10 17:55:21 +03:00
Gokhan Simsek 44e3e0f3d6 Updating version to 1.1.0 2017-05-10 17:54:30 +03:00
Gokhan Simsek 5ae9f76629 Removing the changes related to showing NumberDecimal type more readabl. Showing NumberDecimal values as it is without change, same as mongo shell shows on command line. 2017-05-10 17:37:05 +03:00
Gokhan Simsek a9ec2c1b6d Upgrading esprima.js version to 2.7.3 to support ECMAScript 2015 (Modernized JavaScript Implementation aka ES6) features 2017-05-10 17:20:52 +03:00
Gokhan Simsek 4ccbbced54 Fix for the problem where Users folder was not removing its "..." after double click operation fails. Reproducible with Atlas 3.4 free cluster. 2017-05-03 14:26:31 +03:00
Gokhan Simsek da62ca474b NumberDecimal: Remove trailing zeros (and '.' conditionally) only if there is '.' and no 'E' 2017-05-03 14:21:19 +03:00
Gökhan Simsek e02696d47d Update README.md 2017-04-29 17:45:36 +03:00
Gokhan Simsek 6dc29b910c Adding new icon for type NumberDecimal (Decimal128) 2017-04-28 20:25:45 +03:00
Gokhan Simsek 7e76d29ddf First changes to support new MongoDB 3.4 type NumberDecimal (Decimal128) 2017-04-28 20:25:45 +03:00
Gokhan Simsek 0bad62dfd4 ReplicaSets: Change to fix problem where refresh replica set folder does not refresh when server uses SSL 2017-04-28 20:25:45 +03:00
Gokhan Simsek 98807b0487 Changing Robomongo version to 2.0. Adding main window title automatically built by project major, minor versions. 2017-04-28 20:25:45 +03:00
Gokhan Simsek 78deee7ca2 mongodb_3.4: First changes for Linux to build with roboshell-3.4, connect to 3.4 databases EXcluding Mongo Atlas 3.4 with SSL. 2017-04-28 20:25:45 +03:00
Gokhan Simsek a5ccfebff5 mongodb_3.4: First changes for OSX to build with roboshell-3.4, connect to 3.4 databases including Mongo Atlas 3.4 with SSL. 2017-04-28 20:25:45 +03:00
Gokhan Simsek b39b945a6e mongodb_3.4: First changes which builds with roboshell-3.4 first commit and connects to 3.4 databases including Mongo Atlas 3.4 with SSL. 2017-04-28 20:25:45 +03:00
Gökhan Simsek 18951047eb Update CHANGELOG 2017-04-27 14:47:37 +03:00
1876 changed files with 289059 additions and 5071 deletions
+2
View File
@@ -96,3 +96,5 @@ Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
.vscode/settings.json
.vs/
+16
View File
@@ -0,0 +1,16 @@
os:
- linux
# - osx
# - windows
dist: xenial
sudo: require
language: cpp
script:
- bash bin/clean
- bash bin/configure
# - bash bin/build
# - bash bin/run-unit-tests
# end of file
+175 -67
View File
@@ -1,77 +1,187 @@
Latest Version:
Download latest version:
https://robomongo.org/download
Robo 3T 1.4.2 (Oct, 2020)
Fixes:
- Fix broken paging in DocumentDB (#1694)
Robo 3T 1.4.1 (Sep, 2020)
Fixes:
- Force light mode on macOS (#1761, #1768, #1771)
- Fix broken macOS native theme/look (#1766)
- Fix broken Windows native theme/look
Robo 3T 1.4.0 (Aug, 2020)
blog.robomongo.org/robo-3t-1-4/
New Features:
- Mongo shell 4.2 upgrade
- Support for Ubuntu 20.04 and macOS 10.15 (Catalina)
- SSH: ECDSA and Ed25519 keys support on Windows & macOS (#1719, #1530, #1590)
- Manually specify visible databases (#1696, #1368, #389)
Improvements:
- Qt Upgrade (v5.12.8 - Apr/2020, Windows & macOS only)
  - OpenSSL upgrade (v1.1.1f - Mar/2020, Windows & macOS only)
- libssh2 upgrade (v1.9.0 - Jun/2019, Windows & macOS only)
Fixes:
- Authentication database option isn't used properly (#1696)
- Add/Edit index ops fixed (re-written) (#1692)
- Crash when expanding admin users (#1728)
- Unable to run query after shell timeout reached (#1529)
Robo 3T 1.3.1 (Apr, 2019)
http://blog.robomongo.org/robo-3t-1-3
New Features:
- Biggest change in this version is Mongo Shell version upgrade from 3.4 to 4.0.5.
- Support for importing from DNS SRV based MongoDB connection strings
- Query results windows now supports tabbed output #1591 #1403
- Adding support for SCRAM-SHA-256 auth mechanism #1569
- Support for Ubuntu 18.04 and Mac 10.14.
- Support for creating version 4 UUID #1554
Improvements:
- Encrypted passwords are used in config. file instead of clear text passwords
- Showing much better error reason string from Mongo drivers for connection failures
Fixes:
- Broken create/edit/view user features fixed and updated #638 #1041
- Attempt to fix #1547: Crash when right click on existing results plus a new long running query
- Fix for application crash when adding index with invalid JSON
- 'Repair Database' in Robo3T needs a confirm dialog box #1568
- Robo 3T the input space causes connection failure #1551
- Crash when loading results + right click #1547
- Attempt to fix major connection problems seen with the second edit/add/remove document operation after MongoDB 4.0 upgrade #1603
- Attempt to fix #1581: For CRUD ops showing progress bar and disabling context menu while waiting for edit op to finish
- Fixing UI issue where Functions folder freezing with "Functions..." when fails to refresh
- Fix for #1529: Pagination does not work when the aggregation queries have dotted fields
Robo 3T 1.3.0 Beta (16 Feb, 2019)
Details: https://github.com/Studio3T/robomongo/releases/tag/v1.3.0-beta
Robo 3T 1.2.1 (19 Feb, 2018)
http://blog.robomongo.org/robo-3t-1-2
Fixes:
- Aggregate query results are not pagaeble
- Big double numbers are showing incorrectly #1447
- Editing a document from a projection causes data loss (override) (#881)
- Error: Resources temporarily unavailable. Error when starting up SSH session: -8 #1426
- robo3t 1.1 failed to start on Ubuntu 17.04 #1385
- Robo 3T is not opening on MacOS High Sierra (#1412)
- Cannot load list of indexes #1454
- Robo 3T is not buildable on latest MacOS High Sierra
Improvements
- Qt version upgraded from Qt 5.7.0 to Qt 5.9.3
- Auto switch to HTTP from HTTPS if the program crashes due to HTTPS related operations
- Improvements for Robo 3T is crashing constantly on High Sierra #1412
- PR: Improved query time formatting (#1358) #1455
Robo 3T 1.2.0 Beta (18 Dec, 2017)
https://github.com/Studio3T/robomongo/releases/tag/v1.2.0-beta
Improvements & Fixes:
- Qt version upgraded from Qt 5.7.0 to Qt 5.9.3
- Fix for "Cannot load list of indexes #1454"
- Improvements for Robo 3T is crashing constantly on High Sierra #1412
- PR: Improved query time formatting (#1358) #1455
- Fix for "Robo 3T is not buildable on latest MacOS vesion High Sierra"
- Fix attempt for "Error: Resources temporarily unavailable. Error when starting up SSH session: -8 #1426"
- Fix for "robo3t 1.1 failed to start on Ubuntu 17.04 #1385"
Robo 3T 1.1 (13 June, 2017)
http://blog.robomongo.org/robomongo-1-1/
New Features:
- MongoDB 3.4 support
- New NumberDecimal (Decimal128) data type support
- ECMAScript 2015 aka ES6 Support (Modernized JavaScript Implementation)
- Re-naming from Robomongo to Robo 3T
Improvements & Fixes:
- Stability Improvements: Fix included to prevent a crash on MACOS Sierra
- Shell timeout is configurable on UI now 'Options->Change Shell Timeout'
- Fix for Robomongo Shell Timeout Issue (silently, prematurely finishing long lasting scripts)
- Security Improvements: OpenSSL version upgrade to openssl-1.0.1u (22-Sep-2016)
- Tool chain upgrades: Modern C++14 features are enabled and usable for developers
Robomongo 1.1 Beta (12 May, 2017)
https://github.com/Studio3T/robomongo/releases/tag/v1.1.0-beta
New Features:
- MongoDB 3.4 Support
- New NumberDecimal (Decimal128) data type support
- ECMAScript 2015 (Modernized JavaScript Implementation aka ES6) Support
Improvements:
- Security Improvements: OpenSSL version upgrade to openssl-1.0.1u (22-Sep-2016)
- Tool Chain Improvements: Modern C++14 features are enabled
Robomongo 1.0 (21 Apr, 2017)
http://blog.robomongo.org/robomongo-1-0
Robomongo 1.x:
Major Features:
- Replica set support.
New Features:
- Update Notifications Bar
- Welcome Tab
- New operation logging for almost all operations.
- Welcome Wizard
Major Fixes/Improvements:
- Improved error handling (no double error windows) for almost all operations.
Improvements:
- Replica set name configurable on UI
- Configuration file system location change
- "About Robomongo" dialog changes
Fixes:
- Fix to avoid the same set name problem (https://github.com/Studio3T/robomongo/issues/1302)
- Timestamp value is represented incorrectly (https://github.com/Studio3T/robomongo/issues/1159)
- Local Timezone shows wrong date (https://github.com/Studio3T/robomongo/issues/501)
- Time zone shown as "000:00" when UTC +00:00 is used as local timezone(https://github.com/Studio3T/robomongo/issues/1309)
Robomongo 1.0-RC1 (1 Feb, 2017)
http://blog.robomongo.org/robomongo-1-rc1/
* What's new in 1.0 (21 Apr , 2017)
New Features:
- Update Notifications Bar
- Welcome Tab
- Welcome Wizard
New Features:
- Replica set support.
- New 'Attributes' column in connections list window showing connection properties such as 'Replica Set', 'SSL' and 'SSH'.
- New operation logging for almost all operations.
Improvements:
- Replica set name configurable on UI
- Configuration file system location change
- "About Robomongo" dialog changes
Fixes:
- Fix to avoid the same set name problem (https://github.com/Studio3T/robomongo/issues/1302)
- Timestamp value is represented incorrectly (https://github.com/Studio3T/robomongo/issues/1159)
- Local Timezone shows wrong date (https://github.com/Studio3T/robomongo/issues/501)
- Time zone shown as "000:00" when UTC +00:00 is used as local timezone(https://github.com/Studio3T/robomongo/issues/1309)
* What's new in 1.0-RC1 (1 Feb, 2017)
New Features:
- Replica set support.
- New 'Attributes' column in connections list window showing connection properties such as 'Replica Set', 'SSL' and 'SSH'.
- New operation logging for almost all operations.
Improvements:
- Improved error handling (no double error windows) for all fail and success conditions for the following operations:
. Create, Drop Database
. Create, Edit User
. Create, Drop, Duplicate, Rename Collection
. Insert Document
. Remove document, Delete document, Remove all documents (triggered both from explorer and from result widget)
. Refresh Users
. Refresh Functions
. Refresh Collections
. Connection establish & refresh server fail and success cases.
- Windows size is saved and restored for Edit, View and Insert Document dialogs.
- Connections are automatically imported from the latest Robomongo version.
- Better error reporting/handling and logging have been added for the operations below:
. Create, Drop Function
. Drop User
- More informative and adjusted log level prefix strings haven added for log window. (Error, Warn, Info etc..).
- After a new connection is created, now the focus goes to the newly created connection (end of list) instead of the
beginning of connections list. And when Robomongo is opened, the focus goes to the end of the connection list instead
of beginning.
- Error messages added and error handling for 'remove document', 'remove all documents' operations triggered explorer
and single or multi 'delete document' from results window have been re-implemented and improved.
- Relevant errors are shown for the following cases now:
. Drop attempt of non-existing collection.
. Duplicating a collection with a collection name which already exists finishes silently.
Fixes:
- Fix for the problem where the connections list comes empty if the Robomongo config file or it's directory do not exist.
- Fix for the problem where 'in-progress bar' widget was not centered on main window for "Update Documents/Remove Documents"
operations. https://github.com/paralect/robomongo/issues/1256
- Fix for two problems where the operations 'insert or update documents' in one tab was causing auto reloading of other
unrelated tabs and also multiple error windows to popup. https://github.com/paralect/robomongo/issues/1236
- Fix for the problem where the operations 'remove document', 'remove all documents' triggered explorer and single or
multi 'delete document' from results window were causing auto reloading of other unrelated tabs.
Improvements:
- Improved error handling (no double error windows) for all fail and success conditions for the following operations:
. Create, Drop Database
. Create, Edit User
. Create, Drop, Duplicate, Rename Collection
. Insert Document
. Remove document, Delete document, Remove all documents (triggered both from explorer and from result widget)
. Refresh Users
. Refresh Functions
. Refresh Collections
. Connection establish & refresh server fail and success cases.
- Windows size is saved and restored for Edit, View and Insert Document dialogs.
- Connections are automatically imported from the latest Robomongo version.
- Better error reporting/handling and logging have been added for the operations below:
. Create, Drop Function
. Drop User
- More informative and adjusted log level prefix strings haven added for log window. (Error, Warn, Info etc..).
- After a new connection is created, now the focus goes to the newly created connection (end of list) instead of the
beginning of connections list. And when Robomongo is opened, the focus goes to the end of the connection list instead
of beginning.
- Error messages added and error handling for 'remove document', 'remove all documents' operations triggered explorer
and single or multi 'delete document' from results window have been re-implemented and improved.
- Relevant errors are shown for the following cases now:
. Drop attempt of non-existing collection.
. Duplicating a collection with a collection name which already exists finishes silently.
Fixes:
- Fix for the problem where the connections list comes empty if the Robomongo config file or it's directory do not exist.
- Fix for the problem where 'in-progress bar' widget was not centered on main window for "Update Documents/Remove Documents"
operations. https://github.com/paralect/robomongo/issues/1256
- Fix for two problems where the operations 'insert or update documents' in one tab was causing auto reloading of other
unrelated tabs and also multiple error windows to popup. https://github.com/paralect/robomongo/issues/1236
- Fix for the problem where the operations 'remove document', 'remove all documents' triggered explorer and single or
multi 'delete document' from results window were causing auto reloading of other unrelated tabs.
Robomongo 0.9:
@@ -95,9 +205,7 @@ Robomongo 0.9:
#910, #748, #697, #699, #760, #815, #870, #892,
#894, #905, #945, #974, #978, #990, #831, #842
- SSH connection failure to servers on Ubuntu and OS X with the following error:
"Resource temporarily unavailable. Error when starting up SSH session: -8" (#1090)
"Resource temporarily unavailable. Error when starting up SSH session: -8" (#1090)
What's new in 0.9.0 Final (30 Sep, 2016)
http://blog.robomongo.org/robomongo-0-9-0-final/
+29 -8
View File
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.0.0)
cmake_minimum_required(VERSION 3.8.0)
project(Robomongo)
# Where to look first for CMake modules, before "${CMAKE_ROOT}/Modules" is checked
@@ -6,11 +6,15 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
# Project version
set(PROJECT_VERSION_MAJOR "1")
set(PROJECT_VERSION_MINOR "0")
set(PROJECT_VERSION_PATCH "0")
set(PROJECT_VERSION_MINOR "4")
set(PROJECT_VERSION_PATCH "2")
set(PROJECT_VERSION_BUILD "")
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}${PROJECT_VERSION_BUILD}")
# Enable C++17 features
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Modules
include(RobomongoPrintUtils)
include(RobomongoCMakeDefaults)
@@ -33,16 +37,33 @@ find_package(MongoDB REQUIRED)
find_package(OpenSSL REQUIRED)
if (SYSTEM_MACOSX)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
find_package(Qt5MacExtras REQUIRED)
endif()
# Projects
add_subdirectory(src/third-party/libssh2)
set(LIBSSH2_VERSION 1.9.0)
if(SYSTEM_LINUX)
set(LIBSSH2_VERSION 1.7.0)
endif()
set(LIBSSH2_DIR src/third-party/libssh2-${LIBSSH2_VERSION})
set(QJSON_VERSION 0.8.1)
set(QJSON_DIR src/third-party/qjson-${QJSON_VERSION})
set(QSCINTILLA_VERSION 2.8.4)
set(QSCINTILLA_DIR src/third-party/qscintilla-${QSCINTILLA_VERSION})
set(ESPRIMA_VERSION 2.7.3)
set(ESPRIMA_DIR src/third-party/esprima-${ESPRIMA_VERSION})
# todo: Use equivalent vars from googletest cmake files. Currently they are somehow not working.
set(GOOGLE_TEST_VERSION 1.8.1)
set(GOOGLE_TEST_DIR src/third-party/googletest-${GOOGLE_TEST_VERSION})
add_subdirectory(${LIBSSH2_DIR})
add_subdirectory(src/robomongo/ssh)
add_subdirectory(src/third-party/qjson)
add_subdirectory(src/third-party/qscintilla)
add_subdirectory(${QJSON_DIR})
add_subdirectory(${QSCINTILLA_DIR})
add_subdirectory(${GOOGLE_TEST_DIR})
add_subdirectory(src/robomongo)
# todo: Enable unit tests
# add_subdirectory(src/robomongo-unit-tests) # Disabled in Robo 1.4 due to too many link errors
# Show configuration summary
include(RobomongoConfigurationSummary)
include(RobomongoConfigurationSummary)
+3 -3
View File
@@ -1,11 +1,11 @@
Robomongo, shell-centric cross-platform MongoDB management tool.
Robo 3T, shell-centric cross-platform MongoDB management tool.
Copyright 2014-2017 3T Software Labs Ltd.
The Robomongo is released under the terms of the GNU General Public
The Robo 3T is released under the terms of the GNU General Public
License, version 3.
The Robomongo Project includes files written by third parties
The Robo 3T Project includes files written by third parties
and used with permission or subject to their respective license
agreements.
+1 -1
View File
@@ -1,3 +1,3 @@
Robomongo is a shell-centric cross-platform open source MongoDB management
Robo 3T is a shell-centric cross-platform open source MongoDB management
tool (i.e. Admin GUI). Robomongo embeds the same JavaScript engine that
powers MongoDB's mongo shell.
+52 -64
View File
@@ -1,82 +1,76 @@
About Robomongo [![Join the chat at https://gitter.im/paralect/robomongo](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/paralect/robomongo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
About Robo 3T
===============
[Robomongo](http://www.robomongo.org) is a shell-centric cross-platform MongoDB management tool. Unlike most other MongoDB admin UI tools, Robomongo embeds the actual `mongo` shell in a tabbed interface with access to a shell command line as well as GUI interaction.
[Robo 3T](http://www.robomongo.org) (formerly Robomongo *) is a shell-centric cross-platform MongoDB management tool. Unlike most other MongoDB admin UI tools, Robo 3T embeds the actual `mongo` shell in a tabbed interface with access to a shell command line as well as GUI interaction.
Starting from version 0.9, Robomongo is compatibile with MongoDB 3.x (including SCRAM-SHA-1 auth and support for WiredTiger storage engine). Robomongo 0.9 embeds the **MongoDB 3.2** shell.
The latest stable release **Robo 3T 1.4** embeds **MongoDB 4.2** shell.
Robomongo 0.8.x embeds the **MongoDB 2.4.0** shell.
What's new in latest Robomongo 1.0?
====================================
Latest release of Robomongo 1.0 includes:
- Update Notifications Bar
- Welcome Tab
- Welcome Wizard
- Replica set name configurable on UI
- Fixes to avoid same replica set name problem
- Fixes to solve various problems regarding Data and Timestamp data types
Blog: http://blog.robomongo.org/robomongo-1-0/
Blog: http://blog.robomongo.org/robo-3t-1-4/
Download: https://robomongo.org/download
Watch: [Robomongo Youtube channel](https://www.youtube.com/channel/UCM_7WAseRWeeiBikExppstA)
Older Releases: https://github.com/Studio3T/robomongo/releases
Watch: [Robo 3T Youtube channel](https://www.youtube.com/channel/UCM_7WAseRWeeiBikExppstA)
Follow: https://twitter.com/Robomongo
What's Planned for the Next Releases?
**Embedded MongoDB shell history:**
Robo 3T 1.3 upgraded to MongoDB 4.0
Robo 3T 1.1 upgraded to MongoDB 3.4
Robo 3T 0.9 upgraded to MongoDB 3.2
Robo 3T 0.8.x embeds MongoDB 2.4.0
\* [Robomongo has been acquired by 3T](https://studio3t.com/press/3t-software-labs-acquires-robomongo-the-most-widely-used-mongodb-tool/)
What's new in latest Robo 3T 1.4?
====================================
We are currently working towards [Robomongo 2.0 milestone](https://github.com/paralect/robomongo/milestone/21).
Currently in progress:
- MongoDB 3.4 Support
New Features:
- Mongo shell 4.2 upgrade
- Support for Ubuntu 20.04 and macOS 10.15 (Catalina)
- SSH: ECDSA and Ed25519 keys support on Windows & macOS (issues #1719, #1530, #1590)
- Manually specify visible databases (issues #1696, #1368, #389)
Improvements:
- Qt Upgrade (v5.12.8 - Apr/2020, Windows & macOS only)
- OpenSSL upgrade (v1.1.1f - Mar/2020, Windows & macOS only)
- libssh2 upgrade (v1.9.0 - Jun/2019, Windows & macOS only)
Plans for Future:
- User Roles
- Support execution of multiple simultaneous queries [#1161](https://github.com/paralect/robomongo/issues/1161)
- Selectable mongodb engines [#1249](https://github.com/paralect/robomongo/issues/1249)
- Enhancements for stability, running without crashes ([Stability Milestone](https://github.com/paralect/robomongo/milestone/15))
- More Documentation
- Unit Tests
- Refactoring Debug Log module
Fixes:
- Authentication database option isn't used properly (#1696)
- Add/Edit index ops fixed (re-written) (#1692)
- Crash when expanding admin users (#1728)
- IPv6 support (previously broken) restored
- Unable to run query after shell timeout reached (#1529)
Supported Platforms
===============
| MongoDB Versions |
| :-------------------- |
| 3.2 |
| 3.0 |
| 2.6 |
Note: This sections is for Robo 3T and it directly depends on what MongoDB suppports
(See: https://docs.mongodb.com/manual/administration/production-notes/#prod-notes-supported-platforms)
| MongoDB Cloud Platforms|
| :------------ |
| MongoDB Atlas |
| Compose |
| mLab |
| ObjectRocket |
| Amazon EC2 |
| MongoDB Versions | MongoDB Cloud Platforms |
| :-------------------- | :-------------------- |
| 4.2 | Mongo Atlas |
| 4.0 |
| 3.6 |
| Windows | Mac | Linux |
|:---------------------- | :---------------| :---------------------------|
| Windows 64-bit 10 | Mac OS X 10.11 | Linux Ubuntu 16.04 64-bit* |
Windows 64-bit 8.1 | Mac OS X 10.10 | Linux Ubuntu 14.04 64-bit* |
| Windows 64-bit 7 | | Linux CentOS 7 64-bit* |
| | | Linux CentOS 6 64-bit* |
\* latest stable build
| Windows | Mac | Linux |
|:---------------------- | :--------------------------------| :---------------------------|
| Windows 64-bit 10 | Mac OS X 10.15 (Catalina) | Linux Ubuntu 20.04 64-bit* |
Windows 64-bit 8.1 | Mac OS X 10.14 (Mojave) | Linux Ubuntu 18.04 64-bit* |
| Windows 64-bit 7 | Mac OS X 10.13 (High Sierra) | Linux CentOS 7 64-bit* ** |
| | | Linux CentOS 6 64-bit* ** |
\* Latest stable build
\** Support for CentOS temporarily dropped starting from version 1.1
Download
========
You can download tested install packages for OS X, Windows, and Linux from our site: [www.robomongo.org](http://www.robomongo.org).
The latest stable release is currently [**Robomongo 1.0**](http://blog.robomongo.org/robomongo-1-0/).
You can download tested installer packages for macOS, Windows, and Linux from our site: [www.robomongo.org](http://www.robomongo.org).
Support
=======
Robomongo is an open source project driven by volunteers. We'll try to get to your questions as soon as we can, but please be patient :).
Robo 3T is an open source project driven by volunteers. We'll try to get to your questions as soon as we can, but please be patient :).
You can:
@@ -84,13 +78,6 @@ You can:
- [Join developer discussion on Gitter](https://gitter.im/paralect/robomongo)
Build
=====
The wiki contains prerequisites and instructions to [Build Robomongo](https://github.com/paralect/robomongo/wiki).
If you want to compile from source yourself, you should be able to do so cleanly from a [release branch](https://github.com/paralect/robomongo/releases).
Contribute!
===========
@@ -104,8 +91,9 @@ This project is powered by open source volunteers, so we have a limited amount o
### Code Contributions
Code contributions are always welcome! Just try to follow our pre-commit checks and coding style:
- [Robomongo Code Quality](https://github.com/paralect/robomongo/wiki/Robomongo-Code-Quality)
- [Robomongo Coding Style](https://github.com/paralect/robomongo/wiki/Robomongo-Coding-Style)
- [Robo 3T Code Quality](https://github.com/paralect/robomongo/wiki/Robomongo-Code-Quality)
- [Robo 3T C++11/14 Transition Guide](https://github.com/Studio3T/robomongo/wiki/Robomongo-Cplusplus-11,-14-Transition-Guide)
- [Robo 3T Coding Style](https://github.com/paralect/robomongo/wiki/Robomongo-Coding-Style)
If you plan to contribute, please create a Github issue (or comment on the relevant existing issue) so we can help coordinate with upcoming release plans.
@@ -128,7 +116,7 @@ There are a number of issues we could use help with reproducing. They are marked
License
=======
Copyright 2014-2017 [3T Software Labs Ltd](https://studio3t.com/). All rights reserved.
Copyright 2014-2020 [3T Software Labs Ltd](https://studio3t.com/). All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
+2 -2
View File
@@ -2,7 +2,7 @@
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Get directory of this file
PROJECT_DIR=$(dirname $BIN_DIR) # Get root directory of project
source $BIN_DIR/common/setup $1
source $BIN_DIR/common/setup $1 # $1: release or debug
cd $BUILD_DIR
cmake --build . "${@:2}" -- -j8
cmake --build . "${@:2}" -- -j8
+5
View File
@@ -13,3 +13,8 @@ if %ERRORLEVEL% neq 0 (exit /b 1)
rem Run build
cd "%BUILD_DIR%"
cmake --build . --config %BUILD_TYPE%
rem Install debug *.dll files
if "%BUILD_TYPE%" == "Debug" (
call "%BIN_DIR%\install_debug_dlls.bat" %*
)
+20
View File
@@ -0,0 +1,20 @@
@echo off
setlocal enableextensions enabledelayedexpansion
rem Path to bin and project folder
set BIN_DIR_WITH_BACKSLASH=%~dp0%
set BIN_DIR=%BIN_DIR_WITH_BACKSLASH:~0,-1%
set PROJECT_DIR=%BIN_DIR%\..
rem Run common setup code
call "%BIN_DIR%\common\setup.bat" %*
if %ERRORLEVEL% neq 0 (exit /b 1)
rem Run build with Visual Studio with RunCodeAnalysis
cd "%BUILD_DIR%"
cmake --build . --config %BUILD_TYPE% -- "/p:RunCodeAnalysis=true" "/p:CodeAnalysisRuleSet=NativeRecommendedRules.ruleset"
rem Install debug *.dll files
if "%BUILD_TYPE%" == "Debug" (
call "%BIN_DIR%\install_debug_dlls.bat" %*
)
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Get directory of this file
PROJECT_DIR=$(dirname $BIN_DIR) # Get root directory of project
source $BIN_DIR/build || exit $?
source $BIN_DIR/run_tests $1
+15
View File
@@ -0,0 +1,15 @@
@echo off
setlocal enableextensions enabledelayedexpansion
rem Path to bin and project folder
set BIN_DIR_WITH_BACKSLASH=%~dp0%
set BIN_DIR=%BIN_DIR_WITH_BACKSLASH:~0,-1%
set PROJECT_DIR=%BIN_DIR%\..
rem Run build
call "%BIN_DIR%\build.bat" %*
if %ERRORLEVEL% neq 0 (exit /b 1)
rem Run tests
call "%BIN_DIR%\run_tests.bat" %*
if %ERRORLEVEL% neq 0 (exit /b 1)
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
echo "Building with scan-build in debug mode..."
echo "------------------------------------------------"
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Get directory of this file
PROJECT_DIR=$(dirname $BIN_DIR) # Get root directory of project
source $BIN_DIR/common/setup debug # release or debug
cd $BUILD_DIR
scan-build cmake --build . "${@:2}" -- -j8
# Hint: Use "--use-analyzer /usr/local/opt/llvm/bin/clang++" after "-v"
+1 -1
View File
@@ -44,6 +44,6 @@ if [ "$(uname -s)" == "Darwin" ]; then
# variable. If both the command-line option is specified and the
# environment variable is set, the command-line option will take precedence.
#
export MACOSX_DEPLOYMENT_TARGET=10.9
export MACOSX_DEPLOYMENT_TARGET=10.13
fi
+3 -2
View File
@@ -2,7 +2,8 @@
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Get directory of this file
PROJECT_DIR=$(dirname $BIN_DIR) # Get root directory of project
source $BIN_DIR/common/setup $1
source $BIN_DIR/common/setup $1 # $1: release or debug
cd $BUILD_DIR
cmake -D "CMAKE_PREFIX_PATH=$PREFIX_PATH" -D "CMAKE_BUILD_TYPE=$BUILD_TYPE" -D "CMAKE_INSTALL_PREFIX=$INSTALL_PREFIX" "${@:2}" $PROJECT_DIR
# $BUILD_TYPE: Release or Debug
cmake -D "CMAKE_PREFIX_PATH=$PREFIX_PATH" -D "CMAKE_BUILD_TYPE=$BUILD_TYPE" -D "CMAKE_INSTALL_PREFIX=$INSTALL_PREFIX" "${@:2}" $PROJECT_DIR
+2 -1
View File
@@ -11,5 +11,6 @@ call "%BIN_DIR%\common\setup.bat" %*
if %ERRORLEVEL% neq 0 (exit /b 1)
rem Run CMake configuration step
rem BUILD_TYPE: Release or Debug
cd "%BUILD_DIR%"
cmake -G "Visual Studio 12 2013 Win64" -D "CMAKE_PREFIX_PATH=%PREFIX_PATH%" -D "CMAKE_BUILD_TYPE=%BUILD_TYPE%" -D "CMAKE_INSTALL_PREFIX=%INSTALL_PREFIX%" %PROJECT_DIR%
cmake -G "Visual Studio 15 2017 Win64" -D "CMAKE_PREFIX_PATH=%PREFIX_PATH%" -D "CMAKE_BUILD_TYPE=%BUILD_TYPE%" -D "CMAKE_INSTALL_PREFIX=%INSTALL_PREFIX%" %PROJECT_DIR%
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
echo "Configuring with scan-build in debug mode..."
echo "------------------------------------------------"
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Get directory of this file
PROJECT_DIR=$(dirname $BIN_DIR) # Get root directory of project
source $BIN_DIR/common/setup debug # debug
cd $BUILD_DIR
BUILD_TYPE=Debug # $BUILD_TYPE: Release or Debug
scan-build -v cmake -D "CMAKE_PREFIX_PATH=$PREFIX_PATH" -D "CMAKE_BUILD_TYPE=$BUILD_TYPE" -D "CMAKE_INSTALL_PREFIX=$INSTALL_PREFIX" "${@:2}" $PROJECT_DIR
# Hint: Use "--use-analyzer /usr/local/opt/llvm/bin/clang++" after "-v"
+46
View File
@@ -0,0 +1,46 @@
@echo off
setlocal enableextensions enabledelayedexpansion
rem // This script installs debug *.dll files
rem -------------------------------------------
set INSTALL_DIR=%BUILD_DIR%\src\robomongo\Debug\
if not exist %INSTALL_DIR%*.dll (
echo ----------------------------------------
echo Installing debug *.dll files ...
echo INSTALL_DIR: %INSTALL_DIR%
echo ----------------------------------------
)
rem // Find OpenSSL and Qt paths
for %%i in (%ROBOMONGO_CMAKE_PREFIX_PATH%) do (
set xx=%%i
if not "!xx!"=="!xx:ssl=!" ( set OPENSSL_DIR=!xx! )
if not "!xx!"=="!xx:qt=!" ( set Qt_DIR=!xx! )
)
set OPENSSL_DIR=%OPENSSL_DIR: =%
set Qt_DIR=%Qt_DIR: =%
rem // Copy dll files
for /d %%a in (
"%VS140COMNTOOLS%\..\..\VC\redist\debug_nonredist\x64\Microsoft.VC140.DebugCRT\msvcp140d.dll"
"%VS140COMNTOOLS%\..\..\VC\redist\debug_nonredist\x64\Microsoft.VC140.DebugCRT\vcruntime140d.dll"
"%OPENSSL_DIR%\libssl-1_1-x64.dll"
"%OPENSSL_DIR%\libcrypto-1_1-x64.dll"
"%Qt_DIR%\bin\Qt5Cored.dll"
"%Qt_DIR%\bin\Qt5Guid.dll"
"%Qt_DIR%\bin\Qt5Networkd.dll"
"%Qt_DIR%\bin\Qt5Widgetsd.dll"
) do (
if not exist !INSTALL_DIR!%%~NXa (
xcopy %%a !INSTALL_DIR! /d /y
)
)
if not exist %INSTALL_DIR%\imageformats\qgifd.dll (
xcopy /s "%Qt_DIR%\plugins\imageformats" %INSTALL_DIR%\imageformats\ /d /y
)
if not exist %INSTALL_DIR%\platforms\qminimald.dll (
xcopy /s "%Qt_DIR%\plugins\platforms" %INSTALL_DIR%\platforms\ /d /y
)
+5 -3
View File
@@ -6,7 +6,9 @@ source $BIN_DIR/common/setup $1
if [ "$(uname -s)" == "Darwin" ]; then
# On Mac OS we should run executable from bundle
"$BUILD_DIR/src/robomongo/Robomongo.app/Contents/MacOS/Robomongo"
"$BUILD_DIR/src/robomongo/Robo 3T.app/Contents/MacOS/Robo 3T"
else
"$BUILD_DIR/src/robomongo/robomongo"
fi
echo "Note: ./install must be executed before this script."
echo "Starting $BUILD_DIR/install/bin/robo3t..."
"$BUILD_DIR/install/bin/robo3t"
fi
Executable
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
BIN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # Get directory of this file
PROJECT_DIR=$(dirname $BIN_DIR) # Get root directory of project
source $BIN_DIR/common/setup $1
echo
echo "******************* Running unit tests in $BUILD_TYPE mode *******************"
echo
if [ "$(uname -s)" == "Darwin" ]; then
EXE="$BUILD_DIR/src/robomongo-unit-tests/robo_unit_tests"
echo "Running file: $EXE"
"$EXE"
else # Linux
echo "Error: Currently unit testing is disabled for Linux due to MongoDB linking problem"
exit 0
EXE="$BUILD_DIR/src/robomongo-unit-tests/robo_unit_tests"
echo "Running file: $EXE"
"$EXE"
fi
+15
View File
@@ -0,0 +1,15 @@
@echo off
setlocal enableextensions enabledelayedexpansion
rem Path to bin and project folder
set BIN_DIR_WITH_BACKSLASH=%~dp0%
set BIN_DIR=%BIN_DIR_WITH_BACKSLASH:~0,-1%
set PROJECT_DIR=%BIN_DIR%\..
rem Run tests
echo.
echo ******************* Running unit tests for Release mode *******************
echo ** Note: Only Release mode is supported on Windows
echo.
echo "Running file: \build\Release\src\robomongo-unit-tests\Release\robo_unit_tests.exe"
call "%PROJECT_DIR%\\build\Release\src\robomongo-unit-tests\Release\robo_unit_tests.exe" %*
+38 -11
View File
@@ -41,38 +41,46 @@ set(MongoDB_DEFINITIONS
BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
BOOST_THREAD_HAS_BUG
MONGO_CONFIG_HAVE_HEADER_UNISTD_H
# Suppress "warning C4996: std::allocator..." from third_party\abseil-cpp-master
_SILENCE_CXX17_OLD_ALLOCATOR_MEMBERS_DEPRECATION_WARNING
# Suppress "warning C4996: std::iterator..." from third_party\mozjs-60
_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING
)
# Set common compiler include directories
set(MOZJS_VER mozjs-60)
set(MongoDB_INCLUDE_DIRS
${MongoDB_DIR}/src
${MongoDB_DIR}/src/third_party/boost-1.56.0
${MongoDB_DIR}/src/third_party/mozjs-38/include
${MongoDB_DIR}/src/third_party/mozjs-38/mongo_sources
${MongoDB_DIR}/src/third_party/pcre-8.37
${MongoDB_DIR}/src
${MongoDB_DIR}/src/third_party/abseil-cpp-master/abseil-cpp
${MongoDB_DIR}/src/third_party/boost-1.70.0
${MongoDB_DIR}/src/third_party/fmt/dist/include
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/include
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/mongo_sources
${MongoDB_DIR}/src/third_party/pcre-8.42
${MongoDB_DIR}/src/third_party/SafeInt
${MongoDB_BUILD_DIR}
)
if(SYSTEM_LINUX)
set(MongoDB_OBJECT_LIST_PLATFORM_PART linux)
list(APPEND MongoDB_INCLUDE_DIRS
${MongoDB_DIR}/src/third_party/mozjs-38/platform/x86_64/linux/include)
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/platform/x86_64/linux/include)
elseif(SYSTEM_WINDOWS)
set(MongoDB_OBJECT_LIST_PLATFORM_PART windows)
list(APPEND MongoDB_INCLUDE_DIRS
${MongoDB_DIR}/src/third_party/mozjs-38/platform/x86_64/windows/include)
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/platform/x86_64/windows/include)
elseif(SYSTEM_MACOSX)
set(MongoDB_OBJECT_LIST_PLATFORM_PART macosx)
list(APPEND MongoDB_INCLUDE_DIRS
${MongoDB_DIR}/src/third_party/mozjs-38/platform/x86_64/osx/include)
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/platform/x86_64/macOS/include)
elseif(SYSTEM_FREEBSD)
set(MongoDB_OBJECT_LIST_PLATFORM_PART freebsd)
list(APPEND MongoDB_INCLUDE_DIRS
${MongoDB_DIR}/src/third_party/mozjs-38/platform/x86_64/freebsd/include)
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/platform/x86_64/freebsd/include)
elseif(SYSTEM_OPENBSD)
set(MongoDB_OBJECT_LIST_PLATFORM_PART openbsd)
list(APPEND MongoDB_INCLUDE_DIRS
${MongoDB_DIR}/src/third_party/mozjs-38/platform/x86_64/openbsd/include)
${MongoDB_DIR}/src/third_party/${MOZJS_VER}/platform/x86_64/openbsd/include)
endif()
# Read list of object files
@@ -86,11 +94,30 @@ string(STRIP "${MongoDB_RELATIVE_LIBS}" MongoDB_RELATIVE_LIBS)
# Convert string to list
string(REPLACE " " ";" MongoDB_RELATIVE_LIBS ${MongoDB_RELATIVE_LIBS})
# todo: Find a better solution
# Robo 1.4: Added as workaround fix for build error:
# fatal error LNK1170: line in command file contains 131071 or more characters
# Happens when the path of robo-shell is a long string (e.g. "E:/user/code/robomongo-shell")
set(MongoDB_OBJECTS_DIR_ENV $ENV{MongoDB_OBJECTS})
if(MongoDB_OBJECTS_DIR_ENV)
set(MongoDB_OBJECTS_DIR ${MongoDB_OBJECTS_DIR_ENV})
else()
set(MongoDB_OBJECTS_DIR ${MongoDB_DIR})
endif()
# Convert to absolute path
foreach(lib ${MongoDB_RELATIVE_LIBS})
list(APPEND MongoDB_LIBS ${MongoDB_DIR}/${lib})
list(APPEND MongoDB_LIBS ${MongoDB_OBJECTS_DIR}/${lib})
endforeach()
if(SYSTEM_WINDOWS)
list(APPEND MongoDB_LIBS Crypt32.lib Secur32.lib Dnsapi.lib winhttp.lib)
elseif(SYSTEM_MACOSX)
list(APPEND MongoDB_LIBS -lcurl)
elseif(SYSTEM_LINUX)
list(APPEND MongoDB_LIBS -lresolv -lcurl)
endif()
# Get MongoDB repository recent tag
execute_process(
COMMAND git describe --abbrev=0 --tags
+18 -27
View File
@@ -14,7 +14,6 @@
# Try to find OpenSSL directory (uses CMAKE_PREFIX_PATH locations)
#-------------------------------------------
find_path(
OpenSSL_DIR include/openssl/ssl.h
DOC "Path to OpenSSL (github.com/openssl/openssl) root directory"
@@ -22,12 +21,7 @@ find_path(
# Find OpenSSL version
#-------------------------------------------
if(SYSTEM_WINDOWS)
set (OPENSSL_INCLUDE_DIR "${OpenSSL_DIR}/inc32")
else()
set (OPENSSL_INCLUDE_DIR "${OpenSSL_DIR}/include")
endif()
set (OPENSSL_INCLUDE_DIR "${OpenSSL_DIR}/include")
function(from_hex HEX DEC)
string(TOUPPER "${HEX}" HEX)
@@ -106,33 +100,30 @@ add_library(ssl SHARED IMPORTED)
# Add imported target for crypto (libeay32)
add_library(crypto SHARED IMPORTED)
# todo: refactor
if(SYSTEM_WINDOWS)
set_target_properties(ssl PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/inc32"
IMPORTED_IMPLIB "${OpenSSL_DIR}/out32dll/ssleay32.lib"
)
set_target_properties(crypto PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/inc32"
IMPORTED_IMPLIB "${OpenSSL_DIR}/out32dll/libeay32.lib"
)
elseif(SYSTEM_MACOSX)
set_target_properties(ssl PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/include"
IMPORTED_LOCATION "${OpenSSL_DIR}/libssl.dylib"
IMPORTED_IMPLIB "${OpenSSL_DIR}/libssl.lib"
)
set_target_properties(crypto PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/include"
IMPORTED_LOCATION "${OpenSSL_DIR}/libcrypto.dylib"
)
elseif(SYSTEM_LINUX)
set_target_properties(ssl PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/include"
IMPORTED_LOCATION "${OpenSSL_DIR}/libssl.so"
)
set_target_properties(crypto PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/include"
IMPORTED_LOCATION "${OpenSSL_DIR}/libcrypto.so"
IMPORTED_IMPLIB "${OpenSSL_DIR}/libcrypto.lib"
)
else()
if(SYSTEM_MACOSX)
SET(EXT "dylib")
elseif(SYSTEM_LINUX)
SET(EXT "so")
endif()
set_target_properties(ssl PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/include"
IMPORTED_LOCATION "${OpenSSL_DIR}/libssl.${EXT}"
)
set_target_properties(crypto PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OpenSSL_DIR}/include"
IMPORTED_LOCATION "${OpenSSL_DIR}/libcrypto.${EXT}"
)
endif()
# End of file
+2 -2
View File
@@ -1,3 +1,3 @@
set(ROBOMONGO_DISPLAY_NAME "Robomongo")
set(ROBOMONGO_DISPLAY_FULL_NAME "Robomongo ${PROJECT_VERSION}")
set(ROBOMONGO_DISPLAY_NAME "Robo 3T")
set(ROBOMONGO_DISPLAY_FULL_NAME "Robo 3T ${PROJECT_VERSION}")
+22 -12
View File
@@ -1,17 +1,23 @@
# Show configuration summary and build tip
message("")
message(" _______________[ Robomongo configuration summary ]________________")
message(" _______________[ Robo 3T configuration summary ]________________")
message("| ")
message("|-- Dependencies:")
message("| ")
message("| Qt5 Core: ${Qt5Core_VERSION} ${Qt5Core_DIR}")
message("| Qt5 Gui: ${Qt5Gui_VERSION} ${Qt5Gui_DIR}")
message("| Qt5 Widgets: ${Qt5Widgets_VERSION} ${Qt5Widgets_DIR}")
message("| Qt5 PrintSupport: ${Qt5Widgets_VERSION} ${Qt5PrintSupport_DIR}")
message("| Qt5 Network: ${Qt5Network_VERSION} ${Qt5Network_DIR}")
message("| Qt5 Xml: ${Qt5Xml_VERSION} ${Qt5Xml_DIR}")
message("| Qt5 Core: ${Qt5Core_VERSION} ${Qt5Core_DIR}")
message("| Qt5 Gui: ${Qt5Gui_VERSION} ${Qt5Gui_DIR}")
message("| Qt5 Widgets: ${Qt5Widgets_VERSION} ${Qt5Widgets_DIR}")
message("| Qt5 PrintSupport: ${Qt5Widgets_VERSION} ${Qt5PrintSupport_DIR}")
message("| Qt5 Network: ${Qt5Network_VERSION} ${Qt5Network_DIR}")
message("| Qt5 Xml: ${Qt5Xml_VERSION} ${Qt5Xml_DIR}")
message("| MongoDB: ${MongoDB_VERSION} ${MongoDB_BUILD_DIR}")
message("| MongoDB Objects: ${MongoDB_VERSION} ${MongoDB_OBJECTS_DIR}/build")
message("| OpenSSL: ${OPENSSL_VERSION} ${OpenSSL_DIR}")
message("| libssh2: ${LIBSSH2_VERSION} ${LIBSSH2_DIR}")
message("| QJson: ${QJSON_VERSION} ${QJSON_DIR}")
message("| QScintilla: ${QSCINTILLA_VERSION} ${QSCINTILLA_DIR}")
message("| Google Test: ${GOOGLE_TEST_VERSION} ${GOOGLE_TEST_DIR}")
message("| ESPRIMA: ${ESPRIMA_VERSION} ${ESPRIMA_DIR}")
message("|")
message("|-- Summary:")
message("|")
@@ -20,14 +26,18 @@ if (SYSTEM_MACOSX)
message("| Target SDK: ${CMAKE_OSX_DEPLOYMENT_TARGET}")
endif()
message("| Build type: ${CMAKE_BUILD_TYPE}")
message("| Build number: ${BUILD_NUMBER}")
message("| Install path: ${CMAKE_INSTALL_PREFIX}")
message("|")
message("|-- Building and installing:")
message("|-- Build, Run and Install:")
message("| ")
message("| Now you can build Robomongo with the following command:")
message("| $ cmake --build .")
message("| $ bin/build")
message("| $ bin/run")
message("| $ bin/install")
message("|")
message("| And install it to ${CMAKE_INSTALL_PREFIX}:")
message("| $ cmake --build . --target install")
message("|-- Run Unit Tests:")
message("| ")
message("| $ bin/build_and_run_tests")
message("| $ bin/run_tests (without building)")
message("|__________________________________________________________________")
message("")
+20 -6
View File
@@ -24,10 +24,11 @@ if(SYSTEM_LINUX)
set(qt_conf_dir ${bin_dir})
set(qt_conf_plugins "../lib")
elseif(SYSTEM_MACOSX)
set(bundle_name "Robomongo.app")
set(bundle_name "Robo 3T.app")
set(contents_path ${bundle_name}/Contents)
set(bin_dir ${contents_path}/MacOS)
set(styles_dir ${contents_path}/MacOS/styles)
set(lib_dir ${contents_path}/Frameworks)
set(resources_dir ${contents_path}/Resources)
set(license_dir ${resources_dir})
@@ -37,6 +38,7 @@ elseif(SYSTEM_MACOSX)
set(qt_conf_plugins "PlugIns/Qt")
elseif(SYSTEM_WINDOWS)
set(bin_dir .)
set(styles_dir ${bin_dir}/styles)
set(lib_dir .)
set(resources_dir .)
set(license_dir .)
@@ -60,14 +62,14 @@ install(
if(SYSTEM_WINDOWS)
install(
FILES
"${OpenSSL_DIR}/out32dll/ssleay32.dll"
"${OpenSSL_DIR}/out32dll/libeay32.dll"
"${OpenSSL_DIR}/libssl-1_1-x64.dll"
"${OpenSSL_DIR}/libcrypto-1_1-x64.dll"
DESTINATION ${bin_dir})
elseif(SYSTEM_MACOSX)
install(
FILES
"${OpenSSL_DIR}/libssl.1.0.0.dylib"
"${OpenSSL_DIR}/libcrypto.1.0.0.dylib"
"${OpenSSL_DIR}/libssl.1.1.dylib"
"${OpenSSL_DIR}/libcrypto.1.1.dylib"
DESTINATION ${lib_dir}/lib)
elseif(SYSTEM_LINUX)
install(
@@ -98,12 +100,18 @@ install(
install_qt_lib(Core Gui Widgets PrintSupport Network Xml)
install_qt_plugins(QGifPlugin QICOPlugin)
install_icu_libs()
set(QT_STYLES_DIR ${Qt5Core_DIR}/../../../plugins/styles/)
if(SYSTEM_LINUX)
install_qt_lib(XcbQpa DBus)
install_qt_plugins(
QXcbIntegrationPlugin)
install(
FILES
"/usr/lib/x86_64-linux-gnu/libstdc++.so.6"
"/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28"
DESTINATION ${lib_dir})
elseif(SYSTEM_MACOSX)
install_qt_lib(MacExtras DBus)
install_qt_plugins(
@@ -115,12 +123,18 @@ elseif(SYSTEM_MACOSX)
install(
FILES "${CMAKE_SOURCE_DIR}/install/macosx/robomongo.icns"
DESTINATION "${resources_dir}")
# Install styles
install(FILES "${QT_STYLES_DIR}/libqmacstyle.dylib" DESTINATION ${styles_dir})
elseif(SYSTEM_WINDOWS)
install_qt_plugins(
QWindowsIntegrationPlugin
QMinimalIntegrationPlugin
QOffscreenIntegrationPlugin)
# Install Styles
install(FILES "${QT_STYLES_DIR}/qwindowsvistastyle.dll" DESTINATION ${styles_dir})
# Install runtime libraries:
# msvcp120.dll
# msvcr120.dll
+4 -4
View File
@@ -15,7 +15,7 @@ execute_process(
string(TIMESTAMP timestamp "%Y-%m-%d")
# Package name (as it should appear in UI)
set(CPACK_PACKAGE_NAME robomongo)
set(CPACK_PACKAGE_NAME robo3t)
# Version of the package
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
@@ -35,9 +35,9 @@ set(CPACK_STRIP_FILES ON)
# Additional information
set(CPACK_PACKAGE_VENDOR "3T Software Labs Ltd")
set(CPACK_PACKAGE_CONTACT robomongo@3t.io)
set(CPACK_PACKAGE_CONTACT robo3t@3t.io)
set(CPACK_PACKAGE_DESCRIPTION "Shell-centric cross-platform MongoDB management tool.")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Robomongo is a shell-centric cross-platform MongoDB management tool.")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Robo 3T is a shell-centric cross-platform MongoDB management tool.")
# Use lowercase for system name and package file name
string(TOLOWER ${CMAKE_SYSTEM_NAME} system_name)
@@ -62,7 +62,7 @@ elseif(SYSTEM_MACOSX)
elseif(SYSTEM_WINDOWS)
set(files_dir "${CMAKE_SOURCE_DIR}/install/windows")
set(exe_name "robomongo.exe")
set(exe_name "robo3t.exe")
set(CPACK_GENERATOR NSIS ZIP)
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/DESCRIPTION")
+3 -3
View File
@@ -15,13 +15,13 @@ elseif(SYSTEM_WINDOWS)
set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_CXX_STANDARD_LIBRARIES} psapi.lib bcrypt.lib Iphlpapi.lib dbghelp.lib ws2_32.lib winmm.lib version.lib")
endif()
set(PROJECT_NAME "Robomongo")
set(PROJECT_NAME "Robo 3T")
set(PROJECT_NAME_TITLE ${PROJECT_NAME})
set(PROJECT_DOMAIN "www.robomongo.org")
set(PROJECT_COMPANYNAME "3T Software Labs Ltd")
set(PROJECT_COPYRIGHT "Copyright (C) 2014-2017 ${PROJECT_COMPANYNAME} All Rights Reserved.")
set(PROJECT_COMPANYNAME_DOMAIN "https://studio3t.com/")
set(PROJECT_GITHUB_FORK "www.github.com/paralect/robomongo")
set(PROJECT_GITHUB_ISSUES "www.github.com/paralect/robomongo/issues")
set(PROJECT_GITHUB_FORK "www.github.com/Studio3T/robomongo")
set(PROJECT_GITHUB_ISSUES "www.github.com/Studio3T/robomongo/issues")
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+235
View File
@@ -0,0 +1,235 @@
Building Robo 3T (macOS and Linux)
==================
A. Prerequisites
-------------
1. Modern Compiler
A modern and complete C++17 compiler:
```
GCC 8.0 or newer
Clang 7 (or Apple XCode 10 Clang) or newer
On Linux and macOS, the libcurl library and header is required. macOS includes libcurl.
Fedora/RHEL - dnf install libcurl-devel
Ubuntu/Debian - apt-get install libcurl-dev
Python 3.7
```
For details see: https://github.com/mongodb/mongo/wiki/Build-Mongodb-From-Source
2. Install CMake (3.10.0 or later)
Example:
```
sudo apt-get install build-essential
// or
wget http://www.cmake.org/files/v3.10/cmake-3.10.0.tar.gz
tar xf cmake-3.10.0.tar.gz
cd cmake-3.10.0
./configure // macos: env CC=gcc ./bootstrap
make
sudo make install
(sudo make uninstall)
```
3. Install [Scons](http://scons.org/tag/releases.html) (3.1.2 or later)
```
cd scons-**
python setup.py install
```
4. Install Qt
macOS: Qt 5.12.8
Linux: Qt 5.9.3
```sh
Example installation for macOS and Ubuntu:
Go to http://download.qt.io/archive/qt/5.x/5.x.y/
Download, run and install
qt-opensource-mac-x64-clang-5.x.y.dmg (for macOS)
qt-opensource-linux-x64-5.x.y.run (for Linux)
After successful installation you should have
/path/to/qt-5.x.y/5.x/clang_64 (for macOS)
/path/to/qt-5.x.y/5.x/gcc_64 (for Linux)
More information for installing on Ubuntu:
https://wiki.qt.io/Install_Qt_5_on_Ubuntu
```
5. Download and Build OpenSSL - (explained below in section B)
B. Building Robo 3T and Dependencies
-------------
Ref: https://wiki.openssl.org/index.php/Compilation_and_Installation#OS_X
#### 1. Build OpenSSL
(Todo: Can we find pre-built OpenSSL? To check => https://wiki.openssl.org/index.php/Binaries)
Version 1.1.1f (Mar/2020) on macOS
Version 1.0.2o (Mar/2018) on Linux
**macOS:**
```sh
wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1f.tar.gz
tar -xf openssl-1.1.1f.tar.gz
cd /opt/openssl-1.1.1f
(make clean)
./Configure darwin64-x86_64-cc shared no-ssl2 no-ssl3 no-comp
// Info: With openssl version 1.1.1, configure command with rpath stopped working
// Last working configure command with rpath was:
// ./Configure darwin64-x86_64-cc shared --openssldir="@rpath"
make (or sudo make)
// Verify libssl.dylib and libcrypto.dylib file are created
mkdir lib
cp lib*.dylib lib/
// Due to broken './Configure' command with rpath above, these extra steps are also required:
install_name_tool -id "@rpath/lib/libssl.1.1.dylib" libssl.dylib
install_name_tool -change /usr/local/lib/libcrypto.1.1.dylib @rpath/lib/libcrypto.1.1.dylib libssl.dylib
install_name_tool -id "@rpath/lib/libcrypto.1.1.dylib" libcrypto.dylib
// Finally, we should have this output using otool:
otool -L libssl.dylib
libssl.dylib:
@rpath/lib/libssl.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
@rpath/lib/libcrypto.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
otool -L libcrypto.dylib
libcrypto.dylib:
@rpath/lib/libcrypto.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
```
**Linux:**
```sh
wget https://www.openssl.org/source/old/1.0.2/openssl-1.0.2o.tar.gz
tar -xf openssl-1.0.2o.tar.gz
cd /opt/openssl-1.0.2o
(make clean)
./config shared
make
// Verify libssl.so and libcrypto.so are created
```
#### 2. Build Robo 3T Shell (fork of MongoDB)
Clone Robo 3T Shell and make sure you are on latest branch:
```sh
$ git clone https://github.com/paralect/robomongo-shell.git
$ cd robomongo-shell
$ git branch // "roboshell-v4.2"
```
Set special environment variable `ROBOMONGO_CMAKE_PREFIX_PATH` to point to a set of
directories:
1. Location of Qt 5 SDK
2. Location of Robo 3T Shell
3. Location of OpenSSL
Separate directories by semicolon `;` (not colon):
// macOS example:
export ROBOMONGO_CMAKE_PREFIX_PATH="/path/to/qt-5.x.y/5.x/clang_64;/opt/robo-shell;/opt/openssl-x.y.z"
// Ubuntu example:
export ROBOMONGO_CMAKE_PREFIX_PATH="/home/<user>/Qt5.x.y/5.x.y/gcc_64/;/opt/<user>/robo-shell;/opt/openssl-x.y.z"
Install pip requirements
```
// macOS / Linux
pip3 install --user -r etc/pip/compile-requirements.txt
pip3 install --user -r etc/pip/dev-requirements.txt
```
```
// For ubuntu, the followings might be needed
sudo aptitude install libcurl-dev
sudo pip3 install Typing
sudo pip3 install Cheetah
```
Build Robo 3T Shell (in release mode by default):
```sh
$ bin/build
```
Build Robo 3T Shell in debug mode:
```sh
$ bin/build debug
```
Clean build files for release mode:
```sh
$ bin/clean
```
Clean build files for debug mode:
```sh
$ bin/clean debug
```
For more information refer to [Building Robo 3T Shell](BuildRobo3TShell.md)
#### 3. Build Robo 3T
Download Robo 3T:
$ git clone https://github.com/Studio3T/robomongo
$ cd robomongo
Run configuration step:
$ bin/configure
And finally, build Robo 3T:
$ bin/build
To run robomongo:
$ bin/run
**Debug mode**
For debug mode append `debug` for each command
e.g. `bin/configure debug` or `bin/build debug` etc..
**Helper commands**
Clean build files (in order to start build from scratch):
$ bin/clean
Install Robo 3T to `build/release/install` folder:
$ bin/install
Create package for your OS in `build/release/package` folder:
$ bin/pack
**Important Notes**
- For macOS builds, it might be needed to patch QScintilla with `QScintilla-2.9.3-xcode8.patch` found at robomongo repository's root.
- For Ubuntu 16.04 builds, it has been reported that Robo 3T /bin/configure step might fail and installing `mesa-common-dev` package solves it. Details: https://github.com/paralect/robomongo/issues/1268
- For Centos builds, Robo 3T /bin/configure step might fail due to error: `failed to find gl/gl.h`. In this case, the following packages must be installed:
```sh
$ sudo yum install mesa-libGL
$ sudo yum install mesa-libGL-devel
```
+229
View File
@@ -0,0 +1,229 @@
Building Robo 3T (Windows)
==============================
A. Prerequisites
-------------
#### 0. Git
Download Git installer from http://git-scm.com (we are using Git-2.7.0-64-bit).
When you'll see "Adjusting your PATH environment" wizard page, select
"Use Git from the Windows Command Prompt" option. This will allow to
execute Git from both Windows Command Prompt and Bash. This is required,
because both MongoDB and Robo 3T uses `git` command during build process
which must be perfomed from Windows Command Prompt (not Bash).
On "Configuring the line ending conversion" wizard page, select "Checkout
Windows-style, commit Unix-style line ending" option. This is a common mode
for cross-platform projects and required by both MongoDB and Robo 3T.
All other Git installer options are not important (use defaults).
If you are using SSH clone url, start SSH agent and add your private key
with this commands in Git Bash:
$ eval `ssh-agent` # starts ssh agent
$ ssh-add ~/.ssh/mykey # add your key (which can be in any folder)
#### 1. Visual Studio 2017 version 15.9 or newer (complete C++17 compiler)
We use Visual Studio 2017 version 15.9.22, and recommend to use this version to save
time for Qt compilation. Currently prebuilt binaries for Qt are available
from official Qt site. But you can use any newer version and compile Qt library
yourself.
#### 2. ActivePython 3.7.4
Download ActivePython from http://www.activestate.com/activepython/downloads
Download MSI x64 version. Use default settings in installation wizard.
This installer will add path to `python.exe` to your `PATH` variable.
#### 3. SCons 3.1.2 or newer
We use SCons 3.1.2
Download Scons from http://scons.org/tag/releases.html
Use ZIP archive, not MSI
Open Command Prompt, navigate to Scons directory and run:
$ setup.py install
This command will make `scons` command accessible from Command Prompt
#### 4. CMake
We use CMake 3.10.0
Download CMake from https://cmake.org/download
Use installer package, it will allow you to configure your PATH variable and `cmake`
command will be available from Command Prompt. For this set "Add CMake to the system
PATH for current user" in the installer wizard page.
#### 5. Qt 5.12.8
Download and install Qt from http://download.qt.io/archive/qt
Run the installer and select only 'msvc2017 64-bit'
#### 6. OpenSSL (1.1.1f)
Download openssl from https://www.openssl.org/source/old/1.1.1/openssl-1.1.1f.tar.gz
B. Building Robo 3T and Dependencies
-------------
#### 1. Build OpenSSL
(Todo: Can we find pre-built OpenSSL? To check => https://wiki.openssl.org/index.php/Binaries)
Steps to build OpenSSL on windows:
- Ensure you have perl installed on your machine (e.g. ActiveState or Strawberry), and available on your %PATH%
- Ensure you have NASM installed on your machine, and available on your %PATH%
```sh
Open Visual Studio tool x64 Cross Tools Command prompt
cd to the directory where you have openssl sources cd c:\myPath\openssl
perl Configure VC-WIN64A
(nmake clean)
nmake
// Verify these files are created:
libcrypto-1_1x64.dll, libssl-1_1-x64.dll (with all the build additionals such as .pdb .lik or static .lib)
```
Refer to OpenSSL documentation for more information:
https://wiki.openssl.org/index.php/Compilation_and_Installation#OpenSSL_1.1.0
#### 2. Build Robo 3T Shell (fork of MongoDB)
Clone Robo 3T Shell and make sure to be at `roboshell-v4.2` branch:
```sh
$ git clone https://github.com/paralect/robomongo-shell.git
$ cd robomongo-shell
$ git branch // roboshell-v4.2
```
Set environment variable `ROBOMONGO_CMAKE_PREFIX_PATH`, required by Robo 3T-Shell and Robo 3T build scripts, needs to be set according to the following directories:
1. Location of Qt SDK
2. Location of Robo 3T Shell
3. Location of OpenSSL
**Important:**
Make sure to move all your repos (robo, openssl, robo-shell etc..) into root directory of your drives (e.g. e:\robo-shell) and keep short repo names (e.g. robo-shell instead of robomongo-shell) otherwise you might end up with this error `If you see fatal error LNK1170: line in command file contains 131071 or more characters`
Separate directories by semicolon `;` (not colon). You can do this in Command Prompt:
> setx ROBOMONGO_CMAKE_PREFIX_PATH "e:\Qt\Qt5.9.3\5.9.3\msvc2015_64;e:\robo-shell;e:\openssl-x.y.z"
Open '**a new**' VS2017 x64 Native Tools Command Prompt and navigate to `robomongo-shell` folder.
**Note:**
Run
`pip3 install --user -r ../etc/pip/dev-requirements.txt`
If you have this type of errors:
```
// 1st error
ImportError: No module named typing
// Solution:
pip install Typing
pip install Cheetah
// 2nd error: shell: cheetah module not found
// Solution:
copy C:\Users\<user>\AppData\Roaming\Python\Python27\site-packages
to C:\Python27\Lib\site-packages
```
Build shell in release mode:
> bin\build
Build shell in debug mode:
> bin\build debug
Note that backslash is used (`\`), and not forward slash (`/`).
Clean build files for release mode:
> bin\clean
Clean build files for debug mode:
> bin\clean debug
Refer to MongoDB documentation for additional information:
https://docs.mongodb.org/manual/contributors/tutorial/build-mongodb-from-source/#windows-specific-instructions
#### 3. Build Robo 3T
Clone Robo 3T:
```sh
$ git clone https://github.com/paralect/robomongo.git
```
Open VS2017 x64 Native Tools Command Prompt and navigate to `robomongo` folder.
Run configuration step:
> bin\configure
And finally, build Robo 3T:
> bin\build
```
// If you see fatal error LNK1170: line in command file contains 131071 or more characters
Solution-1:
1. Move all your repos (robo, openssl, robo-shell etc..) into root directory of your drives.
2. Use short names e.g. robo-shell instead of robomongo-shell.
3. Update ROBOMONGO_CMAKE_PREFIX_PATH env. variable and try a fresh (clean) build.
Solution-2:
1. Create environment variable MongoDB_OBJECTS, set a short path e.g. "C:/"
2. Open a new VS2017 x64 Native Tools Command Prompt and build Robo 3T Shell
3. Robo 3T Shell build script will copy the object files into MongoDB_OBJECTS directory
4. Build Robo 3T again (clean build might be needed)
```
**Run Robo 3T**
Install Robo 3T to `build\Release\install` folder:
> bin\install
And run Robo 3T
> \robomongo\build\Release\install\robo3t.exe
**Package Robo 3T**
Install Robo 3T to `build\Release\install` folder:
> bin\pack
Note: nsis-2.46-setup.exe with Full setup must be present.
**Debug mode**
For debug mode append `debug` for each command
e.g. `bin\configure debug` or `bin\build debug` etc..
**Helper commands**
Clean build files (in order to start build from scratch):
> bin\clean
+57
View File
@@ -0,0 +1,57 @@
Building Robo 3T Shell
========================
Robo 3T uses [modified version](https://github.com/paralect/robomongo-shell/tree/roboshell-v3.4) of MongoDB that we call Robo 3T Shell.
Before you can build Robo 3T, you have to build Robo 3T Shell. The following instructions are applicable only for Mac OS X and Linux. For Windows instructions please check [Building Robo 3T on Windows](BuildRobo3TOnWindows.md).
Build for Mac OS X or Linux
---------------------------
#### Prerequisites
1. Install [Scons](http://scons.org/tag/releases.html) (2.3.5 or newer)
2. Clone Robo 3T Shell and checkout to `roboshell-v3.4` branch:
```sh
$ git clone https://github.com/paralect/robomongo-shell.git
$ cd robomongo-shell
$ git checkout roboshell-v3.4
```
3. Build Robo 3T Shell:
```sh
$ bin/build
```
Done! Now you can continue with building Robo 3T
with embedded MongoDB 3.4 shell (that you've just built).
<br/>
#### Advanced helper commands
The following commands are needed only if you are planning to develop or deeper understand
Robo 3T or Robo 3T Shell build processes.
Clean build files for release mode (folder `build/opt` will be removed):
$ bin/clean
Here is a command that is executed by `bin/build` script:
$ scons mongo -j8 --release --osx-version-min=10.9
Argument `--osx-version-min` is required only for Mac OS.
Build MongoDB shell in debug mode:
$ scons mongo -j8 --dbg
Clear builds:
$ scons -c mongo # clears release build
$ scons -c --dbg mongo # clears debug build
+5 -1
View File
@@ -1,6 +1,10 @@
Building Robomongo Shell
Building Robomongo Shell (Old Document)
========================
**Important Note:**
This document is for versions 1.0 and earlier and for MongoDB 3.2.
See latest documents here: https://github.com/Studio3T/robomongo/wiki
Robomongo uses [modified version](https://github.com/paralect/robomongo-shell/tree/roboshell-v3.2) of MongoDB that we call Robomongo Shell. Before you can build Robomongo, you have to build Robomongo Shell. The following instructions are applicable only for Mac OS X and Linux. For Windows instructions please check [Building Robomongo on Windows](BuildingRobomongoOnWindows.md).
Build for Mac OS X or Linux
+4
View File
@@ -1,6 +1,10 @@
Building Robomongo (Mac OS X and Linux)
==================
**Important Note:**
This document is for versions 1.0 and earlier and for MongoDB 3.2.
See latest documents here: https://github.com/Studio3T/robomongo/wiki
A. Prerequisites
-------------
+4
View File
@@ -1,6 +1,10 @@
Building Robomongo (Windows)
==============================
**Important Note:**
This document is for versions 1.0 and earlier and for MongoDB 3.2.
See latest documents here: https://github.com/Studio3T/robomongo/wiki
A. Prerequisites
-------------
+112 -7
View File
@@ -12,26 +12,30 @@ Runtime dependencies that are not privided by platforms but required by Robomong
Diagnostic of dependencies
--------------------------
#### Linux
### Windows
a. View dependencies of executable or shared library:
GUI: http://dependencywalker.com/
### Linux
#### a. View dependencies of executable or shared library:
$ ldd robomongo
$ readelf -d robomongo
b. View dependency tree of executable or shared library:
#### b. View dependency tree of executable or shared library:
$ lddtree robomongo
$ ldd -v robomongo
c. View RPATH or RUNPATH records of executable or shared library:
#### c. View RPATH or RUNPATH records of executable or shared library:
$ objdump -x bin/robomongo | grep "RPATH\|RUNPATH"
$ readelf -d bin/robomongo | grep RPATH
For Robomongo binary it should be `$ORIGIN/../lib`
d. Enable extensive logging for run-time shared library search
#### d. Enable extensive logging for run-time shared library search
$ export LD_DEBUG=files
$ bin/robomongo
@@ -39,7 +43,7 @@ d. Enable extensive logging for run-time shared library search
Source:
http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
e. Modify RPATH using `chrpath` and the dynamic linker and RPATH using paths `patchelf`
#### e. Modify RPATH using `chrpath` and the dynamic linker and RPATH using paths `patchelf`
$ patchelf --set-rpath '$ORIGIN/../lib' robo
@@ -51,7 +55,57 @@ More:
https://linux.die.net/man/1/chrpath
http://www.programering.com/a/MTOwcDNwATU.html // examples
#### Mac OS X
#### f. Show symbols of shared lib file
Error:
```
/opt/robo-shell/src/mongo/util/net/ssl_manager_openssl.cpp:667:
undefined reference to `SSL_library_init'
```
How to debug:
```
openssl-1.1.1f: nm -gD libssl.so | grep SSL_library_init
// not found, since SSL_library_init() is deprecated in 1.1.1
openssl-1.0.2o: nm -gD libssl.so | grep SSL_library_init
0000000000055520 T SSL_library_init
```
#### g. Update path of a dependency of an executable
```
ldd exec_file | grep libcurlpp
libcurlpp.so.1 => not found
patchelf --replace-needed libcurlpp.so.1 /foo/bar/libcurlpp.so.1 exec_file
```
Another example (libcrypto.so.1.1 => not found):
```
cd /opt/openssl-1.1.1f
ldd libssl.so
linux-vdso.so.1 => (0x00007ffcaf911000)
libcrypto.so.1.1 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd4087b4000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd4083ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd408c65000)
sudo cp libcrypto.so.1.1 /lib/x86_64-linux-gnu/
ldd libssl.so
linux-vdso.so.1 => (0x00007fff0f5d8000)
libcrypto.so.1.0.0 => /lib/x86_64-linux-gnu/libcrypto.so.1.1 (0x00007fd3dcc1e000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd3dc854000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd3dc650000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd3dd2d6000)
```
### Mac OS X
#### a. Show dependencies of executable or shared library:
Show dependencies of executable or shared library:
@@ -65,6 +119,57 @@ View LC_RPATH records of executable or shared library:
For Robomongo binary it should be `$executable_path/../Frameworks`
More about `otool -l`
```
$ otool -l /opt/robo/build/release/src/robomongo/Robo\ 3T.app/Contents/MacOS/Robo\ 3T
....
Load command 23
cmd LC_LOAD_DYLIB
cmdsize 56
name @rpath/lib/libssl.1.1.dylib (offset 24)
time stamp 2 Thu Jan 1 03:00:02 1970
current version 1.1.0
compatibility version 1.1.0
Load command 24
cmd LC_LOAD_DYLIB
cmdsize 56
name @rpath/lib/libcrypto.1.1.dylib (offset 24)
time stamp 2 Thu Jan 1 03:00:02 1970
current version 1.1.0
compatibility version 1.1.0
....
Load command 27
cmd LC_RPATH
cmdsize 48
path /opt/Qt5.9.3/5.9.3/clang_64/lib (offset 12)
Load command 28
cmd LC_RPATH
cmdsize 32
path /opt/openssl-1.1.1f (offset 12)
```
#### b. Edit dependencies of executable or shared library:
```
// Before
otool -L libssl.dylib
libssl.dylib:
/usr/local/lib/libssl.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
/usr/local/lib/libcrypto.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
// Edit
install_name_tool -id "@rpath/lib/libssl.1.1.dylib" libssl.dylib
install_name_tool -change /usr/local/lib/libcrypto.1.1.dylib @rpath/lib/libcrypto.1.1.dylib libssl.dylib
// After
otool -L libssl.dylib
libssl.dylib:
@rpath/lib/libssl.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
@rpath/lib/libcrypto.1.1.dylib (compatibility version 1.1.0, current version 1.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.100.1)
```
Diagnostic of Qt plugins
------------------------
Binary file not shown.
+3 -1
View File
@@ -7,7 +7,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>Robomongo</string>
<string>Robo 3T</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
@@ -36,5 +36,7 @@
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>NSRequiresAquaSystemAppearance</key>
<true/>
</dict>
</plist>
+1 -1
View File
@@ -14,7 +14,7 @@ File `robomongo.ico` will be generated.
Which icon sizes are used on Windows?
=====================================
The most important sizes are the one that is small. Robomongo should include
The most important sizes are the one that is small. Robo 3T should include
16, 20, 24, 40, 48. The bigger sizes are usually scaled well, without notable
degrading in quality.
+4 -4
View File
@@ -27,13 +27,13 @@ IDI_ICON1 ICON "@windows_icon@"
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "3T Software Labs Ltd\0"
VALUE "FileDescription", "Robomongo, MongoDB management tool\0"
VALUE "FileDescription", "Robo 3T, MongoDB management tool\0"
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "LegalCopyright", "Copyright 3T Software Labs Ltd, 2014 - 2017\0"
VALUE "ProductName", "Robomongo\0"
VALUE "ProductName", "Robo 3T\0"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
VALUE "OriginalFilename", "Robomongo.exe\0"
VALUE "InternalName", "Robomongo\0"
VALUE "OriginalFilename", "robo3t.exe\0"
VALUE "InternalName", "Robo 3T\0"
END
END
BLOCK "VarFileInfo"
Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

+101
View File
@@ -0,0 +1,101 @@
###
### Unit Testing with Google Test
###
## !! Important Note: Currently unit testing is disabled for Linux due to MongoDB linking problem
if (SYSTEM_LINUX)
message("\n *Note: Currently unit testing is disabled for Linux due to MongoDB linking problem")
return()
endif()
enable_testing()
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
## New test & source file pairs MUST have the following format:
# Test file: /path/Foo_test.cpp
# Source file: /path/Foo.cpp or /path/Foo.h
set(ROBO_SRC_DIR ${CMAKE_HOME_DIRECTORY}/src/robomongo)
set(SOURCES_TEST
${ROBO_SRC_DIR}/utils/RoboCrypt_test.cpp
${ROBO_SRC_DIR}/utils/StringOperations_test.cpp
${ROBO_SRC_DIR}/core/HexUtils_test.cpp
)
add_executable(robo_unit_tests ${SOURCES_TEST})
add_dependencies(robo_unit_tests robomongo)
get_target_property(ROBO_SOURCES robomongo SOURCES)
list(FILTER ROBO_SOURCES INCLUDE REGEX "cpp")
list(FILTER ROBO_SOURCES EXCLUDE REGEX "main.cpp")
if(SYSTEM_WINDOWS) ############# Windows
set(OBJ_DIR ${CMAKE_BINARY_DIR}/src/robomongo/robomongo.dir/${CMAKE_BUILD_TYPE}/)
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}qrc_gui.obj;")
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}qrc_robo.obj;")
foreach(SRC_FILE ${ROBO_SOURCES})
get_filename_component(FILENAME ${SRC_FILE} NAME)
string(REPLACE ".cpp" ".obj" FILENAME ${FILENAME})
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}${FILENAME};")
endforeach()
elseif(SYSTEM_MACOSX) ############# MacOS
set(OBJ_DIR ${CMAKE_BINARY_DIR}/src/robomongo/CMakeFiles/robomongo.dir/)
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}/robomongo_autogen/mocs_compilation.cpp.o;")
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}/robomongo_autogen/YHP5W5E6RA/qrc_gui.cpp.o;")
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}/robomongo_autogen/3YJK5W5UP7/qrc_robo.cpp.o;")
foreach(SRC_FILE ${ROBO_SOURCES})
string(REPLACE ".cpp" ".cpp.o" OBJ_FILE ${SRC_FILE})
set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}${OBJ_FILE};")
endforeach()
find_library(SECURITY NAMES Security)
find_library(CORE_FOUNDATION NAMES CoreFoundation)
set(SSL_LIBRARIES ${SECURITY} ${CORE_FOUNDATION})
target_link_libraries(robo_unit_tests
${SSL_LIBRARIES} -lresolv
)
# elseif(SYSTEM_LINUX) ############# LINUX
# set(OBJ_DIR ${CMAKE_BINARY_DIR}/src/robomongo/CMakeFiles/robomongo.dir/)
# message("--- OBJ_DIR: " ${OBJ_DIR})
# set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}/robomongo_automoc.cpp.o;")
# set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}/robomongo_automoc.dir/gui/resources/qrc_gui.cpp.o;")
# set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}/robomongo_automoc.dir/resources/qrc_robo.cpp.o;")
# foreach(SRC_FILE ${ROBO_SOURCES})
# string(REPLACE ".cpp" ".cpp.o" OBJ_FILE ${SRC_FILE})
# set(ROBO_OBJ_FILES "${ROBO_OBJ_FILES}${OBJ_DIR}${OBJ_FILE};")
# endforeach()
endif()
target_link_libraries(robo_unit_tests
gtest gtest_main
Qt5::Widgets
Qt5::Network
Qt5::Xml
qjson
qscintilla
mongodb
ssh
Threads::Threads
${ROBO_OBJ_FILES}
)
target_include_directories(robo_unit_tests
PRIVATE
${CMAKE_HOME_DIRECTORY}/src)
# For Windows we need to install Qt DLLs
if(SYSTEM_WINDOWS)
get_target_property(target_path Qt5::Core LOCATION)
get_filename_component(qt_bin_dir ${target_path} DIRECTORY)
set(QT_BIN_FILES "${QT_BIN_FILES}" ${qt_bin_dir}/Qt5Core${CMAKE_SHARED_LIBRARY_SUFFIX};)
set(QT_BIN_FILES "${QT_BIN_FILES}" ${qt_bin_dir}/Qt5Gui${CMAKE_SHARED_LIBRARY_SUFFIX};)
set(QT_BIN_FILES "${QT_BIN_FILES}" ${qt_bin_dir}/Qt5Network${CMAKE_SHARED_LIBRARY_SUFFIX};)
set(QT_BIN_FILES "${QT_BIN_FILES}" ${qt_bin_dir}/Qt5PrintSupport${CMAKE_SHARED_LIBRARY_SUFFIX};)
set(QT_BIN_FILES "${QT_BIN_FILES}" ${qt_bin_dir}/Qt5Widgets${CMAKE_SHARED_LIBRARY_SUFFIX};)
set(QT_BIN_FILES "${QT_BIN_FILES}" ${qt_bin_dir}/Qt5Xml${CMAKE_SHARED_LIBRARY_SUFFIX};)
get_target_property(TESTS_BIN_DIR robo_unit_tests BINARY_DIR)
file(COPY ${QT_BIN_FILES}
DESTINATION ${TESTS_BIN_DIR}/${CMAKE_BUILD_TYPE})
endif()
+62 -24
View File
@@ -28,14 +28,11 @@ set(SOURCES
core/EventBus.cpp
core/KeyboardManager.cpp
core/domain/MongoNamespace.cpp
core/domain/MongoUser.cpp
core/domain/MongoUser.cpp
core/domain/MongoFunction.cpp
core/domain/MongoUtils.cpp
core/domain/MongoCollection.cpp
core/domain/MongoCollectionInfo.cpp
core/domain/MongoQueryInfo.cpp
core/domain/MongoShellResult.cpp
core/domain/CursorPosition.cpp
core/domain/ScriptInfo.cpp
core/events/MongoEventsInfo.cpp
@@ -56,8 +53,10 @@ set(SOURCES
core/mongodb/ReplicaSet.cpp
core/settings/SettingsManager.cpp
core/AppRegistry.cpp
utils/string_operations.cpp
utils/StringOperations.cpp
utils/common.cpp
utils/SimpleCrypt.cpp
utils/RoboCrypt.cpp
# Isolated Scope #3
gui/GuiRegistry.cpp
@@ -79,18 +78,20 @@ set(SOURCES
# Isolated scope #4
gui/dialogs/PreferencesDialog.cpp
gui/dialogs/ConnectionsDialog.cpp
gui/dialogs/CreateConnectionDialog.cpp
gui/dialogs/ExportDialog.cpp
gui/dialogs/ChangeShellTimeoutDialog.cpp
# Isolated scope #5
gui/editors/PlainJavaScriptEditor.cpp
gui/editors/JSLexer.cpp
gui/editors/FindFrame.cpp
gui/widgets/explorer/EditIndexDialog.cpp
gui/widgets/explorer/AddEditIndexDialog.cpp
gui/widgets/workarea/ScriptWidget.cpp
# Isolated scope #6
gui/widgets/explorer/ExplorerCollectionTreeItem.cpp
gui/widgets/explorer/ExplorerCollectionIndexesDir.cpp
gui/widgets/explorer/ExplorerCollectionIndexItem.cpp
gui/widgets/explorer/ExplorerTreeItem.cpp
gui/widgets/explorer/ExplorerReplicaSetFolderItem.cpp
gui/widgets/explorer/ExplorerReplicaSetTreeItem.cpp
@@ -141,7 +142,6 @@ set(SOURCES
gui/resources/gui.qrc
)
# Robomongo target
add_executable(robomongo MACOSX_BUNDLE WIN32 app/main.cpp ${SOURCES})
@@ -156,12 +156,45 @@ target_link_libraries(robomongo
ssh
Threads::Threads) # Target from FindThreads CMake module
if(APPLE)
find_library(SECURITY NAMES Security)
find_library(CORE_FOUNDATION NAMES CoreFoundation)
set(SSL_LIBRARIES ${SECURITY} ${CORE_FOUNDATION})
target_link_libraries(robomongo
PRIVATE
${SSL_LIBRARIES}
-lresolv)
endif(APPLE)
target_include_directories(robomongo
PRIVATE
${CMAKE_HOME_DIRECTORY}/src)
# Get build number
find_package(Git)
if(GIT_FOUND)
MESSAGE( STATUS "Info: Git found" )
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE "BUILD_NUMBER"
OUTPUT_STRIP_TRAILING_WHITESPACE
)
else(GIT_FOUND)
MESSAGE( FATAL_ERROR "Unable to find Git" )
set(BUILD_NUMBER 0)
endif(GIT_FOUND)
if(BUILD_NUMBER STREQUAL "")
MESSAGE( FATAL_ERROR "Failed to get BUILD_NUMBER" )
endif()
MESSAGE( STATUS "Info: BUILD_NUMBER set as " \"${BUILD_NUMBER}\" )
target_compile_definitions(robomongo
PRIVATE
BUILDING_ROBO
PROJECT_NAME="${PROJECT_NAME}"
PROJECT_NAME_TITLE="${PROJECT_NAME_TITLE}"
PROJECT_COPYRIGHT="${PROJECT_COPYRIGHT}"
@@ -172,8 +205,16 @@ target_compile_definitions(robomongo
PROJECT_GITHUB_ISSUES="${PROJECT_GITHUB_ISSUES}"
PROJECT_VERSION="${PROJECT_VERSION}"
PROJECT_VERSION_SHORT="${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
PROJECT_QT_VERSION="${Qt5Core_VERSION}"
PROJECT_NAME_LOWERCASE="${PROJECT_NAME_LOWERCASE}")
BUILD_NUMBER="${BUILD_NUMBER}"
PROJECT_NAME_LOWERCASE="${PROJECT_NAME_LOWERCASE}"
PROJECT_QT_VERSION="${Qt5Core_VERSION}"
MongoDB_VERSION="${MongoDB_VERSION}"
OPENSSL_VERSION="${OPENSSL_VERSION}"
LIBSSH2_VERSION="${LIBSSH2_VERSION}"
QJSON_VERSION="${QJSON_VERSION}"
GOOGLE_TEST_VERSION="${GOOGLE_TEST_VERSION}"
ESPRIMA_VERSION="${ESPRIMA_VERSION}"
)
if(SYSTEM_WINDOWS)
# Create Windows Resource file
@@ -184,27 +225,26 @@ if(SYSTEM_WINDOWS)
unset(windows_icon)
# Add additional source file to "robomongo" target
target_sources(robomongo
PRIVATE
"${CMAKE_BINARY_DIR}/winres.rc")
target_sources(robomongo PRIVATE "${CMAKE_BINARY_DIR}/winres.rc")
# Rename output name for Windows
set_target_properties(robomongo PROPERTIES
OUTPUT_NAME "Robomongo")
set_target_properties(robomongo PROPERTIES OUTPUT_NAME "robo3t")
# Suppress "warning C4477: 'sprintf'..." from robomongo\shell\db\ptimeutil.cpp
# Suppress "warning C4291: ...no matching operator delete found" from third_party\mozjs-60
set_target_properties(robomongo PROPERTIES COMPILE_FLAGS "/wd4477 /wd4291")
# Seems that we do not need to do this with recent versions of Qt
target_link_libraries(robomongo
PRIVATE
Qt5::WinMain)
target_link_libraries(robomongo PRIVATE Qt5::WinMain)
elseif(SYSTEM_MACOSX)
set_target_properties(robomongo PROPERTIES
INSTALL_RPATH "@executable_path/../Frameworks"
OUTPUT_NAME "Robomongo"
OUTPUT_NAME "Robo 3T"
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/install/macosx/Info.plist.in"
MACOSX_BUNDLE_BUNDLE_NAME "Robomongo"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.3tsoftwarelabs.robomongo"
MACOSX_BUNDLE_INFO_STRING "Robomongo ${PROJECT_VERSION}. Copyright 3T Software Labs Ltd, 2014 - 2017"
MACOSX_BUNDLE_BUNDLE_NAME "Robo 3T"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.3tsoftwarelabs.robo3t"
MACOSX_BUNDLE_INFO_STRING "Robo 3T ${PROJECT_VERSION}. Copyright 3T Software Labs Ltd, 2014 - 2017"
MACOSX_BUNDLE_SHORT_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_LONG_VERSION "${PROJECT_VERSION}"
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
@@ -214,16 +254,14 @@ elseif(SYSTEM_MACOSX)
elseif(SYSTEM_LINUX)
set_target_properties(robomongo PROPERTIES
INSTALL_RPATH "$ORIGIN/../lib"
OUTPUT_NAME "robomongo")
OUTPUT_NAME "robo3t")
endif()
# Install
include(RobomongoInstall)
#
# Tests targets (code below should be moved to separate file)
#
add_executable(tests WIN32 EXCLUDE_FROM_ALL app/main_test.cpp gui/editors/JSLexer.cpp)
target_link_libraries(tests Qt5::Widgets qjson qscintilla mongodb Threads::Threads)
target_include_directories(tests
+40 -10
View File
@@ -6,17 +6,22 @@
// Header "mongo/util/net/sock" is needed for mongo::enableIPv6()
// Header "mongo/platform/basic" is required by "sock.h" under Windows
#include <mongo/platform/basic.h>
#include <mongo/util/net/sock.h>
#include <mongo/util/net/socket_utils.h>
#include <mongo/base/initializer.h>
#include <mongo/util/net/ssl_options.h>
#include <mongo/db/service_context.h>
#include <mongo/transport/transport_layer_asio.h>
#include <mongo/shell/shell_options.h>
#include <mongo/db/storage/storage_engine_init.h>
#include "robomongo/core/AppRegistry.h"
#include "robomongo/core/settings/SettingsManager.h"
#include "robomongo/core/utils/Logger.h"
#include "robomongo/gui/MainWindow.h"
#include "robomongo/gui/AppStyle.h"
#include "robomongo/gui/dialogs/EulaDialog.h"
#include "robomongo/ssh/ssh.h"
#include "robomongo/utils/RoboCrypt.h"
int main(int argc, char *argv[], char** envp)
{
@@ -39,6 +44,18 @@ int main(int argc, char *argv[], char** envp)
// Initialization routine for MongoDB shell
mongo::runGlobalInitializersOrDie(argc, argv, envp);
mongo::setGlobalServiceContext(mongo::ServiceContext::make());
// Todo from mongo repo: This should use a TransportLayerManager or TransportLayerFactory
auto serviceContext = mongo::getGlobalServiceContext();
mongo::transport::TransportLayerASIO::Options opts;
opts.enableIPv6 = false; // Todo: When true, it breaks connection to localhost, github #1757
opts.mode = mongo::transport::TransportLayerASIO::Options::kEgress;
serviceContext->setTransportLayer(
std::make_unique<mongo::transport::TransportLayerASIO>(opts, nullptr)
);
auto tlPtr = serviceContext->getTransportLayer();
uassertStatusOK(tlPtr->setup());
uassertStatusOK(tlPtr->start());
// Initialize Qt application
QApplication app(argc, argv);
@@ -55,27 +72,40 @@ int main(int argc, char *argv[], char** envp)
#ifdef Q_OS_MAC
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif
// EULA License Agreement
auto const settingsManager = Robomongo::AppRegistry::instance().settingsManager();
if (!settingsManager->acceptedEulaVersions().contains(PROJECT_VERSION)) {
Robomongo::EulaDialog eulaDialog;
if (eulaDialog.exec() == QDialog::Rejected) {
auto const& settings { Robomongo::AppRegistry::instance().settingsManager() };
if (!settings->acceptedEulaVersions().contains(PROJECT_VERSION)) {
bool const showFormPage { settings->programExitedNormally() && !settings->disableHttpsFeatures() };
Robomongo::EulaDialog eulaDialog(showFormPage);
settings->setProgramExitedNormally(false);
settings->save();
int const result = eulaDialog.exec();
settings->setProgramExitedNormally(true);
settings->save();
if (QDialog::Rejected == result) {
rbm_ssh_cleanup();
return 1;
}
// EULA accepted
settingsManager->addAcceptedEulaVersion(PROJECT_VERSION);
settingsManager->save();
}
settings->addAcceptedEulaVersion(PROJECT_VERSION);
settings->save();
}
// Init GUI style
Robomongo::AppStyleUtils::initStyle();
// To be set true at normal program exit
settings->setProgramExitedNormally(false);
settings->save();
// Application main window
Robomongo::MainWindow mainWindow;
mainWindow.show();
for(auto const& msgAndSeverity : Robomongo::RoboCrypt::roboCryptLogs())
Robomongo::LOG_MSG(msgAndSeverity.first, msgAndSeverity.second);
int rc = app.exec();
rbm_ssh_cleanup();
return rc;
+1
View File
@@ -31,6 +31,7 @@ namespace Robomongo
class MongoDocument;
typedef boost::shared_ptr<MongoDocument> MongoDocumentPtr;
// todo: Use enum class
enum ConnectionType {
// This type of connection is shown in Explorer and also opens SSH tunnel for secondary
// connections (if needed)
+15 -17
View File
@@ -13,11 +13,11 @@
namespace
{
struct RemoveIfReciver : public std::unary_function<const Robomongo::EventBus::SubscribersType&, bool>
struct RemoveIfReciver
{
RemoveIfReciver(QObject *receiver) : _receiver(receiver) {}
bool operator()(const Robomongo::EventBus::SubscribersType& item) const {
bool operator()(const Robomongo::EventBus::EventTypeAndSubscriber& item) const {
if (item.second->receiver == _receiver) {
delete item.second;
return true;
@@ -28,13 +28,13 @@ namespace
QObject *_receiver;
};
struct FindIfReciver : public std::unary_function<const Robomongo::EventBus::SubscribersType&, bool>
struct FindIfReciver
{
FindIfReciver(QThread *thread) : _thread(thread) {}
bool operator()(const Robomongo::EventBus::DispatchersType &item) const {
if (item.first == _thread) {
bool operator()(const Robomongo::EventBus::ThreadAndDispatcher &item) const {
if (item.first == _thread)
return true;
}
return false;
}
QThread *_thread;
@@ -50,19 +50,16 @@ namespace Robomongo
EventBus::~EventBus()
{
for (DispatchersContainerType::iterator it = _dispatchersByThread.begin(); it != _dispatchersByThread.end(); ++it) {
DispatchersType item = *it;
delete item.second;
}
for (auto const& dispatchersByThread : _dispatchersByThread)
delete dispatchersByThread.second;
}
void EventBus::publish(Event *event)
{
QMutexLocker lock(&_lock);
QList<QObject*> theReceivers;
EventBusDispatcher *dis = NULL;
for (SubscribersContainerType::iterator it = _subscribersByEventType.begin(); it != _subscribersByEventType.end(); ++it ) {
SubscribersType item = *it;
EventBusDispatcher *dis = nullptr;
for (auto const& item : _subscribersByEventType) {
if (event->type() == item.first) {
EventBusSubscriber *subscriber = item.second;
if (!subscriber->sender || subscriber->sender == event->sender()) {
@@ -118,7 +115,7 @@ namespace Robomongo
VERIFY(connect(receiver, SIGNAL(destroyed(QObject*)), this, SLOT(unsubscibe(QObject*))));
// add subscriber
_subscribersByEventType.push_back(SubscribersType(type, new EventBusSubscriber(dis, receiver, sender)));
_subscribersByEventType.push_back(EventTypeAndSubscriber(type, new EventBusSubscriber(dis, receiver, sender)));
}
void EventBus::unsubscibe(QObject *receiver)
@@ -134,8 +131,9 @@ namespace Robomongo
*/
EventBusDispatcher *EventBus::dispatcher(QThread *thread)
{
DispatchersContainerType::iterator disIt = std::find_if(
_dispatchersByThread.begin(), _dispatchersByThread.end(), FindIfReciver(thread));
auto const& disIt = std::find_if(
_dispatchersByThread.begin(), _dispatchersByThread.end(), FindIfReciver(thread)
);
if (disIt != _dispatchersByThread.end()) {
return (*disIt).second;
@@ -143,7 +141,7 @@ namespace Robomongo
else {
EventBusDispatcher *dis = new EventBusDispatcher();
dis->moveToThread(thread);
_dispatchersByThread.push_back(DispatchersType(thread, dis));
_dispatchersByThread.push_back(ThreadAndDispatcher(thread, dis));
return dis;
}
}
+5 -6
View File
@@ -21,10 +21,9 @@ namespace Robomongo
Q_OBJECT
public:
typedef std::pair<QEvent::Type, EventBusSubscriber *> SubscribersType;
typedef std::vector<SubscribersType > SubscribersContainerType;
typedef std::pair<QThread *, EventBusDispatcher *> DispatchersType;
typedef std::vector<DispatchersType> DispatchersContainerType;
typedef std::pair<QEvent::Type, EventBusSubscriber *> EventTypeAndSubscriber;
typedef std::pair<QThread *, EventBusDispatcher *> ThreadAndDispatcher;
EventBus();
~EventBus();
@@ -65,7 +64,7 @@ namespace Robomongo
private:
QMutex _lock;
SubscribersContainerType _subscribersByEventType;
DispatchersContainerType _dispatchersByThread;
std::vector<EventTypeAndSubscriber> _subscribersByEventType;
std::vector<ThreadAndDispatcher> _dispatchersByThread;
};
}
+1 -1
View File
@@ -1,6 +1,6 @@
#include "robomongo/core/EventError.h"
#include "robomongo/utils/string_operations.h"
#include "robomongo/utils/StringOperations.h"
namespace Robomongo
{
+1 -1
View File
@@ -37,7 +37,7 @@ namespace Robomongo
const char *p = s.c_str();
for (size_t i = 0; i < bytes; i++) {
data[i] = mongo::fromHex(p);
data[i] = mongo::fromHex(p).getValue();
p += 2;
}
+19
View File
@@ -0,0 +1,19 @@
#include "gtest/gtest.h"
#include "HexUtils.h"
#include <string>
/* Example Test:
*
* TEST( [Test_Case_Name], [Test_Name] )
* TEST( [Test_Case_Name], [UnitOfWorkName_ScenarioUnderTest_ExpectedBehavior] )
* TEST( StringParserTests, NumberLeftOf_StringWithoutNumber_ReturnsFalse) {
// ...
}
*/
TEST(hex_utils_tests, test_1)
{
EXPECT_TRUE(Robomongo::HexUtils::isHexString("a"));
}
+109 -97
View File
@@ -1,6 +1,8 @@
#include "robomongo/core/domain/App.h"
#include <QHash>
#include <QInputDialog>
#include <QMessageBox>
#include "robomongo/core/domain/MongoServer.h"
#include "robomongo/core/domain/MongoShell.h"
@@ -35,6 +37,9 @@ namespace Robomongo
}
}
App::~App()
{}
App::App(EventBus *const bus) : QObject(),
_bus(bus), _lastServerHandle(0) {
_bus->subscribe(this, EstablishSshConnectionResponse::Type);
@@ -42,14 +47,68 @@ namespace Robomongo
_bus->subscribe(this, LogEvent::Type);
}
App::~App()
std::unique_ptr<MongoServer>
App::continueOpenServer(int serverHandle, ConnectionSettings* connSettings, ConnectionType type,
int localport)
{
std::for_each(_shells.begin(), _shells.end(), stdutils::default_delete<MongoShell*>());
std::for_each(_servers.begin(), _servers.end(), stdutils::default_delete<MongoServer*>());
ConnectionSettings* connSettingsClone = connSettings->clone();
// Modify connection settings when SSH tunnel is used
if ((type == ConnectionPrimary || type == ConnectionTest)
&& connSettingsClone->sshSettings()->enabled()) {
connSettingsClone->setServerHost("127.0.0.1");
connSettingsClone->setServerPort(localport);
}
auto server{ std::make_unique<MongoServer>(serverHandle, connSettingsClone, type) };
server->runWorkerThread();
auto replicaSetStr = QString::fromStdString(connSettings->connectionName()) + " [Replica Set]";
replicaSetStr = (connSettings->replicaSetSettings()->members().size() > 0)
? replicaSetStr + QString::fromStdString(connSettings->replicaSetSettings()->members()[0])
: replicaSetStr + "";
QString serverAddress = connSettings->isReplicaSet()
? replicaSetStr
: QString::fromStdString(connSettings->getFullAddress());
LOG_MSG(QString("Connecting to %1...").arg(serverAddress), mongo::logger::LogSeverity::Info());
server->tryConnect();
return server;
}
bool App::openServer(ConnectionSettings *connection, ConnectionType type) {
/**
* Creates and opens new server connection.
* @param connection: ConnectionSettings, that will be owned by MongoServer.
* @param visible: should this server be visible in UI (explorer) or not.
*/
std::unique_ptr<MongoServer>
App::openServerInternal(ConnectionSettings* connSettings, ConnectionType type)
{
++_lastServerHandle;
if (type == ConnectionPrimary)
_bus->publish(new ConnectingEvent(this));
// When connection is SECONDARY or do not have
// ssh settings enabled, continue without SSH Tunnel
if (type == ConnectionSecondary || !connSettings->sshSettings()->enabled()) {
return continueOpenServer(_lastServerHandle, connSettings, type);
}
// Open SSH channel and only after that open connection
LOG_MSG(QString("Creating SSH tunnel to %1:%2...")
.arg(QtUtils::toQString(connSettings->sshSettings()->host()))
.arg(connSettings->sshSettings()->port()), mongo::logger::LogSeverity::Info());
ConnectionSettings* settingsCopy = connSettings->clone();
SshTunnelWorker* sshWorker = new SshTunnelWorker(settingsCopy);
_bus->send(sshWorker, new EstablishSshConnectionRequest(this, _lastServerHandle, sshWorker, settingsCopy, type));
return nullptr;
}
bool App::openServer(ConnectionSettings *connection, ConnectionType type)
{
SshSettings *ssh = connection->sshSettings();
if (ssh->enabled() && ssh->askPassword() &&
@@ -97,67 +156,43 @@ namespace Robomongo
}
}
openServerInternal(connection, type);
_servers.push_back(move(openServerInternal(connection, type)));
return true;
}
/**
* Creates and opens new server connection.
* @param connection: ConnectionSettings, that will be owned by MongoServer.
* @param visible: should this server be visible in UI (explorer) or not.
*/
MongoServer *App::openServerInternal(ConnectionSettings* connSettings, ConnectionType type) {
++_lastServerHandle;
if (type == ConnectionPrimary)
_bus->publish(new ConnectingEvent(this));
// When connection is SECONDARY or do not have
// ssh settings enabled, continue without SSH Tunnel
if (type == ConnectionSecondary || !connSettings->sshSettings()->enabled()) {
return continueOpenServer(_lastServerHandle, connSettings, type);
}
// Open SSH channel and only after that open connection
LOG_MSG(QString("Creating SSH tunnel to %1:%2...")
.arg(QtUtils::toQString(connSettings->sshSettings()->host()))
.arg(connSettings->sshSettings()->port()), mongo::logger::LogSeverity::Info());
ConnectionSettings* settingsCopy = connSettings->clone();
SshTunnelWorker* sshWorker = new SshTunnelWorker(settingsCopy);
_bus->send(sshWorker, new EstablishSshConnectionRequest(this, _lastServerHandle, sshWorker, settingsCopy, type));
return NULL;
}
/**
* @brief Closes MongoServer connection and frees all resources, owned
* by MongoServer. Finally, specified MongoServer will also be deleted.
*/
void App::closeServer(MongoServer *server)
{
_servers.erase(std::remove_if(_servers.begin(), _servers.end(), stdutils::RemoveIfFound<MongoServer*>(server)),
_servers.end());
_servers.erase(std::remove_if(_servers.begin(), _servers.end(),
[&](auto const& el) { return el.get() == server; }), _servers.end());
}
void App::openShell(MongoCollection *collection, const QString &filePathToSave)
{
ConnectionSettings *connection = collection->database()->server()->connectionRecord();
connection->setDefaultDatabase(collection->database()->name());
QString script = detail::buildCollectionQuery(collection->name(), "find({})");
openShell(collection->database()->server(), connection, ScriptInfo(script, true, CursorPosition(0, -2),
QtUtils::toQString(collection->database()->name()), filePathToSave));
auto const& dbname = collection->database()->name();
connection->setDefaultDatabase(dbname);
QString const& script = detail::buildCollectionQuery(collection->name(), "find({})");
openShell(collection->database()->server(), connection,
ScriptInfo(script, true, dbname, CursorPosition(0, -2), QtUtils::toQString(dbname), filePathToSave)
);
}
void App::openShell(MongoServer *server, const QString &script, const std::string &dbName,
bool execute, const QString &shellName,
const CursorPosition &cursorPosition, const QString &filePathToSave)
bool execute, const QString &shellName,
const CursorPosition &cursorPosition, const QString &filePathToSave)
{
ConnectionSettings *connection = server->connectionRecord();
if (!dbName.empty())
connection->setDefaultDatabase(dbName);
openShell(server, connection, ScriptInfo(script, execute, cursorPosition, shellName, filePathToSave));
openShell(server, connection,
ScriptInfo(script, execute, dbName, cursorPosition, shellName, filePathToSave)
);
}
void App::openShell(MongoDatabase *database, const QString &script,
@@ -166,22 +201,23 @@ namespace Robomongo
{
ConnectionSettings *connection = database->server()->connectionRecord();
connection->setDefaultDatabase(database->name());
openShell(database->server(), connection, ScriptInfo(script, execute, cursorPosition,
shellName, filePathToSave));
openShell(database->server(), connection, ScriptInfo(script, execute, database->name(),
cursorPosition, shellName, filePathToSave));
}
void App::openShell(MongoServer* server, ConnectionSettings* connection, const ScriptInfo &scriptInfo)
{
MongoServer *serverClone = openServerInternal(connection, ConnectionSecondary);
auto serverClone{ openServerInternal(connection, ConnectionSecondary) };
if (!serverClone || !server)
return;
MongoShell *shell = new MongoShell(serverClone, scriptInfo);
auto shell{ std::make_unique<MongoShell>(serverClone.get(), scriptInfo) };
_servers.push_back(move(serverClone));
// Connection between explorer's server and tab's MongoShells
_bus->subscribe(server, ReplicaSetRefreshed::Type, shell);
_shells.push_back(shell);
_bus->publish(new OpeningShellEvent(this, shell));
_bus->subscribe(server, ReplicaSetRefreshed::Type, shell.get());
_bus->publish(new OpeningShellEvent(this, shell.get()));
shell->execute();
_shells.push_back(move(shell));
return;
}
@@ -191,45 +227,16 @@ namespace Robomongo
*/
void App::closeShell(MongoShell *shell)
{
auto const itr = std::find_if(_shells.begin(), _shells.end(),
[&](auto const& el) { return el.get() == shell; }
);
// Do nothing, if this shell not owned by this App.
MongoShellsContainerType::iterator it = std::find_if(_shells.begin(), _shells.end(), std::bind1st(std::equal_to<MongoShell *>(), shell));
if (it == _shells.end())
if (itr == _shells.end())
return;
_shells.erase(it);
closeServer(shell->server());
delete shell;
}
MongoServer *App::continueOpenServer(int serverHandle, ConnectionSettings* connSettings, ConnectionType type,
int localport)
{
ConnectionSettings* connSettingsClone = connSettings->clone();
// Modify connection settings when SSH tunnel is used
if ((type == ConnectionPrimary || type == ConnectionTest)
&& connSettingsClone->sshSettings()->enabled()) {
connSettingsClone->setServerHost("127.0.0.1");
connSettingsClone->setServerPort(localport);
}
MongoServer *server = new MongoServer(serverHandle, connSettingsClone, type);
_servers.push_back(server);
server->runWorkerThread();
auto replicaSetStr = QString::fromStdString(connSettings->connectionName()) + " [Replica Set]";
replicaSetStr = (connSettings->replicaSetSettings()->members().size() > 0)
? replicaSetStr + QString::fromStdString(connSettings->replicaSetSettings()->members()[0])
: replicaSetStr + "";
QString serverAddress = connSettings->isReplicaSet()
? replicaSetStr
: QString::fromStdString(connSettings->getFullAddress());
LOG_MSG(QString("Connecting to %1...").arg(serverAddress), mongo::logger::LogSeverity::Info());
server->tryConnect();
return server;
_shells.erase(itr);
}
void App::handle(EstablishSshConnectionResponse *event) {
@@ -242,26 +249,31 @@ namespace Robomongo
LOG_MSG(QString("SSH tunnel created successfully"), mongo::logger::LogSeverity::Info());
continueOpenServer(event->serverHandle, event->settings, event->connectionType, event->localport);
_servers.push_back(move(
continueOpenServer(event->serverHandle, event->settings, event->connectionType, event->localport)
));
_bus->send(event->worker, new ListenSshConnectionRequest(this, event->serverHandle, event->connectionType));
}
void App::handle(LogEvent *event) {
if (event->level == LogEvent::RBM_ERROR) {
LOG_MSG(event->message, mongo::logger::LogSeverity::Error());
} else if (event->level == LogEvent::RBM_WARN) {
LOG_MSG(event->message, mongo::logger::LogSeverity::Warning());
} else if (event->level == LogEvent::RBM_INFO) {
LOG_MSG(event->message, mongo::logger::LogSeverity::Info());
} else if (event->level == LogEvent::RBM_DEBUG) {
LOG_MSG(event->message, mongo::logger::LogSeverity::Log());
}
LOG_MSG(event->message, event->mongoLogSeverity());
if (!event->informUser)
return;
QMessageBox(
event->qMessageBoxIcon(),
QString::fromStdString(event->severity()),
QtUtils::toQString(event->severity() + ": " + event->message)
).exec();
}
void App::handle(ListenSshConnectionResponse *event) {
if (event->isError()) {
_bus->publish(new ConnectionFailedEvent(this, event->serverHandle, event->connectionType, event->error().errorMessage(),
ConnectionFailedEvent::SshChannel));
_bus->publish(
new ConnectionFailedEvent(this, event->serverHandle, event->connectionType,
event->error().errorMessage(), ConnectionFailedEvent::SshChannel)
);
return;
}
@@ -287,7 +299,7 @@ namespace Robomongo
s << std::endl << "Enter your PEM key passphrase (will never be stored):";
QString userInput = QInputDialog::getText(NULL, tr("SSL Authentication"),
QString userInput = QInputDialog::getText(NULL, tr("TLS Authentication"),
QtUtils::toQString(s.str()),
QLineEdit::Password, "", &ok);
+14 -12
View File
@@ -38,8 +38,6 @@ namespace Robomongo
Q_OBJECT
public:
typedef std::vector<MongoServer*> MongoServersContainerType;
typedef std::vector<MongoShell*> MongoShellsContainerType;
App(EventBus *const bus);
~App();
@@ -63,19 +61,20 @@ namespace Robomongo
void openShell(MongoCollection *collection, const QString &filePathToSave = QString());
void openShell(MongoServer *server, const QString &script, const std::string &dbName = std::string(),
bool execute = true, const QString &shellName = QString(),
const CursorPosition &cursorPosition = CursorPosition(), const QString &file = QString());
bool execute = true, const QString &shellName = QString(),
const CursorPosition &cursorPosition = CursorPosition(), const QString &file = QString());
void openShell(MongoDatabase *database, const QString &script,
bool execute = true, const QString &shellName = QString(),
const CursorPosition &cursorPosition = CursorPosition(), const QString &filePathToSave = QString());
bool execute = true, const QString &shellName = QString(),
const CursorPosition &cursorPosition = CursorPosition(),
const QString &filePathToSave = QString());
/**
* @brief Open new shell using explorer's MongoServer (ExplorerServerTreeItem's _server)
*/
void openShell(MongoServer* server, ConnectionSettings* connSettings, const ScriptInfo &scriptInfo);
MongoServersContainerType getServers() const { return _servers; };
auto const& getServers() const { return _servers; };
/**
* @brief Closes MongoShell and frees all resources, owned by specified MongoShell.
@@ -83,7 +82,8 @@ namespace Robomongo
*/
void closeShell(MongoShell *shell);
void fireConnectionFailedEvent(int serverHandle, ConnectionType type, std::string errormsg, ConnectionFailedEvent::Reason reason);
void fireConnectionFailedEvent(int serverHandle, ConnectionType type, std::string errormsg,
ConnectionFailedEvent::Reason reason);
int getLastServerHandle() const { return _lastServerHandle; };
@@ -93,8 +93,10 @@ namespace Robomongo
void handle(LogEvent *event);
private:
MongoServer *openServerInternal(ConnectionSettings* connSettings, ConnectionType type);
MongoServer *continueOpenServer(int serverHandle, ConnectionSettings* connSettings, ConnectionType type, int localport = 0);
std::unique_ptr<MongoServer> openServerInternal(ConnectionSettings* connSettings, ConnectionType type);
std::unique_ptr<MongoServer>
continueOpenServer(int serverHandle, ConnectionSettings* connSettings, ConnectionType type, int localport = 0);
/**
* @brief Create prompt dialog to enter SSL PEM key passphrase and save passphrase into SSL settings
@@ -106,12 +108,12 @@ namespace Robomongo
/**
* MongoServers, owned by this App.
*/
MongoServersContainerType _servers;
std::vector<std::unique_ptr<MongoServer>> _servers;
/**
* MongoShells, owned by this App.
*/
MongoShellsContainerType _shells;
std::vector<std::unique_ptr<MongoShell>> _shells;
EventBus *const _bus;
@@ -0,0 +1,23 @@
#pragma once
namespace Robomongo
{
struct AggrInfo
{
AggrInfo() {}
AggrInfo(const std::string& collectionName, int skip, int batchSize,
mongo::BSONObj const& pipeline, mongo::BSONObj const& options, int resultIndex) :
collectionName(collectionName), skip(skip), batchSize(batchSize), pipeline(pipeline),
options(options), isValid(true), resultIndex(resultIndex)
{}
std::string collectionName = "";
int skip = 0;
int batchSize = 0;
mongo::BSONObj pipeline;
mongo::BSONObj options;
bool isValid = false;
int resultIndex = -1;
};
}
@@ -1,6 +1,6 @@
#include "MongoCollectionInfo.h"
#include "robomongo/core/utils/BsonUtils.h"
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
namespace Robomongo
{
+12 -16
View File
@@ -81,39 +81,35 @@ namespace Robomongo
_bus->send(_server->worker(), new CopyCollectionToDiffServerRequest(this, server->worker(), sourceDatabase, collection, _name));
}
void MongoDatabase::createUser(const MongoUser &user, bool overwrite)
void MongoDatabase::createUser(const MongoUser &user)
{
_bus->send(_server->worker(), new CreateUserRequest(this, _name, user, overwrite));
_bus->send(_server->worker(), new CreateUserRequest(this, _name, user));
}
void MongoDatabase::dropUser(const mongo::OID &id, std::string const& userName)
void MongoDatabase::dropUser(std::string const& userName)
{
_bus->send(_server->worker(), new DropUserRequest(this, _name, id, userName));
_bus->send(_server->worker(), new DropUserRequest(this, _name, userName));
}
void MongoDatabase::createFunction(const MongoFunction &fun)
{
_bus->send(_server->worker(), new CreateFunctionRequest(this, _name, fun));
_bus->send(_server->worker(), new CreateFunctionRequest(this, _name, _server->version(), fun));
}
void MongoDatabase::updateFunction(const std::string &name, const MongoFunction &fun)
{
_bus->send(_server->worker(), new CreateFunctionRequest(this, _name, fun, name));
_bus->send(_server->worker(), new CreateFunctionRequest(this, _name, _server->version(), fun, name));
}
void MongoDatabase::dropFunction(const std::string &name)
{
_bus->send(_server->worker(), new DropFunctionRequest(this, _name, name));
_bus->send(_server->worker(), new DropFunctionRequest(this, _name, _server->version(), name));
}
void MongoDatabase::handle(LoadCollectionNamesResponse *event)
{
if (event->isError()) {
if (_server->connectionRecord()->isReplicaSet()) // replica set
handleIfReplicaSetUnreachable(event);
else // single server
_bus->publish(new MongoDatabaseCollectionListLoadedEvent(this, event->error()));
_bus->publish(new MongoDatabaseCollectionListLoadedEvent(this, event->error()));
genericEventErrorHandler(event, "Failed to refresh 'Collections'.", _bus, this);
return;
}
@@ -154,10 +150,10 @@ namespace Robomongo
void MongoDatabase::handle(LoadUsersResponse *event)
{
if (event->isError()) {
_bus->publish(new MongoDatabaseUsersLoadedEvent(this, event->error()));
if (_server->connectionRecord()->isReplicaSet()) // replica set
handleIfReplicaSetUnreachable(event);
else // single server
_bus->publish(new MongoDatabaseUsersLoadedEvent(this, event->error()));
genericEventErrorHandler(event, "Failed to refresh 'Users'.", _bus, this);
return;
@@ -170,10 +166,10 @@ namespace Robomongo
void MongoDatabase::handle(LoadFunctionsResponse *event)
{
if (event->isError()) {
_bus->publish(new MongoDatabaseFunctionsLoadedEvent(this, event->error()));
if (_server->connectionRecord()->isReplicaSet()) // replica set
handleIfReplicaSetUnreachable(event);
else // single server
_bus->publish(new MongoDatabaseFunctionsLoadedEvent(this, event->error()));
genericEventErrorHandler(event, "Failed to refresh 'Functions'.", _bus, this);
return;
+2 -2
View File
@@ -62,8 +62,8 @@ namespace Robomongo
void duplicateCollection(const std::string &collection, const std::string &newCollection);
void copyCollection(MongoServer *server, const std::string &sourceDatabase, const std::string &collection);
void createUser(const MongoUser &user, bool overwrite);
void dropUser(const mongo::OID &id, std::string const& userName);
void createUser(const MongoUser &user);
void dropUser(std::string const& userName);
void createFunction(const MongoFunction &fun);
void updateFunction(const std::string &name, const MongoFunction &fun);
+1 -1
View File
@@ -1,6 +1,6 @@
#include "robomongo/core/domain/MongoDocument.h"
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
#include "robomongo/core/settings/SettingsManager.h"
#include "robomongo/core/AppRegistry.h"
#include "robomongo/core/utils/BsonUtils.h"
+1 -1
View File
@@ -1,6 +1,6 @@
#include "robomongo/core/domain/MongoFunction.h"
#include "robomongo/core/utils/BsonUtils.h"
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
namespace Robomongo
{
+1 -1
View File
@@ -1,6 +1,6 @@
#include "robomongo/core/domain/MongoQueryInfo.h"
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
namespace Robomongo
{
+39 -9
View File
@@ -13,13 +13,17 @@
#include "robomongo/core/events/MongoEventsInfo.h"
#include "robomongo/core/utils/Logger.h"
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/gui/MainWindow.h"
#include "robomongo/utils/common.h"
#include "robomongo/utils/string_operations.h"
#include "robomongo/utils/StringOperations.h"
#include <QApplication>
namespace Robomongo {
R_REGISTER_EVENT(MongoServerLoadingDatabasesEvent)
MongoServer::MongoServer(int handle, ConnectionSettings *settings, ConnectionType connectionType) : QObject(),
MongoServer::MongoServer(int handle, ConnectionSettings *settings, ConnectionType connectionType)
: QObject(),
_version(0.0f),
_connectionType(connectionType),
_worker(nullptr),
@@ -217,6 +221,16 @@ namespace Robomongo {
if (ConnectionPrimary == event->connectionType)
_bus->send(_worker, new RefreshReplicaSetFolderRequest(this, false));
}
// Save connected db version if not saved before and if this is primary connection.
QString const versionStr = QString::fromStdString(info._dbVersionStr);
auto const& settingsManager = AppRegistry::instance().settingsManager();
if (ConnectionPrimary == _connectionType &&
!settingsManager->dbVersionsConnected().contains(versionStr)) {
settingsManager->addDbVersionConnected(versionStr);
settingsManager->save();
}
}
void MongoServer::handle(RefreshReplicaSetFolderResponse *event)
@@ -233,10 +247,8 @@ namespace Robomongo {
clearDatabases();
for (auto const& dbname : event->databaseNames) {
MongoDatabase *db = new MongoDatabase(this, dbname);
addDatabase(db);
}
for (auto const& dbname : event->databaseNames)
addDatabase(new MongoDatabase(this, dbname));
_bus->publish(new DatabaseListLoadedEvent(this, _databases));
LOG_MSG("Database list refreshed. Connection: " + _connSettings->connectionName(),
@@ -246,6 +258,7 @@ namespace Robomongo {
void MongoServer::handle(InsertDocumentResponse *event)
{
if (event->isError()) {
hideProgressBar();
if (_connSettings->isReplicaSet()) {
if (ConnectionPrimary == _connectionType) { // Insert document from explorer context menu
if (EventError::SetPrimaryUnreachable == event->error().errorCode()) {
@@ -263,11 +276,10 @@ namespace Robomongo {
_bus->publish(new InsertDocumentResponse(this, event->error()));
LOG_MSG("Document inserted.", mongo::logger::LogSeverity::Info());
}
}
void MongoServer::handle(RemoveDocumentResponse *event)
{
{
if (event->removeCount == RemoveDocumentCount::MULTI && event->index > 0)
return;
@@ -280,6 +292,7 @@ namespace Robomongo {
}
if (event->isError()) {
hideProgressBar();
if (_connSettings->isReplicaSet() &&
EventError::SetPrimaryUnreachable == event->error().errorCode()) {
auto refreshEvent = ReplicaSetRefreshed(this, event->error(), event->error().replicaSetInfo());
@@ -339,6 +352,11 @@ namespace Robomongo {
handleReplicaSetRefreshEvents(event->isError(), event->error(), event->replicaSet, false);
}
void MongoServer::changeWorkerShellTimeout(int newTimeout)
{
_worker->changeTimeout(newTimeout);
}
void MongoServer::handleReplicaSetRefreshEvents(bool isError, EventError eventError,
ReplicaSet const& replicaSet, bool expanded)
{
@@ -444,7 +462,7 @@ namespace Robomongo {
auto reason = ConnectionFailedEvent::SslConnection;
ss.clear();
ss << "Cannot connect to the MongoDB at " << connectionRecord()->getFullAddress()
<< ".\n\nError:\n" << "SSL connection failure: " << event->error().errorMessage();
<< ".\n\nError:\n" << "TLS connection failure: " << event->error().errorMessage();
_app->fireConnectionFailedEvent(_handle, _connectionType, ss.str(), reason);
}
else
@@ -469,4 +487,16 @@ namespace Robomongo {
}
}
void MongoServer::hideProgressBar() const
{
MainWindow* mainWindow = nullptr;
for (auto wid : QApplication::topLevelWidgets()) {
if ((mainWindow = qobject_cast<MainWindow*>(wid)))
break;
}
if(mainWindow)
mainWindow->hideQueryWidgetProgressBar();
}
} // namespace Robomongo
+3
View File
@@ -105,6 +105,8 @@ namespace Robomongo
void handle(ReplicaSetRefreshed *event);
void changeWorkerShellTimeout(int newTimeout);
protected Q_SLOTS:
void handle(EstablishConnectionResponse *event);
void handle(RefreshReplicaSetFolderResponse *event);
@@ -120,6 +122,7 @@ namespace Robomongo
bool expanded);
void updateReplicaSetSettings(EstablishConnectionResponse* event);
void handleConnectionFailure(EstablishConnectionResponse* event);
void hideProgressBar() const;
MongoWorker *_worker;
std::unique_ptr<ConnectionSettings> _connSettings;
+52 -35
View File
@@ -12,19 +12,20 @@
namespace Robomongo
{
auto const& eventBus = []() { return AppRegistry::instance().bus(); };
MongoShell::MongoShell(MongoServer *server, const ScriptInfo &scriptInfo) :
MongoShell::MongoShell(MongoServer *server, ScriptInfo scriptInfo) :
QObject(),
_scriptInfo(scriptInfo),
_server(server)
_server(server)
{
}
void MongoShell::open(const std::string &script, const std::string &dbName)
{
AppRegistry::instance().bus()->publish(new ScriptExecutingEvent(this));
eventBus()->publish(new ScriptExecutingEvent(this));
_scriptInfo.setScript(QtUtils::toQString(script));
AppRegistry::instance().bus()->send(_server->worker(), new ExecuteScriptRequest(this, query(), dbName));
eventBus()->send(_server->worker(), new ExecuteScriptRequest(this, query(), dbName));
LOG_MSG(_scriptInfo.script(), mongo::logger::LogSeverity::Info());
}
@@ -33,31 +34,36 @@ namespace Robomongo
return QtUtils::toStdString(_scriptInfo.script());
}
void MongoShell::execute(const std::string &dbName)
void MongoShell::execute(const std::string &script /* = "" */,
const std::string &dbName /* = "" */)
{
if (_scriptInfo.execute()) {
AppRegistry::instance().bus()->publish(new ScriptExecutingEvent(this));
AppRegistry::instance().bus()->send(_server->worker(), new ExecuteScriptRequest(this, query(), dbName));
if (!_scriptInfo.script().isEmpty())
LOG_MSG(_scriptInfo.script(), mongo::logger::LogSeverity::Info());
} else {
AppRegistry::instance().bus()->publish(new ScriptExecutingEvent(this));
_scriptInfo.setScript("");
AppRegistry::instance().bus()->send(_server->worker(), new ExecuteScriptRequest(this, query() , dbName));
}
if (!_scriptInfo.execute())
return;
std::string const finalScript = script.empty() ? query() : script;
eventBus()->publish(new ScriptExecutingEvent(this));
eventBus()->send(_server->worker(),
new ExecuteScriptRequest(this, finalScript, dbName, _aggrInfo));
if (!_scriptInfo.script().isEmpty())
LOG_MSG(_scriptInfo.script(), mongo::logger::LogSeverity::Info());
}
void MongoShell::query(int resultIndex, const MongoQueryInfo &info)
{
AppRegistry::instance().bus()->send(_server->worker(), new ExecuteQueryRequest(this, resultIndex, info));
eventBus()->send(_server->worker(), new ExecuteQueryRequest(this, resultIndex, info));
}
void MongoShell::autocomplete(const std::string &prefix)
{
AutocompletionMode autocompletionMode = AppRegistry::instance().settingsManager()->autocompletionMode();
AutocompletionMode autocompletionMode {
AppRegistry::instance().settingsManager()->autocompletionMode()
};
if (autocompletionMode == AutocompleteNone)
return;
AppRegistry::instance().bus()->send(_server->worker(), new AutocompleteRequest(this, prefix, autocompletionMode));
eventBus()->send(_server->worker(),
new AutocompleteRequest(this, prefix, autocompletionMode)
);
}
void MongoShell::stop()
@@ -84,39 +90,50 @@ namespace Robomongo
void MongoShell::handle(ExecuteQueryResponse *event)
{
if (event->isError()) {
AppRegistry::instance().bus()->publish(new DocumentListLoadedEvent(this, event->error()));
eventBus()->publish(new DocumentListLoadedEvent(this, event->error()));
return;
}
AppRegistry::instance().bus()->publish(new DocumentListLoadedEvent(this, event->resultIndex, event->queryInfo, query(), event->documents));
eventBus()->publish(
new DocumentListLoadedEvent(this,
event->resultIndex, event->queryInfo, query(), event->documents)
);
}
void MongoShell::handle(ExecuteScriptResponse *event)
{
if (event->isError()) {
if (_server->connectionRecord()->isReplicaSet()) {
AppRegistry::instance().bus()->publish(
new ReplicaSetRefreshed(this, event->error(), event->error().replicaSetInfo()));
AppRegistry::instance().bus()->publish(new ScriptExecutedEvent(this, event->error()));
return;
}
else { // single server
AppRegistry::instance().bus()->publish(new ScriptExecutedEvent(this, event->error()));
return;
}
if (!event->isError()) {
eventBus()->publish(
new ScriptExecutedEvent(this, event->result, event->empty, event->timeoutReached())
);
return;
}
AppRegistry::instance().bus()->publish(new ScriptExecutedEvent(this, event->result, event->empty));
if (_server->connectionRecord()->isReplicaSet()) {
eventBus()->publish(
new ReplicaSetRefreshed(this, event->error(), event->error().replicaSetInfo())
);
eventBus()->publish(
new ScriptExecutedEvent(this, event->error(), event->timeoutReached())
);
return;
}
else { // single server
eventBus()->publish(
new ScriptExecutedEvent(this, event->error(), event->timeoutReached())
);
return;
}
}
void MongoShell::handle(AutocompleteResponse *event)
{
if (event->isError()) {
AppRegistry::instance().bus()->publish(new AutocompleteResponse(this, event->error()));
eventBus()->publish(new AutocompleteResponse(this, event->error()));
return;
}
AppRegistry::instance().bus()->publish(new AutocompleteResponse(this, event->list, event->prefix));
eventBus()->publish(new AutocompleteResponse(this, event->list, event->prefix));
}
}
+9 -2
View File
@@ -2,15 +2,18 @@
#include <QObject>
#include "robomongo/core/events/MongoEvents.h"
#include "robomongo/core/domain/ScriptInfo.h"
#include "robomongo/core/domain/MongoAggregateInfo.h"
namespace Robomongo
{
struct AggrInfo;
class MongoShell : public QObject
{
Q_OBJECT
public:
MongoShell(MongoServer *server, const ScriptInfo &scriptInfo);
MongoShell(MongoServer *server, ScriptInfo scriptInfo);
void open(const std::string &script, const std::string &dbName = std::string());
void query(int resultIndex, const MongoQueryInfo &info);
@@ -18,11 +21,14 @@ namespace Robomongo
void stop();
MongoServer *server() const { return _server; }
std::string query() const;
void execute(const std::string &dbName = std::string());
void execute(const std::string &script = "", const std::string &dbName = "");
bool isExecutable() const { return _scriptInfo.execute(); }
const QString &title() const { return _scriptInfo.title(); }
std::string dbname() const { return _scriptInfo.dbname(); }
const CursorPosition &cursor() const { return _scriptInfo.cursor(); }
void setScript(const QString &script) { return _scriptInfo.setScript(script); }
void setScriptExecutable(bool execute) { _scriptInfo.setExecutable(execute); }
void setAggrInfo(AggrInfo const& aggrInfo) { _aggrInfo = aggrInfo; }
QString filePath() const { return _scriptInfo.filePath(); }
bool saveToFile();
@@ -36,6 +42,7 @@ namespace Robomongo
private:
ScriptInfo _scriptInfo;
AggrInfo _aggrInfo;
MongoServer *_server;
};
@@ -1,21 +0,0 @@
#include "robomongo/core/domain/MongoShellResult.h"
namespace Robomongo
{
MongoShellResult::MongoShellResult(const std::string &type, const std::string &response, const MongoDocumentPtrContainerType &documents,
const MongoQueryInfo &queryInfo, qint64 elapsedms) :
_type(type),
_response(response),
_documents(documents),
_queryInfo(queryInfo),
_elapsedms(elapsedms) { }
MongoShellExecResult::MongoShellExecResult(const std::vector<MongoShellResult> &results,
const std::string &currentServer, bool isCurrentServerValid,
const std::string &currentDatabase, bool isCurrentDatabaseValid) :
_results(results),
_currentServer(currentServer),
_currentDatabase(currentDatabase),
_isCurrentServerValid(isCurrentServerValid),
_isCurrentDatabaseValid(isCurrentDatabaseValid) { }
}
+46 -11
View File
@@ -1,43 +1,76 @@
#pragma once
#include "robomongo/core/domain/MongoQueryInfo.h"
#include "robomongo/core/domain/MongoAggregateInfo.h"
#include "robomongo/core/domain/MongoDocument.h"
namespace Robomongo
{
/* -------------- MongoShellResult Class --------- */
class MongoShellResult
{
public:
typedef std::vector<MongoDocumentPtr> MongoDocumentPtrContainerType;
MongoShellResult(const std::string &type, const std::string &response, const MongoDocumentPtrContainerType &documents,
const MongoQueryInfo &queryInfo, qint64 elapsedms);
MongoShellResult(
const std::string &type, const std::string &response,
const std::vector<MongoDocumentPtr> &documents,
const MongoQueryInfo &queryInfo, const std::string &statement,
qint64 elapsedms, AggrInfo aggrInfo = AggrInfo()) :
_type(type),
_response(response),
_documents(documents),
_queryInfo(queryInfo),
_statement(statement),
_elapsedms(elapsedms),
_aggrInfo(aggrInfo)
{ }
std::string response() const { return _response; }
std::string type() const { return _type; }
MongoDocumentPtrContainerType documents() const { return _documents; }
std::vector<MongoDocumentPtr> documents() const { return _documents; }
MongoQueryInfo queryInfo() const { return _queryInfo; }
std::string statement() const { return _statement; }
std::string statementShort() const {
std::size_t const LEN = _statement.size() < 10 ? _statement.size() : 10;
std::string statementShort { _statement, 0, LEN };
statementShort.append((_statement.size() > 10) ? ".." : "");
return statementShort;
}
qint64 elapsedMs() const { return _elapsedms; }
AggrInfo const& aggrInfo() const { return _aggrInfo; }
private:
std::string _type;
std::string _response;
MongoDocumentPtrContainerType _documents;
std::vector<MongoDocumentPtr> _documents;
MongoQueryInfo _queryInfo;
std::string const _statement;
qint64 _elapsedms;
AggrInfo _aggrInfo = AggrInfo();
};
/* -------------- MongoShellExecResult Class --------- */
class MongoShellExecResult
{
public:
MongoShellExecResult() { }
MongoShellExecResult(const std::vector<MongoShellResult> &results,
const std::string &currentServer, bool isCurrentServerValid,
const std::string &currentDatabase, bool isCurrentDatabaseValid);
MongoShellExecResult(
const std::vector<MongoShellResult> &results,
const std::string &currentServer, bool isCurrentServerValid,
const std::string &currentDatabase, bool isCurrentDatabaseValid,
bool timeoutReached = false) :
_results(results),
_currentServer(currentServer),
_currentDatabase(currentDatabase),
_isCurrentServerValid(isCurrentServerValid),
_isCurrentDatabaseValid(isCurrentDatabaseValid),
_timeoutReached(timeoutReached)
{ }
MongoShellExecResult(bool error, std::string const& errorMsg = "") :
_error(error), _errorMessage(errorMsg) { }
MongoShellExecResult(bool error, std::string const& errorMsg = "", bool timeoutReached = false) :
_error(error), _errorMessage(errorMsg), _timeoutReached(timeoutReached) { }
std::vector<MongoShellResult> results() const { return _results; }
std::vector<MongoShellResult> const& results() const { return _results; }
std::string currentServer() const { return _currentServer; }
void setCurrentServer(std::string const& server) { _currentServer = server; }
std::string currentDatabase() const { return _currentDatabase; }
@@ -45,6 +78,7 @@ namespace Robomongo
bool isCurrentDatabaseValid() const { return _isCurrentDatabaseValid; }
std::string errorMessage() const { return _errorMessage; }
bool error() const { return _error; }
bool timeoutReached() const { return _timeoutReached; }
private:
std::vector<MongoShellResult> _results;
@@ -54,5 +88,6 @@ namespace Robomongo
bool _isCurrentDatabaseValid;
std::string _errorMessage;
bool _error = false;
bool _timeoutReached = false;
};
}
-63
View File
@@ -1,63 +0,0 @@
#include "robomongo/core/domain/MongoUser.h"
#include <mongo/client/dbclientinterface.h>
#include "robomongo/core/utils/BsonUtils.h"
namespace Robomongo
{
const float MongoUser::minimumSupportedVersion = 2.4f;
MongoUser::MongoUser(const float version, const mongo::BSONObj &obj) :
_version(version), _readOnly(false)
{
_id = obj.getField("_id").OID();
_name = BsonUtils::getField<mongo::String>(obj, "user");
_passwordHash = BsonUtils::getField<mongo::String>(obj, "pwd");
if (_version<minimumSupportedVersion) {
_readOnly = BsonUtils::getField<mongo::Bool>(obj, "readOnly");
}
else {
_userSource = BsonUtils::getField<mongo::String>(obj, "userSource");
std::vector<mongo::BSONElement> roles = BsonUtils::getField<mongo::Array>(obj, "roles");
for (std::vector<mongo::BSONElement>::const_iterator it = roles.begin(); it != roles.end(); ++it)
{
_role.push_back(BsonUtils::bsonelement_cast<std::string>(*it));
}
}
}
MongoUser::MongoUser(const float version) :
_version(version), _readOnly(false), _role() {}
mongo::BSONObj MongoUser::toBson() const
{
mongo::BSONObjBuilder builder;
if (!(_id == mongo::OID())) // if not empty (i.e. not Object("0000000000000000"))
builder.append("_id", _id);
builder.append("user", _name);
if (!_passwordHash.empty())
builder.append("pwd", _passwordHash);
if (_version<minimumSupportedVersion) {
builder.append("readOnly", _readOnly);
}
else {
if (!_userSource.empty())
builder.append("userSource", _userSource);
mongo::BSONArrayBuilder builderA;
for (RoleType::const_iterator it = _role.begin(); it != _role.end(); ++it)
{
builderA << *it;
}
mongo::BSONObj arObj = builderA.arr();
builder.appendArray("roles", arObj);
}
mongo::BSONObj obj = builder.obj();
return obj;
}
}
+19 -20
View File
@@ -2,46 +2,45 @@
#include <mongo/bson/bsonobj.h>
#include <mongo/bson/bsonelement.h>
#include "robomongo/core/utils/BsonUtils.h"
namespace Robomongo
{
class MongoUser
{
public:
typedef std::vector<std::string> RoleType;
/**
* @brief Creates user from "system.users" document
*/
explicit MongoUser(const float version, const mongo::BSONObj &obj);
typedef std::vector<std::string> RolesVector;
/**
* @brief Creates new user with empty attributes
*/
MongoUser(const float version);
explicit MongoUser(const float version, const mongo::BSONObj &obj) :
_version(version), _readOnly(false),
_name(BsonUtils::getField<mongo::String>(obj, "user"))
{};
// Creates new user with empty attributes
MongoUser(const float version) :
_version(version), _readOnly(false), _roles() {}
mongo::OID id() const { return _id; }
std::string name() const { return _name; }
RoleType role() const { return _role; }
std::string passwordHash() const { return _passwordHash; }
std::string password() const { return _password; }
std::vector<std::string> roles() const { return _roles; }
void setName(const std::string &name) { _name = name; }
void setRole(const RoleType &role) { _role = role; }
void setPasswordHash(const std::string &hash) { _passwordHash = hash; }
void setPassword(const std::string &pwd) { _password = pwd; }
void setRoles(const std::vector<std::string> &roles) { _roles = roles; }
std::string userSource() const { return _userSource; }
void setUserSource(const std::string &source) { _userSource = source; }
mongo::BSONObj toBson() const;
bool readOnly() const { return _readOnly; }
void setReadOnly(bool readonly) { _readOnly = readonly; }
float version() const { return _version; }
static const float minimumSupportedVersion;
static constexpr float minimumSupportedVersion = 2.4f;
private:
float _version;
mongo::OID _id;
std::string _name;
bool _readOnly;
RoleType _role;
std::string _passwordHash;
RolesVector _roles;
std::string _password;
std::string _userSource;
};
}
}
+32 -13
View File
@@ -1,5 +1,8 @@
#include "robomongo/core/domain/Notifier.h"
#include <thread>
#include <chrono>
#include <QAction>
#include <QClipboard>
#include <QApplication>
@@ -15,6 +18,7 @@
#include "robomongo/shell/db/ptimeutil.h"
#include "robomongo/gui/MainWindow.h"
#include "robomongo/gui/widgets/workarea/BsonTreeItem.h"
#include "robomongo/gui/dialogs/DocumentTextEditor.h"
#include "robomongo/gui/utils/DialogUtils.h"
@@ -138,8 +142,9 @@ namespace Robomongo
void Notifier::initMenu(QMenu *const menu, BsonTreeItem *const item)
{
bool isEditable = _queryInfo._info.isValid();
bool onItem = item ? true : false;
bool const isProjection = !_queryInfo._fields.isEmpty();
bool const isEditable = _queryInfo._info.isValid() && !isProjection;
bool const onItem = item ? true : false;
bool isSimple = false;
bool isDocument = false;
@@ -220,12 +225,14 @@ namespace Robomongo
RemoveDocumentCount::MULTI;
_shell->server()->removeDocuments(query, _queryInfo._info._ns, removeCount, index);
++index;
mainWindow()->showQueryWidgetProgressBar();
}
}
void Notifier::handle(InsertDocumentResponse *event)
{
if (event->isError()) { // Error
mainWindow()->hideQueryWidgetProgressBar();
if (_shell->server()->connectionRecord()->isReplicaSet()) {
// Insert document from tab results window (Notifier, OutputWindow widget)
if (EventError::SetPrimaryUnreachable == event->error().errorCode()) {
@@ -235,11 +242,12 @@ namespace Robomongo
}
else // single server
QMessageBox::warning(NULL, "Database Error", QString::fromStdString(event->error().errorMessage()));
return;
}
// Success
std::this_thread::sleep_for(std::chrono::milliseconds(100));
_shell->query(0, _queryInfo);
}
@@ -249,8 +257,10 @@ namespace Robomongo
if (!(event->removeCount == RemoveDocumentCount::MULTI && event->index > 0))
QMessageBox::warning(NULL, "Database Error", QString::fromStdString(event->error().errorMessage()));
}
else // Success
_shell->query(0, _queryInfo);
else { // Success
std::this_thread::sleep_for(std::chrono::milliseconds(100));
_shell->query(0, _queryInfo);
}
}
void Notifier::onCopyNameDocument()
@@ -300,6 +310,16 @@ namespace Robomongo
clipboard->setText(namesList.join("."));
}
MainWindow* Notifier::mainWindow() const
{
MainWindow* mainWindow;
for (auto wid : QApplication::topLevelWidgets()) {
if ((mainWindow = qobject_cast<MainWindow*>(wid)))
break;
}
return mainWindow;
}
void Notifier::handleDeleteCommand()
{
if (_observer->selectedIndexes().count() > 1)
@@ -358,22 +378,20 @@ namespace Robomongo
if (!documentItem)
return;
mongo::BSONObj obj = documentItem->superRoot();
std::string str = BsonUtils::jsonString(obj, mongo::TenGen, 1,
AppRegistry::instance().settingsManager()->uuidEncoding(),
AppRegistry::instance().settingsManager()->timeZone());
std::string str = BsonUtils::jsonString(documentItem->superRoot(), mongo::TenGen, 1,
AppRegistry::instance().settingsManager()->uuidEncoding(),
AppRegistry::instance().settingsManager()->timeZone());
const QString &json = QtUtils::toQString(str);
DocumentTextEditor editor(_queryInfo._info,
json, false, dynamic_cast<QWidget*>(_observer));
DocumentTextEditor editor(_queryInfo._info, json, false, dynamic_cast<QWidget*>(_observer));
editor.setWindowTitle("Edit Document");
int result = editor.exec();
if (result == QDialog::Accepted) {
_shell->server()->saveDocuments(editor.bsonObj(), _queryInfo._info._ns);
mainWindow()->showQueryWidgetProgressBar();
}
}
@@ -399,7 +417,7 @@ namespace Robomongo
json, true, dynamic_cast<QWidget*>(_observer));
editor->setWindowTitle("View Document");
editor->exec();
editor->show();
}
void Notifier::onInsertDocument()
@@ -420,6 +438,7 @@ namespace Robomongo
DocumentTextEditor::ReturnType obj = editor.bsonObj();
for (DocumentTextEditor::ReturnType::const_iterator it = obj.begin(); it != obj.end(); ++it) {
_shell->server()->insertDocument(*it, _queryInfo._info._ns);
mainWindow()->showQueryWidgetProgressBar();
}
}
+3
View File
@@ -11,6 +11,7 @@ QT_END_NAMESPACE
namespace Robomongo
{
class MainWindow;
class MongoShell;
class BsonTreeItem;
class InsertDocumentResponse;
@@ -65,6 +66,8 @@ namespace Robomongo
void onCopyPathDocument();
private:
MainWindow* mainWindow() const;
QAction *_deleteDocumentAction;
QAction *_deleteDocumentsAction;
QAction *_editDocumentAction;
+3 -2
View File
@@ -62,10 +62,11 @@ namespace
namespace Robomongo
{
ScriptInfo::ScriptInfo(const QString &script, bool execute, const CursorPosition &position,
const QString &title, const QString &filePath) :
ScriptInfo::ScriptInfo(const QString &script, bool execute, const std::string &dbname,
const CursorPosition &position, const QString &title, const QString &filePath) :
_script(script),
_execute(execute),
_dbname(dbname),
_title(title),
_cursor(position),
_filePath(filePath) {}
+5 -2
View File
@@ -9,12 +9,14 @@ namespace Robomongo
class ScriptInfo
{
public:
ScriptInfo(const QString &script, bool execute = false,
ScriptInfo(const QString &script, bool execute = false, const std::string &dbname = "",
const CursorPosition &position = CursorPosition(),
const QString &title = QString(), const QString &filePath = QString());
bool execute() const { return _execute; }
void setExecutable(bool execute) { _execute = execute; }
QString script() const { return _script; }
std::string dbname() const { return _dbname; }
const QString &title() const { return _title; }
const CursorPosition &cursor() const { return _cursor; }
void setScript(const QString &script) { _script = script; }
@@ -26,7 +28,8 @@ namespace Robomongo
private:
QString _script;
const bool _execute;
std::string _dbname;
bool _execute;
const QString _title;
const CursorPosition _cursor;
QString _filePath;
+106 -58
View File
@@ -15,6 +15,7 @@
//#include <third_party/js-1.7/jsstr.h>
#include <mongo/util/assert_util.h>
#include <mongo/util/exit_code.h>
#include <mongo/scripting/engine.h>
// v0.9
@@ -23,12 +24,14 @@
#include <mongo/shell/shell_utils.h>
#include <mongo/base/string_data.h>
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
#include <pcrecpp.h>
#include "robomongo/core/events/MongoEvents.h"
#include "robomongo/core/settings/ConnectionSettings.h"
#include "robomongo/core/settings/CredentialSettings.h"
#include "robomongo/core/domain/MongoDocument.h"
#include "robomongo/core/utils/Logger.h"
#include "robomongo/core/utils/QtUtils.h"
namespace
@@ -50,7 +53,6 @@ namespace
namespace mongo {
extern bool isShell;
void logProcessDetailsForLogRotate() {}
void exitCleanly(ExitCode code) {}
}
namespace Robomongo
@@ -91,19 +93,18 @@ namespace Robomongo
<< _connection->primaryCredential()->userPassword() << "')";
{
mongo::shell_utils::_dbConnect = ss.str();
mongo::shell_utils::_dbAuth = "(function() { \nDB.prototype._defaultGssapiServiceName = \"mongodb\";\n}())";
mongo::shell_utils::dbConnect = ss.str();
// v0.9
// mongo::isShell = true;
mongo::ScriptEngine::setConnectCallback( mongo::shell_utils::onConnect );
mongo::ScriptEngine::setup();
mongo::globalScriptEngine->setScopeInitCallback(mongo::shell_utils::initScope);
mongo::globalScriptEngine->enableJIT(true);
mongo::ScriptEngine::setup();
mongo::getGlobalScriptEngine()->setScopeInitCallback(mongo::shell_utils::initScope);
mongo::getGlobalScriptEngine()->enableJIT(true);
_scope.reset(mongo::globalScriptEngine->newScope());
_engine = mongo::globalScriptEngine;
_scope.reset(mongo::getGlobalScriptEngine()->newScope());
_engine = mongo::getGlobalScriptEngine();
// Load '.mongorc.js' from user's home directory
if (isLoadMongoRcJs) {
@@ -137,7 +138,7 @@ namespace Robomongo
// Cache result of original "DB.autocomplete"
// Cache invalidated by the invalidateDbCollectionsCache() method.
std::string cacheAutocompletion =
std::string const cacheAutocompletion =
"__robomongoAutocompletionCache = null;"
"DB.autocompleteCached = function(obj) { "
" if (__robomongoAutocompletionCache == null) {"
@@ -148,10 +149,26 @@ namespace Robomongo
_scope->exec(cacheAutocompletion, "", false, false, false);
// Capture aggregate parameters: pipeline, options
std::string const aggregateInterceptor =
"__robomongoAggregateUsed = false;"
"__robomongoAggregate = DBCollection.prototype.aggregate;"
"__robomongoAggregatePipeline = null;"
"__robomongoAggregateOptions = null;"
"DBCollection.prototype.aggregate = function(pipeline, options) { "
" __robomongoAggregateUsed = true;"
" __robomongoAggregatePipeline = pipeline;"
" __robomongoAggregateOptions = options;"
" return __robomongoAggregate.call(this, pipeline, options);"
"}";
_scope->exec(aggregateInterceptor, "", false, false, false);
_initialized = true;
}
MongoShellExecResult ScriptEngine::exec(const std::string &originalScript, const std::string &dbName)
MongoShellExecResult ScriptEngine::exec(const std::string &originalScript, const std::string &dbName,
AggrInfo aggrInfo /* = AggrInfo() */)
{
QMutexLocker lock(&_mutex);
@@ -160,6 +177,9 @@ namespace Robomongo
return MongoShellExecResult(true, "Connection error. Uninitialized mongo scope.");
}
// robomongo shell timeout
bool timeoutReached = false;
/*
* Replace all commands ('show dbs', 'use db' etc.) with call
* to shellHelper('show', 'dbs') and so on.
@@ -179,17 +199,14 @@ namespace Robomongo
std::string error;
bool result = statementize(stdstr, statements, error);
if (!result && statements.size() == 0) {
if (!result && statements.size() == 0)
statements.push_back("print(__robomongoResult.error)");
}
std::vector<MongoShellResult> results;
use(dbName);
for (std::vector<std::string>::const_iterator it = statements.begin(); it != statements.end(); ++it)
{
std::string statement = *it;
for (auto const& statement : statements) {
// clear global objects
__objects.clear();
__type = "";
@@ -205,23 +222,27 @@ namespace Robomongo
_scope->exec( "__robomongoLastRes = __lastres__; shellPrintHelper( __lastres__ );",
"(shell2)" , true , true , false, _timeoutSec * 1000);
}
else { // failed to run script
failed = true;
}
else // failed to run script
failed = true;
qint64 elapsed = timer.elapsed();
qint64 elapsed = timer.elapsed(); // milliseconds
if (elapsed > _timeoutSec * 1000)
timeoutReached = true;
std::string logs = __logs.str();
std::string answer = logs.c_str();
std::string type = __type.c_str();
if (failed)
if (failed && !timeoutReached)
return MongoShellExecResult(true, answer);
std::vector<MongoDocumentPtr> docs = MongoDocument::fromBsonObj(__objects);
if (!answer.empty() || docs.size() > 0)
results.push_back(prepareResult(type, answer, docs, elapsed));
results.push_back(
prepareResult(type, answer, docs, elapsed, statement, aggrInfo)
);
}
catch (const std::exception &e) {
std::cout << "error:" << e.what() << std::endl;
@@ -229,7 +250,7 @@ namespace Robomongo
}
}
return prepareExecResult(results);
return prepareExecResult(results, timeoutReached);
}
void ScriptEngine::interrupt()
@@ -311,14 +332,17 @@ namespace Robomongo
}
MongoShellResult ScriptEngine::prepareResult(const std::string &type, const std::string &output,
const std::vector<MongoDocumentPtr> &objects, qint64 elapsedms)
const std::vector<MongoDocumentPtr> &objects, qint64 elapsedms,
const std::string &statement, AggrInfo aggrInfo /*= AggrInfo()*/)
{
const char *script =
"__robomongoQuery = false; \n"
"__robomongoIsAggregate = false; \n"
"__robomongoDbName = '[invalid database]'; \n"
"__robomongoServerAddress = '[invalid connection]'; \n"
"__robomongoCollectionName = '[invalid collection]'; \n"
"if (typeof __robomongoLastRes == 'object' && __robomongoLastRes != null && __robomongoLastRes instanceof DBQuery) { \n"
"if (typeof __robomongoLastRes == 'object' && __robomongoLastRes != null \n"
" && __robomongoLastRes instanceof DBQuery) { \n"
" __robomongoQuery = true; \n"
" __robomongoDbName = __robomongoLastRes._db.getName();\n "
" __robomongoServerAddress = __robomongoLastRes._mongo.host; \n"
@@ -330,16 +354,27 @@ namespace Robomongo
" __robomongoBatchSize = __robomongoLastRes._batchSize; \n"
" __robomongoOptions = __robomongoLastRes._options; \n"
" __robomongoSpecial = __robomongoLastRes._special; \n"
"} \n";
"} \n"
"else if (typeof __robomongoLastRes == 'object' && __robomongoLastRes != null \n"
" && __robomongoLastRes instanceof DBCommandCursor \n"
" && __robomongoAggregateUsed) { \n"
" __robomongoAggregateUsed = false; \n"
" __robomongoIsAggregate = true; \n"
" __robomongoDbName = __robomongoLastRes._db.getName();\n "
" __robomongoServerAddress = __robomongoLastRes._db._mongo.host; \n"
" __robomongoCollectionName = __robomongoLastRes._collName; \n"
"} \n"
;
_scope->exec(script, "(getresultinfo)", false, false, false);
bool isQuery = _scope->getBoolean("__robomongoQuery");
bool const isQuery = _scope->getBoolean("__robomongoQuery");
bool const isAggregate = _scope->getBoolean("__robomongoIsAggregate");
if (isQuery) {
std::string serverAddress = getString("__robomongoServerAddress");
std::string dbName = getString("__robomongoDbName");
std::string collectionName = getString("__robomongoCollectionName");
mongo::BSONObj query = _scope->getObject("__robomongoQuery");
mongo::BSONObj fields = _scope->getObject("__robomongoFields");
@@ -350,15 +385,32 @@ namespace Robomongo
bool special = _scope->getBoolean("__robomongoSpecial");
MongoQueryInfo info = MongoQueryInfo(CollectionInfo(serverAddress, dbName, collectionName),
query, fields, limit, skip, batchSize, options, special);
return MongoShellResult(type, output, objects, info, elapsedms);
MongoQueryInfo const info{ CollectionInfo(serverAddress, dbName, collectionName),
query, fields, limit, skip, batchSize, options, special };
return MongoShellResult(type, output, objects, info, statement, elapsedms);
}
else if (isAggregate) {
std::string const serverAddress = getString("__robomongoServerAddress");
std::string const dbName = getString("__robomongoDbName");
std::string const collectionName = getString("__robomongoCollectionName");
mongo::BSONObj const pipeline = _scope->getObject("__robomongoAggregatePipeline");
mongo::BSONObj const options = _scope->getObject("__robomongoAggregateOptions");
return MongoShellResult(type, output, objects, MongoQueryInfo(), elapsedms);
// This query can be paging of an original aggr. query, we store the original/unpaged
// pipeline object here.
mongo::BSONObj const origPipeline = aggrInfo.isValid ? aggrInfo.pipeline : pipeline;
int const skip = aggrInfo.isValid ? aggrInfo.skip : 0;
int const batchSize = aggrInfo.isValid ? aggrInfo.batchSize : 50;
int const resultIndex = aggrInfo.isValid ? aggrInfo.resultIndex : -1;
AggrInfo const newAggrInfo { collectionName, skip, batchSize, origPipeline, options, resultIndex };
return MongoShellResult(type, output, objects, MongoQueryInfo(), statement, elapsedms, newAggrInfo);
}
return MongoShellResult(type, output, objects, MongoQueryInfo(), statement, elapsedms);
}
MongoShellExecResult ScriptEngine::prepareExecResult(const std::vector<MongoShellResult> &results)
MongoShellExecResult ScriptEngine::prepareExecResult(const std::vector<MongoShellResult> &results,
bool timeoutReached /* = false */)
{
const char *script =
"__robomongoServerAddress = '[invalid connection]'; \n"
@@ -380,7 +432,7 @@ namespace Robomongo
std::string dbName = getString("__robomongoDbName");
bool dbIsValid = _scope->getBoolean("__robomongoDbIsValid");
return MongoShellExecResult(results, serverName, serverIsValid, dbName, dbIsValid);
return MongoShellExecResult(results, serverName, serverIsValid, dbName, dbIsValid, timeoutReached);
}
std::string ScriptEngine::getString(const char *fieldName)
@@ -388,12 +440,12 @@ namespace Robomongo
return _scope->getString(fieldName);
}
bool ScriptEngine::statementize(const std::string &script, std::vector<std::string> &outList, std::string &outError)
bool ScriptEngine::statementize(
const std::string &script, std::vector<std::string> &outVec, std::string &outError)
{
QString qScript = QtUtils::toQString(script);
_scope->setString("__robomongoEsprima", script.c_str());
mongo::StringData data(
mongo::StringData const data {
"var __robomongoResult = {};"
"try {"
"__robomongoResult.result = esprima.parse(__robomongoEsprima, { range: true, loc : true });"
@@ -401,36 +453,31 @@ namespace Robomongo
"__robomongoResult.error = e.name + ': ' + e.message;"
"}"
"__robomongoResult;"
);
};
bool res2 = _scope->exec(data, "(esprima2)", false, true, false);
mongo::BSONObj obj = _scope->getObject("__lastres__");
if(!_scope->exec(data, "(esprima2)", false, true, false)) {
sendLog(this, LogEvent::RBM_ERROR, "ScriptEngine: Scope failed. Resetting scope.");
_scope->reset();
sendLog(this, LogEvent::RBM_INFO, "ScriptEngine: Scope reset complete.");
_scope->exec(data, "(esprima2)", false, true, false);
}
mongo::BSONObj const obj = _scope->getObject("__lastres__");
if (obj.hasField("error")) {
outError = obj.getField("error");
return false;
}
mongo::BSONObj result = obj.getField("result").Obj();
std::vector<mongo::BSONElement> v = result.getField("body").Array();
for (std::vector<mongo::BSONElement>::iterator it = v.begin(); it != v.end(); ++it)
for (auto const& bsonElem : obj.getField("result").Obj().getField("body").Array())
{
mongo::BSONObj item = (*it).Obj();
mongo::BSONObj loc = item.getField("loc").Obj();
mongo::BSONObj start = loc.getField("start").Obj();
mongo::BSONObj end = loc.getField("end").Obj();
mongo::BSONObj const item = bsonElem.Obj();
std::vector<mongo::BSONElement> const range = item.getField("range").Array();
auto const from = static_cast<int>(range.at(0).number());
auto const till = static_cast<int>(range.at(1).number());
int startLine = start.getIntField("line");
int startColumn = start.getIntField("column");
int endLine = end.getIntField("line");
int endColumn = end.getIntField("column");
std::vector<mongo::BSONElement> range = item.getField("range").Array();
int from = (int) range.at(0).number();
int till = (int) range.at(1).number();
std::string statement = QtUtils::toStdString(qScript.mid(from, till - from));
outList.push_back(statement);
QString const qScript = QtUtils::toQString(script);
std::string statement = qScript.mid(from, till - from).toStdString();
outVec.push_back(statement);
}
return true;
@@ -457,3 +504,4 @@ namespace Robomongo
return QtUtils::toStdString(content);
}
}
+17 -8
View File
@@ -1,5 +1,6 @@
#pragma once
#include <QObject>
#include <QMutex>
#include <mongo/scripting/engine.h>
//#include <third_party/js-1.7/jsparse.h>
@@ -11,15 +12,17 @@ namespace Robomongo
{
class ConnectionSettings;
class ScriptEngine
class ScriptEngine : public QObject
{
Q_OBJECT
public:
ScriptEngine(ConnectionSettings *connection, int timeoutSec);
~ScriptEngine();
void init(bool isLoadMongoJs, const std::string& serverAddr = "", const std::string& dbName = "");
MongoShellExecResult exec(const std::string &script, const std::string &dbName = std::string());
MongoShellExecResult exec(const std::string &script, const std::string &dbName = std::string(),
AggrInfo aggrInfo = AggrInfo());
void interrupt();
void use(const std::string &dbName);
@@ -31,20 +34,26 @@ namespace Robomongo
bool failedScope() const { return _failedScope; }
void changeTimeout(int newTimeout) { _timeoutSec = newTimeout; }
private:
ConnectionSettings *_connection;
MongoShellResult prepareResult(const std::string &type, const std::string &output, const std::vector<MongoDocumentPtr> &objects, qint64 elapsedms);
MongoShellExecResult prepareExecResult(const std::vector<MongoShellResult> &results);
MongoShellResult prepareResult(const std::string &type, const std::string &output,
const std::vector<MongoDocumentPtr> &objects, qint64 elapsedms,
const std::string &statement, AggrInfo aggrInfo = AggrInfo());
MongoShellExecResult prepareExecResult(
const std::vector<MongoShellResult> &results, bool timeoutReached = false);
std::string loadFile(const QString &path, bool throwOnError);
std::string getString(const char *fieldName);
bool statementize(const std::string &script, std::vector<std::string> &outList, std::string &outError);
bool statementize(
const std::string &script, std::vector<std::string> &outVec, std::string &outError);
int _timeoutSec;
mongo::ScriptEngine *_engine;
std::unique_ptr<mongo::Scope> _scope;
std::unique_ptr<mongo::Scope> _scope; // MozJSProxyScope
bool _failedScope = false;
QMutex _mutex;
bool _initialized;
+3 -3
View File
@@ -17,10 +17,10 @@ namespace Robomongo
R_REGISTER_EVENT(LoadUsersRequest)
R_REGISTER_EVENT(LoadCollectionIndexesRequest)
R_REGISTER_EVENT(LoadCollectionIndexesResponse)
R_REGISTER_EVENT(EnsureIndexRequest)
R_REGISTER_EVENT(AddEditIndexRequest)
R_REGISTER_EVENT(AddEditIndexResponse)
R_REGISTER_EVENT(DropCollectionIndexRequest)
R_REGISTER_EVENT(DeleteCollectionIndexResponse)
R_REGISTER_EVENT(EditIndexRequest)
R_REGISTER_EVENT(DropCollectionIndexResponse)
R_REGISTER_EVENT(LoadUsersResponse)
R_REGISTER_EVENT(LoadFunctionsRequest)
R_REGISTER_EVENT(LoadFunctionsResponse)
+116 -67
View File
@@ -1,15 +1,17 @@
#pragma once
#include <QMessageBox>
#include <QString>
#include <QStringList>
#include <QEvent>
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
#include "robomongo/core/domain/MongoShellResult.h"
#include "robomongo/core/domain/CursorPosition.h"
#include "robomongo/core/domain/MongoUser.h"
#include "robomongo/core/domain/MongoFunction.h"
#include "robomongo/core/events/MongoEventsInfo.h"
#include "robomongo/core/domain/MongoAggregateInfo.h"
#include "robomongo/core/Event.h"
#include "robomongo/core/Enums.h"
#include "robomongo/core/mongodb/ReplicaSet.h"
@@ -223,58 +225,80 @@ namespace Robomongo
{
R_EVENT
public:
LoadCollectionIndexesResponse(QObject *sender, const std::vector<EnsureIndexInfo> &indexes) :
LoadCollectionIndexesResponse(QObject *sender, const std::vector<IndexInfo> &indexes) :
Event(sender), _indexes(indexes) {}
LoadCollectionIndexesResponse(QObject *sender, const EventError &error) :
Event(sender, error) {}
std::vector<EnsureIndexInfo> indexes() const { return _indexes; }
std::vector<IndexInfo> indexes() const { return _indexes; }
private:
std::vector<EnsureIndexInfo> _indexes;
std::vector<IndexInfo> _indexes;
};
class EnsureIndexRequest : public Event
class AddEditIndexRequest : public Event
{
R_EVENT
EnsureIndexRequest(QObject *sender, const EnsureIndexInfo &oldInfo, const EnsureIndexInfo &newInfo) : Robomongo::Event(sender), oldInfo_(oldInfo), newInfo_(newInfo) {}
const EnsureIndexInfo &oldInfo() const
AddEditIndexRequest(QObject *sender, const IndexInfo &oldInfo, const IndexInfo &newInfo)
: Robomongo::Event(sender), oldInfo_(oldInfo), newInfo_(newInfo) {}
const IndexInfo &oldInfo() const
{
return oldInfo_;
}
const EnsureIndexInfo &newInfo() const
const IndexInfo &newInfo() const
{
return newInfo_;
}
private:
const EnsureIndexInfo oldInfo_;
const EnsureIndexInfo newInfo_;
const IndexInfo oldInfo_;
const IndexInfo newInfo_;
};
struct AddEditIndexResponse : public Event
{
R_EVENT
AddEditIndexResponse(QObject *sender, const IndexInfo &oldIndex, const IndexInfo &newIndex)
: Event(sender), oldIndex_(oldIndex), newIndex_(newIndex)
{}
AddEditIndexResponse(QObject *sender, const EventError &error,
const IndexInfo &oldIndex, const IndexInfo &newIndex)
: Event(sender, error), oldIndex_(oldIndex), newIndex_(newIndex)
{}
const IndexInfo oldIndex_;
const IndexInfo newIndex_;
};
class DropCollectionIndexRequest : public Event
{
R_EVENT
public:
DropCollectionIndexRequest(QObject *sender, const MongoCollectionInfo &collection, const std::string &name) :
Event(sender),
_collection(collection),
_name(name) {}
DropCollectionIndexRequest(QObject *sender, const MongoCollectionInfo &collection,
const std::string &index)
: Event(sender), _collection(collection), _index(index)
{}
MongoCollectionInfo collection() const { return _collection; }
std::string name() const { return _name; }
std::string index() const { return _index; }
private:
const MongoCollectionInfo _collection;
std::string _name;
std::string _index; // todo: rename to index
};
class DeleteCollectionIndexResponse: public Event
class DropCollectionIndexResponse: public Event
{
R_EVENT
public:
DeleteCollectionIndexResponse(QObject *sender, const MongoCollectionInfo &collection, const std::string &index) :
Event(sender), _collection(collection), _index(index) {}
DropCollectionIndexResponse(QObject *sender, const MongoCollectionInfo &collection,
const std::string &index)
: Event(sender), _collection(collection), _index(index)
{}
DeleteCollectionIndexResponse(QObject *sender, const EventError &error) :
Event(sender, error) {}
DropCollectionIndexResponse(QObject *sender, const EventError &error,
const std::string &index)
: Event(sender, error), _index(index)
{}
MongoCollectionInfo collection() const { return _collection; }
std::string index() const { return _index; }
@@ -283,21 +307,6 @@ namespace Robomongo
std::string _index;
};
class EditIndexRequest : public Event
{
R_EVENT
public:
EditIndexRequest(QObject *sender, const MongoCollectionInfo &collection, const std::string &oldIndex, const std::string &newIndex) :
Event(sender), _collection(collection), _oldIndex(oldIndex), _newIndex(newIndex) {}
MongoCollectionInfo collection() const { return _collection; }
std::string oldIndex() const { return _oldIndex; }
std::string newIndex() const { return _newIndex; }
private:
const MongoCollectionInfo _collection;
std::string _oldIndex;
std::string _newIndex;
};
/**
* @brief Load Users
*/
@@ -726,20 +735,17 @@ namespace Robomongo
R_EVENT
public:
CreateUserRequest(QObject *sender, const std::string &database, const MongoUser &user, bool overwrite = false) :
CreateUserRequest(QObject *sender, const std::string &database, const MongoUser &user) :
Event(sender),
_database(database),
_user(user),
_overwrite(overwrite) {}
_user(user) {}
std::string database() const { return _database; }
MongoUser user() const { return _user; }
bool overwrite() const { return _overwrite; }
private:
std::string _database;
MongoUser _user;
bool _overwrite;
};
struct CreateUserResponse : public Event
@@ -765,17 +771,14 @@ namespace Robomongo
R_EVENT
public:
DropUserRequest(QObject *sender, const std::string &database, const mongo::OID &id,
std::string const& username) :
Event(sender), _database(database), _id(id), _username(username) {}
DropUserRequest(QObject *sender, const std::string &database, std::string const& username) :
Event(sender), _database(database), _username(username) {}
std::string database() const { return _database; }
mongo::OID id() const { return _id; }
std::string username() const { return _username; }
private:
std::string _database;
mongo::OID _id;
std::string const _username;
};
@@ -802,21 +805,25 @@ namespace Robomongo
R_EVENT
public:
CreateFunctionRequest(QObject *sender, const std::string &database, const MongoFunction &function,
const std::string &existingFunctionName = std::string(), bool overwrite = false) :
CreateFunctionRequest(QObject *sender, const std::string &database, float dbVersion,
const MongoFunction &function, const std::string &existingFunctionName = std::string(),
bool overwrite = false) :
Event(sender),
_database(database),
_dbVersion(dbVersion),
_existingFunctionName(existingFunctionName),
_function(function),
_overwrite(overwrite) {}
std::string database() const { return _database; }
float dbVersion() const { return _dbVersion; }
std::string existingFunctionName() const { return _existingFunctionName; }
MongoFunction function() const { return _function; }
bool overwrite() const { return _overwrite; }
private:
std::string _database;
float const _dbVersion = 0.0f;
std::string _existingFunctionName;
MongoFunction _function;
bool _overwrite;
@@ -846,16 +853,20 @@ namespace Robomongo
R_EVENT
public:
DropFunctionRequest(QObject *sender, const std::string &database, const std::string &funcName) :
DropFunctionRequest(QObject *sender, const std::string &database, float dbVersion,
const std::string &funcName) :
Event(sender),
_database(database),
_dbVersion(dbVersion),
_functionName(funcName) {}
std::string database() const { return _database; }
float dbVersion() const { return _dbVersion; }
std::string functionName() const { return _functionName; }
private:
std::string _database;
float const _dbVersion = 0.0f;
std::string _functionName;
};
@@ -950,33 +961,39 @@ namespace Robomongo
{
R_EVENT
ExecuteScriptRequest(QObject *sender, const std::string &script, const std::string &dbName, int take = 0, int skip = 0) :
ExecuteScriptRequest(QObject *sender, const std::string &script, const std::string &dbName,
AggrInfo aggrInfo = AggrInfo(), int take = 0, int skip = 0) :
Event(sender),
script(script),
databaseName(dbName),
aggrInfo(aggrInfo),
take(take),
skip(skip) {}
skip(skip)
{}
std::string script;
std::string databaseName;
int take; //
int skip;
AggrInfo const aggrInfo;
};
class ExecuteScriptResponse : public Event
{
R_EVENT
ExecuteScriptResponse(QObject *sender, const MongoShellExecResult &result, bool empty) :
Event(sender),
result(result),
empty(empty) { }
ExecuteScriptResponse(QObject *sender, const MongoShellExecResult &result, bool empty,
bool timeoutReached = false) :
Event(sender), result(result), empty(empty), _timeoutReached(timeoutReached) {}
ExecuteScriptResponse(QObject *sender, const EventError &error) :
Event(sender, error) {}
ExecuteScriptResponse(QObject *sender, const EventError &error, bool timeoutReached = false) :
Event(sender, error), _timeoutReached(timeoutReached) {}
bool timeoutReached() const { return _timeoutReached; }
MongoShellExecResult result;
bool empty;
bool const _timeoutReached = false;
};
class ConnectingEvent : public Event
@@ -1087,20 +1104,21 @@ namespace Robomongo
R_EVENT
public:
ScriptExecutedEvent(QObject *sender, const MongoShellExecResult &result, bool empty) :
Event(sender),
_result(result),
_empty(empty) { }
ScriptExecutedEvent(QObject *sender, const MongoShellExecResult &result, bool empty,
bool timeoutReached = false) :
Event(sender), _result(result), _empty(empty), _timeoutReached(timeoutReached) {}
ScriptExecutedEvent(QObject *sender, const EventError &error) :
Event(sender, error) {}
ScriptExecutedEvent(QObject *sender, const EventError &error, bool timeoutReached = false) :
Event(sender, error), _timeoutReached(timeoutReached) {}
MongoShellExecResult result() const { return _result; }
bool empty() const { return _empty; }
bool timeoutReached() const { return _timeoutReached; }
private:
MongoShellExecResult _result;
bool _empty;
bool const _timeoutReached = false;
};
class ScriptExecutingEvent : public Event
@@ -1237,13 +1255,44 @@ namespace Robomongo
RBM_DEBUG = 100 // log as much as possible
};
LogEvent(QObject *sender, const std::string& message, LogLevel level) :
Event(sender),
message(message),
level(level) {}
LogEvent(QObject *sender, const std::string& message, LogLevel level,
bool const informUser = false)
: Event(sender), message(message), level(level), informUser(informUser)
{}
std::string severity() const {
switch (level) {
case RBM_ERROR : return "Error";
case RBM_WARN : return "Warning";
case RBM_INFO : return "Info";
case RBM_DEBUG : return "Debug";
default: return "Undefined";
}
}
QMessageBox::Icon qMessageBoxIcon() const {
switch (level) {
case RBM_ERROR: return QMessageBox::Icon::Critical;
case RBM_WARN: return QMessageBox::Icon::Warning;
case RBM_INFO: return QMessageBox::Icon::Information;
case RBM_DEBUG: return QMessageBox::Icon::Information;
default: return QMessageBox::Icon::Information;
}
}
mongo::logger::LogSeverity mongoLogSeverity() const {
switch (level) {
case RBM_ERROR: return mongo::logger::LogSeverity::Error();
case RBM_WARN: return mongo::logger::LogSeverity::Warning();
case RBM_INFO: return mongo::logger::LogSeverity::Info();
case RBM_DEBUG: return mongo::logger::LogSeverity::Log();
default: return mongo::logger::LogSeverity::Info();
}
}
std::string message;
LogLevel level;
bool const informUser = false;
};
class StopScriptRequest : public Event
@@ -2,15 +2,15 @@
namespace Robomongo
{
EnsureIndexInfo::EnsureIndexInfo(const MongoCollectionInfo &collection, const std::string &name, const std::string &request,
bool isUnique, bool isBackGround, bool isDropDuplicates, bool isSparce, int expireAfter,
IndexInfo::IndexInfo(
const MongoCollectionInfo &collection, const std::string &name, const std::string &keys,
bool isUnique, bool isBackGround, bool isSparce, int expireAfter,
const std::string &defaultLanguage, const std::string &languageOverride, const std::string &textWeights) :
_name(name),
_collection(collection),
_request(request),
_keys(keys),
_unique(isUnique),
_backGround(isBackGround),
_dropDups(isDropDuplicates),
_sparse(isSparce),
_ttl(expireAfter),
_defaultLanguage(defaultLanguage),
@@ -21,14 +21,17 @@ namespace Robomongo
_address(),
_databases(),
_version(0.0f),
_dbVersionStr(),
_uuid(uuid)
{}
ConnectionInfo::ConnectionInfo(const std::string &address, const std::vector<std::string> &databases,
float version, const std::string& storageEngine, std::string const& uuid) :
float version, const std::string& dbVersionStr, const std::string& storageEngine,
std::string const& uuid) :
_address(address),
_databases(databases),
_version(version),
_dbVersionStr(dbVersionStr),
_storageEngineType(storageEngine),
_uuid(uuid)
{}
+6 -6
View File
@@ -4,15 +4,14 @@
namespace Robomongo
{
struct EnsureIndexInfo
struct IndexInfo
{
EnsureIndexInfo(
IndexInfo(
const MongoCollectionInfo &collection,
const std::string &name = std::string(),
const std::string &request = std::string(),
bool isUnique = false,
bool isBackGround = false,
bool isDropDuplicates = false,
bool isSparce = false,
int expireAfter = -1,
const std::string &defaultLanguage = std::string(),
@@ -21,10 +20,9 @@ namespace Robomongo
MongoCollectionInfo _collection;
std::string _name;
std::string _request;
std::string _keys;
bool _unique;
bool _backGround;
bool _dropDups;
bool _sparse;
int _ttl;
std::string _defaultLanguage;
@@ -36,10 +34,12 @@ namespace Robomongo
{
ConnectionInfo(std::string const& uuid);
ConnectionInfo(const std::string &address, const std::vector<std::string> &databases, float version,
const std::string& storageEngine, std::string const& uuid);
const std::string& dbVersionStr, const std::string& storageEngine,
std::string const& uuid);
const std::string _address;
const std::vector<std::string> _databases;
const float _version;
const std::string _dbVersionStr;
const std::string _storageEngineType;
std::string const _uuid;
};
+181 -185
View File
@@ -8,28 +8,28 @@
namespace
{
Robomongo::EnsureIndexInfo makeEnsureIndexInfoFromBsonObj(
Robomongo::IndexInfo makeIndexInfoFromBsonObj(
const Robomongo::MongoCollectionInfo &collection,
const mongo::BSONObj &obj)
{
using namespace Robomongo::BsonUtils;
Robomongo::EnsureIndexInfo info(collection);
info._name = getField<mongo::String>(obj, "name");
mongo::BSONObj keyObj = getField<mongo::Object>(obj, "key");
if (keyObj.isValid()) {
info._request = jsonString(keyObj, mongo::TenGen, 1, Robomongo::DefaultEncoding, Robomongo::Utc);
}
info._unique = getField<mongo::Bool>(obj, "unique");
info._backGround = getField<mongo::Bool>(obj, "background");
info._dropDups = getField<mongo::Bool>(obj, "dropDups");
info._sparse = getField<mongo::Bool>(obj, "sparse");
Robomongo::IndexInfo info(collection);
info._name = obj.getStringField("name");
mongo::BSONObj keyObj = obj.getObjectField("key");
if (keyObj.isValid())
info._keys = jsonString(keyObj, mongo::TenGen, 1, Robomongo::DefaultEncoding, Robomongo::Utc);
info._unique = obj.getBoolField("unique");
info._backGround = obj.getBoolField("background");
info._sparse = obj.getBoolField("sparse");
info._ttl = obj.getIntField("expireAfterSeconds");
info._defaultLanguage = getField<mongo::String>(obj, "default_language");
info._languageOverride = getField<mongo::String>(obj, "language_override");
mongo::BSONObj weightsObj = getField<mongo::Object>(obj, "weights");
if (weightsObj.isValid()) {
info._textWeights = jsonString(weightsObj, mongo::TenGen, 1, Robomongo::DefaultEncoding, Robomongo::Utc);
}
info._defaultLanguage = obj.getStringField("default_language");
info._languageOverride = obj.getStringField("language_override");
mongo::BSONObj weightsObj = obj.getObjectField("weights");
if (weightsObj.isValid())
info._textWeights = jsonString(weightsObj, mongo::TenGen, 1, Robomongo::DefaultEncoding,
Robomongo::Utc);
return info;
}
}
@@ -39,20 +39,21 @@ namespace Robomongo
MongoClient::MongoClient(mongo::DBClientBase *const dbclient) :
_dbclient(dbclient) { }
std::vector<std::string> MongoClient::getCollectionNames(const std::string &dbname) const
std::vector<std::string> MongoClient::getCollectionNamesWithDbname(const std::string &dbname) const
{
typedef std::list<std::string> cont_string_t;
cont_string_t dbs = _dbclient->getCollectionNames(dbname);
std::list<mongo::BSONObj> collList = _dbclient->getCollectionInfos(dbname);
std::vector<std::string> stringList;
for (cont_string_t::const_iterator i = dbs.begin(); i != dbs.end(); i++) {
stringList.push_back(*i);
}
std::sort(stringList.begin(), stringList.end());
return stringList;
std::vector<std::string> collNames;
for (auto const& coll : collList)
collNames.push_back(dbname + '.' + coll.getStringField("name")); // todo: verify
std::sort(collNames.begin(), collNames.end());
return collNames;
}
// Warning:
// Use string version dbVersionStr(), version number is corrupted after conversion to float
// Todo: Remove this function
float MongoClient::getVersion() const
{
float result = 0.0f;
@@ -63,6 +64,14 @@ namespace Robomongo
return result;
}
std::string MongoClient::dbVersionStr() const
{
mongo::BSONObj resultObj;
_dbclient->runCommand("db", BSON("buildInfo" << "1"), resultObj);
std::string const resultStr = BsonUtils::getField<mongo::String>(resultObj, "version");
return resultStr;
}
std::string MongoClient::getStorageEngineType() const
{
mongo::BSONObj resultObj;
@@ -72,93 +81,89 @@ namespace Robomongo
std::vector<std::string> MongoClient::getDatabaseNames() const
{
typedef std::list<std::string> cont_string_t;
cont_string_t dbs = _dbclient->getDatabaseNames();
std::vector<std::string> dbNames;
for (cont_string_t::const_iterator i = dbs.begin(); i != dbs.end(); ++i) {
dbNames.push_back(*i);
}
std::list<std::string> const& dbs = _dbclient->getDatabaseNames();
std::vector<std::string> dbNames = {dbs.begin(), dbs.end()};
std::sort(dbNames.begin(), dbNames.end());
return dbNames;
}
std::vector<MongoUser> MongoClient::getUsers(const std::string &dbName)
{
MongoNamespace ns(dbName, "system.users");
std::vector<MongoUser> users;
mongo::BSONObjBuilder cmd;
cmd.append("usersInfo", 1);
std::unique_ptr<mongo::DBClientCursor> cursor(_dbclient->query(ns.toString(), mongo::Query()));
mongo::BSONObj result;
if (!_dbclient->runCommand(dbName, cmd.done(), result)) {
std::string errStr = result.getStringField("errmsg");
if (errStr.empty())
errStr = "Failed to get error message.";
// Cursor may be NULL, it means we have connectivity problem
if (!cursor)
throw mongo::DBException("Network error while attempting to load list of users", 0);
float ver = getVersion();
while (cursor->more()) {
mongo::BSONObj bsonObj = cursor->next();
MongoUser user(ver, bsonObj);
users.push_back(user);
throw std::runtime_error(errStr);
}
std::vector<MongoUser> users;
for (auto const& usr : result.getField("users").Array())
users.push_back(MongoUser(getVersion(), usr.embeddedObject()));
return users;
}
void MongoClient::createUser(const std::string &dbName, const MongoUser &user, bool overwrite)
void MongoClient::createUser(const std::string &dbName, const MongoUser &user)
{
MongoNamespace ns(dbName, "system.users");
mongo::BSONObj obj = user.toBson();
if (!overwrite) { // create new user
_dbclient->insert(ns.toString(), obj);
}
else { // update existing user
mongo::BSONElement id = obj.getField("_id");
mongo::BSONObjBuilder builder;
builder.append(id);
mongo::BSONObj bsonQuery = builder.obj();
mongo::Query query(bsonQuery);
_dbclient->update(ns.toString(), query, obj, true, false);
mongo::BSONObjBuilder cmd;
cmd.append("createUser", user.name());
cmd.append("pwd", user.password());
mongo::BSONArrayBuilder roles;
auto const& rolesStrs = user.roles();
for (auto const& roleStr : rolesStrs) {
mongo::BSONObjBuilder role;
role.append("role", roleStr).append("db", user.userSource());
roles.append(role.done());
}
cmd.appendArray("roles", roles.done());
std::string errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw mongo::DBException(errorStr, 0);
mongo::BSONObj result;
if (!_dbclient->runCommand(dbName, cmd.done(), result)) {
std::string errStr = result.getStringField("errmsg");
if (errStr.empty())
errStr = "Failed to get error message.";
throw std::runtime_error(errStr);
}
}
void MongoClient::dropUser(const std::string &dbName, const mongo::OID &id)
void MongoClient::dropUser(const std::string &dbName, const std::string &user)
{
MongoNamespace ns(dbName, "system.users");
mongo::BSONObjBuilder cmd;
cmd.append("dropUser", user);
mongo::BSONObjBuilder builder;
builder.append("_id", id);
mongo::BSONObj bsonQuery = builder.obj();
mongo::Query query(bsonQuery);
mongo::BSONObj result;
if (!_dbclient->runCommand(dbName, cmd.done(), result)) {
std::string errStr = result.getStringField("errmsg");
if (errStr.empty())
errStr = "Failed to get error message.";
_dbclient->remove(ns.toString(), query, true);
std::string errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw mongo::DBException(errorStr, 0);
throw std::runtime_error(errStr);
}
}
std::vector<MongoFunction> MongoClient::getFunctions(const std::string &dbName)
std::vector<MongoFunction> MongoClient::getFunctions(const std::string &dbName) const
{
MongoNamespace ns(dbName, "system.js");
std::vector<MongoFunction> functions;
std::unique_ptr<mongo::DBClientCursor> cursor(_dbclient->query(ns.toString(), mongo::Query().sort("_id")));
std::unique_ptr<mongo::DBClientCursor> cursor(
_dbclient->query(mongo::NamespaceString(dbName, "system.js"), mongo::Query().sort("_id")));
// Cursor may be NULL, it means we have connectivity problem
if (!cursor)
throw mongo::DBException("Network error while attempting to load list of functions.", 0);
throw std::runtime_error("Network error while attempting to load list of functions.");
while (cursor->more()) {
mongo::BSONObj bsonObj = cursor->next();
try {
MongoFunction user(bsonObj);
functions.push_back(user);
MongoFunction func(bsonObj);
functions.push_back(func);
} catch (const std::exception &) {
// skip invalid docs
}
@@ -166,89 +171,77 @@ namespace Robomongo
return functions;
}
std::vector<EnsureIndexInfo> MongoClient::getIndexes(const MongoCollectionInfo &collection) const
std::vector<IndexInfo> MongoClient::getIndexes(const MongoCollectionInfo &collection) const
{
std::vector<EnsureIndexInfo> result;
std::vector<IndexInfo> result;
std::list<mongo::BSONObj> indexes = _dbclient->getIndexSpecs(collection.ns().toString());
// std::unique_ptr<mongo::DBClientCursor> cursor(_dbclient->getIndexSpecs(collection.ns().toString()));
for (std::list<mongo::BSONObj>::iterator it = indexes.begin(); it != indexes.end(); ++it) {
mongo::BSONObj bsonObj = *it;
result.push_back(makeEnsureIndexInfoFromBsonObj(collection, bsonObj));
result.push_back(makeIndexInfoFromBsonObj(collection, bsonObj));
}
return result;
}
void MongoClient::ensureIndex(const EnsureIndexInfo &oldInfo, const EnsureIndexInfo &newInfo) const
void MongoClient::addEditIndex(const IndexInfo &oldInfo, const IndexInfo &newInfo) const
{
std::string ns = newInfo._collection.ns().toString();
bool const editIndex = !oldInfo._name.empty();
// v0.9
// mongo::BSONObj keys = mongo::Robomongo::fromjson(newInfo._request);
mongo::BSONObj keys = mongo::Robomongo::fromjson(newInfo._request);
mongo::BSONObjBuilder toSave;
bool cache = true;
int version = -1;
toSave.append( "ns" , ns );
toSave.append( "key" , keys );
std::string cacheKey(ns);
cacheKey += "--";
if ( newInfo._name != "" ) {
toSave.append( "name" , newInfo._name );
cacheKey += newInfo._name;
}
else {
std::string nn = _dbclient->genIndexName(keys);
toSave.append( "name" , nn );
cacheKey += nn;
}
if (version >= 0)
toSave.append("v", version);
if (oldInfo._unique != newInfo._unique)
toSave.appendBool("unique", newInfo._unique);
if (oldInfo._backGround != newInfo._backGround)
toSave.appendBool("background", newInfo._backGround);
if (oldInfo._dropDups != newInfo._dropDups)
toSave.appendBool("dropDups", newInfo._dropDups);
if (oldInfo._sparse != newInfo._sparse)
toSave.appendBool("sparse", newInfo._sparse);
if (oldInfo._defaultLanguage != newInfo._defaultLanguage)
toSave.append("default_language", newInfo._defaultLanguage);
if (oldInfo._languageOverride != newInfo._languageOverride)
toSave.append("language_override", newInfo._languageOverride);
if (oldInfo._textWeights != newInfo._textWeights)
toSave.append("weights", newInfo._textWeights);
/* if ( _seenIndexes.count( cacheKey ) )
return 0;
if ( cache )
_seenIndexes.insert( cacheKey );*/
if (oldInfo._ttl != newInfo._ttl)
toSave.append("expireAfterSeconds", newInfo._ttl);
MongoNamespace namesp(newInfo._collection.ns().databaseName(), "system.indexes");
mongo::BSONObj obj = toSave.obj();
if (!oldInfo._name.empty())
// 1.Step: Drop Index (if this is an Edit Index action).
// MongoDB docs: To modify an existing index, you need to drop and recreate the index.
std::string const ns = newInfo._collection.ns().toString();
if (editIndex)
_dbclient->dropIndex(ns, oldInfo._name);
_dbclient->insert(namesp.toString().c_str(), obj);
// 2.Step: Add/Edit Index
auto const createIndexSpec = [](IndexInfo const& indexInfo) {
mongo::IndexSpec indexSpec;
indexSpec.name(indexInfo._name);
indexSpec.addKeys(mongo::Robomongo::fromjson(indexInfo._keys));
mongo::BSONObjBuilder optionsBuilder;
auto const addIfTrue = [&](auto const& keyValuePair) {
if (keyValuePair.second)
optionsBuilder.appendBool(keyValuePair.first, true);
};
addIfTrue(std::pair{ "unique", indexInfo._unique });
addIfTrue(std::pair{ "background", indexInfo._backGround });
addIfTrue(std::pair{ "sparse", indexInfo._sparse });
if (!indexInfo._defaultLanguage.empty())
optionsBuilder.append("default_language", indexInfo._defaultLanguage);
if (!indexInfo._languageOverride.empty())
optionsBuilder.append("language_override", indexInfo._languageOverride);
if (!mongo::Robomongo::fromjson(indexInfo._textWeights).isEmpty())
optionsBuilder.append("weights", mongo::Robomongo::fromjson(indexInfo._textWeights));
if (indexInfo._ttl > 0)
optionsBuilder.append("expireAfterSeconds", indexInfo._ttl);
indexSpec.addOptions(optionsBuilder.obj());
return indexSpec;
};
try {
_dbclient->createIndex(ns, createIndexSpec(newInfo));
}
catch (std::exception const& /*ex*/) { // Logging of "ex" is done in upper scope
if (editIndex) {
// If we are here, index that is being edited, must have already been dropped and
// creation of new index failed. So, we try to at least recover the dropped (old) index
_dbclient->createIndex(ns, createIndexSpec(oldInfo));
}
throw;
}
std::string const errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw std::runtime_error(errorStr);
}
void MongoClient::renameIndexFromCollection(const MongoCollectionInfo &collection, const std::string &oldIndexName, const std::string &newIndexName) const
@@ -312,7 +305,7 @@ namespace Robomongo
_dbclient->insert(ns.toString(), obj);
std::string errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw mongo::DBException(errorStr, 0);
throw std::runtime_error(errorStr/* , 0 */);
} else { // this is update
std::string name = fun.name();
@@ -326,7 +319,7 @@ namespace Robomongo
_dbclient->update(ns.toString(), query, obj, true, false);
std::string errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw mongo::DBException(errorStr, 0);
throw std::runtime_error(errorStr);
} else { // update function name (remove & insert)
_dbclient->insert(ns.toString(), obj);
std::string errorStr = _dbclient->getLastError();
@@ -340,7 +333,7 @@ namespace Robomongo
_dbclient->remove(ns.toString(), query, true);
}
else {
throw mongo::DBException(errorStr, 0);
throw std::runtime_error(errorStr);
}
}
}
@@ -358,7 +351,7 @@ namespace Robomongo
_dbclient->remove(ns.toString(), query, true);
std::string errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw mongo::DBException(errorStr, 0);
throw std::runtime_error(errorStr);
}
void MongoClient::createDatabase(const std::string &dbName)
@@ -368,12 +361,11 @@ namespace Robomongo
* This will create <dbName> database for us.
* Finally we are dropping just created temporary collection.
*/
MongoNamespace ns(dbName, "temp");
// If <dbName>.temp already exists, stop.
if (_dbclient->exists(ns.toString()))
throw mongo::DBException(dbName + ".temp already exists.", 0);
throw std::runtime_error(dbName + ".temp already exists.");
// Building { _id : "temp" } document
mongo::BSONObjBuilder builder;
@@ -384,7 +376,7 @@ namespace Robomongo
_dbclient->insert(ns.toString(), obj);
std::string errorStr = _dbclient->getLastError();
if (!errorStr.empty())
throw mongo::DBException(errorStr, 0);
throw std::runtime_error(errorStr);
// Drop temp collection
_dbclient->dropCollection(ns.toString());
@@ -392,13 +384,13 @@ namespace Robomongo
void MongoClient::dropDatabase(const std::string &dbName)
{
mongo::BSONObj result;
if (!_dbclient->dropDatabase(dbName, &result)) {
std::string errStr = result.getStringField("errmsg");
mongo::BSONObj info;
if (!_dbclient->dropDatabase(dbName, mongo::WriteConcernOptions(), &info)) { // todo: do we catch errorStr via info - test it??
std::string errStr = info.toString();
if (errStr.empty())
errStr = "Failed to get error message.";
throw mongo::DBException(errStr, 0);
throw std::runtime_error(errStr);
}
}
@@ -430,11 +422,11 @@ namespace Robomongo
if (errStr.empty())
errStr = "Failed to get error message.";
throw mongo::DBException(errStr, 0);
throw std::runtime_error(errStr);
}
}
else {
throw mongo::DBException("Collection with same name already exists.", 0);
throw std::runtime_error("Collection with same name already exists.");
}
}
@@ -454,14 +446,13 @@ namespace Robomongo
if (errStr.empty())
errStr = "Failed to get error message.";
throw mongo::DBException(errStr, 0);
throw std::runtime_error(errStr);
}
}
void MongoClient::duplicateCollection(const MongoNamespace &ns, const std::string &newCollectionName)
{
MongoNamespace sourceCollection(ns);
MongoNamespace newCollection(ns.databaseName(), newCollectionName);
MongoNamespace const newCollection(ns.databaseName(), newCollectionName);
if (!_dbclient->exists(newCollection.toString())) {
mongo::BSONObj result;
@@ -473,18 +464,20 @@ namespace Robomongo
if (errStr.empty())
errStr = "Failed to get error message.";
throw mongo::DBException(errStr, 0);
throw std::runtime_error(errStr);
}
}
else {
throw mongo::DBException("Collection with same name already exists.", 0);
throw std::runtime_error("Collection with same name already exists.");
}
std::unique_ptr<mongo::DBClientCursor> cursor(_dbclient->query(sourceCollection.toString(), mongo::Query()));
std::unique_ptr<mongo::DBClientCursor> cursor {
_dbclient->query(mongo::NamespaceString(ns.databaseName(), ns.collectionName()), mongo::Query())
};
// Cursor may be NULL, it means we have connectivity problem
if (!cursor)
throw mongo::DBException("Network error while attempting to run query", 0);
throw std::runtime_error("Network error while attempting to run query");
while (cursor->more()) {
mongo::BSONObj bsonObj = cursor->next();
@@ -498,11 +491,14 @@ namespace Robomongo
if (!_dbclient->exists(to.toString()))
_dbclient->createCollection(to.toString());
std::unique_ptr<mongo::DBClientCursor> cursor(fromServ->query(from.toString(), mongo::Query()));
std::unique_ptr<mongo::DBClientCursor> cursor{fromServ->query(
mongo::NamespaceString(from.databaseName(), from.collectionName()),
mongo::Query())
};
// Cursor may be NULL, it means we have connectivity problem
if (!cursor)
throw mongo::DBException("Network error while attempting to run query", 0);
throw std::runtime_error("Network error while attempting to run query");
while (cursor->more()) {
mongo::BSONObj bsonObj = cursor->next();
@@ -513,17 +509,17 @@ namespace Robomongo
void MongoClient::dropCollection(const MongoNamespace &ns)
{
if (_dbclient->exists(ns.toString())) {
mongo::BSONObj result;
if (!_dbclient->dropCollection(ns.toString(), &result)) {
std::string errStr = result.getStringField("errmsg");
mongo::BSONObj info;
if (!_dbclient->dropCollection(ns.toString(), mongo::WriteConcernOptions(), &info)) {
std::string errStr = info.toString();
if (errStr.empty())
errStr = "Failed to get error message.";
throw mongo::DBException(errStr, 0);
throw std::runtime_error(errStr);
}
}
else {
throw mongo::DBException("Collection does not exist.", 0);
throw std::runtime_error("Collection does not exist.");
}
}
@@ -547,7 +543,7 @@ namespace Robomongo
void MongoClient::removeDocuments(const MongoNamespace &ns, mongo::Query query, bool justOne /*= true*/)
{
_dbclient->remove(ns.toString(), query, justOne);
_dbclient->remove(ns.toString(), query, justOne);
checkLastErrorAndThrow(ns.databaseName());
}
@@ -563,12 +559,14 @@ namespace Robomongo
return docs;
std::unique_ptr<mongo::DBClientCursor> cursor = _dbclient->query(
ns.toString(), info._query, info._limit, info._skip,
info._fields.nFields() ? &info._fields : 0, info._options, info._batchSize);
mongo::NamespaceString(ns.databaseName(), ns.collectionName()),
info._query, info._limit, info._skip, info._fields.nFields() ? &info._fields : 0,
info._options, info._batchSize
);
// DBClientBase::query may return nullptr
if (!cursor)
throw mongo::DBException("Network error while attempting to run query", 0);
throw std::runtime_error("Network error while attempting to run query");
while (cursor->more()) {
mongo::BSONObj bsonObj = cursor->next();
@@ -618,12 +616,10 @@ namespace Robomongo
void MongoClient::checkLastErrorAndThrow(const std::string &db)
{
std::string lastError = _dbclient->getLastError(db);
// Nothing to do when there is no error
std::string const lastError = _dbclient->getLastError(db);
if (lastError.empty())
return;
throw mongo::DBException(lastError, mongo::ErrorCodes::InternalError);
throw std::runtime_error(lastError/*, mongo::ErrorCodes::InternalError*/);
}
}
+8 -7
View File
@@ -1,6 +1,6 @@
#pragma once
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
#include <mongo/bson/bsonobj.h>
#include "robomongo/core/Core.h"
@@ -16,19 +16,20 @@ namespace Robomongo
public:
MongoClient(mongo::DBClientBase *const scopedConnection);
std::vector<std::string> getCollectionNames(const std::string &dbname) const;
std::vector<std::string> getCollectionNamesWithDbname(const std::string &dbname) const;
std::vector<std::string> getDatabaseNames() const;
float getVersion() const;
std::string dbVersionStr() const;
std::string getStorageEngineType() const;
std::vector<MongoUser> getUsers(const std::string &dbName);
void createUser(const std::string &dbName, const MongoUser &user, bool overwrite);
void dropUser(const std::string &dbName, const mongo::OID &id);
void createUser(const std::string &dbName, const MongoUser &user);
void dropUser(const std::string &dbName, const std::string &user);
std::vector<MongoFunction> getFunctions(const std::string &dbName);
std::vector<EnsureIndexInfo> getIndexes(const MongoCollectionInfo &collection) const;
std::vector<MongoFunction> getFunctions(const std::string &dbName) const;
std::vector<IndexInfo> getIndexes(const MongoCollectionInfo &collection) const;
void dropIndexFromCollection(const MongoCollectionInfo &collection, const std::string &indexName) const;
void ensureIndex(const EnsureIndexInfo &oldInfo, const EnsureIndexInfo &newInfo) const;
void addEditIndex(const IndexInfo &oldInfo, const IndexInfo &newInfo) const;
void renameIndexFromCollection(const MongoCollectionInfo &collection, const std::string &oldIndexName,
const std::string &newIndexName) const;
File diff suppressed because it is too large Load Diff
+19 -32
View File
@@ -23,20 +23,15 @@ namespace Robomongo
{
Q_OBJECT
public:
enum { pingTimeMs = 60 * 1000 };
typedef std::vector<std::string> DatabasesContainerType;
using DBClientReplicaSet = std::unique_ptr<mongo::DBClientReplicaSet>;
using DBClientConnection = std::unique_ptr<mongo::DBClientConnection>;
public:
explicit MongoWorker(ConnectionSettings *connection, bool isLoadMongoRcJs, int batchSize,
int mongoTimeoutSec, int shellTimeoutSec, QObject *parent = NULL);
double mongoTimeoutSec, int shellTimeoutSec, QObject *parent = nullptr);
~MongoWorker();
void interrupt();
void stopAndDelete();
void changeTimeout(int newTimeout);
protected Q_SLOTS:
void init();
@@ -79,20 +74,15 @@ namespace Robomongo
void handle(LoadCollectionIndexesRequest *event);
/**
* @brief Load indexes in collection
* @brief Add/edit indexes in collection
*/
void handle(EnsureIndexRequest *event);
void handle(AddEditIndexRequest *event);
/**
* @brief delete index from collection
*/
void handle(DropCollectionIndexRequest *event);
/**
* @brief Edit index
*/
void handle(EditIndexRequest *event);
/**
* @brief Load list of all JS functions
*/
@@ -117,6 +107,7 @@ namespace Robomongo
* @brief Execute javascript
*/
void handle(ExecuteScriptRequest *event);
void retry(ExecuteScriptRequest *event);
void handle(StopScriptRequest *event);
void handle(AutocompleteRequest *event);
@@ -126,9 +117,9 @@ namespace Robomongo
void handle(CreateCollectionRequest *event);
void handle(DropCollectionRequest *event);
void handle(RenameCollectionRequest *event);
void handle(DuplicateCollectionRequest *event);
void handle(CopyCollectionToDiffServerRequest *event);
void handle(DuplicateCollectionRequest *event);
void handle(CopyCollectionToDiffServerRequest *event); // todo: unused? remove
void handle(CreateUserRequest *event);
void handle(DropUserRequest *event);
@@ -139,15 +130,19 @@ namespace Robomongo
virtual void timerEvent(QTimerEvent *);
private:
// Added after Mongo 4.0 to fix connection failures seen after a first edit/add/remove doc. operation
void restartReplicaSetConnection();
/**
* @brief Send event to this MongoWorker
*/
void send(Event *event);
DatabasesContainerType getDatabaseNamesSafe();
std::vector<std::string> getDatabaseNamesSafe(EstablishConnectionRequest* event = nullptr);
std::string getAuthBase() const;
mongo::DBClientBase *getConnection(bool mayReturnNull = false);
// Returns a pair of DBClientBase* connection and error string
std::pair<mongo::DBClientBase*, std::string> getConnection(bool mayReturnNull = false);
MongoClient *getClient();
/**
@@ -168,15 +163,8 @@ namespace Robomongo
/**
*@brief Update Replica Set related parameters/settings.
* Warning: Using parameter 'refresh' as false might return incorrect cached values for status
* of secondary members.
* @param refresh : If true it will be deep scan of replica set status which
* might take quite some time. If false, it will be quick scan
* which might return incorrect cached values for status of secondary members.
* Use false only to achieve quick first connection, in all other cases true
* should be used.
*/
ReplicaSet getReplicaSetInfo(bool refresh = true) const;
ReplicaSet getReplicaSetInfo() const;
std::string connectAndGetReplicaSetName() const;
@@ -195,12 +183,11 @@ namespace Robomongo
std::unique_ptr<ScriptEngine> _scriptEngine;
bool _isAdmin;
const bool _isLoadMongoRcJs;
const int _batchSize;
int _timerId;
int _dbAutocompleteCacheTimerId;
int _mongoTimeoutSec;
double _mongoTimeoutSec;
int _shellTimeoutSec;
QAtomicInteger<int> _isQuiting;
@@ -217,4 +204,4 @@ namespace Robomongo
std::unordered_set<std::string> _createdDbs;
};
}
}
+6 -2
View File
@@ -1,6 +1,7 @@
#pragma once
#include <mongo/util/net/hostandport.h>
#include <vector>
namespace Robomongo
{
@@ -15,8 +16,11 @@ namespace Robomongo
ReplicaSet() {};
std::string const setName;
mongo::HostAndPort const primary;
std::vector<std::pair<std::string, bool>> const membersAndHealths; // pair: {HostNameAndPort, Health}
mongo::HostAndPort const primary;
std::string const errorStr;
// pair: {HostNameAndPort, Health}
std::vector<std::pair<std::string, bool>> const membersAndHealths;
// todo: make first element of pair type HostnameAndPort
};
}
@@ -49,6 +49,8 @@ namespace Robomongo
_replicaSetSettings(new ReplicaSetSettings(uri)),
_clone(isClone)
{
// Disabling unfinished feature : Export / Import to / from MongoURI
/*
if (!uri.getServers().empty()) {
_host = uri.getServers().front().host();
_port = uri.getServers().front().port();
@@ -69,6 +71,7 @@ namespace Robomongo
credential->setEnabled(true);
}
addCredential(credential);
*/
}
void ConnectionSettings::fromVariant(const QVariantMap &map) {
@@ -166,9 +169,8 @@ namespace Robomongo
map.insert("serverPort", serverPort());
map.insert("defaultDatabase", QtUtils::toQString(defaultDatabase()));
map.insert("isReplicaSet", isReplicaSet());
if (isReplicaSet()) {
if (isReplicaSet())
map.insert("replicaSet", _replicaSetSettings->toVariant());
}
#ifdef MONGO_SSL
SSLInfo infl = _info.sslInfo();
@@ -176,12 +178,10 @@ namespace Robomongo
map.insert("sslPemKeyFile", QtUtils::toQString(infl._sslPEMKeyFile));
#endif
QVariantList list;
for (QList<CredentialSettings *>::const_iterator it = _credentials.begin(); it != _credentials.end(); ++it) {
CredentialSettings *credential = *it;
list.append(credential->toVariant());
}
for (auto const& cred : _credentials)
list.append(cred->toVariant());
map.insert("credentials", list);
map.insert("ssh", _sshSettings->toVariant());
map.insert("ssl", _sslSettings->toVariant());
map.insert("uuid", _uuid);
@@ -4,7 +4,7 @@
#include <QVariant>
#include <QVariantMap>
#include <mongo/client/dbclientinterface.h>
#include <mongo/client/dbclient_base.h>
#include <mongo/client/mongo_uri.h>
#include <mongo/util/net/hostandport.h>
@@ -1,6 +1,7 @@
#include "robomongo/core/settings/CredentialSettings.h"
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/utils/RoboCrypt.h"
namespace Robomongo
{
@@ -9,17 +10,25 @@ namespace Robomongo
_userPassword(),
_databaseName(),
_mechanism(),
_enabled(false)
_enabled(false),
_useManuallyVisibleDbs(false),
_manuallyVisibleDbs()
{
}
CredentialSettings::CredentialSettings(const QVariantMap &map) :
_userName(QtUtils::toStdString(map.value("userName").toString())),
_userPassword(QtUtils::toStdString(map.value("userPassword").toString())),
_databaseName(QtUtils::toStdString(map.value("databaseName").toString())),
_mechanism(QtUtils::toStdString(map.value("mechanism").toString())),
_useManuallyVisibleDbs(map.value("useManuallyVisibleDbs").toBool()),
_manuallyVisibleDbs(QtUtils::toStdString(map.value("manuallyVisibleDbs").toString())),
_enabled(map.value("enabled").toBool())
{
// From version Robo 1.3 "userPasswordEncrypted" is used instead of "userPassword" in config. file
if(map.contains("userPassword")) // Robo 1.2 and below
_userPassword = map.value("userPassword").toString().toStdString();
else if(map.contains("userPasswordEncrypted")) // From Robo 1.3
_userPassword = RoboCrypt::decrypt(map.value("userPasswordEncrypted").toString().toStdString());
}
/**
@@ -35,10 +44,13 @@ namespace Robomongo
{
QVariantMap map;
map.insert("userName", QtUtils::toQString(userName()));
map.insert("userPassword", QtUtils::toQString(userPassword()));
map.insert("userPasswordEncrypted", userPassword().empty() ? "" :
QtUtils::toQString(RoboCrypt::encrypt(userPassword())));
map.insert("databaseName", QtUtils::toQString(databaseName()));
map.insert("mechanism", QtUtils::toQString(mechanism()));
map.insert("useManuallyVisibleDbs", _useManuallyVisibleDbs);
map.insert("manuallyVisibleDbs", QtUtils::toQString(_manuallyVisibleDbs));
map.insert("enabled", enabled());
return map;
}
}
}
@@ -41,7 +41,7 @@ namespace Robomongo
void setDatabaseName(const std::string &databaseName) { _databaseName = databaseName; }
/**
* @brief Authentication mechanism (SCRAM-SHA-1 or MONGODB-CR)
* @brief Authentication mechanism (SCRAM-SHA-1, SCRAM-SHA-256 or MONGODB-CR)
*/
std::string mechanism() const { return _mechanism.empty() ? "SCRAM-SHA-1" : _mechanism; }
void setMechanism(const std::string &mechanism) { _mechanism = mechanism; }
@@ -53,11 +53,19 @@ namespace Robomongo
bool enabled() const { return _enabled; }
void setEnabled(bool enabled) { _enabled = enabled; }
bool useManuallyVisibleDbs() const { return _useManuallyVisibleDbs; }
void setUseManuallyVisibleDbs(bool enabled) { _useManuallyVisibleDbs = enabled; }
std::string manuallyVisibleDbs() const { return _manuallyVisibleDbs; }
void setManuallyVisibleDbs(std::string const& dbs) { _manuallyVisibleDbs = dbs; }
private:
std::string _userName;
std::string _userPassword;
std::string _userPassword; // clear text password (decrypted)
std::string _databaseName;
std::string _mechanism; // authentication mechanism (MONGODB-CR or SCRAM-SHA-1)
std::string _mechanism; // authentication mechanism (SCRAM-SHA-1, SCRAM-SHA-256 or MONGODB-CR)
bool _useManuallyVisibleDbs;
std::string _manuallyVisibleDbs;
/**
* @brief Flag, indecating whether we should use this
+163 -75
View File
@@ -6,19 +6,7 @@
#include <QUuid>
#include <QJsonArray>
#include <QXmlStreamReader>
// Todo:
// Warning:
// Currently, this include statement should be maintained manually.
// The Qt version must be updated if Qt is upgraded. Otherwise it might cause build error.
// The correct path will be: PROJECT_QT_VERSION/QtGui/private/qzipreader_p.h
// Details:
// Ideally, private class inside qzipreader_p.h should not be used since it is not
// a publicly/officially supported API by Qt. It is used here since we are doing a
// a very lightweight zip operation which is unzipping a zip archive with one, small file.
// The alternative is including QuaZip and Zlib third party libraries into CMAKE project and
// building, and using them which might be time consuming.
#include <5.7.0/QtGui/private/qzipreader_p.h>
#include <QDirIterator>
#include <parser.h>
#include <serializer.h>
@@ -32,14 +20,24 @@
#include "robomongo/core/utils/StdUtils.h"
#include "robomongo/gui/AppStyle.h"
#include "robomongo/utils/common.h"
#include "robomongo/utils/qzip/qzipreader_p.h"
#include "robomongo/utils/RoboCrypt.h"
namespace Robomongo
{
// 3T config files
auto const Studio3T_PropertiesDat = QString("%1/.3T/studio-3t/properties.dat").arg(QDir::homePath());
auto const DataMongodb_PropertiesDat = QString("%1/.3T/data-man-mongodb/properties.dat").arg(QDir::homePath());
auto const MongoChefPro_PropertiesDat = QString("%1/.3T/mongochef-pro/properties.dat").arg(QDir::homePath());
auto const MongoChefEnt_PropertiesDat = QString("%1/.3T/mongochef-enterprise/properties.dat").arg(QDir::homePath());
auto const Studio3T_PropertiesDat {
QString("%1/.3T/studio-3t/properties.dat").arg(QDir::homePath())
};
auto const DataMongodb_PropertiesDat {
QString("%1/.3T/data-man-mongodb/properties.dat").arg(QDir::homePath())
};
auto const MongoChefPro_PropertiesDat {
QString("%1/.3T/mongochef-pro/properties.dat").arg(QDir::homePath())
};
auto const MongoChefEnt_PropertiesDat {
QString("%1/.3T/mongochef-enterprise/properties.dat").arg(QDir::homePath())
};
const std::vector<std::pair<QString, QString>> S_3T_ZipFile_And_ConfigFile_List
{
@@ -50,46 +48,49 @@ namespace Robomongo
};
// Extract zipFile and find the value of "anonymousID" field in propFile
QString extractAnonymousID(QString const& zipFile, QString const& propfile);
QString extractAnonymousIDFromZip(QString const& zipFile, QString const& propfile);
// Extract "anonymousID" from a config file
QString extractAnonymousID(QString const& configFile);
/**
* @brief Version of schema
*/
const QString SchemaVersion = "2.0";
}
namespace Robomongo
{
/**
* @brief Robomongo config. files
*/
const auto CONFIG_FILE_0_8_5 = QString("%1/.config/robomongo/robomongo.json").arg(QDir::homePath());
const auto CONFIG_FILE_0_9 = QString("%1/.config/robomongo/0.9/robomongo.json").arg(QDir::homePath());
const auto CONFIG_FILE_1_0_RC1 = QString("%1/.config/robomongo/1.0/robomongo.json").arg(QDir::homePath());
// Change of path due to re-branding to 3T
const auto CONFIG_FILE_1_0_0 = QString("%1/.3T/robomongo/1.0.0/robomongo.json").arg(QDir::homePath());
struct ConfigFileAndImportFunction
{
ConfigFileAndImportFunction(QString const& configFile, std::function<bool()> importFunction)
: file(configFile), import(importFunction) {}
QString file;
std::function<bool()> import;
const auto CONFIG_FILE_0_8_5 {
QString("%1/.config/robomongo/robomongo.json").arg(QDir::homePath())
};
const auto CONFIG_FILE_1_0_RC1 {
QString("%1/.config/robomongo/1.0/robomongo.json").arg(QDir::homePath())
};
const auto CONFIG_FILE_1_1_0_BETA {
QString("%1/.3T/robomongo/1.1.0-Beta/robomongo.json").arg(QDir::homePath())
};
// Warning: Config. file and import function of a new release must be placed as first element of
// vector initializer list below in order.
std::vector<ConfigFileAndImportFunction> const SettingsManager::_configFilesAndImportFunctions
/**
* @brief Robomongo config. files of old versions
*/
// Important: In order to import connections from a version, config. file path must
// be defined and placed into the vector initializer list below in order.
std::vector<QString> const SettingsManager::_configFilesOfOldVersions
{
ConfigFileAndImportFunction(CONFIG_FILE_1_0_RC1, SettingsManager::importConnectionsFrom_1_0_RC1_to_1_0_0),
ConfigFileAndImportFunction(CONFIG_FILE_0_9, SettingsManager::importConnectionsFrom_0_9_to_1_0_RC1),
ConfigFileAndImportFunction(CONFIG_FILE_0_8_5, SettingsManager::importConnectionsFrom_0_8_5_to_0_9)
QString("%1/.3T/robo-3t/1.4.1/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_4_1
QString("%1/.3T/robo-3t/1.4.0/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_4_0
QString("%1/.3T/robo-3t/1.3.1/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_3_1
QString("%1/.3T/robo-3t/1.3.0/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_3_0_BETA
QString("%1/.3T/robo-3t/1.2.1/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_2_1
QString("%1/.3T/robo-3t/1.2.0/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_2_0_BETA
QString("%1/.3T/robo-3t/1.1.1/robo3t.json").arg(QDir::homePath()), // CONFIG_FILE_1_1_1
CONFIG_FILE_1_1_0_BETA, // CONFIG_FILE_1_1_0_BETA
QString("%1/.3T/robomongo/1.0.0/robomongo.json").arg(QDir::homePath()), // CONFIG_FILE_1_0_0
CONFIG_FILE_1_0_RC1, // CONFIG_FILE_1_0_RC1
QString("%1/.config/robomongo/0.9/robomongo.json").arg(QDir::homePath()), // CONFIG_FILE_0_9
CONFIG_FILE_0_8_5 // CONFIG_FILE_0_8_5
};
std::vector<ConnectionSettings*> SettingsManager::_connections;
// Temporarily disabling Recent Connections feature
// std::vector<RecentConnection> SettingsManager::_recentConnections;
@@ -112,8 +113,12 @@ namespace Robomongo
_textFontPointSize(-1),
_mongoTimeoutSec(10),
_shellTimeoutSec(15),
_imported(false)
_imported(false)
{
if (!QDir().mkpath(ConfigDir))
LOG_MSG("ERROR: Could not create settings path: " + ConfigDir, mongo::logger::LogSeverity::Error());
RoboCrypt::initKey();
if (!load()) { // if load fails (probably due to non-existing config. file or directory)
save(); // create empty settings file
load(); // try loading again for the purpose of import from previous Robomongo versions
@@ -157,12 +162,7 @@ namespace Robomongo
*/
bool SettingsManager::save()
{
QVariantMap map = convertToMap();
if (!QDir().mkpath(ConfigDir)) {
LOG_MSG("ERROR: Could not create settings path: " + ConfigDir, mongo::logger::LogSeverity::Error());
return false;
}
QVariantMap const& map = convertToMap();
QFile f(ConfigFilePath);
if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
@@ -222,6 +222,13 @@ namespace Robomongo
_minimizeToTray = map.contains("minimizeToTray") ? map.value("minimizeToTray").toBool() : false;
_lineNumbers = map.contains("lineNumbers") ? map.value("lineNumbers").toBool() : false;
_imported = map.contains("imported") ? map.value("imported").toBool() : false;
_programExitedNormally = map.contains("programExitedNormally") ?
map.value("programExitedNormally").toBool() : true;
_disableHttpsFeatures = map.contains("disableHttpsFeatures") ?
map.value("disableHttpsFeatures").toBool() : false;
_debugMode = map.contains("debugMode") ? map.value("debugMode").toBool() : false;
// 4. Load TimeZone
int timeZone = map.value("timeZone").toInt();
@@ -235,6 +242,9 @@ namespace Robomongo
if (map.contains("acceptedEulaVersions"))
_acceptedEulaVersions = map.value("acceptedEulaVersions").toStringList().toSet();
if (map.contains("dbVersionsConnected"))
_dbVersionsConnected = map.value("dbVersionsConnected").toStringList().toSet();
// Load anonymousID
_anonymousID = getOrCreateAnonymousID(map);
@@ -358,6 +368,13 @@ namespace Robomongo
map.insert("acceptedEulaVersions", arr.toVariantList());
// x. Save unique set of db versions connected
QJsonArray dbVersionsArr;
for (auto const& version : _dbVersionsConnected)
dbVersionsArr.push_back(version);
map.insert("dbVersionsConnected", dbVersionsArr.toVariantList());
// 9. Save batchSize
map.insert("batchSize", _batchSize);
map.insert("checkForUpdates", _checkForUpdates);
@@ -396,7 +413,10 @@ namespace Robomongo
map.insert("imported", _imported);
map.insert("anonymousID", _anonymousID);
map.insert("cacheData", _cacheData);
map.insert("programExitedNormally", _programExitedNormally);
map.insert("disableHttpsFeatures", _disableHttpsFeatures);
map.insert("debugMode", _debugMode);
return map;
}
@@ -411,18 +431,62 @@ namespace Robomongo
anonymousID = id.toString();
}
// Search and import "anonymousID" from other Studio 3T config files
for (auto const& zipFileAndConfigFile : S_3T_ZipFile_And_ConfigFile_List) {
if (!anonymousID.isEmpty())
break;
QUuid const& id = extractAnonymousID(zipFileAndConfigFile.first, zipFileAndConfigFile.second);
QUuid const& id = extractAnonymousIDFromZip(zipFileAndConfigFile.first, zipFileAndConfigFile.second);
if (!id.isNull())
anonymousID = id.toString();
}
// Search and import "anonymousID" from other Robo 3T old config files starting from latest
for (auto const& oldConfigFile : _configFilesOfOldVersions) {
if (!anonymousID.isEmpty())
break;
// Don't import from 1.1-Beta due to a problem where Beta might have redundantly created new UUID
if (oldConfigFile == CONFIG_FILE_1_1_0_BETA)
continue;
// Stop searching in 1_0_RC1 or older versions, "anonymousID" is introduced in version 1.0
if (oldConfigFile == CONFIG_FILE_1_0_RC1)
break;
anonymousID = extractAnonymousID(oldConfigFile);
}
// Search and import "anonymousID" from any other (ideally newer version) Robo 3T config files
if (anonymousID.isEmpty()) {
auto const dir1 = QString("%1/.3T/robo-3t").arg(QDir::homePath());
QDirIterator iter1 { dir1, QStringList() << "robo*.json", QDir::Files,
QDirIterator::Subdirectories };
while (iter1.hasNext()) {
anonymousID = extractAnonymousID(iter1.next());
if (!anonymousID.isEmpty())
break;
}
if (anonymousID.isEmpty()) {
auto const dir2 = QString("%1/.3T/robomongo").arg(QDir::homePath());
QDirIterator iter2 { dir2, QStringList() << "robo*.json", QDir::Files,
QDirIterator::Subdirectories };
while (iter2.hasNext()) {
anonymousID = extractAnonymousID(iter2.next());
if (!anonymousID.isEmpty())
break;
}
}
}
// Couldn't find/import any, create a new anonymousID
if (anonymousID.isEmpty())
anonymousID = QUuid::createUuid().toString();
anonymousID.remove('{');
anonymousID.remove('}');
return anonymousID;
}
@@ -516,21 +580,21 @@ namespace Robomongo
void SettingsManager::importConnections()
{
// Skip when settings already imported
// Do not import if already imported
if (_imported)
return;
// Find and import 'only' from the latest version
for (auto const& configFileAndImportFunction : _configFilesAndImportFunctions) {
if (QFile::exists(configFileAndImportFunction.file)) {
configFileAndImportFunction.import();
// Find and import 'only' from the latest version to current version
for (auto const& configFile : _configFilesOfOldVersions) {
if (QFile::exists(configFile)) {
importConnectionsFromOldVersion(configFile);
setImported(true); // Mark as imported
return;
}
}
}
bool SettingsManager::importConnectionsFrom_0_8_5_to_0_9()
bool SettingsManager::importConnectionsFrom_0_8_5()
{
// Load old configuration file (used till version 0.8.5)
@@ -570,7 +634,7 @@ namespace Robomongo
ssh->setPrivateKeyFile(QtUtils::toStdString(vconn.value("sshPrivateKey").toString()));
ssh->setPassphrase(QtUtils::toStdString(vconn.value("sshPassphrase").toString()));
int auth = vconn.value("sshAuthMethod").toInt();
int const auth = vconn.value("sshAuthMethod").toInt();
ssh->setEnabled(auth == 1 || auth == 2);
ssh->setAuthMethod(auth == 2 ? "publickey" : "password");
}
@@ -588,10 +652,12 @@ namespace Robomongo
QVariantMap vcred = (*itcred).toMap();
auto cred = new CredentialSettings();
cred->setUserName(QtUtils::toStdString(vcred.value("userName").toString()));
cred->setUserPassword(QtUtils::toStdString(vcred.value("userPassword").toString()));
cred->setDatabaseName(QtUtils::toStdString(vcred.value("databaseName").toString()));
cred->setUserName(vcred.value("userName").toString().toStdString());
cred->setUserPassword(vcred.value("userPassword").toString().toStdString());
cred->setDatabaseName(vcred.value("databaseName").toString().toStdString());
cred->setMechanism("MONGODB-CR");
cred->setUseManuallyVisibleDbs(vcred.value("useManuallyVisibleDbs").toBool());
cred->setManuallyVisibleDbs(vcred.value("manuallyVisibleDbs").toString().toStdString());
cred->setEnabled(vcred.value("enabled").toBool());
conn->addCredential(cred);
@@ -637,18 +703,13 @@ namespace Robomongo
return true;
}
bool SettingsManager::importConnectionsFrom_0_9_to_1_0_RC1()
{
return importConnectionsFromOldVersion(CONFIG_FILE_0_9);
}
bool SettingsManager::importConnectionsFrom_1_0_RC1_to_1_0_0()
{
return importConnectionsFromOldVersion(CONFIG_FILE_1_0_RC1);
}
bool SettingsManager::importConnectionsFromOldVersion(QString const& oldConfigFilePath)
{
if (oldConfigFilePath == CONFIG_FILE_0_8_5) {
importConnectionsFrom_0_8_5();
return true;
}
if (!QFile::exists(oldConfigFilePath))
return false;
@@ -687,7 +748,7 @@ namespace Robomongo
return count;
}
QString extractAnonymousID(QString const& zipFile, QString const& propfile)
QString extractAnonymousIDFromZip(QString const& zipFile, QString const& propfile)
{
QZipReader zipReader(zipFile);
if (!zipReader.exists() || !zipReader.isReadable())
@@ -708,4 +769,31 @@ namespace Robomongo
return QString("");
}
QString extractAnonymousID(QString const& configFilePath)
{
if (!QFile::exists(configFilePath))
return QString("");
QFile oldConfigFile(configFilePath);
if (!oldConfigFile.open(QIODevice::ReadOnly))
return QString("");
bool ok = false;
QJson::Parser parser;
QVariantMap const& map = parser.parse(oldConfigFile.readAll(), &ok).toMap();
if (!ok)
return QString("");
QString anonymousID;
if (map.contains("anonymousID")) {
QUuid const& id = map.value("anonymousID").toString();
if (!id.isNull())
anonymousID = id.toString();
}
anonymousID.remove('{');
anonymousID.remove('}');
return anonymousID;
}
}
+30 -11
View File
@@ -4,7 +4,10 @@
#include <QVariantMap>
#include <QSet>
#include <QDir>
#include <vector>
#include <cstdlib>
#include "robomongo/core/Enums.h"
namespace Robomongo
@@ -13,14 +16,14 @@ namespace Robomongo
struct ConfigFileAndImportFunction;
// Current cache directory
QString const CacheDir = QString("%1/.3T/robomongo/%2/cache/").arg(QDir::homePath())
.arg(PROJECT_VERSION);
auto const CacheDir = QString("%1/.3T/robo-3t/%2/cache/").arg(QDir::homePath())
.arg(PROJECT_VERSION);
// Current config file
QString const ConfigFilePath = QString("%1/.3T/robomongo/%2/robomongo.json").arg(QDir::homePath())
.arg(PROJECT_VERSION);
auto const ConfigFilePath = QString("%1/.3T/robo-3t/%2/robo3t.json").arg(QDir::homePath())
.arg(PROJECT_VERSION);
// Current config file directory
QString const ConfigDir = QString("%1/.3T/robomongo/%2/").arg(QDir::homePath())
.arg(PROJECT_VERSION);
auto const ConfigDir = QString("%1/.3T/robo-3t/%2/").arg(QDir::homePath())
.arg(PROJECT_VERSION);
/* Temporarily disabling Recent Connections feature
struct RecentConnection
{
@@ -158,6 +161,11 @@ namespace Robomongo
void addAcceptedEulaVersion(QString const& version) { _acceptedEulaVersions.insert(version); }
QSet<QString> const& acceptedEulaVersions() const { return _acceptedEulaVersions; }
QSet<QString>::iterator addDbVersionConnected(QString const& version) {
return _dbVersionsConnected.insert(version);
}
QSet<QString> const& dbVersionsConnected() const { return _dbVersionsConnected; }
void setCheckForUpdates(bool checkForUpdates) { _checkForUpdates = checkForUpdates; }
bool checkForUpdates() const { return _checkForUpdates; }
@@ -176,6 +184,8 @@ namespace Robomongo
int mongoTimeoutSec() const { return _mongoTimeoutSec; }
int shellTimeoutSec() const { return _shellTimeoutSec; }
void setShellTimeoutSec(int newValue) { _shellTimeoutSec = std::abs(newValue); }
// True when settings from previous versions of Robomongo are imported
void setImported(bool imported) { _imported = imported; }
bool imported() const { return _imported; }
@@ -185,6 +195,13 @@ namespace Robomongo
void addCacheData(QString const& key, QVariant const& value);
QVariant cacheData(QString const& key) const;
void setProgramExitedNormally(bool value) { _programExitedNormally = value; }
bool programExitedNormally() const { return _programExitedNormally; }
// Designed to be set only by human users
bool disableHttpsFeatures() const { return _disableHttpsFeatures; }
bool debugMode() const { return _debugMode; }
/**
* Returns number of imported connections
*/
@@ -214,9 +231,7 @@ namespace Robomongo
// Imports connections from oldConfigFilePath into current config file
static bool importConnectionsFromOldVersion(QString const& oldConfigFilePath);
static bool importConnectionsFrom_0_8_5_to_0_9();
static bool importConnectionsFrom_0_9_to_1_0_RC1();
static bool importConnectionsFrom_1_0_RC1_to_1_0_0();
static bool importConnectionsFrom_0_8_5();
/**
* @brief Version of settings schema currently loaded
@@ -233,7 +248,11 @@ namespace Robomongo
bool _minimizeToTray;
bool _lineNumbers;
bool _disableConnectionShortcuts;
bool _programExitedNormally = true;
bool _disableHttpsFeatures = false;
bool _debugMode = false;
QSet<QString> _acceptedEulaVersions;
QSet<QString> _dbVersionsConnected;
int _batchSize;
bool _checkForUpdates = true;
QString _currentStyle;
@@ -268,8 +287,8 @@ namespace Robomongo
ToolbarSettingsContainerType _toolbars;
// List of config. file absolute paths and related import functions.
// List of config. file absolute paths of old versions
// Must be updated with care and with every new version. Details on cpp file.
static const std::vector<ConfigFileAndImportFunction> _configFilesAndImportFunctions;
static std::vector<QString> const _configFilesOfOldVersions;
};
}
+19 -4
View File
@@ -1,6 +1,7 @@
#include "robomongo/core/settings/SshSettings.h"
#include "robomongo/core/utils/QtUtils.h"
#include "robomongo/utils/RoboCrypt.h"
namespace Robomongo
{
@@ -23,10 +24,12 @@ namespace Robomongo
map.insert("host", QtUtils::toQString(host()));
map.insert("port", port());
map.insert("userName", QtUtils::toQString(userName()));
map.insert("userPassword", QtUtils::toQString(userPassword()));
map.insert("userPasswordEncrypted", userPassword().empty() ? "" :
QtUtils::toQString(RoboCrypt::encrypt(userPassword())));
map.insert("privateKeyFile", QtUtils::toQString(privateKeyFile()));
map.insert("publicKeyFile", QtUtils::toQString(publicKeyFile()));
map.insert("passphrase", QtUtils::toQString(passphrase()));
map.insert("passphraseEncrypted", passphrase().empty() ? "" :
QtUtils::toQString(RoboCrypt::encrypt(passphrase())));
map.insert("method", QtUtils::toQString(authMethod()));
map.insert("enabled", enabled());
map.insert("askPassword", askPassword());
@@ -37,10 +40,22 @@ namespace Robomongo
setHost(QtUtils::toStdString(map.value("host").toString()));
setPort(map.value("port").toInt());
setUserName(QtUtils::toStdString(map.value("userName").toString()));
setUserPassword(QtUtils::toStdString(map.value("userPassword").toString()));
// From version Robo 1.3 "userPasswordEncrypted" is used instead of "userPassword" in config. file
if (map.contains("userPassword")) // Robo 1.2 and below
setUserPassword((map.value("userPassword").toString().toStdString()));
else if (map.contains("userPasswordEncrypted")) // From Robo 1.3
setUserPassword(RoboCrypt::decrypt((map.value("userPasswordEncrypted").toString().toStdString())));
setPrivateKeyFile(QtUtils::toStdString(map.value("privateKeyFile").toString()));
setPublicKeyFile(QtUtils::toStdString(map.value("publicKeyFile").toString()));
setPassphrase(QtUtils::toStdString(map.value("passphrase").toString()));
// From version Robo 1.3 "passphraseEncrypted" is used instead of "passphrase" in config. file
if (map.contains("passphrase")) // Robo 1.2 and below
setPassphrase((map.value("passphrase").toString().toStdString()));
else if (map.contains("passphraseEncrypted")) // From Robo 1.3
setPassphrase(RoboCrypt::decrypt((map.value("passphraseEncrypted").toString().toStdString())));
setAuthMethod(QtUtils::toStdString(map.value("method").toString()));
setEnabled(map.value("enabled").toBool());
setAskPassword(map.value("askPassword").toBool());

Some files were not shown because too many files have changed in this diff Show More