mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2026-10-28 07:30:05 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc38bc132e | ||
|
|
053519aef6 | ||
|
|
1408bad8ba | ||
|
|
33cc2a7514 | ||
|
|
d6a754e850 | ||
|
|
fc05ef49ce | ||
|
|
b36a290b54 | ||
|
|
0ca7dbccf6 | ||
|
|
e67bad3461 | ||
|
|
e2e5a8208c | ||
|
|
a47cbbe26c | ||
|
|
59707fc8af | ||
|
|
25ace94d10 | ||
|
|
ca4d5d0ca4 | ||
|
|
600690a789 | ||
|
|
77931d2315 | ||
|
|
8bf178b0a3 | ||
|
|
d4bf7164f9 | ||
|
|
7468ca36ae | ||
|
|
572b5a126a | ||
|
|
36e5708464 | ||
|
|
d4697e8f1c | ||
|
|
9479f0e632 | ||
|
|
aff84103d9 | ||
|
|
a61a9e5b8f | ||
|
|
eb8168285e | ||
|
|
1ed4d0f95e | ||
|
|
31849ea95f | ||
|
|
d7f5e13cdd | ||
|
|
33aeacd8d1 | ||
|
|
f3bf068066 | ||
|
|
719f8c8fd2 | ||
|
|
fa8b3edda5 | ||
|
|
f71e2e8040 | ||
|
|
39992a817d | ||
|
|
7b85253465 | ||
|
|
35b1e1d0d2 | ||
|
|
711ea3bfa1 | ||
|
|
8eb6f8061d | ||
|
|
2c4ed4d115 | ||
|
|
fc233ed993 | ||
|
|
1d8810775c | ||
|
|
d28e249673 | ||
|
|
c7cd57db91 | ||
|
|
d2a7f7fffe |
No files matched your search
+170
-67
@@ -29,34 +29,34 @@ Flask-Login 0.5.0
|
||||
Flask-Mail 0.9.1 BSD https://github.com/rduplain/flask-mail
|
||||
Flask-Migrate 2.7.0 MIT http://github.com/miguelgrinberg/flask-migrate/
|
||||
Flask-SQLAlchemy 2.5.1 BSD-3-Clause https://github.com/pallets/flask-sqlalchemy
|
||||
Flask-WTF 0.14.3 BSD https://github.com/lepture/flask-wtf
|
||||
Flask-Compress 1.9.0 MIT https://github.com/colour-science/flask-compress
|
||||
Flask-WTF 0.15.1 BSD https://github.com/wtforms/flask-wtf
|
||||
Flask-Compress 1.10.1 MIT https://github.com/colour-science/flask-compress
|
||||
passlib 1.7.4 BSD https://passlib.readthedocs.io
|
||||
pytz 2021.1 MIT http://pythonhosted.org/pytz
|
||||
simplejson 3.17.2 MIT License https://github.com/simplejson/simplejson
|
||||
pytz 2021.3 MIT http://pythonhosted.org/pytz
|
||||
simplejson 3.17.5 MIT License https://github.com/simplejson/simplejson
|
||||
six 1.16.0 MIT https://github.com/benjaminp/six
|
||||
speaklater3 1.4 UNKNOWN https://github.com/ThomasWaldmann/speaklater
|
||||
sqlparse 0.4.1 BSD-3-Clause https://github.com/andialbrecht/sqlparse
|
||||
sqlparse 0.4.2 BSD-3-Clause https://github.com/andialbrecht/sqlparse
|
||||
WTForms 2.3.3 BSD-3-Clause https://wtforms.readthedocs.io/
|
||||
Flask-Paranoid 0.2.0 MIT http://github.com/miguelgrinberg/flask-paranoid/
|
||||
psutil 5.8.0 BSD https://github.com/giampaolo/psutil
|
||||
psycopg2 2.8.6 LGPL with exceptions https://psycopg.org/
|
||||
python-dateutil 2.8.1 Dual License https://dateutil.readthedocs.io
|
||||
python-dateutil 2.8.2 Dual License https://github.com/dateutil/dateutil
|
||||
SQLAlchemy 1.3.24 MIT http://www.sqlalchemy.org
|
||||
itsdangerous 1.1.0 BSD https://palletsprojects.com/p/itsdangerous/
|
||||
Flask-Security-Too 4.0.1 MIT https://github.com/Flask-Middleware/flask-security
|
||||
Flask-Security-Too 4.1.2 MIT https://github.com/Flask-Middleware/flask-security
|
||||
bcrypt 3.2.0 Apache License, Version 2.0 https://github.com/pyca/bcrypt/
|
||||
cryptography 3.4.7 BSD or Apache License, Version 2.0 https://github.com/pyca/cryptography
|
||||
cryptography 3.4.8 BSD or Apache License, Version 2.0 https://github.com/pyca/cryptography
|
||||
sshtunnel 0.4.0 MIT https://github.com/pahaz/sshtunnel
|
||||
ldap3 2.9 LGPL v3 https://github.com/cannatag/ldap3
|
||||
ldap3 2.9.1 LGPL v3 https://github.com/cannatag/ldap3
|
||||
Flask-BabelEx 0.9.4 BSD http://github.com/mrjoes/flask-babelex
|
||||
gssapi 1.6.12 LICENSE.txt https://github.com/pythongssapi/python-gssapi
|
||||
Flask-SocketIO 5.0.3 MIT http://github.com/miguelgrinberg/Flask-SocketIO/
|
||||
gssapi 1.6.14 LICENSE.txt https://github.com/pythongssapi/python-gssapi
|
||||
Flask-SocketIO 5.1.1 UNKNOWN https://github.com/miguelgrinberg/flask-socketio
|
||||
eventlet 0.31.0 UNKNOWN http://eventlet.net
|
||||
httpagentparser 1.9.1 http://www.opensource.org/licenses/mit-license.php http://shon.github.com/httpagentparser
|
||||
user-agents 2.2.0 MIT https://github.com/selwin/python-user-agents
|
||||
pywinpty 1.1.1 Unknown Unknown
|
||||
Authlib 0.15.4 BSD-3-Clause https://authlib.org/
|
||||
Authlib 0.15.5 BSD-3-Clause https://authlib.org/
|
||||
requests 2.25.1 Apache 2.0 https://requests.readthedocs.io
|
||||
|
||||
NOTE: This report was generated using Python 3.9. Full information may not be
|
||||
@@ -69,66 +69,106 @@ Javascript Dependencies
|
||||
|
||||
Name Version Licence URL
|
||||
---- ------- ------- ---
|
||||
@babel/code-frame 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/code-frame 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/compat-data 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/core 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/generator 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-annotate-as-pure 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-compilation-targets 7.13.16 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-create-class-features-plugin 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-function-name 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-get-function-arity 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-member-expression-to-functions 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/compat-data 7.14.7 MIT https://github.com/babel/babel.git
|
||||
@babel/core 7.13.8 MIT https://github.com/babel/babel.git
|
||||
@babel/generator 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-annotate-as-pure 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-compilation-targets 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-create-class-features-plugin 7.14.6 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-function-name 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-get-function-arity 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-hoist-variables 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-member-expression-to-functions 7.14.7 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-module-imports 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-module-transforms 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-optimise-call-expression 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-plugin-utils 7.13.0 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-replace-supers 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-module-transforms 7.13.0 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-optimise-call-expression 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-plugin-utils 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-replace-supers 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-simple-access 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-split-export-declaration 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-validator-identifier 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-validator-option 7.12.17 MIT https://github.com/babel/babel.git
|
||||
@babel/helpers 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/highlight 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/parser 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-split-export-declaration 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-validator-identifier 7.14.9 MIT https://github.com/babel/babel.git
|
||||
@babel/helper-validator-option 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/helpers 7.13.0 MIT https://github.com/babel/babel.git
|
||||
@babel/highlight 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/parser 7.14.7 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-proposal-class-properties 7.13.0 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-syntax-jsx 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-display-name 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-jsx 7.14.3 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-jsx 7.13.12 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-jsx-development 7.12.17 MIT https://github.com/babel/babel.git
|
||||
@babel/plugin-transform-react-pure-annotations 7.12.1 MIT https://github.com/babel/babel.git
|
||||
@babel/preset-react 7.13.13 MIT https://github.com/babel/babel.git
|
||||
@babel/template 7.12.13 MIT https://github.com/babel/babel.git
|
||||
@babel/traverse 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/types 7.14.2 MIT https://github.com/babel/babel.git
|
||||
@babel/runtime 7.14.0 MIT https://github.com/babel/babel.git
|
||||
@babel/template 7.14.5 MIT https://github.com/babel/babel.git
|
||||
@babel/traverse 7.14.7 MIT https://github.com/babel/babel.git
|
||||
@babel/types 7.15.4 MIT https://github.com/babel/babel.git
|
||||
@date-io/core 1.3.13 MIT https://github.com/dmtrKovalenko/date-io
|
||||
@date-io/date-fns 1.3.13 MIT https://github.com/dmtrKovalenko/date-io
|
||||
@emotion/cache 11.4.0 MIT https://github.com/emotion-js/emotion/tree/main/packages/cache
|
||||
@emotion/hash 0.8.0 MIT https://github.com/emotion-js/emotion/tree/master/packages/hash
|
||||
@emotion/is-prop-valid 0.8.8 MIT https://github.com/emotion-js/emotion/tree/master/packages/is-prop-valid
|
||||
@emotion/memoize 0.7.5 MIT https://github.com/emotion-js/emotion/tree/master/packages/memoize
|
||||
@emotion/memoize 0.7.4 MIT https://github.com/emotion-js/emotion/tree/master/packages/memoize
|
||||
@emotion/react 11.4.0 MIT https://github.com/emotion-js/emotion/tree/main/packages/react
|
||||
@emotion/serialize 1.0.2 MIT https://github.com/emotion-js/emotion/tree/main/packages/serialize
|
||||
@emotion/sheet 1.0.1 MIT https://github.com/emotion-js/emotion/tree/master/packages/sheet
|
||||
@emotion/stylis 0.8.5 MIT https://github.com/emotion-js/emotion/tree/master/packages/stylis
|
||||
@emotion/unitless 0.7.5 MIT https://github.com/emotion-js/emotion/tree/master/packages/unitless
|
||||
@emotion/utils 1.0.0 MIT https://github.com/emotion-js/emotion/tree/master/packages/utils
|
||||
@emotion/weak-memoize 0.2.5 MIT https://github.com/emotion-js/emotion/tree/master/packages/weak-memoize
|
||||
@istanbuljs/schema 0.1.3 MIT git+https://github.com/istanbuljs/schema.git
|
||||
@popperjs/core 2.9.2 MIT https://github.com/popperjs/popper-core.git
|
||||
@projectstorm/geometry 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-canvas-core 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams-core 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams-defaults 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams-routing 6.5.2 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@material-ui/core 4.11.0 MIT https://github.com/mui-org/material-ui.git
|
||||
@material-ui/icons 4.11.2 MIT https://github.com/mui-org/material-ui.git
|
||||
@material-ui/lab 4.0.0-alpha.58 MIT https://github.com/mui-org/material-ui.git
|
||||
@material-ui/pickers 3.2.10 MIT https://github.com/mui-org/material-ui-pickers
|
||||
@material-ui/styles 4.11.4 MIT https://github.com/mui-org/material-ui.git
|
||||
@material-ui/system 4.12.1 MIT https://github.com/mui-org/material-ui.git
|
||||
@material-ui/types 5.1.0 MIT https://github.com/mui-org/material-ui.git
|
||||
@material-ui/utils 4.11.2 MIT https://github.com/mui-org/material-ui.git
|
||||
@popperjs/core 2.9.0 MIT https://github.com/popperjs/popper-core.git
|
||||
@projectstorm/geometry 6.6.1 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-canvas-core 6.6.1 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams 6.6.1 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams-core 6.6.1 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams-defaults 6.6.1 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@projectstorm/react-diagrams-routing 6.6.1 MIT https://github.com/projectstorm/react-diagrams.git
|
||||
@simonwep/pickr 1.8.1 MIT https://github.com/Simonwep/pickr.git
|
||||
@tippyjs/react 4.2.5 MIT git+https://github.com/atomiks/tippyjs-react.git
|
||||
@sindresorhus/is 0.7.0 MIT https://github.com/sindresorhus/is.git
|
||||
@tippyjs/react 4.2.3 MIT git+https://github.com/atomiks/tippyjs-react.git
|
||||
@types/classnames 2.3.1 MIT Unknown
|
||||
@types/component-emitter 1.2.10 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/json-schema 7.0.7 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/node 15.6.1 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/node 14.14.32 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/parse-json 4.0.0 MIT https://www.github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/prop-types 15.7.3 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/react 16.14.10 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/react 16.14.18 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/react-dom 16.9.14 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/react-transition-group 4.4.1 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/scheduler 0.16.1 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
@types/styled-jsx 2.2.8 MIT https://github.com/DefinitelyTyped/DefinitelyTyped.git
|
||||
acitree 4.5.0-rc.7 MIT https://github.com/imsurinder90/jquery-aciTree.git
|
||||
ajv 6.12.6 MIT https://github.com/ajv-validator/ajv.git
|
||||
ajv 5.5.2 MIT https://github.com/epoberezkin/ajv.git
|
||||
ajv-errors 1.0.1 MIT git+https://github.com/epoberezkin/ajv-errors.git
|
||||
ajv-keywords 3.5.2 MIT git+https://github.com/epoberezkin/ajv-keywords.git
|
||||
alertifyjs 1.7.1 MIT git@github.com:MohammadYounes/AlertifyJS.git
|
||||
alphanum-sort 1.0.2 MIT https://github.com/TrySound/alphanum-sort.git
|
||||
ansi-regex 2.1.1 MIT https://github.com/chalk/ansi-regex.git
|
||||
ansi-styles 3.2.1 MIT https://github.com/chalk/ansi-styles.git
|
||||
ansi-styles 4.3.0 MIT https://github.com/chalk/ansi-styles.git
|
||||
ansi-styles 2.2.1 MIT https://github.com/chalk/ansi-styles.git
|
||||
axios 0.21.1 MIT https://github.com/axios/axios.git
|
||||
aspen-core 1.0.4 MIT git+https://github.com/neeksandhu/aspen-core.git
|
||||
aspen-decorations 1.1.1 MIT git+https://github.com/neeksandhu/aspen-decorations.git
|
||||
aspen-tree-model 1.0.5 MIT git+https://github.com/neeksandhu/aspen-tree-model.git
|
||||
async 2.6.3 MIT https://github.com/caolan/async.git
|
||||
axios 0.21.4 MIT https://github.com/axios/axios.git
|
||||
babel-code-frame 6.26.0 MIT https://github.com/babel/babel/tree/master/packages/babel-code-frame
|
||||
babel-generator 6.26.1 MIT https://github.com/babel/babel/tree/master/packages/babel-generator
|
||||
babel-messages 6.23.0 MIT https://github.com/babel/babel/tree/master/packages/babel-messages
|
||||
babel-plugin-styled-components 1.12.0 MIT https://github.com/styled-components/babel-plugin-styled-components.git
|
||||
babel-plugin-syntax-jsx 6.18.0 MIT https://github.com/babel/babel/tree/master/packages/babel-plugin-syntax-jsx
|
||||
babel-runtime 6.26.0 MIT https://github.com/babel/babel/tree/master/packages/babel-runtime
|
||||
babel-template 6.26.0 MIT https://github.com/babel/babel/tree/master/packages/babel-template
|
||||
babel-traverse 6.26.0 MIT https://github.com/babel/babel/tree/master/packages/babel-traverse
|
||||
@@ -152,20 +192,23 @@ bignumber.js 7.2.1
|
||||
bootstrap 4.6.0 MIT git+https://github.com/twbs/bootstrap.git
|
||||
bootstrap4-toggle 3.6.1 MIT https://github.com/gitbrent/bootstrap4-toggle.git
|
||||
brace-expansion 1.1.11 MIT git://github.com/juliangruber/brace-expansion.git
|
||||
browserfs 1.4.3 MIT https://github.com/jvilk/BrowserFS.git
|
||||
browserslist 4.16.6 MIT https://github.com/browserslist/browserslist.git
|
||||
callsites 3.1.0 MIT https://github.com/sindresorhus/callsites.git
|
||||
camelcase 6.2.0 MIT https://github.com/sindresorhus/camelcase.git
|
||||
camelize 1.0.0 MIT git://github.com/substack/camelize.git
|
||||
caniuse-api 3.0.0 MIT https://github.com/nyalab/caniuse-api.git
|
||||
chalk 2.4.2 MIT https://github.com/chalk/chalk.git
|
||||
chalk 4.1.1 MIT https://github.com/chalk/chalk.git
|
||||
chalk 1.1.3 MIT https://github.com/chalk/chalk.git
|
||||
chart.js 2.9.4 MIT https://github.com/chartjs/Chart.js.git
|
||||
chartjs-color 2.4.1 MIT https://github.com/chartjs/chartjs-color.git
|
||||
chartjs-color-string 0.6.0 MIT https://github.com/chartjs/chartjs-color-string.git
|
||||
classnames 2.3.1 MIT https://github.com/JedWatson/classnames.git
|
||||
closest 0.0.1 MIT https://github.com/ForbesLindesay/closest.git
|
||||
clsx 1.1.1 MIT https://github.com/lukeed/clsx.git
|
||||
co 4.6.0 MIT https://github.com/tj/co.git
|
||||
codemirror 5.61.1 MIT https://github.com/codemirror/CodeMirror.git
|
||||
codemirror 5.59.4 MIT https://github.com/codemirror/CodeMirror.git
|
||||
color-convert 1.9.3 MIT https://github.com/Qix-/color-convert.git
|
||||
color-convert 2.0.1 MIT https://github.com/Qix-/color-convert.git
|
||||
color-name 1.1.3 MIT git@github.com:dfcreative/color-name.git
|
||||
color-name 1.1.4 MIT git@github.com:colorjs/color-name.git
|
||||
colord 2.0.0 MIT https://github.com/omgovich/colord.git
|
||||
@@ -173,26 +216,35 @@ colorette 1.2.2
|
||||
commander 7.2.0 MIT https://github.com/tj/commander.js.git
|
||||
component-emitter 1.3.0 MIT https://github.com/component/emitter.git
|
||||
concat-map 0.0.1 MIT git://github.com/substack/node-concat-map.git
|
||||
convert-source-map 1.7.0 MIT git://github.com/thlorenz/convert-source-map.git
|
||||
core-js 3.13.0 MIT https://github.com/zloirock/core-js.git
|
||||
context-menu 2.0.0 MIT https://github.com/chipto/context-menu.git
|
||||
convert-source-map 1.8.0 MIT git://github.com/thlorenz/convert-source-map.git
|
||||
core-js 3.12.1 MIT https://github.com/zloirock/core-js.git
|
||||
core-js 2.6.12 MIT https://github.com/zloirock/core-js.git
|
||||
cosmiconfig 7.0.0 MIT git+https://github.com/davidtheclark/cosmiconfig.git
|
||||
css-color-names 1.0.1 MIT git://github.com/bahamas10/css-color-names.git
|
||||
css-color-names 0.0.4 MIT git://github.com/bahamas10/css-color-names.git
|
||||
css-line-break 1.1.1 MIT git+ssh://git@github.com/niklasvh/css-line-break.git
|
||||
css-loader 5.2.6 MIT https://github.com/webpack-contrib/css-loader.git
|
||||
css-loader 5.1.1 MIT https://github.com/webpack-contrib/css-loader.git
|
||||
css-to-react-native 3.0.0 MIT git+https://github.com/styled-components/css-to-react-native.git
|
||||
css-tree 1.1.3 MIT https://github.com/csstree/csstree.git
|
||||
css-vendor 2.0.8 MIT git@github.com:cssinjs/css-vendor.git
|
||||
cssesc 3.0.0 MIT https://github.com/mathiasbynens/cssesc.git
|
||||
cssnano 5.0.4 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano-preset-default 5.1.1 MIT https://github.com/cssnano/cssnano.git
|
||||
cssnano-utils 2.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
csso 4.2.0 MIT https://github.com/css/csso.git
|
||||
csstype 2.6.16 MIT https://github.com/frenic/csstype
|
||||
csstype 3.0.8 MIT https://github.com/frenic/csstype
|
||||
dagre 0.8.5 MIT https://github.com/dagrejs/dagre.git
|
||||
date-fns 2.24.0 MIT https://github.com/date-fns/date-fns
|
||||
debug 4.3.1 MIT git://github.com/visionmedia/debug.git
|
||||
debug 2.6.9 MIT git://github.com/visionmedia/debug.git
|
||||
deep-diff 1.0.2 MIT git://github.com/flitbit/diff.git
|
||||
detect-indent 4.0.0 MIT https://github.com/sindresorhus/detect-indent.git
|
||||
diff-arrays-of-objects 1.1.8 MIT git+https://github.com/malcolmvr/diff-arrays-of-objects.git
|
||||
dom-helpers 5.2.0 MIT git+https://github.com/react-bootstrap/dom-helpers.git
|
||||
dom-serializer 1.3.2 MIT git://github.com/cheeriojs/dom-renderer.git
|
||||
dropzone 5.9.2 MIT https://github.com/dropzone/dropzone.git
|
||||
dropzone 5.8.0 MIT https://github.com/dropzone/dropzone.git
|
||||
emojis-list 3.0.0 MIT git+https://github.com/kikobeats/emojis-list.git
|
||||
engine.io-client 5.1.1 MIT https://github.com/socketio/engine.io-client.git
|
||||
engine.io-parser 4.0.2 MIT git@github.com:socketio/engine.io-parser.git
|
||||
@@ -202,7 +254,8 @@ escape-string-regexp 1.0.5
|
||||
fast-deep-equal 3.1.3 MIT git+https://github.com/epoberezkin/fast-deep-equal.git
|
||||
fast-deep-equal 1.1.0 MIT git+https://github.com/epoberezkin/fast-deep-equal.git
|
||||
fast-json-stable-stringify 2.1.0 MIT git://github.com/epoberezkin/fast-json-stable-stringify.git
|
||||
follow-redirects 1.14.1 MIT git@github.com:follow-redirects/follow-redirects.git
|
||||
filename-reserved-regex 2.0.0 MIT https://github.com/sindresorhus/filename-reserved-regex.git
|
||||
follow-redirects 1.14.4 MIT git@github.com:follow-redirects/follow-redirects.git
|
||||
gensync 1.0.0-beta.2 MIT https://github.com/loganfsmyth/gensync.git
|
||||
globals 11.12.0 MIT https://github.com/sindresorhus/globals.git
|
||||
globals 9.18.0 MIT https://github.com/sindresorhus/globals.git
|
||||
@@ -219,6 +272,7 @@ html2canvas 1.0.0-rc.7
|
||||
immutability-helper 3.1.1 MIT git+https://github.com/kolodny/immutability-helper.git
|
||||
import-fresh 3.3.0 MIT https://github.com/sindresorhus/import-fresh.git
|
||||
imports-loader 2.0.0 MIT https://github.com/webpack-contrib/imports-loader.git
|
||||
insert-if 1.2.0 MIT git+https://github.com/chipto/insert-if.git
|
||||
invariant 2.2.4 MIT https://github.com/zertosh/invariant
|
||||
ip-address 7.1.0 MIT git://github.com/beaugunderson/ip-address.git
|
||||
is-absolute-url 3.0.3 MIT https://github.com/sindresorhus/is-absolute-url.git
|
||||
@@ -226,11 +280,14 @@ is-any-array 1.0.0
|
||||
is-arrayish 0.2.1 MIT https://github.com/qix-/node-is-arrayish.git
|
||||
is-color-stop 1.1.0 MIT git+https://github.com/pigcan/is-color-stop.git
|
||||
is-finite 1.1.0 MIT https://github.com/sindresorhus/is-finite.git
|
||||
is-in-browser 1.1.3 MIT git+https://github.com/tuxsudo/is-in-browser.git
|
||||
is-relative 1.0.0 MIT https://github.com/jonschlinkert/is-relative.git
|
||||
is-unc-path 1.0.0 MIT https://github.com/jonschlinkert/is-unc-path.git
|
||||
istanbul-instrumenter-loader 3.0.1 MIT https://github.com/webpack-contrib/istanbul-instrumenter-loader.git
|
||||
javascript-natural-sort 0.7.1 MIT https://github.com/Bill4Time/javascript-natural-sort.git
|
||||
jquery 3.6.0 MIT https://github.com/jquery/jquery.git
|
||||
jquery-contextmenu 2.9.2 MIT git://github.com/swisnl/jQuery-contextMenu.git
|
||||
jquery-ui 1.12.1 MIT git://github.com/jquery/jquery-ui.git
|
||||
jquery-ui 1.13.0 MIT git://github.com/jquery/jquery-ui.git
|
||||
js-tokens 4.0.0 MIT https://github.com/lydell/js-tokens.git
|
||||
js-tokens 3.0.2 MIT https://github.com/lydell/js-tokens.git
|
||||
jsbn 1.1.0 MIT https://github.com/andyperlitch/jsbn.git
|
||||
@@ -243,6 +300,14 @@ json-schema-traverse 0.3.1
|
||||
json-source-map 0.6.1 MIT git+https://github.com/epoberezkin/json-source-map.git
|
||||
json5 2.2.0 MIT git+https://github.com/json5/json5.git
|
||||
json5 1.0.1 MIT git+https://github.com/json5/json5.git
|
||||
jss 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-camel-case 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-default-unit 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-global 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-nested 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-props-sort 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-rule-value-function 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
jss-plugin-vendor-prefixer 10.5.1 MIT https://github.com/cssinjs/jss
|
||||
karma-coverage 2.0.3 MIT git://github.com/karma-runner/karma-coverage.git
|
||||
lines-and-columns 1.1.6 MIT https://github.com/eventualbuddha/lines-and-columns.git
|
||||
loader-utils 2.0.0 MIT https://github.com/webpack/loader-utils.git
|
||||
@@ -254,6 +319,8 @@ loose-envify 1.4.0
|
||||
lunr 0.7.2 MIT https://github.com/olivernn/lunr.js.git
|
||||
make-dir 3.1.0 MIT https://github.com/sindresorhus/make-dir.git
|
||||
matches-selector 0.0.1 MIT https://github.com/ForbesLindesay/matches-selector.git
|
||||
memoize-one 5.2.1 MIT https://github.com/alexreardon/memoize-one.git
|
||||
mime 2.5.2 MIT https://github.com/broofa/mime
|
||||
minimist 1.2.5 MIT git://github.com/substack/minimist.git
|
||||
ml-array-max 1.2.3 MIT git+https://github.com/mljs/array.git
|
||||
ml-array-min 1.2.2 MIT git+https://github.com/mljs/array.git
|
||||
@@ -265,21 +332,28 @@ moment 2.24.0
|
||||
moment-timezone 0.5.33 MIT https://github.com/moment/moment-timezone.git
|
||||
ms 2.1.2 MIT https://github.com/zeit/ms.git
|
||||
ms 2.0.0 MIT https://github.com/zeit/ms.git
|
||||
nanocolors 0.1.12 MIT https://github.com/ai/nanocolors.git
|
||||
nanoid 3.1.23 MIT https://github.com/ai/nanoid.git
|
||||
nanopop 2.1.0 MIT https://github.com/Simonwep/nanopop.git
|
||||
node-releases 1.1.72 MIT git+https://github.com/chicoxyzzy/node-releases.git
|
||||
normalize-url 4.5.1 MIT https://github.com/sindresorhus/normalize-url.git
|
||||
notificar 1.0.1 MIT git+https://github.com/neeksandhu/notificar.git
|
||||
object-assign 4.1.1 MIT https://github.com/sindresorhus/object-assign.git
|
||||
p-reduce 1.0.0 MIT https://github.com/sindresorhus/p-reduce.git
|
||||
p-series 1.1.0 MIT https://github.com/sindresorhus/p-series.git
|
||||
parent-module 1.0.1 MIT https://github.com/sindresorhus/parent-module.git
|
||||
parse-json 5.2.0 MIT https://github.com/sindresorhus/parse-json.git
|
||||
parseqs 0.0.6 MIT https://github.com/get/querystring.git
|
||||
parseuri 0.0.6 MIT https://github.com/get/parseuri.git
|
||||
path-fx 2.1.1 MIT git+https://github.com/NeekSandhu/path-fx.git
|
||||
path-type 4.0.0 MIT https://github.com/sindresorhus/path-type.git
|
||||
pathfinding 0.4.18 MIT git://github.com/qiao/PathFinding.js.git
|
||||
performance-now 2.1.0 MIT git://github.com/braveg1rl/performance-now.git
|
||||
pgadmin4-tree 1.0.0 MIT Unknown
|
||||
picomodal 3.0.0 MIT https://github.com/Nycto/PicoModal.git
|
||||
popper.js 1.16.1-lts MIT git+https://github.com/FezVrasta/popper.js.git
|
||||
popper.js 1.16.1 MIT git+https://github.com/FezVrasta/popper.js.git
|
||||
postcss 8.3.0 MIT https://github.com/postcss/postcss.git
|
||||
postcss 8.2.15 MIT https://github.com/postcss/postcss.git
|
||||
postcss-calc 8.0.0 MIT https://github.com/postcss/postcss-calc.git
|
||||
postcss-colormin 5.1.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-convert-values 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
@@ -310,20 +384,36 @@ postcss-selector-parser 6.0.6
|
||||
postcss-svgo 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-unique-selectors 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
postcss-value-parser 4.1.0 MIT https://github.com/TrySound/postcss-value-parser.git
|
||||
prop-types 15.7.2 MIT https://github.com/facebook/prop-types.git
|
||||
punycode 2.1.1 MIT https://github.com/bestiejs/punycode.js.git
|
||||
raf 3.4.1 MIT git://github.com/chrisdickinson/raf.git
|
||||
react 16.14.0 MIT git+https://github.com/facebook/react.git
|
||||
react 17.0.2 MIT https://github.com/facebook/react.git
|
||||
react-aspen 1.1.1 MIT https://github.com/neeksandhu/react-aspen.git
|
||||
react-dom 16.14.0 MIT git+https://github.com/facebook/react.git
|
||||
react-dom 17.0.2 MIT https://github.com/facebook/react.git
|
||||
react-input-autosize 3.0.0 MIT https://github.com/JedWatson/react-input-autosize.git
|
||||
react-is 16.13.1 MIT https://github.com/facebook/react.git
|
||||
react-is 17.0.2 MIT https://github.com/facebook/react.git
|
||||
react-select 4.3.1 MIT https://github.com/JedWatson/react-select/tree/master/packages/react-select
|
||||
react-table 7.7.0 MIT https://github.com/tannerlinsley/react-table
|
||||
react-virtualized-auto-sizer 1.0.6 MIT https://github.com/bvaughn/react-virtualized-auto-sizer.git
|
||||
react-window 1.8.6 MIT https://github.com/bvaughn/react-window.git
|
||||
regenerator-runtime 0.13.7 MIT https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime
|
||||
regenerator-runtime 0.11.1 MIT https://github.com/facebook/regenerator/tree/master/packages/regenerator-runtime
|
||||
repeating 2.0.1 MIT https://github.com/sindresorhus/repeating.git
|
||||
resolve-from 4.0.0 MIT https://github.com/sindresorhus/resolve-from.git
|
||||
rgb-regex 1.0.1 MIT https://github.com/regexps/rgb-regex.git
|
||||
rgba-regex 1.0.0 MIT https://github.com/johnotander/rgba-regex.git
|
||||
rifm 0.7.0 MIT https://github.com/istarkov/rifm.git
|
||||
safe-buffer 5.1.2 MIT git://github.com/feross/safe-buffer.git
|
||||
scheduler 0.19.1 MIT https://github.com/facebook/react.git
|
||||
scheduler 0.20.2 MIT https://github.com/facebook/react.git
|
||||
schema-utils 3.0.0 MIT https://github.com/webpack/schema-utils.git
|
||||
schema-utils 0.3.0 MIT git+https://github.com/webpack-contrib/schema-utils.git
|
||||
schema-utils 1.0.0 MIT https://github.com/webpack-contrib/schema-utils
|
||||
select2 4.0.13 MIT git://github.com/select2/select2.git
|
||||
shallowequal 1.1.0 MIT https://github.com/dashed/shallowequal.git
|
||||
shim-loader 1.0.1 MIT https://github.com/zinserjan/shim-loader
|
||||
slickgrid 2.3.16 MIT git+https://github.com/6pac/SlickGrid.git
|
||||
snapsvg-cjs 0.0.6 MIT git+https://github.com/geelen/Snap.svg-cjs.git
|
||||
@@ -334,21 +424,29 @@ split.js 1.6.4
|
||||
stable 0.1.8 MIT https://github.com/Two-Screen/stable.git
|
||||
strip-ansi 3.0.1 MIT https://github.com/chalk/strip-ansi.git
|
||||
strip-comments 2.0.1 MIT https://github.com/jonschlinkert/strip-comments.git
|
||||
styled-components 5.2.1 MIT git+https://github.com/styled-components/styled-components.git
|
||||
stylehacks 5.0.1 MIT https://github.com/cssnano/cssnano.git
|
||||
stylis 4.0.10 MIT https://github.com/thysultan/stylis.js
|
||||
supports-color 5.5.0 MIT https://github.com/chalk/supports-color.git
|
||||
supports-color 7.2.0 MIT https://github.com/chalk/supports-color.git
|
||||
supports-color 2.0.0 MIT https://github.com/chalk/supports-color.git
|
||||
svgo 2.3.0 MIT git://github.com/svg/svgo.git
|
||||
supports-color 7.2.0 MIT https://github.com/chalk/supports-color.git
|
||||
svgo 2.7.0 MIT git://github.com/svg/svgo.git
|
||||
symbol-observable 1.2.0 MIT https://github.com/blesh/symbol-observable.git
|
||||
tempusdominus-bootstrap-4 5.39.0 MIT https://github.com/tempusdominus/bootstrap-4.git
|
||||
tempusdominus-core 5.19.0 MIT https://github.com/tempusdominus/core.git
|
||||
timsort 0.3.0 MIT https://github.com/mziccard/node-timsort.git
|
||||
tiny-emitter 2.1.0 MIT https://github.com/scottcorgan/tiny-emitter.git
|
||||
tiny-warning 1.0.3 MIT https://github.com/alexreardon/tiny-warning.git
|
||||
tippy.js 6.3.1 MIT git+https://github.com/atomiks/tippyjs.git
|
||||
to-fast-properties 2.0.0 MIT https://github.com/sindresorhus/to-fast-properties.git
|
||||
to-fast-properties 1.0.3 MIT https://github.com/sindresorhus/to-fast-properties.git
|
||||
trim-right 1.0.1 MIT https://github.com/sindresorhus/trim-right.git
|
||||
unc-path-regex 0.1.2 MIT https://github.com/regexhq/unc-path-regex.git
|
||||
underscore 1.13.1 MIT git://github.com/jashkenas/underscore.git
|
||||
uniqs 2.0.0 MIT git://github.com/fgnass/uniqs.git
|
||||
url-loader 1.1.2 MIT https://github.com/webpack-contrib/url-loader.git
|
||||
util-deprecate 1.0.2 MIT git://github.com/TooTallNate/util-deprecate.git
|
||||
valid-filename 2.0.1 MIT https://github.com/sindresorhus/valid-filename.git
|
||||
vendors 1.0.4 MIT https://github.com/wooorm/vendors.git
|
||||
webpack-sources 0.2.3 MIT git+https://github.com/webpack/webpack-sources.git
|
||||
wkx 0.5.0 MIT http://github.com/cschwarz/wkx.git
|
||||
@@ -358,10 +456,11 @@ xterm-addon-fit 0.5.0
|
||||
xterm-addon-search 0.8.0 MIT https://github.com/xtermjs/xterm.js
|
||||
xterm-addon-web-links 0.4.0 MIT https://github.com/xtermjs/xterm.js
|
||||
yeast 0.1.2 MIT https://github.com/unshiftio/yeast.git
|
||||
@fortawesome/fontawesome-free 5.15.3 (CC-BY-4.0 AND OFL-1.1 AND MIT) https://github.com/FortAwesome/Font-Awesome
|
||||
@fortawesome/fontawesome-free 5.15.4 (CC-BY-4.0 AND OFL-1.1 AND MIT) https://github.com/FortAwesome/Font-Awesome
|
||||
@sphinxxxx/color-conversion 2.2.2 ISC git+https://github.com/Sphinxxxx/color-conversion.git
|
||||
@trysound/sax 0.1.1 ISC git://github.com/svg/sax.git
|
||||
@trysound/sax 0.2.0 ISC git://github.com/svg/sax.git
|
||||
boolbase 1.0.0 ISC https://github.com/fb55/boolbase
|
||||
css-color-keywords 1.0.0 ISC https://github.com/sonicdoe/css-color-keywords.git
|
||||
css-declaration-sorter 6.0.3 ISC https://github.com/Siilwyn/css-declaration-sorter.git
|
||||
electron-to-chromium 1.3.740 ISC https://github.com/kilian/electron-to-chromium/
|
||||
icss-utils 5.1.0 ISC git+https://github.com/css-modules/icss-utils.git
|
||||
@@ -372,13 +471,15 @@ minimatch 3.0.4
|
||||
postcss-modules-extract-imports 3.0.0 ISC https://github.com/css-modules/postcss-modules-extract-imports.git
|
||||
postcss-modules-scope 3.0.0 ISC https://github.com/css-modules/postcss-modules-scope.git
|
||||
postcss-modules-values 4.0.0 ISC git+https://github.com/css-modules/postcss-modules-values.git
|
||||
semver 7.3.5 ISC https://github.com/npm/node-semver
|
||||
semver 7.3.4 ISC https://github.com/npm/node-semver
|
||||
semver 5.7.1 ISC https://github.com/npm/node-semver
|
||||
semver 6.3.0 ISC https://github.com/npm/node-semver
|
||||
vanilla-picker 2.11.2 ISC https://github.com/Sphinxxxx/vanilla-picker.git
|
||||
yallist 4.0.0 ISC git+https://github.com/isaacs/yallist.git
|
||||
yaml 1.10.2 ISC https://github.com/eemeli/yaml.git
|
||||
ace-builds 1.4.12 BSD-3-Clause https://github.com/ajaxorg/ace-builds.git
|
||||
hoist-non-react-statics 3.3.2 BSD-3-Clause git://github.com/mridgway/hoist-non-react-statics.git
|
||||
hyphenate-style-name 1.0.4 BSD-3-Clause git+ssh://git@github.com/rexxars/hyphenate-style-name.git
|
||||
istanbul-lib-coverage 1.2.1 BSD-3-Clause git@github.com:istanbuljs/istanbuljs.git
|
||||
istanbul-lib-coverage 3.0.0 BSD-3-Clause git+ssh://git@github.com/istanbuljs/istanbuljs.git
|
||||
istanbul-lib-instrument 1.10.2 BSD-3-Clause git@github.com:istanbuljs/istanbuljs.git
|
||||
@@ -386,34 +487,36 @@ istanbul-lib-instrument 4.0.3
|
||||
istanbul-lib-report 3.0.0 BSD-3-Clause git+ssh://git@github.com/istanbuljs/istanbuljs.git
|
||||
istanbul-lib-source-maps 4.0.0 BSD-3-Clause git+ssh://git@github.com/istanbuljs/istanbuljs.git
|
||||
istanbul-reports 3.0.2 BSD-3-Clause git+ssh://git@github.com/istanbuljs/istanbuljs.git
|
||||
react-transition-group 4.4.1 BSD-3-Clause https://github.com/reactjs/react-transition-group.git
|
||||
source-map 0.5.7 BSD-3-Clause http://github.com/mozilla/source-map.git
|
||||
source-map 0.6.1 BSD-3-Clause http://github.com/mozilla/source-map.git
|
||||
source-map-js 0.6.2 BSD-3-Clause http://github.com/7rulnik/source-map.git
|
||||
sprintf-js 1.1.2 BSD-3-Clause https://github.com/alexei/sprintf.js.git
|
||||
bootstrap-datepicker 1.9.0 Apache-2.0 https://github.com/uxsolutions/bootstrap-datepicker.git
|
||||
eve 0.5.4 Apache-2.0 git@github.com:adobe-webplatform/eve.git
|
||||
indefinite-observable 2.0.1 Apache-2.0 git@github.com:material-motion/indefinite-observable-js.git
|
||||
jmespath 0.15.0 Apache-2.0 git://github.com/jmespath/jmespath.js
|
||||
jsoneditor 9.5.3 Apache-2.0 https://github.com/josdejong/jsoneditor.git
|
||||
jsoneditor 9.5.6 Apache-2.0 https://github.com/josdejong/jsoneditor.git
|
||||
paths-js 0.4.11 Apache-2.0 https://github.com/andreaferretti/paths-js.git
|
||||
snapsvg 0.5.1 Apache-2.0 git@github.com:adobe-webplatform/Snap.svg.git
|
||||
caniuse-lite 1.0.30001230 CC-BY-4.0 https://github.com/browserslist/caniuse-lite.git
|
||||
css-select 3.1.2 BSD-2-Clause git://github.com/fb55/css-select.git
|
||||
css-what 4.0.0 BSD-2-Clause https://github.com/fb55/css-what
|
||||
css-select 4.1.3 BSD-2-Clause git://github.com/fb55/css-select.git
|
||||
css-what 5.1.0 BSD-2-Clause https://github.com/fb55/css-what
|
||||
domelementtype 2.2.0 BSD-2-Clause git://github.com/fb55/domelementtype.git
|
||||
domhandler 4.2.0 BSD-2-Clause git://github.com/fb55/domhandler.git
|
||||
domutils 2.6.0 BSD-2-Clause git://github.com/fb55/domutils.git
|
||||
entities 2.2.0 BSD-2-Clause git://github.com/fb55/entities.git
|
||||
esutils 2.0.3 BSD-2-Clause http://github.com/estools/esutils.git
|
||||
leaflet 1.7.1 BSD-2-Clause git://github.com/Leaflet/Leaflet.git
|
||||
nth-check 2.0.0 BSD-2-Clause https://github.com/fb55/nth-check
|
||||
nth-check 2.0.1 BSD-2-Clause https://github.com/fb55/nth-check
|
||||
uri-js 4.4.1 BSD-2-Clause http://github.com/garycourt/uri-js
|
||||
FileSaver 0.10.0 UNKNOWN Unknown
|
||||
heap 0.2.5 UNKNOWN git://github.com/qiao/heap.js.git
|
||||
mdn-data 2.0.14 CC0-1.0 https://github.com/mdn/data.git
|
||||
mousetrap 1.6.5 Apache-2.0 WITH LLVM-exception git://github.com/ccampbell/mousetrap.git
|
||||
pako 1.0.11 (MIT AND Zlib) https://github.com/nodeca/pako.git
|
||||
precond 0.2.3 MIT* https://github.com/MathieuTurcotte/node-precond.git
|
||||
webcabin-docker 2.2.5 MIT* Unknown
|
||||
tablesorter 2.31.3 (MIT OR GPL-2.0) git://github.com/Mottie/tablesorter.git
|
||||
|
||||
345 dependencies listed.
|
||||
448 dependencies listed.
|
||||
|
||||
@@ -11,6 +11,7 @@ notes for it.
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
release_notes_6_2
|
||||
release_notes_6_1
|
||||
release_notes_6_0
|
||||
release_notes_5_7
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
************
|
||||
Version 6.2
|
||||
************
|
||||
|
||||
Release date: 2021-11-18
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin4 6.1.
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #3834 <https://redmine.postgresql.org/issues/3834>`_ - Added support of Aggregate and Operator node in view-only mode.
|
||||
| `Issue #6953 <https://redmine.postgresql.org/issues/6953>`_ - Ensure that users should be able to modify the REMOTE_USER environment variable as per their environment by introducing the new config parameter WEBSERVER_REMOTE_USER.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #5427 <https://redmine.postgresql.org/issues/5427>`_ - Fixed pgAdmin freezing issue by providing the error message for the operation that can't perform due to lock on the particular table.
|
||||
| `Issue #6780 <https://redmine.postgresql.org/issues/6780>`_ - Ensure that columns should be merged if the newly added column is present in the parent table.
|
||||
| `Issue #6809 <https://redmine.postgresql.org/issues/6809>`_ - Fixed an issue where pgAdmin is not opening properly.
|
||||
| `Issue #6832 <https://redmine.postgresql.org/issues/6832>`_ - Ensure that internal authentication when combined with other authentication providers, the order of internal source should not matter while picking up the provider.
|
||||
| `Issue #6845 <https://redmine.postgresql.org/issues/6845>`_ - Ensure that inherit table icon should be visible properly in the tree view.
|
||||
| `Issue #6859 <https://redmine.postgresql.org/issues/6859>`_ - Fixed an issue where properties panel is not updated when any object is added from the browser tree.
|
||||
| `Issue #6896 <https://redmine.postgresql.org/issues/6896>`_ - Ensure that the user should be able to navigate browser tree objects using arrow keys from keyboard.
|
||||
| `Issue #6905 <https://redmine.postgresql.org/issues/6905>`_ - Fixed an issue where database nodes are not getting loaded behind a reverse proxy with SSL.
|
||||
| `Issue #6925 <https://redmine.postgresql.org/issues/6925>`_ - Fixed SQL syntax error if select "Custom auto-vacuum" option and not set Autovacuum option to Yes or No.
|
||||
| `Issue #6939 <https://redmine.postgresql.org/issues/6939>`_ - Fixed an issue where older server group name displayed in the confirmation pop-up when the user removes server group.
|
||||
| `Issue #6944 <https://redmine.postgresql.org/issues/6944>`_ - Fixed an issue where JSON editor preview colours have inappropriate contrast in dark mode.
|
||||
| `Issue #6945 <https://redmine.postgresql.org/issues/6945>`_ - Fixed JSON Editor scrolling issue in code mode.
|
||||
| `Issue #6940 <https://redmine.postgresql.org/issues/6940>`_ - Fixed an issue where user details are not shown when the non-admin user tries to connect to the shared server.
|
||||
| `Issue #6949 <https://redmine.postgresql.org/issues/6949>`_ - Ensure that dialog should be opened when clicking on Reassign/Drop owned menu.
|
||||
| `Issue #6954 <https://redmine.postgresql.org/issues/6954>`_ - Ensure that changing themes should work on Windows when system high contrast mode is enabled.
|
||||
| `Issue #6972 <https://redmine.postgresql.org/issues/6972>`_ - Ensure that the Binary path for PG14 should be visible in the preferences.
|
||||
| `Issue #6974 <https://redmine.postgresql.org/issues/6974>`_ - Added operators and aggregates in search objects.
|
||||
| `Issue #6976 <https://redmine.postgresql.org/issues/6976>`_ - Fixed an issue where textarea should be allowed to resize and have more than 255 chars.
|
||||
| `Issue #6981 <https://redmine.postgresql.org/issues/6981>`_ - Fixed an issue where SQL for index shows the same column multiple times.
|
||||
| `Issue #6988 <https://redmine.postgresql.org/issues/6988>`_ - Reset the layout if pgAdmin4 detects the layout is in an inconsistent state.
|
||||
@@ -32,6 +32,9 @@ and modify the values for the following parameters:
|
||||
"WEBSERVER_AUTO_CREATE_USER", "Set the value to *True* if you want to automatically
|
||||
create a pgAdmin user corresponding to a successfully authenticated Webserver user.
|
||||
Please note that password is not stored in the pgAdmin database."
|
||||
"WEBSERVER_REMOTE_USER", "The default value is REMOTE_USER, set this variable to any header
|
||||
or environemnt variable to get the webserver remote user details. Possible values: REMOTE_USER,
|
||||
HTTP_X_FORWARDED_USER, X-Forwarded-User."
|
||||
|
||||
|
||||
Master Password
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
font-size: 14px;
|
||||
background-color: #ebeef3;
|
||||
}
|
||||
@media screen and (forced-colors: active) {
|
||||
body {
|
||||
forced-color-adjust: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -27,6 +27,11 @@
|
||||
margin-right: auto;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
@media screen and (forced-colors: active) {
|
||||
body {
|
||||
forced-color-adjust: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- Disable/block all password saving in nw.js -->
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
font-size: 14px;
|
||||
background-color: #ebeef3;
|
||||
}
|
||||
@media screen and (forced-colors: active) {
|
||||
body {
|
||||
forced-color-adjust: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
font-size: 14px;
|
||||
background-color: #ebeef3;
|
||||
}
|
||||
@media screen and (forced-colors: active) {
|
||||
body {
|
||||
forced-color-adjust: none !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
+9
-2
@@ -43,7 +43,7 @@ APP_ICON = 'pg-icon'
|
||||
|
||||
# Application version number components
|
||||
APP_RELEASE = 6
|
||||
APP_REVISION = 1
|
||||
APP_REVISION = 2
|
||||
|
||||
# Application version suffix, e.g. 'beta1', 'dev'. Usually an empty string
|
||||
# for GA releases.
|
||||
@@ -52,7 +52,7 @@ APP_SUFFIX = ''
|
||||
# Numeric application version for upgrade checks. Should be in the format:
|
||||
# [X]XYYZZ, where X is the release version, Y is the revision, with a leading
|
||||
# zero if needed, and Z represents the suffix, with a leading zero if needed
|
||||
APP_VERSION_INT = 60100
|
||||
APP_VERSION_INT = 60200
|
||||
|
||||
# DO NOT CHANGE!
|
||||
# The application version string, constructed from the components
|
||||
@@ -736,6 +736,13 @@ OAUTH2_AUTO_CREATE_USER = True
|
||||
|
||||
WEBSERVER_AUTO_CREATE_USER = True
|
||||
|
||||
# REMOTE_USER variable will be used to check the environment variable
|
||||
# is set or not first, if not available,
|
||||
# request header will be checked for the same.
|
||||
# Possible values: REMOTE_USER, HTTP_X_FORWARDED_USER, X-Forwarded-User
|
||||
|
||||
WEBSERVER_REMOTE_USER = 'REMOTE_USER'
|
||||
|
||||
##########################################################################
|
||||
# PSQL tool settings
|
||||
##########################################################################
|
||||
|
||||
+5
-5
@@ -66,7 +66,7 @@
|
||||
"svgo-loader": "^2.2.0",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"typescript": "^3.2.2",
|
||||
"webfonts-loader": "^7.1.1",
|
||||
"webfonts-loader": "^7.3.0",
|
||||
"webpack": "^5.21.2",
|
||||
"webpack-bundle-analyzer": "^4.4.0",
|
||||
"webpack-cli": "^4.5.0",
|
||||
@@ -122,7 +122,7 @@
|
||||
"istanbul-instrumenter-loader": "^3.0.1",
|
||||
"jquery": "^3.6.0",
|
||||
"jquery-contextmenu": "^2.9.2",
|
||||
"jquery-ui": "^1.12.1",
|
||||
"jquery-ui": "^1.13.0",
|
||||
"json-bignumber": "^1.0.1",
|
||||
"jsoneditor": "^9.5.4",
|
||||
"karma-coverage": "^2.0.3",
|
||||
@@ -136,7 +136,7 @@
|
||||
"path-fx": "^2.0.0",
|
||||
"pathfinding": "^0.4.18",
|
||||
"paths-js": "^0.4.9",
|
||||
"pgadmin4-tree": "git+https://github.com/EnterpriseDB/pgadmin4-treeview/#ab0af8e27c7bf24a750c998461c5a7aec2d4624f",
|
||||
"pgadmin4-tree": "git+https://github.com/EnterpriseDB/pgadmin4-treeview/#90e62d4371d3d25a957b3ffc7c6cb81a928da06f",
|
||||
"postcss": "^8.2.15",
|
||||
"raf": "^3.4.1",
|
||||
"react": "^17.0.1",
|
||||
@@ -181,8 +181,8 @@
|
||||
"test": "yarn run test:karma-once && yarn run bundle && python regression/runtests.py",
|
||||
"pep8": "pycodestyle --config=../.pycodestyle ../docs && pycodestyle --config=../.pycodestyle ../pkg && pycodestyle --config=../.pycodestyle ../tools && pycodestyle --config=../.pycodestyle ../web",
|
||||
"auditjs-html": "yarn audit --json | yarn run yarn-audit-html --output ../auditjs.html",
|
||||
"auditjs": "yarn audit",
|
||||
"auditpy": "safety check --full-report",
|
||||
"auditjs": "yarn audit --groups dependencies",
|
||||
"auditpy": "safety check --full-report -i 40493",
|
||||
"audit": "yarn run auditjs && yarn run auditpy"
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -104,7 +104,13 @@ if config.SERVER_MODE:
|
||||
|
||||
# Authentication sources
|
||||
if len(config.AUTHENTICATION_SOURCES) > 0:
|
||||
app.PGADMIN_EXTERNAL_AUTH_SOURCE = config.AUTHENTICATION_SOURCES[0]
|
||||
# Creating a temporary auth source list removing INTERNAL
|
||||
# This change is done to avoid selecting INTERNAL authentication when user
|
||||
# mistakenly keeps that the first option.
|
||||
auth_source = [x for x in config.AUTHENTICATION_SOURCES
|
||||
if x != INTERNAL]
|
||||
app.PGADMIN_EXTERNAL_AUTH_SOURCE = auth_source[0] \
|
||||
if len(auth_source) > 0 else INTERNAL
|
||||
else:
|
||||
app.PGADMIN_EXTERNAL_AUTH_SOURCE = INTERNAL
|
||||
|
||||
|
||||
@@ -77,7 +77,11 @@ class WebserverAuthentication(BaseAuthentication):
|
||||
return True
|
||||
|
||||
def get_user(self):
|
||||
return request.environ.get('REMOTE_USER')
|
||||
username = request.environ.get(config.WEBSERVER_REMOTE_USER)
|
||||
if not username:
|
||||
# One more try to get the Remote User from the hearders
|
||||
username = request.headers.get(config.WEBSERVER_REMOTE_USER)
|
||||
return username
|
||||
|
||||
def authenticate(self, form):
|
||||
username = self.get_user()
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
""" Implements Aggregate Node """
|
||||
|
||||
from functools import wraps
|
||||
|
||||
from flask import render_template
|
||||
from flask_babelex import gettext
|
||||
|
||||
import pgadmin.browser.server_groups.servers.databases as database
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
||||
import SchemaChildModule
|
||||
from pgadmin.browser.utils import PGChildNodeView
|
||||
from pgadmin.utils.ajax import make_json_response, internal_server_error, \
|
||||
make_response as ajax_response, gone
|
||||
from pgadmin.utils.compile_template_name import compile_template_path
|
||||
from pgadmin.utils.driver import get_driver
|
||||
|
||||
|
||||
class AggregateModule(SchemaChildModule):
|
||||
"""
|
||||
class AggregateModule(SchemaChildModule)
|
||||
|
||||
A module class for Aggregate node derived from SchemaChildModule.
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(*args, **kwargs)
|
||||
- Method is used to initialize the Aggregate and it's base module.
|
||||
|
||||
* get_nodes(gid, sid, did, scid, agid)
|
||||
- Method is used to generate the browser collection node.
|
||||
|
||||
* node_inode()
|
||||
- Method is overridden from its base class to make the node as leaf node.
|
||||
|
||||
* script_load()
|
||||
- Load the module script for schema, when any of the server node is
|
||||
initialized.
|
||||
"""
|
||||
|
||||
_NODE_TYPE = 'aggregate'
|
||||
_COLLECTION_LABEL = gettext("Aggregates")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Method is used to initialize the AggregateModule and it's base module.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
"""
|
||||
|
||||
super(AggregateModule, self).__init__(*args, **kwargs)
|
||||
self.min_ver = 90100
|
||||
self.max_ver = None
|
||||
|
||||
def get_nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
Generate the collection node
|
||||
"""
|
||||
yield self.generate_browser_collection_node(scid)
|
||||
|
||||
@property
|
||||
def script_load(self):
|
||||
"""
|
||||
Load the module script for database, when any of the database node is
|
||||
initialized.
|
||||
"""
|
||||
return database.DatabaseModule.node_type
|
||||
|
||||
@property
|
||||
def node_inode(self):
|
||||
return False
|
||||
|
||||
|
||||
blueprint = AggregateModule(__name__)
|
||||
|
||||
|
||||
class AggregateView(PGChildNodeView):
|
||||
"""
|
||||
This class is responsible for generating routes for Aggregate node
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(**kwargs)
|
||||
- Method is used to initialize the AggregateView and it's base view.
|
||||
|
||||
* check_precondition()
|
||||
- This function will behave as a decorator which will checks
|
||||
database connection before running view, it will also attaches
|
||||
manager,conn & template_path properties to self
|
||||
|
||||
* list()
|
||||
- This function is used to list all the Aggregate nodes within that
|
||||
collection.
|
||||
|
||||
* nodes()
|
||||
- This function will used to create all the child node within that
|
||||
collection, Here it will create all the Aggregate node.
|
||||
|
||||
* properties(gid, sid, did, scid, agid)
|
||||
- This function will show the properties of the selected Aggregate node
|
||||
|
||||
|
||||
* sql(gid, sid, did, scid):
|
||||
- This function will generate sql to show it in sql pane for the
|
||||
selected Aggregate node.
|
||||
"""
|
||||
|
||||
node_type = blueprint.node_type
|
||||
node_label = "Aggregate"
|
||||
|
||||
parent_ids = [
|
||||
{'type': 'int', 'id': 'gid'},
|
||||
{'type': 'int', 'id': 'sid'},
|
||||
{'type': 'int', 'id': 'did'},
|
||||
{'type': 'int', 'id': 'scid'}
|
||||
]
|
||||
ids = [
|
||||
{'type': 'int', 'id': 'agid'}
|
||||
]
|
||||
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}]
|
||||
})
|
||||
|
||||
def check_precondition(f):
|
||||
"""
|
||||
This function will behave as a decorator which will checks
|
||||
database connection before running view, it will also attaches
|
||||
manager,conn & template_path properties to self
|
||||
"""
|
||||
|
||||
@wraps(f)
|
||||
def wrap(*args, **kwargs):
|
||||
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
||||
self = args[0]
|
||||
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
|
||||
kwargs['sid']
|
||||
)
|
||||
self.conn = self.manager.connection(did=kwargs['did'])
|
||||
self.datlastsysoid = \
|
||||
self.manager.db_info[kwargs['did']]['datlastsysoid'] \
|
||||
if self.manager.db_info is not None and \
|
||||
kwargs['did'] in self.manager.db_info else 0
|
||||
|
||||
self.datistemplate = False
|
||||
if (
|
||||
self.manager.db_info is not None and
|
||||
kwargs['did'] in self.manager.db_info and
|
||||
'datistemplate' in self.manager.db_info[kwargs['did']]
|
||||
):
|
||||
self.datistemplate = self.manager.db_info[
|
||||
kwargs['did']]['datistemplate']
|
||||
|
||||
# Set the template path for the SQL scripts
|
||||
self.template_path = compile_template_path(
|
||||
'aggregates/sql/',
|
||||
self.manager.server_type,
|
||||
self.manager.version
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return wrap
|
||||
|
||||
@check_precondition
|
||||
def list(self, gid, sid, did, scid):
|
||||
"""
|
||||
This function is used to list all the aggregate nodes within that
|
||||
collection.
|
||||
|
||||
Args:
|
||||
gid: Server group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
|
||||
Returns:
|
||||
JSON of available aggregate nodes
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._NODES_SQL]), scid=scid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
return ajax_response(
|
||||
response=res['rows'],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
This function will used to create all the child node within that
|
||||
collection.
|
||||
Here it will create all the aggregate node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
|
||||
Returns:
|
||||
JSON of available aggregate child nodes
|
||||
"""
|
||||
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._NODES_SQL]), scid=scid)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
res.append(
|
||||
self.blueprint.generate_browser_node(
|
||||
row['oid'],
|
||||
scid,
|
||||
row['name'],
|
||||
icon="icon-aggregate"
|
||||
))
|
||||
|
||||
return make_json_response(
|
||||
data=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def node(self, gid, sid, did, scid, agid):
|
||||
"""
|
||||
This function will fetch properties of the aggregate node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
agid: Aggregate ID
|
||||
|
||||
Returns:
|
||||
JSON of given aggregate node
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._NODES_SQL]), agid=agid)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
return make_json_response(
|
||||
data=self.blueprint.generate_browser_node(
|
||||
row['oid'],
|
||||
scid,
|
||||
row['name'],
|
||||
icon="icon-aggregate"
|
||||
),
|
||||
status=200
|
||||
)
|
||||
|
||||
return gone(self.not_found_error_msg())
|
||||
|
||||
@check_precondition
|
||||
def properties(self, gid, sid, did, scid, agid):
|
||||
"""
|
||||
This function will show the properties of the selected aggregate node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
scid: Schema ID
|
||||
agid: Aggregate ID
|
||||
|
||||
Returns:
|
||||
JSON of selected aggregate node
|
||||
"""
|
||||
|
||||
status, res = self._fetch_properties(scid, agid)
|
||||
if not status:
|
||||
return res
|
||||
|
||||
return ajax_response(
|
||||
response=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
def _fetch_properties(self, scid, agid):
|
||||
"""
|
||||
This function fetch the properties for the specified object.
|
||||
|
||||
:param scid: Schema ID
|
||||
:param agid: Aggregate ID
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._PROPERTIES_SQL]),
|
||||
scid=scid, agid=agid,
|
||||
datlastsysoid=self.datlastsysoid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return False, internal_server_error(errormsg=res)
|
||||
|
||||
if len(res['rows']) == 0:
|
||||
return False, gone(self.not_found_error_msg())
|
||||
|
||||
res['rows'][0]['is_sys_obj'] = (
|
||||
res['rows'][0]['oid'] <= self.datlastsysoid or self.datistemplate)
|
||||
|
||||
return True, res['rows'][0]
|
||||
|
||||
@check_precondition
|
||||
def sql(self, gid, sid, did, scid, agid, **kwargs):
|
||||
"""
|
||||
This function will generates reverse engineered sql for aggregate
|
||||
object
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
agid: Aggregate ID
|
||||
json_resp: True then return json response
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._PROPERTIES_SQL]),
|
||||
scid=scid, agid=agid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if len(res['rows']) == 0:
|
||||
return gone(self.not_found_error_msg())
|
||||
|
||||
data = res['rows'][0]
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._CREATE_SQL]),
|
||||
data=data)
|
||||
|
||||
sql_header = "-- Aggregate: {0};\n\n-- ".format(data['name'])
|
||||
|
||||
sql_header += render_template("/".join([self.template_path,
|
||||
self._DELETE_SQL]),
|
||||
data=data)
|
||||
SQL = sql_header + '\n' + SQL.strip('\n')
|
||||
|
||||
return ajax_response(response=SQL)
|
||||
|
||||
|
||||
AggregateView.register_node_view(blueprint)
|
||||
+1
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#cadff1;stroke:#6f6f6f;stroke-linecap:round;stroke-miterlimit:10;}.cls-2{fill:#9cbe44;}.cls-3{fill:#888;}</style></defs><rect class="cls-1" x="4.5" y="3.23" width="7" height="9.54" rx="1"/><rect class="cls-2" x="6.02" y="4.84" width="4" height="2"/><rect class="cls-3" x="6.14" y="7.66" width="1.5" height="1.36"/><rect class="cls-3" x="8.52" y="7.66" width="1.5" height="1.36"/><rect class="cls-3" x="6.14" y="10.02" width="1.5" height="1.36"/><rect class="cls-3" x="8.52" y="10.02" width="1.5" height="1.36"/></svg>
|
||||
|
After Width: | Height: | Size: 635 B |
+1
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#cadff1;stroke:#6f6f6f;stroke-linecap:round;stroke-miterlimit:10;}.cls-2{fill:#9cbe44;}.cls-3{fill:#888;}</style></defs><rect class="cls-1" x="2.48" y="1.21" width="7" height="9.54" rx="1"/><rect class="cls-2" x="4" y="2.83" width="4" height="2"/><rect class="cls-3" x="4.12" y="5.64" width="1.5" height="1.36"/><rect class="cls-3" x="6.5" y="5.64" width="1.5" height="1.36"/><rect class="cls-3" x="4.12" y="8" width="1.5" height="1.36"/><rect class="cls-3" x="6.5" y="8" width="1.5" height="1.36"/><rect class="cls-1" x="4.5" y="3.23" width="7" height="9.54" rx="1"/><rect class="cls-2" x="6.02" y="4.84" width="4" height="2"/><rect class="cls-3" x="6.14" y="7.66" width="1.5" height="1.36"/><rect class="cls-3" x="8.52" y="7.66" width="1.5" height="1.36"/><rect class="cls-3" x="6.14" y="10.02" width="1.5" height="1.36"/><rect class="cls-3" x="8.52" y="10.02" width="1.5" height="1.36"/><rect class="cls-1" x="6.52" y="5.25" width="7" height="9.54" rx="1"/><rect class="cls-2" x="8.04" y="6.86" width="4" height="2"/><rect class="cls-3" x="8.16" y="9.67" width="1.5" height="1.36"/><rect class="cls-3" x="10.54" y="9.67" width="1.5" height="1.36"/><rect class="cls-3" x="8.16" y="12.03" width="1.5" height="1.36"/><rect class="cls-3" x="10.54" y="12.03" width="1.5" height="1.36"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
+86
@@ -0,0 +1,86 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import AggregateSchema from './aggregate.ui';
|
||||
|
||||
define('pgadmin.node.aggregate', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.node.schema.dir/child', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, schemaChild) {
|
||||
|
||||
if (!pgBrowser.Nodes['coll-aggregate']) {
|
||||
pgAdmin.Browser.Nodes['coll-aggregate'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
node: 'aggregate',
|
||||
label: gettext('Aggregates'),
|
||||
type: 'coll-aggregate',
|
||||
columns: ['name', 'owner', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (!pgBrowser.Nodes['aggregate']) {
|
||||
pgAdmin.Browser.Nodes['aggregate'] = schemaChild.SchemaChildNode.extend({
|
||||
type: 'aggregate',
|
||||
sqlAlterHelp: 'sql-alteraggregate.html',
|
||||
sqlCreateHelp: 'sql-createaggregate.html',
|
||||
label: gettext('Aggregate'),
|
||||
collection_type: 'coll-aggregate',
|
||||
hasSQL: true,
|
||||
hasDepends: false,
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
Init: function() {
|
||||
/* Avoid mulitple registration of menus */
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({'owner': userInfo.name}, {silent: true});
|
||||
this.set({'schema': schemaInfo._label}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Aggregate'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
control: 'node-list-by-name',
|
||||
node: 'role',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
}
|
||||
],
|
||||
}),
|
||||
getSchema: ()=>{
|
||||
let schema = new AggregateSchema();
|
||||
return schema;
|
||||
}
|
||||
});
|
||||
}
|
||||
return pgBrowser.Nodes['aggregate'];
|
||||
});
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
|
||||
import gettext from 'sources/gettext';
|
||||
|
||||
export default class AggregateSchema extends BaseUISchema {
|
||||
constructor(fieldOptions = {},initValues) {
|
||||
super({
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
owner: undefined,
|
||||
description: undefined,
|
||||
schema: null,
|
||||
input_types: undefined,
|
||||
state_type: undefined,
|
||||
state_func: undefined,
|
||||
state_data_size: 0,
|
||||
final_type: undefined,
|
||||
final_func: undefined,
|
||||
final_func_modify: undefined,
|
||||
final_extra_param: undefined,
|
||||
initial_val: undefined,
|
||||
moving_state_type: undefined,
|
||||
moving_state_func: undefined,
|
||||
moving_state_data_size: 0,
|
||||
moving_final_type: undefined,
|
||||
moving_final_func: undefined,
|
||||
moving_final_func_modify: undefined,
|
||||
moving_final_extra_param: undefined,
|
||||
moving_initial_val: undefined,
|
||||
moving_inverse_func: undefined,
|
||||
combine_func: undefined,
|
||||
serialization_func: undefined,
|
||||
deserialization_func: undefined,
|
||||
sort_oper: undefined,
|
||||
...initValues
|
||||
});
|
||||
this.fieldOptions = fieldOptions;
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
return [
|
||||
{
|
||||
id: 'name', label: gettext('Name'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'oid', label: gettext('OID'),
|
||||
type: 'text', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'owner', label: gettext('Owner'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'schema', label: gettext('Schema'),
|
||||
mode: ['create', 'edit'],
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'is_sys_obj', label: gettext('System aggregate?'),
|
||||
cell: 'boolean', type: 'switch', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'description', label: gettext('Comment'),
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'input_types', label: gettext('Input types'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'state_type', label: gettext('State type'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'state_func', label: gettext('State function'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'state_data_size', label: gettext('State data size'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'final_type', label: gettext('Final type'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'final_func', label: gettext('Final function'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'final_func_modify', label: gettext('Final function modify'),
|
||||
group: gettext('Options'), min_version: 110000,
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'final_extra_param', label: gettext('Pass extra arguments to final function'),
|
||||
group: gettext('Options'), type: 'switch', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'initial_val', label: gettext('Initial condition'),
|
||||
group: gettext('Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_state_type', label: gettext('State type'),
|
||||
group: gettext('Moving Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_state_func', label: gettext('State function'),
|
||||
group: gettext('Moving Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_state_data_size', label: gettext('State data size'),
|
||||
group: gettext('Moving Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_final_func', label: gettext('Final function'),
|
||||
group: gettext('Moving Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_final_func_modify', label: gettext('Final function modify'),
|
||||
group: gettext('Moving Options'), min_version: 110000,
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_final_extra_param', label: gettext('Pass extra arguments to final function'),
|
||||
group: gettext('Moving Options'), type: 'switch', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_inverse_func', label: gettext('Inverse function'),
|
||||
group: gettext('Moving Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'moving_initial_val', label: gettext('Initial condition'),
|
||||
group: gettext('Moving Options'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'sort_oper', label: gettext('Sort operator'),
|
||||
group: gettext('Advanced'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'combine_func', label: gettext('Combine function'),
|
||||
group: gettext('Advanced'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'serialization_func', label: gettext('Serialization function'),
|
||||
group: gettext('Advanced'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'deserialization_func', label: gettext('Deserialization function'),
|
||||
group: gettext('Advanced'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
{% if data %}
|
||||
CREATE AGGREGATE {{conn|qtIdent(data.schema, data.name)}}({% if data.input_types %}{{data.input_types}}{% endif %}) (
|
||||
SFUNC = {{data.state_func}},
|
||||
STYPE = {{data.state_type}} {% if data.state_data_size %},
|
||||
SSPACE = {{data.state_data_size}}{% endif %}{% if data.final_func %},
|
||||
FINALFUNC = {{data.final_func}}{% endif %}{% if data.final_extra_param %},
|
||||
FINALFUNC_EXTRA{% endif %}{% if data.final_func_modify %},
|
||||
FINALFUNC_MODIFY = {{data.final_func_modify}}{% endif %}{% if data.combine_func %},
|
||||
COMBINEFUNC = {{data.combine_func}}{% endif %}{% if data.serialization_func %},
|
||||
SERIALFUNC = {{data.serialization_func}}{% endif %}{% if data.deserialization_func %},
|
||||
DESERIALFUNC = {{data.deserialization_func}}{% endif %}{% if data.initial_val %},
|
||||
INITCOND = '{{data.initial_val}}'::text{% endif %}{% if data.moving_state_func %},
|
||||
MSFUNC = {{data.moving_state_func}}{% endif %}{% if data.moving_inverse_func %},
|
||||
MINVFUNC = {{data.moving_inverse_func}}{% endif %}{% if data.moving_state_type %},
|
||||
MSTYPE = {{data.moving_state_type}}{% endif %}{% if data.moving_state_data_size %},
|
||||
MSSPACE = {{data.moving_state_data_size}}{% endif %}{% if data.moving_final_func %},
|
||||
MFINALFUNC = {{data.moving_final_func}}{% endif %}{% if data.moving_final_extra_param %},
|
||||
MFINALFUNC_EXTRA{% endif %}{% if data.moving_final_func_modify %},
|
||||
MFINALFUNC_MODIFY = {{data.moving_final_func_modify}}{% endif %}{% if data.moving_initial_val %},
|
||||
MINITCOND = '{{data.moving_initial_val}}'::text{% endif %}{% if data.sort_oper %},
|
||||
SORTOP = {{data.sort_oper}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
SELECT aggfnoid::oid as oid, proname as name, ns.nspname as schema,
|
||||
pg_catalog.pg_get_userbyid(proowner) as owner,
|
||||
COALESCE(pg_catalog.pg_get_function_arguments(aggfnoid::oid), '') as input_types, proacl,
|
||||
CASE WHEN ag.aggkind = 'n' THEN 'normal'
|
||||
WHEN ag.aggkind = 'o' THEN 'ordered-set'
|
||||
WHEN ag.aggkind = 'h' THEN 'hypothetical-set'
|
||||
ELSE 'unknown' END as kind,
|
||||
CASE WHEN aggtransfn = '-'::regproc THEN null ELSE aggtransfn END as state_func,
|
||||
CASE WHEN aggfinalfn = '-'::regproc THEN null ELSE aggfinalfn END as final_func,
|
||||
CASE WHEN aggcombinefn = '-'::regproc THEN null ELSE aggcombinefn END as combine_func,
|
||||
CASE WHEN aggserialfn = '-'::regproc THEN null ELSE aggserialfn END as serialization_func,
|
||||
CASE WHEN aggdeserialfn = '-'::regproc THEN null ELSE aggdeserialfn END as deserialization_func,
|
||||
CASE WHEN aggmtransfn = '-'::regproc THEN null ELSE aggmtransfn END as moving_state_func,
|
||||
CASE WHEN aggmfinalfn = '-'::regproc THEN null ELSE aggmfinalfn END as moving_final_func,
|
||||
CASE WHEN aggminvtransfn = '-'::regproc THEN null ELSE aggminvtransfn END as moving_inverse_func,
|
||||
CASE WHEN ag.aggfinalmodify = 'r' THEN 'READ_ONLY'
|
||||
WHEN ag.aggfinalmodify = 's' THEN 'SHAREABLE'
|
||||
WHEN ag.aggfinalmodify = 'w' THEN 'READ_WRITE'
|
||||
ELSE 'unknown' END as final_func_modify,
|
||||
CASE WHEN ag.aggmfinalmodify = 'r' THEN 'READ_ONLY'
|
||||
WHEN ag.aggmfinalmodify = 's' THEN 'SHAREABLE'
|
||||
WHEN ag.aggmfinalmodify = 'w' THEN 'READ_WRITE'
|
||||
ELSE 'unknown' END as moving_final_func_modify,
|
||||
agginitval as initial_val, aggminitval as moving_initial_val,
|
||||
op.oprname as sort_oper, aggfinalextra as final_extra_param, aggmfinalextra as moving_final_extra_param,
|
||||
aggtransspace as state_data_size, aggmtransspace as moving_state_data_size,
|
||||
CASE WHEN (tt.typlen = -1 AND tt.typelem != 0) THEN
|
||||
(SELECT at.typname FROM pg_type at WHERE at.oid = tt.typelem) || '[]'
|
||||
ELSE tt.typname END as state_type,
|
||||
CASE WHEN (tf.typlen = -1 AND tf.typelem != 0) THEN
|
||||
(SELECT at.typname FROM pg_catalog.pg_type at WHERE at.oid = tf.typelem) || '[]'
|
||||
ELSE tf.typname END as final_type,
|
||||
CASE WHEN (tm.typlen = -1 AND tm.typelem != 0) THEN
|
||||
(SELECT at.typname FROM pg_type at WHERE at.oid = tm.typelem) || '[]'
|
||||
ELSE tm.typname END as moving_state_type,
|
||||
description
|
||||
FROM pg_catalog.pg_aggregate ag
|
||||
LEFT OUTER JOIN pg_catalog.pg_proc pr ON pr.oid = ag.aggfnoid
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=pr.pronamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tt on tt.oid=aggtranstype
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tf on tf.oid=prorettype
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tm on tm.oid=aggmtranstype
|
||||
LEFT OUTER JOIN pg_catalog.pg_operator op on op.oid = ag.aggsortop
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=aggfnoid::oid AND des.classoid='pg_aggregate'::regclass)
|
||||
WHERE pronamespace = {{scid}}::oid
|
||||
{% if agid %} AND ag.aggfnoid = {{agid}}::oid {% endif %}
|
||||
ORDER BY name;
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
{% if data %}
|
||||
CREATE OR REPLACE AGGREGATE {{conn|qtIdent(data.schema, data.name)}}({% if data.input_types %}{{data.input_types}}{% endif %}) (
|
||||
SFUNC = {{data.state_func}},
|
||||
STYPE = {{data.state_type}} {% if data.state_data_size %},
|
||||
SSPACE = {{data.state_data_size}}{% endif %}{% if data.final_func %},
|
||||
FINALFUNC = {{data.final_func}}{% endif %}{% if data.final_extra_param %},
|
||||
FINALFUNC_EXTRA{% endif %}{% if data.final_func_modify %},
|
||||
FINALFUNC_MODIFY = {{data.final_func_modify}}{% endif %}{% if data.combine_func %},
|
||||
COMBINEFUNC = {{data.combine_func}}{% endif %}{% if data.serialization_func %},
|
||||
SERIALFUNC = {{data.serialization_func}}{% endif %}{% if data.deserialization_func %},
|
||||
DESERIALFUNC = {{data.deserialization_func}}{% endif %}{% if data.initial_val %},
|
||||
INITCOND = '{{data.initial_val}}'::text{% endif %}{% if data.moving_state_func %},
|
||||
MSFUNC = {{data.moving_state_func}}{% endif %}{% if data.moving_inverse_func %},
|
||||
MINVFUNC = {{data.moving_inverse_func}}{% endif %}{% if data.moving_state_type %},
|
||||
MSTYPE = {{data.moving_state_type}}{% endif %}{% if data.moving_state_data_size %},
|
||||
MSSPACE = {{data.moving_state_data_size}}{% endif %}{% if data.moving_final_func %},
|
||||
MFINALFUNC = {{data.moving_final_func}}{% endif %}{% if data.moving_final_extra_param %},
|
||||
MFINALFUNC_EXTRA{% endif %}{% if data.moving_final_func_modify %},
|
||||
MFINALFUNC_MODIFY = {{data.moving_final_func_modify}}{% endif %}{% if data.moving_initial_val %},
|
||||
MINITCOND = '{{data.moving_initial_val}}'::text{% endif %}{% if data.sort_oper %},
|
||||
SORTOP = {{data.sort_oper}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{% if data %}
|
||||
CREATE AGGREGATE {{conn|qtIdent(data.schema, data.name)}}({% if data.input_types %}{{data.input_types}}{% endif %}) (
|
||||
SFUNC = {{data.state_func}},
|
||||
STYPE = {{data.state_type}} {% if data.state_data_size %},
|
||||
SSPACE = {{data.state_data_size}}{% endif %}{% if data.final_func %},
|
||||
FINALFUNC = {{data.final_func}}{% endif %}{% if data.final_extra_param %},
|
||||
FINALFUNC_EXTRA{% endif %}{% if data.combine_func %},
|
||||
COMBINEFUNC = {{data.combine_func}}{% endif %}{% if data.serialization_func %},
|
||||
SERIALFUNC = {{data.serialization_func}}{% endif %}{% if data.deserialization_func %},
|
||||
DESERIALFUNC = {{data.deserialization_func}}{% endif %}{% if data.initial_val %},
|
||||
INITCOND = '{{data.initial_val}}'::text{% endif %}{% if data.moving_state_func %},
|
||||
MSFUNC = {{data.moving_state_func}}{% endif %}{% if data.moving_inverse_func %},
|
||||
MINVFUNC = {{data.moving_inverse_func}}{% endif %}{% if data.moving_state_type %},
|
||||
MSTYPE = {{data.moving_state_type}}{% endif %}{% if data.moving_state_data_size %},
|
||||
MSSPACE = {{data.moving_state_data_size}}{% endif %}{% if data.moving_final_func %},
|
||||
MFINALFUNC = {{data.moving_final_func}}{% endif %}{% if data.moving_final_extra_param %},
|
||||
MFINALFUNC_EXTRA{% endif %}{% if data.moving_initial_val %},
|
||||
MINITCOND = '{{data.moving_initial_val}}'::text{% endif %}{% if data.sort_oper %},
|
||||
SORTOP = {{data.sort_oper}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
{% if data %}
|
||||
DROP AGGREGATE IF EXISTS {{conn|qtIdent(data.schema, data.name)}}({% if data.input_types %}{{data.input_types}}{% endif %}){% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
SELECT aggfnoid::oid as oid,
|
||||
proname || '(' || COALESCE(pg_catalog.pg_get_function_arguments(aggfnoid::oid), '') || ')' AS name,
|
||||
pg_catalog.pg_get_userbyid(proowner) AS owner
|
||||
FROM pg_aggregate ag
|
||||
LEFT OUTER JOIN pg_catalog.pg_proc pr ON pr.oid = ag.aggfnoid
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tt on tt.oid=aggtranstype
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tf on tf.oid=prorettype
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=aggfnoid::oid AND des.classoid='pg_aggregate'::regclass)
|
||||
{% if scid %}
|
||||
WHERE pronamespace = {{scid}}::oid
|
||||
{% elif agid %}
|
||||
WHERE ag.aggfnoid = {{agid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY name;
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
SELECT aggfnoid::oid as oid, proname as name, ns.nspname as schema,
|
||||
pg_catalog.pg_get_userbyid(proowner) as owner,
|
||||
COALESCE(pg_catalog.pg_get_function_arguments(aggfnoid::oid), '') as input_types, proacl,
|
||||
CASE WHEN ag.aggkind = 'n' THEN 'normal'
|
||||
WHEN ag.aggkind = 'o' THEN 'ordered-set'
|
||||
WHEN ag.aggkind = 'h' THEN 'hypothetical-set'
|
||||
ELSE 'unknown' END as kind,
|
||||
CASE WHEN aggtransfn = '-'::regproc THEN null ELSE aggtransfn END as state_func,
|
||||
CASE WHEN aggfinalfn = '-'::regproc THEN null ELSE aggfinalfn END as final_func,
|
||||
CASE WHEN aggcombinefn = '-'::regproc THEN null ELSE aggcombinefn END as combine_func,
|
||||
CASE WHEN aggserialfn = '-'::regproc THEN null ELSE aggserialfn END as serialization_func,
|
||||
CASE WHEN aggdeserialfn = '-'::regproc THEN null ELSE aggdeserialfn END as deserialization_func,
|
||||
CASE WHEN aggmtransfn = '-'::regproc THEN null ELSE aggmtransfn END as moving_state_func,
|
||||
CASE WHEN aggmfinalfn = '-'::regproc THEN null ELSE aggmfinalfn END as moving_final_func,
|
||||
CASE WHEN aggminvtransfn = '-'::regproc THEN null ELSE aggminvtransfn END as moving_inverse_func,
|
||||
agginitval as initial_val, aggminitval as moving_initial_val,
|
||||
op.oprname as sort_oper, aggfinalextra as final_extra_param, aggmfinalextra as moving_final_extra_param,
|
||||
aggtransspace as state_data_size, aggmtransspace as moving_state_data_size,
|
||||
CASE WHEN (tt.typlen = -1 AND tt.typelem != 0) THEN
|
||||
(SELECT at.typname FROM pg_type at WHERE at.oid = tt.typelem) || '[]'
|
||||
ELSE tt.typname END as state_type,
|
||||
CASE WHEN (tf.typlen = -1 AND tf.typelem != 0) THEN
|
||||
(SELECT at.typname FROM pg_catalog.pg_type at WHERE at.oid = tf.typelem) || '[]'
|
||||
ELSE tf.typname END as final_type,
|
||||
CASE WHEN (tm.typlen = -1 AND tm.typelem != 0) THEN
|
||||
(SELECT at.typname FROM pg_type at WHERE at.oid = tm.typelem) || '[]'
|
||||
ELSE tm.typname END as moving_state_type,
|
||||
description
|
||||
FROM pg_catalog.pg_aggregate ag
|
||||
LEFT OUTER JOIN pg_catalog.pg_proc pr ON pr.oid = ag.aggfnoid
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=pr.pronamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tt on tt.oid=aggtranstype
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tf on tf.oid=prorettype
|
||||
LEFT OUTER JOIN pg_catalog.pg_type tm on tm.oid=aggmtranstype
|
||||
LEFT OUTER JOIN pg_catalog.pg_operator op on op.oid = ag.aggsortop
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=aggfnoid::oid AND des.classoid='pg_aggregate'::regclass)
|
||||
WHERE pronamespace = {{scid}}::oid
|
||||
{% if agid %} AND ag.aggfnoid = {{agid}}::oid {% endif %}
|
||||
ORDER BY name;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
SET application_name='pgadmin'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer) TO PUBLIC;
|
||||
|
||||
COMMENT ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer)
|
||||
IS 'some comment';
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
|
||||
COMMENT ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer)
|
||||
IS 'some comment';
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
SET application_name='pgadmin'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
|
||||
COMMENT ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer)
|
||||
IS 'some comment';
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
+311
@@ -0,0 +1,311 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function.sql",
|
||||
"expected_msql_file": "create_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function comment",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"description": "Some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_function_comment.sql",
|
||||
"expected_msql_file": "alter_function_comment.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for alter.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function rename.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name":"Function3_$%{}[]()&*^!@\"'`\\/#"
|
||||
},
|
||||
"expected_sql_file": "alter_function_rename.sql",
|
||||
"expected_msql_file": "alter_function_rename.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function code and add parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"prosrc": "begin\nselect '2';\nend\n",
|
||||
"variables": {
|
||||
"added": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_parameter.sql",
|
||||
"expected_msql_file": "alter_function_add_parameter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"deleted": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_parameter.sql",
|
||||
"expected_msql_file": "alter_function_delete_parameter.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for acl.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function add acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_acl.sql",
|
||||
"expected_msql_file": "alter_function_add_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function remove partial privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function change grantee in privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"old_grantee": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_change_grantee_acl.sql",
|
||||
"expected_msql_file": "alter_function_change_grantee_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_acl.sql",
|
||||
"expected_msql_file": "alter_function_delete_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create procedure",
|
||||
"endpoint": "NODE-procedure.obj",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"name": "Proc1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [],
|
||||
"arguments": [{"argtype": "integer", "argmode": "IN", "argname": "i1", "argdefval": ""}],
|
||||
"funcowner": "postgres",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"pronamespace": 2200,
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [],
|
||||
"schema": "public",
|
||||
"provolatile": null,
|
||||
"proisstrict": false,
|
||||
"proparallel": null,
|
||||
"procost": null,
|
||||
"proleakproof": false,
|
||||
"probin": "$libdir/"
|
||||
},
|
||||
"expected_sql_file": "create_procedure.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter procedure comment",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"description": "some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_proc_comment.sql",
|
||||
"expected_msql_file": "alter_proc_comment_msql.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter procedure param",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"added": [{"name": "application_name", "value": "pgadmin"}]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_proc_param.sql",
|
||||
"expected_msql_file": "alter_proc_param_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter procedure add privileges",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter procedure delete privileges",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter procedure change privileges",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "postgres",
|
||||
"old_grantee": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_proc_change_grantee_priv.sql",
|
||||
"expected_msql_file": "alter_proc_change_grantee_priv.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop procedure",
|
||||
"endpoint": "NODE-procedure.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create trigger function",
|
||||
"endpoint": "NODE-trigger_function.obj",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"name": "Trig1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [],
|
||||
"args": [],
|
||||
"funcowner": "postgres",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "trigger",
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_plain_trigger.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function comment",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"description": "some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_comment.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function Set 1 - Strict, Leakproof, Security of definer, Volatility",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"proisstrict": true,
|
||||
"proleakproof": true,
|
||||
"prosecdef": true,
|
||||
"provolatile": "s"
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_set_1.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function Set 2 - Cost, Volatility, Add Param",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"procost": "123",
|
||||
"provolatile": "i",
|
||||
"variables": {
|
||||
"added": [{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
},{
|
||||
"name": "search_path",
|
||||
"value": "public, pg_temp"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_set_2.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function Set 3 - Add Param, Change Param",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"added": [{
|
||||
"name": "application_name",
|
||||
"value": "appname2"
|
||||
}],
|
||||
"changed": [{
|
||||
"name": "array_nulls",
|
||||
"value": true
|
||||
},{
|
||||
"name": "search_path",
|
||||
"value": "public, pg_catalog"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_set_3.sql"
|
||||
}, {
|
||||
"type": "delete",
|
||||
"name": "Drop trigger function",
|
||||
"endpoint": "NODE-trigger_function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}, {
|
||||
"type": "create",
|
||||
"name": "Create full fledged trigger function",
|
||||
"endpoint": "NODE-trigger_function.obj",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"name": "Trig1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": true
|
||||
}
|
||||
]
|
||||
}],
|
||||
"args": [],
|
||||
"description": "some comment",
|
||||
"funcowner": "postgres",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"procost": "1234",
|
||||
"proisstrict": true,
|
||||
"proiswindow": true,
|
||||
"proleakproof": true,
|
||||
"pronamespace": 2200,
|
||||
"proretset": true,
|
||||
"prorettypename": "trigger",
|
||||
"prorows": "4321",
|
||||
"prosecdef": true,
|
||||
"provolatile": "s",
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
},{
|
||||
"name": "search_path",
|
||||
"value": "public, pg_temp"
|
||||
}],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_plain_trigger_full.sql"
|
||||
}, {
|
||||
"type": "delete",
|
||||
"name": "Drop full fledged trigger function",
|
||||
"endpoint": "NODE-trigger_function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}, {
|
||||
"type": "create",
|
||||
"name": "Create full fledged event trigger function",
|
||||
"endpoint": "NODE-trigger_function.obj",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"name": "Trig1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [{
|
||||
"grantee": "postgres",
|
||||
"grantor": "postgres",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": true
|
||||
}
|
||||
]
|
||||
}],
|
||||
"args": [],
|
||||
"description": "some comment",
|
||||
"funcowner": "postgres",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"procost": "1234",
|
||||
"proisstrict": true,
|
||||
"proiswindow": true,
|
||||
"proleakproof": true,
|
||||
"pronamespace": 2200,
|
||||
"proretset": true,
|
||||
"prorettypename": "event_trigger",
|
||||
"prorows": "4321",
|
||||
"prosecdef": true,
|
||||
"provolatile": "s",
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
}],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_event_trigger_full.sql"
|
||||
}, {
|
||||
"type": "delete",
|
||||
"name": "Drop full fledged event trigger function",
|
||||
"endpoint": "NODE-trigger_function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
SET application_name='pgadmin'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
|
||||
GRANT EXECUTE ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer) TO PUBLIC;
|
||||
|
||||
COMMENT ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer)
|
||||
IS 'some comment';
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
|
||||
COMMENT ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer)
|
||||
IS 'some comment';
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
SET application_name='pgadmin'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
|
||||
COMMENT ON PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(integer)
|
||||
IS 'some comment';
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
-- PROCEDURE: public.Proc1_$%{}[]()&*^!@"'`\/#(integer)
|
||||
|
||||
-- DROP PROCEDURE IF EXISTS public."Proc1_$%{}[]()&*^!@""'`\/#"(integer);
|
||||
|
||||
CREATE OR REPLACE PROCEDURE public."Proc1_$%{}[]()&*^!@""'`\/#"(
|
||||
IN i1 integer)
|
||||
LANGUAGE 'plpgsql'
|
||||
AS $BODY$
|
||||
begin
|
||||
select 1;
|
||||
end;
|
||||
$BODY$;
|
||||
+323
@@ -0,0 +1,323 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proretset": false,
|
||||
"proisstrict": true,
|
||||
"prosecdef": true,
|
||||
"proiswindow": true,
|
||||
"proparallel": "u",
|
||||
"procost": "100",
|
||||
"prorows": "0",
|
||||
"proleakproof": true,
|
||||
"arguments": [
|
||||
{
|
||||
"argtype": "character varying",
|
||||
"argmode": "IN",
|
||||
"argname": "param",
|
||||
"argdefval": "'1'"
|
||||
}
|
||||
],
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function.sql",
|
||||
"expected_msql_file": "create_function.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function comment",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"description": "Some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_function_comment.sql",
|
||||
"expected_msql_file": "alter_function_comment.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for alter.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"prosecdef": true,
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function rename.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function3_$%{}[]()&*^!@\"'`\\/#"
|
||||
},
|
||||
"expected_sql_file": "alter_function_rename.sql",
|
||||
"expected_msql_file": "alter_function_rename.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function code and add parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"prosrc": "begin\nselect '2';\nend\n",
|
||||
"variables": {
|
||||
"added": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_parameter.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete parameters.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"deleted": [
|
||||
{
|
||||
"name": "application_name",
|
||||
"value": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_parameter.sql",
|
||||
"expected_msql_file": "alter_function_delete_parameter.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function for acl.",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"name": "Function2_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"lanname": "plpgsql",
|
||||
"provolatile": "v",
|
||||
"proparallel": "u",
|
||||
"prosecdef": true,
|
||||
"arguments": [],
|
||||
"procost": "100",
|
||||
"prosrc": "begin\nselect '1';\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [
|
||||
{
|
||||
"name": "enable_sort",
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_for_alter.sql",
|
||||
"expected_msql_file": "create_function_for_alter.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function add acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_add_acl.sql",
|
||||
"expected_msql_file": "alter_function_add_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function remove partial privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function change grantee in privileges.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"old_grantee": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_change_grantee_acl.sql",
|
||||
"expected_msql_file": "alter_function_change_grantee_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function delete acl.",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege_type": "X",
|
||||
"privilege": true,
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_function_delete_acl.sql",
|
||||
"expected_msql_file": "alter_function_delete_acl.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create procedure",
|
||||
"endpoint": "NODE-procedure.obj",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"name": "Proc1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [],
|
||||
"arguments": [{"argtype": "integer", "argmode": "IN", "argname": "i1", "argdefval": ""}],
|
||||
"funcowner": "enterprisedb",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"pronamespace": 2200,
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [],
|
||||
"schema": "public",
|
||||
"provolatile": null,
|
||||
"proisstrict": false,
|
||||
"proparallel": null,
|
||||
"procost": null,
|
||||
"proleakproof": false,
|
||||
"probin": "$libdir/"
|
||||
},
|
||||
"expected_sql_file": "create_procedure.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter procedure comment",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"description": "some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_proc_comment.sql",
|
||||
"expected_msql_file": "alter_proc_comment_msql.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter procedure param",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"added": [{"name": "application_name", "value": "pgadmin"}]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_proc_param.sql",
|
||||
"expected_msql_file": "alter_proc_param_msql.sql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter procedure add privileges",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"added": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter procedure delete privileges",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"deleted": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter procedure change privileges",
|
||||
"endpoint": "NODE-procedure.obj_id",
|
||||
"sql_endpoint": "NODE-procedure.sql_id",
|
||||
"data": {
|
||||
"acl": {
|
||||
"changed": [
|
||||
{
|
||||
"grantee": "PUBLIC",
|
||||
"grantor": "enterprisedb",
|
||||
"old_grantee": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_proc_change_grantee_priv.sql",
|
||||
"expected_msql_file": "alter_proc_change_grantee_priv.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop procedure",
|
||||
"endpoint": "NODE-procedure.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create trigger function",
|
||||
"endpoint": "NODE-trigger_function.obj",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"name": "Trig1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [],
|
||||
"args": [],
|
||||
"funcowner": "enterprisedb",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "trigger",
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_plain_trigger.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function comment",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"description": "some comment"
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_comment.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function Set 1 - Strict, Leakproof, Security of definer, Volatility",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"proisstrict": true,
|
||||
"proleakproof": true,
|
||||
"prosecdef": true,
|
||||
"provolatile": "s"
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_set_1.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function Set 2 - Cost, Volatility, Add Param",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"procost": "123",
|
||||
"provolatile": "i",
|
||||
"variables": {
|
||||
"added": [{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
},{
|
||||
"name": "search_path",
|
||||
"value": "public, pg_temp"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_set_2.sql"
|
||||
}, {
|
||||
"type": "alter",
|
||||
"name": "Alter trigger function Set 3 - Add Param, Change Param",
|
||||
"endpoint": "NODE-trigger_function.obj_id",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"variables": {
|
||||
"added": [{
|
||||
"name": "application_name",
|
||||
"value": "appname2"
|
||||
}],
|
||||
"changed": [{
|
||||
"name": "array_nulls",
|
||||
"value": true
|
||||
},{
|
||||
"name": "search_path",
|
||||
"value": "public, pg_catalog"
|
||||
}]
|
||||
}
|
||||
},
|
||||
"expected_sql_file": "alter_ptrig_set_3.sql"
|
||||
}, {
|
||||
"type": "delete",
|
||||
"name": "Drop trigger function",
|
||||
"endpoint": "NODE-trigger_function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}, {
|
||||
"type": "create",
|
||||
"name": "Create full fledged trigger function",
|
||||
"endpoint": "NODE-trigger_function.obj",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"name": "Trig1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": true
|
||||
}
|
||||
]
|
||||
}],
|
||||
"args": [],
|
||||
"description": "some comment",
|
||||
"funcowner": "enterprisedb",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"procost": "1234",
|
||||
"proisstrict": true,
|
||||
"proiswindow": true,
|
||||
"proleakproof": true,
|
||||
"pronamespace": 2200,
|
||||
"proretset": true,
|
||||
"prorettypename": "trigger",
|
||||
"prorows": "4321",
|
||||
"prosecdef": true,
|
||||
"provolatile": "v",
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
},{
|
||||
"name": "search_path",
|
||||
"value": "public, pg_temp"
|
||||
}],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_plain_trigger_full.sql"
|
||||
}, {
|
||||
"type": "delete",
|
||||
"name": "Drop full fledged trigger function",
|
||||
"endpoint": "NODE-trigger_function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}, {
|
||||
"type": "create",
|
||||
"name": "Create full fledged event trigger function",
|
||||
"endpoint": "NODE-trigger_function.obj",
|
||||
"sql_endpoint": "NODE-trigger_function.sql_id",
|
||||
"data": {
|
||||
"name": "Trig1_$%{}[]()&*^!@\"'`\\/#",
|
||||
"acl": [{
|
||||
"grantee": "enterprisedb",
|
||||
"grantor": "enterprisedb",
|
||||
"privileges": [
|
||||
{
|
||||
"privilege": true,
|
||||
"privilege_type": "X",
|
||||
"with_grant": true
|
||||
}
|
||||
]
|
||||
}],
|
||||
"args": [],
|
||||
"description": "some comment",
|
||||
"funcowner": "enterprisedb",
|
||||
"lanname": "plpgsql",
|
||||
"options": [],
|
||||
"procost": "1234",
|
||||
"proisstrict": true,
|
||||
"proiswindow": true,
|
||||
"proleakproof": true,
|
||||
"pronamespace": 2200,
|
||||
"proretset": true,
|
||||
"prorettypename": "event_trigger",
|
||||
"prorows": "4321",
|
||||
"prosecdef": true,
|
||||
"provolatile": "v",
|
||||
"prosrc": "begin\nselect 1;\nend;",
|
||||
"seclabels": [],
|
||||
"variables": [{
|
||||
"name": "application_name",
|
||||
"value": "appname"
|
||||
}],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_event_trigger_full.sql"
|
||||
}, {
|
||||
"type": "delete",
|
||||
"name": "Drop full fledged event trigger function",
|
||||
"endpoint": "NODE-trigger_function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+4
-1
@@ -25,7 +25,7 @@ class ProcedureExecSQLTestCase(BaseTestGenerator):
|
||||
('Fetch Procedure SQL to execute', dict(
|
||||
url='/browser/procedure/exec_sql/', with_args=False, args="",
|
||||
expected_sql="{0} {1}.{2}()")),
|
||||
('Fetch Procedure with arguuments SQL to execute', dict(
|
||||
('Fetch Procedure with arguments SQL to execute', dict(
|
||||
url='/browser/procedure/exec_sql/', with_args=True,
|
||||
args="arg1 bigint",
|
||||
expected_sql="{0} {1}.{2}( <arg1 bigint> )"))
|
||||
@@ -41,6 +41,9 @@ class ProcedureExecSQLTestCase(BaseTestGenerator):
|
||||
message = "Procedures are not supported by PG < 110000."
|
||||
self.skipTest(message)
|
||||
|
||||
if self.with_args and self.server_version >= 140000:
|
||||
self.expected_sql = "{0} {1}.{2}( <IN arg1 bigint> )"
|
||||
|
||||
proc_name = "test_procedure_exec_sql_%s" % str(uuid.uuid4())[1:8]
|
||||
proc_info = funcs_utils.create_procedure(
|
||||
self.server, self.db_name, self.schema_name, proc_name,
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
""" Implements Operator Node """
|
||||
|
||||
from functools import wraps
|
||||
|
||||
from flask import render_template
|
||||
from flask_babelex import gettext
|
||||
|
||||
import pgadmin.browser.server_groups.servers.databases as database
|
||||
from config import PG_DEFAULT_DRIVER
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
||||
import SchemaChildModule
|
||||
from pgadmin.browser.utils import PGChildNodeView
|
||||
from pgadmin.utils.ajax import make_json_response, internal_server_error, \
|
||||
make_response as ajax_response, gone
|
||||
from pgadmin.utils.compile_template_name import compile_template_path
|
||||
from pgadmin.utils.driver import get_driver
|
||||
|
||||
|
||||
class OperatorModule(SchemaChildModule):
|
||||
"""
|
||||
class OperatorModule(SchemaChildModule)
|
||||
|
||||
A module class for Operator node derived from SchemaChildModule.
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(*args, **kwargs)
|
||||
- Method is used to initialize the Operator and it's base module.
|
||||
|
||||
* get_nodes(gid, sid, did, scid, opid)
|
||||
- Method is used to generate the browser collection node.
|
||||
|
||||
* node_inode()
|
||||
- Method is overridden from its base class to make the node as leaf node.
|
||||
|
||||
* script_load()
|
||||
- Load the module script for schema, when any of the server node is
|
||||
initialized.
|
||||
"""
|
||||
|
||||
_NODE_TYPE = 'operator'
|
||||
_COLLECTION_LABEL = gettext("Operators")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""
|
||||
Method is used to initialize the OperatorModule and it's base module.
|
||||
|
||||
Args:
|
||||
*args:
|
||||
**kwargs:
|
||||
"""
|
||||
|
||||
super(OperatorModule, self).__init__(*args, **kwargs)
|
||||
self.min_ver = 90100
|
||||
self.max_ver = None
|
||||
|
||||
def get_nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
Generate the collection node
|
||||
"""
|
||||
yield self.generate_browser_collection_node(scid)
|
||||
|
||||
@property
|
||||
def script_load(self):
|
||||
"""
|
||||
Load the module script for database, when any of the database node is
|
||||
initialized.
|
||||
"""
|
||||
return database.DatabaseModule.node_type
|
||||
|
||||
@property
|
||||
def node_inode(self):
|
||||
return False
|
||||
|
||||
|
||||
blueprint = OperatorModule(__name__)
|
||||
|
||||
|
||||
class OperatorView(PGChildNodeView):
|
||||
"""
|
||||
This class is responsible for generating routes for Operator node
|
||||
|
||||
Methods:
|
||||
-------
|
||||
* __init__(**kwargs)
|
||||
- Method is used to initialize the OperatorView and it's base view.
|
||||
|
||||
* check_precondition()
|
||||
- This function will behave as a decorator which will checks
|
||||
database connection before running view, it will also attaches
|
||||
manager,conn & template_path properties to self
|
||||
|
||||
* list()
|
||||
- This function is used to list all the Operator nodes within that
|
||||
collection.
|
||||
|
||||
* nodes()
|
||||
- This function will used to create all the child node within that
|
||||
collection, Here it will create all the Operator node.
|
||||
|
||||
* properties(gid, sid, did, scid, opid)
|
||||
- This function will show the properties of the selected Operator node
|
||||
|
||||
* sql(gid, sid, did, scid):
|
||||
- This function will generate sql to show it in sql pane for the
|
||||
selected Operator node.
|
||||
"""
|
||||
|
||||
node_type = blueprint.node_type
|
||||
node_label = "Operator"
|
||||
|
||||
parent_ids = [
|
||||
{'type': 'int', 'id': 'gid'},
|
||||
{'type': 'int', 'id': 'sid'},
|
||||
{'type': 'int', 'id': 'did'},
|
||||
{'type': 'int', 'id': 'scid'}
|
||||
]
|
||||
ids = [
|
||||
{'type': 'int', 'id': 'opid'}
|
||||
]
|
||||
|
||||
operations = dict({
|
||||
'obj': [
|
||||
{'get': 'properties', 'delete': 'delete', 'put': 'update'},
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}]
|
||||
})
|
||||
|
||||
def check_precondition(f):
|
||||
"""
|
||||
This function will behave as a decorator which will checks
|
||||
database connection before running view, it will also attaches
|
||||
manager,conn & template_path properties to self
|
||||
"""
|
||||
|
||||
@wraps(f)
|
||||
def wrap(*args, **kwargs):
|
||||
# Here args[0] will hold self & kwargs will hold gid,sid,did
|
||||
self = args[0]
|
||||
self.manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(
|
||||
kwargs['sid']
|
||||
)
|
||||
self.conn = self.manager.connection(did=kwargs['did'])
|
||||
self.datlastsysoid = \
|
||||
self.manager.db_info[kwargs['did']]['datlastsysoid'] \
|
||||
if self.manager.db_info is not None and \
|
||||
kwargs['did'] in self.manager.db_info else 0
|
||||
|
||||
self.datistemplate = False
|
||||
if (
|
||||
self.manager.db_info is not None and
|
||||
kwargs['did'] in self.manager.db_info and
|
||||
'datistemplate' in self.manager.db_info[kwargs['did']]
|
||||
):
|
||||
self.datistemplate = self.manager.db_info[
|
||||
kwargs['did']]['datistemplate']
|
||||
|
||||
# Set the template path for the SQL scripts
|
||||
self.template_path = compile_template_path(
|
||||
'operators/sql/',
|
||||
self.manager.server_type,
|
||||
self.manager.version
|
||||
)
|
||||
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return wrap
|
||||
|
||||
@check_precondition
|
||||
def list(self, gid, sid, did, scid):
|
||||
"""
|
||||
This function is used to list all the operator nodes within that
|
||||
collection.
|
||||
|
||||
Args:
|
||||
gid: Server group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
|
||||
Returns:
|
||||
JSON of available operator nodes
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._NODES_SQL]), scid=scid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
return ajax_response(
|
||||
response=res['rows'],
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def nodes(self, gid, sid, did, scid):
|
||||
"""
|
||||
This function will used to create all the child node within that
|
||||
collection.
|
||||
Here it will create all the operator node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
|
||||
Returns:
|
||||
JSON of available operator child nodes
|
||||
"""
|
||||
|
||||
res = []
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._NODES_SQL]), scid=scid)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
res.append(
|
||||
self.blueprint.generate_browser_node(
|
||||
row['oid'],
|
||||
scid,
|
||||
row['name'],
|
||||
icon="icon-operator"
|
||||
))
|
||||
|
||||
return make_json_response(
|
||||
data=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
@check_precondition
|
||||
def node(self, gid, sid, did, scid, opid):
|
||||
"""
|
||||
This function will fetch properties of the operator node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
opid: Operator ID
|
||||
|
||||
Returns:
|
||||
JSON of given operator node
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._NODES_SQL]), opid=opid)
|
||||
status, rset = self.conn.execute_2darray(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
for row in rset['rows']:
|
||||
return make_json_response(
|
||||
data=self.blueprint.generate_browser_node(
|
||||
row['oid'],
|
||||
scid,
|
||||
row['name'],
|
||||
icon="icon-operator"
|
||||
),
|
||||
status=200
|
||||
)
|
||||
|
||||
return gone(self.not_found_error_msg())
|
||||
|
||||
@check_precondition
|
||||
def properties(self, gid, sid, did, scid, opid):
|
||||
"""
|
||||
This function will show the properties of the selected operator node.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
scid: Schema ID
|
||||
opid: Operator ID
|
||||
|
||||
Returns:
|
||||
JSON of selected operator node
|
||||
"""
|
||||
|
||||
status, res = self._fetch_properties(scid, opid)
|
||||
if not status:
|
||||
return res
|
||||
|
||||
return ajax_response(
|
||||
response=res,
|
||||
status=200
|
||||
)
|
||||
|
||||
def _fetch_properties(self, scid, opid):
|
||||
"""
|
||||
This function fetch the properties for the specified object.
|
||||
|
||||
:param scid: Schema ID
|
||||
:param opid: Operator ID
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._PROPERTIES_SQL]),
|
||||
scid=scid, opid=opid,
|
||||
datlastsysoid=self.datlastsysoid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
|
||||
if not status:
|
||||
return False, internal_server_error(errormsg=res)
|
||||
|
||||
if len(res['rows']) == 0:
|
||||
return False, gone(self.not_found_error_msg())
|
||||
|
||||
res['rows'][0]['is_sys_obj'] = (
|
||||
res['rows'][0]['oid'] <= self.datlastsysoid or self.datistemplate)
|
||||
|
||||
return True, res['rows'][0]
|
||||
|
||||
@check_precondition
|
||||
def sql(self, gid, sid, did, scid, opid):
|
||||
"""
|
||||
This function will generates reverse engineered sql for operator
|
||||
object
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
opid: Operator ID
|
||||
json_resp: True then return json response
|
||||
"""
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._PROPERTIES_SQL]),
|
||||
scid=scid, opid=opid)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
if len(res['rows']) == 0:
|
||||
return gone(self.not_found_error_msg())
|
||||
|
||||
data = res['rows'][0]
|
||||
|
||||
SQL = render_template("/".join([self.template_path,
|
||||
self._CREATE_SQL]),
|
||||
data=data)
|
||||
|
||||
sql_header = "-- Operator: {0};\n\n-- ".format(data['name'])
|
||||
|
||||
sql_header += render_template("/".join([self.template_path,
|
||||
self._DELETE_SQL]),
|
||||
name=data['name'],
|
||||
oprnamespace=data['schema'],
|
||||
lefttype=data['lefttype'],
|
||||
righttype=data['righttype'],
|
||||
)
|
||||
SQL = sql_header + '\n' + SQL.strip('\n')
|
||||
|
||||
return ajax_response(response=SQL)
|
||||
|
||||
|
||||
OperatorView.register_node_view(blueprint)
|
||||
+1
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#d4e3f3;}.cls-2{fill:#6f6f6f;}</style></defs><polygon class="cls-1" points="2.15 7.15 2.15 4.65 4.65 4.65 4.65 2.15 7.15 2.15 7.15 7.15 2.15 7.15"/><path class="cls-2" d="M6.65,2.65v4h-4V5.15h2.5V2.65h1.5m1-1H4.15v2.5H1.65v3.5h6v-6Z"/><polygon class="cls-1" points="4.15 9.15 4.15 6.65 6.65 6.65 6.65 4.15 9.15 4.15 9.15 9.15 4.15 9.15"/><path class="cls-2" d="M8.65,4.65v4h-4V7.15h2.5V4.65h1.5m1-1H6.15v2.5H3.65v3.5h6v-6Z"/><polygon class="cls-1" points="8.85 13.85 8.85 11.35 6.35 11.35 6.35 8.85 8.85 8.85 8.85 6.35 11.35 6.35 11.35 8.85 13.85 8.85 13.85 11.35 11.35 11.35 11.35 13.85 8.85 13.85"/><path class="cls-2" d="M10.85,6.85v2.5h2.5v1.5h-2.5v2.5H9.35v-2.5H6.85V9.35h2.5V6.85h1.5m1-1H8.35v2.5H5.85v3.5h2.5v2.5h3.5v-2.5h2.5V8.35h-2.5V5.85Z"/></svg>
|
||||
|
After Width: | Height: | Size: 875 B |
+1
@@ -0,0 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#d4e3f3;stroke:#6f6f6f;stroke-miterlimit:10;}</style></defs><polygon class="cls-1" points="13 6.85 9.15 6.85 9.15 3 6.85 3 6.85 6.85 3 6.85 3 9.15 6.85 9.15 6.85 13 9.15 13 9.15 9.15 13 9.15 13 6.85"/></svg>
|
||||
|
After Width: | Height: | Size: 325 B |
+86
@@ -0,0 +1,86 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import OperatorSchema from './operator.ui';
|
||||
|
||||
define('pgadmin.node.operator', [
|
||||
'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'pgadmin.browser',
|
||||
'pgadmin.node.schema.dir/child', 'pgadmin.browser.collection',
|
||||
], function(gettext, url_for, $, _, pgAdmin, pgBrowser, schemaChild) {
|
||||
|
||||
if (!pgBrowser.Nodes['coll-operator']) {
|
||||
pgAdmin.Browser.Nodes['coll-operator'] =
|
||||
pgAdmin.Browser.Collection.extend({
|
||||
node: 'operator',
|
||||
label: gettext('Operators'),
|
||||
type: 'coll-operator',
|
||||
columns: ['name', 'owner', 'description'],
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
});
|
||||
}
|
||||
|
||||
if (!pgBrowser.Nodes['operator']) {
|
||||
pgAdmin.Browser.Nodes['operator'] = schemaChild.SchemaChildNode.extend({
|
||||
type: 'operator',
|
||||
sqlAlterHelp: 'sql-alteroperator.html',
|
||||
sqlCreateHelp: 'sql-createoperator.html',
|
||||
label: gettext('Operator'),
|
||||
collection_type: 'coll-operator',
|
||||
hasSQL: true,
|
||||
hasDepends: false,
|
||||
canDrop: false,
|
||||
canDropCascade: false,
|
||||
Init: function() {
|
||||
/* Avoid mulitple registration of menus */
|
||||
if (this.initialized)
|
||||
return;
|
||||
|
||||
this.initialized = true;
|
||||
},
|
||||
model: pgAdmin.Browser.Node.Model.extend({
|
||||
idAttribute: 'oid',
|
||||
|
||||
// Default values!
|
||||
initialize: function(attrs, args) {
|
||||
var isNew = (_.size(attrs) === 0);
|
||||
|
||||
if (isNew) {
|
||||
var userInfo = pgBrowser.serverInfo[args.node_info.server._id].user;
|
||||
var schemaInfo = args.node_info.schema;
|
||||
|
||||
this.set({'owner': userInfo.name}, {silent: true});
|
||||
this.set({'schema': schemaInfo._label}, {silent: true});
|
||||
}
|
||||
pgAdmin.Browser.Node.Model.prototype.initialize.apply(this, arguments);
|
||||
},
|
||||
|
||||
schema: [{
|
||||
id: 'name', label: gettext('Operator'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
},{
|
||||
id: 'owner', label: gettext('Owner'), cell: 'string',
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
control: 'node-list-by-name',
|
||||
node: 'role',
|
||||
},{
|
||||
id: 'description', label: gettext('Comment'), cell: 'string',
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
}
|
||||
],
|
||||
}),
|
||||
getSchema: ()=>{
|
||||
let schema = new OperatorSchema();
|
||||
return schema;
|
||||
}
|
||||
});
|
||||
}
|
||||
return pgBrowser.Nodes['operator'];
|
||||
});
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/////////////////////////////////////////////////////////////
|
||||
//
|
||||
// pgAdmin 4 - PostgreSQL Tools
|
||||
//
|
||||
// Copyright (C) 2013 - 2021, The pgAdmin Development Team
|
||||
// This software is released under the PostgreSQL Licence
|
||||
//
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
|
||||
import gettext from 'sources/gettext';
|
||||
|
||||
export default class OperatorSchema extends BaseUISchema {
|
||||
constructor(fieldOptions = {},initValues) {
|
||||
super({
|
||||
name: undefined,
|
||||
oid: undefined,
|
||||
owner: undefined,
|
||||
description: undefined,
|
||||
schema: null,
|
||||
lefttype: undefined,
|
||||
righttype: undefined,
|
||||
operproc:undefined,
|
||||
joinproc: undefined,
|
||||
restrproc: undefined,
|
||||
commutator: undefined,
|
||||
negator:undefined,
|
||||
support_hash: false,
|
||||
support_merge: false,
|
||||
...initValues
|
||||
});
|
||||
this.fieldOptions = fieldOptions;
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
return [
|
||||
{
|
||||
id: 'name', label: gettext('Name'), type: 'tel',
|
||||
readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'oid', label: gettext('OID'),
|
||||
type: 'text', mode: ['properties']
|
||||
},
|
||||
{
|
||||
id: 'owner', label: gettext('Owner'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'schema', label: gettext('Schema'),
|
||||
mode: ['create', 'edit'],
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'is_sys_obj', label: gettext('System operator?'),
|
||||
cell: 'boolean', type: 'switch', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'description', label: gettext('Comment'),
|
||||
type: 'multiline', mode: ['properties', 'create', 'edit'],
|
||||
readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'lefttype', label: gettext('Left type'),
|
||||
group: gettext('Definition'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'righttype', label: gettext('Right type'),
|
||||
group: gettext('Definition'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'resulttype', label: gettext('Result type'),
|
||||
group: gettext('Definition'),
|
||||
type: 'text', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'oprkind', label: gettext('Kind'),
|
||||
group: gettext('Definition'),
|
||||
type: 'text', mode: ['properties'],
|
||||
},
|
||||
{
|
||||
id: 'operproc', label: gettext('Operator function'),
|
||||
group: gettext('Definition'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'restrproc', label: gettext('Restrict function'),
|
||||
group: gettext('Implementation'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'joinproc', label: gettext('Join function'),
|
||||
group: gettext('Implementation'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'commutator', label: gettext('Commutator'),
|
||||
group: gettext('Implementation'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'negator', label: gettext('Negator'),
|
||||
group: gettext('Implementation'),
|
||||
type: 'text', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'support_hash', label: gettext('Supports hash'),
|
||||
group: gettext('Implementation'),
|
||||
cell: 'boolean', type: 'switch', readonly: true,
|
||||
},
|
||||
{
|
||||
id: 'support_merge', label: gettext('Supports merge'),
|
||||
group: gettext('Implementation'),
|
||||
cell: 'boolean', type: 'switch', readonly: true,
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{% if data %}
|
||||
CREATE OPERATOR {{data.schema}}.{{data.name}} (
|
||||
FUNCTION = {{data.operproc}}{% if data.lefttype %},
|
||||
LEFTARG = {{data.lefttype}}{% endif %}{% if data.righttype %},
|
||||
RIGHTARG = {{data.righttype}}{% endif %}{% if data.commutator %},
|
||||
COMMUTATOR = {{data.commutator}}{% endif %}{% if data.negator %},
|
||||
NEGATOR = {{data.negator}}{% endif %}{% if data.restrproc %},
|
||||
RESTRICT = {{data.restrproc}}{% endif %}{% if data.joinproc %},
|
||||
JOIN = {{data.joinproc}}{% endif %}{% if data.support_hash %},
|
||||
HASHES{% endif %}{% if data.support_merge %}, MERGES{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{% if data %}
|
||||
CREATE OPERATOR {{data.schema}}.{{data.name}} (
|
||||
PROCEDURE = {{data.operproc}}{% if data.lefttype %},
|
||||
LEFTARG = {{data.lefttype}}{% endif %}{% if data.righttype %},
|
||||
RIGHTARG = {{data.righttype}}{% endif %}{% if data.commutator %},
|
||||
COMMUTATOR = {{data.commutator}}{% endif %}{% if data.negator %},
|
||||
NEGATOR = {{data.negator}}{% endif %}{% if data.restrproc %},
|
||||
RESTRICT = {{data.restrproc}}{% endif %}{% if data.joinproc %},
|
||||
JOIN = {{data.joinproc}}{% endif %}{% if data.support_hash %},
|
||||
HASHES{% endif %}{% if data.support_merge %}, MERGES{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{% if lefttype %}
|
||||
{% set ltype = lefttype %}
|
||||
{% else %}
|
||||
{% set ltype = none %}
|
||||
{% endif %}
|
||||
{% if righttype %}
|
||||
{% set rtype = righttype %}
|
||||
{% else %}
|
||||
{% set rtype = none %}
|
||||
{% endif %}
|
||||
{% if name %}
|
||||
DROP OPERATOR IF EXISTS {{conn|qtIdent(oprnamespace)}}.{{name}} ({{ltype}} , {{rtype}}){% if cascade %} CASCADE{% endif %};
|
||||
{% endif %}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
SELECT op.oid, pg_catalog.pg_get_userbyid(op.oprowner) as owner,
|
||||
CASE WHEN lt.typname IS NOT NULL AND rt.typname IS NOT NULL THEN
|
||||
op.oprname || ' (' || pg_catalog.format_type(lt.oid, NULL) || ', ' || pg_catalog.format_type(rt.oid, NULL) || ')'
|
||||
WHEN lt.typname IS NULL AND rt.typname IS NOT NULL THEN
|
||||
op.oprname || ' (' || pg_catalog.format_type(rt.oid, NULL) || ')'
|
||||
WHEN lt.typname IS NOT NULL AND rt.typname IS NULL THEN
|
||||
op.oprname || ' (' || pg_catalog.format_type(lt.oid, NULL) || ')'
|
||||
ELSE op.oprname || '()'
|
||||
END as name,
|
||||
lt.typname as lefttype, rt.typname as righttype
|
||||
FROM pg_catalog.pg_operator op
|
||||
LEFT OUTER JOIN pg_catalog.pg_type lt ON lt.oid=op.oprleft
|
||||
LEFT OUTER JOIN pg_catalog.pg_type rt ON rt.oid=op.oprright
|
||||
JOIN pg_catalog.pg_type et on et.oid=op.oprresult
|
||||
LEFT OUTER JOIN pg_catalog.pg_operator co ON co.oid=op.oprcom
|
||||
LEFT OUTER JOIN pg_catalog.pg_operator ne ON ne.oid=op.oprnegate
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=op.oid AND des.classoid='pg_operator'::regclass)
|
||||
{% if scid %}
|
||||
WHERE op.oprnamespace = {{scid}}::oid
|
||||
{% elif opid %}
|
||||
WHERE op.oid = {{opid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY op.oprname;
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
SELECT op.oid, op.oprname as name, ns.nspname as schema,
|
||||
pg_catalog.pg_get_userbyid(op.oprowner) as owner,
|
||||
op.oprcanhash as support_hash, op.oprcanmerge as support_merge,
|
||||
ns.nspname as schema,
|
||||
CASE WHEN op.oprkind = 'b' THEN 'infix'
|
||||
WHEN op.oprkind = 'l' THEN 'prefix'
|
||||
WHEN op.oprkind = 'r' THEN 'postfix'
|
||||
ELSE 'unknown' END as oprkind, et.typname as resulttype,
|
||||
pg_catalog.format_type(lt.oid, NULL) as lefttype,
|
||||
pg_catalog.format_type(rt.oid, NULL) as righttype,
|
||||
co.oprname as commutator, op.oprcode as operproc,
|
||||
ne.oprname as negator, description,
|
||||
CASE WHEN op.oprrest = '-'::regproc THEN null ELSE op.oprrest END as restrproc,
|
||||
CASE WHEN op.oprjoin = '-'::regproc THEN null ELSE op.oprjoin END as joinproc
|
||||
FROM pg_catalog.pg_operator op
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=op.oprnamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_type lt ON lt.oid=op.oprleft
|
||||
LEFT OUTER JOIN pg_catalog.pg_type rt ON rt.oid=op.oprright
|
||||
JOIN pg_catalog.pg_type et on et.oid=op.oprresult
|
||||
LEFT OUTER JOIN pg_catalog.pg_operator co ON co.oid=op.oprcom
|
||||
LEFT OUTER JOIN pg_catalog.pg_operator ne ON ne.oid=op.oprnegate
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=op.oid AND des.classoid='pg_operator'::regclass)
|
||||
WHERE op.oprnamespace = {{scid}}::oid
|
||||
{% if opid %} AND op.oid = {{opid}}::oid {% endif %}
|
||||
ORDER BY op.oprname;
|
||||
@@ -29,6 +29,7 @@ from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
|
||||
columns import utils as column_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
|
||||
constraints.exclusion_constraint import utils as exclusion_utils
|
||||
from pgadmin.utils.exception import ExecuteError
|
||||
|
||||
|
||||
class TableModule(SchemaChildModule):
|
||||
@@ -318,19 +319,19 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
|
||||
|
||||
def get_icon_css_class(self, table_info, default_val='icon-table'):
|
||||
if ('is_inherits' in table_info and
|
||||
table_info['is_inherits'] == '1') or \
|
||||
table_info['is_inherits'] > '0') or \
|
||||
('coll_inherits' in table_info and
|
||||
len(table_info['coll_inherits']) > 0):
|
||||
|
||||
if ('is_inherited' in table_info and
|
||||
table_info['is_inherited'] == '1')\
|
||||
table_info['is_inherited'] > '0')\
|
||||
or ('relhassubclass' in table_info and
|
||||
table_info['relhassubclass']):
|
||||
default_val = 'icon-table-multi-inherit'
|
||||
else:
|
||||
default_val = 'icon-table-inherits'
|
||||
elif ('is_inherited' in table_info and
|
||||
table_info['is_inherited'] == '1')\
|
||||
table_info['is_inherited'] > '0')\
|
||||
or ('relhassubclass' in table_info and
|
||||
table_info['relhassubclass']):
|
||||
default_val = 'icon-table-inherited'
|
||||
@@ -1024,6 +1025,11 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
|
||||
if not status:
|
||||
return res
|
||||
|
||||
lock_on_table = self.get_table_locks(did, res['rows'][0])
|
||||
if lock_on_table != '':
|
||||
return ExecuteError(
|
||||
error_msg=str(lock_on_table.json['info']))
|
||||
|
||||
return super(TableView, self).update(
|
||||
gid, sid, did, scid, tid, data=data, res=res)
|
||||
except Exception as e:
|
||||
@@ -1070,6 +1076,10 @@ class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare):
|
||||
)
|
||||
)
|
||||
|
||||
lock_on_table = self.get_table_locks(did, res['rows'][0])
|
||||
if lock_on_table != '':
|
||||
return lock_on_table
|
||||
|
||||
status, res = super(TableView, self).delete(gid, sid, did,
|
||||
scid, tid, res)
|
||||
|
||||
|
||||
@@ -99,6 +99,9 @@ def get_column_details(conn, idx, data, mode='properties', template_path=None):
|
||||
"/".join([template_path, 'column_details.sql']), idx=idx
|
||||
)
|
||||
status, rset = conn.execute_2darray(SQL)
|
||||
# Remove column if duplicate column is present in list.
|
||||
rset['rows'] = [i for n, i in enumerate(rset['rows']) if
|
||||
i not in rset['rows'][n + 1:]]
|
||||
if not status:
|
||||
return internal_server_error(errormsg=rset)
|
||||
|
||||
|
||||
+2
-2
@@ -115,12 +115,12 @@ define('pgadmin.node.rule', [
|
||||
{
|
||||
name: 'enable_rule', node: 'rule', module: this,
|
||||
applies: ['object', 'context'], callback: 'enable_rule',
|
||||
category: 'connect', priority: 3, label: gettext('Enable rule'),
|
||||
category: 'connect', priority: 3, label: gettext('Enable'),
|
||||
icon: 'fa fa-check', enable: 'canCreate_with_rule_enable',
|
||||
},{
|
||||
name: 'disable_rule', node: 'rule', module: this,
|
||||
applies: ['object', 'context'], callback: 'disable_rule',
|
||||
category: 'drop', priority: 3, label: gettext('Disable rule'),
|
||||
category: 'drop', priority: 3, label: gettext('Disable'),
|
||||
icon: 'fa fa-times', enable: 'canCreate_with_rule_disable'
|
||||
}
|
||||
]);
|
||||
|
||||
@@ -205,6 +205,9 @@ define('pgadmin.node.table', [
|
||||
t.select(i);
|
||||
}, 10);
|
||||
}
|
||||
if (res.success == 2) {
|
||||
Alertify.error(res.info, 0);
|
||||
}
|
||||
})
|
||||
.fail(function(xhr, status, error) {
|
||||
Alertify.pgRespErrorNotify(xhr, error);
|
||||
|
||||
+18
-1
@@ -537,7 +537,24 @@ export default class TableSchema extends BaseUISchema {
|
||||
tabColsResponse.then((res)=>{
|
||||
resolve((state)=>{
|
||||
let finalCols = res.map((col)=>obj.columnsSchema.getNewData(col));
|
||||
finalCols = [...state.columns, ...finalCols];
|
||||
let currentSelectedCols = [];
|
||||
if (!_.isEmpty(state.columns)){
|
||||
currentSelectedCols = state.columns;
|
||||
}
|
||||
let colNameList = [];
|
||||
state.columns.forEach((col=>{
|
||||
colNameList.push(col.name);
|
||||
}));
|
||||
for (let col of Object.values(finalCols)) {
|
||||
if(!colNameList.includes(col.name)){
|
||||
currentSelectedCols.push(col);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_.isEmpty(currentSelectedCols)){
|
||||
finalCols = currentSelectedCols;
|
||||
}
|
||||
|
||||
obj.changeColumnOptions(finalCols);
|
||||
return {
|
||||
adding_inherit_cols: false,
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@
|
||||
{% set empty_bracket = "\n(\n)"%}
|
||||
{% endif %}
|
||||
{% set with_clause = false%}
|
||||
{% if data.fillfactor or data.parallel_workers or data.toast_tuple_target or data.autovacuum_custom or data.autovacuum_enabled in ('t', 'f') or data.toast_autovacuum or data.toast_autovacuum_enabled in ('t', 'f') %}
|
||||
{% if data.fillfactor or data.parallel_workers or data.toast_tuple_target or (data.autovacuum_custom and data.add_vacuum_settings_in_sql) or data.autovacuum_enabled in ('t', 'f') or (data.toast_autovacuum and data.add_vacuum_settings_in_sql) or data.toast_autovacuum_enabled in ('t', 'f') %}
|
||||
{% set with_clause = true%}
|
||||
{% endif %}
|
||||
CREATE {% if data.relpersistence %}UNLOGGED {% endif %}TABLE{% if add_not_exists_clause %} IF NOT EXISTS{% endif %} {{conn|qtIdent(data.schema, data.name)}}{{empty_bracket}}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
SELECT
|
||||
usename,
|
||||
application_name
|
||||
FROM
|
||||
pg_catalog.pg_stat_activity
|
||||
WHERE
|
||||
pid = {{ pid }}
|
||||
ORDER BY pid
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
SELECT
|
||||
pid,
|
||||
locktype,
|
||||
datname,
|
||||
relation::regclass,
|
||||
page,
|
||||
tuple,
|
||||
virtualxid
|
||||
transactionid,
|
||||
classid::regclass,
|
||||
objid,
|
||||
objsubid,
|
||||
virtualtransaction,
|
||||
mode,
|
||||
granted,
|
||||
fastpath
|
||||
FROM
|
||||
pg_catalog.pg_locks l
|
||||
LEFT OUTER JOIN pg_catalog.pg_database d ON (l.database = d.oid)
|
||||
{% if did %}WHERE
|
||||
datname = (SELECT datname FROM pg_catalog.pg_database WHERE oid = {{ did }}){% endif %}
|
||||
ORDER BY
|
||||
pid, locktype
|
||||
+2
-2
@@ -79,12 +79,12 @@ define('pgadmin.node.trigger', [
|
||||
},{
|
||||
name: 'enable_trigger', node: 'trigger', module: this,
|
||||
applies: ['object', 'context'], callback: 'enable_trigger',
|
||||
category: 'connect', priority: 3, label: gettext('Enable trigger'),
|
||||
category: 'connect', priority: 3, label: gettext('Enable'),
|
||||
icon: 'fa fa-check', enable : 'canCreate_with_trigger_enable',
|
||||
},{
|
||||
name: 'disable_trigger', node: 'trigger', module: this,
|
||||
applies: ['object', 'context'], callback: 'disable_trigger',
|
||||
category: 'drop', priority: 3, label: gettext('Disable trigger'),
|
||||
category: 'drop', priority: 3, label: gettext('Disable'),
|
||||
icon: 'fa fa-times', enable : 'canCreate_with_trigger_disable',
|
||||
},{
|
||||
name: 'create_trigger_onView', node: 'view', module: this,
|
||||
|
||||
@@ -49,6 +49,7 @@ from pgadmin.utils.preferences import Preferences
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.utils \
|
||||
import VacuumSettings
|
||||
from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
|
||||
from pgadmin.dashboard import locks
|
||||
|
||||
|
||||
class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
|
||||
@@ -1952,6 +1953,10 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
|
||||
|
||||
data = res['rows'][0]
|
||||
|
||||
lock_on_table = self.get_table_locks(did, data)
|
||||
if lock_on_table != '':
|
||||
return lock_on_table
|
||||
|
||||
sql = render_template("/".join([self.table_template_path,
|
||||
'truncate.sql']),
|
||||
data=data, cascade=is_cascade,
|
||||
@@ -2004,6 +2009,41 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
|
||||
'scid': scid
|
||||
}
|
||||
|
||||
def get_table_locks(self, did, data):
|
||||
"""
|
||||
This function returns the lock details if there is any on table
|
||||
:param did:
|
||||
:param data:
|
||||
:return:
|
||||
"""
|
||||
sql = render_template(
|
||||
"/".join([self.table_template_path, 'locks.sql']), did=did
|
||||
)
|
||||
status, lock_table_result = self.conn.execute_dict(sql)
|
||||
|
||||
for row in lock_table_result['rows']:
|
||||
if row['relation'].strip('\"') == data['name']:
|
||||
|
||||
sql = render_template(
|
||||
"/".join([self.table_template_path,
|
||||
'get_application_name.sql']), pid=row['pid']
|
||||
)
|
||||
status, res = self.conn.execute_dict(sql)
|
||||
|
||||
application_name = res['rows'][0]['application_name']
|
||||
|
||||
return make_json_response(
|
||||
success=2,
|
||||
info=gettext(
|
||||
"The table is currently locked and the "
|
||||
"operation cannot be completed. "
|
||||
"Please try again later. "
|
||||
"\r\nBlocking Process ID : {0} "
|
||||
"Application Name : {1}").format(row['pid'],
|
||||
application_name)
|
||||
)
|
||||
return ''
|
||||
|
||||
def get_schema_and_table_name(self, tid):
|
||||
"""
|
||||
This function will fetch the schema qualified name of the
|
||||
@@ -2056,8 +2096,18 @@ class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings):
|
||||
if data is None:
|
||||
if vacuum_key in old_data:
|
||||
for opt in old_data[vacuum_key]:
|
||||
if 'value' in opt and opt['value'] is None:
|
||||
if 'add_vacuum_settings_in_sql' not in old_data:
|
||||
old_data['add_vacuum_settings_in_sql'] = False
|
||||
|
||||
if ('value' in opt and opt['value'] is None) or \
|
||||
('value' in opt and opt['value'] == ''):
|
||||
opt.pop('value')
|
||||
|
||||
if 'value' in opt and 'add_vacuum_settings_in_sql' in \
|
||||
old_data and not \
|
||||
old_data['add_vacuum_settings_in_sql']:
|
||||
old_data['add_vacuum_settings_in_sql'] = True
|
||||
|
||||
# Iterate vacuum table
|
||||
elif vacuum_key in data and 'changed' in data[vacuum_key] \
|
||||
and vacuum_key in old_data:
|
||||
|
||||
@@ -16,7 +16,8 @@ _default_database_response = [
|
||||
{
|
||||
'typname': 'type name',
|
||||
'elemoid': 1560,
|
||||
'is_collatable': True
|
||||
'is_collatable': True,
|
||||
'oid': 16635
|
||||
}
|
||||
]
|
||||
_default_expected_function_output = [
|
||||
@@ -28,7 +29,8 @@ _default_expected_function_output = [
|
||||
'length': True,
|
||||
'min_val': 1,
|
||||
'max_val': 2147483647,
|
||||
'is_collatable': True
|
||||
'is_collatable': True,
|
||||
'oid': 16635
|
||||
}
|
||||
]
|
||||
_default_manager = dict(
|
||||
|
||||
@@ -182,7 +182,8 @@ class DataTypeReader:
|
||||
'label': row['typname'], 'value': row['typname'],
|
||||
'typval': typeval, 'precision': precision,
|
||||
'length': length, 'min_val': min_val, 'max_val': max_val,
|
||||
'is_collatable': row['is_collatable']
|
||||
'is_collatable': row['is_collatable'],
|
||||
'oid': row['oid']
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -129,7 +129,7 @@ define('pgadmin.node.role', [
|
||||
|
||||
var tree = pgBrowser.tree,
|
||||
_i = tree.selected(),
|
||||
_d = _i && _i.length == 1 ? tree.itemData(_i) : undefined,
|
||||
_d = _i ? tree.itemData(_i) : undefined,
|
||||
obj = this, finalUrl, old_role_name;
|
||||
|
||||
//RoleReassign Model (Objects like role, database)
|
||||
@@ -435,7 +435,7 @@ define('pgadmin.node.role', [
|
||||
// Find current/selected node
|
||||
var tree = pgBrowser.tree,
|
||||
_i = tree.selected(),
|
||||
_d = _i && _i.length == 1 ? tree.itemData(_i) : undefined,
|
||||
_d = _i ? tree.itemData(_i) : undefined,
|
||||
node = _d && pgBrowser.Nodes[_d._type];
|
||||
|
||||
finalUrl = obj.generate_url(_i, 'reassign' , _d, true);
|
||||
|
||||
@@ -202,7 +202,9 @@
|
||||
"expected_data": {
|
||||
"status_code": 200,
|
||||
"error_msg": null,
|
||||
"test_result_data": {}
|
||||
"test_result_data": {
|
||||
"result": "REASSIGN OWNED BY role_user_1 TO CURRENT_ROLE"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -813,14 +813,12 @@ define('pgadmin.node.server', [
|
||||
|
||||
var connect_to_server = function(obj, data, tree, item, reconnect) {
|
||||
// Open properties dialog in edit mode
|
||||
const selectedTreeNode = tree.selected().length > 0 ? tree.selected() : tree.first();
|
||||
const selectedTreeNodeData = selectedTreeNode && selectedTreeNode.length === 1 ? tree.itemData(selectedTreeNode) : undefined;
|
||||
var server_url = obj.generate_url(item, 'obj', data, true);
|
||||
// Fetch the updated data
|
||||
$.get(server_url)
|
||||
.done(function(res) {
|
||||
if (res.shared && _.isNull(res.username) && data.user_id != current_user.id){
|
||||
if (selectedTreeNodeData._type == 'server' && !res.service){
|
||||
if (!res.service){
|
||||
pgAdmin.Browser.Node.callbacks.show_obj_properties.call(
|
||||
pgAdmin.Browser.Nodes[tree.itemData(item)._type], {action: 'edit'}
|
||||
);
|
||||
|
||||
@@ -143,7 +143,7 @@ export default class ServerSchema extends BaseUISchema {
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
readonly: function(state){
|
||||
var serverOwner = obj.userId;
|
||||
if (obj.isNew(state) && serverOwner != current_user.id) {
|
||||
if (!obj.isNew(state) && serverOwner != current_user.id) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -102,11 +102,18 @@ class ServerType(object):
|
||||
bin_paths_server_based = \
|
||||
copy.deepcopy(BINARY_PATHS['as_bin_paths'])
|
||||
|
||||
bin_path_dict = \
|
||||
{item['version']: item for item in bin_paths_server_based}
|
||||
old_path_dict = \
|
||||
{item['version']: item for item in json.loads(old_path)}
|
||||
|
||||
for item in bin_path_dict:
|
||||
bin_path_dict[item].update(old_path_dict.get(item, {}))
|
||||
|
||||
bin_paths_server_based = list(bin_path_dict.values())
|
||||
if not ServerType.is_binary_path_of_type_json(old_path):
|
||||
set_binary_path(old_path, bin_paths_server_based,
|
||||
key, set_as_default=True)
|
||||
else:
|
||||
bin_paths_server_based = json.loads(old_path)
|
||||
|
||||
# Set the DEFAULT_BINARY_PATHS if any
|
||||
ServerType.set_default_binary_path(bin_paths_server_based, key)
|
||||
|
||||
@@ -430,7 +430,7 @@ define('pgadmin.browser', [
|
||||
|
||||
// Stored layout in database from the previous session
|
||||
var layout = pgBrowser.utils.layout;
|
||||
obj.restore_layout(obj.docker, layout, obj.buildDefaultLayout.bind(obj));
|
||||
obj.restore_layout(obj.docker, layout, obj.buildDefaultLayout.bind(obj), true);
|
||||
|
||||
obj.docker.on(wcDocker.EVENT.LAYOUT_CHANGED, function() {
|
||||
obj.save_current_layout('Browser/Layout', obj.docker);
|
||||
@@ -440,14 +440,16 @@ define('pgadmin.browser', [
|
||||
initializeBrowserTree(obj);
|
||||
|
||||
// Syntax highlight the SQL Pane
|
||||
obj.editor = CodeMirror.fromTextArea(
|
||||
document.getElementById('sql-textarea'), {
|
||||
lineNumbers: true,
|
||||
mode: 'text/x-pgsql',
|
||||
readOnly: true,
|
||||
extraKeys: pgAdmin.Browser.editor_shortcut_keys,
|
||||
screenReaderLabel: gettext('SQL'),
|
||||
});
|
||||
if(document.getElementById('sql-textarea')){
|
||||
obj.editor = CodeMirror.fromTextArea(
|
||||
document.getElementById('sql-textarea'), {
|
||||
lineNumbers: true,
|
||||
mode: 'text/x-pgsql',
|
||||
readOnly: true,
|
||||
extraKeys: pgAdmin.Browser.editor_shortcut_keys,
|
||||
screenReaderLabel: gettext('SQL'),
|
||||
});
|
||||
}
|
||||
/* Cache may take time to load for the first time
|
||||
* Reflect the changes once cache is available
|
||||
*/
|
||||
@@ -465,8 +467,8 @@ define('pgadmin.browser', [
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
obj.editor.setValue('-- ' + select_object_msg);
|
||||
obj.editor.refresh();
|
||||
obj?.editor?.setValue('-- ' + select_object_msg);
|
||||
obj?.editor?.refresh();
|
||||
}, 10);
|
||||
|
||||
// Build the treeview context menu
|
||||
@@ -1086,11 +1088,13 @@ define('pgadmin.browser', [
|
||||
};
|
||||
|
||||
if (binarySearch()) {
|
||||
__ctx.t.before(i, _data).then(() => {
|
||||
__ctx.t.before(i, _data).then((_item) => {
|
||||
if (
|
||||
__ctx.o && __ctx.o.success && typeof(__ctx.o.success) == 'function'
|
||||
) {
|
||||
__ctx.o.success.apply(__ctx.t, [i, _data]);
|
||||
} else {
|
||||
__ctx.t.select(_item);
|
||||
}
|
||||
}, () => {
|
||||
console.warn('Failed to add before...', arguments);
|
||||
@@ -1437,6 +1441,7 @@ define('pgadmin.browser', [
|
||||
'_label': this.new._label,
|
||||
'label': this.new.label,
|
||||
});
|
||||
this.t.update(ctx.i, this.new);
|
||||
this.t.setLabel(ctx.i, {label: this.new.label});
|
||||
this.t.addIcon(ctx.i, {icon: this.new.icon});
|
||||
this.t.setId(ctx.i, {id: this.new.id});
|
||||
|
||||
@@ -45,7 +45,7 @@ define([
|
||||
pgAdmin.Browser.add_menus([{
|
||||
name: 'refresh', node: this.type, module: this,
|
||||
applies: ['object', 'context'], callback: 'refresh',
|
||||
priority: 1, label: gettext('Refresh...'),
|
||||
priority: 1, label: gettext('Refresh'),
|
||||
icon: 'fa fa-sync-alt',
|
||||
}]);
|
||||
|
||||
|
||||
@@ -56,11 +56,23 @@ _.extend(pgBrowser, {
|
||||
}
|
||||
},
|
||||
|
||||
restore_layout: function(docker, layout, defaultLayoutCallback) {
|
||||
restore_layout: function(docker, layout, defaultLayoutCallback, checkLayout= false) {
|
||||
// Try to restore the layout if there is one
|
||||
if (layout != '') {
|
||||
try {
|
||||
docker.restore(layout);
|
||||
if(checkLayout) {
|
||||
// Check restore layout is restored pgAdmin 4 layout successfully if not then reset layout to default pgAdmin 4 layout.
|
||||
var _panel = docker.findPanels('properties');
|
||||
if(_panel.length == 0 && defaultLayoutCallback){
|
||||
// clear the wcDocker before reset layout.
|
||||
docker.clear();
|
||||
Alertify.info(gettext('pgAdmin has detected some issues with the UI layout, so reset it to the default.'), 0);
|
||||
if(defaultLayoutCallback){
|
||||
defaultLayoutCallback(docker);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(err) {
|
||||
docker.clear();
|
||||
@@ -100,7 +112,10 @@ _.extend(pgBrowser, {
|
||||
},
|
||||
|
||||
lock_layout: function(docker, op) {
|
||||
let menu_items = this.menus['file']['mnu_locklayout']['menu_items'];
|
||||
let menu_items = [];
|
||||
if('mnu_locklayout' in this.menus['file']) {
|
||||
menu_items = this.menus['file']['mnu_locklayout']['menu_items'];
|
||||
}
|
||||
|
||||
switch(op) {
|
||||
case this.lock_layout_levels.PREVENT_DOCKING:
|
||||
@@ -114,13 +129,15 @@ _.extend(pgBrowser, {
|
||||
break;
|
||||
}
|
||||
|
||||
_.each(menu_items, function(menu_item) {
|
||||
if(menu_item.name != ('mnu_lock_'+op)) {
|
||||
menu_item.change_checked(false);
|
||||
} else {
|
||||
menu_item.change_checked(true);
|
||||
}
|
||||
});
|
||||
if(menu_items) {
|
||||
_.each(menu_items, function(menu_item) {
|
||||
if(menu_item.name != ('mnu_lock_'+op)) {
|
||||
menu_item.change_checked(false);
|
||||
} else {
|
||||
menu_item.change_checked(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
save_lock_layout: function(op) {
|
||||
|
||||
@@ -118,7 +118,7 @@ define('pgadmin.browser.node', [
|
||||
applies: ['object', 'context'],
|
||||
callback: 'refresh',
|
||||
priority: 1,
|
||||
label: gettext('Refresh...'),
|
||||
label: gettext('Refresh'),
|
||||
icon: 'fa fa-sync-alt',
|
||||
}]);
|
||||
|
||||
@@ -838,6 +838,10 @@ define('pgadmin.browser.node', [
|
||||
type: 'DELETE',
|
||||
})
|
||||
.done(function(res) {
|
||||
if(res.success == 2){
|
||||
Alertify.error(res.info, 0);
|
||||
return;
|
||||
}
|
||||
if (res.success == 0) {
|
||||
pgBrowser.report_error(res.errormsg, res.info);
|
||||
} else {
|
||||
@@ -867,7 +871,6 @@ define('pgadmin.browser.node', [
|
||||
}
|
||||
pgBrowser.report_error(
|
||||
gettext('Error dropping/removing %s: "%s"', obj.label, objName), errmsg);
|
||||
|
||||
});
|
||||
},
|
||||
null
|
||||
|
||||
@@ -124,14 +124,14 @@ _.extend(pgBrowser, {
|
||||
if(module === 'sqleditor' || module === null || typeof module === 'undefined') {
|
||||
let sqlEditPreferences = obj.get_preferences_for_module('sqleditor');
|
||||
|
||||
$(obj.editor.getWrapperElement()).css(
|
||||
$(obj?.editor?.getWrapperElement()).css(
|
||||
'font-size',SqlEditorUtils.calcFontSize(sqlEditPreferences.sql_font_size)
|
||||
);
|
||||
obj.editor.setOption('tabSize', sqlEditPreferences.tab_size);
|
||||
obj.editor.setOption('lineWrapping', sqlEditPreferences.wrap_code);
|
||||
obj.editor.setOption('autoCloseBrackets', sqlEditPreferences.insert_pair_brackets);
|
||||
obj.editor.setOption('matchBrackets', sqlEditPreferences.brace_matching);
|
||||
obj.editor.refresh();
|
||||
obj?.editor?.setOption('tabSize', sqlEditPreferences.tab_size);
|
||||
obj?.editor?.setOption('lineWrapping', sqlEditPreferences.wrap_code);
|
||||
obj?.editor?.setOption('autoCloseBrackets', sqlEditPreferences.insert_pair_brackets);
|
||||
obj?.editor?.setOption('matchBrackets', sqlEditPreferences.brace_matching);
|
||||
obj?.editor?.refresh();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class BrowserToolBarFeatureTest(BaseFeatureTest):
|
||||
file=sys.stderr, end="")
|
||||
self.test_view_data_tool_button()
|
||||
print("OK.", file=sys.stderr)
|
||||
#
|
||||
|
||||
# Check for filtered rows button
|
||||
print("\nFiltered Rows ToolBar Button ",
|
||||
file=sys.stderr, end="")
|
||||
@@ -60,28 +60,24 @@ class BrowserToolBarFeatureTest(BaseFeatureTest):
|
||||
self.test_table_name)
|
||||
|
||||
def test_query_tool_button(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Servers", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
self.assertTrue(self.page.retry_click(
|
||||
(By.CSS_SELECTOR,
|
||||
BrowserToolBarLocators.open_query_tool_button_css),
|
||||
(By.CSS_SELECTOR, BrowserToolBarLocators.query_tool_panel_css)),
|
||||
'Query tool did not open on clicking Query Tool button.')
|
||||
self.page.close_query_tool(prompt=False)
|
||||
|
||||
def test_view_data_tool_button(self):
|
||||
self.page.click_a_tree_node(
|
||||
self.test_db,
|
||||
TreeAreaLocators.sub_nodes_of_databases_node(self.server['name']))
|
||||
self.page.toggle_open_schema_node(
|
||||
self.server['name'], self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.toggle_open_tables_node(
|
||||
self.server['name'], self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.click_a_tree_node(
|
||||
self.test_table_name,
|
||||
TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
self.page.expand_tables_node("Servers", self.server['name'],
|
||||
self.server['db_password'], self.test_db,
|
||||
"public")
|
||||
|
||||
table_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.table_node(self.test_table_name))
|
||||
table_node.click()
|
||||
|
||||
self.assertTrue(self.page.retry_click(
|
||||
(By.CSS_SELECTOR,
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
##########################################################################
|
||||
|
||||
import random
|
||||
import time
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.common.by import By
|
||||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
from regression.feature_utils.locators import QueryToolLocators
|
||||
@@ -37,9 +39,9 @@ class CopySelectedQueryResultsFeatureTest(BaseFeatureTest):
|
||||
self.server, self.test_db, self.test_table_name)
|
||||
|
||||
def runTest(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Servers", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
self.page.open_query_tool()
|
||||
|
||||
self.page.fill_codemirror_area_with(
|
||||
@@ -60,8 +62,8 @@ class CopySelectedQueryResultsFeatureTest(BaseFeatureTest):
|
||||
|
||||
def paste_values_to_scratch_pad(self):
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(
|
||||
self.page.driver.find_element_by_tag_name("iframe"))
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element(By.TAG_NAME, "iframe"))
|
||||
scratch_pad_ele = self.page.find_by_css_selector(
|
||||
QueryToolLocators.scratch_pad_css)
|
||||
self.page.paste_values(scratch_pad_ele)
|
||||
|
||||
@@ -67,9 +67,9 @@ class CheckFileManagerFeatureTest(BaseFeatureTest):
|
||||
print("OK.", file=sys.stderr)
|
||||
|
||||
def _navigate_to_query_tool(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
self.page.open_query_tool()
|
||||
|
||||
def _create_new_file(self):
|
||||
|
||||
@@ -133,7 +133,7 @@ class KeyboardShortcutFeatureTest(BaseFeatureTest):
|
||||
"and contains(.,'" + locator + "')]"
|
||||
)
|
||||
|
||||
field = file_menu.find_element_by_name('key')
|
||||
field = file_menu.find_element(By.NAME, 'key')
|
||||
field.click()
|
||||
field.send_keys(key)
|
||||
|
||||
@@ -141,5 +141,5 @@ class KeyboardShortcutFeatureTest(BaseFeatureTest):
|
||||
self.page.click_modal('Save')
|
||||
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(".ajs-modal")
|
||||
lambda driver: driver.find_element(By.CSS_SELECTOR, ".ajs-modal")
|
||||
)
|
||||
@@ -137,7 +137,7 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
||||
self.page.click_modal('Save')
|
||||
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(".ajs-modal")
|
||||
lambda driver: driver.find_element(By.CSS_SELECTOR, ".ajs-modal")
|
||||
)
|
||||
time.sleep(0.5)
|
||||
|
||||
@@ -154,7 +154,9 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
||||
def runTest(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self.page.add_server(self.server)
|
||||
self._schema_node_expandable()
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
|
||||
# Check data types
|
||||
self._check_datatype()
|
||||
@@ -163,17 +165,15 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
||||
def after(self):
|
||||
self.page.remove_server(self.server)
|
||||
|
||||
# TODO - To be remove
|
||||
def _schema_node_expandable(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
|
||||
def _check_datatype(self):
|
||||
# Slick grid does not render all the column if viewport is not enough
|
||||
# wide. So execute test as batch of queries.
|
||||
self.page.click_a_tree_node(
|
||||
self.test_db,
|
||||
TreeAreaLocators.sub_nodes_of_databases_node(self.server['name']))
|
||||
self.page.open_query_tool()
|
||||
self._create_enum_type()
|
||||
for batch in config_data:
|
||||
@@ -200,8 +200,8 @@ class PGDataypeFeatureTest(BaseFeatureTest):
|
||||
|
||||
# For every sample data-type value, check the expected output.
|
||||
cnt = 2
|
||||
cells = canvas.find_elements_by_css_selector(
|
||||
QueryToolLocators.query_output_cells)
|
||||
cells = canvas.find_elements(
|
||||
By.CSS_SELECTOR, QueryToolLocators.query_output_cells)
|
||||
# remove first element as it is row number.
|
||||
cells.pop(0)
|
||||
for val, cell, datatype in zip(
|
||||
|
||||
@@ -67,9 +67,9 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
self.wait = WebDriverWait(self.page.driver, 20)
|
||||
|
||||
def runTest(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.database_name)
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.database_name)
|
||||
|
||||
# Backup
|
||||
self.initiate_backup()
|
||||
@@ -87,8 +87,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
(By.XPATH,
|
||||
NavMenuLocators.process_watcher_alertfier))
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(
|
||||
".loading-logs"), 10)
|
||||
lambda driver: driver.find_element(
|
||||
By.CSS_SELECTOR, ".loading-logs"), 10)
|
||||
|
||||
expected_backup_success_msg = "Successfully completed."
|
||||
self.assertEqual(status, expected_backup_success_msg)
|
||||
@@ -133,8 +133,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
(By.XPATH,
|
||||
NavMenuLocators.process_watcher_alertfier))
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(
|
||||
".loading-logs"), 10)
|
||||
lambda driver: driver.find_element(
|
||||
By.CSS_SELECTOR, ".loading-logs"), 10)
|
||||
self.assertEqual(status, expected_backup_success_msg)
|
||||
|
||||
# Check for XSS in Restore details
|
||||
@@ -209,15 +209,16 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
try:
|
||||
take_bckup.click()
|
||||
if self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_name(
|
||||
lambda driver: driver.find_element(
|
||||
By.NAME,
|
||||
NavMenuLocators.backup_filename_txt_box_name)):
|
||||
click = False
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def initiate_restore(self):
|
||||
tools_menu = self.driver.find_element_by_link_text(
|
||||
NavMenuLocators.tools_menu_link_text)
|
||||
tools_menu = self.driver.find_element(
|
||||
By.LINK_TEXT, NavMenuLocators.tools_menu_link_text)
|
||||
tools_menu.click()
|
||||
|
||||
restore_obj = self.page.find_by_css_selector(
|
||||
@@ -239,7 +240,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
restore_btn.click()
|
||||
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(
|
||||
lambda driver: driver.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
NavMenuLocators.restore_file_name_txt_box_name))
|
||||
|
||||
def _check_escaped_characters(self, source_code, string_to_find, source):
|
||||
@@ -286,8 +288,8 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
default_binary_path = self.server['default_binary_paths']
|
||||
if default_binary_path is not None:
|
||||
def get_server_version_string():
|
||||
server_version = {130000: '13', 120000: '12', 110000: '11',
|
||||
100000: '10', 90600: '9.6'}
|
||||
server_version = {140000: '14', 130000: '13', 120000: '12',
|
||||
110000: '11', 100000: '10', 90600: '9.6'}
|
||||
for k, v in server_version.items():
|
||||
if k <= self.server_information['server_version']:
|
||||
return v
|
||||
@@ -317,5 +319,5 @@ class PGUtilitiesBackupFeatureTest(BaseFeatureTest):
|
||||
self.page.click_modal('Save')
|
||||
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(".ajs-modal")
|
||||
lambda driver: driver.find_element(By.CSS_SELECTOR, ".ajs-modal")
|
||||
)
|
||||
@@ -81,8 +81,8 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
|
||||
self._open_maintenance_dialogue()
|
||||
self.page.click_modal('OK')
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_xpath(
|
||||
NavMenuLocators.maintenance_operation))
|
||||
lambda driver: driver.find_element(
|
||||
By.XPATH, NavMenuLocators.maintenance_operation))
|
||||
|
||||
# Wait for the backup status alertfier
|
||||
self.wait.until(EC.visibility_of_element_located(
|
||||
@@ -91,29 +91,25 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
|
||||
self.verify_command()
|
||||
|
||||
def _open_maintenance_dialogue(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.database_name)
|
||||
if self.test_level == 'table':
|
||||
self.page.toggle_open_schema_node(self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.database_name, 'public')
|
||||
self.page.toggle_open_tables_node(self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.database_name, 'public')
|
||||
retry = 5
|
||||
status = False
|
||||
while retry > 0:
|
||||
status = self.page.click_a_tree_node(
|
||||
self.table_name,
|
||||
TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
if status:
|
||||
break
|
||||
else:
|
||||
retry -= 1
|
||||
self.assertTrue(status, "Table name {} is not selected".format(
|
||||
self.table_name))
|
||||
self.page.expand_tables_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.database_name, 'public')
|
||||
|
||||
table_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.table_node(self.table_name))
|
||||
|
||||
status = False
|
||||
if table_node:
|
||||
status = True
|
||||
self.assertTrue(status, "Table name {} is not visible/selected".
|
||||
format(self.table_name))
|
||||
table_node.click()
|
||||
|
||||
else:
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.database_name)
|
||||
self.page.retry_click(
|
||||
(By.LINK_TEXT,
|
||||
NavMenuLocators.tools_menu_link_text),
|
||||
@@ -133,8 +129,8 @@ class PGUtilitiesMaintenanceFeatureTest(BaseFeatureTest):
|
||||
(By.XPATH,
|
||||
NavMenuLocators.process_watcher_alertfier))
|
||||
self.page.wait_for_element_to_disappear(
|
||||
lambda driver: driver.find_element_by_css_selector(".loading-logs")
|
||||
)
|
||||
lambda driver: driver.find_element(
|
||||
By.CSS_SELECTOR, ".loading-logs"))
|
||||
|
||||
if status != "Successfully completed.":
|
||||
self.assertEqual(status, "Successfully completed.")
|
||||
|
||||
@@ -12,6 +12,7 @@ import random
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.common.by import By
|
||||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
from regression.feature_utils.locators import QueryToolLocators
|
||||
@@ -55,9 +56,9 @@ class QueryToolAutoCompleteFeatureTest(BaseFeatureTest):
|
||||
test_utils.create_table(self.server, self.test_db,
|
||||
self.second_table_name)
|
||||
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
|
||||
self.page.open_query_tool()
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
@@ -171,7 +172,7 @@ class QueryToolAutoCompleteFeatureTest(BaseFeatureTest):
|
||||
Keys.CONTROL).send_keys(Keys.SPACE).key_up(
|
||||
Keys.CONTROL).perform()
|
||||
if self.page.check_if_element_exist_by_xpath(
|
||||
QueryToolLocators.code_mirror_hint_box_xpath, 20):
|
||||
QueryToolLocators.code_mirror_hint_box_xpath, 15):
|
||||
hint_displayed = True
|
||||
break
|
||||
else:
|
||||
@@ -184,8 +185,8 @@ class QueryToolAutoCompleteFeatureTest(BaseFeatureTest):
|
||||
else:
|
||||
# if no IntelliSense is present it means there is only one option
|
||||
# so check if required string is present in codeMirror
|
||||
code_mirror = self.driver.find_elements_by_xpath(
|
||||
QueryToolLocators.code_mirror_data_xpath)
|
||||
code_mirror = self.driver.find_elements(
|
||||
By.XPATH, QueryToolLocators.code_mirror_data_xpath)
|
||||
for data in code_mirror:
|
||||
code_mirror_text = data.text
|
||||
print("Single entry..........")
|
||||
|
||||
@@ -12,6 +12,7 @@ import random
|
||||
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.webdriver.common.keys import Keys
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
@@ -94,7 +95,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
|
||||
def _test_copies_rows(self):
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element_by_tag_name("iframe"))
|
||||
|
||||
select_row = self.page.find_by_xpath(
|
||||
@@ -106,7 +107,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
copy_row.click()
|
||||
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element_by_tag_name("iframe"))
|
||||
|
||||
scratch_pad_ele = self.page.find_by_css_selector(
|
||||
@@ -121,7 +122,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
|
||||
def _test_copies_columns(self):
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element_by_tag_name("iframe"))
|
||||
|
||||
column_header = self.page.find_by_css_selector(
|
||||
@@ -133,7 +134,7 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
copy_btn.click()
|
||||
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.driver.switch_to_frame(
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element_by_tag_name("iframe"))
|
||||
|
||||
scratch_pad_ele = self.page.find_by_css_selector(
|
||||
@@ -169,13 +170,13 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
failed_history_detail_pane.text
|
||||
)
|
||||
self.page.wait_for_elements(
|
||||
lambda driver: driver.find_elements_by_css_selector(
|
||||
QueryToolLocators.query_history_entries))
|
||||
lambda driver: driver.find_elements(
|
||||
By.CSS_SELECTOR, QueryToolLocators.query_history_entries))
|
||||
|
||||
# get the query history rows and click the previous query row which
|
||||
# was executed and verify it
|
||||
history_rows = self.driver.find_elements_by_css_selector(
|
||||
QueryToolLocators.query_history_entries)
|
||||
history_rows = self.driver.find_elements(
|
||||
By.CSS_SELECTOR, QueryToolLocators.query_history_entries)
|
||||
history_rows[1].click()
|
||||
|
||||
selected_history_entry = self.page.find_by_css_selector(
|
||||
@@ -209,8 +210,8 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
self.page.click_tab(self.query_history_tab_name)
|
||||
|
||||
query_list = self.page.wait_for_elements(
|
||||
lambda driver: driver.find_elements_by_css_selector(
|
||||
QueryToolLocators.query_history_entries))
|
||||
lambda driver: driver.find_elements(
|
||||
By.CSS_SELECTOR, QueryToolLocators.query_history_entries))
|
||||
|
||||
self.assertTrue(17, len(query_list))
|
||||
|
||||
@@ -420,9 +421,9 @@ class QueryToolJourneyTest(BaseFeatureTest):
|
||||
self.page.click_modal('Yes')
|
||||
|
||||
def _navigate_to_query_tool(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
self.page.open_query_tool()
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
|
||||
|
||||
@@ -36,9 +36,9 @@ class QueryToolFeatureTest(BaseFeatureTest):
|
||||
def before(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self.page.add_server(self.server)
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.expand_database_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db)
|
||||
self.page.open_query_tool()
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self._reset_options()
|
||||
@@ -128,7 +128,7 @@ class QueryToolFeatureTest(BaseFeatureTest):
|
||||
QueryToolLocators.btn_explain_buffers,
|
||||
QueryToolLocators.btn_explain_timing):
|
||||
btn = self.page.find_by_css_selector(op)
|
||||
check = btn.find_element_by_tag_name('i')
|
||||
check = btn.find_element(By.TAG_NAME, 'i')
|
||||
if 'visibility-hidden' not in check.get_attribute('class'):
|
||||
btn.click()
|
||||
|
||||
@@ -286,10 +286,10 @@ SELECT generate_series(1, 1000) as id order by id desc"""
|
||||
)
|
||||
|
||||
# Search for 'Output' word in result (verbose option)
|
||||
canvas.find_element_by_xpath("//*[contains(string(), 'Output')]")
|
||||
canvas.find_element(By.XPATH, "//*[contains(string(), 'Output')]")
|
||||
|
||||
# Search for 'Total Cost' word in result (cost option)
|
||||
canvas.find_element_by_xpath("//*[contains(string(),'Total Cost')]")
|
||||
canvas.find_element(By.XPATH, "//*[contains(string(),'Total Cost')]")
|
||||
|
||||
def _query_tool_explain_analyze_with_buffers_and_timing(self):
|
||||
query = """-- Explain analyze query with buffers and timing
|
||||
@@ -382,8 +382,8 @@ SELECT relname FROM pg_catalog.pg_class
|
||||
canvas = self.wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, QueryToolLocators.query_output_canvas_css)))
|
||||
|
||||
el = canvas.find_elements_by_xpath(
|
||||
QueryToolLocators.output_column_data_xpath.format(table_name))
|
||||
el = canvas.find_elements(By.XPATH, QueryToolLocators.
|
||||
output_column_data_xpath.format(table_name))
|
||||
|
||||
assert len(el) == 0, "Table '{}' created with auto commit disabled " \
|
||||
"and without any explicit commit.".format(
|
||||
@@ -468,8 +468,9 @@ SELECT relname FROM pg_catalog.pg_class
|
||||
canvas = self.wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, QueryToolLocators.query_output_canvas_css)))
|
||||
|
||||
el = canvas.find_elements_by_xpath(
|
||||
QueryToolLocators.output_column_data_xpath.format(table_name))
|
||||
el = canvas.find_elements(
|
||||
By.XPATH, QueryToolLocators.output_column_data_xpath.format(
|
||||
table_name))
|
||||
|
||||
assert len(el) != 0, "Table '{}' is not created with auto " \
|
||||
"commit enabled.".format(table_name)
|
||||
@@ -561,8 +562,9 @@ SELECT relname FROM pg_catalog.pg_class
|
||||
canvas = self.wait.until(EC.presence_of_element_located(
|
||||
(By.CSS_SELECTOR, QueryToolLocators.query_output_canvas_css)))
|
||||
|
||||
el = canvas.find_elements_by_xpath(
|
||||
QueryToolLocators.output_column_data_xpath.format(table_name))
|
||||
el = canvas.find_elements(
|
||||
By.XPATH, QueryToolLocators.output_column_data_xpath.format(
|
||||
table_name))
|
||||
|
||||
assert len(el) == 0, "Table '{}' created even after ROLLBACK due to " \
|
||||
"sql error.".format(table_name)
|
||||
@@ -699,7 +701,7 @@ SELECT 1, pg_sleep(300)"""
|
||||
QueryToolLocators.btn_explain_buffers,
|
||||
QueryToolLocators.btn_explain_timing):
|
||||
btn = self.page.find_by_css_selector(op)
|
||||
check = btn.find_element_by_tag_name('i')
|
||||
check = btn.find_element(By.TAG_NAME, 'i')
|
||||
if 'visibility-hidden' not in check.get_attribute('class'):
|
||||
btn.click()
|
||||
# click cost button
|
||||
@@ -720,7 +722,7 @@ SELECT 1, pg_sleep(300)"""
|
||||
(By.CSS_SELECTOR, QueryToolLocators.query_output_canvas_css))
|
||||
)
|
||||
# Search for 'Output' word in result (verbose option)
|
||||
canvas.find_element_by_xpath("//*[contains(string(), 'JIT')]")
|
||||
canvas.find_element(By.XPATH, "//*[contains(string(), 'JIT')]")
|
||||
|
||||
self.page.clear_query_tool()
|
||||
|
||||
@@ -732,7 +734,7 @@ class WaitForAnyElementWithText(object):
|
||||
|
||||
def __call__(self, driver):
|
||||
try:
|
||||
elements = EC._find_elements(driver, self.locator)
|
||||
elements = driver.find_elements(*self.locator)
|
||||
for elem in elements:
|
||||
if self.text in elem.text:
|
||||
return True
|
||||
|
||||
@@ -31,16 +31,13 @@ class TableDdlFeatureTest(BaseFeatureTest):
|
||||
self.test_table_name = "test_table" + str(random.randint(1000, 3000))
|
||||
test_utils.create_table(self.server, self.test_db,
|
||||
self.test_table_name)
|
||||
self.page.expand_tables_node("Server", self.server['name'],
|
||||
self.server['db_password'], self.test_db,
|
||||
'public')
|
||||
table_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.table_node(self.test_table_name))
|
||||
table_node.click()
|
||||
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.toggle_open_tables_node(
|
||||
self.server['name'], self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.click_a_tree_node(
|
||||
self.test_table_name,
|
||||
TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
self.page.click_tab("SQL")
|
||||
|
||||
# Wait till data is displayed in SQL Tab
|
||||
|
||||
@@ -56,8 +56,8 @@ class CopySQLFeatureTest(BaseFeatureTest):
|
||||
% self.test_table_name, 10), "No data displayed in SQL tab")
|
||||
|
||||
# Fetch the inner html & check for escaped characters
|
||||
source_code = self.driver.find_elements_by_xpath(
|
||||
QueryToolLocators.code_mirror_data_xpath)
|
||||
source_code = self.driver.find_elements(
|
||||
By.XPATH, QueryToolLocators.code_mirror_data_xpath)
|
||||
|
||||
sql_query = ''
|
||||
for data in source_code:
|
||||
@@ -73,11 +73,11 @@ class CopySQLFeatureTest(BaseFeatureTest):
|
||||
time.sleep(5)
|
||||
|
||||
self.driver.switch_to.default_content()
|
||||
self.driver.switch_to_frame(
|
||||
self.driver.find_element_by_tag_name("iframe"))
|
||||
self.driver.switch_to.frame(
|
||||
self.driver.find_element(By.TAG_NAME, "iframe"))
|
||||
|
||||
code_mirror = self.driver.find_elements_by_xpath(
|
||||
QueryToolLocators.code_mirror_data_xpath)
|
||||
code_mirror = self.driver.find_elements(
|
||||
By.XPATH, QueryToolLocators.code_mirror_data_xpath)
|
||||
query_tool_result = ''
|
||||
for data in code_mirror:
|
||||
query_tool_result += data.text
|
||||
@@ -89,16 +89,12 @@ class CopySQLFeatureTest(BaseFeatureTest):
|
||||
self.test_table_name = "test_table" + str(random.randint(1000, 3000))
|
||||
test_utils.create_table(self.server, self.test_db,
|
||||
self.test_table_name)
|
||||
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.toggle_open_tables_node(
|
||||
self.server['name'], self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.click_a_tree_node(
|
||||
self.test_table_name,
|
||||
TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
self.page.expand_tables_node("Server", self.server['name'],
|
||||
self.server['db_password'], self.test_db,
|
||||
'public')
|
||||
table_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.table_node(self.test_table_name))
|
||||
table_node.click()
|
||||
|
||||
def _update_preferences_setting(self):
|
||||
file_menu = self.page.find_by_css_selector(
|
||||
|
||||
@@ -121,13 +121,9 @@ CREATE TABLE public.nonintpkey
|
||||
def runTest(self):
|
||||
self.page.wait_for_spinner_to_disappear()
|
||||
self.page.add_server(self.server)
|
||||
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.toggle_open_tables_node(self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.expand_tables_node("Server", self.server['name'],
|
||||
self.server['db_password'], self.test_db,
|
||||
'public')
|
||||
|
||||
self._load_config_data('table_insert_update_cases')
|
||||
data_local = config_data
|
||||
@@ -169,12 +165,17 @@ CREATE TABLE public.nonintpkey
|
||||
config_data = config_data_json[config_key]
|
||||
|
||||
def _perform_test_for_table(self, table_name, config_data_local):
|
||||
self.page.click_a_tree_node(
|
||||
table_name,
|
||||
TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
# self.page.click_a_tree_node(
|
||||
# table_name,
|
||||
# TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
table_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.table_node(table_name))
|
||||
table_node.click()
|
||||
|
||||
# Open Object -> View/Edit data
|
||||
self._view_data_grid(table_name)
|
||||
|
||||
time.sleep(3)
|
||||
self.page.wait_for_query_tool_loading_indicator_to_disappear()
|
||||
# Run test to insert a new row in table with default values
|
||||
self._add_row(config_data_local)
|
||||
@@ -237,7 +238,7 @@ CREATE TABLE public.nonintpkey
|
||||
|
||||
if cell_type in ['int', 'int[]']:
|
||||
if value == 'clear':
|
||||
cell_el.find_element_by_css_selector('input').clear()
|
||||
cell_el.find_element(By.CSS_SELECTOR, 'input').clear()
|
||||
else:
|
||||
ActionChains(self.driver).send_keys(value). \
|
||||
send_keys(Keys.ENTER).perform()
|
||||
@@ -273,13 +274,13 @@ CREATE TABLE public.nonintpkey
|
||||
else:
|
||||
# Boolean editor test for to True click
|
||||
if data[1] == 'true':
|
||||
checkbox_el = cell_el.find_element_by_xpath(
|
||||
".//*[contains(@class, 'multi-checkbox')]")
|
||||
checkbox_el = cell_el.find_element(
|
||||
By.XPATH, ".//*[contains(@class, 'multi-checkbox')]")
|
||||
checkbox_el.click()
|
||||
# Boolean editor test for to False click
|
||||
elif data[1] == 'false':
|
||||
checkbox_el = cell_el.find_element_by_xpath(
|
||||
".//*[contains(@class, 'multi-checkbox')]")
|
||||
checkbox_el = cell_el.find_element(
|
||||
By.XPATH, ".//*[contains(@class, 'multi-checkbox')]")
|
||||
# Sets true
|
||||
checkbox_el.click()
|
||||
# Sets false
|
||||
@@ -307,7 +308,7 @@ CREATE TABLE public.nonintpkey
|
||||
), CheckForViewDataTest.TIMEOUT_STRING
|
||||
)
|
||||
self.page.driver.switch_to.frame(
|
||||
self.page.driver.find_element_by_tag_name('iframe')
|
||||
self.page.driver.find_element(By.TAG_NAME, 'iframe')
|
||||
)
|
||||
|
||||
def _copy_paste_row(self, config_data_l):
|
||||
@@ -380,7 +381,7 @@ CREATE TABLE public.nonintpkey
|
||||
try:
|
||||
result_row = self.page.find_by_xpath(xpath)
|
||||
element = \
|
||||
result_row.find_element_by_class_name("r" + str(idx))
|
||||
result_row.find_element(By.CLASS_NAME, "r" + str(idx))
|
||||
self.page.driver.execute_script(
|
||||
scroll_on_arg_for_js, element)
|
||||
break
|
||||
@@ -398,6 +399,6 @@ CREATE TABLE public.nonintpkey
|
||||
list_item.sort(reverse=True)
|
||||
for idx in list_item:
|
||||
time.sleep(0.4)
|
||||
element = result_row.find_element_by_class_name("r" + str(idx))
|
||||
element = result_row.find_element(By.CLASS_NAME, "r" + str(idx))
|
||||
self.page.driver.execute_script(
|
||||
scroll_on_arg_for_js, element)
|
||||
@@ -9,12 +9,14 @@
|
||||
|
||||
import sys
|
||||
import random
|
||||
import time
|
||||
|
||||
from regression.python_test_utils import test_utils
|
||||
from regression.feature_utils.base_feature_test import BaseFeatureTest
|
||||
from selenium.webdriver import ActionChains
|
||||
from selenium.common.exceptions import StaleElementReferenceException, \
|
||||
WebDriverException
|
||||
from selenium.webdriver.common.by import By
|
||||
from regression.feature_utils.locators import QueryToolLocators
|
||||
from regression.feature_utils.tree_area_locators import TreeAreaLocators
|
||||
|
||||
@@ -74,7 +76,6 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
while retry > 0:
|
||||
try:
|
||||
self.page.refresh_page()
|
||||
self.page.toggle_open_servers_group()
|
||||
self._tables_node_expandable()
|
||||
self._check_xss_in_dependents_tab()
|
||||
retry = 0
|
||||
@@ -106,15 +107,13 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
self.server, self.test_db, self.test_table_name)
|
||||
|
||||
def _tables_node_expandable(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.toggle_open_tables_node(self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.click_a_tree_node(
|
||||
self.test_table_name,
|
||||
TreeAreaLocators.sub_nodes_of_tables_node)
|
||||
self.page.expand_tables_node("Server", self.server['name'],
|
||||
self.server['db_password'], self.test_db,
|
||||
'public')
|
||||
|
||||
table_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.table_node(self.test_table_name))
|
||||
table_node.click()
|
||||
|
||||
def _check_xss_in_browser_tree(self):
|
||||
print(
|
||||
@@ -138,6 +137,12 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
file=sys.stderr, end=""
|
||||
)
|
||||
self.page.click_tab("SQL")
|
||||
|
||||
# Wait till data is displayed in SQL Tab
|
||||
self.assertTrue(self.page.check_if_element_exist_by_xpath(
|
||||
"//*[contains(@class,'CodeMirror-lines') and "
|
||||
"contains(.,'CREATE TABLE')]", 10), "No data displayed in SQL tab")
|
||||
|
||||
# Fetch the inner html & check for escaped characters
|
||||
source_code = self.page.find_by_xpath(
|
||||
"//*[contains(@class,'CodeMirror-lines') and "
|
||||
@@ -197,7 +202,7 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
"contains(@style, 'top:0px')]"
|
||||
)
|
||||
|
||||
cells = result_row.find_elements_by_tag_name('div')
|
||||
cells = result_row.find_elements(By.TAG_NAME, 'div')
|
||||
|
||||
# remove first element as it is row number.
|
||||
source_code = cells[1].get_attribute('innerHTML')
|
||||
@@ -239,8 +244,8 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
while retry > 0:
|
||||
try:
|
||||
history_ele = self.driver \
|
||||
.find_element_by_css_selector(
|
||||
".query-detail .content-value")
|
||||
.find_element(By.CSS_SELECTOR,
|
||||
".query-detail .content-value")
|
||||
source_code = history_ele.get_attribute('innerHTML')
|
||||
break
|
||||
except StaleElementReferenceException:
|
||||
@@ -279,8 +284,8 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
)
|
||||
|
||||
self.page.find_by_css_selector(".slick-header-column")
|
||||
cells = self.driver.\
|
||||
find_elements_by_css_selector(".slick-header-column")
|
||||
cells = self.driver. \
|
||||
find_elements(By.CSS_SELECTOR, ".slick-header-column")
|
||||
|
||||
# remove first element as it is row number.
|
||||
# currently 4th col
|
||||
@@ -310,9 +315,9 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
# Re-try logic
|
||||
try:
|
||||
ActionChains(self.driver).move_to_element(
|
||||
self.driver.find_element_by_css_selector(
|
||||
'div.pgadmin-explain-container > svg > g > g > image'
|
||||
)
|
||||
self.driver.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
'div.pgadmin-explain-container > svg > g > g > image')
|
||||
).click().perform()
|
||||
break
|
||||
except Exception:
|
||||
@@ -326,7 +331,8 @@ class CheckForXssFeatureTest(BaseFeatureTest):
|
||||
)
|
||||
raise
|
||||
|
||||
source_code = self.driver.find_element_by_css_selector(
|
||||
source_code = self.driver.find_element(
|
||||
By.CSS_SELECTOR,
|
||||
'.pgadmin-explain-details:not(.d-none)').get_attribute('innerHTML')
|
||||
|
||||
self._check_escaped_characters(
|
||||
|
||||
@@ -58,16 +58,12 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
|
||||
self.function_name)
|
||||
|
||||
def _function_node_expandable(self):
|
||||
self.page.expand_database_node(
|
||||
self.server['name'],
|
||||
self.server['db_password'], self.test_db)
|
||||
self.page.toggle_open_schema_node(self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db, 'public')
|
||||
self.page.toggle_open_function_node()
|
||||
self.page.click_a_tree_node(
|
||||
self.function_name + "()",
|
||||
TreeAreaLocators.sub_nodes_of_functions_node)
|
||||
self.page.expand_schema_child_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
self.test_db, 'public', "Functions")
|
||||
function_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.function_node(self.function_name + "()"))
|
||||
function_node.click()
|
||||
|
||||
def _debug_function(self):
|
||||
self.page.driver.find_element_by_link_text("Object").click()
|
||||
@@ -138,7 +134,7 @@ class CheckDebuggerForXssFeatureTest(BaseFeatureTest):
|
||||
self._close_debugger()
|
||||
|
||||
def _close_debugger(self):
|
||||
self.page.driver.switch_to_default_content()
|
||||
self.page.driver.switch_to.default_content()
|
||||
self.page.click_element(
|
||||
self.page.find_by_xpath(
|
||||
"//*[@id='dockerContainer']/div/div[3]/div/div[2]/div[1]")
|
||||
|
||||
@@ -42,6 +42,8 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
||||
self.role)
|
||||
test_utils.create_role(self.server, "postgres",
|
||||
"<h1>test</h1>")
|
||||
test_utils.grant_role(self.server, "postgres",
|
||||
self.role, "<h1>test</h1>")
|
||||
self.wait = WebDriverWait(self.page.driver, 20)
|
||||
|
||||
def runTest(self):
|
||||
@@ -58,11 +60,13 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
||||
"<h1>test</h1>")
|
||||
|
||||
def _role_node_expandable(self, role):
|
||||
self.page.expand_server_node(
|
||||
self.server['name'], self.server['db_password'])
|
||||
self.page.toggle_open_tree_item('Login/Group Roles')
|
||||
self.page.click_a_tree_node(
|
||||
role, TreeAreaLocators.sub_nodes_of_login_group_node)
|
||||
self.page.expand_server_child_node("Server", self.server['name'],
|
||||
self.server['db_password'],
|
||||
'Login/Group Roles')
|
||||
|
||||
role_node = self.page.check_if_element_exists_with_scroll(
|
||||
TreeAreaLocators.role_node(role))
|
||||
role_node.click()
|
||||
|
||||
def _check_role_membership_control(self):
|
||||
self.page.driver.find_element_by_link_text(
|
||||
@@ -70,24 +74,22 @@ class CheckRoleMembershipControlFeatureTest(BaseFeatureTest):
|
||||
property_object = self.wait.until(EC.visibility_of_element_located(
|
||||
(By.CSS_SELECTOR, NavMenuLocators.properties_obj_css)))
|
||||
property_object.click()
|
||||
WebDriverWait(self.page.driver, 4).until(
|
||||
membership_tab = WebDriverWait(self.page.driver, 4).until(
|
||||
EC.presence_of_element_located((
|
||||
By.XPATH, "//a[normalize-space(text())='Membership']")))
|
||||
self.click_membership_tab()
|
||||
By.XPATH, "//span[normalize-space(text())='Membership']")))
|
||||
membership_tab.click()
|
||||
|
||||
# Fetch the source code for our custom control
|
||||
source_code = self.page.find_by_xpath(
|
||||
"//div[contains(@class,'rolmembership')]"
|
||||
).get_attribute('innerHTML')
|
||||
"//span[contains(@class,'icon-')]/following-sibling::span"
|
||||
).text
|
||||
|
||||
self._check_escaped_characters(
|
||||
source_code,
|
||||
'<h1>test</h1>',
|
||||
'Role Membership Control'
|
||||
)
|
||||
self.page.find_by_xpath(
|
||||
"//button[contains(@type, 'cancel') and "
|
||||
"contains(.,'Cancel')]"
|
||||
).click()
|
||||
self.page.find_by_xpath("//button/span[text()='Close']").click()
|
||||
|
||||
def _check_escaped_characters(self, source_code, string_to_find, source):
|
||||
# For XSS we need to search against element's html code
|
||||
|
||||
+1224
-1127
File diff suppressed because it is too large.
Load diff
@@ -46,3 +46,9 @@
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
@media screen and (forced-colors: active) {
|
||||
body {
|
||||
forced-color-adjust: none !important;
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,8 @@ function MappedFormControlBase({type, value, id, onChange, className, visible, i
|
||||
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props} type='int'/>;
|
||||
case 'numeric':
|
||||
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props} type='numeric'/>;
|
||||
case 'tel':
|
||||
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props} type='tel'/>;
|
||||
case 'text':
|
||||
return <FormInputText name={name} value={value} onChange={onTextChange} className={className} inputRef={inputRef} {...props}/>;
|
||||
case 'multiline':
|
||||
|
||||
@@ -101,6 +101,7 @@ basicSettings = createMuiTheme(basicSettings, {
|
||||
},
|
||||
inputMultiline: {
|
||||
padding: basicSettings.spacing(0.75, 1.5),
|
||||
resize: 'auto',
|
||||
},
|
||||
adornedEnd: {
|
||||
paddingRight: basicSettings.spacing(1.5),
|
||||
|
||||
@@ -320,7 +320,7 @@ export const InputText = forwardRef(({
|
||||
let changeVal = e.target.value;
|
||||
|
||||
/* For type number, we set type as tel with number regex to get validity.*/
|
||||
if(['numeric', 'int'].indexOf(type) > -1) {
|
||||
if(['numeric', 'int', 'tel'].indexOf(type) > -1) {
|
||||
if(!e.target.validity.valid && changeVal !== '' && changeVal !== '-') {
|
||||
return;
|
||||
}
|
||||
@@ -345,9 +345,9 @@ export const InputText = forwardRef(({
|
||||
className={classes.formInput}
|
||||
inputProps={{
|
||||
id: cid,
|
||||
maxLength: maxlength,
|
||||
maxLength: controlProps?.multiline ? null : maxlength,
|
||||
'aria-describedby': helpid,
|
||||
...(type ? {pattern: patterns[type]} : {})
|
||||
...(type ? {pattern: !_.isUndefined(controlProps) && !_.isUndefined(controlProps.pattern) ? controlProps.pattern : patterns[type]} : {})
|
||||
}}
|
||||
readOnly={Boolean(readonly)}
|
||||
disabled={Boolean(disabled)}
|
||||
|
||||
@@ -327,6 +327,12 @@ import Alertify from 'pgadmin.alertifyjs';
|
||||
}
|
||||
};
|
||||
|
||||
this.resizeJsoneditorObserver = new ResizeObserver(() => {
|
||||
if ($editor){
|
||||
$editor.resize();
|
||||
}
|
||||
});
|
||||
|
||||
this.save = function() {
|
||||
args.commitChanges();
|
||||
};
|
||||
@@ -352,6 +358,7 @@ import Alertify from 'pgadmin.alertifyjs';
|
||||
};
|
||||
|
||||
this.destroy = function() {
|
||||
this.resizeJsoneditorObserver.unobserve(document.getElementById('pg-json-editor'));
|
||||
$editor.destroy();
|
||||
$wrapper.remove();
|
||||
};
|
||||
@@ -408,6 +415,7 @@ import Alertify from 'pgadmin.alertifyjs';
|
||||
throw(error);
|
||||
}, 'jsoneditorchunk');
|
||||
}
|
||||
this.resizeJsoneditorObserver.observe(document.getElementById('pg-json-editor'));
|
||||
};
|
||||
|
||||
this.serializeValue = function() {
|
||||
@@ -641,6 +649,7 @@ import Alertify from 'pgadmin.alertifyjs';
|
||||
};
|
||||
|
||||
this.destroy = function() {
|
||||
this.resizeJsoneditorObserver.unobserve(document.getElementById('pg-json-editor'));
|
||||
$editor.destroy();
|
||||
$wrapper.remove();
|
||||
};
|
||||
@@ -649,6 +658,13 @@ import Alertify from 'pgadmin.alertifyjs';
|
||||
$editor.focus();
|
||||
};
|
||||
|
||||
// listen to resize event for json editor
|
||||
this.resizeJsoneditorObserver = new ResizeObserver(() => {
|
||||
if ($editor){
|
||||
$editor.resize();
|
||||
}
|
||||
});
|
||||
|
||||
this.loadValue = function(item) {
|
||||
var data = defaultValue = item[args.column.field];
|
||||
tmpdata = data;
|
||||
@@ -689,6 +705,7 @@ import Alertify from 'pgadmin.alertifyjs';
|
||||
}, function(error){
|
||||
throw(error);
|
||||
}, 'jsoneditorchunk');
|
||||
this.resizeJsoneditorObserver.observe(document.getElementById('pg-json-editor'));
|
||||
};
|
||||
|
||||
this.serializeValue = function() {
|
||||
|
||||
@@ -81,7 +81,7 @@ export class Tree {
|
||||
}
|
||||
|
||||
async update(item, data) {
|
||||
await this.tree.update(item, data.itemData);
|
||||
await this.tree.update(item, data);
|
||||
}
|
||||
|
||||
async remove(item) {
|
||||
@@ -140,12 +140,12 @@ export class Tree {
|
||||
await this.tree.toggleDirectory(item);
|
||||
}
|
||||
|
||||
async select(item, ensureVisible=false) {
|
||||
await this.tree.setActiveFile(item, ensureVisible);
|
||||
async select(item, ensureVisible=false, align='auto') {
|
||||
await this.tree.setActiveFile(item, ensureVisible, align);
|
||||
}
|
||||
|
||||
async selectNode(item, ensureVisible=false) {
|
||||
this.tree.setActiveFile(item, ensureVisible);
|
||||
async selectNode(item, ensureVisible=false, align='auto') {
|
||||
this.tree.setActiveFile(item, ensureVisible, align);
|
||||
}
|
||||
|
||||
async unload(item) {
|
||||
|
||||
@@ -30,8 +30,8 @@ export class ManageTreeNodes {
|
||||
})
|
||||
|
||||
public updateNode = (_path, _data) => new Promise((res, rej) => {
|
||||
if (_path in this.tree) {
|
||||
const item = this.tree[_path];
|
||||
const item = this.findNode(_path);
|
||||
if (item) {
|
||||
item.name = _data.label;
|
||||
item.metadata.data = _data;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ export class ManageTreeNodes {
|
||||
else {
|
||||
if (node.metadata.data._type.includes("coll-")) {
|
||||
let _type = node.metadata.data._type.replace("coll-", "")
|
||||
url = _type + '/nodes/' + _parent_url;
|
||||
url = _type + '/nodes/' + _parent_url + '/';
|
||||
}
|
||||
else {
|
||||
url = node.metadata.data._type + '/children/' + _parent_url + '/' + node.metadata.data._id;
|
||||
|
||||
@@ -230,7 +230,9 @@ div.jsoneditor td.jsoneditor-tree {
|
||||
}
|
||||
|
||||
pre.jsoneditor-preview{
|
||||
background-color: $color-gray-lighter !important;
|
||||
background-color: $color-gray-lighter !important;
|
||||
opacity: 0.8;
|
||||
color: $color-fg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ define([
|
||||
callback: 'check_func_debuggable',
|
||||
category: gettext('Debugging'),
|
||||
priority: 10,
|
||||
label: gettext('Set breakpoint'),
|
||||
label: gettext('Set Breakpoint'),
|
||||
data: {
|
||||
object: 'function',
|
||||
debug_type: 'indirect',
|
||||
@@ -87,7 +87,7 @@ define([
|
||||
callback: 'check_func_debuggable',
|
||||
category: gettext('Debugging'),
|
||||
priority: 10,
|
||||
label: gettext('Set breakpoint'),
|
||||
label: gettext('Set Breakpoint'),
|
||||
data: {
|
||||
object: 'procedure',
|
||||
debug_type: 'indirect',
|
||||
@@ -101,7 +101,7 @@ define([
|
||||
applies: ['object', 'context'],
|
||||
callback: 'check_func_debuggable',
|
||||
priority: 10,
|
||||
label: gettext('Set breakpoint'),
|
||||
label: gettext('Set Breakpoint'),
|
||||
category: gettext('Debugging'),
|
||||
icon: 'fa fa-arrow-circle-right',
|
||||
data: {
|
||||
@@ -116,7 +116,7 @@ define([
|
||||
applies: ['object', 'context'],
|
||||
callback: 'check_func_debuggable',
|
||||
priority: 10,
|
||||
label: gettext('Set breakpoint'),
|
||||
label: gettext('Set Breakpoint'),
|
||||
category: gettext('Debugging'),
|
||||
icon: 'fa fa-arrow-circle-right',
|
||||
data: {
|
||||
@@ -146,7 +146,7 @@ define([
|
||||
callback: 'check_func_debuggable',
|
||||
category: gettext('Debugging'),
|
||||
priority: 10,
|
||||
label: gettext('Set breakpoint'),
|
||||
label: gettext('Set Breakpoint'),
|
||||
data: {
|
||||
object: 'edbfunc',
|
||||
debug_type: 'indirect',
|
||||
@@ -175,7 +175,7 @@ define([
|
||||
callback: 'check_func_debuggable',
|
||||
category: gettext('Debugging'),
|
||||
priority: 10,
|
||||
label: gettext('Set breakpoint'),
|
||||
label: gettext('Set Breakpoint'),
|
||||
data: {
|
||||
object: 'edbproc',
|
||||
debug_type: 'indirect',
|
||||
|
||||
@@ -289,7 +289,7 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper {
|
||||
tree.findNodeWithToggle(rowData.id_path)
|
||||
.then((treeItem)=>{
|
||||
setTimeout(() => {
|
||||
tree.select(treeItem, true);
|
||||
tree.select(treeItem, true, 'center');
|
||||
}, 100);
|
||||
this.showMessage(null);
|
||||
})
|
||||
|
||||
+35
-1
@@ -130,7 +130,7 @@ FROM (
|
||||
from pg_catalog.pg_proc p
|
||||
left join pg_catalog.pg_namespace n on p.pronamespace = n.oid
|
||||
left join pg_catalog.pg_type t on p.prorettype = t.oid
|
||||
WHERE ({{ CATALOGS.DB_SUPPORT('n') }})
|
||||
WHERE ({{ CATALOGS.DB_SUPPORT('n') }}) AND NOT p.proisagg
|
||||
{% endif %}
|
||||
{% if all_obj %}
|
||||
UNION
|
||||
@@ -500,6 +500,40 @@ FROM (
|
||||
JOIN pg_catalog.pg_namespace n on t.relnamespace = n.oid
|
||||
where {{ CATALOGS.DB_SUPPORT('n') }}
|
||||
{% endif %}
|
||||
{% if all_obj %}
|
||||
UNION
|
||||
{% endif %}
|
||||
{% if all_obj or obj_type in ['aggregate'] %}
|
||||
SELECT 'aggregate' AS obj_type, pr.proname AS obj_name,
|
||||
':schema.'|| ns.oid || ':/' || ns.nspname || '/' || ':aggregate.' || ag.aggfnoid::oid ||':/' || pr.proname AS obj_path,
|
||||
ns.nspname AS schema_name,
|
||||
{{ show_node_prefs['aggregate'] }} AS show_node, pg_catalog.pg_get_function_arguments(aggfnoid::oid) AS other_info
|
||||
FROM pg_aggregate ag
|
||||
LEFT OUTER JOIN pg_catalog.pg_proc pr ON pr.oid = ag.aggfnoid
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=pr.pronamespace
|
||||
WHERE ({{ CATALOGS.DB_SUPPORT('ns') }})
|
||||
{% endif %}
|
||||
{% if all_obj %}
|
||||
UNION
|
||||
{% endif %}
|
||||
{% if all_obj or obj_type in ['operator'] %}
|
||||
SELECT 'operator' AS obj_type, op.oprname AS obj_name,
|
||||
':schema.'|| ns.oid || ':/' || ns.nspname || '/' || ':operator.' || op.oid::oid ||':/' || op.oprname AS obj_path,
|
||||
ns.nspname AS schema_name,
|
||||
{{ show_node_prefs['operator'] }} AS show_node,
|
||||
CASE WHEN lt.typname IS NOT NULL AND rt.typname IS NOT NULL THEN
|
||||
pg_catalog.format_type(lt.oid, NULL) || ', ' || pg_catalog.format_type(rt.oid, NULL)
|
||||
WHEN lt.typname IS NULL AND rt.typname IS NOT NULL THEN
|
||||
pg_catalog.format_type(rt.oid, NULL)
|
||||
WHEN lt.typname IS NOT NULL AND rt.typname IS NULL THEN
|
||||
pg_catalog.format_type(lt.oid, NULL)
|
||||
ELSE '' END AS other_info
|
||||
FROM pg_catalog.pg_operator op
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=op.oprnamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_type lt ON lt.oid=op.oprleft
|
||||
LEFT OUTER JOIN pg_catalog.pg_type rt ON rt.oid=op.oprright
|
||||
WHERE ({{ CATALOGS.DB_SUPPORT('ns') }})
|
||||
{% endif %}
|
||||
|
||||
) sn
|
||||
where lower(sn.obj_name) like '%{{ search_text }}%'
|
||||
|
||||
+35
-1
@@ -147,7 +147,7 @@ FROM (
|
||||
WHEN t.typname IN ('trigger', 'event_trigger') THEN lng.lanname NOT IN ('edbspl', 'sql', 'internal')
|
||||
ELSE true
|
||||
END
|
||||
AND ({{ CATALOGS.DB_SUPPORT('n') }})
|
||||
AND ({{ CATALOGS.DB_SUPPORT('n') }}) AND p.prokind != 'a'
|
||||
{% endif %}
|
||||
{% if all_obj %}
|
||||
UNION
|
||||
@@ -516,6 +516,40 @@ FROM (
|
||||
JOIN pg_catalog.pg_namespace n on t.relnamespace = n.oid
|
||||
where {{ CATALOGS.DB_SUPPORT('n') }}
|
||||
{% endif %}
|
||||
{% if all_obj %}
|
||||
UNION
|
||||
{% endif %}
|
||||
{% if all_obj or obj_type in ['aggregate'] %}
|
||||
SELECT 'aggregate' AS obj_type, pr.proname AS obj_name,
|
||||
':schema.'|| ns.oid || ':/' || ns.nspname || '/' || ':aggregate.' || ag.aggfnoid::oid ||':/' || pr.proname AS obj_path,
|
||||
ns.nspname AS schema_name,
|
||||
{{ show_node_prefs['aggregate'] }} AS show_node, pg_catalog.pg_get_function_arguments(aggfnoid::oid) AS other_info
|
||||
FROM pg_aggregate ag
|
||||
LEFT OUTER JOIN pg_catalog.pg_proc pr ON pr.oid = ag.aggfnoid
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=pr.pronamespace
|
||||
WHERE ({{ CATALOGS.DB_SUPPORT('ns') }})
|
||||
{% endif %}
|
||||
{% if all_obj %}
|
||||
UNION
|
||||
{% endif %}
|
||||
{% if all_obj or obj_type in ['operator'] %}
|
||||
SELECT 'operator' AS obj_type, op.oprname AS obj_name,
|
||||
':schema.'|| ns.oid || ':/' || ns.nspname || '/' || ':operator.' || op.oid::oid ||':/' || op.oprname AS obj_path,
|
||||
ns.nspname AS schema_name,
|
||||
{{ show_node_prefs['operator'] }} AS show_node,
|
||||
CASE WHEN lt.typname IS NOT NULL AND rt.typname IS NOT NULL THEN
|
||||
pg_catalog.format_type(lt.oid, NULL) || ', ' || pg_catalog.format_type(rt.oid, NULL)
|
||||
WHEN lt.typname IS NULL AND rt.typname IS NOT NULL THEN
|
||||
pg_catalog.format_type(rt.oid, NULL)
|
||||
WHEN lt.typname IS NOT NULL AND rt.typname IS NULL THEN
|
||||
pg_catalog.format_type(lt.oid, NULL)
|
||||
ELSE '' END AS other_info
|
||||
FROM pg_catalog.pg_operator op
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=op.oprnamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_type lt ON lt.oid=op.oprleft
|
||||
LEFT OUTER JOIN pg_catalog.pg_type rt ON rt.oid=op.oprright
|
||||
WHERE ({{ CATALOGS.DB_SUPPORT('ns') }})
|
||||
{% endif %}
|
||||
|
||||
) sn
|
||||
where lower(sn.obj_name) like '%{{ search_text }}%'
|
||||
|
||||
Loaded 100 of 141 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user