Compare commits

...
421 Commits
Author SHA1 Message Date
Pradip Parkale 593d86d3f2 Ensure that the 'Remove Server Group' option is available in the context menu. Fixes #5834 2020-09-15 13:19:00 +05:30
Pradip Parkale 8e132eab08 Fixed some accessibility issues. Fixes #5732 2020-09-15 13:03:18 +05:30
Akshay Joshi 324e3e74be Fixed an issue where custom sequences are not visible when show system objects are set to false. Fixes #5833 2020-09-15 12:58:43 +05:30
Akshay Joshi 7dca844cbe Update version for release. 2020-09-14 17:53:54 +05:30
Rahul Shirsat 8029d9e65e 1) Fixed internal server error when clicking on the open new query tool button
from the View/Edit Data window. Fixes #5831
2) Fixed schema diff panel title issue on new tab.
2020-09-14 17:42:59 +05:30
Domenico Sgarbossa cea41cb4a9 Update Italian translation. 2020-09-14 16:17:00 +05:30
Akshay Joshi 5eb1c57320 1) Correct the reverse engineering SQL of the collation node for database server version < 10.
2) Added 'rngcollation' and 'attnum' in the ignore list of Types node and fixed an issue occurs due to SonarQube fix.
2020-09-14 16:12:20 +05:30
Akshay Joshi 5462aeab11 Update Dependencies. 2020-09-13 19:14:56 +05:30
Libor M a850852847 Update Czech translation. 2020-09-13 19:01:21 +05:30
Identifier Anonymous 291ee5366c Update Japanese translation. 2020-09-13 18:58:22 +05:30
Libor M a1b48d2c64 Modify babel config for javascript files. 2020-09-13 18:54:35 +05:30
Akshay Joshi 913e92a96e Update message catalogs. 2020-09-11 20:00:07 +05:30
Aditya Toshniwal b82e6dbdb8 1) Added email id validation on the login page.
2) Added validation for the file manager.
2020-09-11 19:55:19 +05:30
Nidhi Bhammar 6ded547a0d Added documentation for shared server support. Fixes #5792 2020-09-11 19:12:08 +05:30
Akshay Joshi a7d40e238e Ensure that the 'CREATE SCHEMA' statement should be present in the generated script if the schema is not present in the target database. Fixes #5816 2020-09-11 19:06:56 +05:30
Akshay Joshi ed1bd74301 Ensure that a valid error message should be displayed for an incorrect user or password. 2020-09-11 11:26:47 +05:30
Akshay Joshi 1bd0a0edf5 Remove illegal argument from trigger function in trigger DDL statement. Fixes #5779 2020-09-10 17:27:01 +05:30
Rahul Shirsat 7fac72cac5 Fixed an issue where alert message should get displayed on active browser window.
refs #4059
2020-09-10 12:09:56 +05:30
Aditya Toshniwal d0310b669e Fixed an issue where clicking on the 'Generate script' button shows a forever spinner due to pop up blocker. Fixes #5815 2020-09-09 20:10:56 +05:30
Rahul Shirsat 62e6848dc8 1) Added tooltip & keyboard shortcut for the query tool button.
2) Fixed TypeError issue.

refs #4059
2020-09-09 19:32:33 +05:30
Akshay Joshi 1bc1ef7f17 Fixed an issue where vacuum options not consider in Schema Diff. It's a regression. 2020-09-09 15:34:50 +05:30
Akshay Joshi ffb829e80c Fixed an issue while refreshing Resource Group. Fixes #5820 2020-09-09 14:34:14 +05:30
Aditya Toshniwal 796a8a013a 1) Changing the state of the react directly is not recommended, so avoid changing it directly.
2) Fixed API test cases.
2020-09-09 13:08:58 +05:30
Aditya Toshniwal 535739c0c7 Fixed cognitive complexity issues reported by SonarQube. 2020-09-09 11:25:43 +05:30
Nikhil Mohite 72f0e87367 Fixed cognitive complexity issues reported by SonarQube. 2020-09-09 11:20:17 +05:30
Nidhi Bhammar f278490540 Update the description of GIN and GiST indexes in the documentation. Fixes #5734 2020-09-08 12:04:58 +05:30
Akshay Joshi 76b0e3e9f7 Moved logic to check fixed port is in use to ConfigWindow class.
refs #5751
2020-09-08 12:00:24 +05:30
Pradip Parkale 98e86a8160 Fixed an issue where the server icon getting change to the shared server icon in desktop mode.
refs #4979
2020-09-08 10:09:16 +05:30
Pradip Parkale 9e5487d5ad Fixed SQL for Row Level Security which is incorrectly generated. Fixes #5764 2020-09-07 18:40:49 +05:30
Aditya Toshniwal 8c2e965f6e Fixed excessive CPU usage by stopping the indefinite growth of the graph dataset. Fixes #5794 2020-09-07 18:23:04 +05:30
Aditya Toshniwal f8f00b4ecf Fixed an issue in the query tool when columns are having the same name as javascript object internal functions. Fixes #5765. 2020-09-07 18:10:27 +05:30
Pradip Parkale 4da4a05611 Fixed code smell 'Remove duplicates string literals'. 2020-09-07 17:56:02 +05:30
Akshay Joshi 9ae9ccff16 Modified the logic to check Port is in use for runtime. Fixes #5751. 2020-09-03 19:21:54 +05:30
Akshay Joshi eaa90ee8eb Fixed primary key/unique constraint icon issue. 2020-09-03 18:53:40 +05:30
Khushboo Vashi 31bbdd6a12 Fixed code smell 'String literals should not be duplicated'. 2020-09-03 18:35:58 +05:30
Aditya Toshniwal 974d395a48 Fixed cognitive complexity issues reported by SonarQube. 2020-09-03 18:10:57 +05:30
Akshay Joshi a67f6e4f9c Fixed API test cases failed due to commit for #4979. 2020-09-03 14:20:45 +05:30
Akshay Joshi ed0c4037ad Fixed linter error by removing 'debugger;' keyword. 2020-09-03 13:16:08 +05:30
Pradip Parkale b562ab7681 Added shared server support for admin users. Fixes #4979 2020-09-03 12:59:28 +05:30
Yogesh Mahajan 3e35dc95e5 Improve code coverage and API test cases for Tables. Fixes #5774. 2020-09-03 12:35:56 +05:30
Akshay Joshi ddf5b33219 Added exclamation icon to alertify warning messages. 2020-09-02 17:27:26 +05:30
Akshay Joshi 1c9badec9c Rename the menu option 'Search objects' to 'Search Objects...' 2020-09-02 16:44:30 +05:30
Aditya Toshniwal 8f3bdf1cf3 Fixed cognitive complexity issues reported by SonarQube. 2020-09-02 14:39:54 +05:30
Akshay Joshi 3b9e8e47ec Modified 'cryptography' version to less than or equal to 3.0 to fix the
pgAdmin4 launch issue on Windows.

Cryptography's new version may be creating a problem. This is a temporary
fix and will have to investigate the proper fix.
2020-09-01 16:05:41 +05:30
Dave Page b85831fb5f Fix typo 2020-09-01 09:22:10 +01:00
Ganesh Jaybhay fd0ed81f7f Fixed accessibility issues for main panels. 2020-09-01 12:58:23 +05:30
Rahul Shirsat b5c299c5ad Fixed an issue where --load-server does not allow loading connections that use pg_services. Fixes #5746 2020-08-31 17:49:46 +05:30
Cyril Jouve 5a253f9053 Change the following to replace Python 2 code with Python 3:
1) Replace the deprecated unit test method.
2) Wraps filter usage in a list call.
3) Converts the old metaclass syntax to new.
4) Use range instead of xrange method.
5) Change Unicode to str.
6) Several other transformations.
7) Fixed change password test cases.
8) Use simplejson instead of plain JSON.
2020-08-31 16:45:31 +05:30
Aditya Toshniwal 11d5613866 Fixed RESQL test cases for Roles module. 2020-08-28 18:22:25 +05:30
Yogesh Mahajan 3984544bdb Fixed code smell 'String literals should not be duplicated'. 2020-08-28 18:17:27 +05:30
Yogesh Mahajan e226b2fa75 Adjusted the height of jobstep code block to use maximum space. Fixes #5426. 2020-08-28 14:00:49 +05:30
Rahul Shirsat e8b192be3e Added a new button to the query tool toolbar to open a new query tool window. Fixes #4059 2020-08-28 13:53:08 +05:30
Dave Page 8368eed645 Ensure that 'setup-web.sh' should work in Debian 10. Fixes #5775. 2020-08-27 19:21:21 +05:30
Aditya Toshniwal 28b637c99c Fixed RE-SQL test cases failed due to the previous commit.
Introduces a new key - replace_regex_pattern to synchronize the
expected SQL with the backend SQL based on the regex string
2020-08-27 19:08:00 +05:30
Aditya Toshniwal 53a5410337 Fixed cognitive complexity issues and added some more RESQL test cases for roles module. 2020-08-27 13:09:22 +05:30
Chethana Kumar 8222bf6420 Modified the 'Commit' and 'Rollback' query tool button icons. Fixes #5662 2020-08-27 12:58:13 +05:30
Chris Mayo 0998d349ca Fixed an issue where the application ignores the fixed port configuration value. Fixes #5773 2020-08-27 12:49:58 +05:30
Yogesh Mahajan f3bde7b5f1 Ensure that schema names starting with 'pg' should be visible in browser tree when standard_conforming_strings is set to off. Fixes #4216 2020-08-26 18:16:16 +05:30
Yogesh Mahajan 8fcf527632 Improve code coverage and API test cases for Columns and Constraints (Index, Foreign Key, Check, Exclusion). Fixes #5332 2020-08-26 12:35:22 +05:30
Dave Page 4eb17afe4e Warn the user when connecting to a server that is older than pgAdmin supports. Fixes #5772 2020-08-25 17:18:43 +01:00
Nikhil Mohite d2577e32e6 Fixed cognitive complexity issues reported by SonarQube. 2020-08-25 18:13:01 +05:30
Aditya Toshniwal e582ffca38 Fixed regression issue in taking backup of the table. Added some more test cases. 2020-08-25 18:06:38 +05:30
Akshay Joshi 59649ca42c 1) Enable the 'Configure' and 'View log' menu option when the server taking longer than usual time to start.
2) When an error occurs from the backend, the configure window opens and if the user has changed the setting
   of the port, it won't take any effect as we have retrieved the value of the port at the start of the runtime.
3) Added logic to identify the specified fixed port is already in use. Throw the error before starting the pgAdmin server.

Fixes #5751
2020-08-25 18:01:27 +05:30
Akshay Joshi e2ac6187dc Fixed Jenkins build failure due to API test case failed. 2020-08-25 14:14:48 +05:30
Akshay Joshi df9aaf19c2 Fixed string indices must be integers issue for PostgreSQL < 9.3. Fixes #5766 2020-08-25 13:38:24 +05:30
Aditya Toshniwal 275c671576 Fixed cognitive complexity issues reported by SonarQube. 2020-08-25 12:39:14 +05:30
Pradip Parkale 86bbc3a9e8 Ensure that the user should be able to drop the database even if it is connected. Fixes #5722 2020-08-25 12:37:50 +05:30
Nikhil Mohite b3d49c61a5 Fixed incorrect reverse engineering SQL for Foreign key when creating a table. Fixes #5748 2020-08-25 12:31:58 +05:30
Pradip Parkale 7f947f146c Fixed cognitive complexity issues reported by SonarQube. 2020-08-25 12:28:55 +05:30
Romulo Rodriguez e6bd085c15 Simplifies the search of the LDAP user name by adding to the user's search condition directly in the existing search filter. 2020-08-24 12:47:09 +05:30
Akshay Joshi 52d0241a17 Fixed an issue where schema diff is not working when providing the options to Foreign Data Wrapper, Foreign Server, and User Mapping. Fixes #5754 2020-08-24 12:11:09 +05:30
Neel Patel b53de0c31d Updated some more font awesome icons for v5 2020-08-21 14:15:18 +05:30
Nikhil Mohite 19491d79a5 Fixed cognitive complexity issues reported by SonarQube. 2020-08-21 13:52:05 +05:30
Akshay Joshi dd6ae193ff Replace 'fa-clock-o' with 'fa-clock' which is appropriate for font awesome v5 2020-08-21 13:44:29 +05:30
Akshay Joshi fbbbc36221 Fixed code smell 'Define a constant instead of duplicating this literal' reported by SonarQube. 2020-08-20 20:26:51 +05:30
Rahul Shirsat 7f3e8596e3 Fixed code smell 'Define a constant instead of duplicating this literal' reported by SonarQube. 2020-08-20 18:34:49 +05:30
Akshay Joshi 103b08c9c5 Define constants for preferences label to fix SonarQube issues. 2020-08-20 17:58:37 +05:30
Dave Page 99a7ada58a Cleanup a bunch of duplicated gettext calls. 2020-08-20 10:00:12 +01:00
Nikhil Mohite 6415294782 Improve code coverage and API test cases for Grant Wizard. Fixes #5344 2020-08-20 14:04:24 +05:30
Dave Page 79e6480513 Added SQL Formatter support in Query Tool. Fixes #2042 2020-08-20 13:05:00 +05:30
Khushboo Vashi cc5a7ea334 Fixed code smell 'String literals should not be duplicated'.
Create a constant.py file which contains the common Constants.
2020-08-19 14:16:02 +05:30
Nikhil Mohite 4b56962c1b Fixed cognitive complexity issues reported by SonarQube. 2020-08-19 13:41:53 +05:30
Yogesh Mahajan 0668a52c6b Fixed following SonarQube issues:
1. String literals should not be duplicated.
 2. Cognitive Complexity of functions should not be too high.
2020-08-19 13:22:17 +05:30
Akshay Joshi 89e2f09b84 Ensure that 'bcrypt' version should be less than or equal to 3.1.7 as the new version supports Python 3.6 and above. 2020-08-18 17:59:06 +05:30
Dave Page 0fd9ee06bd Fix typo 2020-08-18 11:15:24 +01:00
Libor M 3f73516f8c Update Czech translation. 2020-08-17 17:53:55 +05:30
Akshay Joshi e3b1ef0b80 Update version for release. 2020-08-17 17:29:19 +05:30
Khushboo Vashi ae18b9a0ac Fixed schema diff issue when selecting any identical node. 2020-08-17 17:26:58 +05:30
Akshay Joshi b0af385ea0 Fixed an issue where the entire logs is in red text when the user runs backup and restore. Fixes #5604 2020-08-17 17:23:30 +05:30
Yogesh Mahajan 0122cf9aac Fixed feature test failure due to updating font-awesome from v4 to v5. 2020-08-17 12:31:19 +05:30
Akshay Joshi 085a4f4abf Update Dependencies. 2020-08-17 11:56:23 +05:30
Fred Escallier ad0bcba99e Update French translation. 2020-08-17 11:31:01 +05:30
Identifier Anonymous 7a05edc42a Update Japanese translation. 2020-08-17 11:27:24 +05:30
Domenico Sgarbossa d2f93d6fad Update Italian translation. 2020-08-17 11:23:32 +05:30
Akshay Joshi 1466e414ec Update message catalogs. 2020-08-14 17:26:42 +05:30
Akshay Joshi 8f61944386 1) Added special handling for the extension to resolve the dependency.
2) Added 'is_sys_obj' to the ignore list of Schema Diff.
3) Font awesome v5 fixes.
2020-08-13 17:48:04 +05:30
Akshay Joshi 63df19ee1c Fixed following schema diff issues:
1) Avoid template databases from the Database drop-down list.
 2) Exclude system schemas while comparing two databases.
 3) Escape group name for XSS.
2020-08-13 14:12:37 +05:30
Nikhil Mohite 93adf6884f Upgrade font awesome from v4 to v5. Fixes #5731 2020-08-13 12:04:00 +05:30
Cyril Jouve 36574b25b6 The 'str' object never has attribute decode in Python3, so remove the dead code. 2020-08-12 18:55:35 +05:30
Akshay Joshi 26506a9727 Fix PEP8 2020-08-12 17:48:08 +05:30
Aditya Toshniwal caeea7940a Fixed errors occurring when saving preferences, regression of SonarQube fixes. 2020-08-12 17:42:53 +05:30
Khushboo Vashi 5b688cf949 Resolve schema diff dependencies by selecting the appropriate node automatically and maintain the order in the generated script. Fixes #5730 2020-08-12 17:36:48 +05:30
Aditya Toshniwal 7dd313f5fc Fixed an issue where debugger doesn't work if the search path is set other than 'public'. Fixes #4123 2020-08-12 14:24:40 +05:30
Yogesh Mahajan 1f70385a4e Fixed an issue where conversion of bytea to the binary string results in an error. Fixes #5567 2020-08-11 15:31:14 +05:30
Aditya Toshniwal 8129df42da Fixed cognitive complexity issues reported by SonarQube. 2020-08-11 15:13:35 +05:30
Akshay Joshi 082b968bbc Fixed following schema diff issues:
1) Wrong SQL generated for the columns having different data type.
  2) Added 'castfunc' in the ignore list.
2020-08-11 14:42:32 +05:30
Rahul Shirsat 2907a79dd7 Added missing comments in reverse engineering SQL for each column of a View. Fixes #3791 2020-08-11 11:30:47 +05:30
Akshay Joshi 46af290b85 Fixed API test cases for packages. 2020-08-10 18:13:00 +05:30
Aditya Toshniwal 26a758a0d6 Fixed an issue where copying and pasting a cell with multiple line data
will result in multiple rows. Fixes #5526

Fixed an old issue where quotes are not escaped when copying the cells.
As per CSV standards, if the string is in double quotes and there are
double quotes inside the string then they should be escaped with extra double-quotes.
2020-08-10 16:53:32 +05:30
Nikhil Mohite 9d006d0ec5 Fixed cognitive complexity issues reported by SonarQube. 2020-08-10 16:30:07 +05:30
Cyril Jouve 7a0bfecfc5 Use Python3 'ipaddress' module to validate the IPv4 and IPv6 addresses. 2020-08-10 15:57:25 +05:30
Rahul Shirsat 604937cf66 Fixed an issue where 'ALTER VIEW' statement is missing when the user sets the default value of a column for View. Fixes #5664 2020-08-10 15:27:57 +05:30
Akshay Joshi 4f74609ecf Modified schema diff tool to compare two databases instead of two schemas. Fixes #5126 2020-08-10 15:13:34 +05:30
Yogesh Mahajan  3672013ddc Fixed an issue where the error message does not have a close button on utility dialogs. Fixes #5670 2020-08-07 17:17:51 +05:30
Nikhil Mohite  9ad7476a34 Corrected DROP SQL syntax for catalog. Fixes #5713 2020-08-07 16:58:38 +05:30
Pramod Ahire 23a12efd29 Added make file target for the coverage of JS files. 2020-08-07 16:36:48 +05:30
Akshay Joshi 518b13c779 Added the 'ORDER BY' clause for the privileges type to fix schema diff issue. Fixes #5689 2020-08-07 16:30:03 +05:30
Dave Page d9c20de31f Clarify some of the differences when running in server mode in the docs. Fixes #5724 2020-08-07 10:07:28 +01:00
Aditya Toshniwal d6400bbcae Replace the generic exception class with a more specific one. 2020-08-07 12:37:00 +05:30
Pramod Ahire 68a5027d15 Added ability to generate code coverage reports for java script files. 2020-08-07 12:27:12 +05:30
Akshay Joshi 48ec4085d2 Update the sshtunnel version to v0.1.5.
refs #4361
2020-08-06 17:17:27 +05:30
Aditya Toshniwal e494b1520d Fixed an issue where ajax call continues to fire even after disconnect the database server. Fixes #5716 2020-08-06 16:52:16 +05:30
Akshay Joshi aac0da4cbc Fixed ssh tunnel hang issue when the user tries to disconnect the server. Fixes #4361 2020-08-06 16:16:37 +05:30
Yogesh Mahajan  48737e6a02 Fixed code smell 'String literals should not be duplicated' reported by SonarQube. 2020-08-06 12:42:19 +05:30
Nikhil Mohite  1122e06f48 Fixed cognitive complexity issues reported by SonarQube. 2020-08-06 12:38:35 +05:30
Yogesh Mahajan e3dfe03a2a Fixed an issue where the user is not able to insert the data if the table and columns name contains special characters. Fixes #4387 2020-08-06 12:30:10 +05:30
Nikhil Mohite 6a406f466d Fixed cognitive complexity issues reported by SonarQube. 2020-08-05 13:00:44 +05:30
Aditya Toshniwal aa679e06b2 Replace the generic exception class with a more specific one to fix SonarQube issues. 2020-08-05 12:41:28 +05:30
Murtuza Zabuawala d2621282dc Change the scope of '.dashboard-graph-body' CSS class to prevent it from affecting other places. 2020-08-05 12:30:09 +05:30
Akshay Joshi 5ce2773658 Ensure that the Dictionaries drop-down shows all the dictionaries in the FTS configuration dialog. Fixes #5429 2020-08-04 15:48:20 +05:30
Yogesh Mahajan 43e127de31 Ensure that the original file format should be retained when saving the same file in SQL editor. Fixes #3767 2020-08-03 13:18:04 +05:30
Akshay Joshi 87d08de3a0 Corrected the syntax as per jinja standards. refs #5632 2020-08-03 13:08:29 +05:30
Aditya Toshniwal 536593bf8a Fixed following SonarQube issues:
- Remove this assignment to the local variable, the value is never used.
  - Rename local variables to match the regular expression
  - Add logic to this except clause or eliminate it and rethrow the exception automatically.
  - Rename fields to match the regular expression
  - Extract this nested conditional expression into an independent statement.
  - Change this default value to "None" and initialize this parameter inside the function/method.
  - Update this function so that its implementation is not identical to __repr__
  - Refactor this method to not always return the same value
  - Reraise this exception to stop the application as the user expects
  - Add missing parameters _w _PY3. This method overrides simplejson.decoder.JSONDecoder.decode.
  - Remove this redundant continue.
  - Remove this unused function declaration
  - Remove this identity check; it will always be False.
2020-08-03 12:59:51 +05:30
Nikhil Mohite eb2c554601 Fixed cognitive complexity issues reported by SonarQube. 2020-08-03 12:46:34 +05:30
Satish V 318d712c4f Improve code coverage and API test cases for Schemas. Fixes #5327 2020-08-03 12:38:38 +05:30
Shubham Agarwal 32d904058a Fixed SonarQube issues. 2020-08-03 11:44:27 +05:30
Aditya Toshniwal 56cf64ad22 Fixed following SonarQube issues:
- Refactor functions to not always return the same value.
  - Rename "cls" to "self" or add the missing "self" parameter.
  - Remove useless assignment to variables.
2020-07-30 14:04:22 +05:30
Akshay Joshi dd7eb54e90 Fixed an issue when comparing the table with a trigger throwing error in schema diff. Fixes #5710 2020-07-30 13:57:00 +05:30
Nikhil Mohite 89fa85d650 Fixed cognitive complexity issues reported by SonarQube. 2020-07-29 18:29:04 +05:30
Akshay Joshi 099fea15ae Fixed code smells in runtime code reported by SonarQube. 2020-07-29 18:26:41 +05:30
Rahul Shirsat 74fd5dfe96 Ensure that the user will be able to modify the start value of the Identity column. Fixes #5632 2020-07-29 16:22:11 +05:30
Satish V 287a6628ed Improve code coverage and API test cases for Types. Fixes #5336 2020-07-29 15:41:04 +05:30
Akshay Joshi 510dd5c047 1) Fixed pgAdmin hang issue when the user clicks on 'View Log' menu option.
2) Fixed some code smell in runtime code.
2020-07-29 15:31:38 +05:30
Aditya Toshniwal f715373218 Replace charting library Flotr2 with ChartJS using React. Fixes #3904 2020-07-29 14:49:22 +05:30
Dave Page 5820b9521e Make sure the version check is compatible with older versions of Qt 2020-07-29 09:36:27 +01:00
Dave Page 6fc6ec1cda Correct TLS certificate filename in the container deployment docs. Fixes #5708 2020-07-29 09:26:12 +01:00
Aditya Toshniwal a0893fe43b Fixed code smell 'variable shadows a builtin' reported by SonarQube. 2020-07-28 16:20:26 +05:30
Dave Page 46ba0310fa Make the runtime configuration dialog non-modal. Fixes #5490
Major refactoring of the runtime code, Specifically:
  - Move the bulk of the core code from main() into a new Runtime class.
  - Break up the mass of code that was main() into a number of relatively simple functions.
  - Make the Configuration dialog synchronous so the Log dialog can be properly viewed.
  - Enable/disable menu options at the right time.
  - Remove support for Qt < 5.0.
  - Remove the application name constant and hardcode the name to simplify the code.
  - Improve log messages.
  - Replace the sdbm hashing with Qt's MD5 hashing.
2020-07-28 16:13:05 +05:30
Akshay Joshi ed0dc62b69 Fixed incorrect import statement for urlopen.
refs #5700
2020-07-27 17:33:44 +05:30
Akshay Joshi fb0bc65ced Fixed following SonarQube issues:
1) Define a constant instead of duplicating this literal.
  2) Reduce cognitive complexity (Patch by Aditya)
2020-07-27 16:31:03 +05:30
Dave Page f57558fdb2 Add a --yes command line option to setup-web.sh to allow non-interactive use. Fixes #5610. 2020-07-27 06:29:01 -04:00
Cyril Jouve f93cfe8c4c Remove old Python 2 compatibility code. Fixes #5700 2020-07-27 11:03:13 +01:00
Akshay Joshi 7a22cff28c Fixed 'cannot unpack non-iterable Response object' issue. 2020-07-24 14:59:50 +05:30
Yogesh Mahajan 043025d1eb Fixed an issue where the user is not able to save the new row if the table is empty. Fixes #4810 2020-07-24 14:30:22 +05:30
Satish V 4cf8c2f300 Improve code coverage and API test cases for Foreign Servers and User Mappings. Fixes #5324 2020-07-24 14:14:13 +05:30
Rahul Shirsat 937877e841 Ensure that RLS Policy node should be searchable using search object. Fixes #5646 2020-07-24 13:47:39 +05:30
Yogesh Mahajan dd27e08a98 Fixed code smell 'Unused local variables should be removed'. 2020-07-24 12:15:29 +05:30
Nikhil Mohite 1fbf298d30 Fixed cognitive complexity issues reported by SonarQube. 2020-07-24 12:03:05 +05:30
Aditya Toshniwal 505a3ac960 1) Fixed cognitive complexity issues reported by SonarQube.
2) Fixed code smell 'Add a nested comment explaining why this method is
   empty, or complete the implementation'.
2020-07-24 11:46:30 +05:30
Dave Page 310450cfa7 Fix typo. 2020-07-22 10:11:04 +01:00
Nikhil Mohite 5f619ae40a Ensure that data output color is readable on row selection. Fixes #5687 2020-07-21 18:54:06 +05:30
Pradip Parkale 28a4359020 Fixed issue where the user was not able to update policy if the policy is created with space. Fixes #5686 2020-07-21 18:14:49 +05:30
Akshay Joshi f177d54f21 Fixed AttributeError while creating the server group. Fixes #5688 2020-07-21 18:02:51 +05:30
Libor M 851c15b2d6 Update Czech translation. 2020-07-21 17:23:13 +05:30
Akshay Joshi c0e30c93e5 Update version for release. 2020-07-20 16:18:36 +05:30
Khushboo Vashi 645517d22d Added support for LDAP anonymous binding. Fixes #5650 2020-07-20 15:30:06 +05:30
Nikhil Mohite 3983e2c13c Fix the following issues for High Contrast Theme:
1) Schema diff compare button icon is not visible on hover.
  2) Schema diff for identical section text is not readable due to the same color as the background.
  3) Removed extra variables used for set text color for explain - Analysis section (Issue related dark theme.). 
  4) Issue related to the disabled toggle button.

refs #5653
2020-07-20 15:12:46 +05:30
Identifier Anonymous f29db1a9cd Update Japanese translation. 2020-07-20 12:08:50 +05:30
Fred Escallier c723b4584c Update French translation. 2020-07-20 12:04:47 +05:30
Domenico Sgarbossa b75c09d7c0 Update Italian translation. 2020-07-20 12:02:46 +05:30
Yogesh Mahajan 225c3e8f7e Fixed feature tests 2020-07-20 11:59:28 +05:30
Nikhil Mohite 7edcca9b07 Added High Contrast theme support. Fixes #5653
Fixed text color issue in explain analyze for the Dark theme. Fixes #5677
2020-07-20 11:51:21 +05:30
Dave Page 9174db2024 Fix typo. 2020-07-18 07:30:06 +01:00
Dave Page 69e2ec806b Fix PEP-8 issue. 2020-07-17 18:03:31 +01:00
Dave Page 04ce8b2c71 Include LICENSE and DEPENDENCIES [inventory] files in official packages. Fixes #5577
Whilst passing, rename libraries.txt to DEPENDENCIES and update the list of static packages.
2020-07-17 17:06:16 +01:00
Akshay Joshi 2bfb7c20c8 Update message catalogs. 2020-07-17 18:02:50 +05:30
Dave Page fb2178e5d3 Support configuration files that are external to the application installation. Fixes #5235 2020-07-17 17:54:12 +05:30
Nikhil Mohite 4e2c4b0498 Fixed cognitive complexity issues reported by SonarQube. 2020-07-17 15:31:04 +05:30
Dave Page 13d2f9131d Replace the runtime themes with ones that don't have sizing issues. Fixes #5554 2020-07-17 15:31:04 +05:30
Satish V 64cdd509b0 Fixed save button enable issue when focusing in and out of numeric input field. Fixes #5137 2020-07-17 15:31:04 +05:30
Aditya Toshniwal bd15d2d0f7 Fixed CSRF errors when pgAdmin opened in an iframe on safari browser. Fixes #5675 2020-07-17 15:31:04 +05:30
Dave Page 64f5253bd3 Fix typo 2020-07-17 09:20:17 +01:00
Aditya Toshniwal 9d0f3ce90b Fixed code smell 'potential hiding of variables declared in an outer scope'. 2020-07-16 19:53:39 +05:30
Akshay Joshi 703faf3b15 Fixed following SoanrQube issues
1) Rename field "node_type" to prevent any misunderstanding/clash with field "NODE_TYPE" defined.
  2) Define a constant instead of duplicating this literal.

Solution:
  1) Rename the field "NODE_TYPE" and "COLLECTION_LABEL" to "_NODE_TYPE" and "_COLLECTION_LABEL"
  2) Declare the constant in PGChildNodeView for SQL files.
2020-07-16 19:39:55 +05:30
Akshay Joshi 5d8c79da38 Added docstrings for some newly created functions. 2020-07-15 18:07:54 +05:30
Satish V 522ddad72b Fixed code smell 'Variables should not be shadowed'. 2020-07-15 15:03:47 +05:30
Akshay Joshi 11c4877859 Fixed an issue where difference DDL is showing the wrong SQL when changing the policy owner. Fixes #5647 2020-07-15 14:52:14 +05:30
Akshay Joshi 2469032f15 Fixed an issue where fetching the schema throws an error if the database
is not connected in Schema Diff. Fixes #5673

Maintenance Database is selected by default in Schema Diff.
2020-07-15 13:07:28 +05:30
Khushboo Vashi bd9dc97b4f Fixed code smell 'Functions, methods, and lambdas should not have too many parameters' reported by SonarQube. 2020-07-14 19:23:50 +05:30
Rahul Shirsat d6893f9d8a Fixed reverse engineered SQL for partitions when storage parameters are specified. Fixes #5569. 2020-07-14 19:16:33 +05:30
Akshay Joshi 4f34bc0f0e Added missing dependencies/dependent and corrected some wrongly identified. Fixes #5666 2020-07-14 18:34:50 +05:30
Satish V a91e4d8a7f Improve code coverage and API test cases for Foreign Data Wrapper. Fixes #5323. 2020-07-14 15:58:22 +05:30
Aditya Toshniwal 161c9b0fc7 Fixed code smell 'Variables should not be shadowed'.
Fixed all the duplicate CSS blocks issues raised by SonarQube.
2020-07-14 15:45:01 +05:30
Nikhil Mohite 0013a3b047 Fixed cognitive complexity issues reported by SonarQube. 2020-07-14 15:33:54 +05:30
Ashesh Vashi 1889c256e1 Fixed a typo in the psycopg2 driver in fetching result with
'execute_scalar' while attempting to reconnect.
2020-07-13 22:45:01 +05:30
Dave Page 9113932066 Tweak the OpenSSL build instructions. 2020-07-13 13:36:56 +01:00
Akshay Joshi d3eaac8609 Reverted fix for #5569 due to a couple of issues. 2020-07-11 20:32:57 +05:30
Dave Page e6edf40048 Refactor server request code by removing some duplicated code in the runtime and improves some of the debug logs. 2020-07-11 16:59:26 +05:30
Dave Page dd38fed6e0 Use ISO8601 date format in the runtime startup log. 2020-07-11 16:47:36 +05:30
Dave Page 5ac656c638 Refactor config loading/saving for the runtime config dialog to avoid code duplication. 2020-07-11 16:41:31 +05:30
Dave Page 6855ac1d5e Use QStandardPaths::AppLocalDataLocation in the runtime to determine where to store runtime logs. Fixes #5414 2020-07-11 16:32:08 +05:30
Rahul Shirsat 29175d7ec4 Fixed reverse engineered SQL for partitions when storage parameters are specified. Fixes #5569 2020-07-11 16:23:31 +05:30
Yogesh Jain 92858e40bf Ensure that closing the alert box on the login page will close multiple alert boxes if opened. 2020-07-10 11:49:49 +05:30
Rahul Shirsat e8b81db977 Fixed cognitive complexity issues reported by SonarQube. 2020-07-10 11:44:33 +05:30
Nikhil Mohite 7420673a0f Improve code coverage and API test cases for FTS Configuration, FTS Parser, FTS Dictionaries, and FTS Template. Fixes #5329. 2020-07-10 11:40:08 +05:30
Aditya Toshniwal 357a9179b1 Fixed convention related issues reported by SonarQube. 2020-07-09 18:55:33 +05:30
Yogesh Mahajan 2cefa9afca Fixed code smell 'Variables should not be shadowed'. 2020-07-09 18:44:58 +05:30
Nikhil Mohite e1168f8de0 Fixed code smell to reduce cognitive complexity. 2020-07-09 18:41:13 +05:30
Satish V 290cf8271b Fixed code smell 'Variables should not be shadowed'. 2020-07-09 18:35:04 +05:30
Pradip Parkale 916182f80f Fixed code smell for variable naming convention. 2020-07-09 18:28:08 +05:30
Murtuza Zabuawala 2db9242f5c Fixed accessibility issue where few dialogs are not rendering properly
when we zoomed in browser window 200% and screen resolution is low.

Fixes #5662
2020-07-09 18:18:37 +05:30
Yogesh Mahajan 3c08e618bd Fixed an issue where CSV download quotes numeric columns. Fixes #5463 2020-07-09 18:11:46 +05:30
Pradip Parkale c58fda0a70 Ensure that create RLS Policy menu should not be visible for catalog objects. Fixes #5633 2020-07-09 18:04:32 +05:30
Akshay Joshi b4c25bdc0a Fixed code smell 'Functions, methods, and lambdas should not have too many parameters' reported by SonarQube. 2020-07-07 19:39:06 +05:30
Pradip Parkale 36a2c073bd Added support for permissive/restricted policy type while creating RLS Policy. Fixes #5622 2020-07-07 17:55:05 +05:30
Yogesh Mahajan 776bec0d82 Fixed following SoanrQube issues:
1) Variables should not be shadowed.
  2) Variables and functions should not be redeclared.
2020-07-07 16:25:46 +05:30
Satish V ab2dc60097 Fixed the SoanrQube code smell 'Variables should not be shadowed'. 2020-07-07 16:18:18 +05:30
Nikhil Mohite aee6bac5ef Fixed cognitive complexity code smell reported by SonarQube. 2020-07-07 15:19:47 +05:30
Khushboo Vashi 58b4c45d0c Added support for LDAP authentication with different DN by setting the dedicated user for the LDAP connection. Fixes #5484 2020-07-06 19:35:55 +05:30
Pramod Ahire a6ce78a8c0 Fixed SonarQube issues in css/scss files. 2020-07-06 19:11:43 +05:30
Satish V 2ebf203412 Fixed issue of error message not getting displayed when filename is empty for backup, restore, and import/export. Fixes #3814. 2020-07-06 19:04:26 +05:30
Aditya Toshniwal 45a03dd663 Fixed 'convention' related code smell reported by SonarQube. 2020-07-06 11:48:23 +05:30
Satish V fcf720a5d8 Fixed code smell 'Variable should not be shadowed' 2020-07-06 11:31:36 +05:30
Murtuza Zabuawala cb1cdd1b23 Modified EPAS templates to support schema restriction. 2020-07-03 18:42:17 +05:30
Akshay Joshi 0d92059155 Fixed code smells having rule 'Functions, methods and lambdas should not have too many parameters'. 2020-07-03 18:37:37 +05:30
Yogesh Mahajan 80ab596992 Fixed the SoanrQube code smell 'Variables should not be shadowed'. 2020-07-03 14:33:30 +05:30
Khushboo Vashi b5f0190799 Fixed the SonarQube Code smells having Rule 'Functions, methods and lambdas should not have too many parameters'. 2020-07-03 14:24:54 +05:30
Aditya Toshniwal 3d5a2046c4 Fixed jasmin test cases failed due to last commit. 2020-07-03 12:57:53 +05:30
Aditya Toshniwal 341c3aded6 Fixed dark theme-related CSS and modify the color codes. Fixes #5287
Fixed backgrid row hover issue where on hover background color is set for edit and delete cell only. Fixes #5470
2020-07-03 11:47:40 +05:30
Aditya Toshniwal dd4dc19add Fixed issue where dialog sizes snapping to the default widths. 2020-07-03 11:26:06 +05:30
Nikhil Mohite 1ab257d512 Fixed Cognitive Complexity code smell reproted by SonarQube. 2020-07-03 11:15:41 +05:30
Nikhil Mohite 2ec8051303 Remove the duplicate code for tab indent and add the logic into codemirror. 2020-07-03 10:47:39 +05:30
Akshay Joshi ec30e6ace7 Comment out the 'yarn audit' command to fix the vulnerability found in the 'lodash' package. No fix is currently available. 2020-07-02 16:21:56 +05:30
Aditya Toshniwal ced296939f Fixed an issue where the user is able to edit properties when some of the collection nodes are selected. Fixes #5629 2020-07-02 16:21:56 +05:30
Yogesh Mahajan 1802f8a3f8 Ensure that the referenced table should be displayed on foreign key constraints. Fixes #5530 2020-07-02 16:21:56 +05:30
Pradip Parkale 8b10315e2a Added hints for 'Using' and 'With check' options of RLS Policy node. 2020-07-02 16:21:56 +05:30
Dave Page e0fa4a6cb2 Fix typo. Fixes #5517 2020-07-02 09:32:31 +01:00
Ashesh Vashi 1366dd1fcd Show horizontal scrollbar when needed in the menubar in the lower
resolution, when navbar button is visible.

Added appropriate CSS in the .navbar-collapse class to show scrollbar
in screen resolution (992px widith)
2020-07-02 11:21:23 +05:30
Akshay Joshi 0850db2a9b Fixed database connection issue, regression of SonarQube fixes. 2020-07-01 17:32:22 +05:30
Akshay Joshi a881e4e3f8 Fix PEP8 2020-07-01 15:33:51 +05:30
Nikhil Mohite 192a446131 Fixed API test cases failing due to updating the server manager instance. 2020-07-01 15:29:59 +05:30
Pradip Parkale b30c590866 Fixed SonarQube code smell 'Rename function and variable name to match the regular expression'. 2020-07-01 13:50:51 +05:30
Yogesh Mahajan 6dd3ca31be Fixed SonarQube code smell 'Variables should not be shadowed'. 2020-07-01 13:43:00 +05:30
Nikhil Mohite c2e875d54b Fixed tab indent issue on a selection of lines is deleting the content when 'use spaces == true' in the preferences. Fixes #4235 2020-07-01 13:34:48 +05:30
Pradip Parkale 979f806161 1) Added RLS Policy support in Schema Diff. Fixes #5601
2) Fixed 'cant execute empty query' issue when remove the value of
   'USING' or 'WITH CHECK' option of RLS Policy. Fixes #5631
2020-07-01 12:44:28 +05:30
Ashesh Vashi 3102a8d24b Fix the dialog size when zoom level is changed of the browser.
The screen.width & screen.height does not reflect the values of the
height and width respectively when zoom level is changed for the
browser. It is better to review the calculated height and width based
on the window.innerHeight and window.innerWidth and re-evaluate them.
2020-07-01 11:49:43 +05:30
Ashesh Vashi 21d57b1f10 Do not let browser autocomplete the password field while connecting a
database server.

Set the autocomplete attribute of the password field to 'new-password'
to let browser know, we require a new password for the password, and do
not autocomplete it.
2020-07-01 11:26:52 +05:30
Nikhil Mohite c873218c32 Added support for schema level restriction. Fixes #5583
Allow user to edit the connection properties when the database server
is already connected.
2020-06-30 19:15:23 +05:30
Satish V 4c05287677 Fixed SonarQube code smell 'Variables should not be shadowed'. 2020-06-30 17:26:18 +05:30
Nikhil Mohite 6713bc068b Fixed SonarQube code smells 'Refactor this function to reduce its Cognitive Complexity'. 2020-06-30 17:06:55 +05:30
Akshay Joshi 46d26cd029 Remove extra brackets from reverse engineering SQL of RLS Policy. Fixes #5621 2020-06-30 16:11:02 +05:30
Zhang Jie 88db5ec4d5 Remove extra brackets from reverse engineering SQL of trigger. 2020-06-30 16:07:55 +05:30
Akshay Joshi 102d6e7a9a Fixed an issue where panels get disappeared. Regression of SonarQube fix. 2020-06-29 14:05:07 +05:30
Rahul Shirsat 7add777b21 Add proper indentation to the code while generating functions, procedures, and trigger functions. Fixes #3851 2020-06-29 12:36:28 +05:30
Paresh More 2db518c9c6 Fixed an issue where installation of pgadmin4 not working on 32-bit Windows. Fixes #5630 2020-06-29 10:22:04 +05:30
Akshay Joshi b91f6f0f5c Fixed an issue where the semicolon is misplaced in RLS Policy SQL.
Fixed one regression issue introduced by renaming the method 'gc' to 'gc_timeout'.
2020-06-26 19:24:54 +05:30
Nikhil Mohite 115657a465 Fixed following SonarQube issues:
1) Refactor function to reduce its Cognitive Complexity.
 2) Rename variable to match the regular expression ^[_a-z][a-z0-9_]*$.
2020-06-26 15:03:50 +05:30
Satish V 8e28e0a32b Improve code coverage and API test cases for Domain and Domain Constraints. Fixes #5326 2020-06-26 14:15:09 +05:30
Satish V 830ac1cc91 Fixed following SonarQube issues:
1. Method/Field names should comply with a naming convention.
 2. Conditionals should start on new lines
2020-06-26 13:32:45 +05:30
Pradip Parkale 5206dafb35 Fixed code smells having rule 'Rename class name to match the regular expression'. 2020-06-26 13:23:23 +05:30
Khushboo Vashi c7a16a4bd5 Fixed code smells having rule 'Nested blocks of code should not be left empty'. 2020-06-26 13:18:27 +05:30
Yogesh Mahajan 707ff450b5 Fixed following SonarQube issues:
1. Boolean checks should not be inverted.
2. The comma operator should not be used.
3. Arguments to built-in functions should match documented types.
4. Redundant pairs of parentheses should be removed.
5. A conditionally executed single line should be denoted by indentation, 
6. A while loop should be used instead of a 'for' loop.
2020-06-26 13:12:07 +05:30
Diego Augusto Molina 6a63279396 Ensure that the OWNER should be quoted for foreign tables, procedures, and trigger functions. 2020-06-26 12:28:36 +05:30
Aditya Toshniwal d3b3d07f2e Fixed SonarQube issues with the tag unused. All the unused variables, assignments, code comments are fixed. 2020-06-25 11:09:43 +05:30
Satish V a1fd9ea3ce Fixed issue related to extra semicolons and function naming convention reported by SonarQube. 2020-06-24 16:16:12 +05:30
Nikhil Mohite db9d684524 Fixed 'Rename local variable to match the regular expression' issue reported by SonarQube. 2020-06-24 16:08:14 +05:30
Akshay Joshi 15c621b1d8 Fixed following SonarQube issues:
1) TypeError can be thrown as <variable_name> might be null or undefined here.
2) Unexpected duplicate "white-space".
3) Unexpected missing generic font family.
4) Unexpected shorthand "padding" after "padding-left".
2020-06-24 15:57:01 +05:30
Yogesh Mahajan cdf1c7a2a6 Fixed parallel test execution failure by handling slowness when multiple sessions are logged in concurrently. 2020-06-23 18:43:54 +05:30
Akshay Joshi d265ed9729 Fixed an issue while creating RLS Policy with the name having space. Fixes #5620 2020-06-23 14:28:21 +05:30
Akshay Joshi 18b3cc2683 Initialize pointer variables with Q_NULLPTR. 2020-06-23 14:23:28 +05:30
Murtuza Zabuawala c064eb0795 Fix an issue where RLS Policy dialog help is not working. 2020-06-23 14:13:08 +05:30
Akshay Joshi c2268c82ee Update version for release. 2020-06-22 17:42:46 +05:30
Yogesh Mahajan caebdcfa91 Ensure that the query tool should display the proper error message while terminating the active session. Fixes #3591 2020-06-22 17:09:10 +05:30
Pradip Parkale 6012f49919 Added policy event 'ALL' in events drop-down list. 2020-06-22 17:09:10 +05:30
Yogesh Mahajan d2f4a62bf3 Documentation of Row Level Security Policies. Fixes #5581 2020-06-22 17:09:10 +05:30
Paresh More 9d25973a77 Disallow installation of the 32 and 64 bit builds at the same time on Windows. 2020-06-22 12:15:32 +01:00
Yogesh Mahajan 34fbe756e8 1) Fixes parallel test execution failures.
2) Added capability to pass browser-name via command line for parallel execution.
2020-06-22 13:05:13 +05:30
Satish V daad16ea93 Fixed issue related to reducing the if-else statement to single return expression. Reported by SonarQube. 2020-06-22 12:58:48 +05:30
Aditya Toshniwal 6620f9263d Fixed issues reported by SonarQube with tag 'bad-practice'. 2020-06-22 12:18:59 +05:30
Identifier Anonymous 9e40995ab0 Update Japanese translation. 2020-06-22 11:58:15 +05:30
Domenico Sgarbossa ecdd95d15a Update Italian translation. 2020-06-22 11:55:32 +05:30
Aditya Toshniwal d6b22f1f4c Fixed an issue where the search object is unable to locate inherited tables and constraint filters are not working. Fixes #5492 2020-06-22 11:53:00 +05:30
Akshay Joshi 7ce7808093 Update message catalogs. 2020-06-19 18:01:32 +05:30
Akshay Joshi 2395075b7c Update library inventory. 2020-06-19 18:00:00 +05:30
Akshay Joshi bc24e3643f More code cleanup for SonarQube. 2020-06-18 16:20:34 +01:00
Yogesh Mahajan 6d3f13076f Fixed 'Comma operator should not be used' issue reported by SonarQube. 2020-06-18 16:17:55 +05:30
Satish V 905be1d894 Replace if-then-else statement by a single return statement, issue reported by SonarQube. 2020-06-18 15:51:01 +05:30
Aditya Toshniwal a278e8b1e6 Fixed the master password issue, introduced in the last commit. 2020-06-18 15:38:38 +05:30
Aditya Toshniwal f0490a54b7 Fixed redundant tagged issue reported by SonarQube. 2020-06-18 11:14:56 +05:30
Akshay Joshi 5ed1e1e5b6 Fixed some sonarqube issues. 2020-06-17 19:30:56 +05:30
Aditya Toshniwal df05efd7d9 Fixed vulnerabilities and few design suspicions where two conditional structures are having the same implementation. 2020-06-17 17:15:09 +05:30
Yogesh Mahajan 7c12ade161 Fixed issue related to shadowing variables reported by SonarQube. 2020-06-17 17:08:23 +05:30
Akshay Joshi cb268075c2 1) Added option to ignore the whitespaces while comparing objects in schema diff. Fixes #5468
2) Added server group name while selecting servers in schema diff. Fixes #5500
3) Fixed an issue where two identical tables showing different by schema diff tool. Fixes #5584
2020-06-17 16:27:51 +05:30
Dave Page 9f5e8962b5 Correct function naming. 2020-06-17 11:54:33 +01:00
Dave Page 6525f25a22 Correct URL and versions. 2020-06-17 11:51:11 +01:00
Dave Page aa15d2a7e2 Cleanup some variable naming. 2020-06-17 11:34:03 +01:00
Dave Page 1ca9912987 Cleanup some duplicated styles. 2020-06-17 11:31:07 +01:00
Satish V d43518cb3c Fixed following issues reported by SonarQube:
1) Replace this if-then-else statement by a single return statement. (clumsy)
2) 'switch' statements should have at least 3 'case' clauses. (bad practice)
2020-06-16 15:00:51 +05:30
Akshay Joshi cf64e2c97c Fixed runtime issues reported by SonarQube. 2020-06-16 14:53:40 +05:30
Aditya Toshniwal 3e00fe2b0f Fixed vulnerabilities and few design suspicions where two conditional structures are having the same implementation. Reported by SonarQube 2020-06-16 11:14:57 +05:30
Yogesh Mahajan 2ae5c0ec4f Fixed an issue where select all checkbox only selects the first 50 tables. Fixes #4226 2020-06-16 11:05:10 +05:30
Yogesh Mahajan 697f4aec95 Fixed issue related to shadowing variables reported by SonarQube. 2020-06-16 10:47:40 +05:30
Nikhil Mohite 023a1f222f Remove duplicate properties in CSS and few js standard fixes reported by SonarQube. 2020-06-15 17:15:15 +05:30
Akshay Joshi a21e6448ce Fixed RESQL test cases, regression of RLS policy. 2020-06-15 17:10:25 +05:30
Satish V eb1b17b636 Fix 'expressions evaluated to true/false always' issue reported by SonarQube. 2020-06-15 16:50:07 +05:30
Mishika Singh 38cd3327f3 Ensure that pgadmin should be able to connect to the server which has password more than 1000 characters. Fixes #5592 2020-06-15 16:50:07 +05:30
Khushboo Vashi 8ab358ccec Fix following issues reported by SonarQube:
1) Properties of variables with "null" or "undefined" values should not be accessed
2) Variables should not be self-assigned
3) "in" should not be used with primitive types
2020-06-15 16:50:07 +05:30
Aditya Toshniwal 641f7bbe9d Some clumsy coding related fixes reported by SonarQube. 2020-06-15 16:50:07 +05:30
Akshay Joshi a23fad0ba8 Tidy up some code to keep SonarQube happy. 2020-06-15 12:12:19 +01:00
Pradip Parkale 18277543b6 Added support of Row Security Policies. Fixes #5516 2020-06-15 15:44:59 +05:30
Dave Page bfa0b87791 Make sure we have the wheel package in the venv as it may be needed to build other dependencies. 2020-06-12 11:42:42 +01:00
Aditya Toshniwal 8c20f0c0d2 Some clumsy coding related fixes reported by SonarQube. 2020-06-12 15:24:17 +05:30
Satish V ee1ea47e88 Fixed issue 'expects 4 arguments, but 5 were provided' reported by SonarQube. 2020-06-12 15:15:07 +05:30
Satish V 82c4a4a03e Improve code coverage and API test cases for Collations. Fixes #5325 2020-06-11 11:12:41 +05:30
Dave Page 21efe6f902 Remove blank line at EOF. 2020-06-10 17:03:08 +01:00
Dave Page 5c60dcd501 Remove blank line at EOF. 2020-06-10 17:02:39 +01:00
Dave Page 85e89c869a Cleanup some code smells identified by SonarQube. 2020-06-10 16:42:59 +01:00
Dave Page 1485ff338f Don't use the venv to create the venv on Windows as it doesn't allow python.exe to be relocated on Windows. Use the tried and tested virtualenv instead. Fixes #5595 2020-06-09 16:28:36 +01:00
Akshay Joshi ac4b5ab7fa 1) Correct the typo 'pythonw.exe' should be 'python.exe' for Windows if 'pythonw.exe' not found.
2) Added logging to identify the interpreter command for Windows.
2020-06-09 19:05:20 +05:30
Aditya Toshniwal eb971a0320 Update Codemirror version to the latest which allows us to set screen reader labels on Codemirror editor.
refs #5197
2020-06-08 12:26:12 +05:30
Yogesh Mahajan 92d9c41da7 Fixed connection and version number detection issue when the database server is upgraded. Fixes #5507 2020-06-04 18:18:11 +05:30
Dave Page ba91e3fc1f Fix a couple of typos. 2020-06-04 10:43:05 +01:00
Satish V 726ecd79e6 Fixed import statements.
refs #3669
2020-06-03 12:49:05 +05:30
Satish V d22e276586 Ensure that proper error should be displayed for the deleted node. Fixes #3669 2020-06-03 11:26:26 +05:30
Dave Page 3d0319dba7 Include the libpq5 deb in the Debian/Ubuntu repos. 2020-06-02 13:23:12 +01:00
Dave Page 4a0efc0e86 Fix message. 2020-06-02 13:19:46 +01:00
Dave Page 445abf1e31 Quieten pushd/popd 2020-06-02 13:14:02 +01:00
Dave Page 7f58552f60 Include the PostgreSQL repo so we get the latest libpq 2020-06-02 12:33:57 +01:00
Dave Page 2549085872 We need yum-utils. Fix the rpmmacros message whilst passing. 2020-06-02 11:54:36 +01:00
Dave Page 9e67a0b0e7 Include postgresql-libs in our Yum repos. 2020-06-02 11:30:07 +01:00
Akshay Joshi a1a232a1f1 The 'pwd' module is not available on Windows, so replacing it with the 'getpass' module.
refs #5576
2020-06-02 14:09:44 +05:30
Nagesh Dhope c932213abd Disabled the Stop process button after clicking it and added a message 'Terminating the process...' to notify the user. Fixes #3787 2020-06-02 11:23:52 +05:30
Dave Page a0c19252df Improve error messaging if the storage and log directories cannot be created. Fixes #5576 2020-06-02 11:11:53 +05:30
Dave Page 67c978b7a4 Don't use virtualenv to create the venv on Windows. 2020-06-01 10:32:41 +01:00
Dave Page f4750f0096 Ignore venv directories in the tree. 2020-06-01 10:31:34 +01:00
Dave Page 676fec8694 Cleanup Windows build scripts and ensure Windows x64 builds will work. Fixes #5574 2020-06-01 09:52:24 +01:00
Dave Page 60a0b66414 Conflict with postgresql-libs 9.2 and below as there won't be a suitable libpq.
Per discussion with Devrim.
2020-06-01 09:42:18 +01:00
Aditya Toshniwal 1050c9857a Fixed an issue when dumping servers from a desktop pgAdmin app by providing an option '--sqlite-path'. Fixes #5521 2020-06-01 11:22:38 +05:30
Dave Page b21b03495d Tell Yum where the GPG public key is, and fix the arch and version variables, per Devrim. 2020-05-29 14:04:51 +01:00
Yogesh Mahajan 4632a7faba Fixed an issue where pgadmin detects the wrong browser version of the Microsoft Edge. Fixes #5465 2020-05-29 13:07:02 +05:30
Dave Page ccb39bea1a Require postgresql >= 9.5, and don't bother with Recommends. Per discussion with Devrim. 2020-05-28 16:26:44 +01:00
Dave Page bda62cb1f1 Don't try to import the signing key. YUM/RPM will do that for us, per Devrim. 2020-05-28 16:04:14 +01:00
Yogesh Mahajan 09b76b306c Fixed typo in exception keyword. Fixes #5539 2020-05-28 18:11:41 +05:30
Yogesh Mahajan e10f1274dc Ensure that the query tool panel gets closed when clicking on the 'Don't Save' button. Fixes #5416 2020-05-28 16:39:26 +05:30
Dave Page 9468c16233 Update hint test to use a modern Python version. 2020-05-27 11:36:03 +01:00
Dave Page 65fb0f901c Message clarification and improvement. 2020-05-26 15:02:59 +01:00
Akshay Joshi 1347c89d61 Update version for release. 2020-05-25 17:11:12 +05:30
Akshay Joshi b1cbcc7ef6 Fixed data truncation issue when updating the data of type character with length. Fixes #5481 2020-05-25 17:05:47 +05:30
Domenico Sgarbossa 22c3a2649b Update Italian translation. 2020-05-25 11:24:37 +05:30
Identifier Anonymous 2bb0b25688 Update Japanese translation. 2020-05-25 11:13:37 +05:30
Libor M 2aefc6361e Update Czech translation. 2020-05-25 11:09:52 +05:30
Dave Page 83cb01b8cd Update dependencies in the Docker container and remove PG 9.4 utilities from the Docker container as it's now out of support.
Fixes #5552.
Fixes #5553.
2020-05-22 17:02:12 +01:00
Akshay Joshi d42b712ee4 Update message catalogs 2020-05-22 19:13:13 +05:30
Dave Page fec458dd6a Add repo build information to the Debian README. 2020-05-22 11:58:24 +01:00
Akshay Joshi 9b8902dfb8 Fixed the SQL help issue for EDB Postgres Advanced Server. Fixes #4099 2020-05-22 14:11:58 +05:30
Dave Page 4a8037fc6a Test commit 2020-05-22 09:12:54 +01:00
Yogesh Mahajan d927a517aa Fixed feature test failures on the selenium grid for concurrent execution. 2020-05-21 19:44:28 +05:30
Dave Page 96939ba985 Add information to the Redhat README about signing RPMs, creating a repository and creating repo RPMs. 2020-05-21 12:47:41 +01:00
Dave Page 414b074bad Tidy up the web setup script output. 2020-05-19 14:27:23 +01:00
Yogesh Jain 7b1cac6914 Fixed an issue where clicking on Select All button, not selecting all the options in pgAgent job scheduler. Fixes #5496 2020-05-19 13:54:21 +05:30
Dave Page 4aaacfd5b0 Add the public key for our packages for the RPM build. 2020-05-18 15:43:17 +01:00
Dave Page 52187306ce Create the dist/ directory if needed. 2020-05-18 15:37:18 +01:00
Dave Page 0e799b16b0 Only try to run make clean if there is a Makefile present. 2020-05-18 11:18:03 +01:00
Dave Page 569d05df4e Remove obsolete file. 2020-05-18 11:17:07 +01:00
Dave Page eac5fe5157 Cleanup and refactor the macOS build scripts. Fixes #5525 2020-05-18 10:22:59 +01:00
Dave Page 5337514c63 Allow the base directory for the repo to be overridden from the environment. 2020-05-18 10:22:28 +01:00
Khushboo Vashi d1bdb178e2 Fixed an issue where if LDAP_SEARCH_BASE_DN is not set then, the value for LDAP_BASE_DN will be considered. Fixes #5487 2020-05-18 12:35:34 +05:30
Yogesh Mahajan 9f445dc052 Improve code coverage and API test cases for Indexes. Fixes #5333 2020-05-18 12:29:33 +05:30
Aditya Toshniwal d58c33dec0 Search object UI improvements. Fixes #5493 2020-05-18 11:29:12 +05:30
Khushboo Vashi 0f56c25893 Changed the user identity from email to username in the log file.
refs #5452
2020-05-18 11:01:20 +05:30
Dave Page 762784d2b5 Add a script for generating a repo RPM. 2020-05-15 11:22:28 +01:00
Pradip Parkale 6d6cd19b37 Improve code coverage and API test cases for Triggers and Compound Triggers. Fixes #5335 2020-05-15 12:50:50 +05:30
Akshay Joshi c0451cd454 Added connected pgAdmin user and connection name in the log file. Fixes #5452
Patch By: Nico T
2020-05-13 17:43:21 +05:30
Akshay Joshi 0620fafb6c Fixed PEP8 issues discovered after pycodestyle gets upgraded. 2020-05-13 17:14:32 +05:30
Khushboo Vashi a9a1a975a6 Added compatibility for Flask-Security-Too version 3.2 2020-05-13 16:02:38 +05:30
Akshay Joshi 8a06a836f4 Ensure that pgAdmin4 should be compiled with older OSX SDK's. 2020-05-12 17:22:22 +05:30
Yogesh Jain dba5761ad0 Fixed an issue where clicking on the cross button of the alert box on the login page is not working. Fixes #4033 2020-05-12 17:22:22 +05:30
Yogesh Mahajan 8ec1d4c9eb Fixed feature tests failure on chrome caused due to selenium grid implementation changes. 2020-05-12 17:22:22 +05:30
Akshay Joshi 46e9924ebb Fixed Unicode decode error 'utf-8' codec can't decode byte. Fixes #5510
It's a regression of commit id: 04d6d4e2ccc129baa698471ce0680ccabe2282be
2020-05-12 17:22:22 +05:30
Dave Page 12a7ce54d9 Ubuntu 20.04 needs python3-wheel to be explicitly installed. 2020-05-11 15:08:40 +01:00
Akshay Joshi 9d08776824 Ensure that maintenance job should be worked properly for indexes under a materialized view. Fixes #4223. 2020-05-11 16:47:36 +05:30
Akshay Joshi 073d90c4a6 Fixed internal server error when clicking on Triggers -> 'Enable All' for partitions. Fixes #5052 2020-05-11 15:18:39 +05:30
Dave Page 7d4ddc3910 Clarify and correct the docs on enabling the pl/debugger plugin on the server per Jakob Egger. Fixes #5503 2020-05-11 09:05:15 +01:00
Yogesh Mahajan 1294c089a8 Implement Selenium Grid to run multiple tests across different browsers, operating systems, and machines in parallel. Fixes #5255 2020-05-11 12:11:31 +05:30
Aditya Toshniwal b64896f558 Fixed generated SQL issue for auto vacuum options. Fixes #5398
Fixed some more issues:

 1) pgAdmin allows only true or false values for autovacuum_enabled,
    and there is no way to reset it individually without disabling a custom auto vacuum.
    To fix this, the control is changed from the switch to three state buttons.
 2) Setting any vacuum options to zero made the option disappear from the SQL.
 3) Right-click on a table with vacuum options set and create a new table.
 4) The parameters tab will have the options prefilled.
 5) Changed the UI a bit to remove unnecessary space around. Added "Autovacuum" before enabled.
    The SQL generated was appending a ".0" to decimal vacuum options. Changed to remove the leading ".0".
2020-05-08 14:30:30 +05:30
Ashesh Vashi e73e2d2502 Fixed the errors, and warnings reported by pylama.
TODO::
- Don't use unicode in Python 3 for removing the support of Python 2 (
  psycopg2 driver - __init__.py, server_manager.py).
- Merge the lastest pgcli (version: 3.0.0) for SQL autocompletion.
2020-05-08 14:13:38 +05:30
Satish V 9338bdcb3a Fixed an issue where the newly added table is not alphabetically added to the tree. Fixes #5434
Fixed an issue when renaming the column not added in the proper order. Fixes #5450
2020-05-08 12:52:03 +05:30
Khushboo Vashi d68e6bd892 Remove Python2 modules.
refs #5443
2020-05-08 12:28:21 +05:30
Pradip Parkale 057a2b2312 Improve code coverage and API test cases for the Rules module. Fixes #5334 2020-05-07 16:27:58 +05:30
Dave Page 46d186a49f Show the startup log as well as the server log in the runtime's log viewer. Fixes #5489 2020-05-07 11:01:02 +01:00
Dave Page 7164c677de UI layout tweaks. 2020-05-07 10:39:28 +01:00
Akshay Joshi 6ad46e1860 Fixed invalid literal issue when removing the connection limit for the existing role. Fixes #5001 2020-05-07 13:14:45 +05:30
Akshay Joshi a662d866af Ensure that 'With OID' option should be disabled while taking backup of database server version 12 and above. Fixes #4840 2020-05-07 11:56:43 +05:30
Akshay Joshi a0940fd145 Typecast the object to 'text' before using it in length() function, so that correct length function gets called. 2020-05-06 17:34:18 +05:30
Nagesh Dhope f61448eea2 Fixed an issue where the background job creation fails if there is only a version-specific python binary available in PATH. Fixes #5480 2020-05-06 12:38:06 +05:30
Akshay Joshi 943495de31 Fixed list sorting issue in the schema diff tool. Fixes #5440
Fixed an issue while comparing the two identical schemas using the schema diff tool. Fixes #5449
2020-05-06 11:25:43 +05:30
Aditya Toshniwal 059f1e38cc Refactor pgAdmin4.py so it can be imported and is a lot more readable. Fixes #5455 2020-05-04 15:28:44 +01:00
Aditya Toshniwal 370094274c Fixed post-login redirect location when running in server mode under a non-default root. Fixes #5473 2020-05-04 15:00:45 +01:00
Dave Page 04d6d4e2cc Remove support for Python 2. Fixes #5443 2020-05-04 14:58:49 +01:00
Dave Page cf31d0187b Remove support for building the macOS appbundle with Python 2.7. Refs #5443 2020-05-04 14:56:28 +01:00
Akshay Joshi f1963401d6 Raise an exception under Python < 3.4 for WSGI mode.
refs #5443
2020-05-04 15:06:45 +05:30
Dave Page 94bd1f1680 Cleanup Python detection in the runtime project file. Fixes #5444 2020-05-04 10:20:51 +01:00
Dave Page 908e156113 Correct ipv4 "all interfaces" address in the container docs, per Frank Limpert. Fixes #5466 2020-05-04 09:25:05 +01:00
Ganesh Jaybhay 5fe7813f9f Fixed an issue where select2 hover is inconsistent for the SSL field in create server dialog. Fixes #5469 2020-05-04 13:19:13 +05:30
Satish V d61b8eb1b3 Gracefully informed the user that the database is already connected when they click on 'Connect Database...'. Fixes #3694 2020-05-04 13:08:56 +05:30
Murtuza Zabuawala 0fc2afb829 Add Reverse Engineered and Modified SQL tests for Column and Type. 2020-05-04 12:48:24 +05:30
Yogesh Jain cc2e3ece7a Ensure that file browse home button should point to /Users/akshayjoshi rather than /. Fixes #4279 2020-05-04 12:40:19 +05:30
Khushboo Vashi 5656f756e6 Ensure that the dependencies tab shows correct information for Synonyms. Fixes #5422 2020-05-04 12:23:18 +05:30
Dave Page 9bdf900b25 Rename README 2020-05-01 15:18:29 +01:00
Dave Page 0ec60a6f85 Minor cleanup and modernisation. 2020-05-01 15:14:46 +01:00
Dave Page 70e24ba059 Rename the README and fix it up to match modern reality. 2020-05-01 15:14:04 +01:00
Akshay Joshi ad80217593 Remove Python2 references from the source code.
refs #5443

Initial patch: Neel Patel
2020-04-30 17:22:48 +05:30
Dave Page 7dd00a1494 Raise an exception under Python < 3.4.
It also cleans up the README to remove references to Python 2
and removes Python 2-isms from the main config.

refs #5443
2020-04-30 14:17:00 +05:30
Dave Page 109051e1d5 Remove Python 2 support from the desktop runtime
refs #5443
2020-04-30 13:04:09 +05:30
Dave Page 86afec860f Remove Python 2 support from the Python tests.
refs #5443
2020-04-30 12:56:45 +05:30
Dave Page 393741fd9d Remove Python 2.7 support from the wheel package.
refs #5443
2020-04-30 12:51:58 +05:30
Dave Page e8a4b46ba1 Another attempt at fixing the 'do we need the --embed flag for Python' problem.
This change looks at the output from python-config --help (which may go
to stderr or stdout), and if it includes --embed, adds it to the later
call to get the libs string.
2020-04-29 16:19:54 +01:00
Dave Page 97be3d8179 Don't rely on python-config sending the help message to stderr, as older versions seem to use stdout. 2020-04-29 15:49:16 +01:00
Dave Page 505956d1fa OK, another attempt at this as it fails on non-Linux non-Python 3.8. 2020-04-29 14:29:47 +01:00
Dave Page f7ef86dced Sigh. Remove extraneous closing bracket. It's always a bracket. 2020-04-29 14:04:32 +01:00
Dave Page 3138f36e05 Fix the runtime build with Python 3.8 on Linux 2020-04-29 13:55:53 +01:00
1701 changed files with 110259 additions and 63989 deletions

No files matched your search

+4
View File
@@ -41,6 +41,7 @@ web/config_local.py
web/pgadmin/misc/themes/pgadmin.themes.json
web/geckodriver.log
web/regression/test_config.json
web/regression/.coveragerc
node_modules/
web/pgAdmin/static/js/generated
web/pgadmin/static/js/generated
@@ -48,3 +49,6 @@ web/yarn-error.log
/web/cacert.pem
auditjs.html
auditpy.txt
/venv/
.scannerwork/
web/coverage/
File diff suppressed because it is too large. Load diff
+12 -16
View File
@@ -12,7 +12,7 @@
# and clean up the web/ source code
#########################################################################
FROM node:10-alpine AS app-builder
FROM node:12-alpine3.11 AS app-builder
RUN apk add --no-cache \
autoconf \
@@ -45,12 +45,10 @@ RUN npm install && \
npm audit fix && \
rm -f yarn.lock && \
yarn import && \
# Commented the below line to avoid vulnerability in decompress package and
# audit only dependencies folder. Refer https://www.npmjs.com/advisories/1217.
# Pull request is already been send https://github.com/kevva/decompress/pull/73,
# once fixed we will uncomment it.
# Commented the below line to avoid vulnerability in lodash package.
# Refer https://www.npmjs.com/advisories/1523.
# Once fixed we will uncomment it.
# yarn audit && \
yarn audit --groups dependencies && \
rm -f package-lock.json && \
yarn run bundle && \
rm -rf node_modules \
@@ -66,7 +64,7 @@ RUN npm install && \
# Now, create a documentation build container for the Sphinx docs
#########################################################################
FROM python:3.7-alpine3.10 as docs-builder
FROM python:3.8-alpine3.11 as docs-builder
# Install only dependencies absolutely required for documentation building
RUN apk add --no-cache \
@@ -98,21 +96,15 @@ RUN LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 make -C /pgadmin4/docs/en_US -f Makefile
# Create additional builders to get all of the PostgreSQL utilities
#########################################################################
FROM postgres:9.4-alpine as pg94-builder
FROM postgres:9.5-alpine as pg95-builder
FROM postgres:9.6-alpine as pg96-builder
FROM postgres:10-alpine as pg10-builder
FROM postgres:11-alpine as pg11-builder
FROM postgres:12-alpine as pg12-builder
FROM alpine:3.10 as tool-builder
FROM alpine:3.11 as tool-builder
# Copy the PG binaries
COPY --from=pg94-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-9.4/
COPY --from=pg94-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-9.4/
COPY --from=pg94-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-9.4/
COPY --from=pg94-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-9.4/
COPY --from=pg95-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-9.5/
COPY --from=pg95-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-9.5/
COPY --from=pg95-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-9.5/
@@ -142,7 +134,7 @@ COPY --from=pg12-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-12/
# Assemble everything into the final container.
#########################################################################
FROM python:3.7-alpine3.10
FROM python:3.8-alpine3.11
COPY --from=tool-builder /usr/local/pgsql /usr/local/
@@ -154,6 +146,10 @@ COPY --from=app-builder /pgadmin4/web /pgadmin4
COPY --from=docs-builder /pgadmin4/docs/en_US/_build/html/ /pgadmin4/docs
COPY requirements.txt /pgadmin4/requirements.txt
# License files
COPY LICENSE /pgadmin4/LICENSE
COPY DEPENDENCIES /pgadmin4/DEPENDENCIES
# Install build-dependencies, build & install C extensions and purge deps in
# one RUN step
RUN apk add --no-cache --virtual \
@@ -194,7 +190,7 @@ RUN groupadd -g 5050 pgadmin && \
chown pgadmin:pgadmin /var/log/pgadmin && \
touch /pgadmin4/config_distro.py && \
chown pgadmin:pgadmin /pgadmin4/config_distro.py && \
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/python3.7
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/python3.8
USER pgadmin
# Finish up
+146 -162
View File
@@ -2,23 +2,26 @@
SETLOCAL
SET WD=%CD%
SET "PGBUILDPATH=%WD%\win-build"
SET "BUILDROOT=%WD%\win-build"
SET "DISTROOT=%WD%\dist"
SET CMDOPTION=""
IF "%1" == "clean" SET CMDOPTION="VALID"
IF "%1" == "x86" SET CMDOPTION="VALID"
SET CMDOPTIONS=""
IF "%1" == "clean" SET CMDOPTIONS="VALID"
IF "%1" == "" SET CMDOPTIONS="VALID"
IF NOT %CMDOPTION%=="VALID" (
IF NOT %CMDOPTIONS%=="VALID" (
GOTO USAGE
)
SET ARCHITECTURE=%1
IF "%ARCHITECTURE%"=="clean" (
IF "%1" == "clean" (
CALL :CLEAN
EXIT /B %ERRORLEVEL%
)
set "ARCHITECTURE=x64"
if "%Platform%" == "X86" (
set "ARCHITECTURE=x86"
)
REM Main build sequence
CALL :SET_ENVIRONMENT
@@ -37,7 +40,7 @@ REM Main build sequence Ends
:CLEAN
ECHO Removing build directory...
IF EXIST "%PGBUILDPATH%" RD "%PGBUILDPATH%" /S /Q > nul || EXIT /B 1
IF EXIST "%BUILDROOT%" RD "%BUILDROOT%" /S /Q > nul || EXIT /B 1
ECHO Removing temp build directory...
IF EXIST "%WD%\pkg\win32\Output" rd "%WD%\pkg\win32\Output" /S /Q > nul || EXIT /B 1
@@ -50,40 +53,32 @@ REM Main build sequence Ends
:SET_ENVIRONMENT
ECHO Configuring the environment...
IF "%PYTHON_HOME%" == "" SET "PYTHON_HOME=C:\Python27"
IF "%PYTHON_DLL%" == "" SET "PYTHON_DLL=C:\Windows\SysWOW64\python27.dll"
IF "%QTDIR%" == "" SET "QTDIR=C:\Qt\5.9.1\mingw53_32"
IF "%MAKE%" == "" SET "MAKE=mingw32-make.exe"
IF "%PGDIR%" == "" SET "PGDIR=C:\Program Files (x86)\PostgreSQL\10"
IF "%INNOTOOL%" == "" SET "INNOTOOL=C:\Program Files (x86)\Inno Setup 5"
IF "%VCREDIST%" == "" SET "VCREDIST=C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\1033\vcredist_x86.exe"
IF "%SIGNTOOL%" == "" SET "SIGNTOOL=C:\Program Files\Microsoft SDKs\Windows\v7.1A\Bin\signtool.exe"
IF "%PGADMIN_PYTHON_DIR%" == "" SET "PGADMIN_PYTHON_DIR=C:\Python38"
IF "%PGADMIN_QT_DIR%" == "" SET "PGADMIN_QT_DIR=C:\Qt\5.14.2\msvc2017_64"
IF "%PGADMIN_POSTGRES_DIR%" == "" SET "PGADMIN_POSTGRES_DIR=C:\Program Files (x86)\PostgreSQL\12"
IF "%PGADMIN_INNOTOOL_DIR%" == "" SET "PGADMIN_INNOTOOL_DIR=C:\Program Files (x86)\Inno Setup 6"
IF "%PGADMIN_VCREDIST_DIR%" == "" SET "PGADMIN_VCREDIST_DIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.16.27012"
IF "%PGADMIN_SIGNTOOL_DIR%" == "" SET "PGADMIN_SIGNTOOL_DIR=C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64"
REM Set VCREDISTNAME (the filename)
for /f "delims=" %%i in ("%VCREDIST%") do set "VCREDISTNAME=%%~nxi"
REM Set REDIST_NAME (the filename)
set "VCREDIST_FILE=vcredist_%ARCHITECTURE%.exe"
REM Set additional variables we need
SET "QMAKE=%QTDIR%\bin\qmake.exe"
FOR /F "tokens=4,5 delims=. " %%a IN ('%QMAKE% -v ^| findstr /B /C:"Using Qt version "') DO SET QT_VERSION=%%a.%%b
SET "VIRTUALENV=venv"
SET "TARGET_DIR=%WD%\dist"
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_MAJOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\config.py') DO SET APP_MINOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\config.py') DO SET APP_VERSION_SUFFIX=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_RELEASE =" %WD%\web\config.py') DO SET APP_MAJOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_REVISION =" %WD%\web\config.py') DO SET APP_MINOR=%%a
FOR /F "tokens=3" %%a IN ('findstr /C:"APP_SUFFIX =" %WD%\web\config.py') DO SET APP_VERSION_SUFFIX=%%a
REM remove single quote from the string
SET APP_VERSION_SUFFIX=%APP_VERSION_SUFFIX:'=%
SET APP_NAME=""
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a
FOR /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "print('%APP_NAME%'.lower().replace(' ', ''))"') DO SET APP_SHORTNAME=%%G
FOR /F "tokens=2* DELims='" %%a IN ('findstr /C:"APP_NAME =" web\config.py') DO SET APP_NAME=%%a
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "print('%APP_NAME%'.lower().replace(' ', ''))"') DO SET APP_SHORTNAME=%%G
SET APP_VERSION=%APP_MAJOR%.%APP_MINOR%
SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%APP_VERSION_SUFFIX%-%ARCHITECTURE%.exe
IF "%APP_VERSION_SUFFIX%" == "" SET INSTALLERNAME=%APP_SHORTNAME%-%APP_MAJOR%.%APP_MINOR%-%ARCHITECTURE%.exe
REM get Python version for the runtime build ex. 2.7.1 will be 27
FOR /f "tokens=1 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
FOR /f "tokens=2 DELims=." %%G IN ('%PYTHON_HOME%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MINOR=%%G
FOR /f "tokens=1 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MAJOR=%%G
FOR /f "tokens=2 DELims=." %%G IN ('%PGADMIN_PYTHON_DIR%/python.exe -c "import sys; print(sys.version.split(' ')[0])"') DO SET PYTHON_MINOR=%%G
SET "PYTHON_VERSION=%PYTHON_MAJOR%%PYTHON_MINOR%"
EXIT /B 0
@@ -91,32 +86,24 @@ REM Main build sequence Ends
:VALIDATE_ENVIRONMENT
ECHO ****************************************************************
ECHO S U M M A R Y
ECHO * Build summary
ECHO ****************************************************************
ECHO Build path: %PGBUILDPATH%
ECHO Output directory: %TARGET_DIR%
ECHO Build path: %BUILDROOT%
ECHO Output directory: %DISTROOT%
ECHO Installer name: %INSTALLERNAME%
ECHO.
ECHO Python home: %PYTHON_HOME%
ECHO Python DLL: %PYTHON_DLL%
ECHO Python version: %PYTHON_VERSION%
ECHO Python major version: %PYTHON_MAJOR%
ECHO Python minor version: %PYTHON_MINOR%
ECHO Python directory: %PGADMIN_PYTHON_DIR%
ECHO Python DLL: %PGADMIN_PYTHON_DIR%\Python%PYTHON_VERSION%.dll
ECHO Python version: %PYTHON_MAJOR%.%PYTHON_MINOR%
ECHO.
ECHO Qt home: %QTDIR%
ECHO qmake executable: %QMAKE%
ECHO Qt version: %QT_VERSION%
ECHO Qt directory: %PGADMIN_QT_DIR%
ECHO PostgreSQL directory: %PGADMIN_POSTGRES_DIR%
ECHO.
ECHO PostgreSQL home: %PGDIR%
ECHO VC++ redist directory: %PGADMIN_VCREDIST_DIR%
ECHO VC++ redist file: %VCREDIST_FILE%
ECHO InnoTool directory: %PGADMIN_INNOTOOL_DIR%
ECHO signtool directory: %PGADMIN_SIGNTOOL_DIR%
ECHO.
ECHO VC++ redistributable: %VCREDIST%
ECHO VC++ redistributable file: %VCREDISTNAME%
ECHO.
ECHO innotool executable: %INNOTOOL%
ECHO signtool executable: %SIGNTOOL%
ECHO.
ECHO App major version: %APP_MAJOR%
ECHO App minor version: %APP_MINOR%
ECHO App version: %APP_VERSION%
ECHO App version suffix: %APP_VERSION_SUFFIX%
ECHO App short name: %APP_SHORTNAME%
@@ -124,88 +111,87 @@ REM Main build sequence Ends
ECHO ****************************************************************
ECHO Checking the environment...
IF NOT EXIST "%INNOTOOL%" (
ECHO !INNOTOOL! does not exist
ECHO Please install Innotool and set the INNOTOOL environment variable.
IF NOT EXIST "%PGADMIN_INNOTOOL_DIR%" (
ECHO !PGADMIN_INNOTOOL_DIR! does not exist
ECHO Please install InnoTool and set the PGADMIN_INNOTOOL_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%VCREDIST%" (
ECHO !VCREDIST! does not exist
ECHO Please install Microsoft Visual studio and set the VCREDIST environment variable.
IF NOT EXIST "%PGADMIN_VCREDIST_DIR%" (
ECHO !PGADMIN_VCREDIST_DIR! does not exist
ECHO Please install Microsoft Visual studio and set the PGADMIN_VCREDIST_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%QTDIR%" (
ECHO !QTDIR! does not exist.
ECHO Please install Qt and set the QTDIR environment variable.
IF NOT EXIST "%PGADMIN_QT_DIR%" (
ECHO !PGADMIN_QT_DIR! does not exist.
ECHO Please install Qt and set the PGADMIN_QT_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%QMAKE%" (
IF NOT EXIST "%PGADMIN_QT_DIR%\bin\qmake.exe" (
ECHO !QMAKE! does not exist.
ECHO Please install Qt and set the QTDIR environment variable.
ECHO Please install Qt and set the PGADMIN_QT_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PYTHON_HOME%" (
ECHO !PYTHON_HOME! does not exist.
ECHO Please install Python and set the PYTHON_HOME environment variable.
IF NOT EXIST "%PGADMIN_PYTHON_DIR%" (
ECHO !PGADMIN_PYTHON_DIR! does not exist.
ECHO Please install Python and set the PGADMIN_PYTHON_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PYTHON_DLL%" (
ECHO !PYTHON_DLL! does not exist.
ECHO Please install Python and set the PYTHON_DLL environment variable.
IF NOT EXIST "%PGADMIN_PYTHON_DIR%\Python%PYTHON_VERSION%.dll" (
ECHO !PGADMIN_PYTHON_DIR!\Python!PYTHON_VERSION!.dll does not exist.
ECHO Please check your Python installation is complete.
EXIT /B 1
)
IF NOT EXIST "%PGDIR%" (
ECHO !PGDIR! does not exist.
ECHO Please install PostgreSQL and set the PGDIR environment variable.
IF NOT EXIST "%PGADMIN_POSTGRES_DIR%" (
ECHO !PGADMIN_POSTGRES_DIR! does not exist.
ECHO Please install PostgreSQL and set the PGADMIN_POSTGRES_DIR environment variable.
EXIT /B 1
)
IF NOT EXIST "%PYTHON_HOME%\Scripts\virtualenv.exe" (
ECHO !PYTHON_HOME!\Scripts\virtualenv.exe does not exist.
IF NOT EXIST "%PGADMIN_PYTHON_DIR%\Scripts\virtualenv.exe" (
ECHO !PGADMIN_PYTHON_DIR!\Scripts\virtualenv.exe does not exist.
ECHO Please install the virtualenv package in Python.
EXIT /B 1
)
SET "PATH=%PGDIR%\bin;%PATH%"
SET "PATH=%PGADMIN_POSTGRES_DIR%\bin;%PATH%"
EXIT /B 0
:CREATE_VIRTUAL_ENV
ECHO Creating virtual environment...
IF NOT EXIST "%PGBUILDPATH%" MKDIR "%PGBUILDPATH%"
IF NOT EXIST "%BUILDROOT%" MKDIR "%BUILDROOT%"
CD "%PGBUILDPATH%"
"%PYTHON_HOME%\Scripts\virtualenv.exe" "%VIRTUALENV%"
CD "%BUILDROOT%"
XCOPY /S /I /E /H /Y "%PYTHON_HOME%\DLLs" "%PGBUILDPATH%\%VIRTUALENV%\DLLs" > nul || EXIT /B 1
XCOPY /S /I /E /H /Y "%PYTHON_HOME%\Lib" "%PGBUILDPATH%\%VIRTUALENV%\Lib" > nul || EXIT /B 1
REM Note that we must use virtualenv.exe here, as the venv module doesn't allow python.exe to relocate.
"%PGADMIN_PYTHON_DIR%\Scripts\virtualenv.exe" venv
ECHO Activating virtual environment - %PGBUILDPATH%\%VIRTUALENV%...
CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\activate" || EXIT /B 1
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\DLLs" "%BUILDROOT%\venv\DLLs" > nul || EXIT /B 1
XCOPY /S /I /E /H /Y "%PGADMIN_PYTHON_DIR%\Lib" "%BUILDROOT%\venv\Lib" > nul || EXIT /B 1
ECHO Activating virtual environment - %BUILDROOT%\venv...
CALL "%BUILDROOT%\venv\Scripts\activate" || EXIT /B 1
ECHO Installing dependencies...
CALL pip install -r "%WD%\requirements.txt" || EXIT /B 1
CALL pip install sphinx || EXIT /B 1
REM If we're using VC++, and this is Python 3.6+, we need to remove the hack
REM above or it will break qmake. Sigh.
IF "%MAKE%" == "nmake" (
IF %PYTHON_VERSION% GEQ 36 SET CL=
)
REM If this is Python 3.6+, we need to remove the hack above or it will break qmake. Sigh.
IF %PYTHON_VERSION% GEQ 36 SET CL=
CD %WD%
EXIT /B 0
:CREATE_RUNTIME_ENV
MKDIR "%PGBUILDPATH%\runtime"
MKDIR "%BUILDROOT%\runtime"
CD "%WD%\web"
@@ -219,33 +205,37 @@ REM Main build sequence Ends
RD /Q /S "%WD%\web\pgadmin\static\js\generated\.cache" 1> nul 2>&1
ECHO Copying web directory...
XCOPY /S /I /E /H /Y "%WD%\web" "%PGBUILDPATH%\web" > nul || EXIT /B 1
XCOPY /S /I /E /H /Y "%WD%\web" "%BUILDROOT%\web" > nul || EXIT /B 1
ECHO Cleaning up unnecessary .pyc and .pyo files...
FOR /R "%PGBUILDPATH%\web" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
FOR /R "%BUILDROOT%\web" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
ECHO Removing tests, Python caches and node modules...
FOR /R "%PGBUILDPATH%\web" %%f in (tests feature_tests __pycache__ node_modules) do RD /Q /S "%%f" 1> nul 2>&1
FOR /R "%BUILDROOT%\web" %%f in (tests feature_tests __pycache__ node_modules) do RD /Q /S "%%f" 1> nul 2>&1
ECHO Removing the test framework...
RD /Q /S "%PGBUILDPATH%\web\regression" 1> nul 2>&1
RD /Q /S "%BUILDROOT%\web\regression" 1> nul 2>&1
ECHO Removing tools...
RD /Q /S "%PGBUILDPATH%\web\tools" 1> nul 2>&1
RD /Q /S "%BUILDROOT%\web\tools" 1> nul 2>&1
ECHO Removing any existing configurations...
DEL /q "%PGBUILDPATH%\web\pgadmin4.db" 1> nul 2>&1
DEL /q "%PGBUILDPATH%\web\config_local.py" 1> nul 2>&1
DEL /q "%BUILDROOT%\web\pgadmin4.db" 1> nul 2>&1
DEL /q "%BUILDROOT%\web\config_local.py" 1> nul 2>&1
ECHO Staging license files...
COPY "%WD%\LICENSE" "%BUILDROOT%\" > nul || EXIT /B 1
COPY "%WD%\DEPENDENCIES" "%BUILDROOT%\" > nul || EXIT /B 1
ECHO Creating config_distro.py
ECHO SERVER_MODE = False > "%PGBUILDPATH%\web\config_distro.py"
ECHO HELP_PATH = '../../../docs/en_US/html/' >> "%PGBUILDPATH%\web\config_distro.py"
ECHO DEFAULT_BINARY_PATHS = { >> "%PGBUILDPATH%\web\config_distro.py"
ECHO 'pg': '$DIR/../runtime', >> "%PGBUILDPATH%\web\config_distro.py"
ECHO 'ppas': '' >> "%PGBUILDPATH%\web\config_distro.py"
ECHO } >> "%PGBUILDPATH%\web\config_distro.py"
ECHO SERVER_MODE = False > "%BUILDROOT%\web\config_distro.py"
ECHO HELP_PATH = '../../../docs/en_US/html/' >> "%BUILDROOT%\web\config_distro.py"
ECHO DEFAULT_BINARY_PATHS = { >> "%BUILDROOT%\web\config_distro.py"
ECHO 'pg': '$DIR/../runtime', >> "%BUILDROOT%\web\config_distro.py"
ECHO 'ppas': '' >> "%BUILDROOT%\web\config_distro.py"
ECHO } >> "%BUILDROOT%\web\config_distro.py"
ECHO Building docs...
MKDIR "%PGBUILDPATH%\docs\en_US\html"
MKDIR "%BUILDROOT%\docs\en_US\html"
CD "%WD%\docs\en_US"
CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\python.exe" build_code_snippet.py || EXIT /B 1
CALL "%PGBUILDPATH%\%VIRTUALENV%\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%PGBUILDPATH%\docs\en_US\html" || EXIT /B 1
CALL "%BUILDROOT%\venv\Scripts\python.exe" build_code_snippet.py || EXIT /B 1
CALL "%BUILDROOT%\venv\Scripts\sphinx-build.exe" "%WD%\docs\en_US" "%BUILDROOT%\docs\en_US\html" || EXIT /B 1
ECHO Removing Sphinx
CALL pip uninstall -y sphinx Pygments alabaster colorama docutils imagesize requests snowballstemmer
@@ -254,56 +244,50 @@ REM Main build sequence Ends
CD "%WD%\runtime"
ECHO Running qmake...
CALL "%QMAKE%" || EXIT /B 1
CALL set "PGADMIN_PYTHON_DIR=%PGADMIN_PYTHON_DIR%" && "%PGADMIN_QT_DIR%\bin\qmake.exe" || EXIT /B 1
ECHO Cleaning the build directory...
CALL %MAKE% clean || EXIT /B 1
CALL nmake clean || EXIT /B 1
ECHO Running make...
CALL %MAKE% || EXIT /B 1
CALL nmake || EXIT /B 1
ECHO Staging pgAdmin4.exe...
COPY "%WD%\runtime\release\pgAdmin4.exe" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%WD%\runtime\release\pgAdmin4.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
ECHO Staging Qt components...
COPY "%QTDIR%\bin\Qt5Core.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%QTDIR%\bin\Qt5Gui.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%QTDIR%\bin\Qt5Widgets.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%QTDIR%\bin\Qt5Network.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%QTDIR%\bin\Qt5Svg.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%QTDIR%\bin\libgcc_s_dw2-1.dll" COPY "%QTDIR%\bin\libgcc_s_dw2-1.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%QTDIR%\bin\libstdc++-6.dll" COPY "%QTDIR%\bin\libstdc++-6.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%QTDIR%\bin\libwinpthread-1.dll" COPY "%QTDIR%\bin\libwinpthread-1.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
MKDIR "%PGBUILDPATH%\runtime\platforms" > nul || EXIT /B 1
COPY "%QTDIR%\plugins\platforms\qwindows.dll" "%PGBUILDPATH%\runtime\platforms" > nul || EXIT /B 1
MKDIR "%PGBUILDPATH%\runtime\imageformats" > nul || EXIT /B 1
COPY "%QTDIR%\plugins\imageformats\qsvg.dll" "%PGBUILDPATH%\runtime\imageformats" > nul || EXIT /B 1
ECHO [Paths] > "%PGBUILDPATH%\runtime\qt.conf"
ECHO Plugins=plugins >> "%PGBUILDPATH%\runtime\qt.conf"
COPY "%PGADMIN_QT_DIR%\bin\Qt5Core.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_QT_DIR%\bin\Qt5Gui.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_QT_DIR%\bin\Qt5Widgets.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_QT_DIR%\bin\Qt5Network.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_QT_DIR%\bin\Qt5Svg.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
MKDIR "%BUILDROOT%\runtime\platforms" > nul || EXIT /B 1
COPY "%PGADMIN_QT_DIR%\plugins\platforms\qwindows.dll" "%BUILDROOT%\runtime\platforms" > nul || EXIT /B 1
MKDIR "%BUILDROOT%\runtime\imageformats" > nul || EXIT /B 1
COPY "%PGADMIN_QT_DIR%\plugins\imageformats\qsvg.dll" "%BUILDROOT%\runtime\imageformats" > nul || EXIT /B 1
ECHO [Paths] > "%BUILDROOT%\runtime\qt.conf"
ECHO Plugins=plugins >> "%BUILDROOT%\runtime\qt.conf"
ECHO Staging PostgreSQL components...
COPY "%PGDIR%\bin\libpq.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%PGDIR%\bin\libcrypto-1_1.dll" (
REM OpenSSL 1.1.1
COPY "%PGDIR%\bin\libcrypto-1_1.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGDIR%\bin\libssl-1_1.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\libpq.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
IF "%ARCHITECTURE%" == "x64" (
COPY "%PGADMIN_POSTGRES_DIR%\bin\libcrypto-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\libssl-1_1-x64.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
) ELSE (
REM OpenSSL 1.0.2
COPY "%PGDIR%\bin\ssleay32.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGDIR%\bin\libeay32.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\libcrypto-1_1.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\libssl-1_1.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
)
IF EXIST "%PGDIR%\bin\libintl-*.dll" COPY "%PGDIR%\bin\libintl-*.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%PGDIR%\bin\libiconv-*.dll" COPY "%PGDIR%\bin\libiconv-*.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%PGDIR%\bin\zlib.dll" COPY "%PGDIR%\bin\zlib.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%PGDIR%\bin\zlib1.dll" COPY "%PGDIR%\bin\zlib1.dll" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGDIR%\bin\pg_dump.exe" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGDIR%\bin\pg_dumpall.exe" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1L%
COPY "%PGDIR%\bin\pg_restore.exe" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY "%PGDIR%\bin\psql.exe" "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
IF EXIST "%PGADMIN_POSTGRES_DIR%\bin\libintl-*.dll" COPY "%PGADMIN_POSTGRES_DIR%\bin\libintl-*.dll" "%BUILDROOT%\runtime" > nul
IF EXIST "%PGADMIN_POSTGRES_DIR%\bin\libiconv-*.dll" COPY "%PGADMIN_POSTGRES_DIR%\bin\libiconv-*.dll" "%BUILDROOT%\runtime" > nul
COPY "%PGADMIN_POSTGRES_DIR%\bin\zlib.dll" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\pg_dump.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\pg_dumpall.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1L%
COPY "%PGADMIN_POSTGRES_DIR%\bin\pg_restore.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY "%PGADMIN_POSTGRES_DIR%\bin\psql.exe" "%BUILDROOT%\runtime" > nul || EXIT /B 1
ECHO Staging VC++ runtime...
MKDIR "%PGBUILDPATH%\installer" || EXIT /B 1
COPY "%VCREDIST%" "%PGBUILDPATH%\installer" > nul || EXIT /B 1
MKDIR "%BUILDROOT%\installer" || EXIT /B 1
COPY "%PGADMIN_VCREDIST_DIR%\%VCREDIST_FILE%" "%BUILDROOT%\installer" > nul || EXIT /B 1
CD %WD%
EXIT /B 0
@@ -311,51 +295,51 @@ REM Main build sequence Ends
:CREATE_PYTHON_ENV
ECHO Staging Python...
COPY %PYTHON_DLL% "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY %PYTHON_HOME%\python.exe "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY %PYTHON_HOME%\pythonw.exe "%PGBUILDPATH%\runtime" > nul || EXIT /B 1
COPY %PGADMIN_PYTHON_DIR%\python%PYTHON_VERSION%.dll "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY %PGADMIN_PYTHON_DIR%\python.exe "%BUILDROOT%\runtime" > nul || EXIT /B 1
COPY %PGADMIN_PYTHON_DIR%\pythonw.exe "%BUILDROOT%\runtime" > nul || EXIT /B 1
ECHO Cleaning up unnecessary .pyc and .pyo files...
FOR /R "%PGBUILDPATH%\%VIRTUALENV%" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
FOR /R "%BUILDROOT%\venv" %%f in (*.pyc *.pyo) do DEL /q "%%f" 1> nul 2>&1
ECHO Removing tests...
FOR /R "%PGBUILDPATH%\%VIRTUALENV%\Lib" %%f in (test tests) do RD /Q /S "%%f" 1> nul 2>&1
FOR /R "%BUILDROOT%\venv\Lib" %%f in (test tests) do RD /Q /S "%%f" 1> nul 2>&1
ECHO Removing TCL...
RD /Q /S "%PGBUILDPATH%\%VIRTUALENV%\tcl" 1> nul 2>&1
RD /Q /S "%BUILDROOT%\venv\tcl" 1> nul 2>&1
EXIT /B 0
:CREATE_INSTALLER
ECHO Preparing for creation of windows installer...
IF NOT EXIST "%TARGET_DIR%" MKDIR "%TARGET_DIR%"
IF NOT EXIST "%DISTROOT%" MKDIR "%DISTROOT%"
ECHO Copying icon file...
COPY "%WD%\pkg\win32\Resources\pgAdmin4.ico" "%PGBUILDPATH%" > nul || EXIT /B 1
COPY "%WD%\pkg\win32\Resources\pgAdmin4.ico" "%BUILDROOT%" > nul || EXIT /B 1
CD "%WD%\pkg\win32"
ECHO Processing installer configuration script...
CALL "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in" "-o" "%WD%\pkg\win32\installer.iss.in_stage1" "-s" MYAPP_NAME -r """%APP_NAME%"""
CALL "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage1" "-o" "%WD%\pkg\win32\installer.iss.in_stage2" "-s" MYAPP_FULLVERSION -r """%APP_VERSION%"""
CALL "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage2" "-o" "%WD%\pkg\win32\installer.iss.in_stage3" "-s" MYAPP_VERSION -r """v%APP_MAJOR%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in" "-o" "%WD%\pkg\win32\installer.iss.in_stage1" "-s" MYAPP_NAME -r """%APP_NAME%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage1" "-o" "%WD%\pkg\win32\installer.iss.in_stage2" "-s" MYAPP_FULLVERSION -r """%APP_VERSION%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage2" "-o" "%WD%\pkg\win32\installer.iss.in_stage3" "-s" MYAPP_VERSION -r """v%APP_MAJOR%"""
SET ARCMODE=
IF "%ARCHITECTURE%"=="amd64" (
IF "%ARCHITECTURE%" == "x64" (
set ARCMODE="x64"
)
CALL "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage3" "-o" "%WD%\pkg\win32\installer.iss.in_stage4" "-s" MYAPP_ARCHITECTURESMODE -r """%ARCMODE%"""
CALL "%PYTHON_HOME%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage4" "-o" "%WD%\pkg\win32\installer.iss" "-s" MYAPP_VCDIST -r """%VCREDISTNAME%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage3" "-o" "%WD%\pkg\win32\installer.iss.in_stage4" "-s" MYAPP_ARCHITECTURESMODE -r """%ARCMODE%"""
CALL "%PGADMIN_PYTHON_DIR%\python" "%WD%\pkg\win32\replace.py" "-i" "%WD%\pkg\win32\installer.iss.in_stage4" "-o" "%WD%\pkg\win32\installer.iss" "-s" MYAPP_VCDIST -r """%PGADMIN_VCREDIST_DIRNAME%\%VCREDIST_FILE%"""
ECHO Cleaning up...
DEL /s "%WD%\pkg\win32\installer.iss.in_stage*" > nul
ECHO Creating windows installer using INNO tool...
CALL "%INNOTOOL%\ISCC.exe" /q "%WD%\pkg\win32\installer.iss" || EXIT /B 1
CALL "%PGADMIN_INNOTOOL_DIR%\ISCC.exe" /q "%WD%\pkg\win32\installer.iss" || EXIT /B 1
ECHO Renaming installer...
MOVE "%WD%\pkg\win32\Output\Setup.exe" "%TARGET_DIR%\%INSTALLERNAME%" > nul || EXIT /B 1
MOVE "%WD%\pkg\win32\Output\Setup.exe" "%DISTROOT%\%INSTALLERNAME%" > nul || EXIT /B 1
ECHO Location - %TARGET_DIR%\%INSTALLERNAME%
ECHO Location - %DISTROOT%\%INSTALLERNAME%
ECHO Installer generated successfully.
CD %WD%
@@ -364,7 +348,7 @@ REM Main build sequence Ends
:SIGN_INSTALLER
ECHO Attempting to sign the installer...
CALL "%SIGNTOOL%" sign /t http://timestamp.verisign.com/scripts/timstamp.dll "%TARGET_DIR%\%INSTALLERNAME%"
CALL "%PGADMIN_SIGNTOOL_DIR%\signtool.exe" sign /t http://timestamp.verisign.com/scripts/timstamp.dll "%DISTROOT%\%INSTALLERNAME%"
IF %ERRORLEVEL% NEQ 0 (
ECHO.
ECHO ************************************************************
@@ -378,15 +362,15 @@ REM Main build sequence Ends
:CLEANUP_ENV
ECHO Cleaning the build environment...
RD "%PGBUILDPATH%\%VIRTUALENV%\Include" /S /Q 1> nul 2>&1
DEL /s "%PGBUILDPATH%\%VIRTUALENV%\pip-selfcheck.json" 1> nul 2>&1
RD "%BUILDROOT%\venv\Include" /S /Q 1> nul 2>&1
DEL /s "%BUILDROOT%\venv\pip-selfcheck.json" 1> nul 2>&1
EXIT /B 0
:USAGE
ECHO Invalid command line options.
ECHO Usage: "Make.bat <x86 | clean>"
ECHO Usage: "Make.bat [clean]"
ECHO.
EXIT /B 1
+6 -5
View File
@@ -28,12 +28,10 @@ install-node:
cd web && npm audit fix
rm -f web/yarn.lock
cd web && yarn import
# Commented the below line to avoid vulnerability in decompress package and
# audit only dependencies folder. Refer https://www.npmjs.com/advisories/1217.
# Pull request is already been send https://github.com/kevva/decompress/pull/73,
# once fixed we will uncomment it.
# Commented the below line to avoid vulnerability in lodash package.
# Refer https://www.npmjs.com/advisories/1523.
# Once fixed we will uncomment it.
# cd web && yarn audit
cd web && yarn audit --groups dependencies
rm -f package-lock.json
rm -f web/package-lock.json
@@ -84,6 +82,9 @@ check-feature: install-node bundle
check-js: install-node linter
cd web && yarn run karma start --single-run
check-js-coverage:
cd web && yarn run test:karma-coverage
runtime-debug:
cd runtime && qmake CONFIG+=debug && make
+40 -85
View File
@@ -1,4 +1,4 @@
pgAdmin 4
pgAdmin 4
=========
pgAdmin 4 is a rewrite of the popular pgAdmin3 management tool for the
@@ -26,42 +26,46 @@ Building the Runtime
To build the runtime, the following packages must be installed:
- QT 4.6 or above (Use the VC++ build on Windows, not MinGW).
- Python 2.7 or 3.4+
- QT 5 (Use the VC++ build on Windows, not MinGW).
- Python 3.4+
Assuming both qmake and python-config are in the path:
An environment variable named PGADMIN_PYTHON_DIR must be set to the directory
in which Python has been installed, for example:
$ cd $PGADMIN4_SRC/runtime
$ qmake
Project MESSAGE: Building for QT5+...
Project MESSAGE: Building for Linux/Mac...
Project MESSAGE: Using /usr/bin/python-config
Project MESSAGE: Python2 detected.
$ make
...
- /usr
- /usr/local/python-3.8
- C:\Python38
To build the runtime in debug mode, use the option below with qmake
Assuming both qmake is in the path:
dpage@hal:~/git/pgadmin4$ cd runtime
dpage@hal:~/git/pgadmin4/runtime$ export PGADMIN_PYTHON_DIR=/opt/local
dpage@hal:~/git/pgadmin4/runtime$ qmake
Project MESSAGE: ==================================
Project MESSAGE: Configuring the pgAdmin 4 runtime.
Project MESSAGE: ==================================
Project MESSAGE: Qt version: 5
Project MESSAGE: Platform: macOS
Project MESSAGE: Python executable: /opt/local/bin/python3
Project MESSAGE: Python version: 3.8 (38)
Project MESSAGE: Python config: /opt/local/bin/python3-config
Project MESSAGE: CXXFLAGS: -pipe -stdlib=libc++ -I/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8 -I/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8
Project MESSAGE: LDFLAGS: -stdlib=libc++ -L/opt/local/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/config-3.8-darwin -ldl -framework CoreFoundation
Project MESSAGE: LIBS: -lpython3.8 -ldl -framework CoreFoundation
dpage@hal:~/git/pgadmin4/runtime$ make
...
To build the runtime in debug mode, use the option below with qmake:
$ qmake CONFIG+=debug
To build the runtime in release mode, use the option below with qmake
To build the runtime in release mode, use the option below with qmake:
$ qmake CONFIG+=release
By default, the runtime application will be built in release mode.
On Linux, an executable called 'pgAdmin4' will be built, and on Mac OS X, an
app bundle called pgAdmin4.app will be created.
To build the runtime on a Windows system, export PYTHON_HOME and PYTHON_VERSION
variables in the System environment. Specify the PYTHON_VERSION with the major
and minor number. Do not specify micro level version.
For example, given a Python version of A.B.C; A - Major number, B - Minor
number, C - Micro level (Bug fix releases).
If Python version is 2.7.12 than specify PYTHON_VERSION=27
e.g. PYTHON_HOME=C:\Python27\
PYTHON_VERSION=27
On Linux, an executable called 'pgAdmin4' will be built, on Windows,
'pgAdmin4.exe', and on Mac OS X, an app bundle called pgAdmin4.app will be
created.
You can also use Qt Creator to build, develop and debug the runtime. Simply
open the $PGADMIN4_SRC/runtime/pgAdmin4.pro project file in Qt Creator and
@@ -88,10 +92,10 @@ Configuring the Python Environment
----------------------------------
In order to run the Python code, a suitable runtime environment is required.
Python versions - Python 2.7 or 3.4+ are currently supported. It is
recommended that a Python Virtual Environment is setup for this purpose,
rather than using the system Python environment. On Linux and Mac systems, the
process is fairly simple - adapt as required for your distribution:
Python version 3.4 and later are currently supported. It is recommended that a
Python Virtual Environment is setup for this purpose, rather than using the
system Python environment. On Linux and Mac systems, the process is fairly
simple - adapt as required for your distribution:
1) Install the virtualenv packages into the system Python environment
@@ -181,16 +185,7 @@ server or desktop mode, and access it from a web browser using the URL shown in
the terminal once pgAdmin has started up.
Setup of an environment on Windows is somewhat more complicated unfortunately,
largely due to the lack of a native compiler toolset. Thankfully, Microsoft
supply a free compiler specifically for Python 2.7 users. Download and install
it from:
https://www.microsoft.com/en-gb/download/details.aspx?id=44266
A blog detailing the setup of Virtual Environments on Windows can be found
here:
http://www.tylerbutler.com/2012/05/how-to-install-python-pip-and-virtualenv-on-windows-with-powershell/
please see pkg/win32/README.txt for complete details.
Once a virtual environment has been created and enabled, setup can continue
from step 4 above.
@@ -252,7 +247,7 @@ icon and select the Configuration option to open the configuration dialogue.
On a Linux/Mac system, the Python Path will typically consist of a single path
to the virtual environment's site-packages directory, e.g.
/Users/<USERNAME>/.virtualenvs/pgadmin4/lib/python2.7/site-packages
/Users/<USERNAME>/.virtualenvs/pgadmin4/lib/python3.8/site-packages
On Windows, multiple paths are likely to be required, e.g.
@@ -294,49 +289,9 @@ run:
(pgadmin4) $ make pip
On a Mac, build an application bundle in a disk image (DMG file) with:
To build the macOS AppBundle, please see pkg/mac/README.
(pgadmin4) $ make appbundle
Configure the framework.conf to match the QT and Python versions the app is
being built with:
$ cp $PGADMIN4_SRC/pkg/mac/framework.conf.in $PGADMIN4_SRC/pkg/mac/framework.conf
$ vi $PGADMIN4_SRC/pkg/mac/framework.conf
If you have an Apple code signing certificate, both the app bundle and disk
image can be automatically signed by configuring signing:
$ cp $PGADMIN4_SRC/pkg/mac/codesign.conf.in $PGADMIN4_SRC/pkg/mac/codesign.conf
$ vi $PGADMIN4_SRC/pkg/mac/codesign.conf
Edit the file as appropriate, ensuring the various version numbers are correct
and that the appropriate developer ID is specified.
On Windows, the InnoSetup tool is required to create an installer. Download the
Unicode version from:
http://www.jrsoftware.org/isdl.php
A number of environment variables may need to be set to enable the build script
to function. The defaults will usually work on a typical 64 bit system with
Qt 5.5.1, Python 2.7 and Visual Studio 2013. The examples below are for a
similar 32 bit system:
INNOTOOL=C:\Program Files\Inno Setup 5
PGDIR=C:\Program Files\PostgreSQL\10
PYTHON_DLL=C:\Windows\System32\Python27.dll
PYTHON_HOME=C:\Python27
PYTHON_VERSION=27
QTDIR=C:\Qt\5.9\msvc2013
VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC
To build the installer:
C:\$PGADMIN4_SRC> make x86
If you have a code signing certificate, this will automatically be used if
found in the Windows Certificate Store to sign the installer.
To build the Windows installer, please see pkg/win32/README.txt.
Support
-------
+2 -6
View File
@@ -1,11 +1,7 @@
import os
import sys
import inspect
if sys.version_info[0] >= 3:
import builtins
else:
import __builtin__ as builtins
import builtins
# Ensure the global server mode is set.
builtins.SERVER_MODE = None
@@ -63,7 +59,7 @@ def print_code(outstream, name, module, info=None):
print_code(
target, "PgAdminModule", PgAdminModule,
"""
PgAdminModule is inherted from Flask.Blueprint module.
PgAdminModule is inherited from Flask.Blueprint module.
This module defines a set of methods, properties and attributes,
that every module should implement.
""")
+6 -5
View File
@@ -29,9 +29,10 @@ Configuration
The core application configuration is found in **config.py**. This file includes
all configurable settings for the application, along with descriptions of their
use. It is essential that various settings are configured prior to deployent on
a web server; these can be overriden in **config_local.py** to avoid modifying
the main configuration file.
use. It is essential that various settings are configured prior to deployment on
a web server; these can be overridden in **config_local.py** or
**config_system.py** (see the :ref:`config.py <config_py>` documentation) to
avoid modifying the main configuration file.
User Settings
=============
@@ -108,7 +109,7 @@ PgAdminModule class. This is responsible for providing hook points to integrate
the module into the rest of the application - for example, a hook might tell
the caller what CSS files need to be included on the rendered page, or what menu
options to include and what they should do. Hook points need not exist if they
are not required. It is the responsiblity of the caller to ensure they are
are not required. It is the responsibility of the caller to ensure they are
present before attempting to utilise them.
Hooks currently implemented are:
@@ -210,6 +211,6 @@ bootstrap for UI look and feel, Backbone for data manipulation of a node,
Backform for generating properties/create dialog for selected node. We have
divided each module in small chunks as much as possible. Not all javascript
modules are required to be loaded (i.e. loading a javascript module for
database will make sense only when a server node is loaded competely.) Please
database will make sense only when a server node is loaded completely.) Please
look at the the javascript files node.js, browser.js, menu.js, panel.js, etc for
better understanding of the code.
+5 -9
View File
@@ -14,11 +14,7 @@
import os
import sys
if sys.version_info[0] >= 3:
import builtins
else:
import __builtin__ as builtins
import builtins
# Ensure the global server mode is set.
builtins.SERVER_MODE = None
@@ -212,8 +208,8 @@ htmlhelp_basename = 'pgadmin4'
# (source start file, target name, title, author, documentclass
# [howto/manual]).
latex_documents = [
('index', 'pgadmin4.tex', u'pgAdmin 4 Documentation',
u'The pgAdmin Development Team', 'manual'),
('index', 'pgadmin4.tex', 'pgAdmin 4 Documentation',
'The pgAdmin Development Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -251,6 +247,6 @@ latex_elements = {
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
('index', 'pgadmin4', u'pgAdmin 4 Documentation',
[u'The pgAdmin Development Team'], 1)
('index', 'pgadmin4', 'pgAdmin 4 Documentation',
['The pgAdmin Development Team'], 1)
]
+15 -4
View File
@@ -23,10 +23,21 @@ are as follows:
and may be created by users in the same directory as ``config.py`` if
needed.
.. note:: If the SERVER_MODE setting is changed in ``config_distro.py`` or ``config_local.py``,
you will most likely need to re-set the LOG_FILE, SQLITE_PATH, SESSION_DB_PATH
and STORAGE_DIR values as well as they will have been set based on the default
configuration or overridden by the runtime.
* ``config_system.py``: This file is read after ``config_local.py`` and is
intended for system administrators to include settings that are configured
system-wide from a secure location that users cannot normally modify and that
is outside of the pgAdmin installation. The location for this file varies
based on the platform, and only needs to be created if desired:
* Linux: ``/etc/pgadmin/config_system.py``
* macOS: ``/Library/Preferences/pgadmin/config_system.py``
* Windows: ``%CommonProgramFiles%\pgadmin\config_system.py``
.. note:: If the SERVER_MODE setting is changed in ``config_distro.py``,
``config_local.py``, or ``config_system.py`` you will most likely need to
re-set the LOG_FILE, SQLITE_PATH, SESSION_DB_PATH and STORAGE_DIR values
as well as they will have been set based on the default configuration or
overridden by the runtime.
The default ``config.py`` file is shown below for reference:
+3 -4
View File
@@ -17,7 +17,6 @@ maintenance functions to be executed. Multiple versions are included in the
following directories to allow use with different versions of the database
server:
* PostgreSQL 9.4: */usr/local/pgsql-9.4*
* PostgreSQL 9.5: */usr/local/pgsql-9.5*
* PostgreSQL 9.6: */usr/local/pgsql-9.6*
* PostgreSQL 10: */usr/local/pgsql-10*
@@ -52,7 +51,7 @@ connections.
When TLS is enabled, a certificate and key must be provided. Typically these
should be stored on the host file system and mounted from the container. The
expected paths are /certs/server.crt and /certs/server.key
expected paths are /certs/server.cert and /certs/server.key
**PGADMIN_LISTEN_ADDRESS**
@@ -60,7 +59,7 @@ expected paths are /certs/server.crt and /certs/server.key
Specify the local address that the servers listens on. The default should work
for most users - in IPv4-only environments, this may need to be set to
127.0.0.1.
0.0.0.0.
**PGADMIN_LISTEN_PORT**
@@ -319,7 +318,7 @@ adjusted as appropriate to the specific deployment:
listen 443;
server_name _;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate /etc/nginx/server.cert;
ssl_certificate_key /etc/nginx/server.key;
ssl on;
+13
View File
@@ -97,6 +97,19 @@ Follow these steps to add additional parameter value definitions; to discard a
parameter, click the trash icon to the left of the row and confirm deletion in
the *Delete Row* popup.
Click the *Advanced* tab to continue.
.. image:: images/database_advanced.png
:alt: Database dialog advanced tab
:align: center
Use the *Advanced* tab to set advanced parameters for the database.
* Use *Schema restriction* field to provide a SQL restriction that will be used
against the pg_namespace table to limit the schemas that you see.
For example, you might enter: *public* so that only *public* are shown in
the pgAdmin browser.Separate entries with a comma or tab as you type.
Click the *SQL* tab to continue.
Your entries in the *Database* dialog generate a SQL command (see an example
+2 -2
View File
@@ -16,9 +16,9 @@ superuser privileges to use the debugger.
Before using the debugger, you must modify the *postgresql.conf* file, adding
the server-side debugger components to the the value of the
*shared_preload_libraries* parameter:
*shared_preload_libraries* parameter, for example:
shared_preload_libraries = '$libdir/*other_libraries*/plugin_debugger'
shared_preload_libraries = '$libdir/plugin_debugger'
After modifying the *shared_preload_libraries* parameter, restart the server to
apply the changes.
+46 -13
View File
@@ -5,9 +5,19 @@
**************************************************
To enable LDAP authentication for pgAdmin, you must configure the LDAP
settings in the *config_local.py* or *config_distro.py* file on the system where
pgAdmin is installed in Server mode. You can copy these settings from *config.py*
file and modify the values for the following parameters:
settings in the *config_local.py* or *config_system.py* file (see the
:ref:`config.py <config_py>` documentation) on the system where pgAdmin is
installed in Server mode. You can copy these settings from *config.py* file
and modify the values for the following parameters:
There are 3 ways to configure LDAP:
* Bind as pgAdmin user
* Anonymous bind
* Dedicated user bind
.. csv-table::
:header: "**Parameter**", "**Description**"
@@ -21,9 +31,12 @@ file and modify the values for the following parameters:
* [‘ldap’]: pgAdmin will use only LDAP authentication.
* [‘ldap’, ‘internal’]: pgAdmin will first try to authenticate the user through
LDAP. If that authentication fails, then internal user entries of pgAdmin will be used for authentication.
LDAP. If that authentication fails, then internal user entries of pgAdmin
will be used for authentication.
* [‘internal’, ‘ldap’]: pgAdmin will first try to authenticate the user through internal user entries. If that authentication fails, then LDAP authentication will be used."
* [‘internal’, ‘ldap’]: pgAdmin will first try to authenticate the user
through internal user entries. If that authentication fails, then LDAP
authentication will be used."
"LDAP_AUTO_CREATE_USER", "Specifies if you want to automatically create a pgAdmin
user corresponding to the LDAP user credentials. Please note that LDAP password
is not stored in the pgAdmin database."
@@ -34,10 +47,6 @@ file and modify the values for the following parameters:
want to connect to. For example, 'ldap://172.16.209.35:389' is a valid
LDAP_SERVER_URI where ldap is the connection protocol, 172.16.209.35 is the IP
address and 389 is the port. Port 636 is used for the ldaps communication protocol."
"LDAP_BASE_DN","Specifies the base DN from where a server will start the search
for users. For example, an LDAP search for any user will be performed by the server
starting at the base DN (dc=example,dc=com). When the base DN matches, the full
DN (cn=admin,dc=example,dc=com) is used to bind with the supplied password."
"LDAP_USERNAME_ATTRIBUTE","Specifies the LDAP attribute that contains the
usernames. For LDAP authentication, you need to enter the value of that
particular attribute as username. For example, if you set the value of
@@ -45,10 +54,16 @@ file and modify the values for the following parameters:
entries, you should be able to authenticate by entering ‘admin’ in the 
*Email Address / Username* field and its corresponding password in the *Password* 
field."
"LDAP_SEARCH_BASE_DN","Specifies an element of the search request that works in
conjunction with the LDAP search scope to define the subtree of entries that
should be considered when processing the search request. You can use this parameter
for limiting the search request to a specific group of users."
"LDAP_SEARCH_BASE_DN","Specifies the distinguished name (DN) for the top-most user
directory that you want to search. You can use this parameter for limiting the search
request to a specific group of users. For example, if you want to search only within
the Organizational Unit named sales, you can define the value for LDAP_SEARCH_BASE_DN
parameter as following:
LDAP_SEARCH_BASE_DN = ‘ou=sales,dc=example,dc=com'
This is an optional parameter only while binding as pgAdmin user.
If you do not specify any value for LDAP_SEARCH_BASE_DN, then the value for
LDAP_BASE_DN will be considered for the same."
"LDAP_SEARCH_FILTER","Defines the criteria to retrieve matching entries in an
LDAP search request. For example, LDAP_SEARCH_FILTER = '(objectclass=HR)’ setting
searches only for users having HR as their objectClass attribute."
@@ -70,3 +85,21 @@ file and modify the values for the following parameters:
"LDAP_KEY_FILE","Specifies the path to the server private key file. This parameter
is applicable only if you are using *ldaps* as connection protocol and you have
set *LDAP_USE_STARTTLS* parameter to *True*."
"**Bind as pgAdmin user**"
"LDAP_BASE_DN","Specifies the base DN from where a server will start the search
for users. For example, an LDAP search for any user will be performed by the server
starting at the base DN (dc=example,dc=com). When the base DN matches, the full
DN (cn=admin,dc=example,dc=com) is used to bind with the supplied password."
"**Anonymous bind**"
"LDAP_ANONYMOUS_BIND","Set this parameter to *True* for anonymous binding.
After the connection is made, the pgadmin login user will be further authenticated
by the username and password provided at the login screen."
"**Dedicated user bind**"
"LDAP_BIND_USER", "The account of the user to log in for simple bind.
Set this parameter to allow the connection to bind using a dedicated user.
After the connection is made, the pgadmin login user will be further
authenticated by the username and password provided at the login screen.
at the login screen."
"LDAP_BIND_PASSWORD", "Password for simple bind.
Specify the value if you have set the LDAP_BIND_USER parameter."
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 KiB

After

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 185 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 110 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 119 KiB

+17 -2
View File
@@ -23,7 +23,11 @@ the ``--dump-servers`` command line option, followed by the name (and if require
path) to the desired output file. By default, servers owned by the desktop mode
user will be dumped (pgadmin4@pgadmin.org by default - see the DESKTOP_USER
setting in ``config.py``). This can be overridden with the ``--user`` command
line option. For example:
line option. There can be multiple configuations of pgAdmin on the same system.
To dump the servers from specific pgAdmin config DB file, ``--sqlite-path`` option
can be used. It is also recommended to use this option when running pgAdmin in
desktop mode. By default SQLITE_PATH setting in ``config.py`` is taken.
For example:
.. code-block:: bash
@@ -33,6 +37,10 @@ line option. For example:
/path/to/python /path/to/setup.py --dump-servers output_file.json --user user@example.com
# to specify a pgAdmin config DB file:
/path/to/python /path/to/setup.py --dump-servers output_file.json --sqlite-path /path/to/pgadmin4.db
To export only certain servers, use the ``--servers`` option and list one or
more server IDs. For example:
@@ -48,7 +56,10 @@ the ``--load-servers`` command line option, followed by the name (and if require
path) of the JSON file containing the server definitions. Servers will be owned
by the desktop mode user (pgadmin4@pgadmin.org by default - see the DESKTOP_USER
setting in ``config.py``). This can be overridden with the ``--user`` command
line option. For example:
line option. There can be multiple configuations of pgAdmin on the same system.
To load the servers into a specific pgAdmin config DB file, ``--sqlite-path`` option
can be used. It is also recommended to use this option when running pgAdmin in
desktop mode. By default SQLITE_PATH setting in ``config.py`` is taken. For example:
.. code-block:: bash
@@ -58,6 +69,10 @@ line option. For example:
/path/to/python /path/to/setup.py --load-servers input_file.json --user user@example.com
# to specify a pgAdmin config DB file:
/path/to/python /path/to/setup.py --load-servers input_file.json --sqlite-path /path/to/pgadmin4.db
If any Servers are defined with a Server Group that is not already present in
the configuration database, the required Group will be created.
+4 -4
View File
@@ -39,10 +39,10 @@ Use the fields in the *Definition* tab to define the index:
* Select *hash* to create a hash index. A hash index may improve
performance when managing simple equality comparisons.
* Select *gist* to create a GiST index. A GiST index may improve
performance when managing two-dimensional geometric data types and
nearest-neighbor searches.
* Select *gin* to create a GIN index. A GIN index may improve
performance when managing values with more than one key.
* Select *gin* to create a GIN index. A GIN index may improve performance
when managing two-dimensional geometric data types and nearest-neighbor
searches.
* Select *spgist* to create a space-partitioned GiST index. A SP-GiST index
may improve performance when managing non-balanced data structures.
* Select *brin* to create a BRIN index. A BRIN index may improve
@@ -108,4 +108,4 @@ the values in the *code* column of the *distributors* table.
* Click the *Info* button (i) to access online help.
* Click the *Save* button to save work.
* Click the *Cancel* button to exit without saving work.
* Click the *Reset* button to restore configuration parameters.
* Click the *Reset* button to restore configuration parameters.
+4 -3
View File
@@ -67,9 +67,10 @@ thresholds; use the *Table* tab and the *Toast Table* tab to customize values
for the table and the associated toast table. To change the default values:
* Move the *Custom auto-vacuum?* switch to the *Yes* position to perform custom
maintenance on the materialized view.
* Move the *Enabled?* switch to the *Yes* position to select values in the
*Vacuum table*. Provide values for each row in the *Value* column.
maintenance on the materialized view and to select values in the
*Vacuum table*. The *Vacuum Table* provides default values for maintenance
operations.
* Changing *Autovacuum enabled?* to *Not set* will reset autovacuum_enabled.
Click the *Security* tab to continue.
+1
View File
@@ -22,6 +22,7 @@ node, and select *Create Cast...*
foreign_key_dialog
index_dialog
primary_key_dialog
rls_policy_dialog
rule_dialog
table_dialog
trigger_dialog
+38 -9
View File
@@ -49,6 +49,9 @@ Use the fields on the *Display* panel to specify general display preferences:
the client will display the animated dialogues/notifications otherwise it
will be unanimated.
* When the *Hide shared server?* switch is set to *True*, the client will hide
all the shared servers from the browser tree.
* Use the *Lock layout* field to lock the UI layout at different levels. This
can also be changed from File menu on the :ref:`menu bar <menu_bar>`
@@ -185,6 +188,7 @@ Expand the *Miscellaneous* node to specify miscellaneous display preferences.
* Use the *Themes* drop-down listbox to select the theme for pgAdmin. You'll also get a preview just below the
drop down. Note that, to apply the theme you need to refresh the pgAdmin page. You can also submit your
own themes, check `here <https://git.postgresql.org/gitweb/?p=pgadmin4.git;a=blob_plain;f=README>`_ how.
Currently we support Standard, Dark and High Contrast (Beta) theme.
The Paths Node
**************
@@ -305,12 +309,6 @@ Use the fields on the *Editor* panel to change settings of the query editor.
changed to text/plain. Keyword highlighting and code folding will be disabled.
This will improve editor performance with large files.
* Use the *Tab size* field to specify the number of spaces per tab character in
the editor.
* When the *Use spaces* switch is set to *True*, the editor will insert spaces
(instead of tab characters) when the tab key or auto-indent are used.
.. image:: images/preferences_sql_explain.png
:alt: Preferences dialog sqleditor explain options
:align: center
@@ -374,13 +372,41 @@ preferences for copied data.
* Use the *Result copy quoting* drop-down listbox to select which type of fields
require quoting; select *All*, *None*, or *Strings*.
Use the fields on the *Keyboard shortcuts* panel to configure shortcuts for the
Query Tool window navigation:
.. image:: images/preferences_sql_keyboard_shortcuts.png
:alt: Preferences dialog sql keyboard shortcuts section
:align: center
Use the fields on the *Keyboard shortcuts* panel to configure shortcuts for the
Query Tool window navigation:
.. image:: images/preferences_sql_formatting.png
:alt: Preferences dialog SQL Formatting section
:align: center
Use the fields on the *SQL formatting* panel to specify your preferences for
reformatting of SQL.
* Use the *Command-first notation* option to specify whether to place commas
before or after column names.
* Use the *Identifier case* option to specify whether to change identifiers
(object names) into upper, lower, or capitalized case.
* Use the *Keyword case* option to specify whether to change keywords into
upper, lower, or capitalized case.
* Use the *Re-indent aligned?* option to specify that indentations of statements
should be changed, aligned by keywords.
* Use the *Re-indent?* option to specify that indentations of statements should
be changed.
* Use the *Spaces around operators?* option to specify whether or not to include
spaces on either side of operators.
* Use the *Strip comments?* option to specify whether or not comments should be
removed.
* Use the *Tab size* option to specify the number of spaces per tab or indent.
* Use the *Use spaces?* option to select whether to use spaces or tabs when
indenting.
* Use the *Wrap after N characters* option to specify the column limit for
wrapping column separated lists (e.g. of column names in a table). If set to
0 (zero), each item will be on it's own line.
The Schema Diff Node
********************
@@ -390,6 +416,9 @@ Expand the *Schema Diff* node to specify your display preferences.
:alt: Preferences schema diff
:align: center
Use the *Ignore whitespaces* switch to ignores the whitespaces while comparing
the string objects. Whitespace includes space, tabs, and CRLF.
Use the *Open in new browser tab* switch to indicate if you would like Schema Diff
to open in a new tab.
+4 -2
View File
@@ -286,8 +286,10 @@ the *Clear* drop-down menu.
Query History is maintained across sessions for each database on a per-user
basis when running in Query Tool mode. In View/Edit Data mode, history is not
retained. By default, the last 20 queries are stored for each database. This
can be adjusted in `config_local.py` by overriding the `MAX_QUERY_HIST_STORED`
value. See the :ref:`Deployment <deployment>` section for more information.
can be adjusted in ``config_local.py`` or ``config_system.py`` (see the
:ref:`config.py <config_py>` documentation) by overriding the
`MAX_QUERY_HIST_STORED` value. See the :ref:`Deployment <deployment>` section
for more information.
Connection Status
*****************
+182 -180
View File
@@ -1,184 +1,186 @@
.. _query_tool_toolbar:
***************************
`Query Tool Toolbar`:index:
***************************
The *Query Tool* toolbar uses context-sensitive icons that provide shortcuts to
frequently performed tasks. If an icon is highlighted, the option is enabled;
if the icon is grayed-out, the task is disabled.
.. note:: The :ref:`Query Tool <query_tool>` and
:ref:`View/Edit Data <editgrid>` tools are actually different operating
modes of the same tool. Some controls will be disabled in either mode.
.. image:: images/query_toolbar.png
:alt: Query tool toolbar
:align: center
Hover over an icon in pgAdmin to display a tooltip that describes the icon's
functionality.
File Options
************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Open File* | Click the *Open File* icon to display a previously saved query in the SQL Editor. | Accesskey + O |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Save File* | Click the *Save* icon to perform a quick-save of a previously saved query, or to access the | Accesskey + S |
| | *Save* menu: | |
| | | |
| | * Select *Save* to save the selected content of the SQL Editor panel in a file. | |
| | | |
| | * Select *Save As* to open a new browser dialog and specify a new location to which to save the | |
| | selected content of the SQL Editor panel. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
Editing Options
***************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Save Data Changes* | Click the *Save Data Changes* icon to save data changes (insert, update, or delete) in the Data | F6 |
| | Output Panel to the server. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Find* | Use the *Find* menu to search, replace, or navigate the code displayed in the SQL Editor: | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Find* to provide a search target, and search the SQL Editor contents. | Cmd+F |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Find next* to locate the next occurrence of the search target. | Cmd+G |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Find previous* to move to the last occurrence of the search target. | Cmd+Shift+G |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Persistent find* to identify all occurrences of the search target within the editor. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Replace* to locate and replace (with prompting) individual occurrences of the target. | Cmd+Shift+F |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Replace all* to locate and replace all occurrences of the target within the editor. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Jump* to navigate to the next occurrence of the search target. | Alt+G |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Copy* | Click the *Copy* icon to copy the content with or without header: | Accesskey + C |
| | | |
| | * Click the *Copy* icon to copy the content that is currently highlighted in the Data Output | |
| | panel. | |
| | | |
| | * Click *Copy with headers* to copy the highlighted content along with the header. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Paste* | Click the *Paste* icon to paste a previously copied row into a new row. | Accesskey + P |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Delete* | Click the *Delete* icon to mark the selected rows for deletion. These marked rows get deleted |Accesskey + D |
| | when you click the *Save Data Changes* icon. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Edit* | Use options on the *Edit* menu to access text editing tools; the options operate on the text | |
| | displayed in the SQL Editor panel when in Query Tool mode: | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Indent Selection* to indent the currently selected text. | Tab |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Unindent Selection* to remove indentation from the currently selected text. | Shift+Tab |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Inline Comment Selection* to enclose any lines that contain the selection in SQL style | Cmd+/ |
| | comment notation. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Inline Uncomment Selection* to remove SQL style comment notation from the selected line. | Cmd+. |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Block Comment* to enclose all lines that contain the selection in C style comment | Shift+Cmd+/ |
| | notation. This option acts as a toggle. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
View/Edit Data Resultset Control
********************************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Filter* | Click the *Filter* icon to set filtering and sorting criteria for the data when in View/Edit data | Accesskey + F |
| | mode. Click the down arrow to access other filtering and sorting options: | |
| | | |
| | * Click *Sort/Filter* to open the sorting and filtering dialogue. In the *SQL Filter*, you can | |
| | enter a SQL query as filtering criteria. In *Data Sorting*, you can select the column and | |
| | specify the order for sorting. | |
| | | |
| | * Click *Filter by Selection* to show only the rows containing the values in the selected cells. | |
| | | |
| | * Click *Exclude by Selection* to show only the rows that do not contain the values in the | |
| | selected cells. | |
| | | |
| | * Click *Remove Sort/Filter* to remove any previously selected sort or filtering options. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Limit Selector | Select a value in the *Limit Selector* to limit the size of the dataset to a number of rows. | Accesskey + R |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Stop* | Click the *Stop* icon to cancel the execution of the currently running query. | Accesskey + Q |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
Query Execution
***************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Execute/Refresh* | Click the *Execute/Refresh* icon to either execute or refresh the query highlighted in the SQL | F5 |
| | editor panel. Click the down arrow to access other execution options: | |
| | | |
| | * Add a check next to *Auto-Rollback* to instruct the server to automatically roll back a | |
| | transaction if an error occurs during the transaction. | |
| | | |
| | * Add a check next to *Auto-Commit* to instruct the server to automatically commit each | |
| | transaction. Any changes made by the transaction will be visible to others, and | |
| | durable in the event of a crash. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Explain* | Click the *Explain* icon to view an explanation plan for the current query. The result of the | F7 |
| | EXPLAIN is displayed graphically on the *Explain* tab of the output panel, and in text | |
| | form on the *Data Output* tab. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Explain analyze* | Click the *Explain analyze* icon to invoke an EXPLAIN ANALYZE command on the current query. | Shift+F7 |
| | | |
| | Navigate through the *Explain Options* menu to select options for the EXPLAIN command: | |
| | | |
| | * Select *Verbose* to display additional information regarding the query plan. | |
| | | |
| | * Select *Costs* to include information on the estimated startup and total cost of each | |
| | plan node, as well as the estimated number of rows and the estimated width of each | |
| | row. | |
| | | |
| | * Select *Buffers* to include information on buffer usage. | |
| | | |
| | * Select *Timing* to include information about the startup time and the amount of time | |
| | spent in each node of the query. | |
| | | |
| | * Select *Summary* to include the summary information about the query plan. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Commit* | Click the *Commit* icon to commit the transaction. | Shift+CTRL+M |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Rollback* | Click the *Rollback* icon to rollback the transaction. | Shift+CTRL+R |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Clear* | Use options on the *Clear* drop-down menu to erase display contents: | Accesskey + L |
| | | |
| | * Select *Clear Query Window* to erase the content of the SQL Editor panel. | |
| | | |
| | * Select *Clear History* to erase the content of the *History* tab. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
.. _query_tool_toolbar:
***************************
`Query Tool Toolbar`:index:
***************************
The *Query Tool* toolbar uses context-sensitive icons that provide shortcuts to
frequently performed tasks. If an icon is highlighted, the option is enabled;
if the icon is grayed-out, the task is disabled.
.. note:: The :ref:`Query Tool <query_tool>` and
:ref:`View/Edit Data <editgrid>` tools are actually different operating
modes of the same tool. Some controls will be disabled in either mode.
.. image:: images/query_toolbar.png
:alt: Query tool toolbar
:align: center
Hover over an icon in pgAdmin to display a tooltip that describes the icon's
functionality.
File Options
************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Open File* | Click the *Open File* icon to display a previously saved query in the SQL Editor. | Accesskey + O |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Save File* | Click the *Save* icon to perform a quick-save of a previously saved query, or to access the | Accesskey + S |
| | *Save* menu: | |
| | | |
| | * Select *Save* to save the selected content of the SQL Editor panel in a file. | |
| | | |
| | * Select *Save As* to open a new browser dialog and specify a new location to which to save the | |
| | selected content of the SQL Editor panel. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
Editing Options
***************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Save Data Changes* | Click the *Save Data Changes* icon to save data changes (insert, update, or delete) in the Data | F6 |
| | Output Panel to the server. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Find* | Use the *Find* menu to search, replace, or navigate the code displayed in the SQL Editor: | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Find* to provide a search target, and search the SQL Editor contents. | Cmd+F |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Find next* to locate the next occurrence of the search target. | Cmd+G |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Find previous* to move to the last occurrence of the search target. | Cmd+Shift+G |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Persistent find* to identify all occurrences of the search target within the editor. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Replace* to locate and replace (with prompting) individual occurrences of the target. | Cmd+Shift+F |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Replace all* to locate and replace all occurrences of the target within the editor. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Jump* to navigate to the next occurrence of the search target. | Alt+G |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Copy* | Click the *Copy* icon to copy the content with or without header: | Accesskey + C |
| | | |
| | * Click the *Copy* icon to copy the content that is currently highlighted in the Data Output | |
| | panel. | |
| | | |
| | * Click *Copy with headers* to copy the highlighted content along with the header. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Paste* | Click the *Paste* icon to paste a previously copied row into a new row. | Accesskey + P |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Delete* | Click the *Delete* icon to mark the selected rows for deletion. These marked rows get deleted |Accesskey + D |
| | when you click the *Save Data Changes* icon. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Edit* | Use options on the *Edit* menu to access text editing tools; the options operate on the text | |
| | displayed in the SQL Editor panel when in Query Tool mode: | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Indent Selection* to indent the currently selected text. | Tab |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Unindent Selection* to remove indentation from the currently selected text. | Shift+Tab |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Inline Comment Selection* to enclose any lines that contain the selection in SQL style | Cmd+/ |
| | comment notation. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Inline Uncomment Selection* to remove SQL style comment notation from the selected line. | Cmd+. |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Block Comment* to enclose all lines that contain the selection in C style comment | Shift+Cmd+/ |
| | notation. This option acts as a toggle. | |
| +---------------------------------------------------------------------------------------------------+----------------+
| | Select *Format SQL* to format the selected SQL or all the SQL if none is selected | Shift+Cmd+K |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
View/Edit Data Resultset Control
********************************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Filter* | Click the *Filter* icon to set filtering and sorting criteria for the data when in View/Edit data | Accesskey + F |
| | mode. Click the down arrow to access other filtering and sorting options: | |
| | | |
| | * Click *Sort/Filter* to open the sorting and filtering dialogue. In the *SQL Filter*, you can | |
| | enter a SQL query as filtering criteria. In *Data Sorting*, you can select the column and | |
| | specify the order for sorting. | |
| | | |
| | * Click *Filter by Selection* to show only the rows containing the values in the selected cells. | |
| | | |
| | * Click *Exclude by Selection* to show only the rows that do not contain the values in the | |
| | selected cells. | |
| | | |
| | * Click *Remove Sort/Filter* to remove any previously selected sort or filtering options. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Limit Selector | Select a value in the *Limit Selector* to limit the size of the dataset to a number of rows. | Accesskey + R |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Stop* | Click the *Stop* icon to cancel the execution of the currently running query. | Accesskey + Q |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
Query Execution
***************
.. table::
:class: longtable
:widths: 1 4 1
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| Icon | Behavior | Shortcut |
+======================+===================================================================================================+================+
| *Execute/Refresh* | Click the *Execute/Refresh* icon to either execute or refresh the query highlighted in the SQL | F5 |
| | editor panel. Click the down arrow to access other execution options: | |
| | | |
| | * Add a check next to *Auto-Rollback* to instruct the server to automatically roll back a | |
| | transaction if an error occurs during the transaction. | |
| | | |
| | * Add a check next to *Auto-Commit* to instruct the server to automatically commit each | |
| | transaction. Any changes made by the transaction will be visible to others, and | |
| | durable in the event of a crash. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Explain* | Click the *Explain* icon to view an explanation plan for the current query. The result of the | F7 |
| | EXPLAIN is displayed graphically on the *Explain* tab of the output panel, and in text | |
| | form on the *Data Output* tab. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Explain analyze* | Click the *Explain analyze* icon to invoke an EXPLAIN ANALYZE command on the current query. | Shift+F7 |
| | | |
| | Navigate through the *Explain Options* menu to select options for the EXPLAIN command: | |
| | | |
| | * Select *Verbose* to display additional information regarding the query plan. | |
| | | |
| | * Select *Costs* to include information on the estimated startup and total cost of each | |
| | plan node, as well as the estimated number of rows and the estimated width of each | |
| | row. | |
| | | |
| | * Select *Buffers* to include information on buffer usage. | |
| | | |
| | * Select *Timing* to include information about the startup time and the amount of time | |
| | spent in each node of the query. | |
| | | |
| | * Select *Summary* to include the summary information about the query plan. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Commit* | Click the *Commit* icon to commit the transaction. | Shift+CTRL+M |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Rollback* | Click the *Rollback* icon to rollback the transaction. | Shift+CTRL+R |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Clear* | Use options on the *Clear* drop-down menu to erase display contents: | Accesskey + L |
| | | |
| | * Select *Clear Query Window* to erase the content of the SQL Editor panel. | |
| | | |
| | * Select *Clear History* to erase the content of the *History* tab. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
| *Download as CSV/TXT*| Click the *Download as CSV/TXT* icon to download the result set of the current query as a *.csv* | F8 |
| | or as a *.txt* file. if *CSV field seperator* set to comma(,) else as a *.txt* file. | |
| | You can specify the CSV/TXT settings through *Preferences -> SQL Editor -> CSV/TXT output* | |
| | dialogue. | |
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
+5
View File
@@ -11,6 +11,11 @@ notes for it.
.. toctree::
:maxdepth: 1
release_notes_4_26
release_notes_4_25
release_notes_4_24
release_notes_4_23
release_notes_4_22
release_notes_4_21
release_notes_4_20
release_notes_4_19
+54
View File
@@ -0,0 +1,54 @@
************
Version 4.22
************
Release date: 2020-05-28
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.21.
New features
************
| `Issue #5452 <https://redmine.postgresql.org/issues/5452>`_ - Added connected pgAdmin user and connection name in the log file.
| `Issue #5489 <https://redmine.postgresql.org/issues/5489>`_ - Show the startup log as well as the server log in the runtime's log viewer.
Housekeeping
************
| `Issue #5255 <https://redmine.postgresql.org/issues/5255>`_ - Implement Selenium Grid to run multiple tests across different browsers, operating systems, and machines in parallel.
| `Issue #5333 <https://redmine.postgresql.org/issues/5333>`_ - Improve code coverage and API test cases for Indexes.
| `Issue #5334 <https://redmine.postgresql.org/issues/5334>`_ - Improve code coverage and API test cases for the Rules module.
| `Issue #5335 <https://redmine.postgresql.org/issues/5335>`_ - Improve code coverage and API test cases for Triggers and Compound Triggers.
| `Issue #5443 <https://redmine.postgresql.org/issues/5443>`_ - Remove support for Python 2.
| `Issue #5444 <https://redmine.postgresql.org/issues/5444>`_ - Cleanup Python detection in the runtime project file.
| `Issue #5455 <https://redmine.postgresql.org/issues/5455>`_ - Refactor pgAdmin4.py so it can be imported and is a lot more readable.
| `Issue #5493 <https://redmine.postgresql.org/issues/5493>`_ - Search object UI improvements.
| `Issue #5525 <https://redmine.postgresql.org/issues/5525>`_ - Cleanup and refactor the macOS build scripts.
| `Issue #5552 <https://redmine.postgresql.org/issues/5552>`_ - Update dependencies in the Docker container.
| `Issue #5553 <https://redmine.postgresql.org/issues/5553>`_ - Remove PG 9.4 utilities from the Docker container as it's now out of support.
Bug fixes
*********
| `Issue #3694 <https://redmine.postgresql.org/issues/3694>`_ - Gracefully informed the user that the database is already connected when they click on "Connect Database...".
| `Issue #4033 <https://redmine.postgresql.org/issues/4033>`_ - Fixed an issue where clicking on the cross button of the alert box on the login page is not working.
| `Issue #4099 <https://redmine.postgresql.org/issues/4099>`_ - Fixed the SQL help issue for EDB Postgres Advanced Server.
| `Issue #4223 <https://redmine.postgresql.org/issues/4223>`_ - Ensure that maintenance job should be worked properly for indexes under a materialized view.
| `Issue #4279 <https://redmine.postgresql.org/issues/4279>`_ - Ensure that file browse "home" button should point to $HOME rather than /.
| `Issue #4840 <https://redmine.postgresql.org/issues/4840>`_ - Ensure that 'With OID' option should be disabled while taking backup of database server version 12 and above.
| `Issue #5001 <https://redmine.postgresql.org/issues/5001>`_ - Fixed invalid literal issue when removing the connection limit for the existing role.
| `Issue #5052 <https://redmine.postgresql.org/issues/5052>`_ - Fixed internal server error when clicking on Triggers -> 'Enable All' for partitions.
| `Issue #5398 <https://redmine.postgresql.org/issues/5398>`_ - Fixed generated SQL issue for auto vacuum options.
| `Issue #5422 <https://redmine.postgresql.org/issues/5422>`_ - Ensure that the dependencies tab shows correct information for Synonyms.
| `Issue #5434 <https://redmine.postgresql.org/issues/5434>`_ - Fixed an issue where the newly added table is not alphabetically added to the tree.
| `Issue #5440 <https://redmine.postgresql.org/issues/5440>`_ - Fixed list sorting issue in the schema diff tool.
| `Issue #5449 <https://redmine.postgresql.org/issues/5449>`_ - Fixed an issue while comparing the two identical schemas using the schema diff tool.
| `Issue #5450 <https://redmine.postgresql.org/issues/5450>`_ - Fixed an issue when renaming the column not added in the proper order.
| `Issue #5466 <https://redmine.postgresql.org/issues/5466>`_ - Correct ipv4 "all interfaces" address in the container docs, per Frank Limpert.
| `Issue #5469 <https://redmine.postgresql.org/issues/5469>`_ - Fixed an issue where select2 hover is inconsistent for the SSL field in create server dialog.
| `Issue #5473 <https://redmine.postgresql.org/issues/5473>`_ - Fixed post-login redirect location when running in server mode under a non-default root.
| `Issue #5480 <https://redmine.postgresql.org/issues/5480>`_ - Fixed an issue where the background job creation fails if there is only a version-specific python binary available in PATH.
| `Issue #5481 <https://redmine.postgresql.org/issues/5481>`_ - Fixed data truncation issue when updating the data of type character with length.
| `Issue #5487 <https://redmine.postgresql.org/issues/5487>`_ - Fixed an issue where if LDAP_SEARCH_BASE_DN is not set then, the value for LDAP_BASE_DN will be considered.
| `Issue #5496 <https://redmine.postgresql.org/issues/5496>`_ - Fixed an issue where clicking on Select All button, not selecting all the options in pgAgent job scheduler.
| `Issue #5503 <https://redmine.postgresql.org/issues/5503>`_ - Clarify and correct the docs on enabling the pl/debugger plugin on the server.
| `Issue #5510 <https://redmine.postgresql.org/issues/5510>`_ - Fixed Unicode decode error 'utf-8' codec can't decode byte.
+38
View File
@@ -0,0 +1,38 @@
************
Version 4.23
************
Release date: 2020-06-25
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.22.
New features
************
| `Issue #5468 <https://redmine.postgresql.org/issues/5468>`_ - Added option to ignore the whitespaces while comparing objects in schema diff.
| `Issue #5500 <https://redmine.postgresql.org/issues/5500>`_ - Added server group name while selecting servers in schema diff.
| `Issue #5516 <https://redmine.postgresql.org/issues/5516>`_ - Added support of Row Security Policies.
| `Issue #5576 <https://redmine.postgresql.org/issues/5576>`_ - Improve error messaging if the storage and log directories cannot be created.
Housekeeping
************
| `Issue #5325 <https://redmine.postgresql.org/issues/5325>`_ - Improve code coverage and API test cases for Collations.
| `Issue #5574 <https://redmine.postgresql.org/issues/5574>`_ - Cleanup Windows build scripts and ensure Windows x64 builds will work.
| `Issue #5581 <https://redmine.postgresql.org/issues/5581>`_ - Documentation of Row Level Security Policies.
Bug fixes
*********
| `Issue #3591 <https://redmine.postgresql.org/issues/3591>`_ - Ensure that the query tool should display the proper error message while terminating the active session.
| `Issue #3669 <https://redmine.postgresql.org/issues/3669>`_ - Ensure that proper error should be displayed for the deleted node.
| `Issue #3787 <https://redmine.postgresql.org/issues/3787>`_ - Disabled the Stop process button after clicking it and added a message 'Terminating the process...' to notify the user.
| `Issue #4226 <https://redmine.postgresql.org/issues/4226>`_ - Fixed an issue where select all checkbox only selects the first 50 tables.
| `Issue #5416 <https://redmine.postgresql.org/issues/5416>`_ - Ensure that the query tool panel gets closed when clicking on the 'Don't Save' button.
| `Issue #5465 <https://redmine.postgresql.org/issues/5465>`_ - Fixed an issue where the Edge browser version is showing wrong and warning message gets displayed.
| `Issue #5492 <https://redmine.postgresql.org/issues/5492>`_ - Fixed an issue where the search object is unable to locate inherited tables and constraint filters are not working.
| `Issue #5507 <https://redmine.postgresql.org/issues/5507>`_ - Fixed connection and version number detection issue when the database server is upgraded.
| `Issue #5521 <https://redmine.postgresql.org/issues/5521>`_ - Fixed an issue when dumping servers from a desktop pgAdmin app by providing an option '--sqlite-path'.
| `Issue #5539 <https://redmine.postgresql.org/issues/5539>`_ - Fixed typo in exception keyword.
| `Issue #5584 <https://redmine.postgresql.org/issues/5584>`_ - Fixed an issue where two identical tables showing different by schema diff tool.
| `Issue #5592 <https://redmine.postgresql.org/issues/5592>`_ - Ensure that pgadmin should be able to connect to the server which has password more than 1000 characters.
+53
View File
@@ -0,0 +1,53 @@
************
Version 4.24
************
Release date: 2020-07-23
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.23.
New features
************
| `Issue #5235 <https://redmine.postgresql.org/issues/5235>`_ - Support configuration files that are external to the application installation.
| `Issue #5484 <https://redmine.postgresql.org/issues/5484>`_ - Added support for LDAP authentication with different DN by setting the dedicated user for the LDAP connection.
| `Issue #5583 <https://redmine.postgresql.org/issues/5583>`_ - Added support for schema level restriction.
| `Issue #5601 <https://redmine.postgresql.org/issues/5601>`_ - Added RLS Policy support in Schema Diff.
| `Issue #5622 <https://redmine.postgresql.org/issues/5622>`_ - Added support for permissive/restricted policy type while creating RLS Policy.
| `Issue #5650 <https://redmine.postgresql.org/issues/5650>`_ - Added support for LDAP anonymous binding.
| `Issue #5653 <https://redmine.postgresql.org/issues/5653>`_ - Added High Contrast theme support.
Housekeeping
************
| `Issue #5323 <https://redmine.postgresql.org/issues/5323>`_ - Improve code coverage and API test cases for Foreign Data Wrapper.
| `Issue #5326 <https://redmine.postgresql.org/issues/5326>`_ - Improve code coverage and API test cases for Domain and Domain Constraints.
| `Issue #5329 <https://redmine.postgresql.org/issues/5329>`_ - Improve code coverage and API test cases for FTS Configuration, FTS Parser, FTS Dictionaries, and FTS Template.
Bug fixes
*********
| `Issue #3814 <https://redmine.postgresql.org/issues/3814>`_ - Fixed issue of error message not getting displayed when filename is empty for backup, restore, and import/export.
| `Issue #3851 <https://redmine.postgresql.org/issues/3851>`_ - Add proper indentation to the code while generating functions, procedures, and trigger functions.
| `Issue #4235 <https://redmine.postgresql.org/issues/4235>`_ - Fixed tab indent issue on a selection of lines is deleting the content when 'use spaces == true' in the preferences.
| `Issue #5137 <https://redmine.postgresql.org/issues/5137>`_ - Fixed save button enable issue when focusing in and out of numeric input field.
| `Issue #5287 <https://redmine.postgresql.org/issues/5287>`_ - Fixed dark theme-related CSS and modify the color codes.
| `Issue #5414 <https://redmine.postgresql.org/issues/5414>`_ - Use QStandardPaths::AppLocalDataLocation in the runtime to determine where to store runtime logs.
| `Issue #5463 <https://redmine.postgresql.org/issues/5463>`_ - Fixed an issue where CSV download quotes numeric columns.
| `Issue #5470 <https://redmine.postgresql.org/issues/5470>`_ - Fixed backgrid row hover issue where on hover background color is set for edit and delete cell only.
| `Issue #5530 <https://redmine.postgresql.org/issues/5530>`_ - Ensure that the referenced table should be displayed on foreign key constraints.
| `Issue #5554 <https://redmine.postgresql.org/issues/5554>`_ - Replace the runtime themes with ones that don't have sizing issues.
| `Issue #5569 <https://redmine.postgresql.org/issues/5569>`_ - Fixed reverse engineered SQL for partitions when storage parameters are specified.
| `Issue #5577 <https://redmine.postgresql.org/issues/5577>`_ - Include LICENSE and DEPENDENCIES [inventory] files in official packages.
| `Issue #5621 <https://redmine.postgresql.org/issues/5621>`_ - Remove extra brackets from reverse engineering SQL of RLS Policy.
| `Issue #5629 <https://redmine.postgresql.org/issues/5629>`_ - Fixed an issue where the user is able to edit properties when some of the collection nodes are selected.
| `Issue #5630 <https://redmine.postgresql.org/issues/5630>`_ - Fixed an issue where installation of pgadmin4 not working on 32-bit Windows.
| `Issue #5631 <https://redmine.postgresql.org/issues/5631>`_ - Fixed 'cant execute empty query' issue when remove the value of 'USING' or 'WITH CHECK' option of RLS Policy.
| `Issue #5633 <https://redmine.postgresql.org/issues/5633>`_ - Ensure that create RLS Policy menu should not be visible for catalog objects.
| `Issue #5647 <https://redmine.postgresql.org/issues/5647>`_ - Fixed an issue where difference DDL is showing the wrong SQL when changing the policy owner.
| `Issue #5662 <https://redmine.postgresql.org/issues/5662>`_ - Fixed accessibility issue where few dialogs are not rendering properly when we zoomed in browser window 200% and screen resolution is low.
| `Issue #5666 <https://redmine.postgresql.org/issues/5666>`_ - Added missing dependencies/dependent and corrected some wrongly identified.
| `Issue #5673 <https://redmine.postgresql.org/issues/5673>`_ - Fixed an issue where fetching the schema throws an error if the database is not connected in Schema Diff.
| `Issue #5675 <https://redmine.postgresql.org/issues/5675>`_ - Fixed CSRF errors when pgAdmin opened in an iframe on safari browser.
| `Issue #5677 <https://redmine.postgresql.org/issues/5677>`_ - Fixed text color issue in explain analyze for the Dark theme.
| `Issue #5686 <https://redmine.postgresql.org/issues/5686>`_ - Fixed issue where the user was not able to update policy if the policy is created with space.
+49
View File
@@ -0,0 +1,49 @@
************
Version 4.25
************
Release date: 2020-08-20
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.24.
New features
************
| `Issue #3904 <https://redmine.postgresql.org/issues/3904>`_ - Replace charting library Flotr2 with ChartJS using React.
| `Issue #5126 <https://redmine.postgresql.org/issues/5126>`_ - Modified schema diff tool to compare two databases instead of two schemas.
| `Issue #5610 <https://redmine.postgresql.org/issues/5610>`_ - Add a --yes command line option to setup-web.sh to allow non-interactive use.
Housekeeping
************
| `Issue #5324 <https://redmine.postgresql.org/issues/5324>`_ - Improve code coverage and API test cases for Foreign Servers and User Mappings.
| `Issue #5327 <https://redmine.postgresql.org/issues/5327>`_ - Improve code coverage and API test cases for Schemas.
| `Issue #5336 <https://redmine.postgresql.org/issues/5336>`_ - Improve code coverage and API test cases for Types.
| `Issue #5700 <https://redmine.postgresql.org/issues/5700>`_ - Remove old Python 2 compatibility code.
| `Issue #5731 <https://redmine.postgresql.org/issues/5731>`_ - Upgrade font awesome from v4 to v5.
Bug fixes
*********
| `Issue #3767 <https://redmine.postgresql.org/issues/3767>`_ - Ensure that the original file format should be retained when saving the same file in SQL editor.
| `Issue #3791 <https://redmine.postgresql.org/issues/3791>`_ - Added missing comments in reverse engineering SQL for each column of a View.
| `Issue #4123 <https://redmine.postgresql.org/issues/4123>`_ - Fixed an issue where debugger doesn't work if the search path is set other than 'public'.
| `Issue #4361 <https://redmine.postgresql.org/issues/4361>`_ - Fixed ssh tunnel hang issue when the user tries to disconnect the server.
| `Issue #4387 <https://redmine.postgresql.org/issues/4387>`_ - Fixed an issue where the user is not able to insert the data if the table and columns name contains special characters.
| `Issue #4810 <https://redmine.postgresql.org/issues/4810>`_ - Fixed an issue where the user is not able to save the new row if the table is empty.
| `Issue #5429 <https://redmine.postgresql.org/issues/5429>`_ - Ensure that the Dictionaries drop-down shows all the dictionaries in the FTS configuration dialog.
| `Issue #5490 <https://redmine.postgresql.org/issues/5490>`_ - Make the runtime configuration dialog non-modal.
| `Issue #5526 <https://redmine.postgresql.org/issues/5526>`_ - Fixed an issue where copying and pasting a cell with multiple line data will result in multiple rows.
| `Issue #5567 <https://redmine.postgresql.org/issues/5567>`_ - Fixed an issue where conversion of bytea to the binary string results in an error.
| `Issue #5604 <https://redmine.postgresql.org/issues/5604>`_ - Fixed an issue where the entire logs is in red text when the user runs backup and restore.
| `Issue #5632 <https://redmine.postgresql.org/issues/5632>`_ - Ensure that the user will be able to modify the start value of the Identity column.
| `Issue #5646 <https://redmine.postgresql.org/issues/5646>`_ - Ensure that RLS Policy node should be searchable using search object.
| `Issue #5664 <https://redmine.postgresql.org/issues/5664>`_ - Fixed an issue where 'ALTER VIEW' statement is missing when the user sets the default value of a column for View.
| `Issue #5670 <https://redmine.postgresql.org/issues/5670>`_ - Fixed an issue where the error message does not have a close button on utility dialogs.
| `Issue #5689 <https://redmine.postgresql.org/issues/5689>`_ - Added the 'ORDER BY' clause for the privileges type to fix schema diff issue.
| `Issue #5708 <https://redmine.postgresql.org/issues/5708>`_ - Correct TLS certificate filename in the container deployment docs.
| `Issue #5710 <https://redmine.postgresql.org/issues/5710>`_ - Fixed an issue when comparing the table with a trigger throwing error in schema diff.
| `Issue #5713 <https://redmine.postgresql.org/issues/5713>`_ - Corrected DROP SQL syntax for catalog.
| `Issue #5716 <https://redmine.postgresql.org/issues/5716>`_ - Fixed an issue where ajax call continues to fire even after disconnecting the database server.
| `Issue #5724 <https://redmine.postgresql.org/issues/5724>`_ - Clarify some of the differences when running in server mode in the docs.
| `Issue #5730 <https://redmine.postgresql.org/issues/5730>`_ - Resolve schema diff dependencies by selecting the appropriate node automatically and maintain the order in the generated script.
+49
View File
@@ -0,0 +1,49 @@
************
Version 4.26
************
Release date: 2020-09-17
This release contains a number of bug fixes and new features since the release of pgAdmin4 4.25.
New features
************
| `Issue #2042 <https://redmine.postgresql.org/issues/2042>`_ - Added SQL Formatter support in Query Tool.
| `Issue #4059 <https://redmine.postgresql.org/issues/4059>`_ - Added a new button to the query tool toolbar to open a new query tool window.
| `Issue #4979 <https://redmine.postgresql.org/issues/4979>`_ - Added shared server support for admin users.
| `Issue #5772 <https://redmine.postgresql.org/issues/5772>`_ - Warn the user when connecting to a server that is older than pgAdmin supports.
Housekeeping
************
| `Issue #5332 <https://redmine.postgresql.org/issues/5332>`_ - Improve code coverage and API test cases for Columns and Constraints (Index, Foreign Key, Check, Exclusion).
| `Issue #5344 <https://redmine.postgresql.org/issues/5344>`_ - Improve code coverage and API test cases for Grant Wizard.
| `Issue #5774 <https://redmine.postgresql.org/issues/5774>`_ - Improve code coverage and API test cases for Tables.
| `Issue #5792 <https://redmine.postgresql.org/issues/5792>`_ - Added documentation for shared server support.
Bug fixes
*********
| `Issue #4216 <https://redmine.postgresql.org/issues/4216>`_ - Ensure that schema names starting with 'pg' should be visible in browser tree when standard_conforming_strings is set to off.
| `Issue #5426 <https://redmine.postgresql.org/issues/5426>`_ - Adjusted the height of jobstep code block to use maximum space.
| `Issue #5652 <https://redmine.postgresql.org/issues/5652>`_ - Modified the 'Commit' and 'Rollback' query tool button icons.
| `Issue #5722 <https://redmine.postgresql.org/issues/5722>`_ - Ensure that the user should be able to drop the database even if it is connected.
| `Issue #5732 <https://redmine.postgresql.org/issues/5732>`_ - Fixed some accessibility issues.
| `Issue #5734 <https://redmine.postgresql.org/issues/5734>`_ - Update the description of GIN and GiST indexes in the documentation.
| `Issue #5746 <https://redmine.postgresql.org/issues/5746>`_ - Fixed an issue where --load-server does not allow loading connections that use pg_services.
| `Issue #5748 <https://redmine.postgresql.org/issues/5748>`_ - Fixed incorrect reverse engineering SQL for Foreign key when creating a table.
| `Issue #5751 <https://redmine.postgresql.org/issues/5751>`_ - Enable the 'Configure' and 'View log' menu option when the server taking longer than usual time to start.
| `Issue #5754 <https://redmine.postgresql.org/issues/5754>`_ - Fixed an issue where schema diff is not working when providing the options to Foreign Data Wrapper, Foreign Server, and User Mapping.
| `Issue #5764 <https://redmine.postgresql.org/issues/5764>`_ - Fixed SQL for Row Level Security which is incorrectly generated.
| `Issue #5765 <https://redmine.postgresql.org/issues/5765>`_ - Fixed an issue in the query tool when columns are having the same name as javascript object internal functions.
| `Issue #5766 <https://redmine.postgresql.org/issues/5766>`_ - Fixed string indices must be integers issue for PostgreSQL < 9.3.
| `Issue #5773 <https://redmine.postgresql.org/issues/5773>`_ - Fixed an issue where the application ignores the fixed port configuration value.
| `Issue #5775 <https://redmine.postgresql.org/issues/5775>`_ - Ensure that 'setup-web.sh' should work in Debian 10.
| `Issue #5779 <https://redmine.postgresql.org/issues/5779>`_ - Remove illegal argument from trigger function in trigger DDL statement.
| `Issue #5794 <https://redmine.postgresql.org/issues/5794>`_ - Fixed excessive CPU usage by stopping the indefinite growth of the graph dataset.
| `Issue #5815 <https://redmine.postgresql.org/issues/5815>`_ - Fixed an issue where clicking on the 'Generate script' button shows a forever spinner due to pop up blocker.
| `Issue #5816 <https://redmine.postgresql.org/issues/5816>`_ - Ensure that the 'CREATE SCHEMA' statement should be present in the generated script if the schema is not present in the target database.
| `Issue #5820 <https://redmine.postgresql.org/issues/5820>`_ - Fixed an issue while refreshing Resource Group.
| `Issue #5833 <https://redmine.postgresql.org/issues/5833>`_ - Fixed an issue where custom sequences are not visible when show system objects are set to false.
| `Issue #5834 <https://redmine.postgresql.org/issues/5834>`_ - Ensure that the 'Remove Server Group' option is available in the context menu.
+58
View File
@@ -0,0 +1,58 @@
.. _rls_policy_dialog:
**************************
`RLS Policy Dialog`:index:
**************************
Use the *RLS Policy* dialog to Create a Row Level Security Policy.
.. note::
If the Row Level Security is enabled at table level and no policy is created then by default *Deny Policy* is applied. That means, no rows are visible or can be modified for that table.
The *RLS Policy* dialog creates a Row Level Security Policy through the following dialog tabs: *General*, and *Commands*. The *SQL* tab displays the SQL code generated by dialog selections.
.. image:: images/rls_policy_general_tab.png
:alt: RLS Policy General Tab
:align: center
Use the fields in the *General* tab to define the RLS Policy:
* Use the *Name* field to add a descriptive name for the RLS Policy. The name will be displayed in the *pgAdmin* tree control.
* Use the drop-down listbox next to *Role* to select the Role to which the RLS Policy is to be applied.
* Use the drop-down listbox next to *Type* to select the type of the policy.
Click the *Commands* tab to continue.
.. image:: images/rls_policy_commands_tab.png
:alt: RLS Policy Commands Tab
:align: center
Use the fields in the *Commands* tab to define the RLS Policy:
* Use the drop-down listbox next to *Event* to select the command to which policy applies. Valid options are ALL, SELECT, INSERT, UPDATE, and DELETE. Default is ALL.
* Use the *Using* field to add a SQL conditional expression returning boolean. This expression will be added to queries that refer to the table if row level security is enabled.
* Use the *With check* field to add a SQL conditional expression returning boolean. This expression will be used in INSERT and UPDATE queries against the table if row level security is enabled.
Click the *SQL* tab to continue.
Your entries in the *RLS Policy* dialog generate a SQL command (see an example
below). Use the *SQL* tab for review; revisit or switch tabs to make any
changes to the SQL command.
Example
*******
The following is an example of the sql command generated by user selections in
the *RLS Policy* dialog:
.. image:: images/rls_policy_sql_tab.png
:alt: RLS Policy sql tab
:align: center
The example shown demonstrates creating a RLS Policy named *account_managers* that applies the Row Level Security on the *accounts* table.
* Click the *Info* button (i) to access online help.
* Click the *Save* button to save work.
* Click the *Cancel* button to exit without saving work.
* Click the *Reset* button to restore configuration parameters.
+27 -35
View File
@@ -4,29 +4,29 @@
`Schema Diff`:index:
********************
**Schema Diff** is a feature that allows you to compare schema objects between
two database schemas. Use the *Tools* menu to access Schema Diff.
**Schema Diff** is a feature that allows you to compare objects between
two databases. Use the *Tools* menu to access Schema Diff.
The Schema Diff feature allows you to:
* Compare and synchronize the database schemas (from source to target).
* Compare and synchronize the database objects (from source to target).
* Visualize the differences between database schemas.
* Visualize the differences between database objects.
* List the differences in SQL statement for target schema objects.
* List the differences in SQL statement for target database objects.
* Generate synchronization scripts.
**Note** - The source and target databases must be of the same major
**Note** - The source and target database servers must be of the same major
version.
Click on *Schema Diff* under the *Tools* menu to open a selection panel. Choose
the source and target servers, databases, and schemas that will be
the source and target servers, and databases that will be
compared. After selecting the objects, click on the *Compare* button.
You can open multiple copies of *Schema Diff* in individual tabs
simultaneously. To close a copy of Schema Diff, click the *X* in the
simultaneously. To close a copy of Schema Diff, click the *X* in the
upper-right hand corner of the tab bar.
.. image:: images/schema_diff_dialog.png
@@ -44,7 +44,7 @@ The Schema Diff Object Comparison Panel
========================================
In the object comparison panel, you can select the source and target servers
of the same major version, databases, and schemas to be compared. You can
of the same major version, and databases to be compared. You can
select any server listed under the browser tree whether it is connected or
disconnected. If you select a server that is not connected then it will
prompt you for the password before using the server.
@@ -52,40 +52,36 @@ prompt you for the password before using the server.
Next, select the databases that will be compared. The databases can be the
same or different (and within the same server or from different servers).
Lastly, select the source and target schemas which will be compared.
.. image:: images/schema_diff_compare_button.png
:alt: Schema diff compare button
:align: center
After you select servers, databases, and schemas, click on the
After you select servers, and databases, click on the
*Compare* button to obtain the *Comparison Result*.
.. image:: images/schema_diff_comparison_results.png
:alt: Schema diff comparison results
:align: center
Use the drop-down lists of Functions, Materialized Views, Tables,
Trigger Functions, Procedures, and Views to view the DDL statements of
all the schema objects.
Use the drop-down lists of Database Objects to view the DDL statements.
In the upper-right hand corner of the object comparison panel is a *Filter*
option that you can use to filter the schema objects based on the
option that you can use to filter the database objects based on the
following comparison criteria:
* Identical – If the object is found in both schemas with the same SQL statement, then the comparison result is identical.
* Identical – If the object is found in both databases with the same SQL statement, then the comparison result is identical.
* Different – If the object is found in both schemas but have different SQL statements, then the comparison result is different.
* Different – If the object is found in both databases but have different SQL statements, then the comparison result is different.
* Source Only – If the object is found in source schema only and not in target schema, then the comparison result is source only.
* Source Only – If the object is found in source database only and not in target database, then the comparison result is source only.
* Target Only – If the object is found in target schema only and not in source schema, then the comparison result is target only.
* Target Only – If the object is found in target database only and not in source database, then the comparison result is target only.
.. image:: images/schema_diff_filter_option.png
:alt: Schema diff filter option
:align: center
Click on any of the schema objects in the object comparison panel to
Click on any of the database objects in the object comparison panel to
display the DDL Statements of that object in the DDL Comparison panel.
@@ -94,36 +90,32 @@ Schema Diff DDL Comparison Panel
The *DDL Comparison* panel displays three columns:
* The first column displays the DDL statement of the object from the source schema.
* The first column displays the DDL statement of the object from the source database.
* The second column displays the DDL statement of the object from the target schema.
* The second column displays the DDL statement of the object from the target database.
* The third column displays the difference in the SQL statement of the target schema object.
* The third column displays the difference in the SQL statement of the target database object.
.. image:: images/schema_diff_DDL_comparison.png
:alt: Schema diff DDL comparison
:align: center
You can review the DDL statements of all the schema objects to
You can review the DDL statements of all the database objects to
check for the differences in the SQL statements.
Also, you can generate the SQL script of the differences found in the
target schema object based on the SQL statement of the source schema
object. To generate the script, select the checkboxes of the schema
target database object based on the SQL statement of the source database
object. To generate the script, select the checkboxes of the database
objects in the object comparison panel and then click on the *Generate Script*
button in the upper-right hand corner of the object comparison panel.
.. image:: images/schema_diff_generate_script.png
:alt: Schema diff generate script
:align: center
Select the schema objects and click on the *Generate Script*
Select the database objects and click on the *Generate Script*
button to open the *Query Tool* in a new tab, with the difference
in the SQL statement displayed in the *Query Editor*.
If you have clicked on the schema object to check the difference
If you have clicked on the database object to check the difference
generated in the *DDL Comparison* Panel, and you have not selected the
checkbox of the schema object, PEM will open the *Query Tool* in a new
checkbox of the database object, pgAdmin will open the *Query Tool* in a new
tab, with the differences in the SQL statements displayed in the *Query Editor*.
You can also use the *Copy* button to copy the difference generated in
@@ -133,4 +125,4 @@ the *DDL Comparison* panel.
:alt: Schema diff generate script query editor
:align: center
Apply the SQL Statement in the target schema to synchronize the schemas.
Apply the SQL Statement in the target database to synchronize the databases.
+5 -2
View File
@@ -17,14 +17,17 @@ shortcut (default ALT+SHIFT+S).
The minimum pattern length are 3 characters. The search performed is
non-casesensitive and will find all objets whose name contains the pattern.
You can only search for object names.
You can only search for object names currently. Examples are: abc,
%ab%, ab%c, %%%, etc.
The result is presented in the grid with object name, object type and
the object tree path in the :ref:`browser <tree_control>`. You can double
click on a result row to select the object in the
:ref:`browser <tree_control>`. If the object is greyed out, this means that you
have not enabled those object types in the :ref:`preferences <preferences>`,
so you can't double click on it.
so you can't double click on it. You can click on the ellipsis appended to
the function and procedure names to see there arguments.
You can filter based on a particular object type by selecting one from the
object type dropdown. If the search button is hit when one of the object type
+9
View File
@@ -8,6 +8,15 @@ pgAdmin may be deployed as a web application by configuring the app to run in
server mode and then deploying it either behind a webserver running as a reverse
proxy, or using the WSGI interface.
When deployed in server mode, there are two notable differences for users:
* Users must login before they can use pgAdmin. An initial superuser account
is created when server mode is initialised, and this user can add additional
superusers and non-superusers as required.
* File storage is restricted to a virtual root directory for each individual
user under the directory configured using the ``STORAGE_DIR`` configuration
parameter. Users do not have access to the complete filesystem of the server.
The following instructions demonstrate how pgAdmin may be run as a WSGI
application under ``Apache HTTPD``, using ``mod_wsgi``, standalone using ``uWSGI``
or ``Gunicorn``, or under ``NGINX`` using using ``uWSGI`` or ``Gunicorn``.
+17 -1
View File
@@ -16,15 +16,31 @@ Use the fields in the *General* tab to identify the server:
* Use the *Name* field to add a descriptive name for the server; the name
specified will be displayed in the *Browser* tree control.
* Use the drop-down list box in the *Server group* field to select the parent
node for the server; the server will be displayed in the *Browser* tree
control within the specified group.
* Use the color-picker in the *Background* field to specify the background
color for the server.
* Use the color-picker in the *Foreground* field to specify the foreground
color for the server.
* If the *Connect now?* checkbox is checked, the client will attempt a
connection to the server upon completion of the dialog; this is the default
* If the *Shared with all?* switch is moved to *Yes* then that server can be
shared with all the other users. This option is available only to admin users. For more information on users see :ref:`User Management Dialog <user_management>`. The users can access the shared servers with some restritctions. The Users accessing the shared servers cannot do the following operations on the shared servers:
* Create a server
* Delete the server
* Rename the server
* Rename the group server
* Change of host, port, and maintenance database
Please note that once the server is shared, it's icon is changed in the browser tree.
* Provide a comment about the server in the *Comments* field.
Click the *Connection* tab to continue.
@@ -183,4 +199,4 @@ Use the fields in the *Advanced* tab to configure a connection:
.. toctree::
clear_saved_passwords
clear_saved_passwords
+5 -3
View File
@@ -7,7 +7,7 @@
Use the *Table* dialog to create or modify a table.
The *Table* dialog organizes the development of a table through the following
dialog tabs: *General*, *Columns*, *Constraints*, *Advanced*, *Parameter*, and
dialog tabs: *General*, *Columns*, *Constraints*, *Advanced*, *Parition*, *Parameter*, and
*Security*. The *SQL* tab displays the SQL code generated by dialog selections.
.. image:: images/table_general.png
@@ -389,6 +389,8 @@ Click the *Advanced* tab to continue.
Use the fields in the *Advanced* tab to define advanced features for the table:
* Move the *RLS Policy?* switch to the *Yes* position to enable the Row Level Security.
* Move the *Force RLS Policy?* to the *Yes* position to force the policy on the owner of the table.
* Use the drop-down listbox next to *Of type* to copy the table structure from
the specified composite type. Please note that a typed table will be dropped
if the type is dropped (with DROP TYPE ... CASCADE).
@@ -485,10 +487,10 @@ thresholds; use the *Table* tab and the *Toast Table* tab to customize values
for the table and the associated toast table:
* Move the *Custom auto-vacuum?* switch to the *Yes* position to perform custom
maintenance on the table.
* Move the *Enabled?* switch to the *Yes* position to select values in the
maintenance on the table and to select values in the
*Vacuum table*. The *Vacuum Table* provides default values for maintenance
operations.
* Changing *Autovacuum enabled?* to *Not set* will reset autovacuum_enabled.
Provide a custom value in the *Value* column for each metric listed in the
*Label* column.
+1 -9
View File
@@ -22,10 +22,6 @@ div.body {
background-color: #fff;
}
div.related a {
color: #295C85;
}
div.related a:hover {
color: #ebeef3 !important;
text-decoration: underline !important;
@@ -287,23 +283,19 @@ div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points {
padding-right: 0px;
margin-left: 0;
margin-right: 0;
list-style: none;
}
div.sphinxsidebar ul {
margin: 10px 10px 10px 0px;
}
div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points {
list-style: none;
}
div.sphinxsidebar ul li.toctree-l1 a cite {
font-style: normal;
-webkit-font-smoothing: antialiased;
font-weight: 400;
color: #295C85;
font-family: Roboto, Helvetica Neue, -apple-system, BlinkMacSystemFont, Segoe UI, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
-webkit-font-smoothing: antialiased;
border:none;
padding:0px;
background-color: #f5f7f9;
+115 -7
View File
@@ -1,6 +1,12 @@
This directory contains the build runner script for creating .DEB packages for
Debian and Ubuntu.
Supported platforms
===================
Debian 9 & 10
Ubuntu 16.04, 18.04, 19.04 & 19.10
Build configuration
===================
@@ -35,13 +41,115 @@ pgadmin4-web_<version>_<distro>_<distro_version>_<arch>.deb
The server mode setup script for configuring Apache HTTPD. Requires the
server package.
Supported platforms
===================
Building a repo
===============
Debian 9 & 10
Ubuntu 16.04, 18.04, 19.04 & 19.10
An APT repo can be created by building DEBs for the required platforms, moving
them into the required directory structure, and then running a number of
commands to create the required metadata. The pgAdmin repos use the following
structure (which doesn't entirely follow the normal structure for APT, but
does seem to work well unlike other attempts):
Warning
=======
<root>
bionic
dists
pgadmin4
InRelease
main
binary-all
Packages
Packages.gz
pgadmin4_4.21_all.deb
pgadmin4-web_4.21_all.deb
binary-amd64
Packages
Packages.gz
pgadmin4-desktop_4.21_amd64.deb
pgadmin4-server_4.21_amd64.deb
binary-i386
Packages
Packages.gz
Release
Release.gpg
Release.gz
buster
disco
eoan
focal
README
stretch
xenial
These scripts are experimental - use at your own risk!
Note that only the first branches are shown above; other branches (e.g. for
buster, disco etc. follow the structure shown for bionic.
Technically there are actually multiple repos here, one for each OS release.
Note also that the binary-i386 directories do not contain any packages as we're
not building 32bit packages for Linux. The directories and package indexes are
present though, to prevent warnings being emitted on amd64 machines which are
configured to support 32bit packages as well.
In order to sign the repositories you need to import your signing private key
into the gnupg2 keystore, for example:
gpg --import signing_key.priv
Once the files are in the right structure, we need to run a number of commands
to generate the metadata, and sign the relevant files using GPG (in APT, we
sign the repository indexes rather than the packages themselves.
To create the metadata, first we create a config file for the apt-ftparchive
program in $HOME/aptftp.conf (without the start/end markers):
----------
APT::FTPArchive::Release {
Origin "pgAdmin Development Team";
Label "pgAdmin 4";
Suite "pgadmin4";
Architectures "amd64 all";
Components "main";
Description "pgAdmin 4 - Development Tools for PostgreSQL";
};
Default {
Packages::Compress ". gzip bzip2";
Sources::Compress ". gzip bzip2";
Contents::Compress ". gzip bzip2";
};
----------
Next, we create the package indexes. Run the following command for each OS
release to be included (in the example, we're using bionic):
for ARCH in all amd64 i386; do cd <root>/bionic && apt-ftparchive packages -c=$HOME/aptftp.conf dists/pgadmin4/main/binary-${ARCH} > dists/pgadmin4/main/binary-${ARCH}/Packages && gzip -k dists/pgadmin4/main/binary-${ARCH}/Packages; done
Now we need to create the release file for each OS release (again, using bionic
in the example:
cd <root>/bionic/dists/pgadmin4 && apt-ftparchive release -c=$HOME/aptftp.conf . > Release && gzip -k Release
Finally, we can sign the release files. Replace <key name> with the email
address on your signing key:
cd <root>/bionic/dists/pgadmin4 && gpg -u <key name> -bao Release.gpg Release
cd <root>/bionic/dists/pgadmin4 && gpg -u <key name> --clear-sign --output InRelease Release
Note that it is important to run each command in the correct directory (hence
the cd commands) to ensure the relative paths are created correctly in the
indexes.
Repository Configuration
========================
pgAdmin repo configurations live in /etc/apt/sources.list.d/pgadmin4.list. The
file can be created with a command such as:
sudo sh -c 'echo "deb https://server.company.com/apt/$(lsb_release -cs) pgadmin4 main" > /etc/apt/sources.list.d/pgadmin4.list && apt update'
Assuming that <root> in the repository structure corresponds to
https://server.company.com/apt/ from the client's perspective.
If you have signed the repository, you'll also need to import the key on the
client. This is done as follows for the pgAdmin signing key; adjust the URL as
needed for your own:
curl http://www.pgadmin.org/static/packages_pgadmin_org.pub | sudo apt-key add
+8 -1
View File
@@ -35,7 +35,7 @@ cat << EOF > "${SERVERROOT}/DEBIAN/control"
Package: ${APP_NAME}-server
Version: ${APP_LONG_VERSION}
Architecture: ${OS_ARCH}
Depends: python3, libpq5
Depends: python3, libpq5 (>= 11.0)
Recommends: postgresql-client | postgresql-client-12 | postgresql-client-11 | postgresql-client-10
Maintainer: pgAdmin Development Team <pgadmin-hackers@postgresql.org>
Description: The core server package for pgAdmin. pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
@@ -106,3 +106,10 @@ EOF
# Build the Debian meta package
fakeroot dpkg-deb --build "${METAROOT}" "${DISTROOT}/${APP_NAME}_${APP_LONG_VERSION}_all.deb"
# Get the libpq package
pushd ${DISTROOT} 1> /dev/null
apt-get download libpq5
popd 1> /dev/null
echo "Completed. DEBs created in ${DISTROOT}."
+7 -2
View File
@@ -6,11 +6,16 @@ if [ "$EUID" -ne 0 ]
fi
echo "Installing system pre-requisites..."
apt install -y curl apt-transport-https ca-certificates
apt install -y curl apt-transport-https ca-certificates gnupg
echo "Removing yarn (which may not be the package we expect)..."
dpkg -r yarn
# PostgreSQL
echo "Setting up the PostgreSQL repo..."
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# Node repo
echo "Setting up the NodeJS repo..."
curl -sL https://deb.nodesource.com/setup_12.x | bash -
@@ -25,5 +30,5 @@ apt update
# Install pre-reqs
echo "Installing build pre-requisites..."
apt install -y build-essential python3-dev python3-venv python3-sphinx libpq-dev libffi-dev qt5-default nodejs yarn
apt install -y build-essential python3-dev python3-venv python3-sphinx python3-wheel libpq-dev libffi-dev qt5-default nodejs yarn
+12 -4
View File
@@ -53,6 +53,10 @@ _create_python_virtualenv() {
python3 -m venv venv
source venv/bin/activate
# Make sure we have the wheel package present
pip3 install wheel
# Install the requirements
pip3 install --no-cache-dir --no-binary psycopg2 -r ${SOURCEDIR}/requirements.txt
# Figure out some paths for use when completing the venv
@@ -107,9 +111,9 @@ _build_runtime() {
make clean
fi
if hash qmake-qt5 2>/dev/null; then
qmake-qt5
PGADMIN_PYTHON_DIR=/usr qmake-qt5
else
qmake
PGADMIN_PYTHON_DIR=/usr qmake
fi
make
mkdir -p "${DESKTOPROOT}/usr/${APP_NAME}/bin"
@@ -139,10 +143,10 @@ _copy_code() {
# Remove any TCL-related files that may cause us problems
find "${SERVERROOT}/usr/${APP_NAME}/venv/" -name "_tkinter*" -print0 | xargs -0 rm -rf
pushd ${SOURCEDIR}/web
pushd ${SOURCEDIR}/web > /dev/null
yarn install
yarn run bundle
popd
popd > /dev/null
# copy the web directory to the bundle as it is required by runtime
cp -r "${SOURCEDIR}/web" "${SERVERROOT}/usr/${APP_NAME}/web/"
@@ -154,6 +158,10 @@ _copy_code() {
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
find . -name "__pycache__" -type d -print0 | xargs -0 rm -rf
# License files
cp "${SOURCEDIR}/LICENSE" "${SERVERROOT}/usr/${APP_NAME}/"
cp "${SOURCEDIR}/DEPENDENCIES" "${SERVERROOT}/usr/${APP_NAME}/"
# Web setup script
mkdir -p "${WEBROOT}/usr/${APP_NAME}/bin/"
cp "${SOURCEDIR}/pkg/linux/setup-web.sh" "${WEBROOT}/usr/${APP_NAME}/bin/"
+49 -15
View File
@@ -9,16 +9,28 @@ if [ "$EUID" -ne 0 ]
exit 1
fi
if [[ "$#" -ne 0 ]] && ([[ "$#" -eq 1 ]] && [[ "$1" != "--yes" ]]); then
echo "Usage: $0 [--yes]"
exit 1
fi
# Get the distro
IS_REDHAT=0
IS_DEBIAN=0
UNAME=$(uname -a)
# Is this an automated install?
AUTOMATED=0
if [ "$#" -eq 1 ]; then
AUTOMATED=1
echo "Running in non-interactive mode..."
fi
if [ -f /etc/redhat-release ]; then
IS_REDHAT=1
APACHE=httpd
echo "Setting up pgAdmin 4 in web mode on a Redhat platform..."
elif [[ ${UNAME} =~ "Ubuntu" ]] || [[ ${UNAME} =~ "debian" ]]; then
elif [[ ${UNAME} =~ "Ubuntu" ]] || [[ ${UNAME} =~ "Debian" ]]; then
IS_DEBIAN=1
APACHE=apache2
echo "Setting up pgAdmin 4 in web mode on a Debian platform..."
@@ -47,22 +59,33 @@ fi
# Set SELinux up:
if [ ${IS_REDHAT} == 1 ]; then
echo "Configuring SELinux..."
setsebool -P httpd_can_network_connect 1
setsebool -P httpd_can_network_connect_db 1
semanage fcontext -a -t httpd_var_lib_t '/var/lib/pgadmin(/.*)?'
restorecon -R -v /var/lib/pgadmin
semanage fcontext -a -t httpd_log_t '/var/log/pgadmin(/.*)?'
restorecon -R -v /var/log/pgadmin
setsebool -P httpd_can_network_connect 1 1> /dev/null
setsebool -P httpd_can_network_connect_db 1 1> /dev/null
semanage fcontext -a -t httpd_var_lib_t '/var/lib/pgadmin(/.*)?' 1> /dev/null
restorecon -R -v /var/lib/pgadmin 1> /dev/null
semanage fcontext -a -t httpd_log_t '/var/log/pgadmin(/.*)?' 1> /dev/null
restorecon -R -v /var/log/pgadmin 1> /dev/null
fi
# Setup Apache on Debian/Ubuntu
if [ ${IS_DEBIAN} == 1 ]; then
read -p "We can now configure the Apache Web server for you. This involves enabling the wsgi module and configuring the pgAdmin 4 application to mount at /pgadmin4. Do you wish to continue (y/n)? " RESPONSE
if [ ${AUTOMATED} == 1 ]; then
RESPONSE=Y
else
read -p "We can now configure the Apache Web server for you. This involves enabling the wsgi module and configuring the pgAdmin 4 application to mount at /pgadmin4. Do you wish to continue (y/n)? " RESPONSE
fi
case ${RESPONSE} in
y|Y )
a2enmod wsgi 1> /dev/null
a2enconf pgadmin4 1> /dev/null
;;
# Debian uses a different path to Ubuntu
if [[ ${UNAME} =~ "Debian" ]]; then
/sbin/a2enmod wsgi 1> /dev/null
/sbin/a2enconf pgadmin4 1> /dev/null
else
/usr/sbin/a2enmod wsgi 1> /dev/null
/usr/sbin/a2enconf pgadmin4 1> /dev/null
fi
;;
* )
exit 1;;
esac
@@ -70,20 +93,30 @@ fi
APACHE_STATUS=`ps cax | grep ${APACHE}`
if [ $? -eq 0 ]; then
read -p "The Apache web server is running. A restart is required for the pgAdmin 4 installation to complete. Would you like to continue (y/n)? " RESPONSE
if [ ${AUTOMATED} == 1 ]; then
RESPONSE=Y
else
read -p "The Apache web server is running and must be restarted for the pgAdmin 4 installation to complete. Continue (y/n)? " RESPONSE
fi
case ${RESPONSE} in
y|Y )
systemctl restart ${APACHE}
if [ $? != 0 ]; then
echo "Error restarting ${APACHE}. Please check the systemd logs"
else
echo "Apache successfully restarted. You can now start using pgAdmin 4 in web mode"
echo "Apache successfully restarted. You can now start using pgAdmin 4 in web mode at http://127.0.0.1/pgadmin4"
fi;;
* )
exit 1;;
esac
else
read -p "The Apache web server is not running. We can enable and start the web server for you to finish pgAdmin 4 installation. Would you like to continue (y/n)? " RESPONSE
if [ ${AUTOMATED} == 1 ]; then
RESPONSE=Y
else
read -p "The Apache web server is not running. We can enable and start the web server for you to finish pgAdmin 4 installation. Continue (y/n)? " RESPONSE
fi
case ${RESPONSE} in
y|Y )
systemctl enable ${APACHE}
@@ -97,7 +130,8 @@ else
if [ $? != 0 ]; then
echo "Error starting ${APACHE}. Please check the systemd logs"
else
echo "Apache successfully started. You can now start using pgAdmin 4 in web mode"
echo "Apache successfully started."
echo "You can now start using pgAdmin 4 in web mode at http://127.0.0.1/pgadmin4"
fi;;
* )
exit 1;;
+45
View File
@@ -0,0 +1,45 @@
Building pgAdmin4.dmg on Mac OS X
=================================
Required Packages (Either build the sources or get them from macports or
similar):
1. Python installation
- Python 3.4+ or above from https://www.python.org/
2. QT installation
- Qt 5 from http://www.qt.io/
3. PostgreSQL installation
- PostgreSQL 9.5 or above from http://www.postgresql.org/
Building:
1. If a value different from the default of /usr/local/python is required, set
the PGADMIN_PYTHON_DIR environment variable to the Python root installation
directory, e.g.
export PGADMIN_PYTHON_DIR=/opt/local
2. If a value different from the default of ~/Qt/5.13.2/clang_64, is required,
set the PGADMIN_QT_DIR environment variable to the QT root installation
directory, e.g.
export PGADMIN_QT_DIR=~/Qt/5.14.2/clang_64
3. If a value different from the default of /usr/local/pgsql is required, set
the PGADMIN_POSTGRES_DIR environment variable to the PostgreSQL installation
directory, e.g.
export PGADMIN_POSTGRES_DIR=/opt/local/pgsql
4. Copy framework.conf.in to framework.conf, and edit the values accordingly.
5. If you want to codesign the appbundle, copy codesign.conf.in to
codesign.conf and set the values accordingly.
6. To build, go to pgAdmin4 source root directory and execute "make appbundle".
This will create the python virtual environment and install all the required
python modules mentioned in the requirements file using pip, build the
runtime code and finally create the app bundle and the DMG in ./dist
directory.
-32
View File
@@ -1,32 +0,0 @@
Building pgAdmin4.dmg on Mac OS X
=================================
Required Packages (Either build the sources or get them from macports or similar):
1. Python installation
- Python 2.7 or 3.4+ or above from https://www.python.org/
2. QT installation
- Qt 4 or 5 from http://www.qt.io/
3. PostgreSQL installation
- PostgreSQL 9.1 or above from http://www.postgresql.org/
Building:
1. Set the PYTHON_HOME environment variable to the Python root installation directory, e.g.
export PYTHON_HOME=/System/Library/Frameworks/Python.framework/Versions/2.7
2. Set the QTDIR environment variable to the QT root installation directory, e.g.
export QTDIR=~/Qt/5.5/clang_64
3. Set the PGDIR environment variable to the PostgreSQL installation directory, e.g.
export PGDIR=/usr/local/pgsql
4. To build, go to pgAdmin4 source root directory and execute "make appbundle". This will
create the python virtual environment and install all the required python modules mentioned in the
requirements file using pip, build the runtime code and finally create the app bundle and the DMG
in ./dist directory
+386
View File
@@ -0,0 +1,386 @@
_setup_env() {
APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
if [ ! -z ${APP_SUFFIX} ]; then
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
BUNDLE_DIR="${BUILD_ROOT}/${APP_NAME}.app"
}
_cleanup() {
echo Cleaning up the old environment and app bundle...
rm -rf ${SOURCE_DIR}/runtime/*.app
rm -rf ${BUILD_ROOT}
rm -f ${DIST_ROOT}/*.dmg
}
_create_venv() {
PATH=${PGADMIN_POSTGRES_DIR}/bin:${PATH}
LD_LIBRARY_PATH=${PGADMIN_POSTGRES_DIR}/lib:${LD_LIBRARY_PATH}
test -d ${BUILD_ROOT} || mkdir ${BUILD_ROOT}
cd ${BUILD_ROOT}
${PYTHON_EXE} -m venv --copies venv
source venv/bin/activate
pip install --no-cache-dir --no-binary psycopg2 -r ${SOURCE_DIR}/requirements.txt
# Figure the source path for use when completing the venv
SOURCE_PYMODULES_PATH=$(dirname $("${PYTHON_EXE}" -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
# Figure the target path for use when completing the venv
# Use "python" here as we want the venv path
TARGET_PYMODULES_PATH=$(dirname $(python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"))
# Copy in the additional system python modules
cp -R ${SOURCE_PYMODULES_PATH}/* "${TARGET_PYMODULES_PATH}/"
# Link the python<version> directory to python so that the private environment path is found by the application.
ln -s "$(basename ${TARGET_PYMODULES_PATH})" "${TARGET_PYMODULES_PATH}/../python"
# Remove tests
find venv -name "test" -type d -print0 | xargs -0 rm -rf
find venv -name "tests" -type d -print0 | xargs -0 rm -rf
}
_build_runtime() {
cd ${SOURCE_DIR}/runtime
if [ -f Makefile ]; then
make clean
fi
${QMAKE}
make
cp -r pgAdmin4.app "${BUNDLE_DIR}"
}
_build_docs() {
cd ${SOURCE_DIR}/docs/en_US
test -d "${BUNDLE_DIR}/Contents/Resources/docs/en_US" || mkdir -p "${BUNDLE_DIR}/Contents/Resources/docs/en_US"
cp -r _build/html "${BUNDLE_DIR}/Contents/Resources/docs/en_US/"
}
_complete_bundle() {
cd ${SCRIPT_DIR}
# Copy the binary utilities into place
mkdir -p "${BUNDLE_DIR}/Contents/SharedSupport/"
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_dump" "${BUNDLE_DIR}/Contents/SharedSupport/"
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_dumpall" "${BUNDLE_DIR}/Contents/SharedSupport/"
cp "${PGADMIN_POSTGRES_DIR}/bin/pg_restore" "${BUNDLE_DIR}/Contents/SharedSupport/"
cp "${PGADMIN_POSTGRES_DIR}/bin/psql" "${BUNDLE_DIR}/Contents/SharedSupport/"
# Replace the place holders with the current version
sed -e "s/PGADMIN_LONG_VERSION/${APP_LONG_VERSION}/g" -e "s/PGADMIN_SHORT_VERSION/${APP_SHORT_VERSION}/g" pgadmin.Info.plist.in > pgadmin.Info.plist
# copy Python private environment to app bundle
cp -PR ${BUILD_ROOT}/venv "${BUNDLE_DIR}/Contents/Resources/"
# Remove any TCL-related files that may cause us problems
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name "_tkinter*" -print0 | xargs -0 rm -f
test -d "${BUNDLE_DIR}/Contents/Resources" || mkdir -p "${BUNDLE_DIR}/Contents/Resources"
# Create qt.conf so that app knows where the Plugins are present
cat >> "${BUNDLE_DIR}/Contents/Resources/qt.conf" << EOF
[Paths]
Plugins = PlugIns
EOF
test -d "${BUNDLE_DIR}/Contents/Frameworks" || mkdir -p "${BUNDLE_DIR}/Contents/Frameworks"
test -d "${BUNDLE_DIR}/Contents/PlugIns/platforms" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/platforms"
test -d "${BUNDLE_DIR}/Contents/PlugIns/imageformats" || mkdir -p "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
cp -f ${PGADMIN_QT_DIR}/plugins/platforms/libqcocoa.dylib "${BUNDLE_DIR}/Contents/PlugIns/platforms"
cp -f ${PGADMIN_QT_DIR}/plugins/imageformats/libqsvg.dylib "${BUNDLE_DIR}/Contents/PlugIns/imageformats"
cp -f ${PGADMIN_POSTGRES_DIR}/lib/libpq.5.dylib "${BUNDLE_DIR}/Contents/Frameworks"
local todo todo_old fw_relpath lib lib_bn
pushd "${BUNDLE_DIR}" > /dev/null
# We skip nested apps here - those are treated specially
todo=$(file `find ./ -perm +0111 ! -type d ! -path "*.app/*" ! -name "*.app"` | grep -E "Mach-O 64-bit" | awk -F ':| ' '{ORS=" "; print $1}')
echo "Found executables: ${todo}"
while test "${todo}" != ""; do
todo_old=${todo} ;
todo="" ;
for todo_obj in ${todo_old}; do
echo "Post-processing: ${todo_obj}"
# Figure out the relative path from todo_obj to Contents/Frameworks
fw_relpath=$(echo "${todo_obj}" | sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | sed -n 's|[^/][^/]*/|../|gp')"Contents/Frameworks"
fw_relpath_old=${fw_relpath}
# Find all libraries $todo_obj depends on, but skip system libraries
for lib in $(otool -L ${todo_obj} | grep "Qt\|dylib\|Frameworks\|PlugIns" | grep -v ":" | sed 's/(.*//' | egrep -v '(/usr/lib)|(/System)|@executable_path@'); do
if echo ${lib} | grep "PlugIns\|libqcocoa" > /dev/null; then
lib_loc="Contents/PlugIns/platforms"
elif echo ${lib} | grep "PlugIns\|libqsvg" > /dev/null; then
lib_loc="Contents/PlugIns/imageformats"
elif echo ${lib} | grep "Qt" > /dev/null; then
qtfw_path="$(dirname ${lib} | sed 's|.*\(Qt.*framework\)|\1|')"
lib_loc="Contents/Frameworks/${qtfw_path}"
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
lib_loc="$(dirname ${todo_obj})"
qtfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
fi
elif echo ${lib} | grep "Python" > /dev/null; then
pyfw_path="$(dirname ${lib} | sed 's|.*\(Python.*framework\)|\1|')"
lib_loc="Contents/Frameworks/${pyfw_path}"
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
lib_loc="$(dirname ${todo_obj})"
pyfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
fi
else
lib_loc="Contents/Frameworks"
fi
lib_bn="$(basename "${lib}")" ;
if ! test -f "${lib_loc}/${lib_bn}"; then
target_file=""
target_path=""
echo "Adding symlink: ${lib_bn} (because of: ${todo_obj})"
# Copy the QT and Python framework
if echo ${lib} | grep Qt > /dev/null ; then
test -d ${lib_loc} || mkdir -p ${lib_loc}
echo Copying -R ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} to ${lib_loc}/
cp ${PGADMIN_QT_DIR}/lib/${qtfw_path}/${lib_bn} ${lib_loc}/
elif echo ${lib} | grep Python > /dev/null ; then
test -d ${lib_loc} || mkdir -p ${lib_loc}
cp -R "${lib}" "${lib_loc}/${lib_bn}"
else
cp -R "${lib}" "${lib_loc}/${lib_bn}"
fi
if ! test -L "${lib_loc}/${lib_bn}"; then
chmod 755 "${lib_loc}/${lib_bn}"
else
target_file=$(readlink "${lib}")
target_path=$(dirname "${lib}")/${target_file}
echo "Adding symlink target: ${target_path}"
cp "${target_path}" "${lib_loc}/${target_file}"
chmod 755 "${lib_loc}/${target_file}"
fi
echo "Rewriting ID in ${lib_loc}/${lib_bn} to ${lib_bn}"
install_name_tool -id "${lib_bn}" "${lib_loc}/${lib_bn}"
todo="${todo} ./${lib_loc}/${lib_bn}"
fi
if echo ${lib} | grep Qt > /dev/null ; then
fw_relpath="${fw_relpath}/${qtfw_path}"
fi
if echo ${lib} | grep Python > /dev/null ; then
fw_relpath="${fw_relpath}/${pyfw_path}"
fi
chmod +w ${todo_obj}
echo "Rewriting library ${lib} to @loader_path/${fw_relpath}/${lib_bn} in ${todo_obj}"
install_name_tool -change "${lib}" "@loader_path/${fw_relpath}/${lib_bn}" "${todo_obj}"
install_name_tool -change "${target_path}" "@loader_path/${fw_relpath}/${target_file}" "${todo_obj}"
fw_relpath="${fw_relpath_old}"
done
done
done
# Fix the rpaths for psycopg module
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libpq.5.dylib @loader_path/../../../../../../Frameworks/libpq.5.dylib
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libssl.1.0.0.dylib @loader_path/../../../../../../Frameworks/libssl.1.0.0.dylib
find "${BUNDLE_DIR}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libcrypto.1.0.0.dylib @loader_path/../../../../../../Frameworks/libcrypto.1.0.0.dylib
echo "App completed: ${BUNDLE_DIR}"
popd > /dev/null
pushd ${SOURCE_DIR}/web > /dev/null
yarn install
yarn run bundle
curl https://curl.haxx.se/ca/cacert.pem -o cacert.pem -s
popd > /dev/null
# copy the web directory to the bundle as it is required by runtime
cp -r ${SOURCE_DIR}/web "${BUNDLE_DIR}/Contents/Resources/"
cd "${BUNDLE_DIR}/Contents/Resources/web"
rm -f pgadmin4.db config_local.*
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
find . -name "tests" -type d -print0 | xargs -0 rm -rf
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
find . -name ".DS_Store" -print0 | xargs -0 rm -f
echo "SERVER_MODE = False" > config_distro.py
echo "HELP_PATH = '../../../docs/en_US/html/'" >> config_distro.py
echo "DEFAULT_BINARY_PATHS = {" >> config_distro.py
echo " 'pg': '\$DIR/../../SharedSupport'," >> config_distro.py
echo " 'ppas': ''" >> config_distro.py
echo "}" >> config_distro.py
# License files
cp -r ${SOURCE_DIR}/LICENSE "${BUNDLE_DIR}/Contents/"
cp -r ${SOURCE_DIR}/DEPENDENCIES "${BUNDLE_DIR}/Contents/"
# Remove the .pyc files if any
find "${BUNDLE_DIR}" -name "*.pyc" -print0 | xargs -0 rm -f
}
_framework_config() {
# Get the config
source ${SCRIPT_DIR}/framework.conf
echo Reorganising the framework structure...
# Create "Current" and "Current/Resources" inside each of the framework dirs
find "${BUNDLE_DIR}/Contents/Frameworks"/*framework -type d -name "Versions" | while read -r framework_dir; do
pushd "${framework_dir}" > /dev/null
# Create framework 'Current' soft link
VERSION_NUMBER=`ls -1`
ln -s ${VERSION_NUMBER} Current
# Create "Resources" subdirectory
if [ ! -d Current/Resources ]; then
mkdir Current/Resources
fi
popd > /dev/null
done
# Stuff for Qt framework files only
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "Qt*framework" | while read -r framework_dir; do
pushd "${framework_dir}" > /dev/null
# Create soft link to the framework binary
ln -s Versions/Current/Qt*
# Create soft link to the framework Resources dir
ln -s Versions/Current/Resources
# Create the Info.plist files
MYNAME=`ls -1 Qt*`
if [ -f Resources/Info.plist ]; then
chmod +w Resources/Info.plist
fi
sed 's/__SHORT_VERSION__/${QT_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Qt5" | sed 's/__FULL_VERSION__/${QT_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
popd > /dev/null
done
# Same thing, but specific to the Python framework dir
find "${BUNDLE_DIR}/Contents/Frameworks" -type d -name "P*framework" | while read -r framework_dir; do
pushd "${framework_dir}" > /dev/null
# Create soft link to the framework binary
ln -s Versions/Current/Py*
# Create soft link to the framework Resources dir
ln -s Versions/Current/Resources
# Create the Info.plist file
MYNAME=`ls -1 Py*`
sed 's/__SHORT_VERSION__/${PYTHON_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Python" | sed 's/__FULL_VERSION__/${PYTHON_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist"
popd > /dev/null
done
}
_codesign_binaries() {
if [ ${CODESIGN} -eq 0 ]; then
return
fi
if [ -z "${DEVELOPER_ID}" ] ; then
echo "Developer ID Application not found in codesign.conf" >&2
exit 1
fi
if [ -z "${DEVELOPER_BUNDLE_ID}" ]; then
echo "Developer Bundle Identifier not found in codesign.conf" >&2
fi
echo Signing ${BUNDLE_DIR} binaries...
IFS=$'\n'
for i in $(find "${BUNDLE_DIR}" -type f -perm +111 -exec file "{}" \; | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle" | awk -F":| \\\(" '{print $1}' | uniq)
do
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
done
echo Signing ${BUNDLE_DIR} libraries...
for i in $(find "${BUNDLE_DIR}" -type f -name "*.dylib*")
do
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
done
}
_codesign_bundle() {
if [ ${CODESIGN} -eq 0 ]; then
return
fi
# Sign the .app
echo Signing ${BUNDLE_DIR}...
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE_DIR}"
# Verify it worked
echo Verifying the signature...
codesign --verify --verbose --deep --force "${BUNDLE_DIR}"
echo ${BUNDLE_DIR} successfully signed.
}
_create_dmg() {
# move to the directory where we want to create the DMG
test -d ${DIST_ROOT} || mkdir ${DIST_ROOT}
cd ${DIST_ROOT}
DMG_LICENCE=./../pkg/mac/licence.rtf
DMG_VOLUME_NAME=${APP_NAME}
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
DMG_IMAGE=${DMG_NAME}-${APP_LONG_VERSION}.dmg
DMG_DIR=./${DMG_IMAGE}.src
if test -e "${DMG_DIR}"; then
echo "Directory ${DMG_DIR} already exists. Please delete it manually." >&2
exit 1
fi
echo "Cleaning up"
rm -f "${DMG_IMAGE}"
mkdir "${DMG_DIR}"
echo "Copying data into temporary directory"
cp -R "${BUNDLE_DIR}" "${DMG_DIR}"
echo "Creating image"
hdiutil create -quiet -srcfolder "$DMG_DIR" -fs HFS+ -format UDZO -volname "${DMG_VOLUME_NAME}" -ov "${DMG_IMAGE}"
rm -rf "${DMG_DIR}"
echo Attaching License to image...
python ${SCRIPT_DIR}/dmg-license.py "${DMG_IMAGE}" "${DMG_LICENCE}" -c bz2
}
_codesign_dmg() {
if [ ${CODESIGN} -eq 0 ]; then
return
fi
DMG_VOLUME_NAME=${APP_NAME}
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
DMG_IMAGE=${DIST_ROOT}/${DMG_NAME}-${APP_LONG_VERSION}.dmg
if ! test -f "${DMG_IMAGE}" ; then
echo "${DMG_IMAGE} is no disk image!" >&2
exit 1
fi
# Sign the .app
echo Signing ${DMG_IMAGE}...
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DMG_IMAGE}"
# Verify it worked
echo Verifying the signature...
codesign --verify --verbose --force "${DMG_IMAGE}"
echo ${DMG_IMAGE} successfully signed.
}
+45 -250
View File
@@ -2,13 +2,19 @@
# Build script to create Mac App Bundle and DMG for pgAdmin4 runtime
export WD=$(cd `dirname $0` && pwd)
export SOURCEDIR=${WD}/../..
export BUILDROOT=${WD}/../../mac-build
export DISTROOT=${WD}/../../dist
export VIRTUALENV=venv
# Exit when any command fails
set -e -E
if [ ! -f ${SOURCEDIR}/pkg/mac/framework.conf ]; then
# Debugging shizz
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
trap 'if [ $? -ne 0 ]; then echo "\"${last_command}\" command filed with exit code $?."; fi' EXIT
SCRIPT_DIR=$(cd `dirname $0` && pwd)
SOURCE_DIR=$(realpath ${SCRIPT_DIR}/../..)
BUILD_ROOT=$(realpath ${SCRIPT_DIR}/../..)/mac-build
DIST_ROOT=$(realpath ${SCRIPT_DIR}/../..)/dist
if [ ! -f ${SCRIPT_DIR}/framework.conf ]; then
echo
echo "Error: pkg/mac/framework.conf not found!"
echo "Copy pkg/mac/framework.conf.in to pkg/mac/framework.conf and edit as required for the current system."
@@ -16,272 +22,61 @@ if [ ! -f ${SOURCEDIR}/pkg/mac/framework.conf ]; then
exit 1
fi
export SYSTEM_PYTHON=0
if [ "x${PYTHON_HOME}" == "x" ]; then
echo "PYTHON_HOME not set. Setting it to default"
export PYTHON_HOME=/System/Library/Frameworks/Python.framework/Versions/2.7
export PYTHON_VERSION=27
export SYSTEM_PYTHON=1
CODESIGN=1
if [ ! -f ${SCRIPT_DIR}/codesign.conf ]; then
echo
echo "******************************************************************"
echo "* ${SCRIPT_DIR}/codesign.conf not found. NOT signing the binaries."
echo "******************************************************************"
echo
CODESIGN=0
sleep 5
else
source ${SCRIPT_DIR}/codesign.conf
fi
if [ "x${PGADMIN_PYTHON_DIR}" == "x" ]; then
echo "PGADMIN_PYTHON_DIR not set. Setting it to the default: /usr/local/python"
export PGADMIN_PYTHON_DIR=/usr/local/python
fi
PYTHON_EXE=${PGADMIN_PYTHON_DIR}/bin/python3
# Check if Python is working and calculate PYTHON_VERSION
if ${PYTHON_HOME}/bin/python2 -V > /dev/null 2>&1; then
export PYTHON_VERSION=`${PYTHON_HOME}/bin/python2 -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
elif ${PYTHON_HOME}/bin/python3 -V > /dev/null 2>&1; then
export PYTHON_VERSION=`${PYTHON_HOME}/bin/python3 -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
if ${PYTHON_EXE} -V > /dev/null 2>&1; then
PYTHON_VERSION=`${PYTHON_EXE} -V 2>&1 | awk '{print $2}' | cut -d"." -f1-2 | sed 's/\.//'`
else
echo "Error: Python installation missing!"
exit 1
fi
if [ "${PYTHON_VERSION}" -gt "37" -a "${PYTHON_VERSION}" -lt "27" ]; then
echo "Python version not supported"
if [ "${PYTHON_VERSION}" -gt "38" ] && [ "${PYTHON_VERSION}" -lt "34" ]; then
echo "Python version not supported."
exit 1
fi
if [ "${PYTHON_VERSION}" -ge "30" ]; then
export PYTHON=${PYTHON_HOME}/bin/python3
export PIP=pip3
else
export PYTHON=${PYTHON_HOME}/bin/python2
export PIP=pip
if [ "x${PGADMIN_QT_DIR}" == "x" ]; then
echo "PGADMIN_QT_DIR not set. Setting it to the default: ~/Qt/5.13.2/clang_64"
export PGADMIN_QT_DIR=~/Qt/5.13.2/clang_64
fi
if [ "x${QTDIR}" == "x" ]; then
echo "QTDIR not set. Setting it to default"
export QTDIR=~/Qt/5.8/clang_64
fi
export QMAKE=${QTDIR}/bin/qmake
QMAKE=${PGADMIN_QT_DIR}/bin/qmake
if ! ${QMAKE} --version > /dev/null 2>&1; then
echo "Error: qmake not found. QT installation is not present or incomplete."
exit 1
fi
if [ "x${PGDIR}" == "x" ]; then
echo "PGDIR not set. Setting it to default"
export PGDIR=/usr/local/pgsql
if [ "x${PGADMIN_POSTGRES_DIR}" == "x" ]; then
echo "PGADMIN_POSTGRES_DIR not set. Setting it to the default: /usr/local/pgsql"
export PGADMIN_POSTGRES_DIR=/usr/local/pgsql
fi
_get_version() {
export APP_RELEASE=`grep "^APP_RELEASE" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
export APP_REVISION=`grep "^APP_REVISION" web/config.py | cut -d"=" -f2 | sed 's/ //g'`
export APP_NAME=`grep "^APP_NAME" web/config.py | cut -d"=" -f2 | sed "s/'//g" | sed 's/^ //'`
export APP_BUNDLE_NAME=${APP_NAME}.app
export APP_LONG_VERSION=${APP_RELEASE}.${APP_REVISION}
export APP_SHORT_VERSION=`echo ${APP_LONG_VERSION} | cut -d . -f1,2`
export APP_SUFFIX=`grep "^APP_SUFFIX" web/config.py | cut -d"=" -f2 | sed 's/ //g' | sed "s/'//g"`
if [ ! -z ${APP_SUFFIX} ]; then
export APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
fi
}
source ${SCRIPT_DIR}/build-functions.sh
_cleanup() {
echo "Cleaning up the old environment and app bundle"
rm -rf ${SOURCEDIR}/runtime/pgAdmin4.app
rm -rf ${BUILDROOT}
rm -f ${DISTROOT}/pgadmin4*.dmg
}
_create_python_virtualenv() {
export PATH=${PGDIR}/bin:${PATH}
export LD_LIBRARY_PATH=${PGDIR}/lib:${LD_LIBRARY_PATH}
test -d ${BUILDROOT} || mkdir ${BUILDROOT} || exit 1
cd ${BUILDROOT}
if [ ${SYSTEM_PYTHON} -eq 1 ]; then
test -d ${VIRTUALENV} || virtualenv -p ${PYTHON} ${VIRTUALENV} || exit 1
else
test -d ${VIRTUALENV} || virtualenv -p ${PYTHON} --always-copy ${VIRTUALENV} || exit 1
fi
source ${VIRTUALENV}/bin/activate
${PIP} install --no-cache-dir --no-binary psycopg2 -r ${SOURCEDIR}/requirements.txt || { echo PIP install failed. Please resolve the issue and rerun the script; exit 1; }
# Figure out some paths for use when completing the venv
# Use "python" here as we want the venv path
export PYMODULES_PATH=`python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"`
export DIR_PYMODULES_PATH=`dirname ${PYMODULES_PATH}`
# Use $PYTHON here as we want the system path
export PYSYSLIB_PATH=`${PYTHON} -c "import sys; print('%s/lib/python%d.%.d' % (sys.prefix, sys.version_info.major, sys.version_info.minor))"`
# Symlink in the rest of the Python libs. This is required because the runtime
# will clear PYTHONHOME for safety, which has the side-effect of preventing
# it from finding modules that are not explicitly included in the venv
cd ${DIR_PYMODULES_PATH}
# Files
for FULLPATH in ${PYSYSLIB_PATH}/*.py; do
FILE=${FULLPATH##*/}
if [ ! -e ${FILE} ]; then
if [ ${SYSTEM_PYTHON} -eq 1 ]; then
ln -s ${FULLPATH} ${FILE}
else
cp ${FULLPATH} ${FILE}
fi
fi
done
# Paths
for FULLPATH in ${PYSYSLIB_PATH}/*/; do
FULLPATH=${FULLPATH%*/}
FILE=${FULLPATH##*/}
if [ ! -e ${FILE} ]; then
if [ ${SYSTEM_PYTHON} -eq 1 ]; then
ln -s ${FULLPATH} ${FILE}
else
cp -R ${FULLPATH} ${FILE}
fi
fi
done
# Remove tests
cd site-packages
find . -name "test" -type d -print0 | xargs -0 rm -rf
find . -name "tests" -type d -print0 | xargs -0 rm -rf
# Link the python<version> directory to python so that the private environment path is found by the application.
if test -d ${DIR_PYMODULES_PATH}; then
ln -s $(basename ${DIR_PYMODULES_PATH}) ${DIR_PYMODULES_PATH}/../python
fi
}
_build_runtime() {
_create_python_virtualenv || exit 1
cd ${SOURCEDIR}/runtime
make clean
${QMAKE} || { echo qmake failed; exit 1; }
make || { echo make failed; exit 1; }
cp -r pgAdmin4.app "${BUILDROOT}/${APP_BUNDLE_NAME}"
}
_build_doc() {
cd ${SOURCEDIR}/docs/en_US
test -d "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources" || "mkdir -p ${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources"
test -d "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/docs/en_US" || mkdir -p "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/docs/en_US"
cp -r _build/html "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/docs/en_US/" || exit 1
}
_complete_bundle() {
cd ${SOURCEDIR}/pkg/mac
# Copy the binary utilities into place
mkdir -p "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
cp "${PGDIR}/bin/pg_dump" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
cp "${PGDIR}/bin/pg_dumpall" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
cp "${PGDIR}/bin/pg_restore" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
cp "${PGDIR}/bin/psql" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/SharedSupport/" || exit 1
# Replace the place holders with the current version
sed -e "s/PGADMIN_LONG_VERSION/${APP_LONG_VERSION}/g" -e "s/PGADMIN_SHORT_VERSION/${APP_SHORT_VERSION}/g" pgadmin.Info.plist.in > pgadmin.Info.plist
# copy Python private environment to app bundle
cp -PR ${BUILDROOT}/${VIRTUALENV} "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/" || exit 1
if [ ${SYSTEM_PYTHON} -eq 1 ]; then
# remove the python bin and include from app bundle as it is not needed
rm -rf "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/${VIRTUALENV}/bin" "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/${VIRTUALENV}/include"
rm -rf "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/${VIRTUALENV}/.Python"
fi
# Remove any TCL-related files that may cause us problems
find "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/${VIRTUALENV}/" -name "_tkinter*" -print0 | xargs -0 rm -f
# run complete-bundle to copy the dependent libraries and frameworks and fix the rpaths
./complete-bundle.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo complete-bundle.sh failed; exit 1; }
pushd ${SOURCEDIR}/web
yarn install || exit 1
yarn run bundle || exit 1
curl https://curl.haxx.se/ca/cacert.pem -o cacert.pem -s || { echo Failed to download cacert.pem; exit 1; }
popd
# copy the web directory to the bundle as it is required by runtime
cp -r ${SOURCEDIR}/web "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/" || exit 1
cd "${BUILDROOT}/${APP_BUNDLE_NAME}/Contents/Resources/web"
rm -f pgadmin4.db config_local.*
rm -rf karma.conf.js package.json node_modules/ regression/ tools/ pgadmin/static/js/generated/.cache
find . -name "tests" -type d -print0 | xargs -0 rm -rf
find . -name "feature_tests" -type d -print0 | xargs -0 rm -rf
find . -name ".DS_Store" -print0 | xargs -0 rm -f
echo "SERVER_MODE = False" > config_distro.py
echo "HELP_PATH = '../../../docs/en_US/html/'" >> config_distro.py
echo "DEFAULT_BINARY_PATHS = {" >> config_distro.py
echo " 'pg': '\$DIR/../../SharedSupport'," >> config_distro.py
echo " 'ppas': ''" >> config_distro.py
echo "}" >> config_distro.py
# Remove the .pyc files if any
cd "${BUILDROOT}/${APP_BUNDLE_NAME}"
find . -name *.pyc -print0 | xargs -0 rm -f
}
_framework_config() {
cd ${SOURCEDIR}/pkg/mac
./framework-config.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo "framework-config.sh failed"; exit 1; }
}
_codesign_binaries() {
cd ${SOURCEDIR}/pkg/mac
if [ ! -f codesign.conf ]; then
echo
echo "******************************************************************"
echo "* codesign.conf not found. NOT signing the binaries."
echo "******************************************************************"
echo
sleep 5
return
fi
./codesign-binaries.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo codesign-binaries.sh failed; exit 1; }
}
_codesign_bundle() {
cd ${SOURCEDIR}/pkg/mac
if [ ! -f codesign.conf ]; then
echo
echo "******************************************************************"
echo "* codesign.conf not found. NOT signing the bundle."
echo "******************************************************************"
echo
sleep 5
return
fi
./codesign-bundle.sh "${BUILDROOT}/${APP_BUNDLE_NAME}" || { echo codesign-bundle.sh failed; exit 1; }
}
_create_dmg() {
cd ${SOURCEDIR}
./pkg/mac/create-dmg.sh || { echo create-dmg.sh failed; exit 1; }
# Clean the mac-build/ on successful build
rm -rf ${BUILDROOT}/*
}
_codesign_dmg() {
cd ${SOURCEDIR}/pkg/mac
if [ ! -f codesign.conf ]; then
echo
echo "******************************************************************"
echo "* codesign.conf not found. NOT signing the disk image."
echo "******************************************************************"
echo
sleep 5
return
fi
./codesign-dmg.sh || { echo codesign-bundle.sh failed; exit 1; }
}
_get_version || { echo Could not get versioning; exit 1; }
_setup_env
_cleanup
_build_runtime || { echo Runtime build failed; exit 1; }
_build_doc
_create_venv
_build_runtime
_build_docs
_complete_bundle
_framework_config
_codesign_binaries
-36
View File
@@ -1,36 +0,0 @@
#!/bin/sh
BUNDLE="$1"
if ! test -d "${BUNDLE}" ; then
echo "${BUNDLE} is no bundle!" >&2
exit 1
fi
# Get the config
source codesign.conf
if [ -z "${DEVELOPER_ID}" ] ; then
echo "Developer ID Application not found in codesign.conf" >&2
exit 1
fi
if [ -z "${DEVELOPER_BUNDLE_ID}" ]; then
echo "Developer Bundle Identifier not found in codesign.conf" >&2
fi
echo Signing ${BUNDLE} binaries
IFS=$'\n'
for i in $(find "${BUNDLE}" -type f)
do
file "${i}" | grep -E "Mach-O executable|Mach-O 64-bit executable|Mach-O 64-bit bundle"
if [ $? -eq 0 ] ; then
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
fi
done
echo Signing ${BUNDLE} libraries
for i in $(find "${BUNDLE}" -type f -name "*.dylib*")
do
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "$i"
done
-26
View File
@@ -1,26 +0,0 @@
#!/bin/sh
BUNDLE="$1"
if ! test -d "${BUNDLE}" ; then
echo "${BUNDLE} is no bundle!" >&2
exit 1
fi
# Get the config
source codesign.conf
# Sign the .app
echo Signing ${BUNDLE}
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${BUNDLE}"
# Verify it worked
echo Verifying the signature
codesign --verify --verbose --deep --force "${BUNDLE}"
RETURN_STATUS=$?
if [ ${RETURN_STATUS} -ne 0 ]; then
echo Code signing did not work, check the log
exit 1
else
echo ${BUNDLE} successfully signed
fi
-30
View File
@@ -1,30 +0,0 @@
#!/bin/bash
DMG_VOLUME_NAME=${APP_NAME}
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
DMG_IMAGE=${DISTROOT}/${DMG_NAME}-${APP_LONG_VERSION}.dmg
if ! test -f "${DMG_IMAGE}" ; then
echo "${DMG_IMAGE} is no disk image!" >&2
exit 1
fi
# Get the config
source codesign.conf
SCRIPT_DIR=`pwd`
# Sign the .app
echo Signing ${DMG_IMAGE}
codesign --deep --force --verify --verbose --timestamp --options runtime -i "${DEVELOPER_BUNDLE_ID}" --sign "${DEVELOPER_ID}" "${DMG_IMAGE}"
# Verify it worked
echo Verifying the signature
codesign --verify --verbose --force "${DMG_IMAGE}"
RETURN_STATUS=$?
if [ ${RETURN_STATUS} -ne 0 ]; then
echo ERROR: Code signing did not work
exit 1
else
echo ${DMG_IMAGE} successfully signed
fi
+1 -1
View File
@@ -1,5 +1,5 @@
# In order to enable codesigning of the Mac Appbundle, copy this file to
# codesign.conf, and edit the value below to reflect your developer ID
# codesign.conf, and edit the values below to reflect your developer ID.
DEVELOPER_ID="Developer ID Application: My Name (12345ABCD)"
DEVELOPER_BUNDLE_ID="Developer Bundle Identifier (pgadmin4-4)"
-146
View File
@@ -1,146 +0,0 @@
#!/bin/sh
bundle="$1"
if ! test -d "$bundle" ; then
echo "${bundle} is no bundle!" >&2
exit 1
fi
if test -z ${QTDIR} ; then
echo "QTDIR environment variable not set"
exit 1
else
echo "QTDIR=${QTDIR}"
fi
test -d "${bundle}/Contents/Resources" || mkdir -p "${bundle}/Contents/Resources" || exit 1
# Create qt.conf so that app knows where the Plugins are present
cat >> "${bundle}/Contents/Resources/qt.conf" << EOF
[Paths]
Plugins = PlugIns
EOF
test -d "${bundle}/Contents/Frameworks" || mkdir -p "${bundle}/Contents/Frameworks" || exit 1
test -d "${bundle}/Contents/PlugIns/platforms" || mkdir -p "${bundle}/Contents/PlugIns/platforms" || exit 1
test -d "${bundle}/Contents/PlugIns/imageformats" || mkdir -p "${bundle}/Contents/PlugIns/imageformats" || exit 1
cp -f ${QTDIR}/plugins/platforms/libqcocoa.dylib "${bundle}/Contents/PlugIns/platforms" || { echo libqcocoa.dylib not found in ${QTDIR}/plugins/platforms; exit 1; }
cp -f ${QTDIR}/plugins/imageformats/libqsvg.dylib "${bundle}/Contents/PlugIns/imageformats" || { echo libqsvg.dylib not found in ${QTDIR}/plugins/imageformats; exit 1; }
cp -f ${PGDIR}/lib/libpq.5.dylib "${bundle}/Contents/Frameworks" || { echo libpq.5.dylib not found in ${PGDIR}; exit 1; }
function CompleteSingleApp() {
local bundle=$1 tag=$(basename "$1") todo todo_old fw_relpath lib lib_bn nested_app na_relpath
echo "Completing app: ${bundle}"
pushd "${bundle}" > /dev/null
#We skip nested apps here - those are treated specially
todo=$(file `find ./ -perm +0111 ! -type d ! -path "*.app/*" ! -name "*.app"` | grep -E "Mach-O 64-bit" | awk -F ':| ' '{ORS=" "; print $1}')
echo "App: ${tag}: Found executables: ${todo}"
while test "${todo}" != ""; do
todo_old=${todo} ;
todo="" ;
for todo_obj in ${todo_old}; do
echo "App: ${tag}: Post-processing: ${todo_obj}"
#Figure out the relative path from todo_obj to Contents/Frameworks
fw_relpath=$(echo "${todo_obj}" |\
sed -n 's|^\(\.//*\)\(\([^/][^/]*/\)*\)[^/][^/]*$|\2|gp' | \
sed -n 's|[^/][^/]*/|../|gp' \
)"Contents/Frameworks"
fw_relpath_old=${fw_relpath}
fw_loc="Contents/Frameworks"
#Find all libraries $todo_obj depends on, but skip system libraries
for lib in $(
otool -L ${todo_obj} | \
grep "Qt\|dylib\|Frameworks\|PlugIns" | grep -v ":" | sed 's/(.*//' | egrep -v '(/usr/lib)|(/System)|@executable_path@' \
) $(otool -L ${todo_obj} | grep "Python" | grep -v ":" | sed 's/(.*//' \
); do
if echo ${lib} | grep "PlugIns\|libqcocoa" > /dev/null; then
lib_loc="Contents/PlugIns/platforms"
elif echo ${lib} | grep "PlugIns\|libqsvg" > /dev/null; then
lib_loc="Contents/PlugIns/imageformats"
elif echo ${lib} | grep "Qt" > /dev/null; then
qtfw_path="$(dirname ${lib} | sed 's|.*\(Qt.*framework\)|\1|')"
lib_loc="Contents/Frameworks/${qtfw_path}"
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
lib_loc="$(dirname ${todo_obj})"
qtfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
fi
elif echo ${lib} | grep "Python" > /dev/null; then
pyfw_path="$(dirname ${lib} | sed 's|.*\(Python.*framework\)|\1|')"
lib_loc="Contents/Frameworks/${pyfw_path}"
if [ "$(basename ${todo_obj})" = "${lib}" ]; then
lib_loc="$(dirname ${todo_obj})"
pyfw_path=$(echo ${lib_loc} | sed 's/Contents\/Frameworks\///')
fi
else
lib_loc="Contents/Frameworks"
fi
lib_bn="$(basename "${lib}")" ;
if ! test -f "${lib_loc}/${lib_bn}"; then
target_file=""
target_path=""
echo "App: ${tag}: Adding symlink: ${lib_bn} (because of: ${todo_obj})"
# Copy the QT and Python framework
if echo ${lib} | grep Qt > /dev/null ; then
test -d ${lib_loc} || mkdir -p ${lib_loc}
echo Copying -R ${QTDIR}/lib/${qtfw_path}/${lib_bn} to ${lib_loc}/
cp ${QTDIR}/lib/${qtfw_path}/${lib_bn} ${lib_loc}/
elif echo ${lib} | grep Python > /dev/null ; then
test -d ${lib_loc} || mkdir -p ${lib_loc}
cp -R "${lib}" "${lib_loc}/${lib_bn}"
else
cp -R "${lib}" "${lib_loc}/${lib_bn}"
fi
if ! test -L "${lib_loc}/${lib_bn}"; then
chmod 755 "${lib_loc}/${lib_bn}"
else
target_file=$(readlink "${lib}")
target_path=$(dirname "${lib}")/${target_file}
echo "App: ${tag}: Adding symlink target: ${target_path}"
cp "${target_path}" "${lib_loc}/${target_file}"
chmod 755 "${lib_loc}/${target_file}"
fi
echo "Rewriting ID in ${lib_loc}/${lib_bn} to ${lib_bn}"
echo install_name_tool -id "${lib_bn}" "${lib_loc}/${lib_bn}"
install_name_tool \
-id "${lib_bn}" \
"${lib_loc}/${lib_bn}" || exit 1
todo="${todo} ./${lib_loc}/${lib_bn}"
fi
if echo ${lib} | grep Qt > /dev/null ; then
fw_relpath="${fw_relpath}/${qtfw_path}"
fi
if echo ${lib} | grep Python > /dev/null ; then
fw_relpath="${fw_relpath}/${pyfw_path}"
fi
chmod +w ${todo_obj}
echo "Rewriting library ${lib} to @loader_path/${fw_relpath}/${lib_bn} in ${todo_obj}"
echo install_name_tool -change "${lib}" "@loader_path/${fw_relpath}/${lib_bn}" "${todo_obj}"
install_name_tool -change \
"${lib}" \
"@loader_path/${fw_relpath}/${lib_bn}" \
"${todo_obj}" || exit 1
install_name_tool -change \
"${target_path}" \
"@loader_path/${fw_relpath}/${target_file}" \
"${todo_obj}" || exit 1
fw_relpath="${fw_relpath_old}"
done
done
done
# Fix the rpaths for psycopg module
find "${bundle}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libpq.5.dylib @loader_path/../../../../../../Frameworks/libpq.5.dylib
find "${bundle}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libssl.1.0.0.dylib @loader_path/../../../../../../Frameworks/libssl.1.0.0.dylib
find "${bundle}/Contents/Resources/venv/" -name _psycopg.so -print0 | xargs -0 install_name_tool -change libcrypto.1.0.0.dylib @loader_path/../../../../../../Frameworks/libcrypto.1.0.0.dylib
echo "App completed: ${bundle}"
popd > /dev/null
}
CompleteSingleApp "${bundle}"
-36
View File
@@ -1,36 +0,0 @@
#!/bin/sh
# move to the directory where we want to create the DMG
test -d ${DISTROOT} || mkdir ${DISTROOT}
cd ${DISTROOT}
DMG_SOURCES="./../mac-build/${APP_BUNDLE_NAME}"
DMG_LICENCE=./../pkg/mac/licence.rtf
DMG_VOLUME_NAME=${APP_NAME}
DMG_NAME=`echo ${DMG_VOLUME_NAME} | sed 's/ //g' | awk '{print tolower($0)}'`
DMG_IMAGE=${DMG_NAME}-${APP_LONG_VERSION}.dmg
HDIUTIL=/usr/bin/hdiutil
REZ="/usr/bin/Rez"
DMG_DIR=./${DMG_IMAGE}.src
if test -e "${DMG_DIR}"; then
echo "Directory ${DMG_DIR} already exists. Please delete it manually." >&2
exit 1
fi
echo "Cleaning up"
rm -f "${DMG_IMAGE}" || exit 1
mkdir "${DMG_DIR}" || exit 1
echo "Copying data into temporary directory"
for src in "${DMG_SOURCES}"; do
cp -R "${src}" "${DMG_DIR}" || exit 1
done
echo "Creating image"
${HDIUTIL} create -quiet -srcfolder "$DMG_DIR" -fs HFS+ -format UDZO -volname "${DMG_VOLUME_NAME}" -ov "${DMG_IMAGE}" || exit 1
rm -rf "${DMG_DIR}" || exit 1
echo "Attaching License to image"
python ./../pkg/mac/dmg-license.py "${DMG_IMAGE}" "${DMG_LICENCE}" -c bz2
+17 -16
View File
@@ -45,9 +45,9 @@ def mktemp(dir=None, suffix=''):
def main(options, args):
dmgFile, license = args
with mktemp('.') as tmpFile:
with open(tmpFile, 'w') as f:
dmg_file, license_file = args
with mktemp('.') as tmp_file:
with open(tmp_file, 'w') as f:
f.write("""data 'TMPL' (128, "LPic") {
$"1344 6566 6175 6C74 204C 616E 6775 6167"
$"6520 4944 4457 5244 0543 6F75 6E74 4F43"
@@ -90,8 +90,9 @@ data 'STR#' (5002, "English") {
$"2C20 7072 6573 7320 2244 6973 6167 7265"
$"6522 2E"
};\n\n""")
with open(license, 'r') as lines:
kind = 'RTF ' if license.lower().endswith('.rtf') else 'TEXT'
with open(license_file, 'r') as lines:
kind = 'RTF ' if license_file.lower().endswith('.rtf') \
else 'TEXT'
f.write('data \'%s\' (5000, "English") {\n' % kind)
def escape(s):
@@ -110,24 +111,24 @@ data 'STR#' (5002, "English") {
$"0100 0000 0000 0000 0000 0000 002A 000C"
$"0009 0014 0000 0000 0000 0000 0000"
};\n""")
os.system('hdiutil unflatten -quiet "%s"' % dmgFile)
os.system('hdiutil unflatten -quiet "%s"' % dmg_file)
ret = os.system('%s -a %s -o "%s"' %
(options.rez, tmpFile, dmgFile))
os.system('hdiutil flatten -quiet "%s"' % dmgFile)
(options.rez, tmp_file, dmg_file))
os.system('hdiutil flatten -quiet "%s"' % dmg_file)
if options.compression is not None:
os.system('cp %s %s.temp.dmg' % (dmgFile, dmgFile))
os.remove(dmgFile)
os.system('cp %s %s.temp.dmg' % (dmg_file, dmg_file))
os.remove(dmg_file)
if options.compression == "bz2":
os.system('hdiutil convert %s.temp.dmg -format UDBZ -o %s' %
(dmgFile, dmgFile))
(dmg_file, dmg_file))
elif options.compression == "gz":
os.system('hdiutil convert %s.temp.dmg -format ' % dmgFile +
'UDZO -imagekey zlib-devel=9 -o %s' % dmgFile)
os.remove('%s.temp.dmg' % dmgFile)
os.system('hdiutil convert %s.temp.dmg -format ' % dmg_file +
'UDZO -imagekey zlib-devel=9 -o %s' % dmg_file)
os.remove('%s.temp.dmg' % dmg_file)
if ret == 0:
print("Successfully added license to '%s'" % dmgFile)
print("Successfully added license to '%s'" % dmg_file)
else:
print("Failed to add license to '%s'" % dmgFile)
print("Failed to add license to '%s'" % dmg_file)
if __name__ == '__main__':
-71
View File
@@ -1,71 +0,0 @@
#!/bin/sh
BUNDLE="$1"
if ! test -d "${BUNDLE}" ; then
echo "${BUNDLE} is no bundle!" >&2
exit 1
fi
# Get the config
source framework.conf
SCRIPT_DIR=`pwd`
echo Reorganising the framework structure
# Create "Current" and "Current/Resources" inside each of the framework dirs
MYDIR=`pwd`
find "${BUNDLE}/Contents/Frameworks"/*framework -type d -name "Versions" | while read -r framework_dir; do
cd "${framework_dir}"
# Create framework 'Current' soft link
VERSION_NUMBER=`ls -1`
ln -s ${VERSION_NUMBER} Current || { echo "link creation in framework-config.sh failed"; exit 1; }
# Create "Resources" subdirectory
if [ ! -d Current/Resources ]; then
mkdir Current/Resources
fi
cd "${MYDIR}"
done
# Stuff for Qt framework files only
find "${BUNDLE}/Contents/Frameworks" -type d -name "Qt*framework" | while read -r framework_dir; do
cd "${framework_dir}"
# Create soft link to the framework binary
ln -s Versions/Current/Qt* || { echo "link creation in framework-config.sh failed"; exit 1; }
# Create soft link to the framework Resources dir
ln -s Versions/Current/Resources || { echo "link creation in framework-config.sh failed"; exit 1; }
# Create the Info.plist files
MYNAME=`ls -1 Qt*`
if [ -f Resources/Info.plist ]; then
chmod +w Resources/Info.plist
fi
sed 's/__SHORT_VERSION__/${QT_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Qt5" | sed 's/__FULL_VERSION__/${QT_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist" || { echo "sed replacement in framework-config.sh failed"; exit 1; }
cd "${MYDIR}"
done
# Same thing, but specific to the Python framework dir
find "${BUNDLE}/Contents/Frameworks" -type d -name "P*framework" | while read -r framework_dir; do
cd "${framework_dir}"
# Create soft link to the framework binary
ln -s Versions/Current/Py* || { echo "link creation in framework-config.sh failed"; exit 1; }
# Create soft link to the framework Resources dir
ln -s Versions/Current/Resources || { echo "link creation in framework-config.sh failed"; exit 1; }
# Create the Info.plist file
MYNAME=`ls -1 Py*`
sed 's/__SHORT_VERSION__/${PYTHON_SHORT_VERSION}/' "${SCRIPT_DIR}/Info.plist-template_Python" | sed 's/__FULL_VERSION__/${PYTHON_FULL_VERSION}/' | sed "s/__FRAMEWORK_NAME__/${MYNAME}/" > "Resources/Info.plist" || { echo "sed replacement in framework-config.sh failed"; exit 1; }
cd "${MYDIR}"
done
echo ${BUNDLE} framework config finished
+6 -6
View File
@@ -1,10 +1,10 @@
# copy this file to framework.conf, and edit the values below to reflect your environment
# (versions of Python/Qt used)
# Copy this file to framework.conf, and edit the values below to reflect your
# environment (versions of Python/Qt used)
PYTHON_SHORT_VERSION=2.7
PYTHON_FULL_VERSION=2.7.10
PYTHON_SHORT_VERSION=3.8
PYTHON_FULL_VERSION=3.8.2
QT_SHORT_VERSION=5.8
QT_FULL_VERSION=5.8.0
QT_SHORT_VERSION=5.14
QT_FULL_VERSION=5.14.2
+2 -2
View File
@@ -83,7 +83,7 @@ do
done
cd ../
for FILE in LICENSE README libraries.txt
for FILE in LICENSE DEPENDENCIES README
do
echo Adding ${FILE}
# We use tar here to preserve the path, as Mac (for example) doesn't support cp --parents
@@ -102,7 +102,7 @@ echo recursive-include pgadmin4 \* > pip-build/MANIFEST.in
# Run the build
echo Building wheel...
cd pip-build
python ../pkg/pip/setup_pip.py bdist_wheel --universal
python ../pkg/pip/setup_pip.py bdist_wheel
cd ../
# Get the build
+22 -40
View File
@@ -7,68 +7,51 @@
#
##########################################################################
import builtins
import os
import sys
from codecs import open
from importlib.machinery import SourceFileLoader
from setuptools import setup
from codecs import open
if sys.version_info[0] >= 3:
import builtins
else:
import __builtin__ as builtins
# Load a source file
def load_source(name, path):
if not os.path.exists(path):
print("ERROR: Could not find %s" % path)
sys.exit(1)
return SourceFileLoader(name, path).load_module()
# Ensure the global server mode is set.
builtins.SERVER_MODE = None
"""This script helps to generate PIP packages"""
# Get the requirements list for the current version of Python
req_file = '../requirements.txt'
with open(req_file, 'r') as reqf:
if sys.version_info[0] >= 3:
required = reqf.read().splitlines()
else:
required = reqf.read().decode("utf-8").splitlines()
with open(req_file, 'r') as req_lines:
requires = req_lines.read().splitlines()
# Remove any requirements with environment specifiers. These
# must be explicitly listed in extras_require below.
for index, req in enumerate(required):
for index, req in enumerate(requires):
if ";" in req or req.startswith("#") or req == "":
required.remove(req)
requires.remove(req)
continue
# Ensure the Wheel will use psycopg2-binary, not the source distro
if 'psycopg2' in req:
required[index] = req.replace('psycopg2', 'psycopg2-binary')
requires[index] = req.replace('psycopg2', 'psycopg2-binary')
# Get the app version
if sys.version_info[:2] >= (3, 3):
from importlib.machinery import SourceFileLoader
def load_source(name, path):
if not os.path.exists(path):
print("ERROR: Could not find %s" % path)
sys.exit(1)
return SourceFileLoader(name, path).load_module()
else:
import imp
def load_source(name, path):
if not os.path.exists(path):
print("ERROR: Could not find %s" % path)
sys.exit(1)
return imp.load_source(name, path)
modl = load_source('APP_VERSION', '../web/config.py')
# Get the version
config = load_source('APP_VERSION', '../web/config.py')
setup(
name='pgadmin4',
version=modl.APP_VERSION,
version=config.APP_VERSION,
description='PostgreSQL Tools',
long_description='Administration and management tools for '
@@ -86,7 +69,6 @@ setup(
'Development Status :: 5 - Production/Stable',
# Supported programming languages
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
@@ -100,10 +82,10 @@ setup(
include_package_data=True,
install_requires=required,
install_requires=requires,
entry_points={
'console_scripts': ['pgadmin4=pgadmin4.pgAdmin4.__init__:main'],
'console_scripts': ['pgadmin4=pgadmin4.pgAdmin4:main'],
},
)
+64
View File
@@ -0,0 +1,64 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFtyz58BEACgKbtY59R0mxs8rWJNAn1BWNXwhuTvELNCV6gZkMRGFP14tMop
d9VcUx5UWiulT5wysji63xhkNljmE90jJdlxZwZ+XtnmLzIqp6i29EkAIUt1AoxM
w2ipMhfuwE6WA6VYxQihu5z2IDOR1PdDUHF5cX/GZgBon/2A33rG5IKTcaNZzL0O
c3rS5VzOzwnp1FHPlR7PY7BRDNe8q1MrQq14tlgMTaYziNg2t2YwjuhNV6G33qGE
h390aUnO/eMWIPJzKoi4mE5mhEbh4L/7sFlcRUC6Vs1xa5Ab+L5y2xoDe2grraKD
u+XpGJaDPLunlhDSTUsp0HsoLVU4ne/HNbCAm2b25tKFcFTUwDH4Ekge1/bQLCvx
kB63MMLa/FgsJ0XAr8zKEQFrc89qJU4JuvadL4hAIqZ1ywFlwTOBaNfZHbW2Pt5f
prktIL5d5jIHAdQrFPvLqhhjhM03de6O6dS5lDeP8dTdqzMcqBkwFMmjZMeRAcoJ
vs0jJNc0fYwL3h2JSWQnIhsvcSe6gk8GFVRbCCy9UplK1K/5TWw+y3mtfWwUCUSW
nBIuUTV+5iG21o3rdZgfEjXJtBAWW/hKoVwBTe5Ir9yIqaomG5ul0Sn2EgOravns
AWe2nk4l9cno5CPhGunEtiOD8YQJHskk7/NMtnPegB5j4tprXGS/cK/5hQARAQAB
tDxQYWNrYWdlIE1hbmFnZXIgKFBhY2thZ2UgU2lnbmluZyBLZXkpIDxwYWNrYWdl
c0BwZ2FkbWluLm9yZz6JAk4EEwEKADgWIQToaX4u73bALTpjMneIgbKoIQl28gUC
W3LPnwIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRCIgbKoIQl28ukfD/4y
3gGysVSJU1964mpi/4NtSTruQ+fx8rN1vY/cctdQVr1ltuJsDRyPgGpXIh9zeK0/
bkCreCcuGezm2WOUFR6Kf54zMWWbIrAPpbib7rYi8n50jz7SkCfSyJZgqO2bAPBU
MP6Y09mdLaB4jib9Y6nDhFgm2V0rO64yX/bznVjBzNXFjCTgbPoABU0Guy4yHGUF
HkQ7Hdg1QLhupMWlphlMJbeSxZJx0T6ApNvr2Qg+uFykSXbXjP2e/tXGb9NeHveT
tw/hD2yMPzXJZ4uQbk8mJWDfD87fHY4ZUVqLJtKiS3omePJ5FWMPnLl0PLICkvmh
mhoxyKFGjB+62/PpYwclZLR8iB7wn9tIA/q6BqP/BBhgmzpuh7ZOAU/zUZ5D+tHu
Q9X0e29iFs4nxewmSM1uCq++l+gGMFRMn0FPH8nyQS/EcB/qXXRc0J3Ja7VVfH5B
djmVvqTeJmwY+xGdLZAh/WZ9raWd/qbRGNIcYOyhHnvp719EQxYSiiJbIQcRLDbc
IBiUG322ubSiR4+saYfx4ixrHvx8QYbtagien0kkXtoouhhIuLxq/EADRb979ZvQ
1hnlUkSGHRN6mDNyLztRqy/iibZrSgX+iKR9lQYI5MnhchihgoN7jyFUiGTV/VSG
6oH2KHiTgUQawli9OirnBB1oekf2+QZfZUvnM+b+SokCMwQQAQoAHRYhBODEzuuC
ax/aT7Ro4CSt+q9pjxUZBQJbcs/+AAoJECSt+q9pjxUZ4fAP/iQpwcrUZrPp3WI3
hi3wHAe+L6E6LiWlhMEMlqfy/2/xOpDEniwy6IEbMV7+H8WSbFYnTBM6EJAWPCMK
ZAfkduuB6xqHllEuPuFY9O13+fV5bJMrW/ej3MbX2yz+wfa6LLORRBB/e4R34suz
mlSzQzRttPHejmpNicn0S2kA07kqdl/2I3KcsWM1a5GeRZAukDSMLI6orZAGR+r4
xKpdEiEMHfoxYYxujmQR9+jqYYPsuViHc3LtIwaKMjTiWBx7wUDF+qIl7bNkT7P9
4VudNU9hhzCcYSAt4qiDykTojbSlXSx/ltqoTRhVQlk1kFk2g1O1zHyVpuAkolje
5ZmRGa/ZFQWuSOd01n1QqiRLrQDXHKDBh+sUOqaF4Hby/pwZwcsXGLEzSI9uC5He
WAn/yomDJInpyYwGmT9FyD9YSd9QjpM1y2/w2+KMj1KRq7GvmZUONYaWp1+A0eCL
yhdsZ+bqdS6DVnh0qKT/8ulWUKe+sxiRyAaKBF0QacuuRiRFAfgWbQbsrEQGcDqL
q7lmtmOKa0GrBQJAvTMUkxrpMG6SIe+HsJJ3/u+pmTWg77oiQqTByQPPJF0/EgMV
g/JzstHdI+FA7Q/4DKJZ5NrPBpUUQC0h+Iex426C7gBtnGXQHYB2Nx6xCtwmpPZv
w5THrRb07Y59nZEZLEdcL8bbH/CZuQINBFtyz58BEACt0Hcb8t24ZXsGcOlVnElo
cMMo17IdyDvs1j2jJxrNTT6jkxlgwG+ojStsRvllRrG85Wq/FNI6LuBY3Ux+Ymda
Nm+p8CJiEDE/Gql4GPSNZ7fCiiopRyyFXg61VM72lWokAT9o9GaSU0/sM5WDeXvM
A5QIlAg6+jQ7+R0MMLHeH0GTMnF58KAFmE7T72+H1zPtvH3qeQlOt+PBMJVNhjiO
2MwU7NlUIKVz4Vn1JmxA1kCWEIxZyFS82XXKc9BXgPqwnk27lqBxdZzDWFki8SBn
DdvwTT/s0chtwekWN4t2RofK0w33TF7+MSQLxpWLr8igrQQvBq6LBfMqm8tQWHL2
VDORDg5kKIpZv4pNxxIFmu1VX+W01Oj2GV6AOJgX6jadMiRlHptkz7D/dmnqsCyf
DRCmLcwB3y2/behbV1+iW2bViUaFoQIt/XXm2Jo1YtskxZ7LDngDin88pU6jId1N
dxjP2rKUjm/dyH5jMn1engv71w16TH+GVr42ho+yOwOTYo8qKDAvQgI8I8e+MlkM
LRLpgmFiECmWCovJOQ2JHizqFOmr+eSbeg7o5VpWA+cb0sCdbGUX8Kv6i8zP/ayh
VnWg1oU5Q0HTgH9gQ0rzkR+Re2O5xSKuNYnqVOJv4eRzt1NPFgZZOw+PFMJlvEz4
ujGwA/OsdJNLQK/HEK75GwARAQABiQI2BBgBCgAgFiEE6Gl+Lu92wC06YzJ3iIGy
qCEJdvIFAltyz58CGwwACgkQiIGyqCEJdvKPUg//f2YJGHX9FaNkCpoEk51QW5sv
pqITO24Ig65mEVVyx1GPOR9BQnCJoXZrnhEv2d/BpijFE/cR/fHv9bmqc434waeZ
PyDyflWTn6+MQYMJJfszKdJFaaY4qPeaCcoh7GC2qw4I5MINfNVTcinOU52XZzt6
F+ENm4h8u6vbS+55sKXjRRxNMHbBlNMr0yylukdGrs3PTGEYtXEPBhms4Plz5uHj
wkvf+rti84z2qqdX6y0YWxtRBy0cGeo15NYA8kHJLIQeUYbkV20PC7Uooj29DpIs
RxDv7F2qZ3KIse8oiJTIubdM+O7zNhzMo+XSUY2HM6aWDLCjV5SuJVJUsPxA3aEK
ijn/PjmGkr4DKhiant0nIB/pzyKelNQJHO5fgCFuV72R9GIR7yBRG2AU5OwgHQdy
5F0/4/6LtNVWZMKy2lEYuyW8fm0rbC7G5Qbz0KhYZWxp3F20rO6679ViMuNQTwQf
HI9akdtFqFEFPuoHyT3VAMxzeUAcMXwBaPcHw1EOlX1kibaM5dbDVOfKEr6JNj4V
N00CeuM++rHJSTeM/gcxO+BWpzaNFF9MMrCBL74wiY+WJ7rogRf5Du7H2e0+w/XO
puIx3rGSO9VhVrVcoTHimJPuWH7j56wybLS/TCh6HI8soMjYLzxWbqvSyV0b4xfb
czb/7fY4Fah80eE59/M=
=E6/L
-----END PGP PUBLIC KEY BLOCK-----
+98 -7
View File
@@ -1,6 +1,12 @@
This directory contains the build runner script for creating .RPM packages for
Redhat distributions.
Supported platforms
===================
Fedora 30, 31 & 32
RHEL/CentOS 7 & 8
Build configuration
===================
@@ -39,13 +45,98 @@ pgadmin4-python3-mod_wsgi-4.7.1-2.el7.<arch>.rpm
The Python 3 build of mod_wsgi for the Apache HTTPD server. Only built
on RHEL/CentOS 7.
Supported platforms
===================
Signing Packages
================
Fedora 30 & 31
RHEL/CentOS 7 & 8
It is good practice to sign RPMs to prove their provenance. The build scripts
included in this directory do NOT do that; doing so is done using a Jenkins
task in the pgAdmin buildfarm.
Warning
=======
If you want to sign your own RPMs, you'll first need to ensure that the
gnupg2 and rpmsign tools are available on your system.
These scripts are experimental - use at your own risk!
Then, create a .rpmmacros file in the home directory of the user account that
will be doing the signing. On Fedora 30 and later, and RHEL/CentOS 8 and later,
that should contain the following contents (without the start/end markers).
Replace <your signing key> with the email address in your key:
---------
%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name <your signing key>
%_gpgbin /usr/bin/gpg2
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename
} --digest-algo sha256 %{__plaintext_filename}
---------
On RHEL/CentOS 7, the .rpmmacros file should look like this:
---------
%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name Package Manager
%_gpgbin /usr/bin/gpg2
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" -sbo %{__
signature_filename} --digest-algo sha256 %{__plaintext_filename}
---------
Note that these configurations are designed for automated signing in a CI/CD
system. You may need to adjust them to handle passphrases on keys in your own
environment.
You also need to import your signing private key into the gnupg2 keystore, for
example:
gpg --import signing_key.priv
Once everything is setup, RPMs can be signed easily; for example:
rpmsign --addsign dist/*.rpm
Building a repo
===============
A Yum repo can be created by building RPMs for the required platforms, moving
them into the required directory structure, and then running the createrepo tool
over that directory. The pgAdmin repos use the following structure:
<root>
redhat/
rhel-7-x86_64/
pgadmin4-4.21-1.el7.noarch.rpm
pgadmin4-desktop-4.21-1.el7.x86_64.rpm
pgadmin4-python3-mod_wsgi-4.7.1-2.el7.x86_64.rpm
pgadmin4-server-4.21-1.el7.x86_64.rpm
pgadmin4-web-4.21-1.el7.noarch.rpm
rhel-8-x86_64/
<...>
fedora/
<...>
pgadmin4-fedora-repo-1-1.noarch.rpm
pgadmin4-redhat-repo-1-1.noarch.rpm
README
Note that only the first branches are shown above; other branches (e.g. for
Fedora and RHEL 8 follow the structure shown for RHEL 7.
Technically there are multiple different repos, one for each platform and
architecture. The metadata can be created for each as follows:
/usr/bin/createrepo <root>/redhat/rhel-7-x86_64
/usr/bin/createrepo <root>/redhat/rhel-8-x86_64
...
Repository RPMs
===============
A script is provided for the creation of repo RPMs. It will create RPMs that
install the required Yum configuration file and the public signing key for
pgAdmin (you may want to replace the contents of PGADMIN_PKG_KEY with your own
public key):
./repo-rpms.sh
Set the PGADMIN_REPO_DIR environment variable to define the repository root
from the client's perspective. Given the example above, you might do:
PGADMIN_REPO_DIR=https://yum.company.com/repos/<root> ./repo-rpms.sh
+10 -6
View File
@@ -11,6 +11,9 @@ OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2
OS_NAME=$(cat /etc/os-release | grep "^ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
OS_ARCH=$(arch)
# Make sure we get the right libpq
export PATH=/usr/pgsql-12/bin:$PATH
# Common Linux build functions
source pkg/linux/build-functions.sh
@@ -48,12 +51,8 @@ Release: 1%{?dist}
Summary: The core server package for pgAdmin.
License: PostgreSQL
URL: https://www.pgadmin.org/
%if 0%{?rhel} && 0%{?rhel} != 7
Requires: python3, libpq
Recommends: postgresql
%else
Requires: python3, postgresql
%endif
Requires: python3, postgresql-libs >= 11
%description
The core server package for pgAdmin. pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
@@ -204,6 +203,9 @@ if [ ${OS_VERSION} == 7 ]; then
rpmbuild -bb "${SOURCEDIR}/pkg/redhat/pgadmin4-python-mod_wsgi.spec"
fi
# Get the libpq we need
yumdownloader --downloadonly --destdir=$DISTROOT postgresql12-libs
#
# Get the results!
#
@@ -212,3 +214,5 @@ cp ${HOME}/rpmbuild/RPMS/noarch/${APP_NAME}-*${APP_LONG_VERSION}-*.noarch.rpm "$
if [ ${OS_VERSION} == 7 ]; then
cp ${HOME}/rpmbuild/RPMS/${OS_ARCH}/pgadmin4-python3-mod_wsgi-4.7.1-2.el7.x86_64.rpm "${DISTROOT}/"
fi
echo "Completed. RPMs created in ${DISTROOT}."
+110
View File
@@ -0,0 +1,110 @@
#!/bin/bash
# Set the repo RPM version and build
REPO_RPM_VERSION=1
REPO_RPM_BUILD=1
# Set the repo base directory
if [ "x${PGADMIN_REPO_DIR}" == "x" ]; then
echo "PGADMIN_REPO_DIR not set. Setting it to the default: https://ftp.postgresql.org/pub/pgadmin/pgadmin4/repos/yum"
export PGADMIN_REPO_DIR=https://ftp.postgresql.org/pub/pgadmin/pgadmin4/repos/yum
fi
# Exit when any command fails
set -e
# Debugging shizz
trap 'last_command=$current_command; current_command=$BASH_COMMAND' DEBUG
trap 'if [ $? -ne 0 ]; then echo "\"${last_command}\" command filed with exit code $?."; fi' EXIT
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
OS_NAME=$(cat /etc/os-release | grep "^ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
OS_ARCH=$(arch)
# Common Linux build functions
source pkg/linux/build-functions.sh
# Are we installing a package key?
INCLUDE_KEY=0
if [ -f "pkg/redhat/PGADMIN_PKG_KEY" ]; then
INCLUDE_KEY=1
echo "Building repo RPMs including a package signing key..."
else
echo "pkg/redhat/PGADMIN_PKG_KEY not found."
echo "Building repo RPMs WITHOUT a package signing key..."
sleep 5
fi
# Create the Redhat packaging stuffs for the repo
_create_repo_rpm() {
DISTRO=$1
if [ ${DISTRO} == "redhat" ]; then
PLATFORM="rhel"
else
PLATFORM=${DISTRO}
fi
echo "Creating the repo package for ${DISTRO}..."
test -d ${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d || mkdir -p ${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d
cat << EOF > "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
[pgAdmin4]
name=pgadmin4
baseurl=${PGADMIN_REPO_DIR}/${DISTRO}/${PLATFORM}-\$releasever-\$basearch
enabled=1
EOF
if [ ${INCLUDE_KEY} -eq 1 ]; then
echo gpgcheck=1 >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
echo gpgkey=file:///etc/pki/rpm-gpg/PGADMIN_PKG_KEY >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
else
echo gpgcheck=0 >> "${BUILDROOT}/${DISTRO}-repo/etc/yum.repos.d/pgadmin4.repo"
fi
echo "Creating the spec file for ${DISTRO}..."
cat << EOF > "${BUILDROOT}/${DISTRO}-repo.spec"
%global __requires_exclude_from ^/.*$
%global __provides_exclude_from ^/.*$
Name: ${APP_NAME}-${DISTRO}-repo
Version: ${REPO_RPM_VERSION}
Release: ${REPO_RPM_BUILD}
BuildArch: noarch
Summary: Repository configuration for the pgAdmin ${DISTRO^} repositories.
License: PostgreSQL
URL: https://www.pgadmin.org/
%description
The yum repository configuration for ${DISTRO^} platforms.
%build
%install
cp -rfa %{pga_build_root}/${DISTRO}-repo/* \${RPM_BUILD_ROOT}
%files
/etc/yum.repos.d/pgadmin4.repo
EOF
if [ ${INCLUDE_KEY} -eq 1 ]; then
cat << EOF >> ${BUILDROOT}/${DISTRO}-repo.spec
/etc/pki/rpm-gpg/PGADMIN_PKG_KEY
EOF
test -d ${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg || mkdir -p ${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg
cp pkg/redhat/PGADMIN_PKG_KEY ${BUILDROOT}/${DISTRO}-repo/etc/pki/rpm-gpg/
fi
# Build the package
echo "Building the repo RPM for ${DISTRO}..."
rpmbuild --define "pga_build_root ${BUILDROOT}" -bb "${BUILDROOT}/${DISTRO}-repo.spec"
}
_setup_env $0 "redhat"
_create_repo_rpm redhat
_create_repo_rpm fedora
#
# Get the results!
#
test -d "${DISTROOT}/" || mkdir -p "${DISTROOT}/"
cp ${HOME}/rpmbuild/RPMS/noarch/${APP_NAME}-*-repo-${REPO_RPM_VERSION}-${REPO_RPM_BUILD}.noarch.rpm "${DISTROOT}/"
+28 -10
View File
@@ -8,9 +8,18 @@ fi
OS_VERSION=$(cat /etc/os-release | grep "^VERSION_ID=" | awk -F "=" '{ print $2 }' | sed 's/"//g')
# EPEL & other repos
yum -y install centos-release-scl
yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-${OS_VERSION}.noarch.rpm
if [ ${OS_VERSION} == 8 ]; then
yum config-manager --enable PowerTools AppStream BaseOS *epel
dnf -qy module disable postgresql
fi
# PostgreSQL repo
if [ ${OS_VERSION} == 7 ] || [ ${OS_VERSION} == 8 ]; then
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-${OS_VERSION}-x86_64/pgdg-redhat-repo-latest.noarch.rpm
else
yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/F-${OS_VERSION}-x86_64/pgdg-fedora-repo-latest.noarch.rpm
fi
# Node repo
@@ -26,28 +35,37 @@ echo "Installing build pre-requisites..."
yum groupinstall -y "Development Tools"
if [ ${OS_VERSION} == 7 ]; then
yum install -y expect fakeroot httpd-devel qt5-qtbase-devel postgresql-devel python3-devel nodejs yarn rpm-build rpm-sign
yum install -y expect fakeroot httpd-devel qt5-qtbase-devel postgresql12-devel python3-devel nodejs yarn rpm-build rpm-sign yum-utils
pip3 install sphinx
else
yum install -y expect fakeroot qt5-qtbase-devel libpq-devel python3-devel python3-sphinx nodejs yarn rpm-build rpm-sign
yum install -y expect fakeroot qt5-qtbase-devel postgresql12-devel python3-devel python3-sphinx nodejs yarn rpm-build rpm-sign yum-utils
fi
# Setup RPM macros for signing
echo "Please add the following macros to ~/.rpmmacros for the user that will sign the RPMs if required:"
echo
cat << EOF
if [ ${OS_VERSION} == 7 ]; then
cat << EOF
# Macros for signing RPMs.
%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name Package Manager
%_gpgbin /usr/bin/gpg2
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename} --digest-algo sha256 %{__plaintext_filename}'
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --passphrase-fd 3 --no-secmem-warning -u "%{_gpg_name}" -sbo %{__
signature_filename} --digest-algo sha256 %{__plaintext_filename}
EOF
else
cat << EOF
# Macros for signing RPMs.
%_signature gpg
%_gpg_path ~/.gnupg
%_gpg_name <your signing key>
%_gpgbin /usr/bin/gpg2
%__gpg_sign_cmd %{__gpg} gpg --force-v3-sigs --batch --verbose --no-armor --no-secmem-warning -u "%{_gpg_name}" -sbo %{__signature_filename
} --digest-algo sha256 %{__plaintext_filename}
EOF
fi
echo
+2 -2
View File
@@ -69,7 +69,7 @@ do
tar cf - ${FILE} | (cd src-build/${TARBALL_NAME}; tar xf -)
done
pushd web
pushd web > /dev/null
yarn install
yarn run bundle
@@ -78,7 +78,7 @@ pushd web
echo Adding ${FILE}
tar cf - ${FILE} | (cd ../src-build/${TARBALL_NAME}/web; tar xf -)
done
popd
popd > /dev/null
# Create the tarball
echo Creating tarball...
+136 -27
View File
@@ -1,46 +1,155 @@
Building pgAdmin windows installer on windows
=================================
These notes describe how to setup a Windows development/build environment for
pgAdmin. They assume a 64bit build is required; adjustments will be required for
a 32bit build.
To generate a pgAdmin 4 installer for Windows bit, the following packages must be installed:
Installing build requirements
=============================
1. Python installation
- Python 2.7 or 3.4+ or above from https://www.python.org/
1) Install Qt 5.14.2: https://www.qt.io/download-qt-installer
2. QT installation
- Qt 4.6 through 5.5 from http://www.qt.io/
Use the MSVC++ 2017 64bit option.
3. PostgreSQL installation
- PostgreSQL 9.1 or above from http://www.postgresql.org/
2) Install Visual Studio 2017 Pro: https://my.visualstudio.com/Downloads?q=Visual%20Studio%202017
4. Inno Setup Installer (unicode)
- 5.0 and above from http://www.jrsoftware.org/isdl.php
Choose the Desktop development with C++ option.
5. Microsoft visual studio (2008 and above)
3) Install Chocolatey: https://chocolatey.org/install#individual
Building: Depending upon the archicture of the OS(x86|amd64) set then environment variables.
4) Install various command line tools:
1. Set the PYTHON environment variable to the Python root installation directory, e.g. for x86
choco install -y bzip2 cmake diffutils gzip git innosetup nodejs-lts python strawberryperl wget yarn
SET "PYTHON_HOME=C:\Python27"
SET "PYTHON_DLL=C:\Windows\System32\python27.dll"
5) Upgrade pip (this may give a permissions error that can be ignored):
2. Set the QTDIR environment variable to the QT root installation directory, e.g. for x86
pip install --upgrade pip
SET "QTDIR=C:\Qt\Qt5.5.1\5.5\msvc2013"
6) Install virtualenv
3. Set the PGDIR environment variable to the PostgreSQL installation directory, e.g. for x86
pip install virtualenv
SET "PGDIR=C:\Program Files\PostgreSQL\9.5"
Building dependencies
=====================
4. Set the Inno Setup Installer environment variable to the Inno root installation directory, e.g. for x86
The following steps should be run from a Visual Studio 2017 64bit command
prompt.
SET "INNOTOOL=C:\Program Files\Inno Setup 5"
1) Create a directory for the dependencies:
5. Set the Miscrosoft Visual studio environment variable to the Visual studio root installation directory, e.g. for x86
mkdir c:\build64
SET "VCDIR=C:\Program Files\Microsoft Visual Studio 12.0\VC"
2) Download the zlib source code, unpack, and build it:
6. To build, go to pgAdmin4 source root directory and execute "Make.bat x86|amd64". Based on x86|amd64, this will
create the python virtual environment and install all the required python modules mentioned in the
requirements file using pip, build the runtime code and finally create the windows installer x86|amd64 in ./dist directory
wget https://zlib.net/zlib-1.2.11.tar.gz
tar -zxvf zlib-1.2.11.tar.gz
cd zlib-1.2.11
cmake -DCMAKE_INSTALL_PREFIX=C:/build64/zlib -G "Visual Studio 15 2017 Win64" .
msbuild RUN_TESTS.vcxproj /p:Configuration=Release
msbuild INSTALL.vcxproj /p:Configuration=Release
copy C:\build64\zlib\lib\zlib.lib C:\build64\zlib\lib\zdll.lib
3) Download the OpenSSL source code, unpack and build it:
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz
tar -zxvf openssl-1.1.1g.tar.gz
cd openssl-1.1.1g
perl Configure VC-WIN64A no-asm --prefix=C:\build64\openssl no-ssl2 no-ssl3 no-comp
nmake
nmake test
nmake install
Note that if you are not working in an administrative account, you may need to
create and give your regular account appropriate permissions to write/modify
files in C:\Program Files\Common Files\SSL. This is the default directory used
for the OPENSSLDIR, and should not be changed to a directory that un-privileged
users could potentially write to.
4) Download the PostgreSQL source code, unpack and build it:
wget https://ftp.postgresql.org/pub/source/v12.3/postgresql-12.3.tar.bz2
tar -zxvf postgresql-12.3.tar.gz
cd postgresql-12.3\src\tools\msvc
>> config.pl echo # Configuration arguments for vcbuild.
>> config.pl echo use strict;
>> config.pl echo use warnings;
>> config.pl echo.
>> config.pl echo our $config = {
>> config.pl echo asserts =^> 0, # --enable-cassert
>> config.pl echo ldap =^> 1, # --with-ldap
>> config.pl echo extraver =^> undef, # --with-extra-version=^<string^>
>> config.pl echo gss =^> undef, # --with-gssapi=^<path^>
>> config.pl echo icu =^> undef, # --with-icu=^<path^>
>> config.pl echo nls =^> undef, # --enable-nls=^<path^>
>> config.pl echo tap_tests =^> undef, # --enable-tap-tests
>> config.pl echo tcl =^> undef, # --with-tcl=^<path^>
>> config.pl echo perl =^> undef, # --with-perl
>> config.pl echo python =^> undef, # --with-python=^<path^>
>> config.pl echo openssl =^> 'C:\build64\openssl', # --with-openssl=^<path^>
>> config.pl echo uuid =^> undef, # --with-ossp-uuid
>> config.pl echo xml =^> undef, # --with-libxml=^<path^>
>> config.pl echo xslt =^> undef, # --with-libxslt=^<path^>
>> config.pl echo iconv =^> undef, # (not in configure, path to iconv)
>> config.pl echo zlib =^> 'C:\build64\zlib' # --with-zlib=^<path^>
>> config.pl echo };
>> config.pl echo.
>> config.pl echo 1;
>> buildenv.pl echo $ENV{PATH} = "C:\\build64\\openssl\\bin;C:\\build64\\zlib\\bin;$ENV{PATH}";
perl build.pl Release
perl vcregress.pl check
perl install.pl C:\build64\pgsql
copy C:\build64\zlib\bin\zlib.dll C:\build64\pgsql\bin"
copy C:\build64\openssl\bin\libssl-1_1-x64.dll C:\build64\pgsql\bin"
copy C:\build64\openssl\bin\libcrypto-1_1-x64.dll C:\build64\pgsql\bin"
Setting up a dev environment
============================
This section describes the steps to setup and run pgAdmin for the first time in
a development environment. You do not need to complete this section if you just
want to build an installer.
1) Check out the source code:
git clone https://git.postgresql.org/git/pgadmin4.git
2) Install and build the JS dependencies
cd pgadmin4\web
yarn install
yarn run bundle
3) Create a virtual env
cd pgadmin4
python -m venv venv
pip install -r web\regression\requirements.txt
pip install sphinx
You should now be able to run the pgAdmin Python application, or build the
desktop runtime.
Building an installer
=====================
1) Set the required environment variables, either system-wide, or in a Visual
Studio 2017 64bit command prompt. Note that the examples shown below are the
defaults for the build system, so if they match your requirements you don't
need to set them:
SET "PGADMIN_POSTGRES_DIR=C:\Program Files\PostgreSQL\12"
SET "PGADMIN_PYTHON_DIR=C:\Python38"
SET "PGADMIN_QT_DIR=C:\Qt\5.14.2\msvc2017_64"
SET "PGADMIN_INNOTOOL_DIR=C:\Program Files (x86)\Inno Setup 6"
SET "PGADMIN_SIGNTOOL_DIR=C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64"
SET "PGADMIN_VCREDIST_DIR=C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Redist\MSVC\14.16.27012"
2) Run:
make
If you have a code signing certificate, this will automatically be used if
found in the Windows Certificate Store to sign the installer.
3) Find the completed installer in the dist/ subdirectory of your source tree.
+62 -15
View File
@@ -8,6 +8,8 @@
#define MyAppArchitecturesMode MYAPP_ARCHITECTURESMODE
#define MyAppVCDist MYAPP_VCDIST
#define MyAppInvalidPath "Please provide a valid path."
#define MyAppErrorMsgIsWin32 "You already have a 32 bit installation of pgAdmin 4. Please uninstall this before installing the 64 bit version."
#define MyAppErrorMsgIsWin64 "You already have a 64 bit installation of pgAdmin 4. Please uninstall this before installing the 32 bit version."
[Setup]
AppId={#MyAppName}{#MyAppVersion}
@@ -35,7 +37,7 @@ AllowNoIcons=yes
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
;This section will override the standered error message by default which is called internally and we don't have a controll over this.
;This section will override the standard error message by default which is called internally and we don't have a control over this.
[Messages]
InvalidPath={#MyAppInvalidPath}
@@ -170,30 +172,75 @@ begin
Result := Ret;
end;
// Find current version before installation
function InitializeSetup: Boolean;
function CheckPgAdminAlreadyInstalled: Boolean;
var
Version: String;
InstallationFound: Boolean;
begin
if RegValueExists(HKEY_LOCAL_MACHINE,'Software\{#MyAppName}\{#MyAppVersion}', 'Version') then
InstallationFound := False;
// Check the installation mode 64 or 32 bit of installer
if Is64BitInstallMode then
begin
UpgradeMode := True;
RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\{#MyAppName}\{#MyAppVersion}', 'Version', Version);
if CompareVersions(Version, '{#MyAppFullVersion}') = 1 then
// Check if pgAdmin 32 bit is already installed
RegQueryStringValue(HKLM32,'Software\{#MyAppName}\{#MyAppVersion}', 'Version', Version);
// If version is found then shouldn't install 64bit - abort
if Length(Version) > 0 then
begin
MsgBox(ExpandConstant('{cm:NewerVersionExists}' + '(v' + Version + ') is already installed' ), mbInformation, MB_OK);
Result := False;
end
else
begin
Result := True;
MsgBox(ExpandConstant('{#MyAppErrorMsgIsWin32}'), mbCriticalError, MB_OK);
Result := False;
InstallationFound := True;
end;
end
else
begin
Result := True;
UpgradeMode := False;
// Suppose system is running a 32-bit version of Windows then no need to check HKLM64 in RegQueryStringValue
// So IsWin64 - will make sure its should only execute on 64-bit veersion of windows.
if IsWin64 then
begin
// Check if pgAdmin 64 bit is already installed
RegQueryStringValue(HKLM64,'Software\{#MyAppName}\{#MyAppVersion}', 'Version', Version);
// If version is found the shouldn't install 32bit - abort
if Length(Version) > 0 then
begin
MsgBox(ExpandConstant('{#MyAppErrorMsgIsWin64}'), mbCriticalError, MB_OK);
Result := False;
InstallationFound := True;
end;
end;
end;
if not (InstallationFound) then
begin
if RegValueExists(HKEY_LOCAL_MACHINE,'Software\{#MyAppName}\{#MyAppVersion}', 'Version') then
begin
UpgradeMode := True;
RegQueryStringValue(HKEY_LOCAL_MACHINE,'Software\{#MyAppName}\{#MyAppVersion}', 'Version', Version);
if CompareVersions(Version, '{#MyAppFullVersion}') = 1 then
begin
MsgBox(ExpandConstant('{cm:NewerVersionExists}' + '(v' + Version + ') is already installed' ), mbInformation, MB_OK);
Result := False;
end
else
begin
Result := True;
end;
end;
end;
if ( not (InstallationFound) and not (UpgradeMode) ) then
begin
// This is required as it will be passed on to the InitializeSetup function
Result := True;
end;
end;
// Find current version before installation
function InitializeSetup: Boolean;
begin
Result := CheckPgAdminAlreadyInstalled;
end;
function IsUpgradeMode(): Boolean;
+3 -1
View File
@@ -38,5 +38,7 @@ psycopg2>=2.8
python-dateutil>=2.8.0
SQLAlchemy>=1.3.13
Flask-Security-Too>=3.0.0
sshtunnel>=0.1.4
bcrypt<=3.1.7
cryptography<=3.0
sshtunnel>=0.1.5
ldap3>=2.5.1
+95 -80
View File
@@ -9,28 +9,106 @@
//
//////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
#include "ConfigWindow.h"
#include "ui_ConfigWindow.h"
#include <QSettings>
#include <QTcpSocket>
#include <QtWidgets>
ConfigWindow::ConfigWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::ConfigWindow)
QDialog(parent)
{
ui->setupUi(this);
initConfigWindow();
}
ConfigWindow::~ConfigWindow()
void ConfigWindow::initConfigWindow()
{
delete ui;
ui = new Ui::ConfigWindow;
ui->setupUi(this);
m_needRestart = false;
setConfigValues();
}
void ConfigWindow::setConfigValues()
{
QSettings settings;
ui->browserCommandLineEdit->setText(settings.value("BrowserCommand").toString());
if(settings.value("FixedPort").toBool())
{
ui->chkFixedPort->setCheckState(Qt::Checked);
ui->spinPortNumber->setEnabled(true);
}
else
{
ui->chkFixedPort->setCheckState(Qt::Unchecked);
ui->spinPortNumber->setEnabled(false);
}
ui->spinPortNumber->setValue(settings.value("PortNumber").toInt());
if (settings.value("OpenTabAtStartup", true).toBool())
{
ui->chkOpenTabAtStartup->setCheckState(Qt::Checked);
}
else
{
ui->chkOpenTabAtStartup->setCheckState(Qt::Unchecked);
}
ui->pythonPathLineEdit->setText(settings.value("PythonPath").toString());
ui->applicationPathLineEdit->setText(settings.value("ApplicationPath").toString());
}
void ConfigWindow::on_buttonBox_accepted()
{
QSettings settings;
// Save the settings, and return true if a restart is required, otherwise false.
QString browsercommand = ui->browserCommandLineEdit->text();
bool fixedport = ui->chkFixedPort->isChecked();
int portnumber = ui->spinPortNumber->value();
bool opentabatstartup = ui->chkOpenTabAtStartup->isChecked();
QString pythonpath = ui->pythonPathLineEdit->text();
QString applicationpath = ui->applicationPathLineEdit->text();
if (fixedport && (settings.value("FixedPort").toBool() != fixedport ||
settings.value("PortNumber").toInt() != portnumber) && isPortInUse(portnumber))
{
QString error = QString(QWidget::tr("The specified fixed port is already in use. Please provide any other valid port."));
QMessageBox::critical(Q_NULLPTR, QString(QWidget::tr("Fatal Error")), error);
}
else
{
m_needRestart = (settings.value("FixedPort").toBool() != fixedport ||
settings.value("PortNumber").toInt() != portnumber ||
settings.value("PythonPath").toString() != pythonpath ||
settings.value("ApplicationPath").toString() != applicationpath);
settings.setValue("BrowserCommand", browsercommand);
settings.setValue("FixedPort", fixedport);
settings.setValue("PortNumber", portnumber);
settings.setValue("OpenTabAtStartup", opentabatstartup);
settings.setValue("PythonPath", pythonpath);
settings.setValue("ApplicationPath", applicationpath);
settings.sync();
}
emit accepted(m_needRestart);
emit closing(true);
this->close();
}
void ConfigWindow::on_buttonBox_rejected()
{
emit closing(false);
this->close();
}
@@ -42,80 +120,17 @@ void ConfigWindow::on_chkFixedPort_stateChanged(int state)
ui->spinPortNumber->setEnabled(false);
}
QString ConfigWindow::getBrowserCommand()
bool ConfigWindow::isPortInUse(const quint16 port) const
{
return ui->browserCommandLineEdit->text();
QTcpSocket socket;
// Bind the socket on the specified port.
socket.bind(port, QTcpSocket::DontShareAddress);
// Returns the host port number of the local socket if available; otherwise returns 0
quint16 tmpPort = socket.localPort();
if (tmpPort == 0)
return true;
return false;
}
bool ConfigWindow::getFixedPort()
{
return ui->chkFixedPort->isChecked();
}
int ConfigWindow::getPortNumber()
{
return ui->spinPortNumber->value();
}
bool ConfigWindow::getOpenTabAtStartup()
{
return ui->chkOpenTabAtStartup->isChecked();
}
QString ConfigWindow::getPythonPath()
{
return ui->pythonPathLineEdit->text();
}
QString ConfigWindow::getApplicationPath()
{
return ui->applicationPathLineEdit->text();
}
void ConfigWindow::setBrowserCommand(QString command)
{
ui->browserCommandLineEdit->setText(command);
}
void ConfigWindow::setFixedPort(bool fixedPort)
{
if (fixedPort)
{
ui->chkFixedPort->setCheckState(Qt::Checked);
ui->spinPortNumber->setEnabled(true);
}
else
{
ui->chkFixedPort->setCheckState(Qt::Unchecked);
ui->spinPortNumber->setEnabled(false);
}
}
void ConfigWindow::setPortNumber(int port)
{
ui->spinPortNumber->setValue(port);
}
void ConfigWindow::setOpenTabAtStartup(bool openTabAtStartup)
{
if (openTabAtStartup)
{
ui->chkOpenTabAtStartup->setCheckState(Qt::Checked);
}
else
{
ui->chkOpenTabAtStartup->setCheckState(Qt::Unchecked);
}
}
void ConfigWindow::setPythonPath(QString path)
{
ui->pythonPathLineEdit->setText(path);
}
void ConfigWindow::setApplicationPath(QString path)
{
ui->applicationPathLineEdit->setText(path);
}
+8 -14
View File
@@ -24,21 +24,11 @@ class ConfigWindow : public QDialog
public:
explicit ConfigWindow(QWidget *parent = Q_NULLPTR);
~ConfigWindow();
void setConfigValues();
QString getBrowserCommand();
bool getFixedPort();
int getPortNumber();
bool getOpenTabAtStartup();
QString getPythonPath();
QString getApplicationPath();
void setBrowserCommand(QString command);
void setFixedPort(bool fixedPort);
void setPortNumber(int port);
void setOpenTabAtStartup(bool openTabAtStartup);
void setPythonPath(QString path);
void setApplicationPath(QString path);
signals:
void accepted(bool needRestart);
void closing(bool accepted);
private slots:
void on_buttonBox_accepted();
@@ -47,6 +37,10 @@ private slots:
private:
Ui::ConfigWindow *ui;
bool m_needRestart;
void initConfigWindow();
bool isPortInUse(const quint16 port) const;
};
#endif // CONFIGWINDOW_H
+49 -54
View File
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>975</width>
<height>398</height>
<width>800</width>
<height>415</height>
</rect>
</property>
<property name="sizePolicy">
@@ -18,12 +18,12 @@
</property>
<property name="minimumSize">
<size>
<width>975</width>
<height>300</height>
<width>800</width>
<height>415</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>pgAdmin 4 Configuration</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@@ -81,7 +81,7 @@
</property>
<property name="minimumSize">
<size>
<width>150</width>
<width>250</width>
<height>0</height>
</size>
</property>
@@ -96,22 +96,6 @@
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLineEdit" name="browserCommandLineEdit">
<property name="placeholderText">
@@ -132,7 +116,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>20</height>
</size>
</property>
</spacer>
@@ -140,7 +124,7 @@
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>By default the runtime uses a random port number to ensure it can always run successfully. If you need to use a predictable port number, you can set one here. Note that if the port is already in use, the application will be unable start.</string>
<string>By default the runtime uses a random port number to ensure it can always run successfully. If you need to use a predictable port number, you can set one here. Note that if the port is already in use, the application will be unable to start.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
@@ -159,7 +143,7 @@
</property>
<property name="minimumSize">
<size>
<width>150</width>
<width>250</width>
<height>0</height>
</size>
</property>
@@ -261,7 +245,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>20</height>
</size>
</property>
</spacer>
@@ -280,6 +264,12 @@
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_9">
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Open a Browser Window/Tab at Startup?</string>
</property>
@@ -313,19 +303,6 @@
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
@@ -365,8 +342,8 @@
</property>
<property name="minimumSize">
<size>
<width>450</width>
<height>28</height>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
@@ -401,10 +378,16 @@
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="pythonPathLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>50</width>
<height>20</height>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="layoutDirection">
@@ -427,12 +410,12 @@
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -444,7 +427,7 @@
<item>
<widget class="QLineEdit" name="pythonPathLineEdit">
<property name="placeholderText">
<string>/usr/pgadmin4/lib/python2.7;/usr/pgadmin4/lib/python2.7/site-packages</string>
<string>/usr/pgadmin4/lib/python3.8;/usr/pgadmin4/lib/python3.8/site-packages</string>
</property>
</widget>
</item>
@@ -458,8 +441,8 @@
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
@@ -499,6 +482,18 @@
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="applicationPathLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>250</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Application Path</string>
</property>
@@ -513,12 +508,12 @@
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@@ -544,8 +539,8 @@
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
+59 -19
View File
@@ -9,30 +9,25 @@
//
////////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
#include "FloatingWindow.h"
#include "ui_FloatingWindow.h"
#include <QMenu>
#include <QMenuBar>
FloatingWindow::FloatingWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::FloatingWindow)
QMainWindow(parent)
{
m_newAction = Q_NULLPTR;
m_configAction = Q_NULLPTR;
m_logAction = Q_NULLPTR;
m_quitAction = Q_NULLPTR;
m_menuActions = Q_NULLPTR;
m_floatingWindowMenu = Q_NULLPTR;
ui->setupUi(this);
}
FloatingWindow::~FloatingWindow()
{
delete ui;
}
bool FloatingWindow::Init()
{
ui = new Ui::FloatingWindow;
ui->setupUi(this);
// Creating Menu
createMenu();
@@ -50,12 +45,13 @@ bool FloatingWindow::Init()
return true;
}
// Create the menu
void FloatingWindow::createMenu()
{
createActions();
m_floatingWindowMenu = menuBar()->addMenu(QString(tr("&%1")).arg(PGA_APP_NAME));
m_floatingWindowMenu = menuBar()->addMenu(tr("&pgAdmin 4"));
m_floatingWindowMenu->addAction(m_newAction);
m_floatingWindowMenu->addAction(m_copyUrlAction);
m_floatingWindowMenu->addSeparator();
@@ -65,19 +61,24 @@ void FloatingWindow::createMenu()
m_floatingWindowMenu->addAction(m_quitAction);
}
// Create the menu actions
void FloatingWindow::createActions()
{
m_newAction = new QAction(QString(tr("&New %1 window...")).arg(PGA_APP_NAME), this);
m_newAction = new QAction(tr("&New pgAdmin 4 window..."), this);
m_newAction->setEnabled(false);
connect(m_newAction, SIGNAL(triggered()), m_menuActions, SLOT(onNew()));
m_copyUrlAction = new QAction(tr("&Copy server URL"), this);
m_copyUrlAction->setEnabled(false);
connect(m_copyUrlAction, SIGNAL(triggered()), m_menuActions, SLOT(onCopyUrl()));
m_configAction = new QAction(tr("C&onfigure..."), this);
m_configAction->setEnabled(false);
connect(m_configAction, SIGNAL(triggered()), m_menuActions, SLOT(onConfig()));
m_logAction = new QAction(tr("&View log..."), this);
m_logAction->setEnabled(false);
connect(m_logAction, SIGNAL(triggered()), m_menuActions, SLOT(onLog()));
m_quitAction = new QAction(tr("&Shut down server"), this);
@@ -85,12 +86,23 @@ void FloatingWindow::createActions()
connect(m_quitAction, SIGNAL(triggered()), m_menuActions, SLOT(onQuit()));
}
void FloatingWindow::enableShutdownMenu()
void FloatingWindow::enablePostStartOptions()
{
if (m_newAction != Q_NULLPTR)
m_newAction->setEnabled(true);
if (m_copyUrlAction != Q_NULLPTR)
m_copyUrlAction->setEnabled(true);
if (m_configAction != Q_NULLPTR)
m_configAction->setEnabled(true);
if (m_logAction != Q_NULLPTR)
m_logAction->setEnabled(true);
if (m_quitAction != Q_NULLPTR)
{
m_quitAction->setEnabled(true);
}
}
void FloatingWindow::setMenuActions(MenuActions * menuActions)
@@ -98,6 +110,34 @@ void FloatingWindow::setMenuActions(MenuActions * menuActions)
m_menuActions = menuActions;
}
// Enable the View Log option
void FloatingWindow::enableViewLogOption()
{
if (m_logAction != Q_NULLPTR)
m_logAction->setEnabled(true);
}
// Disable the View Log option
void FloatingWindow::disableViewLogOption()
{
if (m_logAction != Q_NULLPTR)
m_logAction->setEnabled(false);
}
// Enable the configure option
void FloatingWindow::enableConfigOption()
{
if (m_configAction != Q_NULLPTR)
m_configAction->setEnabled(true);
}
// Disable the configure option
void FloatingWindow::disableConfigOption()
{
if (m_configAction != Q_NULLPTR)
m_configAction->setEnabled(false);
}
void FloatingWindow::closeEvent(QCloseEvent * event)
{
// Emit the signal to shut down the python server.
+12 -11
View File
@@ -9,11 +9,9 @@
//
////////////////////////////////////////////////////////////////////////////
#ifndef FLOATINGWINDOW_H
#define FLOATINGWINDOW_H
#include "pgAdmin4.h"
#include "MenuActions.h"
#include <QMainWindow>
@@ -28,10 +26,13 @@ class FloatingWindow : public QMainWindow
public:
explicit FloatingWindow(QWidget *parent = Q_NULLPTR);
~FloatingWindow();
bool Init();
void enableShutdownMenu();
void enablePostStartOptions();
void enableViewLogOption();
void disableViewLogOption();
void enableConfigOption();
void disableConfigOption();
void setMenuActions(MenuActions * menuActions);
private:
@@ -41,14 +42,14 @@ private:
void createActions();
void closeEvent(QCloseEvent * event);
QAction *m_newAction;
QAction *m_copyUrlAction;
QAction *m_configAction;
QAction *m_logAction;
QAction *m_quitAction;
QAction *m_newAction = Q_NULLPTR;
QAction *m_copyUrlAction = Q_NULLPTR;
QAction *m_configAction = Q_NULLPTR;
QAction *m_logAction = Q_NULLPTR;
QAction *m_quitAction = Q_NULLPTR;
QMenu *m_floatingWindowMenu;
MenuActions *m_menuActions;
QMenu *m_floatingWindowMenu = Q_NULLPTR;
MenuActions *m_menuActions = Q_NULLPTR;
signals:
void shutdownSignal(QUrl);
+1 -1
View File
@@ -17,7 +17,7 @@
</sizepolicy>
</property>
<property name="windowTitle">
<string>MainWindow</string>
<string>pgAdmin 4</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QWidget" name="verticalLayoutWidget">
+2 -2
View File
@@ -8,9 +8,9 @@
<key>CFBundleName</key>
<string>pgAdmin 4</string>
<key>CFBundleShortVersionString</key>
<string>4.21.0</string>
<string>4.26.0</string>
<key>CFBundleVersion</key>
<string>4.21.0</string>
<string>4.26.0</string>
<key>LSMinimumSystemVersion</key>
<string>10.10</string>
<key>NSHumanReadableCopyright</key>
+36 -22
View File
@@ -9,58 +9,74 @@
//
//////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
#include "LogWindow.h"
#include "ui_LogWindow.h"
#include <QStandardPaths>
#include <QTime>
#include <stdio.h>
LogWindow::LogWindow(QWidget *parent, QString logFile) :
QDialog(parent),
ui(new Ui::LogWindow),
m_logFile(logFile)
LogWindow::LogWindow(QWidget *parent) :
QDialog(parent)
{
initLogWindow();
}
void LogWindow::initLogWindow()
{
ui = new Ui::LogWindow;
ui->setupUi(this);
}
LogWindow::~LogWindow()
void LogWindow::LoadLog()
{
delete ui;
int startupLines;
int serverLines;
ui->lblStatus->setText(tr("Loading logfiles..."));
ui->lblStartupLog->setText(tr("Startup Log (%1):").arg(g_startupLogFile));
ui->lblServerLog->setText(tr("Server Log (%1):").arg(g_serverLogFile));
startupLines = this->readLog(g_startupLogFile, ui->textStartupLog);
serverLines = this->readLog(g_serverLogFile, ui->textServerLog);
ui->lblStatus->setText(QString(tr("Loaded startup log (%1 lines) and server log (%2 lines).")).arg(startupLines).arg(serverLines));
}
void LogWindow::reload()
{
this->ReadLog();
this->LoadLog();
}
// Read the logfile
void LogWindow::ReadLog()
int LogWindow::readLog(QString logFile, QPlainTextEdit *logWidget)
{
FILE *log;
char *buffer;
long len = 0;
int i, lines = 0;
int i;
int lines = 0;
// Look busy!
QApplication::setOverrideCursor(Qt::WaitCursor);
ui->lblStatus->setText(tr("Loading logfile..."));
this->setDisabled(true);
QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
ui->textLog->clear();
logWidget->clear();
// Attempt to open the file
log = fopen(m_logFile.toUtf8().data(), "r");
log = fopen(logFile.toUtf8().data(), "r");
if (log == Q_NULLPTR)
{
ui->textLog->setPlainText(QString(tr("The log file (%1) could not be opened.")).arg(m_logFile));
logWidget->setPlainText(QString(tr("The log file (%1) could not be opened.")).arg(g_serverLogFile));
this->setDisabled(false);
QApplication::restoreOverrideCursor();
return;
return 0;
}
// Get the file size, and read the data
@@ -70,20 +86,18 @@ void LogWindow::ReadLog()
buffer = static_cast<char *>(malloc((len + 1) * sizeof(char)));
for (i = 0; i < len; i++) {
if (fread(buffer + i, 1, 1, log) > 0)
{
if (buffer[i] == '\n')
lines++;
}
if (fread(buffer + i, 1, 1, log) > 0 && buffer[i] == '\n')
lines++;
}
buffer[i] = 0;
fclose(log);
ui->textLog->setPlainText(buffer);
logWidget->setPlainText(buffer);
// And... relax
ui->lblStatus->setText(QString(tr("Loaded logfile (%1 lines).")).arg(lines));
this->setDisabled(false);
QApplication::restoreOverrideCursor();
return lines;
}
+5 -5
View File
@@ -13,6 +13,7 @@
#define LOGWINDOW_H
#include <QDialog>
#include <QPlainTextEdit>
namespace Ui {
class LogWindow;
@@ -23,10 +24,8 @@ class LogWindow : public QDialog
Q_OBJECT
public:
explicit LogWindow(QWidget *parent = Q_NULLPTR, QString logFile = "");
~LogWindow();
void ReadLog();
explicit LogWindow(QWidget *parent = Q_NULLPTR);
void LoadLog();
private slots:
void reload();
@@ -34,7 +33,8 @@ private slots:
private:
Ui::LogWindow *ui;
QString m_logFile;
void initLogWindow();
int readLog(QString logFile, QPlainTextEdit *logWidget);
};
#endif // LOGWINDOW_H
+34 -2
View File
@@ -11,11 +11,43 @@
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
<string>pgAdmin 4 Log</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="textLog">
<widget class="QLabel" name="lblStartupLog">
<property name="text">
<string>Startup Log:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="textStartupLog">
<property name="font">
<font>
<family>Courier</family>
</font>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string notr="true"/>
</property>
<property name="centerOnScroll">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblServerLog">
<property name="text">
<string>Server Log:</string>
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="textServerLog">
<property name="font">
<font>
<family>Courier</family>
+9 -5
View File
@@ -11,13 +11,18 @@
#include "pgAdmin4.h"
#include "Logger.h"
#include <QDateTime>
#include <QTextStream>
#include <QStandardPaths>
Logger* Logger::m_pThis = Q_NULLPTR;
QString Logger::m_sFileName = "";
QFile* Logger::m_Logfile = Q_NULLPTR;
Logger::Logger()
{
}
Logger::~Logger()
{
}
@@ -27,9 +32,8 @@ Logger* Logger::GetLogger()
if (m_pThis == Q_NULLPTR)
{
m_pThis = new Logger();
m_sFileName = QDir::homePath() + (QString("/.%1.startup.log").arg(PGA_APP_NAME)).remove(" ");
m_Logfile = new QFile;
m_Logfile->setFileName(m_sFileName);
m_Logfile->setFileName(g_startupLogFile);
m_Logfile->open(QIODevice::WriteOnly | QIODevice::Text);
m_Logfile->setPermissions(QFile::ReadOwner|QFile::WriteOwner);
}
@@ -37,9 +41,9 @@ Logger* Logger::GetLogger()
return m_pThis;
}
void Logger::Log(const QString& sMessage)
void Logger::Log(const QString& sMessage) const
{
QString text = QDateTime::currentDateTime().toString("dd.MM.yyyy hh:mm:ss ") + sMessage + "\n";
QString text = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss: ") + sMessage + "\n";
if (m_Logfile != Q_NULLPTR)
{
QTextStream out(m_Logfile);
+1 -3
View File
@@ -20,15 +20,13 @@ class Logger : public QObject
public:
static Logger* GetLogger();
static void ReleaseLogger();
void Log(const QString& sMessage);
void Log(const QString& sMessage) const;
private:
Logger();
virtual ~Logger();
private:
static Logger* m_pThis;
static QString m_sFileName;
static QFile *m_Logfile;
};
+28 -60
View File
@@ -9,20 +9,18 @@
//
//////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
#include "MenuActions.h"
// QT headers
#include <QApplication>
#include <QClipboard>
#include <QDesktopServices>
#include <QEventLoop>
#include <QMessageBox>
#include <QProcess>
#include <QSettings>
MenuActions::MenuActions()
{
m_logWindow = Q_NULLPTR;
m_logFile = "";
m_appServerUrl = "";
}
MenuActions::~MenuActions()
{
}
@@ -31,13 +29,9 @@ void MenuActions::setAppServerUrl(QString appServerUrl)
m_appServerUrl = appServerUrl;
}
void MenuActions::setLogFile(QString logFile)
{
m_logFile = logFile;
}
// Create a new application browser window on user request
void MenuActions::onNew()
void MenuActions::onNew() const
{
QSettings settings;
QString cmd = settings.value("BrowserCommand").toString();
@@ -61,7 +55,7 @@ void MenuActions::onNew()
// Copy the application server URL to the clipboard
void MenuActions::onCopyUrl()
void MenuActions::onCopyUrl() const
{
QClipboard *clipboard = QApplication::clipboard();
clipboard->setText(m_appServerUrl);
@@ -71,48 +65,25 @@ void MenuActions::onCopyUrl()
// Show the config dialogue
void MenuActions::onConfig()
{
QSettings settings;
bool ok;
if (!m_configWindow)
m_configWindow = new ConfigWindow();
ConfigWindow *dlg = new ConfigWindow();
dlg->setWindowTitle(QString(tr("%1 Configuration")).arg(PGA_APP_NAME));
dlg->setBrowserCommand(settings.value("BrowserCommand").toString());
dlg->setFixedPort(settings.value("FixedPort").toBool());
dlg->setPortNumber(settings.value("PortNumber").toInt());
dlg->setOpenTabAtStartup(settings.value("OpenTabAtStartup", true).toBool());
dlg->setPythonPath(settings.value("PythonPath").toString());
dlg->setApplicationPath(settings.value("ApplicationPath").toString());
dlg->setModal(true);
ok = dlg->exec();
m_configWindow->setConfigValues();
m_configWindow->show();
m_configWindow->raise();
m_configWindow->activateWindow();
connect(m_configWindow, SIGNAL(accepted(bool)), this, SLOT(onConfigDone(bool)));
}
QString browsercommand = dlg->getBrowserCommand();
bool fixedport = dlg->getFixedPort();
int portnumber = dlg->getPortNumber();
bool opentabatstartup = dlg->getOpenTabAtStartup();
QString pythonpath = dlg->getPythonPath();
QString applicationpath = dlg->getApplicationPath();
if (ok)
void MenuActions::onConfigDone(bool needRestart) const
{
if (needRestart && QMessageBox::Yes == QMessageBox::question(Q_NULLPTR,
tr("Shut down server?"),
tr("The pgAdmin 4 server must be restarted for changes to take effect. Do you want to shut down the server now?"),
QMessageBox::Yes | QMessageBox::No))
{
bool needRestart = (settings.value("FixedPort").toBool() != fixedport ||
settings.value("PortNumber").toInt() != portnumber ||
settings.value("PythonPath").toString() != pythonpath ||
settings.value("ApplicationPath").toString() != applicationpath);
settings.setValue("BrowserCommand", browsercommand);
settings.setValue("FixedPort", fixedport);
settings.setValue("PortNumber", portnumber);
settings.setValue("OpenTabAtStartup", opentabatstartup);
settings.setValue("PythonPath", pythonpath);
settings.setValue("ApplicationPath", applicationpath);
if (needRestart)
{
if (QMessageBox::Yes == QMessageBox::question(Q_NULLPTR, tr("Shut down server?"), QString(tr("The %1 server must be restarted for changes to take effect. Do you want to shut down the server now?")).arg(PGA_APP_NAME), QMessageBox::Yes | QMessageBox::No))
{
exit(0);
}
}
exit(0);
}
}
@@ -123,28 +94,25 @@ void MenuActions::onLog()
QSettings settings;
if (!m_logWindow)
{
m_logWindow = new LogWindow(Q_NULLPTR, m_logFile);
m_logWindow->setWindowTitle(QString(tr("%1 Log")).arg(PGA_APP_NAME));
}
m_logWindow = new LogWindow();
m_logWindow->show();
m_logWindow->raise();
m_logWindow->activateWindow();
QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
m_logWindow->ReadLog();
m_logWindow->LoadLog();
}
// Exit
void MenuActions::onQuit()
{
if (QMessageBox::Yes == QMessageBox::question(Q_NULLPTR, tr("Shut down server?"), QString(tr("Are you sure you want to shut down the %1 server?")).arg(PGA_APP_NAME), QMessageBox::Yes | QMessageBox::No))
if (QMessageBox::Yes == QMessageBox::question(Q_NULLPTR, tr("Shut down server?"), tr("Are you sure you want to shut down the pgAdmin 4 server?"), QMessageBox::Yes | QMessageBox::No))
{
// Emit the signal to shut down the python server.
emit shutdownSignal(m_appServerUrl);
exit(0);
QApplication::quit();
}
}
+9 -10
View File
@@ -12,9 +12,6 @@
#ifndef MENUACTIONS_H
#define MENUACTIONS_H
#include "pgAdmin4.h"
// App headers
#include "LogWindow.h"
#include "ConfigWindow.h"
@@ -23,19 +20,21 @@ class MenuActions: public QObject
Q_OBJECT
public:
MenuActions();
~MenuActions();
void setAppServerUrl(QString appServerUrl);
void setLogFile(QString logFile);
QString getAppServerUrl() { return m_appServerUrl; }
QString getAppServerUrl() const { return m_appServerUrl; }
private:
QString m_appServerUrl, m_logFile;
LogWindow *m_logWindow;
QString m_appServerUrl = "";
LogWindow *m_logWindow = Q_NULLPTR;
ConfigWindow *m_configWindow = Q_NULLPTR;
public slots:
void onConfigDone(bool needRestart) const;
protected slots:
void onNew();
void onCopyUrl();
void onNew() const;
void onCopyUrl() const;
void onConfig();
void onLog();
void onQuit();
+660
View File
@@ -0,0 +1,660 @@
//////////////////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
// Runtime.cpp - Core of the runtime
//
//////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
#include "Runtime.h"
#include "Server.h"
#include "TrayIcon.h"
#include "MenuActions.h"
#include "ConfigWindow.h"
#include "FloatingWindow.h"
#include "Logger.h"
#ifdef Q_OS_MAC
#include "macos.h"
#endif
// Must be before QT
#include <Python.h>
#include <QtWidgets>
#include <QNetworkProxyFactory>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTime>
Runtime::Runtime()
{
}
bool Runtime::go(int argc, char *argv[])
{
// Before starting main application, need to set 'QT_X11_NO_MITSHM=1'
// to make the runtime work with IBM PPC machines.
#if defined (Q_OS_LINUX)
QByteArray val("1");
qputenv("QT_X11_NO_MITSHM", val);
#endif
// Create the QT application
QApplication app(argc, argv);
app.setQuitOnLastWindowClosed(false);
// Setup look n feel
setupStyling(&app);
// Setup the settings management
QCoreApplication::setOrganizationName("pgadmin");
QCoreApplication::setOrganizationDomain("pgadmin.org");
QCoreApplication::setApplicationName("pgadmin4");
QSettings settings;
// Interlock
if (alreadyRunning())
exit(0);
// Proxy config
configureProxy();
// Display the spash screen
m_splash = displaySplash(&app);
// Generate a random key to authenticate the client to the server
QString key = QUuid::createUuid().toString();
key = key.mid(1, key.length() - 2);
// Create Menu Actions
MenuActions *menuActions = new MenuActions();
// Create the control object (tray icon or floating window
m_splash->showMessage(QString(QWidget::tr("Checking for system tray...")), Qt::AlignBottom | Qt::AlignCenter);
if (QSystemTrayIcon::isSystemTrayAvailable())
m_trayIcon = createTrayIcon(menuActions);
else
m_floatingWindow = createFloatingWindow(menuActions);
// Fire up the app server
const Server *server = startServerLoop(key);
// Ensure we'll cleanup
QObject::connect(server, SIGNAL(finished()), server, SLOT(deleteLater()));
atexit(cleanup);
// Generate the app server URL
QString url = QString("http://127.0.0.1:%1/?key=%2").arg(m_port).arg(key);
Logger::GetLogger()->Log(QString(QWidget::tr("Application Server URL: %1")).arg(url));
// Check the server is running
checkServer(url);
// Stash the URL for any duplicate processes to open
createAddressFile(url);
// Go!
menuActions->setAppServerUrl(url);
// Enable the shutdown server menu as server started successfully.
if (m_trayIcon != Q_NULLPTR)
m_trayIcon->enablePostStartOptions();
if (m_floatingWindow != Q_NULLPTR)
m_floatingWindow->enablePostStartOptions();
// Open the browser if needed
if (settings.value("OpenTabAtStartup", true).toBool())
openBrowserTab(url);
// Make sure the server is shutdown if the server is quit by the user
QObject::connect(menuActions, SIGNAL(shutdownSignal(QUrl)), server, SLOT(shutdown(QUrl)));
// Final cleanup
m_splash->finish(Q_NULLPTR);
if (m_floatingWindow != Q_NULLPTR)
m_floatingWindow->show();
Logger::GetLogger()->Log("Everything works fine, successfully started pgAdmin4.");
Logger::ReleaseLogger();
return app.exec();
}
// Setup the styling
void Runtime::setupStyling(QApplication *app) const
{
// Setup the styling
#ifndef Q_OS_LINUX
QFile stylesheet;
#ifdef Q_OS_WIN32
QSettings registry("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", QSettings::Registry64Format);
if (!registry.value("AppsUseLightTheme", true).toBool())
{
qDebug( "Windows Dark Mode..." );
stylesheet.setFileName(":/qdarkstyle/style.qss");
stylesheet.open(QFile::ReadOnly | QFile::Text);
QTextStream stream(&stylesheet);
app->setStyleSheet(stream.readAll());
}
#endif
#ifdef Q_OS_MAC
if (IsDarkMode())
{
qDebug( "macOS Dark Mode...");
stylesheet.setFileName(":/qdarkstyle/style.qss");
stylesheet.open(QFile::ReadOnly | QFile::Text);
QTextStream stream(&stylesheet);
app->setStyleSheet(stream.readAll());
}
#endif
#endif
// Set high DPI pixmap to display icons clear on Qt widget.
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
}
// Check if we're already running. If we are, open a new browser tab.
bool Runtime::alreadyRunning()
{
// Create a system-wide semaphore keyed by app name, exe hash and the username
// to ensure instances are unique to the user and path
QString userName = qgetenv("USER"); // *nix
if (userName.isEmpty())
userName = qgetenv("USERNAME"); // Windows
QString semaName = QString("pgadmin4-%1-%2-sema").arg(userName).arg(getExeHash());
QString shmemName = QString("pgadmin4-%1-%2-shmem").arg(userName).arg(getExeHash());
qDebug() << "Semaphore name:" << semaName;
qDebug() << "Shared memory segment name:" << shmemName;
QSystemSemaphore sema(semaName, 1);
sema.acquire();
#ifndef Q_OS_WIN32
// We may need to clean up stale shmem segments on *nix. Attaching and detaching
// should remove the segment if it is orphaned.
QSharedMemory stale_shmem(shmemName);
if (stale_shmem.attach())
stale_shmem.detach();
#endif
m_shmem = new QSharedMemory(shmemName);
bool is_running;
if (m_shmem->attach())
is_running = true;
else
{
m_shmem->create(1);
is_running = false;
}
sema.release();
if (is_running)
{
QFile addressFile(g_addressFile);
addressFile.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&addressFile);
QString url = in.readLine();
qDebug() << "Already running. Opening browser tab to: " << url << "and exiting.";
openBrowserTab(url);
return true;
}
return false;
}
void Runtime::configureProxy() const
{
// In windows and linux, it is required to set application level proxy
// because socket bind logic to find free port gives socket creation error
// when system proxy is configured. We are also setting
// "setUseSystemConfiguration"=true to use the system proxy which will
// override this application level proxy. As this bug is fixed in Qt 5.9 so
// need to set application proxy for Qt version < 5.9.
//
#if defined (Q_OS_WIN) && QT_VERSION <= 0x050800
// Give dummy URL required to find proxy server configured in windows.
QNetworkProxyQuery proxyQuery(QUrl("https://www.pgadmin.org"));
QNetworkProxy l_proxy;
QList<QNetworkProxy> listOfProxies = QNetworkProxyFactory::systemProxyForQuery(proxyQuery);
if (listOfProxies.size())
{
l_proxy = listOfProxies[0];
// If host name is not empty means proxy server is configured.
if (!l_proxy.hostName().isEmpty()) {
QNetworkProxy::setApplicationProxy(QNetworkProxy());
}
}
#endif
#if defined (Q_OS_LINUX) && QT_VERSION <= 0x050800
QByteArray proxy_env;
proxy_env = qgetenv("http_proxy");
// If http_proxy environment is defined in linux then proxy server is configured.
if (!proxy_env.isEmpty()) {
QNetworkProxy::setApplicationProxy(QNetworkProxy());
}
#endif
}
// Display the splash screen
QSplashScreen * Runtime::displaySplash(QApplication *app)
{
QSplashScreen *splash = new QSplashScreen();
splash->setPixmap(QPixmap(":/splash.png"));
splash->setWindowFlags(splash->windowFlags() | Qt::WindowStaysOnTopHint);
splash->show();
app->processEvents(QEventLoop::AllEvents);
return splash;
}
// Get the port number we're going to use
quint16 Runtime::getPort() const
{
quint16 port = 0L;
QSettings settings;
if (settings.value("FixedPort", false).toBool())
{
// Use the fixed port number
port = settings.value("PortNumber", 5050).toUInt();
}
else
{
// Find an unused port number. Essentially, we're just reserving one
// here that Flask will use when we start up the server.
QTcpSocket socket;
#if QT_VERSION >= 0x050900
socket.setProxy(QNetworkProxy::NoProxy);
#endif
socket.bind(0, QTcpSocket::ShareAddress);
port = socket.localPort();
}
return port;
}
// Create a tray icon
TrayIcon * Runtime::createTrayIcon(MenuActions *menuActions)
{
TrayIcon *trayIcon = Q_NULLPTR;
m_splash->showMessage(QString(QWidget::tr("Checking for system tray...")), Qt::AlignBottom | Qt::AlignCenter);
Logger::GetLogger()->Log("Checking for system tray...");
// Start the tray service
trayIcon = new TrayIcon();
// Set the MenuActions object to connect to slot
if (trayIcon != Q_NULLPTR)
trayIcon->setMenuActions(menuActions);
trayIcon->Init();
return trayIcon;
}
// Create a floating window
FloatingWindow * Runtime::createFloatingWindow(MenuActions *menuActions)
{
FloatingWindow *floatingWindow = Q_NULLPTR;
m_splash->showMessage(QString(QWidget::tr("System tray not found, creating floating window...")), Qt::AlignBottom | Qt::AlignCenter);
Logger::GetLogger()->Log("System tray not found, creating floating window...");
floatingWindow = new FloatingWindow();
if (floatingWindow == Q_NULLPTR)
{
QString error = QString(QWidget::tr("Unable to initialize either a tray icon or floating window."));
QMessageBox::critical(Q_NULLPTR, QString(QWidget::tr("Fatal Error")), error);
Logger::GetLogger()->Log(error);
Logger::ReleaseLogger();
exit(1);
}
// Set the MenuActions object to connect to slot
floatingWindow->setMenuActions(menuActions);
floatingWindow->Init();
return floatingWindow;
}
void Runtime::openConfigureWindow(const QString errorMsg)
{
m_splash->finish(Q_NULLPTR);
qDebug() << errorMsg;
QMessageBox::critical(Q_NULLPTR, QString(QWidget::tr("Fatal Error")), errorMsg);
Logger::GetLogger()->Log(errorMsg);
// Allow the user to tweak the configuration if needed
m_configDone = false;
QSettings settings;
bool oldFixedPort = settings.value("FixedPort", false).toBool();
ConfigWindow *dlg = new ConfigWindow();
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
dlg->raise();
dlg->activateWindow();
QObject::connect(dlg, SIGNAL(closing(bool)), this, SLOT(onConfigDone(bool)));
// Wait for configuration to be completed
while (!m_configDone)
delay(100);
// Read the value of port again if user has changed.
bool newFixedPort = settings.value("FixedPort", false).toBool();
quint16 newPort = settings.value("PortNumber").toUInt();
// User hasn't changed the value of fixed port check box
// only change the value of the port
if (oldFixedPort == newFixedPort && newFixedPort && m_port != newPort)
m_port = newPort;
// User has selected the fixed port and it's old value is random port,
// so port needs to be updated.
else if (oldFixedPort != newFixedPort && newFixedPort)
m_port = newPort;
// User has deselect the fixed port and it's old value is fixed port,
// so we will have to get the random port
else if (oldFixedPort != newFixedPort && !newFixedPort)
m_port = getPort();
}
// Server startup loop
Server * Runtime::startServerLoop(QString key)
{
bool done = false;
Server *server;
// Get the port number to use
m_port = getPort();
while (!done)
{
server = startServer(key);
if (server == NULL)
{
Logger::ReleaseLogger();
QApplication::quit();
}
// Check for server startup errors
if (server->isFinished() || server->getError().length() > 0)
{
QString error = QString(QWidget::tr("An error occurred initialising the pgAdmin 4 server:\n\n%1")).arg(server->getError());
delete server;
// Enable the View Log option for diagnostics
if (m_floatingWindow)
m_floatingWindow->enableViewLogOption();
if (m_trayIcon)
m_trayIcon->enableViewLogOption();
// Open the configuration window
openConfigureWindow(error);
// Disable the View Log option again
if (m_floatingWindow)
m_floatingWindow->disableViewLogOption();
if (m_trayIcon)
m_trayIcon->disableViewLogOption();
}
else
{
// Startup appears successful
done = true;
}
}
return server;
}
// Slot called when re-configuration is done.
void Runtime::onConfigDone(bool accepted)
{
if (accepted)
m_configDone = true;
else
exit(0);
}
// Start the server
Server * Runtime::startServer(QString key)
{
Server *server;
m_splash->showMessage(QString(QWidget::tr("Starting pgAdmin4 server...")), Qt::AlignBottom | Qt::AlignCenter);
Logger::GetLogger()->Log("Starting pgAdmin4 server...");
QString msg = QString(QWidget::tr("Creating server object, port:%1, key:%2, logfile:%3")).arg(m_port).arg(key).arg(g_serverLogFile);
Logger::GetLogger()->Log(msg);
server = new Server(this, m_port, key, g_serverLogFile);
Logger::GetLogger()->Log("Initializing server...");
if (!server->Init())
{
m_splash->finish(Q_NULLPTR);
qDebug() << server->getError();
QString error = QString(QWidget::tr("An error occurred initialising the pgAdmin 4 server:\n\n%1")).arg(server->getError());
QMessageBox::critical(Q_NULLPTR, QString(QWidget::tr("Fatal Error")), error);
Logger::GetLogger()->Log(error);
Logger::ReleaseLogger();
exit(1);
}
Logger::GetLogger()->Log("Server initialized, starting server thread...");
server->start();
// This is a hack to give the server a chance to start and potentially fail. As
// the Python interpreter is a synchronous call, we can't check for proper startup
// easily in a more robust way - we have to rely on a clean startup not returning.
// It should always fail pretty quickly, and take longer to start if it succeeds, so
// we don't really get a visible delay here.
delay(1000);
return server;
}
// Check the server is running properly
void Runtime::checkServer(QString url)
{
// Read the server connection timeout from the registry or set the default timeout.
QSettings settings;
int timeout = settings.value("ConnectionTimeout", 90).toInt();
// Now the server should be up, we'll attempt to connect and get a response.
// We'll retry in a loop a few time before aborting if necessary.
QTime endTime = QTime::currentTime().addSecs(timeout);
QTime midTime1 = QTime::currentTime().addSecs(timeout/3);
QTime midTime2 = QTime::currentTime().addSecs(timeout*2/3);
bool alive = false;
bool enableOptions = false;
Logger::GetLogger()->Log("The server should be up. Attempting to connect and get a response.");
while(QTime::currentTime() <= endTime)
{
alive = pingServer(QUrl(url));
if (alive)
{
break;
}
if(QTime::currentTime() >= midTime1)
{
if (m_floatingWindow && !enableOptions)
{
m_floatingWindow->enableViewLogOption();
m_floatingWindow->enableConfigOption();
enableOptions = true;
}
if (m_trayIcon && !enableOptions)
{
m_trayIcon->enableViewLogOption();
m_trayIcon->enableConfigOption();
enableOptions = true;
}
if(QTime::currentTime() < midTime2) {
m_splash->showMessage(QString(QWidget::tr("Taking longer than usual...")), Qt::AlignBottom | Qt::AlignCenter);
}
else
{
m_splash->showMessage(QString(QWidget::tr("Almost there...")), Qt::AlignBottom | Qt::AlignCenter);
}
}
delay(200);
}
// Attempt to connect one more time in case of a long network timeout while looping
Logger::GetLogger()->Log("Attempt to connect one more time in case of a long network timeout while looping");
if (!alive && !pingServer(QUrl(url)))
{
m_splash->finish(Q_NULLPTR);
QString error(QWidget::tr("The pgAdmin 4 server could not be contacted."));
QMessageBox::critical(Q_NULLPTR, QString(QWidget::tr("Fatal Error")), error);
Logger::ReleaseLogger();
exit(1);
}
}
// Create the address file
void Runtime::createAddressFile(QString url) const
{
QFile addressFile(g_addressFile);
if (addressFile.open(QIODevice::WriteOnly))
{
addressFile.setPermissions(QFile::ReadOwner|QFile::WriteOwner);
QTextStream out(&addressFile);
out << url << endl;
}
}
// Open a browser tab
void Runtime::openBrowserTab(QString url) const
{
QSettings settings;
QString cmd = settings.value("BrowserCommand").toString();
if (!cmd.isEmpty())
{
cmd.replace("%URL%", url);
QProcess::startDetached(cmd);
}
else
{
if (!QDesktopServices::openUrl(url))
{
QString error(QWidget::tr("Failed to open the system default web browser. Is one installed?."));
QMessageBox::critical(Q_NULLPTR, QString(QWidget::tr("Fatal Error")), error);
Logger::GetLogger()->Log(error);
Logger::ReleaseLogger();
exit(1);
}
}
}
// Make a request to the Python API server
QString Runtime::serverRequest(QUrl url, QString path)
{
QNetworkAccessManager manager;
QEventLoop loop;
QNetworkReply *reply;
QVariant redirectUrl;
url.setPath(path);
QString requestUrl = url.toString();
do
{
reply = manager.get(QNetworkRequest(url));
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
redirectUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
url = redirectUrl.toUrl();
if (!redirectUrl.isNull())
delete reply;
} while (!redirectUrl.isNull());
if (reply->error() != QNetworkReply::NoError)
{
qDebug() << "Failed to connect to the server:" << reply->errorString() << "- request URL:" << requestUrl << ".";
return QString();
}
QString response = reply->readAll();
qDebug() << "Server response:" << response << "- request URL:" << requestUrl << ".";
return response;
}
// Ping the application server to see if it's alive
bool Runtime::pingServer(QUrl url)
{
return serverRequest(url, "/misc/ping") == "PING";
}
// Shutdown the application server
bool Runtime::shutdownServer(QUrl url)
{
return serverRequest(url, "/misc/shutdown") == "SHUTDOWN";
}
void Runtime::delay(int milliseconds) const
{
QTime endTime = QTime::currentTime().addMSecs(milliseconds);
while(QTime::currentTime() < endTime)
{
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
}
+69
View File
@@ -0,0 +1,69 @@
//////////////////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2020, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
// Runtime.h - Core of the runtime
//
//////////////////////////////////////////////////////////////////////////
#ifndef RUNTIME_H
#define RUNTIME_H
// Include the Python header here as it needs to appear before any QT
// headers anywhere in the app.
#ifdef __MINGW32__
#include <cmath>
#endif
#include <Python.h>
#include "TrayIcon.h"
#include "MenuActions.h"
#include "FloatingWindow.h"
// QT headers
#include <QtWidgets>
class Server;
class Runtime: public QObject
{
Q_OBJECT
public:
Runtime();
bool alreadyRunning();
bool go(int argc, char *argv[]);
void delay(int milliseconds) const;
bool shutdownServer(QUrl url);
private:
QSharedMemory *m_shmem;
bool m_configDone;
FloatingWindow *m_floatingWindow = Q_NULLPTR;
TrayIcon *m_trayIcon = Q_NULLPTR;
QSplashScreen *m_splash = Q_NULLPTR;
quint16 m_port = 0;
void setupStyling(QApplication *app) const;
void configureProxy() const;
QSplashScreen *displaySplash(QApplication *app);
quint16 getPort() const;
TrayIcon *createTrayIcon(MenuActions *menuActions);
FloatingWindow *createFloatingWindow(MenuActions *menuActions);
Server *startServerLoop(QString key);
Server *startServer(QString key);
void checkServer(QString url);
void createAddressFile(QString url) const;
void openBrowserTab(QString url) const;
QString serverRequest(QUrl url, QString path);
bool pingServer(QUrl url);
void openConfigureWindow(const QString errorMsg);
private slots:
void onConfigDone(bool accepted);
};
#endif // RUNTIME_H
+25 -65
View File
@@ -10,19 +10,21 @@
//////////////////////////////////////////////////////////////////////////
#include "pgAdmin4.h"
#include "Logger.h"
// Must be before QT
#include <Python.h>
#include "Server.h"
#include "Logger.h"
// QT headers
#include <QCoreApplication>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QMessageBox>
#include <QSettings>
// App headers
#include "Server.h"
static void add_to_path(QString &python_path, QString path, bool prepend=false)
{
@@ -55,41 +57,32 @@ static void add_to_path(QString &python_path, QString path, bool prepend=false)
}
}
Server::Server(quint16 port, QString key, QString logFileName)
Server::Server(Runtime *runtime, quint16 port, QString key, QString logFileName):
m_runtime(runtime),
m_port(port),
m_key(key),
m_logFileName(logFileName)
{
// Appserver port etc
m_port = port;
m_key = key;
m_logFileName = logFileName;
m_wcAppName = Q_NULLPTR;
m_wcPythonHome = Q_NULLPTR;
// Initialise Python
Py_NoSiteFlag=1;
Py_NoUserSiteDirectory=1;
Py_DontWriteBytecodeFlag=1;
PGA_APP_NAME_UTF8 = PGA_APP_NAME.toUtf8();
// Python3 requires conversion of char * to wchar_t *, so...
#ifdef PYTHON2
Py_SetProgramName(PGA_APP_NAME_UTF8.data());
#else
char *appName = PGA_APP_NAME_UTF8.data();
const char *appName = QString("pgAdmin 4").toUtf8();
const size_t cSize = strlen(appName)+1;
m_wcAppName = new wchar_t[cSize];
mbstowcs (m_wcAppName, appName, cSize);
Py_SetProgramName(m_wcAppName);
#endif
// Setup the search path
QSettings settings;
QString python_path = settings.value("PythonPath").toString();
// Get the application directory
QString app_dir = qApp->applicationDirPath(),
path_env = qgetenv("PATH"),
pythonHome;
QString app_dir = QCoreApplication::applicationDirPath();
QString path_env = qgetenv("PATH");
QString pythonHome;
QStringList path_list;
int i;
@@ -182,17 +175,12 @@ Server::Server(quint16 port, QString key, QString logFileName)
if (!pythonHome.isEmpty())
{
pythonHome_utf8 = pythonHome.toUtf8();
#ifdef PYTHON2
Py_SetPythonHome(pythonHome_utf8.data());
#else
char *python_home = pythonHome_utf8.data();
const size_t cSize = strlen(python_home) + 1;
m_wcPythonHome = new wchar_t[cSize];
mbstowcs (m_wcPythonHome, python_home, cSize);
const char *python_home = pythonHome.toUtf8().data();
const size_t home_size = strlen(python_home) + 1;
m_wcPythonHome = new wchar_t[home_size];
mbstowcs (m_wcPythonHome, python_home, home_size);
Py_SetPythonHome(m_wcPythonHome);
#endif
}
Logger::GetLogger()->Log("Initializing Python...");
@@ -207,15 +195,7 @@ Server::Server(quint16 port, QString key, QString logFileName)
Logger::GetLogger()->Log("Adding new additional path elements");
for (i = path_list.size() - 1; i >= 0 ; --i)
{
#ifdef PYTHON2
PyList_Append(sysPath, PyString_FromString(path_list.at(i).toUtf8().data()));
#else
#if PY_MINOR_VERSION > 2
PyList_Append(sysPath, PyUnicode_DecodeFSDefault(path_list.at(i).toUtf8().data()));
#else
PyList_Append(sysPath, PyBytes_FromString(path_list.at(i).toUtf8().data()));
#endif
#endif
}
}
else
@@ -227,9 +207,6 @@ Server::Server(quint16 port, QString key, QString logFileName)
if (sys != Q_NULLPTR)
{
PyObject *err = Q_NULLPTR;
#ifdef PYTHON2
err = PyFile_FromString(m_logFileName.toUtf8().data(), (char *)"w");
#else
FILE *log = Q_NULLPTR;
#if defined(Q_OS_WIN)
@@ -256,7 +233,6 @@ Server::Server(quint16 port, QString key, QString logFileName)
delete wcLogFileName;
wcLogFileName = NULL;
}
#endif
#endif
QFile(m_logFileName).setPermissions(QFile::ReadOwner|QFile::WriteOwner);
if (err != Q_NULLPTR)
@@ -347,32 +323,14 @@ void Server::run()
// Run the app!
QByteArray m_appfile_utf8 = m_appfile.toUtf8();
#ifdef PYTHON2
/*
* Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
* versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
* which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
* Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
*/
char* n_argv[] = { m_appfile_utf8.data() };
PySys_SetArgv(1, n_argv);
Logger::GetLogger()->Log("PyRun_SimpleFile launching application server...");
PyObject* PyFileObject = PyFile_FromString(m_appfile_utf8.data(), (char *)"r");
int ret = PyRun_SimpleFile(PyFile_AsFile(PyFileObject), m_appfile_utf8.data());
if (ret != 0)
{
Logger::GetLogger()->Log("Failed to launch the application server, server thread exiting.");
setError(tr("Failed to launch the application server, server thread exiting."));
}
#else
/*
* Untrusted search path vulnerability in the PySys_SetArgv API function in Python 2.6 and earlier, and possibly later
* versions, prepends an empty string to sys.path when the argv[0] argument does not contain a path separator,
* which might allow local users to execute arbitrary code via a Trojan horse Python file in the current working directory.
* Here we have to set arguments explicitly to python interpreter. Check more details in 'PySys_SetArgv' documentation.
*/
char *appName = m_appfile_utf8.data();
const char *appName = m_appfile_utf8.data();
const size_t cSize = strlen(appName)+1;
wchar_t* wcAppName = new wchar_t[cSize];
mbstowcs (wcAppName, appName, cSize);
@@ -385,19 +343,21 @@ void Server::run()
Logger::GetLogger()->Log("Failed to launch the application server, server thread exiting.");
setError(tr("Failed to launch the application server, server thread exiting."));
}
#endif
fclose(cp);
}
void Server::shutdown(QUrl url)
{
bool shotdown = shutdownServer(url);
if (!shotdown)
if (!m_runtime->shutdownServer(url))
setError(tr("Failed to shut down application server thread."));
QThread::quit();
QThread::wait();
while(!this->isFinished()){}
while(!this->isFinished())
{
Logger::GetLogger()->Log("Waiting for server to shut down.");
m_runtime->delay(250);
}
}
Loaded 100 of 1701 files, more files were not shown because too many files have changed in this diff. Show more