Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91ad54d17b | ||
|
|
ea5ee74205 | ||
|
|
5f22b4e2d2 | ||
|
|
758bbc7272 | ||
|
|
618e03b65f | ||
|
|
e9b97d61f8 | ||
|
|
83377d4a50 | ||
|
|
c03d21899b | ||
|
|
d03a0cdce6 | ||
|
|
f3567518d3 | ||
|
|
b30520adc0 | ||
|
|
c6af61afd3 | ||
|
|
04024c7f61 | ||
|
|
9e6ab295df | ||
|
|
5c9acc1c3d | ||
|
|
c75bba03c2 | ||
|
|
93bbadb994 | ||
|
|
42ff67c845 | ||
|
|
5376d88444 | ||
|
|
f733d124bd | ||
|
|
7ff3c4bbeb | ||
|
|
e5590797c0 | ||
|
|
8576a5e7e6 | ||
|
|
3e66b6f7be | ||
|
|
2fd2a144f1 | ||
|
|
500a5c7101 | ||
|
|
5498682934 | ||
|
|
cdeb18fcbb | ||
|
|
0de635cc4c | ||
|
|
e09af0a0e9 | ||
|
|
ade57d4ec4 | ||
|
|
fc41c795f1 | ||
|
|
7caaf2de82 | ||
|
|
09bc544e83 | ||
|
|
42a47126aa | ||
|
|
db87df8f82 | ||
|
|
15c212a2df | ||
|
|
68627ab44e | ||
|
|
800fdce316 | ||
|
|
a5557b466c |
No files matched your search
@@ -20,7 +20,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
pgver: [13, 14, 15, 16, 17]
|
||||
pgver: [13, 14, 15, 16, 17, 18]
|
||||
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
|
||||
@@ -73,6 +73,14 @@ jobs:
|
||||
IF %ERRORLEVEL% EQU 3010 cmd /c "exit /b 0"
|
||||
shell: cmd
|
||||
|
||||
- name: Add pg_config path to PATH
|
||||
shell: pwsh
|
||||
run: |
|
||||
$pgPath = "C:\\EPAS\\${{ matrix.pgver }}\\bin"
|
||||
Write-Output $pgPath
|
||||
Add-Content -Path $env:GITHUB_PATH -Value $pgPath
|
||||
pg_config --version
|
||||
|
||||
- name: Create the tablespace directory on Linux
|
||||
if: ${{ matrix.os == 'ubuntu-22.04' }}
|
||||
run: |
|
||||
@@ -97,8 +105,13 @@ jobs:
|
||||
run: |
|
||||
# Note: we use a custom port for PostgreSQL as the runner may already have a version of PostgreSQL installed
|
||||
sudo su -c "echo local all all trust > /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all 127.0.0.1/32 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all ::1/128 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres 127.0.0.1/32 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres ::1/128 trust >> /etc/edb-as/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo sed -i "s/port = 544[0-9]/port = 58${{ matrix.pgver }}/g" /etc/edb-as/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo sed -i "s/shared_preload_libraries = '/shared_preload_libraries = '\$libdir\/plugin_debugger,/g" /etc/edb-as/${{ matrix.pgver }}/main/postgresql.conf
|
||||
echo "wal_level = logical" | sudo tee -a /etc/edb-as/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo su - enterprisedb -c "mkdir -p /var/run/edb-as/${{ matrix.pgver }}-main.epas_stat_tmp"
|
||||
sudo systemctl restart edb-as@${{ matrix.pgver }}-main
|
||||
|
||||
@@ -107,6 +120,16 @@ jobs:
|
||||
sleep 2
|
||||
done
|
||||
|
||||
- name: Start PostgreSQL on Windows
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
echo host replication postgres 127.0.0.1/32 trust >> "C:\EPAS\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo host replication postgres ::1/128 trust >> "C:\EPAS\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo wal_level = logical >> "C:\EPAS\${{ matrix.pgver }}\data\postgresql.conf"
|
||||
net stop epas-${{ matrix.pgver }}
|
||||
net start epas-${{ matrix.pgver }}
|
||||
shell: cmd
|
||||
|
||||
- name: Create pgagent extension on Linux
|
||||
if: ${{ matrix.os == 'ubuntu-22.04' && matrix.pgver <= 16 }}
|
||||
run: psql -U enterprisedb -d postgres -p 58${{ matrix.pgver }} -c 'CREATE EXTENSION IF NOT EXISTS pgagent;'
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-latest, ubuntu-22.04, windows-latest]
|
||||
pgver: [13, 14, 15, 16, 17]
|
||||
pgver: [13, 14, 15, 16, 17, 18]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
@@ -64,6 +64,7 @@ jobs:
|
||||
brew install postgresql@${{ matrix.pgver }}
|
||||
echo "/opt/homebrew/opt/postgresql@${{ matrix.pgver }}/bin" >> $GITHUB_PATH
|
||||
|
||||
|
||||
- name: Uninstall PostgreSQL if already present on windows
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
@@ -85,6 +86,14 @@ jobs:
|
||||
IF %ERRORLEVEL% EQU 3010 cmd /c "exit /b 0"
|
||||
shell: cmd
|
||||
|
||||
- name: Add pg_config path to PATH
|
||||
shell: pwsh
|
||||
run: |
|
||||
$pgPath = "C:\\PostgreSQL\\${{ matrix.pgver }}\\bin"
|
||||
Write-Output $pgPath
|
||||
Add-Content -Path $env:GITHUB_PATH -Value $pgPath
|
||||
pg_config --version
|
||||
|
||||
- name: Create the tablespace directory on Linux
|
||||
if: ${{ matrix.os == 'ubuntu-22.04' }}
|
||||
run: |
|
||||
@@ -107,8 +116,13 @@ jobs:
|
||||
if: ${{ matrix.os == 'ubuntu-22.04' }}
|
||||
run: |
|
||||
sudo su -c "echo local all all trust > /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all 127.0.0.1/32 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host all all ::1/128 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres 127.0.0.1/32 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo su -c "echo host replication postgres ::1/128 trust >> /etc/postgresql/${{ matrix.pgver }}/main/pg_hba.conf"
|
||||
sudo sed -i "s/port = 543[0-9]/port = 59${{ matrix.pgver }}/g" /etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = '\$libdir\/plugin_debugger'/g" /etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf
|
||||
echo "wal_level = logical" | sudo tee -a /etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf
|
||||
sudo su - postgres -c "/usr/lib/postgresql/${{ matrix.pgver }}/bin/postgres -D /var/lib/postgresql/${{ matrix.pgver }}/main -c config_file=/etc/postgresql/${{ matrix.pgver }}/main/postgresql.conf &"
|
||||
|
||||
until sudo runuser -l postgres -c "pg_isready -p 59${{ matrix.pgver }}" 2>/dev/null; do
|
||||
@@ -124,7 +138,12 @@ jobs:
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
run: |
|
||||
echo local all all trust > /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host all all 127.0.0.1/32 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host all all ::1/128 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host replication postgres 127.0.0.1/32 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
echo 'host replication postgres ::1/128 trust' >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/pg_hba.conf
|
||||
sed -i '' "s/#port = 543[0-9]/port = 59${{ matrix.pgver }}/g" /opt/homebrew/var/postgresql@${{ matrix.pgver }}/postgresql.conf
|
||||
echo "wal_level = logical" >> /opt/homebrew/var/postgresql@${{ matrix.pgver }}/postgresql.conf
|
||||
brew services restart postgresql@${{ matrix.pgver }}
|
||||
|
||||
until /opt/homebrew/opt/postgresql@${{ matrix.pgver }}/bin/pg_isready -p 59${{ matrix.pgver }} 2>/dev/null; do
|
||||
@@ -134,6 +153,16 @@ jobs:
|
||||
|
||||
psql postgres -p 59${{ matrix.pgver }} -c 'CREATE ROLE postgres SUPERUSER LOGIN;'
|
||||
|
||||
- name: Start PostgreSQL on Windows
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
run: |
|
||||
echo host replication postgres 127.0.0.1/32 trust >> "C:\PostgreSQL\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo host replication postgres ::1/128 trust >> "C:\PostgreSQL\${{ matrix.pgver }}\data\pg_hba.conf"
|
||||
echo wal_level = logical >> "C:\PostgreSQL\${{ matrix.pgver }}\data\postgresql.conf"
|
||||
net stop postgresql-x64-${{ matrix.pgver }}
|
||||
net start postgresql-x64-${{ matrix.pgver }}
|
||||
shell: cmd
|
||||
|
||||
- name: Install Python dependencies on Linux and macOS
|
||||
if: ${{ matrix.os == 'macos-latest' || matrix.os == 'ubuntu-22.04' }}
|
||||
run: make install-python-testing
|
||||
|
||||
@@ -120,21 +120,16 @@ RUN rm -rf /pgadmin4/docs/en_US/_build/html/_static/*.png
|
||||
# Create additional builders to get all of the PostgreSQL utilities
|
||||
#########################################################################
|
||||
|
||||
FROM postgres:12-alpine AS pg12-builder
|
||||
FROM postgres:13-alpine AS pg13-builder
|
||||
FROM postgres:14-alpine AS pg14-builder
|
||||
FROM postgres:15-alpine AS pg15-builder
|
||||
FROM postgres:16-alpine AS pg16-builder
|
||||
FROM postgres:17-alpine AS pg17-builder
|
||||
FROM postgres:18-alpine AS pg18-builder
|
||||
|
||||
FROM alpine:latest AS tool-builder
|
||||
|
||||
# Copy the PG binaries
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-12/
|
||||
COPY --from=pg12-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-12/
|
||||
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-13/
|
||||
COPY --from=pg13-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-13/
|
||||
@@ -160,6 +155,11 @@ COPY --from=pg17-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-17/
|
||||
COPY --from=pg17-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-17/
|
||||
COPY --from=pg17-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-17/
|
||||
|
||||
COPY --from=pg18-builder /usr/local/bin/pg_dump /usr/local/pgsql/pgsql-18/
|
||||
COPY --from=pg18-builder /usr/local/bin/pg_dumpall /usr/local/pgsql/pgsql-18/
|
||||
COPY --from=pg18-builder /usr/local/bin/pg_restore /usr/local/pgsql/pgsql-18/
|
||||
COPY --from=pg18-builder /usr/local/bin/psql /usr/local/pgsql/pgsql-18/
|
||||
|
||||
#########################################################################
|
||||
# Assemble everything into the final container.
|
||||
#########################################################################
|
||||
@@ -171,12 +171,12 @@ COPY --from=env-builder /venv /venv
|
||||
|
||||
# Copy in the tools
|
||||
COPY --from=tool-builder /usr/local/pgsql /usr/local/
|
||||
COPY --from=pg17-builder /usr/local/lib/libpq.so.5.17 /usr/lib/
|
||||
COPY --from=pg17-builder /usr/lib/libzstd.so.1.5.7 /usr/lib/
|
||||
COPY --from=pg17-builder /usr/lib/liblz4.so.1.10.0 /usr/lib/
|
||||
COPY --from=pg18-builder /usr/local/lib/libpq.so.5.18 /usr/lib/
|
||||
COPY --from=pg18-builder /usr/lib/libzstd.so.1.5.7 /usr/lib/
|
||||
COPY --from=pg18-builder /usr/lib/liblz4.so.1.10.0 /usr/lib/
|
||||
|
||||
RUN ln -s libpq.so.5.17 /usr/lib/libpq.so.5 && \
|
||||
ln -s libpq.so.5.17 /usr/lib/libpq.so && \
|
||||
RUN ln -s libpq.so.5.18 /usr/lib/libpq.so.5 && \
|
||||
ln -s libpq.so.5.18 /usr/lib/libpq.so && \
|
||||
ln -s libzstd.so.1.5.7 /usr/lib/libzstd.so.1 && \
|
||||
ln -s liblz4.so.1.10.0 /usr/lib/liblz4.so.1
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ REM Main build sequence Ends
|
||||
|
||||
REM WGET
|
||||
FOR /f "tokens=*" %%i IN ('npm info electron version') DO SET "ELECTRON_VERSION=%%i"
|
||||
SET ELECTRON_VERSION="35.4.0"
|
||||
|
||||
:GET_NW
|
||||
wget https://github.com/electron/electron/releases/download/v%ELECTRON_VERSION%/electron-v%ELECTRON_VERSION%-win32-x64.zip -O "%TMPDIR%\electron-v%ELECTRON_VERSION%-win32-x64.zip"
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO GET_NW
|
||||
|
||||
@@ -53,6 +53,7 @@ The default binary paths set in the container are as follows:
|
||||
.. code-block:: bash
|
||||
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg-18': '/usr/local/pgsql-18',
|
||||
'pg-17': '/usr/local/pgsql-17',
|
||||
'pg-16': '/usr/local/pgsql-16',
|
||||
'pg-15': '/usr/local/pgsql-15',
|
||||
|
||||
@@ -41,6 +41,9 @@ Use the fields in the *Definition* tab to define the function:
|
||||
will change to an input text field.
|
||||
* Use the drop-down listbox next to *Language* to select the implementation
|
||||
language. The default is *sql*.
|
||||
* Use the drop-down listbox next to *Depends on extensions* to select the extension that this function
|
||||
depends on (for example, plpgsql). If set, dropping the extension will automatically drop the
|
||||
function as well.
|
||||
* Use the fields in the *Arguments* to define an argument. Click the *Add*
|
||||
icon (+) to set parameters and values for the argument:
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 72 KiB |
@@ -81,9 +81,9 @@ following options (in alphabetical order):
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Trigger(s)* | Click to *Disable* or *Enable* trigger(s) for the currently selected table. Options are displayed on the flyout menu. |
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| *Truncate* | Click to remove all rows from a table (*Truncate*), to remove all rows from a table and its child tables |
|
||||
| | (*Truncate Cascade*) or to remove all rows from a table and automatically restart sequences owned by columns |
|
||||
| | (*Truncate Restart Identity*). Options are displayed on the flyout menu. |
|
||||
| *Truncate* | Click to remove all rows from a table/foreign tables (*Truncate*), to remove all rows from a table/foreign tables and |
|
||||
| | its child tables (*Truncate Cascade*) or to remove all rows from a table/foreign tables and automatically restart |
|
||||
| | sequences owned by columns (*Truncate Restart Identity*). Options are displayed on the flyout menu. |
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
| *View Data* | Click to access a context menu that provides several options for viewing data (see below). |
|
||||
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
@@ -12,6 +12,8 @@ notes for it.
|
||||
:maxdepth: 1
|
||||
|
||||
|
||||
release_notes_9_9
|
||||
release_notes_9_8
|
||||
release_notes_9_7
|
||||
release_notes_9_6
|
||||
release_notes_9_5
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
***********
|
||||
Version 9.8
|
||||
***********
|
||||
|
||||
Release date: 2025-09-04
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v9.7.
|
||||
|
||||
Supported Database Servers
|
||||
**************************
|
||||
**PostgreSQL**: 13, 14, 15, 16 and 17
|
||||
|
||||
**EDB Advanced Server**: 13, 14, 15, 16 and 17
|
||||
|
||||
Bundled PostgreSQL Utilities
|
||||
****************************
|
||||
**psql**, **pg_dump**, **pg_dumpall**, **pg_restore**: 17.5
|
||||
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #6396 <https://github.com/pgadmin-org/pgadmin4/issues/6396>`_ - Add menu items for truncating foreign tables.
|
||||
| `Issue #7928 <https://github.com/pgadmin-org/pgadmin4/issues/7928>`_ - Added Debian Trixie as a supported platform for pgAdmin.
|
||||
| `Issue #8891 <https://github.com/pgadmin-org/pgadmin4/issues/8891>`_ - Allow user to configure security related gunicorn parameters.
|
||||
| `Issue #9093 <https://github.com/pgadmin-org/pgadmin4/issues/9093>`_ - Change the default pgAdmin theme to System.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
| `Issue #7448 <https://github.com/pgadmin-org/pgadmin4/issues/7448>`_ - Remove usage of BrowserFS as it is deprecated.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #9090 <https://github.com/pgadmin-org/pgadmin4/issues/9090>`_ - Pin Paramiko to version 3.5.1 to fix the DSSKey error introduced in the latest release.
|
||||
| `Issue #9095 <https://github.com/pgadmin-org/pgadmin4/issues/9095>`_ - Fixed an issue where pgAdmin config migration was failing while upgrading to v9.7.
|
||||
| `Issue #9114 <https://github.com/pgadmin-org/pgadmin4/issues/9114>`_ - Fixed Cross-Origin Opener Policy (COOP) vulnerability in the OAuth 2.0 authentication flow (CVE-2025-9636).
|
||||
| `Issue #9116 <https://github.com/pgadmin-org/pgadmin4/issues/9116>`_ - Fixed an issue where editor shortcuts fail when using Option key combinations on macOS, due to macOS treating Option+Key as a different key input.
|
||||
@@ -0,0 +1,40 @@
|
||||
***********
|
||||
Version 9.9
|
||||
***********
|
||||
|
||||
Release date: 2025-10-16
|
||||
|
||||
This release contains a number of bug fixes and new features since the release of pgAdmin 4 v9.8.
|
||||
|
||||
Supported Database Servers
|
||||
**************************
|
||||
**PostgreSQL**: 13, 14, 15, 16, 17 and 18
|
||||
|
||||
**EDB Advanced Server**: 13, 14, 15, 16 and 17
|
||||
|
||||
Bundled PostgreSQL Utilities
|
||||
****************************
|
||||
**psql**, **pg_dump**, **pg_dumpall**, **pg_restore**: 17.5
|
||||
|
||||
|
||||
New features
|
||||
************
|
||||
|
||||
| `Issue #6385 <https://github.com/pgadmin-org/pgadmin4/issues/6385>`_ - Add support of DEPENDS/NO DEPENDS ON EXTENSION for ALTER FUNCTION.
|
||||
| `Issue #6394 <https://github.com/pgadmin-org/pgadmin4/issues/6394>`_ - Added "MULTIRANGE_TYPE_NAME" option while creating a Range Type.
|
||||
| `Issue #6395 <https://github.com/pgadmin-org/pgadmin4/issues/6395>`_ - Added "SUBSCRIPT" option while creating a External Type.
|
||||
| `Issue #6996 <https://github.com/pgadmin-org/pgadmin4/issues/6996>`_ - Added option to skip the password dialog when using an identity file.
|
||||
| `Issue #8932 <https://github.com/pgadmin-org/pgadmin4/issues/8932>`_ - Added 'failover' and 'two_phase' parameter support in CREATE/ALTER SUBSCRIPTION for PostgreSQL v17+.
|
||||
| `Issue #9225 <https://github.com/pgadmin-org/pgadmin4/issues/9225>`_ - Add support for initializing the pgAdmin4 Kubernetes Helm chart.
|
||||
|
||||
Housekeeping
|
||||
************
|
||||
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Issue #9098 <https://github.com/pgadmin-org/pgadmin4/issues/9098>`_ - Fixed an issue where the query tool displayed 'default' instead of 'null' for null text data in the data output.
|
||||
| `Issue #9125 <https://github.com/pgadmin-org/pgadmin4/issues/9125>`_ - Fixed an issue where the pgAdmin configuration database wasn't being created on a fresh install when an external database was used for the configuration.
|
||||
| `Issue #9157 <https://github.com/pgadmin-org/pgadmin4/issues/9157>`_ - Fixed an issue where shortcuts are not working as expected on multiple keyboard layouts.
|
||||
| `Issue #9158 <https://github.com/pgadmin-org/pgadmin4/issues/9158>`_ - Fixed an issue where saving the newly changed preferences was not reflecting on the preferences tab.
|
||||
@@ -177,6 +177,9 @@ not be able to connect directly.
|
||||
*Identity file* field to specify the location of the key file.
|
||||
* If the SSH host is expecting a password of the user name or an identity file
|
||||
if being used, use the *Password* field to specify the password.
|
||||
* Check the box next to *Prompt for password?* to to have pgAdmin prompt for
|
||||
a password if the identity file includes one. This setting applies only when
|
||||
using an identity file, which may or may not require a password.
|
||||
* Check the box next to *Save password?* to instruct pgAdmin to save the
|
||||
password for future use. Use
|
||||
:ref:`Clear SSH Tunnel Password <clear_saved_passwords>` to remove the saved
|
||||
|
||||
@@ -106,6 +106,7 @@ Use the *With* tab to define some parameters for a subscription:
|
||||
* Move the *Run as owner?* switch to *true* position to specify all replication actions are performed as the subscription owner. If *false*, replication workers will perform actions on each table as the owner of that table. The default is *false*. This option is available only on PostgreSQL 16 and above.
|
||||
* Use the *Password required?* to specify whether connections to the publisher made as a result of this subscription must use password authentication. This setting is ignored when the subscription is owned by a superuser. The default is true. Only superusers can set this value to *false*. This option is available only on PostgreSQL 16 and above.
|
||||
* Use the *Origin* to specify whether the subscription will request the publisher to only send changes that don't have an origin or send changes regardless of origin. The default is *any*. This option is available only on PostgreSQL 16 and above.
|
||||
* Use the *Failover* to specify whether the replication slots associated with the subscription are enabled to be synced to the standbys so that logical replication can be resumed from the new primary after failover. The default is false. This option is available only on PostgreSQL 17 and above.
|
||||
|
||||
Click the *SQL* tab to continue.
|
||||
|
||||
|
||||
@@ -109,17 +109,17 @@ On the *Optional-1* tab:
|
||||
to select a type_modifier_output_function. It is allowed to omit the
|
||||
type_modifier_output_function, in which case the default display format is the
|
||||
stored typmod integer value enclosed in parentheses.
|
||||
* Use the drop-down listbox next to the optional *Analyze function* field to
|
||||
select a function for performing type-specific statistics collection for
|
||||
columns of the data type.
|
||||
* Use the drop-down listbox next to the optional *Subscript function* field to
|
||||
select a function for allows the data type to be subscripted in SQL commands.
|
||||
* Use the optional *Internal length* to specify a value for internal
|
||||
representation.
|
||||
* Move the *Variable?* switch to specify the internal representation is of
|
||||
variable length (VARIABLE). The default is a fixed length positive integer.
|
||||
* Specify a default value in the optional *Default* field in cases where a
|
||||
column of the data type defaults to something other than the null value.
|
||||
Specify the default with the DEFAULT key word. (A default can be overridden
|
||||
by an explicit DEFAULT clause attached to a particular column.)
|
||||
* Use the drop-down listbox next to the optional *Analyze function* field to
|
||||
select a function for performing type-specific statistics collection for
|
||||
columns of the data type.
|
||||
* Use the drop-down listbox next to the optional *Category type* field to help
|
||||
control which implicit cast will be applied in ambiguous situations.
|
||||
* Move the *Preferred?* switch to *Yes* to specify the selected category type is
|
||||
@@ -162,6 +162,9 @@ disabled.
|
||||
values to a canonical form.
|
||||
* Use the drop-down listbox next to *Sub-type diff function* to select a
|
||||
user-defined subtype_diff function.
|
||||
* Specify the optional *Multirange type name* parameter to specifies the
|
||||
name of the corresponding multirange type. If not specified, this name is
|
||||
chosen automatically.
|
||||
|
||||
If you select *Shell* in the *Type* field, the *Definition* tab displays the
|
||||
*Shell* panel:
|
||||
|
||||
@@ -5,8 +5,8 @@ Debian and Ubuntu.
|
||||
|
||||
## Supported platforms
|
||||
|
||||
* Debian 11 & 12
|
||||
* Ubuntu 22.04, 24.04 & 24.10
|
||||
* Debian 11, 12 & 13
|
||||
* Ubuntu 22.04, 24.04 & 25.04
|
||||
|
||||
## Build configuration
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ CA_FILE = '/etc/ssl/certs/ca-certificates.crt'
|
||||
LOG_FILE = '/dev/null'
|
||||
HELP_PATH = '../../docs'
|
||||
DEFAULT_BINARY_PATHS = {
|
||||
'pg': '/usr/local/pgsql-17',
|
||||
'pg': '/usr/local/pgsql-18',
|
||||
'pg-18': '/usr/local/pgsql-18',
|
||||
'pg-17': '/usr/local/pgsql-17',
|
||||
'pg-16': '/usr/local/pgsql-16',
|
||||
'pg-15': '/usr/local/pgsql-15',
|
||||
@@ -188,5 +189,5 @@ fi
|
||||
if [ -n "${PGADMIN_ENABLE_TLS}" ]; then
|
||||
exec /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" --keyfile /certs/server.key --certfile /certs/server.cert -c gunicorn_config.py run_pgadmin:app
|
||||
else
|
||||
exec /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" -c gunicorn_config.py run_pgadmin:app
|
||||
exec /venv/bin/gunicorn --limit-request-line "${GUNICORN_LIMIT_REQUEST_LINE:-8190}" --limit-request-fields "${GUNICORN_LIMIT_REQUEST_FIELDS:-100}" --limit-request-field_size "${GUNICORN_LIMIT_REQUEST_FIELD_SIZE:-8190}" --timeout "${TIMEOUT}" --bind "${BIND_ADDRESS}" -w 1 --threads "${GUNICORN_THREADS:-25}" --access-logfile "${GUNICORN_ACCESS_LOGFILE:--}" -c gunicorn_config.py run_pgadmin:app
|
||||
fi
|
||||
@@ -0,0 +1,11 @@
|
||||
apiVersion: v2
|
||||
name: pgadmin4-helm
|
||||
version: 9.9.0
|
||||
description: pgAdmin is the most popular and feature rich Open Source administration and development platform for PostgreSQL, the most advanced Open Source database in the world.
|
||||
home: https://pgadmin.org
|
||||
sources: ["https://github.com/pgadmin-org/pgadmin4/tree/master/helm"]
|
||||
maintainers:
|
||||
- name: Koren Peretz
|
||||
url: https://github.com/KorenP1
|
||||
icon: data:image/png;base64,AAABAAEAiooAAAEAIACANAEAFgAAACgAAACKAAAAFAEAAAEAIAAAAAAAkCkBACMuAAAjLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAABk2cxNJRpMXeTaTKtk2gy05NoMu6TaDL7k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv2TaDLulGgy2JNoMrGTaDJ/lWYzPKpVVQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjmM5EpJpMXyTaDLdk2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMuWTaDKJk2wxGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJJtJAeSaTF8lGgy8pNoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy+JRoMYyJYjsNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkmg0MZRoMtiTaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDLkk2g0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSaDJbk2gy95NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/JRnMXIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJRpMmuTaDL+k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDGHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk2kzWpNoMv2TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gy/5NoMv+TaDL/k2gLine truncated
|
||||
appVersion: 9.9.0
|
||||
@@ -0,0 +1,41 @@
|
||||
# PgAdmin4 K8S Helm Chart
|
||||
|
||||
Its been a struggle to deploy pgadmin4 container on different restricted k8s distributions for example openshift, gke or vanilla k8s pod security standards.
|
||||
This helm chart follows best security measures and practices and compatible with all different security contexts and restrictions.
|
||||
Further explanation about the security implementation can be read here: https://korenp1.github.io
|
||||
|
||||
The helm chart also implements most pgadmin4 features, for instance, config_local.py, predefined server definitions or preferences.
|
||||
|
||||
The majority of features and values are covered in the helm chart but always can be more customable or tpl'able, open for contributions.
|
||||
|
||||
### Package && Push
|
||||
The chart should dump its version and appVersion in the Chart.yaml file every release and pushed to docker.io/dpage repository.
|
||||
`helm package . && helm push pgadmin4-helm-<VERSION>.tgz oci://docker.io/dpage`
|
||||
|
||||
### Installation Example:
|
||||
`helm install mypgadmin4 oci://docker.io/dpage/pgadmin4-helm --set ingress.enabled=true`
|
||||
|
||||
### Important Values
|
||||
| Value | Description | Default |
|
||||
| --------- | ----------- | ------- |
|
||||
| `containerPort` | Internal PgAdmin4 Port | `5050` |
|
||||
| `image.registry` | Image registry | `"docker.io"` |
|
||||
| `image.repository` | Image Repository | `"dpage/pgadmin4"` |
|
||||
| `image.tag` | Image tag (If empty, will use .Chart.AppVersion) | `""` |
|
||||
| `auth.email` | Admin Email | `"admin@pgadmin.org"` |
|
||||
| `auth.password` | Admin password (If both auth.password and auth.existingSecret are empty, the password will be randomly generated) | `""` |
|
||||
| `auth.existingSecret` | Existing secret name for admin password (If both auth.password and auth.existingSecret are empty, the password will be randomly generated) | `""` |
|
||||
| `extraEnvVars` | Extra environment variables | `[]` |
|
||||
| `config_local.enabled` | Whether to mount config_local.py file | `false` |
|
||||
| `config_local.data` | config_local.py configuration content | `""` |
|
||||
| `config_local.existingSecret` | Existing secret name containing config_local.py file | `""` |
|
||||
| `serverDefinitions.enabled` | Whether to mount servers.json | `false` |
|
||||
| `serverDefinitions.data` | Server definitions to import | `{}` |
|
||||
| `preferences.enabled` | Whether to mount preferences.json | `false` |
|
||||
| `preferences.data` | Preferences to load | `{}` |
|
||||
| `resources.*` | Allocated requests and limits resources | `{"requests": {...}, "limits": {...}}` |
|
||||
| `persistence.enabled` | PVC resource creation | `false` |
|
||||
| `service.type` | Service type | `"ClusterIP"` |
|
||||
| `service.loadBalancerIP` | Load balancer IP (Only if service.type is LoadBalancer) | `""` |
|
||||
| `ingress.enabled` | Ingress resource creation | `false` |
|
||||
| `ingress.hostname` | Ingress resource hostname | `"pgadmin4.local"` |
|
||||
@@ -0,0 +1,11 @@
|
||||
Thanks for using PgAdmin4 Helm Chart :)
|
||||
|
||||
Image: {{ template "pgadmin4.image" . }}
|
||||
|
||||
Credentials:
|
||||
Email: {{ .Values.auth.email }}
|
||||
Password: {{ printf "kubectl get secret %s -n %s -o jsonpath='{.data.%s}' | base64 -d" (include "pgadmin4.fullname" .) .Release.Namespace .Values.auth.passwordKey }}
|
||||
|
||||
Ingress: {{ ternary (tpl .Values.ingress.hostname .) "DISABLED" .Values.ingress.enabled }}
|
||||
|
||||
GOOD LUCK!
|
||||
@@ -0,0 +1,28 @@
|
||||
{{- define "pgadmin4.fullname" -}}
|
||||
{{- tpl .Values.fullname . -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "pgadmin4.image" -}}
|
||||
{{- printf "%s/%s:%s" (default .Values.image.registry .Values.global.imageRegistry) .Values.image.repository (default .Chart.AppVersion .Values.image.tag | toString) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "pgadmin4.serviceAccountName" -}}
|
||||
{{- default (ternary (include "pgadmin4.fullname" .) "default" .Values.serviceAccount.create) .Values.serviceAccount.name -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "renderSecurityContext" -}}
|
||||
{{- $securityContext := omit .securityContext "enabled" -}}
|
||||
{{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (ternary "true" "" (.context.Capabilities.APIVersions.Has "security.openshift.io/v1"))) -}}
|
||||
{{- $securityContext = omit $securityContext "fsGroup" "runAsUser" "runAsGroup" -}}
|
||||
{{- if not $securityContext.seLinuxOptions }}
|
||||
{{- $securityContext = omit $securityContext "seLinuxOptions" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if $securityContext.privileged }}
|
||||
{{- $securityContext = omit $securityContext "capabilities" -}}
|
||||
{{- end -}}
|
||||
{{- if not .context.Values.global.compatibility.appArmor.enabled }}
|
||||
{{- $securityContext = omit $securityContext "appArmorProfile" -}}
|
||||
{{- end -}}
|
||||
{{- $securityContext | toYaml -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.preferences.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}-preferences
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
preferences.json: | {{ dict "preferences" .Values.preferences.data | toPrettyJson | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,14 @@
|
||||
{{- if .Values.serverDefinitions.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}-server-definitions
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
data:
|
||||
servers.json: | {{ tpl (dict "Servers" .Values.serverDefinitions.data | toYaml) . | fromYaml | toPrettyJson | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,237 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: {{ default "pgadmin4" .Values.commonLabels.app }}
|
||||
{{- with omit .Values.commonLabels "app" }}
|
||||
{{- . | toYaml | nindent 6 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: {{ default "pgadmin4" .Values.commonLabels.app }}
|
||||
{{- with omit .Values.commonLabels "app" }}
|
||||
{{- . | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if or (not (empty .Values.commonAnnotations)) (not .Values.existingSecret) .Values.preferences.enabled .Values.serverDefinitions.enabled }}
|
||||
annotations:
|
||||
{{- with .Values.commonAnnotations }}
|
||||
{{- . | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.existingSecret }}
|
||||
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
{{- if and .Values.config_local.enabled (empty .Values.config_local.existingSecret) }}
|
||||
checksum/secret-config: {{ include (print $.Template.BasePath "/secret-config.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
{{- if .Values.serverDefinitions.enabled }}
|
||||
checksum/configmap-server-definitions: {{ include (print $.Template.BasePath "/configmap-serverDefinitions.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
{{- if .Values.preferences.enabled }}
|
||||
checksum/configmap-preferences: {{ include (print $.Template.BasePath "/configmap-preferences.yaml") . | sha256sum }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if or .Values.global.imagePullSecrets .Values.image.pullSecrets }}
|
||||
imagePullSecrets: {{- concat .Values.global.imagePullSecrets .Values.image.pullSecrets | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ template "pgadmin4.serviceAccountName" . }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
||||
{{- if .Values.podSecurityContext.enabled }}
|
||||
securityContext: {{- include "renderSecurityContext" (dict "securityContext" .Values.podSecurityContext "context" .) | nindent 8 }}
|
||||
enableServiceLinks: {{ .Values.enableServiceLinks }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: empty-dir
|
||||
emptyDir: {}
|
||||
{{- if .Values.persistence.enabled }}
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ template "pgadmin4.fullname" . }}
|
||||
{{- end }}
|
||||
{{- if .Values.config_local.enabled }}
|
||||
- name: config-local
|
||||
secret:
|
||||
secretName: {{ default (printf "%s-config" (include "pgadmin4.fullname" .)) .Values.config_local.existingSecret }}
|
||||
items:
|
||||
- key: {{ .Values.config_local.configKey }}
|
||||
path: {{ .Values.config_local.configKey }}
|
||||
{{- end }}
|
||||
{{- if .Values.serverDefinitions.enabled }}
|
||||
- name: server-definitions
|
||||
configMap:
|
||||
name: {{ template "pgadmin4.fullname" . }}-server-definitions
|
||||
items:
|
||||
- key: servers.json
|
||||
path: servers.json
|
||||
{{- end }}
|
||||
{{- if .Values.preferences.enabled }}
|
||||
- name: preferences
|
||||
configMap:
|
||||
name: {{ template "pgadmin4.fullname" . }}-preferences
|
||||
items:
|
||||
- key: preferences.json
|
||||
path: preferences.json
|
||||
{{- end }}
|
||||
{{- with .Values.extraVolumes }}
|
||||
{{- . | toYaml | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: pgadmin4
|
||||
{{- if .Values.containerSecurityContext.enabled }}
|
||||
securityContext: {{- include "renderSecurityContext" (dict "securityContext" .Values.containerSecurityContext "context" .) | nindent 12 }}
|
||||
{{- end }}
|
||||
image: {{ template "pgadmin4.image" . }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
containerPort: {{ .Values.containerPort }}
|
||||
resources:
|
||||
requests:
|
||||
cpu: {{ .Values.resources.requests.cpu }}
|
||||
memory: {{ .Values.resources.requests.memory }}
|
||||
limits:
|
||||
cpu: {{ .Values.resources.limits.cpu }}
|
||||
memory: {{ .Values.resources.limits.memory }}
|
||||
env:
|
||||
- name: PGADMIN_DEFAULT_EMAIL
|
||||
value: {{ .Values.auth.email }}
|
||||
- name: PGADMIN_DEFAULT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ default (include "pgadmin4.fullname" .) .Values.auth.existingSecret }}
|
||||
key: {{ .Values.auth.passwordKey }}
|
||||
- name: PGADMIN_LISTEN_PORT
|
||||
value: {{ .Values.containerPort | quote }}
|
||||
- name: PGADMIN_DISABLE_POSTFIX
|
||||
value: {{ .Values.disablePostfix | quote }}
|
||||
{{- with .Values.extraEnvVars }}
|
||||
{{- tpl (. | toYaml) $ | nindent 14 }}
|
||||
{{- end }}
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/pgadmin
|
||||
{{- if .Values.persistence.enabled }}
|
||||
name: data
|
||||
{{- else }}
|
||||
name: empty-dir
|
||||
subPath: data
|
||||
{{- end }}
|
||||
- name: empty-dir
|
||||
mountPath: /pgadmin4/config_distro.py
|
||||
subPath: config_distro.py
|
||||
- name: empty-dir
|
||||
mountPath: /usr/bin/python3
|
||||
subPath: python3
|
||||
- name: empty-dir
|
||||
mountPath: /tmp
|
||||
subPath: tmp
|
||||
- name: empty-dir
|
||||
mountPath: /var/log/pgadmin
|
||||
subPath: logs
|
||||
{{- if .Values.config_local.enabled }}
|
||||
- name: config-local
|
||||
mountPath: /pgadmin4/config_local.py
|
||||
subPath: {{ .Values.config_local.configKey }}
|
||||
{{- end }}
|
||||
{{- if .Values.serverDefinitions.enabled }}
|
||||
- name: server-definitions
|
||||
mountPath: /pgadmin4/servers.json
|
||||
subPath: servers.json
|
||||
{{- end }}
|
||||
{{- if .Values.preferences.enabled }}
|
||||
- name: preferences
|
||||
mountPath: /pgadmin4/preferences.json
|
||||
subPath: preferences.json
|
||||
{{- end }}
|
||||
{{- with .Values.extraVolumes }}
|
||||
{{- . | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.startupProbe.enabled }}
|
||||
startupProbe: {{- omit .Values.startupProbe "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.readinessProbe.enabled }}
|
||||
readinessProbe: {{- omit .Values.readinessProbe "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.livenessProbe.enabled }}
|
||||
livenessProbe: {{- omit .Values.livenessProbe "enabled" | toYaml | nindent 12 }}
|
||||
{{- end }}
|
||||
initContainers:
|
||||
- name: modify-config-distro-py-permissions
|
||||
image: {{ template "pgadmin4.image" . }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
command: ["sh", "-x", "-c"]
|
||||
args: ['cp /pgadmin4/config_distro.py . && chmod 777 config_distro.py']
|
||||
workingDir: /emptyDir
|
||||
volumeMounts:
|
||||
- name: empty-dir
|
||||
mountPath: /emptyDir
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
securityContext:
|
||||
seLinuxOptions: {}
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- if .Values.global.compatibility.appArmor.enabled }}
|
||||
appArmorProfile:
|
||||
type: RuntimeDefault
|
||||
{{- end }}
|
||||
windowsOptions:
|
||||
hostProcess: false
|
||||
- name: unset-python3-cli-net-cap
|
||||
image: {{ template "pgadmin4.image" . }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
command: ["sh", "-x", "-c"]
|
||||
args: ['ls /usr/bin/python3.* | sort -V -r | head -n 1 | xargs -I {} cp {} python3']
|
||||
workingDir: /emptyDir
|
||||
volumeMounts:
|
||||
- name: empty-dir
|
||||
mountPath: /emptyDir
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
securityContext:
|
||||
seLinuxOptions: {}
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- if .Values.global.compatibility.appArmor.enabled }}
|
||||
appArmorProfile:
|
||||
type: RuntimeDefault
|
||||
{{- end }}
|
||||
windowsOptions:
|
||||
hostProcess: false
|
||||
@@ -0,0 +1,4 @@
|
||||
{{- range .Values.extraDeploy }}
|
||||
---
|
||||
{{ tpl (. | toYaml) $ }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,24 @@
|
||||
{{- if .Values.ingress.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.ingress.annotations .Values.commonAnnotations }}
|
||||
annotations: {{ merge .Values.ingress.annotations .Values.commonAnnotations | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
rules:
|
||||
- host: {{ tpl .Values.ingress.hostname . }}
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
service:
|
||||
name: {{ template "pgadmin4.fullname" . }}
|
||||
port:
|
||||
name: http
|
||||
path: /
|
||||
pathType: Prefix
|
||||
{{- end }}
|
||||
@@ -0,0 +1,20 @@
|
||||
{{- if .Values.persistence.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if or .Values.global.defaultStorageClass .Values.persistence.storageClass }}
|
||||
storageClassName: {{ default .Values.global.defaultStorageClass .Values.persistence.storageClass }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size }}
|
||||
accessModes: {{ .Values.persistence.accessModes }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if and .Values.config_local.enabled (empty .Values.config_local.existingSecret) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}-config
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
{{ .Values.config_local.configKey }}: | {{ tpl .Values.config_local.data . | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,15 @@
|
||||
{{- if empty .Values.auth.existingSecret }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
type: Opaque
|
||||
stringData:
|
||||
{{ .Values.auth.passwordKey }}: {{ coalesce .Values.auth.password (dig "data" .Values.auth.passwordKey "" (lookup "v1" "Secret" .Release.Namespace (include "pgadmin4.fullname" .)) | b64dec) (randAlphaNum 12) | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,25 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.fullname" . }}
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if or .Values.service.annotations .Values.commonAnnotations }}
|
||||
annotations: {{ merge .Values.service.annotations .Values.commonAnnotations | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
{{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }}
|
||||
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
|
||||
{{- end }}
|
||||
selector:
|
||||
app: {{ default "pgadmin4" .Values.commonLabels.app }}
|
||||
{{- with omit .Values.commonLabels "app" }}
|
||||
{{- . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
port: {{ .Values.service.port }}
|
||||
@@ -0,0 +1,13 @@
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ template "pgadmin4.serviceAccountName" . }}
|
||||
{{- with .Values.commonLabels }}
|
||||
labels: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with .Values.commonAnnotations }}
|
||||
annotations: {{ . | toYaml | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,155 @@
|
||||
global:
|
||||
imageRegistry: ""
|
||||
defaultStorageClass: ""
|
||||
imagePullSecrets: []
|
||||
compatibility:
|
||||
openshift:
|
||||
adaptSecurityContext: auto
|
||||
appArmor:
|
||||
enabled: false
|
||||
|
||||
fullname: pgadmin4
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: dpage/pgadmin4
|
||||
tag: ""
|
||||
pullPolicy: IfNotPresent
|
||||
pullSecrets: []
|
||||
|
||||
commonLabels:
|
||||
app: pgadmin4
|
||||
commonAnnotations: {}
|
||||
|
||||
extraDeploy: []
|
||||
|
||||
replicas: 1
|
||||
|
||||
containerPort: 5050
|
||||
disablePostfix: true
|
||||
enableServiceLinks: false
|
||||
auth:
|
||||
email: admin@pgadmin.org
|
||||
password: ""
|
||||
existingSecret: ""
|
||||
passwordKey: password
|
||||
extraEnvVars: []
|
||||
# - name: PGADMIN_CONFIG_LOGIN_BANNER
|
||||
# value: '"Welcome to pgAdmin4 :)"'
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
config_local:
|
||||
enabled: false
|
||||
existingSecret: ""
|
||||
configKey: config_local.py
|
||||
data: ""
|
||||
# data: |
|
||||
# DEBUG = True
|
||||
# JSON_LOGGER = True
|
||||
# AUTHENTICATION_SOURCES = ['oauth2', 'internal']
|
||||
|
||||
serverDefinitions:
|
||||
enabled: false
|
||||
data: {}
|
||||
# "1":
|
||||
# Name: Minimally Defined Server
|
||||
# Group: Servers
|
||||
# Port: 5432
|
||||
# Username: postgres
|
||||
# Host: myHost
|
||||
# MaintenanceDB: postgres
|
||||
# ConnectionParameters:
|
||||
# sslmode: prefer
|
||||
# connect_timeout: 10
|
||||
|
||||
preferences:
|
||||
enabled: false
|
||||
data: {}
|
||||
# misc:user_interface:theme: dark
|
||||
# file_manager:options:file_upload_size: 500
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 1Gi
|
||||
storageClass: ""
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
annotations: {}
|
||||
loadBalancerIP: ""
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
name: ""
|
||||
automountServiceAccountToken: false
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
hostname: pgadmin4.local
|
||||
annotations: {}
|
||||
|
||||
startupProbe:
|
||||
enabled: false
|
||||
httpGet:
|
||||
path: /misc/ping
|
||||
port: http
|
||||
initialDelaySeconds: null
|
||||
periodSeconds: null
|
||||
timeoutSeconds: null
|
||||
failureThreshold: null
|
||||
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
httpGet:
|
||||
path: /misc/ping
|
||||
port: http
|
||||
initialDelaySeconds: null
|
||||
periodSeconds: null
|
||||
timeoutSeconds: null
|
||||
failureThreshold: null
|
||||
|
||||
livenessProbe:
|
||||
enabled: false
|
||||
httpGet:
|
||||
path: /misc/ping
|
||||
port: http
|
||||
initialDelaySeconds: null
|
||||
periodSeconds: null
|
||||
timeoutSeconds: null
|
||||
failureThreshold: null
|
||||
|
||||
podSecurityContext:
|
||||
enabled: true
|
||||
fsGroupChangePolicy: Always
|
||||
sysctls: []
|
||||
supplementalGroups: []
|
||||
fsGroup: 1001
|
||||
|
||||
containerSecurityContext:
|
||||
enabled: true
|
||||
seLinuxOptions: {}
|
||||
runAsUser: 1001
|
||||
runAsGroup: 1001
|
||||
runAsNonRoot: true
|
||||
privileged: false
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
appArmorProfile:
|
||||
type: RuntimeDefault
|
||||
windowsOptions:
|
||||
hostProcess: false
|
||||
@@ -140,8 +140,6 @@ _build_runtime() {
|
||||
fi
|
||||
|
||||
ELECTRON_VERSION="$(npm info electron version)"
|
||||
# Can't use the latest as it is not compatible with few OS versions.
|
||||
ELECTRON_VERSION="35.4.0"
|
||||
|
||||
pushd "${BUILDROOT}" > /dev/null || exit
|
||||
while true;do
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# shellcheck shell=bash
|
||||
|
||||
# uname -m returns "x86_64" on Intel, but we need "x64"
|
||||
ARCH="x64"
|
||||
if [ "$(uname -m)" == "arm64" ]; then
|
||||
ARCH="arm64"
|
||||
fi
|
||||
|
||||
_setup_env() {
|
||||
FUNCS_DIR=$(cd "$(dirname "$0")" && pwd)/../..
|
||||
APP_RELEASE=$(grep "^APP_RELEASE" "${FUNCS_DIR}/web/version.py" | cut -d"=" -f2 | sed 's/ //g')
|
||||
@@ -11,7 +17,7 @@ _setup_env() {
|
||||
APP_LONG_VERSION=${APP_LONG_VERSION}-${APP_SUFFIX}
|
||||
fi
|
||||
BUNDLE_DIR="${BUILD_ROOT}/${APP_NAME}.app"
|
||||
DMG_NAME="${DIST_ROOT}"/$(echo "${APP_NAME}" | sed 's/ //g' | awk '{print tolower($0)}')-"${APP_LONG_VERSION}-$(uname -m).dmg"
|
||||
DMG_NAME="${DIST_ROOT}/$(echo "${APP_NAME}" | sed 's/ //g' | awk '{print tolower($0)}')-${APP_LONG_VERSION}-${ARCH}.dmg"
|
||||
PYTHON_OS_VERSION="11"
|
||||
}
|
||||
|
||||
@@ -27,21 +33,14 @@ _build_runtime() {
|
||||
|
||||
test -d "${BUILD_ROOT}" || mkdir "${BUILD_ROOT}"
|
||||
# Get a fresh copy of electron
|
||||
# uname -m returns "x86_64" on Intel, but we need "x64"
|
||||
ELECTRON_ARCH="x64"
|
||||
if [ "$(uname -m)" == "arm64" ]; then
|
||||
ELECTRON_ARCH="arm64"
|
||||
fi
|
||||
|
||||
ELECTRON_VERSION="$(npm info electron version)"
|
||||
ELECTRON_VERSION="35.4.0"
|
||||
|
||||
pushd "${BUILD_ROOT}" > /dev/null || exit
|
||||
while true;do
|
||||
wget "https://github.com/electron/electron/releases/download/v${ELECTRON_VERSION}/electron-v${ELECTRON_VERSION}-darwin-${ELECTRON_ARCH}.zip" && break
|
||||
rm "electron-v${ELECTRON_VERSION}-darwin-${ELECTRON_ARCH}.zip"
|
||||
wget "https://github.com/electron/electron/releases/download/v${ELECTRON_VERSION}/electron-v${ELECTRON_VERSION}-darwin-${ARCH}.zip" && break
|
||||
rm "electron-v${ELECTRON_VERSION}-darwin-${ARCH}.zip"
|
||||
done
|
||||
unzip "electron-v${ELECTRON_VERSION}-darwin-${ELECTRON_ARCH}.zip"
|
||||
unzip "electron-v${ELECTRON_VERSION}-darwin-${ARCH}.zip"
|
||||
popd > /dev/null || exit
|
||||
# WGET END
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ WizardImageFile=sidebar.bmp
|
||||
MinVersion={#MinimumWindowsVer}
|
||||
SignTool=pgAdminSigntool
|
||||
SignedUninstaller=yes
|
||||
CloseApplications=yes
|
||||
|
||||
[Languages]
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
###############################################################################
|
||||
|
||||
Authlib==1.6.*
|
||||
azure-identity==1.24.0
|
||||
azure-identity==1.25.0
|
||||
azure-mgmt-rdbms==10.1.0
|
||||
azure-mgmt-resource==24.0.0
|
||||
azure-mgmt-subscription==3.1.1
|
||||
bcrypt==4.3.*
|
||||
bcrypt==5.0.*
|
||||
boto3==1.40.*
|
||||
cryptography==45.0.*
|
||||
cryptography==46.0.*
|
||||
Flask-Babel==4.0.*
|
||||
Flask-Compress==1.*
|
||||
Flask-Login==0.*
|
||||
@@ -34,24 +34,26 @@ Flask-WTF==1.2.*
|
||||
Flask==3.1.*
|
||||
google-api-python-client==2.*
|
||||
google-auth-oauthlib==1.2.2
|
||||
gssapi==1.9.*
|
||||
gssapi==1.10.*
|
||||
jsonformatter~=0.3.4
|
||||
keyring==25.*
|
||||
ldap3==2.*
|
||||
libgravatar==1.0.*
|
||||
paramiko==3.5.1
|
||||
passlib==1.*
|
||||
psutil==7.0.*
|
||||
psycopg[c]==3.2.9
|
||||
psutil==7.1.*
|
||||
psycopg[c]==3.2.10
|
||||
pyotp==2.*
|
||||
python-dateutil==2.*
|
||||
pytz==2025.*
|
||||
# pinned for https://github.com/andfoy/pywinpty/issues/545
|
||||
pywinpty==2.0.*; sys_platform=="win32"
|
||||
qrcode[pil]==8.*; python_version >= '3.9'
|
||||
setuptools==80.*
|
||||
SQLAlchemy==2.*
|
||||
sqlparse==0.*
|
||||
sshtunnel==0.*
|
||||
typer[all]==0.16.*
|
||||
typer[all]==0.19.*
|
||||
urllib3==1.26.*; python_version <= '3.9'
|
||||
urllib3==2.5.*; python_version > '3.9'
|
||||
user-agents==2.2.0
|
||||
|
||||
@@ -12,13 +12,13 @@
|
||||
},
|
||||
"packageManager": "yarn@4.9.2",
|
||||
"devDependencies": {
|
||||
"electron": "37.2.6",
|
||||
"eslint": "^9.33.0",
|
||||
"eslint-plugin-unused-imports": "^4.1.4"
|
||||
"electron": "38.2.1",
|
||||
"eslint": "^9.37.0",
|
||||
"eslint-plugin-unused-imports": "^4.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.11.0",
|
||||
"axios": "^1.12.0",
|
||||
"electron-context-menu": "^4.1.0",
|
||||
"electron-store": "^10.1.0"
|
||||
"electron-store": "^11.0.2"
|
||||
}
|
||||
}
|
||||
@@ -21,24 +21,24 @@ export function updateConfigAndMenus(event, configStore, pgAdminMainScreen, menu
|
||||
// This function registers autoUpdater event listeners ONCE
|
||||
function registerAutoUpdaterEvents({ pgAdminMainScreen, configStore, menuCallbacks }) {
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
misc.writeServerLog('[Auto-Updater]: Checking for update...');
|
||||
misc.writeServerLog('[Auto-Updater]: Checking for update.');
|
||||
});
|
||||
|
||||
autoUpdater.on('update-available', () => {
|
||||
updateConfigAndMenus('update-available', configStore, pgAdminMainScreen, menuCallbacks);
|
||||
misc.writeServerLog('[Auto-Updater]: Update downloading...');
|
||||
misc.writeServerLog('[Auto-Updater]: Update downloading.');
|
||||
pgAdminMainScreen.webContents.send('notifyAppAutoUpdate', { update_downloading: true });
|
||||
});
|
||||
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
updateConfigAndMenus('update-not-available', configStore, pgAdminMainScreen, menuCallbacks);
|
||||
misc.writeServerLog('[Auto-Updater]: No update available...');
|
||||
misc.writeServerLog('[Auto-Updater]: No update available.');
|
||||
pgAdminMainScreen.webContents.send('notifyAppAutoUpdate', { no_update_available: true });
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', () => {
|
||||
updateConfigAndMenus('update-downloaded', configStore, pgAdminMainScreen, menuCallbacks);
|
||||
misc.writeServerLog('[Auto-Updater]: Update downloaded...');
|
||||
misc.writeServerLog('[Auto-Updater]: Update downloaded.');
|
||||
pgAdminMainScreen.webContents.send('notifyAppAutoUpdate', { update_downloaded: true });
|
||||
});
|
||||
|
||||
@@ -82,7 +82,7 @@ function handleSendDataForAppUpdate({
|
||||
|
||||
try {
|
||||
autoUpdater.setFeedURL({ url: serverUrl });
|
||||
misc.writeServerLog('[Auto-Updater]: Initiating update check...');
|
||||
misc.writeServerLog('[Auto-Updater]: Initiating update check.');
|
||||
autoUpdater.checkForUpdates();
|
||||
} catch (err) {
|
||||
misc.writeServerLog('[Auto-Updater]: Error setting autoUpdater feed URL: ' + err.message);
|
||||
|
||||
@@ -75,7 +75,7 @@ function handleAutoUpdateMenu(menuFile, configStore, callbacks) {
|
||||
menuFile.submenu.unshift({
|
||||
name: 'mnu_restart_to_update',
|
||||
id: 'mnu_restart_to_update',
|
||||
label: 'Restart to Update...',
|
||||
label: 'Restart to Update',
|
||||
enabled: true,
|
||||
priority: 998,
|
||||
click: callbacks['restart_to_update'],
|
||||
|
||||
@@ -443,14 +443,14 @@ function notifyUpdateInstalled() {
|
||||
try {
|
||||
// Notify renderer
|
||||
if (pgAdminMainScreen) {
|
||||
misc.writeServerLog('[Auto-Updater]: Update installed successfully...');
|
||||
misc.writeServerLog('[Auto-Updater]: Update installed successfully.');
|
||||
setTimeout(() => {
|
||||
pgAdminMainScreen.webContents.send('notifyAppAutoUpdate', {update_installed: true});
|
||||
}, 10000);
|
||||
} else {
|
||||
// If main screen not ready, wait and send after it's created
|
||||
app.once('browser-window-created', (event, window) => {
|
||||
misc.writeServerLog('[Auto-Updater]: Update installed successfully...');
|
||||
misc.writeServerLog('[Auto-Updater]: Update installed successfully.');
|
||||
setTimeout(() => {
|
||||
pgAdminMainScreen.webContents.send('notifyAppAutoUpdate', {update_installed: true});
|
||||
}, 10000);
|
||||
|
||||
@@ -24,14 +24,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint-community/eslint-utils@npm:^4.2.0":
|
||||
version: 4.7.0
|
||||
resolution: "@eslint-community/eslint-utils@npm:4.7.0"
|
||||
"@eslint-community/eslint-utils@npm:^4.8.0":
|
||||
version: 4.9.0
|
||||
resolution: "@eslint-community/eslint-utils@npm:4.9.0"
|
||||
dependencies:
|
||||
eslint-visitor-keys: "npm:^3.4.3"
|
||||
peerDependencies:
|
||||
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
|
||||
checksum: 10c0/c0f4f2bd73b7b7a9de74b716a664873d08ab71ab439e51befe77d61915af41a81ecec93b408778b3a7856185244c34c2c8ee28912072ec14def84ba2dec70adf
|
||||
checksum: 10c0/8881e22d519326e7dba85ea915ac7a143367c805e6ba1374c987aa2fbdd09195cc51183d2da72c0e2ff388f84363e1b220fd0d19bef10c272c63455162176817
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -53,19 +53,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/config-helpers@npm:^0.3.1":
|
||||
version: 0.3.1
|
||||
resolution: "@eslint/config-helpers@npm:0.3.1"
|
||||
checksum: 10c0/f6c5b3a0b76a0d7d84cc93e310c259e6c3e0792ddd0a62c5fc0027796ffae44183432cb74b2c2b1162801ee1b1b34a6beb5d90a151632b4df7349f994146a856
|
||||
"@eslint/config-helpers@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "@eslint/config-helpers@npm:0.4.0"
|
||||
dependencies:
|
||||
"@eslint/core": "npm:^0.16.0"
|
||||
checksum: 10c0/4e20c13aaeba1fa024983785df6625b36c8f4415b2433097982e1ccb08db9909e2f7bf60b793538d52ecfd572f2c4eec39a884c13c185cb6be35151f053beed5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/core@npm:^0.15.2":
|
||||
version: 0.15.2
|
||||
resolution: "@eslint/core@npm:0.15.2"
|
||||
"@eslint/core@npm:^0.16.0":
|
||||
version: 0.16.0
|
||||
resolution: "@eslint/core@npm:0.16.0"
|
||||
dependencies:
|
||||
"@types/json-schema": "npm:^7.0.15"
|
||||
checksum: 10c0/c17a6dc4f5a6006ecb60165cc38bcd21fefb4a10c7a2578a0cfe5813bbd442531a87ed741da5adab5eb678e8e693fda2e2b14555b035355537e32bcec367ea17
|
||||
checksum: 10c0/f27496a244ccfdca3e0fbc3331f9da3f603bdf1aa431af0045a3205826789a54493bc619ad6311a9090eaf7bc25798ff4e265dea1eccd2df9ce3b454f7e7da27
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -86,10 +88,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/js@npm:9.33.0":
|
||||
version: 9.33.0
|
||||
resolution: "@eslint/js@npm:9.33.0"
|
||||
checksum: 10c0/4c42c9abde76a183b8e47205fd6c3116b058f82f07b6ad4de40de56cdb30a36e9ecd40efbea1b63a84d08c206aadbb0aa39a890197e1ad6455a8e542df98f186
|
||||
"@eslint/js@npm:9.37.0":
|
||||
version: 9.37.0
|
||||
resolution: "@eslint/js@npm:9.37.0"
|
||||
checksum: 10c0/84f98a6213522fc76ea104bd910f606136200bd918544e056a7a22442d3f9d5c3c5cd7f4cdf2499d49b1fa140155b87d597a1f16d01644920f05c228e9ca0378
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -100,13 +102,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@eslint/plugin-kit@npm:^0.3.5":
|
||||
version: 0.3.5
|
||||
resolution: "@eslint/plugin-kit@npm:0.3.5"
|
||||
"@eslint/plugin-kit@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "@eslint/plugin-kit@npm:0.4.0"
|
||||
dependencies:
|
||||
"@eslint/core": "npm:^0.15.2"
|
||||
"@eslint/core": "npm:^0.16.0"
|
||||
levn: "npm:^0.4.1"
|
||||
checksum: 10c0/c178c1b58c574200c0fd125af3e4bc775daba7ce434ba6d1eeaf9bcb64b2e9fea75efabffb3ed3ab28858e55a016a5efa95f509994ee4341b341199ca630b89e
|
||||
checksum: 10c0/125614e902bb34c041da859794c47ac2ec4a814f5d9e7c4d37fcd34b38d8ee5cf1f97020d38d168885d9bf4046a9a7decb86b4cee8dac9eedcc6ad08ebafe204
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -118,12 +120,12 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@humanfs/node@npm:^0.16.6":
|
||||
version: 0.16.6
|
||||
resolution: "@humanfs/node@npm:0.16.6"
|
||||
version: 0.16.7
|
||||
resolution: "@humanfs/node@npm:0.16.7"
|
||||
dependencies:
|
||||
"@humanfs/core": "npm:^0.19.1"
|
||||
"@humanwhocodes/retry": "npm:^0.3.0"
|
||||
checksum: 10c0/8356359c9f60108ec204cbd249ecd0356667359b2524886b357617c4a7c3b6aace0fd5a369f63747b926a762a88f8a25bc066fa1778508d110195ce7686243e1
|
||||
"@humanwhocodes/retry": "npm:^0.4.0"
|
||||
checksum: 10c0/9f83d3cf2cfa37383e01e3cdaead11cd426208e04c44adcdd291aa983aaf72d7d3598844d2fe9ce54896bb1bf8bd4b56883376611c8905a19c44684642823f30
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -134,14 +136,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@humanwhocodes/retry@npm:^0.3.0":
|
||||
version: 0.3.1
|
||||
resolution: "@humanwhocodes/retry@npm:0.3.1"
|
||||
checksum: 10c0/f0da1282dfb45e8120480b9e2e275e2ac9bbe1cf016d046fdad8e27cc1285c45bb9e711681237944445157b430093412b4446c1ab3fc4bb037861b5904101d3b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@humanwhocodes/retry@npm:^0.4.2":
|
||||
"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2":
|
||||
version: 0.4.3
|
||||
resolution: "@humanwhocodes/retry@npm:0.4.3"
|
||||
checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42
|
||||
@@ -207,20 +202,20 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:*":
|
||||
version: 24.2.1
|
||||
resolution: "@types/node@npm:24.2.1"
|
||||
version: 24.7.0
|
||||
resolution: "@types/node@npm:24.7.0"
|
||||
dependencies:
|
||||
undici-types: "npm:~7.10.0"
|
||||
checksum: 10c0/439a3c7edf88a298e0c92e46f670234070b892589c3b06e82cc86c47a7e1cf220f4a4b4736ec6ac7e4b9e1c40d7b6d443a1e22f99dd17f13f9dd15de3b32011b
|
||||
undici-types: "npm:~7.14.0"
|
||||
checksum: 10c0/f036c78062cb3a0d5c6586bf2dac347ed3f4af121cef4ab92c85c44e32be1c50aab5ba96955842b7f8165f0e0f1c8066d1813ae259372df6c0fa9fadb1116a3e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^22.7.7":
|
||||
version: 22.17.1
|
||||
resolution: "@types/node@npm:22.17.1"
|
||||
version: 22.18.8
|
||||
resolution: "@types/node@npm:22.18.8"
|
||||
dependencies:
|
||||
undici-types: "npm:~6.21.0"
|
||||
checksum: 10c0/b04063bdabfc4146af05d14d4fd23ee68615194473d0ef971ddef549b80b791f52c8f93abdd8d1092ee0257f3dea862fa233519244fd051e79233cdce614de14
|
||||
checksum: 10c0/54473730e7417b923fec427f62ed3204259acbd8e450a7593bad8ae02a75effcfcc864b34bf02c108eeb9c04a404791687f42b801bafa5264a8761f4df9122fd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -299,9 +294,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"ansi-regex@npm:^6.0.1":
|
||||
version: 6.1.0
|
||||
resolution: "ansi-regex@npm:6.1.0"
|
||||
checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc
|
||||
version: 6.2.2
|
||||
resolution: "ansi-regex@npm:6.2.2"
|
||||
checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -315,9 +310,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"ansi-styles@npm:^6.0.0":
|
||||
version: 6.2.1
|
||||
resolution: "ansi-styles@npm:6.2.1"
|
||||
checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c
|
||||
version: 6.2.3
|
||||
resolution: "ansi-styles@npm:6.2.3"
|
||||
checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -328,6 +323,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"async-function@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "async-function@npm:1.0.0"
|
||||
checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"async-generator-function@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "async-generator-function@npm:1.0.0"
|
||||
checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"asynckit@npm:^0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "asynckit@npm:0.4.0"
|
||||
@@ -345,14 +354,14 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"axios@npm:^1.11.0":
|
||||
version: 1.11.0
|
||||
resolution: "axios@npm:1.11.0"
|
||||
"axios@npm:^1.12.0":
|
||||
version: 1.12.2
|
||||
resolution: "axios@npm:1.12.2"
|
||||
dependencies:
|
||||
follow-redirects: "npm:^1.15.6"
|
||||
form-data: "npm:^4.0.4"
|
||||
proxy-from-env: "npm:^1.1.0"
|
||||
checksum: 10c0/5de273d33d43058610e4d252f0963cc4f10714da0bfe872e8ef2cbc23c2c999acc300fd357b6bce0fc84a2ca9bd45740fa6bb28199ce2c1266c8b1a393f2b36e
|
||||
checksum: 10c0/80b063e318cf05cd33a4d991cea0162f3573481946f9129efb7766f38fde4c061c34f41a93a9f9521f02b7c9565ccbc197c099b0186543ac84a24580017adfed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -487,20 +496,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"conf@npm:^14.0.0":
|
||||
version: 14.0.0
|
||||
resolution: "conf@npm:14.0.0"
|
||||
"conf@npm:^15.0.2":
|
||||
version: 15.0.2
|
||||
resolution: "conf@npm:15.0.2"
|
||||
dependencies:
|
||||
ajv: "npm:^8.17.1"
|
||||
ajv-formats: "npm:^3.0.1"
|
||||
atomically: "npm:^2.0.3"
|
||||
debounce-fn: "npm:^6.0.0"
|
||||
dot-prop: "npm:^9.0.0"
|
||||
dot-prop: "npm:^10.0.0"
|
||||
env-paths: "npm:^3.0.0"
|
||||
json-schema-typed: "npm:^8.0.1"
|
||||
semver: "npm:^7.7.2"
|
||||
uint8array-extras: "npm:^1.4.0"
|
||||
checksum: 10c0/d1472ea24dad78d0d33dee47a795dfefe92fcdf2633763a8b35563989f22b2658e768c9d338de8e8e5f9163525d22df9e5f8733094d822a8329f4571dedce208
|
||||
uint8array-extras: "npm:^1.5.0"
|
||||
checksum: 10c0/77713ffe61e1ec26713fba972b6a4f589a3c45872cf07f0e6499a3e54fe855d2c88bf80e148346b28abef0174e4bffcb98cc0a58dd42d451c936a045bd319113
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -525,14 +534,14 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2":
|
||||
version: 4.4.1
|
||||
resolution: "debug@npm:4.4.1"
|
||||
version: 4.4.3
|
||||
resolution: "debug@npm:4.4.3"
|
||||
dependencies:
|
||||
ms: "npm:^2.1.3"
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
checksum: 10c0/d2b44bc1afd912b49bb7ebb0d50a860dc93a4dd7d946e8de94abc957bb63726b7dd5aa48c18c2386c379ec024c46692e15ed3ed97d481729f929201e671fcd55
|
||||
checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -595,12 +604,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dot-prop@npm:^9.0.0":
|
||||
version: 9.0.0
|
||||
resolution: "dot-prop@npm:9.0.0"
|
||||
"dot-prop@npm:^10.0.0":
|
||||
version: 10.1.0
|
||||
resolution: "dot-prop@npm:10.1.0"
|
||||
dependencies:
|
||||
type-fest: "npm:^4.18.2"
|
||||
checksum: 10c0/4bac49a2f559156811862ac92813906f70529c50da918eaab81b38dd869743c667d578e183607f5ae11e8ae2a02e43e98e32c8a37bc4cae76b04d5b576e3112f
|
||||
type-fest: "npm:^5.0.0"
|
||||
checksum: 10c0/b034a06f017909ed55c6c164ddea962ccdce3d88b9b092f7106a9b738116a4cd003db5d47a0c6e140e93adbf1922b5e3a147e3d4a124c8556862940446ba5f75
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -616,13 +625,13 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"electron-context-menu@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "electron-context-menu@npm:4.1.0"
|
||||
version: 4.1.1
|
||||
resolution: "electron-context-menu@npm:4.1.1"
|
||||
dependencies:
|
||||
cli-truncate: "npm:^4.0.0"
|
||||
electron-dl: "npm:^4.0.0"
|
||||
electron-is-dev: "npm:^3.0.1"
|
||||
checksum: 10c0/ec5b12107d8ddad419f41a486e325ff3dc7b17384c13f6d325611d12297064e6ca850e8f414a48df850b50c225f3ddd87af654bfbcbbcf6ac62619d46265ed60
|
||||
checksum: 10c0/3e2eb5298a311f320734427fadb1cf22ef6685c8d86387d1a2d558b698b079de8eabb4d7a8790cab100cf5eba3607df887846067f5a805d1c011016b9eccdf70
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -644,33 +653,33 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"electron-store@npm:^10.1.0":
|
||||
version: 10.1.0
|
||||
resolution: "electron-store@npm:10.1.0"
|
||||
"electron-store@npm:^11.0.2":
|
||||
version: 11.0.2
|
||||
resolution: "electron-store@npm:11.0.2"
|
||||
dependencies:
|
||||
conf: "npm:^14.0.0"
|
||||
type-fest: "npm:^4.41.0"
|
||||
checksum: 10c0/a527a1957b09decbbb36828e299bb06c239ed9a7d406ceda07abe84d2a9dfd1920120c63859e42c9c7a0922b95b840c4f4e5d8db90256814445f22a8a48de07e
|
||||
conf: "npm:^15.0.2"
|
||||
type-fest: "npm:^5.0.1"
|
||||
checksum: 10c0/14a24b49f92b5fc818285a528a2032257dc3221fc3917ba94c0308f4c45bf468f92fb7ba401f1d7f0151bcf10487370448632e8a765dab47db20fc7b3f1925bb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"electron@npm:37.2.6":
|
||||
version: 37.2.6
|
||||
resolution: "electron@npm:37.2.6"
|
||||
"electron@npm:38.2.1":
|
||||
version: 38.2.1
|
||||
resolution: "electron@npm:38.2.1"
|
||||
dependencies:
|
||||
"@electron/get": "npm:^2.0.0"
|
||||
"@types/node": "npm:^22.7.7"
|
||||
extract-zip: "npm:^2.0.1"
|
||||
bin:
|
||||
electron: cli.js
|
||||
checksum: 10c0/d0653bbaf6b449260d65d51aa12717ad8acaffce337d32e9892aea5cb70e1dc70f0da54393548595dd3a57cce1dbf699e3fa5d9155427f4151ada572f4430778
|
||||
checksum: 10c0/f9be3bda71dfa4e04e28e4e23cb02a1103d822763d62d2b0bf9a553e8593a298fdfb47dbc0ed4a252a77ea05a890b4612370d8aa339a2b67dacbcd28c3713798
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"emoji-regex@npm:^10.3.0":
|
||||
version: 10.4.0
|
||||
resolution: "emoji-regex@npm:10.4.0"
|
||||
checksum: 10c0/a3fcedfc58bfcce21a05a5f36a529d81e88d602100145fcca3dc6f795e3c8acc4fc18fe773fbf9b6d6e9371205edb3afa2668ec3473fa2aa7fd47d2a9d46482d
|
||||
version: 10.5.0
|
||||
resolution: "emoji-regex@npm:10.5.0"
|
||||
checksum: 10c0/17cf84335a461fc23bf90575122ace2902630dc760e53299474cd3b0b5e4cfbc6c0223a389a766817538e5d20bf0f36c67b753f27c9e705056af510b8777e312
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -760,16 +769,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint-plugin-unused-imports@npm:^4.1.4":
|
||||
version: 4.1.4
|
||||
resolution: "eslint-plugin-unused-imports@npm:4.1.4"
|
||||
"eslint-plugin-unused-imports@npm:^4.2.0":
|
||||
version: 4.2.0
|
||||
resolution: "eslint-plugin-unused-imports@npm:4.2.0"
|
||||
peerDependencies:
|
||||
"@typescript-eslint/eslint-plugin": ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0
|
||||
eslint: ^9.0.0 || ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
"@typescript-eslint/eslint-plugin":
|
||||
optional: true
|
||||
checksum: 10c0/3899f64b0e8b23fa6b81e2754fc10f93d8741e051d70390a8100ca39af7878bde8625f234b76111af69562ef2512104b52c3703e986ccb3ac9adc07911896acf
|
||||
checksum: 10c0/b6293323670dda64b0b5931ace1ab45f731e399e87da591c208da09c6bf89a84591b160b8e15e3b47f8f1f662dc80306368a60c09f833de0f6f1dbd97c247949
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -797,18 +806,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"eslint@npm:^9.33.0":
|
||||
version: 9.33.0
|
||||
resolution: "eslint@npm:9.33.0"
|
||||
"eslint@npm:^9.37.0":
|
||||
version: 9.37.0
|
||||
resolution: "eslint@npm:9.37.0"
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils": "npm:^4.2.0"
|
||||
"@eslint-community/eslint-utils": "npm:^4.8.0"
|
||||
"@eslint-community/regexpp": "npm:^4.12.1"
|
||||
"@eslint/config-array": "npm:^0.21.0"
|
||||
"@eslint/config-helpers": "npm:^0.3.1"
|
||||
"@eslint/core": "npm:^0.15.2"
|
||||
"@eslint/config-helpers": "npm:^0.4.0"
|
||||
"@eslint/core": "npm:^0.16.0"
|
||||
"@eslint/eslintrc": "npm:^3.3.1"
|
||||
"@eslint/js": "npm:9.33.0"
|
||||
"@eslint/plugin-kit": "npm:^0.3.5"
|
||||
"@eslint/js": "npm:9.37.0"
|
||||
"@eslint/plugin-kit": "npm:^0.4.0"
|
||||
"@humanfs/node": "npm:^0.16.6"
|
||||
"@humanwhocodes/module-importer": "npm:^1.0.1"
|
||||
"@humanwhocodes/retry": "npm:^0.4.2"
|
||||
@@ -843,7 +852,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
eslint: bin/eslint.js
|
||||
checksum: 10c0/1e1f60d2b62d9d65553e9af916a8dccf00eeedd982103f35bf58c205803907cb1fda73ef595178d47384ea80d8624a182b63682a6b15d8387e9a5d86904a2a2d
|
||||
checksum: 10c0/30b71350b0e43542eeffa6f7380ed85c960055dde8003f17bf87d209a4a9afc6091bc0419aa32f86853e7ecef18790bdc4d678112b89dbebe61b69efcb1100e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -948,9 +957,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"fast-uri@npm:^3.0.1":
|
||||
version: 3.0.6
|
||||
resolution: "fast-uri@npm:3.0.6"
|
||||
checksum: 10c0/74a513c2af0584448aee71ce56005185f81239eab7a2343110e5bad50c39ad4fb19c5a6f99783ead1cac7ccaf3461a6034fda89fffa2b30b6d99b9f21c2f9d29
|
||||
version: 3.1.0
|
||||
resolution: "fast-uri@npm:3.1.0"
|
||||
checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1040,28 +1049,38 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"generator-function@npm:^2.0.0":
|
||||
version: 2.0.1
|
||||
resolution: "generator-function@npm:2.0.1"
|
||||
checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"get-east-asian-width@npm:^1.0.0":
|
||||
version: 1.3.0
|
||||
resolution: "get-east-asian-width@npm:1.3.0"
|
||||
checksum: 10c0/1a049ba697e0f9a4d5514c4623781c5246982bdb61082da6b5ae6c33d838e52ce6726407df285cdbb27ec1908b333cf2820989bd3e986e37bb20979437fdf34b
|
||||
version: 1.4.0
|
||||
resolution: "get-east-asian-width@npm:1.4.0"
|
||||
checksum: 10c0/4e481d418e5a32061c36fbb90d1b225a254cc5b2df5f0b25da215dcd335a3c111f0c2023ffda43140727a9cafb62dac41d022da82c08f31083ee89f714ee3b83
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"get-intrinsic@npm:^1.2.6":
|
||||
version: 1.3.0
|
||||
resolution: "get-intrinsic@npm:1.3.0"
|
||||
version: 1.3.1
|
||||
resolution: "get-intrinsic@npm:1.3.1"
|
||||
dependencies:
|
||||
async-function: "npm:^1.0.0"
|
||||
async-generator-function: "npm:^1.0.0"
|
||||
call-bind-apply-helpers: "npm:^1.0.2"
|
||||
es-define-property: "npm:^1.0.1"
|
||||
es-errors: "npm:^1.3.0"
|
||||
es-object-atoms: "npm:^1.1.1"
|
||||
function-bind: "npm:^1.1.2"
|
||||
generator-function: "npm:^2.0.0"
|
||||
get-proto: "npm:^1.0.1"
|
||||
gopd: "npm:^1.2.0"
|
||||
has-symbols: "npm:^1.1.0"
|
||||
hasown: "npm:^2.0.2"
|
||||
math-intrinsics: "npm:^1.1.0"
|
||||
checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a
|
||||
checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1569,12 +1588,12 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "pgadmin4@workspace:."
|
||||
dependencies:
|
||||
axios: "npm:^1.11.0"
|
||||
electron: "npm:37.2.6"
|
||||
axios: "npm:^1.12.0"
|
||||
electron: "npm:38.2.1"
|
||||
electron-context-menu: "npm:^4.1.0"
|
||||
electron-store: "npm:^10.1.0"
|
||||
eslint: "npm:^9.33.0"
|
||||
eslint-plugin-unused-imports: "npm:^4.1.4"
|
||||
electron-store: "npm:^11.0.2"
|
||||
eslint: "npm:^9.37.0"
|
||||
eslint-plugin-unused-imports: "npm:^4.2.0"
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
@@ -1617,11 +1636,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"pupa@npm:^3.1.0":
|
||||
version: 3.1.0
|
||||
resolution: "pupa@npm:3.1.0"
|
||||
version: 3.3.0
|
||||
resolution: "pupa@npm:3.3.0"
|
||||
dependencies:
|
||||
escape-goat: "npm:^4.0.0"
|
||||
checksum: 10c0/02afa6e4547a733484206aaa8f8eb3fbfb12d3dd17d7ca4fa1ea390a7da2cb8f381e38868bbf68009c4d372f8f6059f553171b6a712d8f2802c7cd43d513f06c
|
||||
checksum: 10c0/9707e0a7f00e5922d47527d1c8d88d4224b1e86502da2fca27943eb0e9bb218121c91fa0af6c30531a2ee5ade0c326b5d33c40fdf61bc593c4224027412fd9b7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1773,11 +1792,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"strip-ansi@npm:^7.1.0":
|
||||
version: 7.1.0
|
||||
resolution: "strip-ansi@npm:7.1.0"
|
||||
version: 7.1.2
|
||||
resolution: "strip-ansi@npm:7.1.2"
|
||||
dependencies:
|
||||
ansi-regex: "npm:^6.0.1"
|
||||
checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4
|
||||
checksum: 10c0/0d6d7a023de33368fd042aab0bf48f4f4077abdfd60e5393e73c7c411e85e1b3a83507c11af2e656188511475776215df9ca589b4da2295c9455cc399ce1858b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1813,6 +1832,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tagged-tag@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "tagged-tag@npm:1.0.0"
|
||||
checksum: 10c0/91d25c9ffb86a91f20522cefb2cbec9b64caa1febe27ad0df52f08993ff60888022d771e868e6416cf2e72dab68449d2139e8709ba009b74c6c7ecd4000048d1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
|
||||
version: 0.4.0
|
||||
resolution: "type-check@npm:0.4.0"
|
||||
@@ -1829,17 +1855,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type-fest@npm:^4.18.2, type-fest@npm:^4.41.0":
|
||||
version: 4.41.0
|
||||
resolution: "type-fest@npm:4.41.0"
|
||||
checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4
|
||||
"type-fest@npm:^5.0.0, type-fest@npm:^5.0.1":
|
||||
version: 5.0.1
|
||||
resolution: "type-fest@npm:5.0.1"
|
||||
dependencies:
|
||||
tagged-tag: "npm:^1.0.0"
|
||||
checksum: 10c0/8d248edd9705e0da3cc14f4f4ca7fb40a6c5b2c822fe4ba8fc226743578bc229f66fa4ff66e7d4070806ab8312adc64199ce0f0836d20ede13922ced2ff36118
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uint8array-extras@npm:^1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "uint8array-extras@npm:1.4.0"
|
||||
checksum: 10c0/eaffd3388634b7e5e1496073b878dd19136043137d3e7e0d2a453e37f566a5a551e640819e1a6596c6df9b9d1f7b70884cc29db6a357bdd424811f3598d504dd
|
||||
"uint8array-extras@npm:^1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "uint8array-extras@npm:1.5.0"
|
||||
checksum: 10c0/0e74641ac7dadb02eadefc1ccdadba6010e007757bda824960de3c72bbe2b04e6d3af75648441f412148c4103261d54fcb60be45a2863beb76643a55fddba3bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -1850,10 +1878,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"undici-types@npm:~7.10.0":
|
||||
version: 7.10.0
|
||||
resolution: "undici-types@npm:7.10.0"
|
||||
checksum: 10c0/8b00ce50e235fe3cc601307f148b5e8fb427092ee3b23e8118ec0a5d7f68eca8cee468c8fc9f15cbb2cf2a3797945ebceb1cbd9732306a1d00e0a9b6afa0f635
|
||||
"undici-types@npm:~7.14.0":
|
||||
version: 7.14.0
|
||||
resolution: "undici-types@npm:7.14.0"
|
||||
checksum: 10c0/e7f3214b45d788f03c51ceb33817be99c65dae203863aa9386b3ccc47201a245a7955fc721fb581da9c888b6ebad59fa3f53405214afec04c455a479908f0f14
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
||||
@@ -129,6 +129,17 @@ WEB_SERVER = 'Python'
|
||||
# See https://tools.ietf.org/html/rfc7034 for more info.
|
||||
X_FRAME_OPTIONS = "SAMEORIGIN"
|
||||
|
||||
|
||||
# The Cross-Origin-Opener-Policy allows a website to control whether
|
||||
# a new top-level document, opened using Window.open() or by navigating
|
||||
# to a new page, is opened in the same browsing context group (BCG)
|
||||
# or in a new browsing context group.
|
||||
# Set to 'unsafe-none', 'same-origin-allow-popups', 'same-origin',
|
||||
# or 'noopener-allow-popups'
|
||||
|
||||
CROSS_ORIGIN_OPENER_POLICY = "same-origin"
|
||||
|
||||
|
||||
# The Content-Security-Policy header allows you to restrict how resources
|
||||
# such as JavaScript, CSS, or pretty much anything that the browser loads.
|
||||
# see https://content-security-policy.com/#source_list for more info
|
||||
|
||||
@@ -15,11 +15,10 @@ Revises: e24b1c4def17
|
||||
Create Date: 2025-07-15 12:27:48.780562
|
||||
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.orm.session import Session
|
||||
from pgadmin.model import Preferences, ModulePreference, PreferenceCategory,\
|
||||
UserPreference
|
||||
from pgadmin.browser import register_editor_preferences
|
||||
from pgadmin.model import Preferences, ModulePreference, PreferenceCategory
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
@@ -29,21 +28,11 @@ branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
class Migration:
|
||||
"""
|
||||
This is a placeholder class for registering editor preferences
|
||||
"""
|
||||
def __init__(self, value=None):
|
||||
self.editor_preference = value
|
||||
|
||||
|
||||
def upgrade():
|
||||
migration_obj = Migration()
|
||||
register_editor_preferences(migration_obj, migration_gettext=lambda x: x)
|
||||
|
||||
session = Session(bind=op.get_bind())
|
||||
pref_categories = ['keyboard_shortcuts', 'editor', 'Editor']
|
||||
new_categories = ['keyboard_shortcuts', 'sql_formatting', 'options']
|
||||
old_pref_categories = ['keyboard_shortcuts', 'editor', 'Editor']
|
||||
new_pref_categories = ['keyboard_shortcuts', 'sql_formatting', 'options']
|
||||
prefs = ['find', 'replace', 'goto_line_col',
|
||||
'comment', 'format_sql', 'plain_editor_mode',
|
||||
'code_folding', 'wrap_code', 'insert_pair_brackets',
|
||||
@@ -53,14 +42,76 @@ def upgrade():
|
||||
'data_type_case', 'spaces_around_operators', 'tab_size',
|
||||
'use_spaces', 'expression_width', 'logical_operator_new_line',
|
||||
'lines_between_queries', 'new_line_before_semicolon']
|
||||
preference_map = {
|
||||
'keyboard_shortcuts': [
|
||||
'find', 'replace', 'goto_line_col', 'comment', 'format_sql'
|
||||
],
|
||||
'options': [
|
||||
'plain_editor_mode', 'code_folding', 'cursor_blink_rate',
|
||||
'wrap_code', 'insert_pair_brackets', 'highlight_selection_matches',
|
||||
'brace_matching', 'sql_font_size', 'sql_font_ligatures',
|
||||
'sql_font_family', 'indent_new_line'
|
||||
],
|
||||
'sql_formatting': [
|
||||
'keyword_case', 'identifier_case', 'function_case',
|
||||
'data_type_case', 'spaces_around_operators', 'tab_size',
|
||||
'use_spaces', 'expression_width', 'logical_operator_new_line',
|
||||
'lines_between_queries', 'new_line_before_semicolon'
|
||||
]
|
||||
}
|
||||
category_ids = []
|
||||
new_ids = []
|
||||
pref_map = {}
|
||||
|
||||
# get metadata from current connection
|
||||
meta = sa.MetaData()
|
||||
# define table representation
|
||||
meta.reflect(op.get_bind(), only=('user_preferences', 'module_preference',
|
||||
'preference_category', 'preferences'))
|
||||
module_pref_table = sa.Table('module_preference', meta)
|
||||
|
||||
module_id = session.query(ModulePreference).filter_by(
|
||||
name='editor').first()
|
||||
|
||||
# Insert the 'editor' module in module_preference table
|
||||
if not module_id:
|
||||
op.execute(
|
||||
module_pref_table.insert().values(name='editor')
|
||||
)
|
||||
|
||||
module_id = session.query(ModulePreference).filter_by(
|
||||
name='editor').first().id
|
||||
|
||||
# Insert the new preference categories in preference_category table
|
||||
pref_category_table = sa.Table('preference_category', meta)
|
||||
|
||||
op.bulk_insert(pref_category_table, [
|
||||
{'mid': module_id, 'name': 'keyboard_shortcuts'},
|
||||
{'mid': module_id, 'name': 'sql_formatting'},
|
||||
{'mid': module_id, 'name': 'options'},
|
||||
])
|
||||
|
||||
# Insert the new preferences in preferences table
|
||||
prefs_table = sa.Table('preferences', meta)
|
||||
|
||||
for category in new_pref_categories:
|
||||
category_id = session.query(PreferenceCategory
|
||||
).filter_by(name=category,
|
||||
mid=module_id).first().id
|
||||
|
||||
op.bulk_insert(
|
||||
prefs_table,
|
||||
[
|
||||
{'cid':category_id, 'name': pref_name}
|
||||
for pref_name in preference_map[category]
|
||||
]
|
||||
)
|
||||
|
||||
# Migrate the preferences from 'sqleditor' module to 'editor'
|
||||
category_data = session.query(ModulePreference, PreferenceCategory,).join(
|
||||
PreferenceCategory).filter(
|
||||
ModulePreference.name == 'sqleditor',
|
||||
PreferenceCategory.name.in_(pref_categories)).all()
|
||||
PreferenceCategory.name.in_(old_pref_categories)).all()
|
||||
|
||||
for module_data, pref_cat in category_data:
|
||||
category_ids.append(pref_cat.id)
|
||||
@@ -68,7 +119,7 @@ def upgrade():
|
||||
new_data = session.query(ModulePreference, PreferenceCategory).join(
|
||||
PreferenceCategory).filter(
|
||||
ModulePreference.name == 'editor', PreferenceCategory.name.in_(
|
||||
new_categories)).all()
|
||||
new_pref_categories)).all()
|
||||
|
||||
for module_data, pref_cat in new_data:
|
||||
new_ids.append(pref_cat.id)
|
||||
@@ -84,15 +135,17 @@ def upgrade():
|
||||
if pref.name == new_pref.name:
|
||||
pref_map[pref.id] = new_pref.id
|
||||
|
||||
user_pref_table = sa.Table('user_preferences', meta)
|
||||
|
||||
# Update the user preferences with new preference ids
|
||||
for key, val in pref_map.items():
|
||||
record_to_update = session.query(UserPreference).filter_by(
|
||||
pid=key).first()
|
||||
if record_to_update:
|
||||
record_to_update.pid = val
|
||||
op.execute(
|
||||
user_pref_table.update().where(
|
||||
user_pref_table.c.pid == key).values(pid=val)
|
||||
)
|
||||
|
||||
# Delete the old preferences and categories
|
||||
session.query(Preferences).filter(Preferences.name.in_(prefs),
|
||||
Preferences.cid.in_(category_ids)
|
||||
session.query(Preferences).filter(Preferences.cid.in_(category_ids)
|
||||
).delete(synchronize_session=False)
|
||||
|
||||
session.query(PreferenceCategory).filter(
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
##########################################################################
|
||||
#
|
||||
# pgAdmin 4 - PostgreSQL Tools
|
||||
#
|
||||
# Copyright (C) 2013 - 2025, The pgAdmin Development Team
|
||||
# This software is released under the PostgreSQL Licence
|
||||
#
|
||||
##########################################################################
|
||||
|
||||
"""
|
||||
Revision ID: efbbe5d5862f
|
||||
Revises: e6ed5dac37c2
|
||||
Create Date: 2025-09-29 18:40:30.248908
|
||||
|
||||
"""
|
||||
from alembic import op, context
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'efbbe5d5862f'
|
||||
down_revision = 'e6ed5dac37c2'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
with op.batch_alter_table(
|
||||
"server",
|
||||
table_kwargs={'sqlite_autoincrement': True}) as batch_op:
|
||||
batch_op.add_column(sa.Column('tunnel_prompt_password',
|
||||
sa.Integer(), server_default='0'))
|
||||
with op.batch_alter_table(
|
||||
"sharedserver",
|
||||
table_kwargs={'sqlite_autoincrement': True}) as batch_op:
|
||||
batch_op.add_column(sa.Column('tunnel_prompt_password',
|
||||
sa.Integer(), server_default='0'))
|
||||
|
||||
|
||||
def downgrade():
|
||||
# pgAdmin only upgrades, downgrade not implemented.
|
||||
pass
|
||||
@@ -7,12 +7,12 @@
|
||||
],
|
||||
"license": "PostgreSQL",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.28.0",
|
||||
"@babel/core": "^7.28.3",
|
||||
"@babel/eslint-parser": "^7.26.5",
|
||||
"@babel/eslint-plugin": "^7.26.10",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.10.1",
|
||||
"@babel/plugin-syntax-jsx": "^7.16.0",
|
||||
"@babel/plugin-transform-runtime": "^7.27.4",
|
||||
"@babel/plugin-transform-runtime": "^7.28.3",
|
||||
"@babel/preset-env": "^7.28.0",
|
||||
"@babel/preset-typescript": "^7.24.7",
|
||||
"@emotion/memoize": "^0.9.0",
|
||||
@@ -21,7 +21,7 @@
|
||||
"@emotion/utils": "^1.0.0",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@testing-library/dom": "10.4.1",
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/jest-dom": "^6.7.0",
|
||||
"@testing-library/react": "16.3.0",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@types/jest": "^30.0.0",
|
||||
@@ -30,21 +30,21 @@
|
||||
"babel-loader": "^10.0.0",
|
||||
"browserify": "^17.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"copy-webpack-plugin": "^13.0.0",
|
||||
"copy-webpack-plugin": "^13.0.1",
|
||||
"cross-env": "^10.0.0",
|
||||
"css-loader": "^7.1.2",
|
||||
"css-minimizer-webpack-plugin": "^7.0.0",
|
||||
"eslint": "^9.33.0",
|
||||
"eslint": "^9.37.0",
|
||||
"eslint-plugin-jest": "^29.0.1",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-unused-imports": "^4.1.4",
|
||||
"eslint-plugin-unused-imports": "^4.2.0",
|
||||
"exports-loader": "^5.0.0",
|
||||
"globals": "^16.3.0",
|
||||
"html-react-parser": "^5.2.0",
|
||||
"image-minimizer-webpack-plugin": "^4.1.3",
|
||||
"image-minimizer-webpack-plugin": "^4.1.4",
|
||||
"imports-loader": "^5.0.0",
|
||||
"jest": "^30.0.2",
|
||||
"jest-environment-jsdom": "^30.0.4",
|
||||
"jest": "^30.2.0",
|
||||
"jest-environment-jsdom": "^30.2.0",
|
||||
"loader-utils": "^3.2.1",
|
||||
"mini-css-extract-plugin": "^2.9.2",
|
||||
"postcss-loader": "^8.1.1",
|
||||
@@ -58,7 +58,7 @@
|
||||
"svgo-loader": "^4.0.0",
|
||||
"terser-webpack-plugin": "^5.3.12",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.35.0",
|
||||
"typescript-eslint": "^8.44.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"webfonts-loader": "^8.0.1",
|
||||
"webpack": "^5.101.0",
|
||||
@@ -67,25 +67,26 @@
|
||||
"yarn-audit-html": "7.3.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"sharp": "^0.34.3"
|
||||
"sharp": "^0.34.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||
"@babel/preset-react": "^7.12.13",
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"@codemirror/lang-sql": "^6.9.1",
|
||||
"@codemirror/lang-sql": "^6.10.0",
|
||||
"@date-io/core": "^3.0.0",
|
||||
"@date-io/date-fns": "3.x",
|
||||
"@emotion/sheet": "^1.0.1",
|
||||
"@fluentui/keyboard-key": "^0.4.23",
|
||||
"@fortawesome/fontawesome-free": "latest",
|
||||
"@mui/icons-material": "^7.3.1",
|
||||
"@mui/material": "^7.3.1",
|
||||
"@mui/x-date-pickers": "^8.10.0",
|
||||
"@mui/icons-material": "^7.3.4",
|
||||
"@mui/material": "^7.3.4",
|
||||
"@mui/x-date-pickers": "^8.12.0",
|
||||
"@nozbe/microfuzz": "^1.0.0",
|
||||
"@projectstorm/react-diagrams": "^7.0.4",
|
||||
"@simonwep/pickr": "^1.5.1",
|
||||
"@szhsin/react-menu": "^4.4.1",
|
||||
"@tanstack/react-query": "^5.84.2",
|
||||
"@tanstack/react-query": "^5.87.1",
|
||||
"@tanstack/react-table": "^8.16.0",
|
||||
"@tanstack/react-virtual": "^3.13.6",
|
||||
"@types/classnames": "^2.3.4",
|
||||
@@ -98,11 +99,10 @@
|
||||
"ajv": "^8.8.2",
|
||||
"anti-trojan-source": "^1.4.0",
|
||||
"aspen-decorations": "^1.0.2",
|
||||
"axios": "^1.11.0",
|
||||
"axios": "^1.12.0",
|
||||
"babelify": "~10.0.0",
|
||||
"bignumber.js": "^9.2.0",
|
||||
"brace": "^0.11.1",
|
||||
"browserfs": "^1.4.3",
|
||||
"chart.js": "^4.4.7",
|
||||
"chartjs-plugin-zoom": "^2.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
@@ -138,7 +138,7 @@
|
||||
"react-frame-component": "^5.2.6",
|
||||
"react-leaflet": "^4.2.1",
|
||||
"react-new-window": "^1.0.1",
|
||||
"react-resize-detector": "^12.1.0",
|
||||
"react-resize-detector": "^12.3.0",
|
||||
"react-rnd": "^10.5.1",
|
||||
"react-select": "^5.7.2",
|
||||
"react-timer-hook": "^4.0.1",
|
||||
@@ -146,7 +146,7 @@
|
||||
"snapsvg-cjs": "^0.0.6",
|
||||
"socket.io-client": "^4.5.0",
|
||||
"split.js": "^1.5.10",
|
||||
"sql-formatter": "^15.6.2",
|
||||
"sql-formatter": "^15.6.10",
|
||||
"uplot": "^1.6.32",
|
||||
"uplot-react": "^1.1.4",
|
||||
"use-resize-observer": "^9.1.0",
|
||||
|
||||
@@ -18,16 +18,10 @@ LOWER_CASE_STR = gettext('Lower case')
|
||||
PRESERVE_STR = gettext('Preserve')
|
||||
|
||||
|
||||
def register_editor_preferences(self, migration_gettext=None):
|
||||
def register_editor_preferences(self):
|
||||
"""
|
||||
Registers the editor preferences
|
||||
"""
|
||||
# migration_getttext is used once in case of migration
|
||||
# In that case gettext will be used from migration_gettext
|
||||
# instead of flask_babel gettext.
|
||||
from flask_babel import gettext
|
||||
if migration_gettext is not None:
|
||||
gettext = migration_gettext
|
||||
|
||||
self.editor_preference = Preferences(
|
||||
'editor', gettext('Editor')
|
||||
@@ -58,13 +52,13 @@ def register_editor_preferences(self, migration_gettext=None):
|
||||
gettext('Replace'),
|
||||
'keyboardshortcut',
|
||||
{
|
||||
'alt': True,
|
||||
'alt': False,
|
||||
'shift': False,
|
||||
'control': True,
|
||||
'ctrl_is_meta': True,
|
||||
'key': {
|
||||
'key_code': 70,
|
||||
'char': 'f'
|
||||
'key_code': 82,
|
||||
'char': 'r'
|
||||
}
|
||||
},
|
||||
category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
|
||||
|
||||
@@ -167,6 +167,7 @@ class ServerModule(sg.ServerGroupPluginModule):
|
||||
server.tunnel_password = sharedserver.tunnel_password
|
||||
server.save_password = sharedserver.save_password
|
||||
server.tunnel_identity_file = sharedserver.tunnel_identity_file
|
||||
server.tunnel_prompt_password = sharedserver.tunnel_prompt_password
|
||||
if hasattr(server, 'connection_params') and \
|
||||
hasattr(sharedserver, 'connection_params') and \
|
||||
'passfile' in server.connection_params and \
|
||||
@@ -413,6 +414,7 @@ class ServerModule(sg.ServerGroupPluginModule):
|
||||
tunnel_authentication=0,
|
||||
tunnel_identity_file=None,
|
||||
tunnel_keep_alive=0,
|
||||
tunnel_prompt_password=0,
|
||||
shared=True,
|
||||
connection_params=data.connection_params,
|
||||
prepare_threshold=data.prepare_threshold
|
||||
@@ -790,6 +792,7 @@ class ServerNode(PGChildNodeView):
|
||||
'tunnel_username': 'tunnel_username',
|
||||
'tunnel_authentication': 'tunnel_authentication',
|
||||
'tunnel_identity_file': 'tunnel_identity_file',
|
||||
'tunnel_prompt_password': 'tunnel_prompt_password',
|
||||
'tunnel_keep_alive': 'tunnel_keep_alive',
|
||||
'shared': 'shared',
|
||||
'shared_username': 'shared_username',
|
||||
@@ -1086,6 +1089,8 @@ class ServerNode(PGChildNodeView):
|
||||
'tunnel_username': tunnel_username,
|
||||
'tunnel_identity_file': server.tunnel_identity_file
|
||||
if server.tunnel_identity_file else None,
|
||||
'tunnel_prompt_password': server.tunnel_prompt_password
|
||||
if server.tunnel_identity_file else 0,
|
||||
'tunnel_authentication': tunnel_authentication,
|
||||
'tunnel_keep_alive': tunnel_keep_alive,
|
||||
'kerberos_conn': bool(server.kerberos_conn),
|
||||
@@ -1212,6 +1217,8 @@ class ServerNode(PGChildNodeView):
|
||||
tunnel_authentication=1 if data.get('tunnel_authentication',
|
||||
False) else 0,
|
||||
tunnel_identity_file=data.get('tunnel_identity_file', None),
|
||||
tunnel_prompt_password=1 if data.get('tunnel_prompt_password',
|
||||
True) else 0,
|
||||
tunnel_keep_alive=data.get('tunnel_keep_alive', 0),
|
||||
shared=data.get('shared', None),
|
||||
shared_username=data.get('shared_username', None),
|
||||
@@ -1419,6 +1426,19 @@ class ServerNode(PGChildNodeView):
|
||||
}
|
||||
)
|
||||
|
||||
def is_prompt_tunnel_password(self, server):
|
||||
"""
|
||||
This function will check whether to prompt tunnel password or not.
|
||||
"""
|
||||
prompt_tunnel_password = True
|
||||
# In case of identity file check the value of tunnel_prompt_password.
|
||||
if server.tunnel_password is not None or \
|
||||
(server.tunnel_identity_file is not None and
|
||||
server.tunnel_prompt_password != 1):
|
||||
prompt_tunnel_password = False
|
||||
|
||||
return prompt_tunnel_password
|
||||
|
||||
def connect(self, gid, sid, is_qt=False, server=None):
|
||||
"""
|
||||
Connect the Server and return the connection object.
|
||||
@@ -1502,11 +1522,12 @@ class ServerNode(PGChildNodeView):
|
||||
|
||||
# If server using SSH Tunnel
|
||||
if server.use_ssh_tunnel:
|
||||
if 'tunnel_password' not in data:
|
||||
if server.tunnel_password is None:
|
||||
prompt_tunnel_password = True
|
||||
else:
|
||||
tunnel_password = server.tunnel_password
|
||||
if 'tunnel_password' not in data and \
|
||||
server.tunnel_password is None:
|
||||
prompt_tunnel_password = self.is_prompt_tunnel_password(server)
|
||||
elif 'tunnel_password' not in data and \
|
||||
server.tunnel_password is not None:
|
||||
tunnel_password = server.tunnel_password
|
||||
else:
|
||||
tunnel_password = data['tunnel_password'] \
|
||||
if 'tunnel_password' in data else ''
|
||||
@@ -1562,6 +1583,10 @@ class ServerNode(PGChildNodeView):
|
||||
return self.get_response_for_password(
|
||||
server, 428, prompt_password, prompt_tunnel_password)
|
||||
|
||||
# Check whether to prompt for the tunnel password in case if
|
||||
# password is saved in server object or in data.
|
||||
prompt_tunnel_password = self.is_prompt_tunnel_password(server)
|
||||
|
||||
try:
|
||||
status, errmsg = conn.connect(
|
||||
password=password,
|
||||
@@ -1571,7 +1596,7 @@ class ServerNode(PGChildNodeView):
|
||||
)
|
||||
except Exception as e:
|
||||
return self.get_response_for_password(
|
||||
server, 401, True, True,
|
||||
server, 401, not server.save_password, prompt_tunnel_password,
|
||||
getattr(e, 'message', str(e)))
|
||||
|
||||
if not status:
|
||||
@@ -1583,7 +1608,8 @@ class ServerNode(PGChildNodeView):
|
||||
return internal_server_error(errmsg)
|
||||
|
||||
return self.get_response_for_password(
|
||||
server, 401, True, True, errmsg)
|
||||
server, 401, not server.save_password,
|
||||
prompt_tunnel_password, errmsg)
|
||||
else:
|
||||
if save_password and config.ALLOW_SAVE_PASSWORD:
|
||||
try:
|
||||
|
||||
@@ -37,6 +37,8 @@ from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
|
||||
columns import utils as column_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
|
||||
triggers import utils as trigger_utils
|
||||
from pgadmin.browser.server_groups.servers.databases.schemas.tables.\
|
||||
utils import BaseTableView
|
||||
|
||||
|
||||
class ForeignTableModule(SchemaChildModule):
|
||||
@@ -102,7 +104,7 @@ class ForeignTableModule(SchemaChildModule):
|
||||
blueprint = ForeignTableModule(__name__)
|
||||
|
||||
|
||||
class ForeignTableView(PGChildNodeView, DataTypeReader,
|
||||
class ForeignTableView(BaseTableView, DataTypeReader,
|
||||
SchemaDiffObjectCompare):
|
||||
"""
|
||||
class ForeignTableView(PGChildNodeView)
|
||||
@@ -187,6 +189,9 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
|
||||
* compare(**kwargs):
|
||||
- This function will compare the foreign table nodes from two different
|
||||
schemas.
|
||||
|
||||
* truncate(gid, sid, scid, tid):
|
||||
- This function will truncate foreign table object
|
||||
"""
|
||||
|
||||
node_type = blueprint.node_type
|
||||
@@ -211,6 +216,7 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
|
||||
{'get': 'list', 'post': 'create', 'delete': 'delete'}
|
||||
],
|
||||
'delete': [{'delete': 'delete'}, {'delete': 'delete'}],
|
||||
'truncate': [{'put': 'truncate'}],
|
||||
'children': [{'get': 'children'}],
|
||||
'nodes': [{'get': 'node'}, {'get': 'nodes'}],
|
||||
'sql': [{'get': 'sql'}],
|
||||
@@ -409,6 +415,9 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
|
||||
self.template_path = \
|
||||
self.BASE_TEMPLATE_PATH.format(self.manager.version)
|
||||
|
||||
self.table_template_path = compile_template_path(
|
||||
'tables/sql', self.manager.version)
|
||||
|
||||
self.foreign_table_column_template_path = compile_template_path(
|
||||
'foreign_table_columns/sql', self.manager.version)
|
||||
|
||||
@@ -884,6 +893,39 @@ class ForeignTableView(PGChildNodeView, DataTypeReader,
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def truncate(self, gid, sid, did, scid, foid):
|
||||
"""
|
||||
This function will truncate the foreign table.
|
||||
|
||||
Args:
|
||||
gid: Server Group ID
|
||||
sid: Server ID
|
||||
did: Database ID
|
||||
scid: Schema ID
|
||||
foid: Foreign Table ID
|
||||
"""
|
||||
|
||||
try:
|
||||
SQL = render_template(
|
||||
"/".join([self.template_path, self._PROPERTIES_SQL]),
|
||||
did=did, scid=scid, foid=foid,
|
||||
datlastsysoid=self._DATABASE_LAST_SYSTEM_OID
|
||||
)
|
||||
status, res = self.conn.execute_dict(SQL)
|
||||
if not status:
|
||||
return internal_server_error(errormsg=res)
|
||||
|
||||
if len(res['rows']) == 0:
|
||||
return gone(gettext(self.not_found_error_msg()))
|
||||
|
||||
return super().truncate(
|
||||
gid, sid, did, scid, foid, res
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return internal_server_error(errormsg=str(e))
|
||||
|
||||
@check_precondition
|
||||
def sql(self, gid, sid, did, scid, foid=None, **kwargs):
|
||||
"""
|
||||
|
||||
@@ -12,6 +12,7 @@ import { getNodePrivilegeRoleSchema } from '../../../../../static/js/privilege.u
|
||||
import ForeignTableSchema from './foreign_table.ui';
|
||||
import _ from 'lodash';
|
||||
import Notify from '../../../../../../../../static/js/helpers/Notifier';
|
||||
import getApiInstance from '../../../../../../../../static/js/api_instance';
|
||||
|
||||
/* Create and Register Foreign Table Collection and Node. */
|
||||
define('pgadmin.node.foreign_table', ['pgadmin.tables.js/enable_disable_triggers',
|
||||
@@ -72,6 +73,21 @@ define('pgadmin.node.foreign_table', ['pgadmin.tables.js/enable_disable_triggers
|
||||
applies: ['object', 'context'], callback: 'show_obj_properties',
|
||||
category: 'create', priority: 4, label: gettext('Foreign Table...'),
|
||||
data: {action: 'create', check: false}, enable: 'canCreate',
|
||||
},{
|
||||
name: 'truncate_foreign_table', node: 'foreign_table', module: this,
|
||||
applies: ['object', 'context'], callback: 'truncate_foreign_table',
|
||||
category: gettext('Truncate'), priority: 3, label: gettext('Truncate'),
|
||||
enable : 'canCreate',
|
||||
},{
|
||||
name: 'truncate_foreign_table_cascade', node: 'foreign_table', module: this,
|
||||
applies: ['object', 'context'], callback: 'truncate_foreign_table_cascade',
|
||||
category: gettext('Truncate'), priority: 3, label: gettext('Truncate Cascade'),
|
||||
enable : 'canCreate',
|
||||
},{
|
||||
name: 'truncate_foreign_table_identity', node: 'foreign_table', module: this,
|
||||
applies: ['object', 'context'], callback: 'truncate_foreign_table_identity',
|
||||
category: gettext('Truncate'), priority: 3, label: gettext('Truncate Restart Identity'),
|
||||
enable : 'canCreate',
|
||||
},{
|
||||
// To enable/disable all triggers for the table
|
||||
name: 'enable_all_triggers', node: 'foreign_table', module: this,
|
||||
@@ -112,6 +128,56 @@ define('pgadmin.node.foreign_table', ['pgadmin.tables.js/enable_disable_triggers
|
||||
args
|
||||
);
|
||||
},
|
||||
/* Truncate foreign table */
|
||||
truncate_foreign_table: function(args) {
|
||||
let params = {'cascade': false };
|
||||
this.callbacks.truncate.apply(this, [args, params]);
|
||||
},
|
||||
/* Truncate foreign table with cascade */
|
||||
truncate_foreign_table_cascade: function(args) {
|
||||
let params = {'cascade': true };
|
||||
this.callbacks.truncate.apply(this, [args, params]);
|
||||
},
|
||||
/* Truncate foreign table with identity */
|
||||
truncate_foreign_table_identity: function(args) {
|
||||
let params = {'identity': true };
|
||||
this.callbacks.truncate.apply(this, [args, params]);
|
||||
},
|
||||
truncate: function(args, params) {
|
||||
let input = args || {},
|
||||
obj = this,
|
||||
t = pgBrowser.tree,
|
||||
i = input.item || t.selected(),
|
||||
d = i ? t.itemData(i) : undefined;
|
||||
|
||||
if (!d)
|
||||
return false;
|
||||
|
||||
pgBrowser.notifier.confirm(
|
||||
gettext('Truncate Foreign Table'),
|
||||
gettext('Are you sure you want to truncate foreign table <b>%s</b>?', d.label),
|
||||
function () {
|
||||
let data = d;
|
||||
getApiInstance().put(obj.generate_url(i, 'truncate' , d, true), params)
|
||||
.then(({data: res})=>{
|
||||
if (res.success == 1) {
|
||||
pgBrowser.notifier.success(res.info);
|
||||
t.removeIcon(i);
|
||||
data.icon = data.is_partitioned ? 'icon-partition': 'icon-table';
|
||||
t.addIcon(i, {icon: data.icon});
|
||||
t.updateAndReselectNode(i, data);
|
||||
}
|
||||
if (res.success == 2) {
|
||||
pgBrowser.notifier.error(res.info);
|
||||
}
|
||||
})
|
||||
.catch((error)=>{
|
||||
pgBrowser.notifier.pgRespErrorNotify(error);
|
||||
t.refresh(i);
|
||||
});
|
||||
}, function() {/*This is intentional (SonarQube)*/}
|
||||
);
|
||||
},
|
||||
},
|
||||
// Check to whether table has disable trigger(s)
|
||||
canCreate_with_trigger_enable: function(itemData) {
|
||||
|
||||
@@ -260,7 +260,7 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
list_params = []
|
||||
if request.method == 'GET':
|
||||
list_params = ['arguments', 'variables', 'proacl',
|
||||
'seclabels', 'acl', 'args']
|
||||
'seclabels', 'acl', 'args', 'dependsonextensions']
|
||||
|
||||
if key in list_params and req[key] != '' and req[key] is not None:
|
||||
# Coverts string into python list as expected.
|
||||
@@ -1171,6 +1171,12 @@ class FunctionView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
old_data['proparallel'] = \
|
||||
parallel_dict[old_data['proparallel']]
|
||||
|
||||
if self.node_type == 'function':
|
||||
old_data['dependsonextensions'] = \
|
||||
old_data.get('dependsonextensions') or []
|
||||
data['dependsonextensions'] = \
|
||||
data.get('dependsonextensions') or []
|
||||
|
||||
# If any of the below argument is changed,
|
||||
# then CREATE OR REPLACE SQL statement should be called
|
||||
fun_change_args = ['lanname', 'prosrc', 'probin', 'prosrc_c',
|
||||
|
||||
@@ -76,6 +76,7 @@ define('pgadmin.node.function', [
|
||||
|
||||
},
|
||||
getSchema: function(treeNodeInfo, itemNodeData) {
|
||||
let nodeObj = pgBrowser.Nodes['extension'];
|
||||
return new FunctionSchema(
|
||||
(privileges)=>getNodePrivilegeRoleSchema(this, treeNodeInfo, itemNodeData, privileges),
|
||||
()=>getNodeVariableSchema(this, treeNodeInfo, itemNodeData, false, false),
|
||||
@@ -85,6 +86,16 @@ define('pgadmin.node.function', [
|
||||
cacheLevel: 'database'
|
||||
}
|
||||
),
|
||||
extensionsList:()=>getNodeAjaxOptions('nodes', nodeObj, treeNodeInfo, itemNodeData, { cacheLevel: 'server'},
|
||||
(data)=>{
|
||||
let res = [];
|
||||
if (data && _.isArray(data)) {
|
||||
_.each(data, function(d) {
|
||||
res.push({label: d.label, value: d.label, data: d});
|
||||
});
|
||||
}
|
||||
return res;
|
||||
}),
|
||||
getTypes: ()=>getNodeAjaxOptions('get_types', this, treeNodeInfo, itemNodeData),
|
||||
getLanguage: ()=>getNodeAjaxOptions('get_languages', this, treeNodeInfo, itemNodeData),
|
||||
getSupportFunctions: ()=>getNodeAjaxOptions('get_support_functions', this, treeNodeInfo, itemNodeData, {
|
||||
|
||||
@@ -137,6 +137,7 @@ export default class FunctionSchema extends BaseUISchema {
|
||||
role: [],
|
||||
schema: [],
|
||||
getTypes: [],
|
||||
extensionsList: [],
|
||||
...fieldOptions,
|
||||
};
|
||||
}
|
||||
@@ -274,8 +275,22 @@ export default class FunctionSchema extends BaseUISchema {
|
||||
|
||||
return this.node_info && 'catalog' in this.node_info;
|
||||
}
|
||||
},
|
||||
{
|
||||
},{
|
||||
id: 'dependsonextensions',
|
||||
label: gettext('Depends on extensions'),
|
||||
group: gettext('Definition'),
|
||||
type: 'select',
|
||||
options: this.fieldOptions.extensionsList,
|
||||
controlProps: {
|
||||
multiple: true,
|
||||
allowClear: true,
|
||||
allowSelectAll: true,
|
||||
placeholder: gettext('Select the Depends on extensions...'),
|
||||
},
|
||||
min_version: 130000,
|
||||
mode: ['create', 'edit', 'properties'],
|
||||
visible: obj.isVisible
|
||||
},{
|
||||
id: 'probin', label: gettext('Object file'), cell: 'string',
|
||||
type: 'text', group: gettext('Definition'), deps: ['lanname'], visible:
|
||||
function(state) {
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}
|
||||
{% set is_columns = [] %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% if data %}
|
||||
{% if query_for == 'sql_panel' and func_def is defined %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
|
||||
{% else %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
{% endif %}
|
||||
RETURNS{% if data.proretset and (data.prorettypename.startswith('SETOF ') or data.prorettypename.startswith('TABLE')) %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ data.prorettypename }}{% else %} {{ data.prorettypename }}{% endif %}
|
||||
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }}
|
||||
{% if data.procost %}
|
||||
COST {{data.procost}}
|
||||
{% endif %}
|
||||
{% if data.provolatile %}{% if data.provolatile == 'i' %}IMMUTABLE{% elif data.provolatile == 's' %}STABLE{% else %}VOLATILE{% endif %} {% endif %}{% if data.proleakproof %}LEAKPROOF {% endif %}
|
||||
{% if data.proisstrict %}STRICT {% endif %}
|
||||
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
|
||||
{% if data.proiswindow %}WINDOW {% endif %}
|
||||
{% if data.proparallel and (data.proparallel == 'r' or data.proparallel == 's' or data.proparallel == 'u') %}
|
||||
{% if data.proparallel == 'r' %}PARALLEL RESTRICTED {% elif data.proparallel == 's' %}PARALLEL SAFE {% elif data.proparallel == 'u' %}PARALLEL UNSAFE{% endif %}{% endif %}
|
||||
{% if data.prorows and (data.prorows | int) > 0 %}
|
||||
|
||||
ROWS {{data.prorows}}
|
||||
{% endif %}
|
||||
{% if data.prosupportfunc %}
|
||||
SUPPORT {{ data.prosupportfunc }}
|
||||
{% endif -%}
|
||||
{% if data.variables %}{% for v in data.variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
AS {% if data.lanname == 'c' %}
|
||||
{{ data.probin|qtLiteral(conn) }}, {{ data.prosrc_c|qtLiteral(conn) }}
|
||||
{% else %}
|
||||
$BODY${{ data.prosrc }}$BODY${% endif -%};
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args_without)}}
|
||||
{% endfor %}{% endif %}
|
||||
{% if data.revoke_all %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, "FUNCTION", "PUBLIC", data.name, data.pronamespace, data.func_args_without)}}
|
||||
{% endif %}
|
||||
{% if data.description %}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
{% if data.seclabels %}
|
||||
{% for r in data.seclabels %}
|
||||
{% if r.label and r.provider %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.label, data.pronamespace, data.func_args_without) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
|
||||
{% endif %}
|
||||
@@ -0,0 +1,49 @@
|
||||
SELECT
|
||||
pr.oid, pr.xmin,
|
||||
CASE WHEN pr.prokind = 'w' THEN true ELSE false END AS proiswindow,
|
||||
pr.prosrc, pr.prosrc AS prosrc_c, pr.pronamespace, pr.prolang, pr.procost, pr.prorows, pr.prokind,
|
||||
pr.prosecdef, pr.proleakproof, pr.proisstrict, pr.proretset, pr.provolatile, pr.proparallel,
|
||||
pr.pronargs, pr.prorettype, pr.proallargtypes, pr.proargmodes, pr.probin, pr.proacl,
|
||||
pr.proname, pr.proname AS name, pg_catalog.pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, pg_catalog.oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_catalog.pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
CASE WHEN prosupport = 0::oid THEN ''
|
||||
ELSE (
|
||||
SELECT pg_catalog.quote_ident(nspname) || '.' || pg_catalog.quote_ident(proname) AS tfunctions
|
||||
FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n
|
||||
WHERE p.pronamespace = n.oid
|
||||
AND p.oid = pr.prosupport::OID
|
||||
) END AS prosupportfunc,
|
||||
(SELECT
|
||||
pg_catalog.array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_catalog.pg_seclabel sl1
|
||||
WHERE
|
||||
sl1.objoid=pr.oid) AS seclabels
|
||||
FROM
|
||||
pg_catalog.pg_proc pr
|
||||
JOIN
|
||||
pg_catalog.pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_catalog.pg_namespace typns ON typns.oid=typ.typnamespace
|
||||
JOIN
|
||||
pg_catalog.pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_catalog.pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass and des.objsubid = 0)
|
||||
WHERE
|
||||
pr.prokind IN ('f', 'w')
|
||||
AND typname NOT IN ('trigger', 'event_trigger')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% else %}
|
||||
AND pronamespace = {{scid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
||||
@@ -0,0 +1,146 @@
|
||||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
|
||||
{% set name = o_data.name %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% set set_variables = [] %}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
{% set set_variables = data.merged_variables %}
|
||||
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
|
||||
{% set set_variables = o_data.variables %}
|
||||
{% endif %}
|
||||
{% if data.name %}
|
||||
{% if data.name != o_data.name %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
|
||||
o_data.proargtypenames }})
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
{% set name = data.name %}
|
||||
{% endif %}
|
||||
{% endif -%}
|
||||
{% if data.change_func %}
|
||||
|
||||
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
RETURNS {% if 'prorettypename' in data %}{{ data.prorettypename }}{% else %}{{ o_data.prorettypename }}{% endif %}
|
||||
|
||||
{% if 'lanname' in data %}
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }} {% else %}
|
||||
LANGUAGE {{ o_data.lanname|qtLiteral(conn) }}
|
||||
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
|
||||
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
|
||||
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
|
||||
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
|
||||
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
|
||||
|
||||
{% if 'proparallel' in data and data.proparallel %}PARALLEL {{ data.proparallel }}{% elif 'proparallel' not in data and o_data.proparallel %}PARALLEL {{ o_data.proparallel }}{% endif %}
|
||||
|
||||
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0' %}
|
||||
|
||||
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
|
||||
|
||||
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if (data.lanname == 'c' or o_data.lanname == 'c') and ('probin' in data or 'prosrc_c' in data) %}
|
||||
{% if 'probin' in data %}{{ data.probin|qtLiteral(conn) }}{% else %}{{ o_data.probin|qtLiteral(conn) }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral(conn) }}{% else %}{{ o_data.prosrc_c|qtLiteral(conn) }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral(conn) }}, {{ o_data.prosrc_c|qtLiteral(conn) }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% endif -%};
|
||||
{% endif -%}
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
{# The SQL generated below will change priviledges #}
|
||||
{% if data.acl %}
|
||||
{% if 'deleted' in data.acl %}
|
||||
{% for priv in data.acl.deleted %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in data.acl %}
|
||||
{% for priv in data.acl.changed %}
|
||||
|
||||
{% if priv.grantee != priv.old_grantee %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.old_grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% else %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in data.acl %}
|
||||
{% for priv in data.acl.added %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}{% endif -%}
|
||||
{% endif -%}
|
||||
{% if data.change_func == False %}
|
||||
{% if data.variables %}
|
||||
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
|
||||
|
||||
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
|
||||
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% set seclabels = data.seclabels %}
|
||||
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
|
||||
{% for r in seclabels.deleted %}
|
||||
|
||||
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in seclabels and seclabels.added|length > 0 %}
|
||||
{% for r in seclabels.added %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
|
||||
{% for r in seclabels.changed %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if data.description is defined and data.description != o_data.description%}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.pronamespace %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
@@ -50,6 +50,15 @@ $BODY${{ data.prosrc }}$BODY${% endif -%};
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@ SELECT
|
||||
pg_catalog.pg_get_function_sqlbody(pr.oid) AS prosrc_sql,
|
||||
CASE WHEN pr.prosqlbody IS NOT NULL THEN true ELSE false END as is_pure_sql,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
CASE WHEN prosupport = 0::oid THEN ''
|
||||
ELSE (
|
||||
SELECT pg_catalog.quote_ident(nspname) || '.' || pg_catalog.quote_ident(proname) AS tfunctions
|
||||
|
||||
@@ -130,4 +130,20 @@ ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtype
|
||||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
@@ -0,0 +1,83 @@
|
||||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}
|
||||
{% set is_columns = [] %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% if data %}
|
||||
{% if query_for == 'sql_panel' and func_def is defined %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{func_def}}
|
||||
{% else %}
|
||||
CREATE{% if query_type is defined %}{{' OR REPLACE'}}{% endif %} FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
{% endif %}
|
||||
RETURNS{% if data.proretset and (data.prorettypename.startswith('SETOF ') or data.prorettypename.startswith('TABLE')) %} {{ data.prorettypename }} {% elif data.proretset %} SETOF {{ data.prorettypename }}{% else %} {{ data.prorettypename }}{% endif %}
|
||||
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }}
|
||||
{% if data.procost %}
|
||||
COST {{data.procost}}
|
||||
{% endif %}
|
||||
{% if data.provolatile %}{% if data.provolatile == 'i' %}IMMUTABLE{% elif data.provolatile == 's' %}STABLE{% else %}VOLATILE{% endif %} {% endif %}{% if data.proleakproof %}LEAKPROOF {% endif %}
|
||||
{% if data.proisstrict %}STRICT {% endif %}
|
||||
{% if data.prosecdef %}SECURITY DEFINER {% endif %}
|
||||
{% if data.proiswindow %}WINDOW {% endif %}
|
||||
{% if data.proparallel and (data.proparallel == 'r' or data.proparallel == 's' or data.proparallel == 'u') %}
|
||||
{% if data.proparallel == 'r' %}PARALLEL RESTRICTED {% elif data.proparallel == 's' %}PARALLEL SAFE {% elif data.proparallel == 'u' %}PARALLEL UNSAFE{% endif %}{% endif %}
|
||||
{% if data.prorows and (data.prorows | int) > 0 %}
|
||||
|
||||
ROWS {{data.prorows}}
|
||||
{% endif %}
|
||||
{% if data.prosupportfunc %}
|
||||
|
||||
SUPPORT {{ data.prosupportfunc }}
|
||||
{% endif -%}
|
||||
{% if data.variables %}{% for v in data.variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
AS {% if data.lanname == 'c' %}
|
||||
{{ data.probin|qtLiteral(conn) }}, {{ data.prosrc_c|qtLiteral(conn) }}
|
||||
{% else %}
|
||||
$BODY${{ data.prosrc }}$BODY${% endif -%};
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, "FUNCTION", p.grantee, data.name, p.without_grant, p.with_grant, data.pronamespace, data.func_args_without)}}
|
||||
{% endfor %}{% endif %}
|
||||
{% if data.revoke_all %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, "FUNCTION", "PUBLIC", data.name, data.pronamespace, data.func_args_without)}}
|
||||
{% endif %}
|
||||
{% if data.description %}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
{% if data.seclabels %}
|
||||
{% for r in data.seclabels %}
|
||||
{% if r.label and r.provider %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', data.name, r.provider, r.label, data.pronamespace, data.func_args_without) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
|
||||
{% endif %}
|
||||
@@ -0,0 +1,43 @@
|
||||
SELECT
|
||||
pr.oid, pr.xmin,
|
||||
CASE WHEN pr.prokind = 'w' THEN true ELSE false END AS proiswindow,
|
||||
pr.prosrc, pr.prosrc AS prosrc_c, pr.pronamespace, pr.prolang, pr.procost, pr.prorows, pr.prokind,
|
||||
pr.prosecdef, pr.proleakproof, pr.proisstrict, pr.proretset, pr.provolatile, pr.proparallel,
|
||||
pr.pronargs, pr.prorettype, pr.proallargtypes, pr.proargmodes, pr.probin, pr.proacl,
|
||||
pr.proname, pr.proname AS name, pg_catalog.pg_get_function_result(pr.oid) AS prorettypename,
|
||||
typns.nspname AS typnsp, lanname, proargnames, pg_catalog.oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_catalog.pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
CASE WHEN prosupport = 0::oid THEN '' ELSE prosupport::text END AS prosupportfunc,
|
||||
(SELECT
|
||||
pg_catalog.array_agg(provider || '=' || label)
|
||||
FROM
|
||||
pg_catalog.pg_seclabel sl1
|
||||
WHERE
|
||||
sl1.objoid=pr.oid) AS seclabels
|
||||
FROM
|
||||
pg_catalog.pg_proc pr
|
||||
JOIN
|
||||
pg_catalog.pg_type typ ON typ.oid=prorettype
|
||||
JOIN
|
||||
pg_catalog.pg_namespace typns ON typns.oid=typ.typnamespace
|
||||
JOIN
|
||||
pg_catalog.pg_language lng ON lng.oid=prolang
|
||||
LEFT OUTER JOIN
|
||||
pg_catalog.pg_description des ON (des.objoid=pr.oid AND des.classoid='pg_proc'::regclass and des.objsubid = 0)
|
||||
WHERE
|
||||
pr.prokind IN ('f', 'w')
|
||||
AND typname NOT IN ('trigger', 'event_trigger')
|
||||
{% if fnid %}
|
||||
AND pr.oid = {{fnid}}::oid
|
||||
{% else %}
|
||||
AND pronamespace = {{scid}}::oid
|
||||
{% endif %}
|
||||
ORDER BY
|
||||
proname;
|
||||
@@ -0,0 +1,146 @@
|
||||
{% import 'macros/functions/security.macros' as SECLABEL %}
|
||||
{% import 'macros/functions/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'macros/functions/variable.macros' as VARIABLE %}{% if data %}
|
||||
{% set name = o_data.name %}
|
||||
{% set exclude_quoting = ['search_path'] %}
|
||||
{% set set_variables = [] %}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
{% set set_variables = data.merged_variables %}
|
||||
{% elif 'variables' in o_data and o_data.variables|length > 0 %}
|
||||
{% set set_variables = o_data.variables %}
|
||||
{% endif %}
|
||||
{% if data.name %}
|
||||
{% if data.name != o_data.name %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, o_data.name) }}({{
|
||||
o_data.proargtypenames }})
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
{% set name = data.name %}
|
||||
{% endif %}
|
||||
{% endif -%}
|
||||
{% if data.change_func %}
|
||||
|
||||
CREATE OR REPLACE FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({% if data.arguments %}
|
||||
{% for p in data.arguments %}{% if p.argmode %}{{p.argmode}} {% endif %}{% if p.argname %}{{ conn|qtIdent(p.argname) }} {% endif %}{% if p.argtype %}{{ p.argtype }}{% endif %}{% if p.argdefval %} DEFAULT {{p.argdefval}}{% endif %}
|
||||
{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
)
|
||||
RETURNS {% if 'prorettypename' in data %}{{ data.prorettypename }}{% else %}{{ o_data.prorettypename }}{% endif %}
|
||||
|
||||
{% if 'lanname' in data %}
|
||||
LANGUAGE {{ data.lanname|qtLiteral(conn) }} {% else %}
|
||||
LANGUAGE {{ o_data.lanname|qtLiteral(conn) }}
|
||||
{% endif %}{% if 'provolatile' in data and data.provolatile %}{{ data.provolatile }} {% elif 'provolatile' not in data and o_data.provolatile %}{{ o_data.provolatile }}{% endif %}
|
||||
{% if ('proleakproof' in data and data.proleakproof) or ('proleakproof' not in data and o_data.proleakproof) %} LEAKPROOF{% elif 'proleakproof' in data and not data.proleakproof %} NOT LEAKPROOF{% endif %}
|
||||
{% if ('proisstrict' in data and data.proisstrict) or ('proisstrict' not in data and o_data.proisstrict) %} STRICT{% endif %}
|
||||
{% if ('prosecdef' in data and data.prosecdef) or ('prosecdef' not in data and o_data.prosecdef) %} SECURITY DEFINER{% endif %}
|
||||
{% if ('proiswindow' in data and data.proiswindow) or ('proiswindow' not in data and o_data.proiswindow) %} WINDOW{% endif %}
|
||||
|
||||
{% if 'proparallel' in data and data.proparallel %}PARALLEL {{ data.proparallel }}{% elif 'proparallel' not in data and o_data.proparallel %}PARALLEL {{ o_data.proparallel }}{% endif %}
|
||||
|
||||
{% if data.procost %}COST {{data.procost}}{% elif o_data.procost %}COST {{o_data.procost}}{% endif %}{% if data.prorows and data.prorows != '0' %}
|
||||
|
||||
ROWS {{data.prorows}}{% elif data.prorows is not defined and o_data.prorows and o_data.prorows != '0' %} ROWS {{o_data.prorows}} {%endif %}
|
||||
|
||||
{% if data.prosupportfunc %}SUPPORT {{ data.prosupportfunc }}{% elif data.prosupportfunc is not defined and o_data.prosupportfunc %}SUPPORT {{ o_data.prosupportfunc }}{% endif -%}{% if set_variables and set_variables|length > 0 %}{% for v in set_variables %}
|
||||
|
||||
SET {{ conn|qtIdent(v.name) }}={% if v.name in exclude_quoting %}{{ v.value }}{% else %}{{ v.value|qtLiteral(conn) }}{% endif %}{% endfor -%}
|
||||
{% endif %}
|
||||
|
||||
AS {% if (data.lanname == 'c' or o_data.lanname == 'c') and ('probin' in data or 'prosrc_c' in data) %}
|
||||
{% if 'probin' in data %}{{ data.probin|qtLiteral(conn) }}{% else %}{{ o_data.probin|qtLiteral(conn) }}{% endif %}, {% if 'prosrc_c' in data %}{{ data.prosrc_c|qtLiteral(conn) }}{% else %}{{ o_data.prosrc_c|qtLiteral(conn) }}{% endif %}{% elif 'prosrc' in data %}
|
||||
$BODY${{ data.prosrc }}$BODY${% elif o_data.lanname == 'c' %}
|
||||
{{ o_data.probin|qtLiteral(conn) }}, {{ o_data.prosrc_c|qtLiteral(conn) }}{% else %}
|
||||
$BODY${{ o_data.prosrc }}$BODY${% endif -%};
|
||||
{% endif -%}
|
||||
{% if data.funcowner %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
{# The SQL generated below will change priviledges #}
|
||||
{% if data.acl %}
|
||||
{% if 'deleted' in data.acl %}
|
||||
{% for priv in data.acl.deleted %}
|
||||
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in data.acl %}
|
||||
{% for priv in data.acl.changed %}
|
||||
|
||||
{% if priv.grantee != priv.old_grantee %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.old_grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% else %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'FUNCTION', priv.grantee, name, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in data.acl %}
|
||||
{% for priv in data.acl.added %}
|
||||
|
||||
{{ PRIVILEGE.SET(conn, 'FUNCTION', priv.grantee, name, priv.without_grant, priv.with_grant, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}{% endif -%}
|
||||
{% endif -%}
|
||||
{% if data.change_func == False %}
|
||||
{% if data.variables %}
|
||||
{% if 'deleted' in data.variables and data.variables.deleted|length > 0 %}
|
||||
|
||||
{{ VARIABLE.UNSET(conn, 'FUNCTION', name, data.variables.deleted, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% if 'merged_variables' in data and data.merged_variables|length > 0 %}
|
||||
|
||||
{{ VARIABLE.SET(conn, 'FUNCTION', name, data.merged_variables, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% endif -%}
|
||||
{% set seclabels = data.seclabels %}
|
||||
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
|
||||
{% for r in seclabels.deleted %}
|
||||
|
||||
{{ SECLABEL.UNSET(conn, 'FUNCTION', name, r.provider, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'added' in seclabels and seclabels.added|length > 0 %}
|
||||
{% for r in seclabels.added %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
|
||||
{% for r in seclabels.changed %}
|
||||
|
||||
{{ SECLABEL.SET(conn, 'FUNCTION', name, r.provider, r.label, o_data.pronamespace, o_data.proargtypenames) }}
|
||||
{% endfor %}
|
||||
{% endif -%}
|
||||
{% if data.description is defined and data.description != o_data.description%}
|
||||
|
||||
COMMENT ON FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.pronamespace %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtypenames }})
|
||||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
@@ -50,6 +50,15 @@ $BODY${{ data.prosrc }}$BODY${% endif -%};
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
OWNER TO {{ conn|qtIdent(data.funcowner) }};
|
||||
{% endif -%}
|
||||
|
||||
{% if data.dependsonextensions %}
|
||||
{% for ext in data.dependsonextensions %}
|
||||
|
||||
ALTER FUNCTION {{ conn|qtIdent(data.pronamespace, data.name) }}({{data.func_args_without}})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if data.acl %}
|
||||
{% for p in data.acl %}
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@ SELECT
|
||||
typns.nspname AS typnsp, lanname, proargnames, pg_catalog.oidvectortypes(proargtypes) AS proargtypenames,
|
||||
pg_catalog.pg_get_expr(proargdefaults, 'pg_catalog.pg_class'::regclass) AS proargdefaultvals,
|
||||
pr.pronargdefaults, proconfig, pg_catalog.pg_get_userbyid(proowner) AS funcowner, description,
|
||||
(
|
||||
SELECT array_agg(DISTINCT e.extname)
|
||||
FROM pg_depend d
|
||||
JOIN pg_extension e ON d.refobjid = e.oid
|
||||
WHERE d.objid = pr.oid
|
||||
) AS dependsonextensions,
|
||||
pg_catalog.pg_get_function_sqlbody(pr.oid) AS prosrc_sql,
|
||||
CASE WHEN pr.prosqlbody IS NOT NULL THEN true ELSE false END as is_pure_sql,
|
||||
CASE WHEN prosupport = 0::oid THEN '' ELSE prosupport::text END AS prosupportfunc,
|
||||
|
||||
@@ -130,4 +130,20 @@ ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{o_data.proargtype
|
||||
SET SCHEMA {{ conn|qtIdent(data.pronamespace) }};
|
||||
{% endif -%}
|
||||
|
||||
{% set old_exts = (o_data.dependsonextensions or []) | list %}
|
||||
{% set new_exts = data.dependsonextensions if 'dependsonextensions' in data else None %}
|
||||
|
||||
{% if new_exts is not none and old_exts != new_exts %}
|
||||
{% for ext in (old_exts + new_exts) | unique %}
|
||||
|
||||
{% if ext in new_exts and ext not in old_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% elif ext in old_exts and ext not in new_exts %}
|
||||
ALTER FUNCTION {{ conn|qtIdent(o_data.pronamespace, name) }}({{ o_data.proargtypenames }})
|
||||
NO DEPENDS ON EXTENSION {{ conn|qtIdent(ext) }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
NO DEPENDS ON EXTENSION postgres_fdw;
|
||||
@@ -0,0 +1,22 @@
|
||||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO postgres;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
@@ -0,0 +1,20 @@
|
||||
CREATE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(IN param character varying DEFAULT '1')
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort=true
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO postgres;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
@@ -0,0 +1,25 @@
|
||||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO postgres;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
@@ -0,0 +1,434 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"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": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"name": "Create function with custom return type.",
|
||||
"data": {
|
||||
"name": "Function3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "postgres",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "table(val 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\n return query select '1'::character varying;\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_with_custom_return.sql",
|
||||
"expected_msql_file": "create_function_with_custom_return.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,81 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"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": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
NO DEPENDS ON EXTENSION postgres_fdw;
|
||||
@@ -0,0 +1,22 @@
|
||||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO enterprisedb;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
@@ -0,0 +1,20 @@
|
||||
CREATE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(IN param character varying DEFAULT '1')
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort=true
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO enterprisedb;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
@@ -0,0 +1,25 @@
|
||||
-- FUNCTION: public.Function1_$%{}[]()&*^!@"'`\/#(character varying)
|
||||
|
||||
-- DROP FUNCTION IF EXISTS public."Function1_$%{}[]()&*^!@""'`\/#"(character varying);
|
||||
|
||||
CREATE OR REPLACE FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(
|
||||
param character varying DEFAULT '1'::character varying)
|
||||
RETURNS character varying
|
||||
LANGUAGE 'plpgsql'
|
||||
COST 100
|
||||
VOLATILE LEAKPROOF STRICT SECURITY DEFINER WINDOW PARALLEL UNSAFE
|
||||
SET enable_sort='true'
|
||||
AS $BODY$
|
||||
begin
|
||||
select '1';
|
||||
end
|
||||
$BODY$;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
OWNER TO enterprisedb;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION plpgsql;
|
||||
|
||||
ALTER FUNCTION public."Function1_$%{}[]()&*^!@""'`\/#"(character varying)
|
||||
DEPENDS ON EXTENSION postgres_fdw;
|
||||
@@ -0,0 +1,446 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"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": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"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": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"endpoint": "NODE-function.obj",
|
||||
"msql_endpoint": "NODE-function.msql",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"name": "Create function with custom return type.",
|
||||
"data": {
|
||||
"name": "Function3_$%{}[]()&*^!@\"'`\\/#",
|
||||
"funcowner": "enterprisedb",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "table(val 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\n return query select '1'::character varying;\nend",
|
||||
"probin": "$libdir/",
|
||||
"options": [],
|
||||
"variables": [],
|
||||
"seclabels": [],
|
||||
"acl": [],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_with_custom_return.sql",
|
||||
"expected_msql_file": "create_function_with_custom_return.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,81 @@
|
||||
{
|
||||
"scenarios": [
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create Extension",
|
||||
"endpoint": "NODE-extension.obj",
|
||||
"sql_endpoint": "NODE-extension.sql_id",
|
||||
"data": {
|
||||
"name": "postgres_fdw",
|
||||
"version": "",
|
||||
"relocatable": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with extensions.",
|
||||
"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": [],
|
||||
"dependsonextensions": ["plpgsql", "postgres_fdw"],
|
||||
"schema": "public"
|
||||
},
|
||||
"expected_sql_file": "create_function_on_depends.sql",
|
||||
"expected_msql_file": "create_function_on_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "alter",
|
||||
"name": "Alter function with NO DEPENDS ON",
|
||||
"endpoint": "NODE-function.obj_id",
|
||||
"msql_endpoint": "NODE-function.msql_id",
|
||||
"sql_endpoint": "NODE-function.sql_id",
|
||||
"data": {
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
},
|
||||
"expected_sql_file": "alter_function_no_depends.sql",
|
||||
"expected_msql_file": "alter_function_no_depends.msql"
|
||||
},
|
||||
{
|
||||
"type": "delete",
|
||||
"name": "Drop function",
|
||||
"endpoint": "NODE-function.delete_id",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "create",
|
||||
"name": "Create function with all options.",
|
||||
|
||||
@@ -76,6 +76,19 @@ class FunctionAddTestCase(BaseTestGenerator):
|
||||
"status_code": 500
|
||||
}
|
||||
)),
|
||||
('Create Function With Invalid Depends On Extension Fail', dict(
|
||||
url='/browser/function/obj/',
|
||||
is_positive_test=False,
|
||||
mocking_required=True,
|
||||
is_mock_function=True,
|
||||
mock_data={
|
||||
"function_name": "_get_sql",
|
||||
"return_value": "(False, 'Invalid extension specified')"
|
||||
},
|
||||
expected_data={
|
||||
"status_code": 500
|
||||
}
|
||||
))
|
||||
]
|
||||
|
||||
def create_function(self, data):
|
||||
@@ -113,6 +126,7 @@ class FunctionAddTestCase(BaseTestGenerator):
|
||||
"lanname": "sql",
|
||||
"name": "test_function",
|
||||
"options": [],
|
||||
"dependsonextensions": ["plpgsql"],
|
||||
"proleakproof": True,
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "integer",
|
||||
@@ -143,10 +157,13 @@ class FunctionAddTestCase(BaseTestGenerator):
|
||||
)
|
||||
|
||||
data['prosupportfuc'] = support_function_name
|
||||
|
||||
if self.is_positive_test:
|
||||
response = self.create_function(data)
|
||||
else:
|
||||
if "Invalid Depends On Extension" in getattr(
|
||||
self, 'scenario_name', ''
|
||||
):
|
||||
data["dependsonextensions"] = ["non_existing_extensions"]
|
||||
if hasattr(self, 'is_mock_function'):
|
||||
def _get_sql(self, **kwargs):
|
||||
return False, ''
|
||||
|
||||
@@ -35,6 +35,7 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
||||
"funcowner": "",
|
||||
"pronamespace": 2200,
|
||||
"prorettypename": "character varying",
|
||||
"dependsonextensions": [],
|
||||
"lanname": "sql",
|
||||
"arguments": [],
|
||||
"prosrc": "select '1'",
|
||||
@@ -67,7 +68,8 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
||||
"probin": "$libdir/",
|
||||
"variables": [],
|
||||
"seclabels": [],
|
||||
"acl": []
|
||||
"acl": [],
|
||||
"dependsonextensions": ["non_existing_extension"]
|
||||
},
|
||||
mock_data={
|
||||
"function_name": '_get_sql',
|
||||
@@ -178,7 +180,6 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
||||
func_name = "test_function_delete_%s" % str(uuid.uuid4())[1:8]
|
||||
function_info = funcs_utils.create_function(
|
||||
self.server, self.db_name, self.schema_name, func_name)
|
||||
|
||||
func_id = function_info[0]
|
||||
self.test_data['oid'] = func_id
|
||||
self.test_data['name'] = func_name
|
||||
@@ -187,6 +188,7 @@ class FunctionGetmsqlTestCase(BaseTestGenerator):
|
||||
self.schema_id) + '/' + str(func_id) + '?' + (
|
||||
urlencode(self.test_data))
|
||||
else:
|
||||
self.test_data['dependsonextensions'] = json.dumps(["plpgsql"])
|
||||
url = self.url + str(utils.SERVER_GROUP) + '/' + str(
|
||||
self.server_id) + '/' + str(self.db_id) + '/' + str(
|
||||
self.schema_id) + '/?' + (urlencode(self.test_data))
|
||||
|
||||
@@ -75,7 +75,7 @@ class FunctionPutTestCase(BaseTestGenerator):
|
||||
}
|
||||
)),
|
||||
(
|
||||
'Fetch Function update with arguments',
|
||||
'Fetch Function update with arguments and depends on exxtensions.',
|
||||
dict(
|
||||
url='/browser/function/obj/',
|
||||
is_positive_test=True,
|
||||
@@ -155,7 +155,8 @@ class FunctionPutTestCase(BaseTestGenerator):
|
||||
|
||||
data = {
|
||||
"description": "This is a procedure update comment",
|
||||
"id": func_id
|
||||
"id": func_id,
|
||||
"dependsonextensions": ["plpgsql"]
|
||||
}
|
||||
|
||||
if hasattr(self, "is_add_argument") and self.is_add_argument:
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
add empty bracket with table name
|
||||
#}
|
||||
{% set empty_bracket = ""%}
|
||||
{% if data.coll_inherits|length == 0 and data.columns|length == 0 and not data.typname and not data.like_relation and data.primary_key|length == 0 and data.unique_constraint|length == 0 and data.foreign_key|length == 0 and data.check_constraint|length == 0 and data.exclude_constraint|length == 0 %}
|
||||
{% if not (data.coll_inherits or data.columns or data.typname or data.like_relation or data.primary_key or data.unique_constraint or data.foreign_key or data.check_constraint or data.exclude_constraint) %}
|
||||
{% set empty_bracket = "\n(\n)"%}
|
||||
{% endif %}
|
||||
{% set with_clause = false%}
|
||||
|
||||
@@ -249,6 +249,15 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
|
||||
return wrap
|
||||
|
||||
def has_dependent_type(self, data):
|
||||
"""
|
||||
This function is used to check the type has dependent
|
||||
on another type.
|
||||
"""
|
||||
return ('rngmultirangetype' in data and
|
||||
data['rngmultirangetype'] is not None and
|
||||
data['rngmultirangetype'] != '')
|
||||
|
||||
@check_precondition
|
||||
def list(self, gid, sid, did, scid):
|
||||
"""
|
||||
@@ -317,7 +326,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
rset['rows'][0]['oid'],
|
||||
scid,
|
||||
rset['rows'][0]['name'],
|
||||
icon=self.icon_str % self.node_type
|
||||
icon=self.icon_str % self.node_type,
|
||||
has_dependent=self.has_dependent_type(rset['rows'][0])
|
||||
)
|
||||
|
||||
return make_json_response(
|
||||
@@ -359,7 +369,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
scid,
|
||||
row['name'],
|
||||
icon=self.icon_str % self.node_type,
|
||||
description=row['description']
|
||||
description=row['description'],
|
||||
has_dependent=self.has_dependent_type(row)
|
||||
))
|
||||
|
||||
return make_json_response(
|
||||
@@ -536,7 +547,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
enum_list = []
|
||||
for row in rset['rows']:
|
||||
properties_list.append(row['enumlabel'])
|
||||
enum_list.append({'label': row['enumlabel']})
|
||||
enum_list.append({'label': row['enumlabel'],
|
||||
'old_label': row['enumlabel']})
|
||||
|
||||
# Adding both results in ouput
|
||||
res['enum_list'] = ', '.join(properties_list)
|
||||
@@ -1063,7 +1075,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
tid,
|
||||
scid,
|
||||
data['name'],
|
||||
icon="icon-type"
|
||||
icon="icon-type",
|
||||
has_dependent=self.has_dependent_type(data)
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -1086,7 +1099,7 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
request.data
|
||||
)
|
||||
try:
|
||||
SQL, name = self.get_sql(gid, sid, data, scid, tid)
|
||||
SQL, name, has_dependent = self.get_sql(gid, sid, data, scid, tid)
|
||||
# Most probably this is due to error
|
||||
if not isinstance(SQL, str):
|
||||
return SQL
|
||||
@@ -1114,6 +1127,7 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
scid,
|
||||
name,
|
||||
icon=self.icon_str % self.node_type,
|
||||
has_dependent=has_dependent,
|
||||
**other_node_info
|
||||
)
|
||||
)
|
||||
@@ -1226,11 +1240,15 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
for key, val in req.items():
|
||||
if key in ['composite', 'enum', 'seclabels', 'typacl']:
|
||||
data[key] = json.loads(val)
|
||||
elif key in ['typreceive', 'typsend', 'typmodin', 'typmodout',
|
||||
'typanalyze', 'typsubscript','typstorage'] and \
|
||||
val == 'null':
|
||||
data[key] = json.loads(val)
|
||||
else:
|
||||
data[key] = val
|
||||
|
||||
try:
|
||||
sql, _ = self.get_sql(gid, sid, data, scid, tid)
|
||||
sql, _, _ = self.get_sql(gid, sid, data, scid, tid)
|
||||
# Most probably this is due to error
|
||||
if not isinstance(sql, str):
|
||||
return sql
|
||||
@@ -1330,7 +1348,7 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
self._CREATE_SQL]),
|
||||
data=data, conn=self.conn, is_sql=is_sql)
|
||||
|
||||
return SQL, data['name']
|
||||
return SQL, data['name'], False
|
||||
|
||||
def get_sql(self, gid, sid, data, scid, tid=None, is_sql=False):
|
||||
"""
|
||||
@@ -1339,6 +1357,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
if tid is None:
|
||||
return self._get_new_sql(data, is_sql)
|
||||
|
||||
data = self._convert_for_sql(data)
|
||||
|
||||
for key in ['added', 'changed', 'deleted']:
|
||||
if key in data.get('typacl', []):
|
||||
data['typacl'][key] = parse_priv_to_db(
|
||||
@@ -1411,7 +1431,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
data=data, o_data=old_data, conn=self.conn
|
||||
)
|
||||
|
||||
return SQL, old_data['name']
|
||||
return (SQL, data['name'] if 'name' in data else old_data['name'],
|
||||
self.has_dependent_type(old_data))
|
||||
|
||||
@check_precondition
|
||||
def sql(self, gid, sid, did, scid, tid, **kwargs):
|
||||
@@ -1478,7 +1499,7 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
if data[k] == '-':
|
||||
data[k] = None
|
||||
|
||||
SQL, _ = self.get_sql(gid, sid, data, scid, tid=None, is_sql=True)
|
||||
SQL, _, _ = self.get_sql(gid, sid, data, scid, tid=None, is_sql=True)
|
||||
# Most probably this is due to error
|
||||
if not isinstance(SQL, str):
|
||||
return SQL
|
||||
@@ -1588,8 +1609,8 @@ class TypeView(PGChildNodeView, DataTypeReader, SchemaDiffObjectCompare):
|
||||
if data:
|
||||
if target_schema:
|
||||
data['schema'] = target_schema
|
||||
sql, _ = self.get_sql(gid=gid, sid=sid, scid=scid, data=data,
|
||||
tid=oid)
|
||||
sql, _, _ = self.get_sql(gid=gid, sid=sid, scid=scid, data=data,
|
||||
tid=oid)
|
||||
else:
|
||||
if drop_sql:
|
||||
sql = self.delete(gid=gid, sid=sid, did=did,
|
||||
|
||||
@@ -42,6 +42,9 @@ define('pgadmin.node.type', [
|
||||
hasSQL: true,
|
||||
hasDepends: true,
|
||||
width: pgBrowser.stdW.md + 'px',
|
||||
refreshParent: function(node) {
|
||||
return node?._metadata?.data?.has_dependent;
|
||||
},
|
||||
Init: function() {
|
||||
/* Avoid multiple registration of menus */
|
||||
if (this.initialized)
|
||||
|
||||
@@ -192,7 +192,6 @@ function isVisible(state, type) {
|
||||
}
|
||||
|
||||
class EnumerationSchema extends BaseUISchema {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
oid: undefined,
|
||||
@@ -201,18 +200,14 @@ class EnumerationSchema extends BaseUISchema {
|
||||
}
|
||||
|
||||
get idAttribute() {
|
||||
return 'oid';
|
||||
return 'old_label';
|
||||
}
|
||||
|
||||
get baseFields() {
|
||||
let obj = this;
|
||||
return [
|
||||
{
|
||||
id: 'label', label: gettext('Label'),
|
||||
type: 'text', cell: 'text', minWidth: 620,
|
||||
editable: (state) => {
|
||||
return _.isUndefined(obj.isNew) ? true : obj.isNew(state);
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -395,6 +390,15 @@ class RangeSchema extends BaseUISchema {
|
||||
}
|
||||
};
|
||||
},
|
||||
}, {
|
||||
id: 'rngmultirangetype', label: gettext('Multirange type name'),
|
||||
cell: 'string', group: gettext('Range Type'),
|
||||
type: 'text', mode: ['properties', 'create', 'edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
min_version: 140000,
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -562,9 +566,6 @@ class ExternalSchema extends BaseUISchema {
|
||||
group: gettext('Optional-1'),
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
},{
|
||||
id: 'typsend', label: gettext('Send function'),
|
||||
@@ -586,9 +587,6 @@ class ExternalSchema extends BaseUISchema {
|
||||
},
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
},{
|
||||
id: 'typmodin', label: gettext('Typmod in function'),
|
||||
@@ -623,9 +621,6 @@ class ExternalSchema extends BaseUISchema {
|
||||
},
|
||||
mode: ['properties', 'create', 'edit'], group: gettext('Optional-1'),
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
},{
|
||||
id: 'typmodout', label: gettext('Typmod out function'),
|
||||
@@ -661,9 +656,24 @@ class ExternalSchema extends BaseUISchema {
|
||||
},
|
||||
mode: ['properties', 'create', 'edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},{
|
||||
id: 'typanalyze', label: gettext('Analyze function'),
|
||||
group: gettext('Optional-1'),
|
||||
type: (state) => {
|
||||
return obj.getFunctionType(state);
|
||||
},
|
||||
mode: ['properties', 'create','edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
},{
|
||||
id: 'typsubscript', label: gettext('Subscript function'),
|
||||
group: gettext('Optional-1'), min_version: 140000,
|
||||
type: (state) => {
|
||||
return obj.getFunctionType(state);
|
||||
},
|
||||
mode: ['properties', 'create','edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
},{
|
||||
id: 'typlen', label: gettext('Internal length'),
|
||||
cell: 'integer', group: gettext('Optional-1'),
|
||||
@@ -672,14 +682,6 @@ class ExternalSchema extends BaseUISchema {
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
},{
|
||||
id: 'variable', label: gettext('Variable?'), cell: 'switch',
|
||||
group: gettext('Optional-1'), type: 'switch',
|
||||
mode: ['create','edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
},{
|
||||
id: 'typdefault', label: gettext('Default?'),
|
||||
cell: 'string', group: gettext('Optional-1'),
|
||||
@@ -688,18 +690,6 @@ class ExternalSchema extends BaseUISchema {
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
},{
|
||||
id: 'typanalyze', label: gettext('Analyze function'),
|
||||
group: gettext('Optional-1'),
|
||||
type: (state) => {
|
||||
return obj.getFunctionType(state);
|
||||
},
|
||||
mode: ['properties', 'create','edit'],
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
},{
|
||||
id: 'typcategory', label: gettext('Category type'),
|
||||
cell: 'string',
|
||||
@@ -792,9 +782,6 @@ class ExternalSchema extends BaseUISchema {
|
||||
type: 'select', mode: ['properties', 'create', 'edit'],
|
||||
group: gettext('Optional-2'), cell: 'string',
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
controlProps: { allowClear: true, placeholder: '', width: '100%' },
|
||||
options: obj.fieldOptions.typStorageOptions,
|
||||
},{
|
||||
@@ -1258,14 +1245,13 @@ export default class TypeSchema extends BaseUISchema {
|
||||
},
|
||||
{
|
||||
id: 'typtype', label: gettext('Type'),
|
||||
mode: ['create','edit'], group: gettext('Definition'),
|
||||
type: 'select',
|
||||
mode: ['create','edit', 'properties'], group: gettext('Definition'),
|
||||
disabled: () => obj.inCatalog(),
|
||||
readonly: function (state) {
|
||||
return !obj.isNew(state);
|
||||
},
|
||||
controlProps: { allowClear: false },
|
||||
options: function() {
|
||||
type: (state)=>{
|
||||
let typetype = [
|
||||
{label: gettext('Composite'), value: 'c'},
|
||||
{label: gettext('Enumeration'), value: 'e'},
|
||||
@@ -1273,6 +1259,13 @@ export default class TypeSchema extends BaseUISchema {
|
||||
{label: gettext('Range'), value: 'r'},
|
||||
{label: gettext('Shell'), value: 'p'},
|
||||
];
|
||||
|
||||
if (!obj.isNew(state)) {
|
||||
typetype.push(
|
||||
{label: gettext('Multirange'), value: 'm'}
|
||||
);
|
||||
}
|
||||
|
||||
if (obj.fieldOptions.server_info.server_type === 'ppas' &&
|
||||
obj.fieldOptions.server_info.version >= 90500){
|
||||
typetype.push(
|
||||
@@ -1280,7 +1273,12 @@ export default class TypeSchema extends BaseUISchema {
|
||||
{label: gettext('Varying Array'), value: 'V'}
|
||||
);
|
||||
}
|
||||
return typetype;
|
||||
|
||||
return {
|
||||
type: 'select',
|
||||
options: typetype,
|
||||
optionsReloadBasis: state.typtype,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -1305,6 +1303,7 @@ export default class TypeSchema extends BaseUISchema {
|
||||
schema: new EnumerationSchema(),
|
||||
type: 'collection',
|
||||
group: gettext('Definition'), mode: ['edit', 'create'],
|
||||
uniqueCol: ['label'],
|
||||
canAddRow: function(state) {
|
||||
return !obj.isInvalidColumnAdded(state);
|
||||
},
|
||||
@@ -1389,6 +1388,12 @@ export default class TypeSchema extends BaseUISchema {
|
||||
disabled: () => obj.inCatalog(),
|
||||
visible: (state) => isVisible(state, 'r'),
|
||||
},
|
||||
{
|
||||
id: 'rngmultirangetype', label: gettext('Multirange type name'), cell: 'string',
|
||||
type: 'text', mode: ['properties'], group: gettext('Definition'),
|
||||
disabled: () => obj.inCatalog(),
|
||||
visible: (state) => isVisible(state, 'r'),
|
||||
},
|
||||
{
|
||||
id: 'typinput', label: gettext('Input function'), cell: 'string',
|
||||
type: 'text', mode: ['properties'], group: gettext('Definition'),
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
{# The SQL given below will fetch composite type#}
|
||||
{% if typtype == 'c' %}
|
||||
SELECT attnum, attname, pg_catalog.format_type(t.oid,NULL) AS typname, attndims, atttypmod, nsp.nspname,
|
||||
(SELECT COUNT(1) from pg_catalog.pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup,
|
||||
collname, nspc.nspname as collnspname, att.attrelid,
|
||||
pg_catalog.format_type(t.oid, att.atttypmod) AS fulltype,
|
||||
CASE WHEN t.typelem > 0 THEN t.typelem ELSE t.oid END as elemoid
|
||||
FROM pg_catalog.pg_attribute att
|
||||
JOIN pg_catalog.pg_type t ON t.oid=atttypid
|
||||
JOIN pg_catalog.pg_namespace nsp ON t.typnamespace=nsp.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_type b ON t.typelem=b.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_collation c ON att.attcollation=c.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nspc ON c.collnamespace=nspc.oid
|
||||
WHERE att.attrelid = {{typrelid}}::oid
|
||||
ORDER by attnum;
|
||||
{% endif %}
|
||||
|
||||
{# The SQL given below will fetch enum type#}
|
||||
{% if typtype == 'e' %}
|
||||
SELECT enumlabel
|
||||
FROM pg_catalog.pg_enum
|
||||
WHERE enumtypid={{tid}}::oid
|
||||
ORDER by enumsortorder
|
||||
{% endif %}
|
||||
|
||||
{# The SQL given below will fetch range type#}
|
||||
{% if typtype == 'r' %}
|
||||
SELECT rngsubtype, st.typname,
|
||||
rngcollation, mt.typname as rngmultirangetype,
|
||||
CASE WHEN n.nspname IS NOT NULL THEN pg_catalog.concat(pg_catalog.quote_ident(n.nspname), '.', pg_catalog.quote_ident(col.collname)) ELSE col.collname END AS collname,
|
||||
rngsubopc, opc.opcname,
|
||||
rngcanonical, rngsubdiff as rngsubdiff_proc,
|
||||
CASE WHEN length(ns.nspname::text) > 0 AND length(pgpr.proname::text) > 0 THEN
|
||||
pg_catalog.concat(quote_ident(ns.nspname), '.', pg_catalog.quote_ident(pgpr.proname))
|
||||
ELSE '' END AS rngsubdiff
|
||||
FROM pg_catalog.pg_range
|
||||
LEFT JOIN pg_catalog.pg_type st ON st.oid=rngsubtype
|
||||
LEFT JOIN pg_catalog.pg_type mt ON mt.oid=rngmultitypid
|
||||
LEFT JOIN pg_catalog.pg_collation col ON col.oid=rngcollation
|
||||
LEFT JOIN pg_catalog.pg_namespace n ON col.collnamespace=n.oid
|
||||
LEFT JOIN pg_catalog.pg_opclass opc ON opc.oid=rngsubopc
|
||||
LEFT JOIN pg_catalog.pg_proc pgpr ON pgpr.oid = rngsubdiff
|
||||
LEFT JOIN pg_catalog.pg_namespace ns ON ns.oid=pgpr.pronamespace
|
||||
WHERE rngtypid={{tid}}::oid;
|
||||
{% endif %}
|
||||
@@ -0,0 +1,86 @@
|
||||
{% import 'macros/schemas/security.macros' as SECLABEL %}
|
||||
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %}
|
||||
{## If user selected shell type then just create type template ##}
|
||||
{% if data and data.typtype == 'p' %}
|
||||
CREATE TYPE {{ conn|qtIdent(data.schema, data.name) }};
|
||||
{% endif %}
|
||||
{### Composite Type ###}
|
||||
{% if data and data.typtype == 'c' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS
|
||||
({{"\n\t"}}{% if data.composite %}{% for d in data.composite %}{% if loop.index != 1 %},{{"\n\t"}}{% endif %}{{ conn|qtIdent(d.member_name) }} {% if is_sql %}{{ d.fulltype }}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, d.cltype, d.tlength, d.precision, d.hasSqrBracket) }}{% endif %}{% if d.collation %} COLLATE {{d.collation}}{% endif %}{% endfor %}{% endif %}{{"\n"}});
|
||||
{% endif %}
|
||||
{### Enum Type ###}
|
||||
{% if data and data.typtype == 'e' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS ENUM
|
||||
({% for e in data.enum %}{% if loop.index != 1 %}, {% endif %}{{ e.label|qtLiteral(conn) }}{% endfor %});
|
||||
{% endif %}
|
||||
{### Range Type ###}
|
||||
{% if data and data.typtype == 'r' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS RANGE
|
||||
(
|
||||
{% if data.typname %}SUBTYPE={{ conn|qtTypeIdent(data.typname) }}{% endif %}{% if data.collname %},
|
||||
COLLATION = {{ data.collname }}{% endif %}{% if data.opcname %},
|
||||
SUBTYPE_OPCLASS = {{ data.opcname }}{% endif %}{% if data.rngcanonical %},
|
||||
CANONICAL = {{ data.rngcanonical }}{% endif %}{% if data.rngsubdiff %},
|
||||
SUBTYPE_DIFF = {{ data.rngsubdiff }}{% endif %}{% if data.rngmultirangetype %},
|
||||
MULTIRANGE_TYPE_NAME = {{ data.rngmultirangetype }}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{### External Type ###}
|
||||
{% if data and data.typtype == 'b' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %}
|
||||
|
||||
(
|
||||
{% if data.typinput %}INPUT = {{data.typinput}}{% endif %}{% if data.typoutput %},
|
||||
OUTPUT = {{ data.typoutput }}{% endif %}{% if data.typreceive %},
|
||||
RECEIVE = {{data.typreceive}}{% endif %}{% if data.typsend %},
|
||||
SEND = {{data.typsend}}{% endif %}{% if data.typmodin %},
|
||||
TYPMOD_IN = {{data.typmodin}}{% endif %}{% if data.typmodout %},
|
||||
TYPMOD_OUT = {{data.typmodout}}{% endif %}{% if data.typanalyze %},
|
||||
ANALYZE = {{data.typanalyze}}{% endif %}{% if data.typsubscript %},
|
||||
SUBSCRIPT = {{data.typsubscript}}{% endif %}{% if data.typlen %},
|
||||
INTERNALLENGTH = {{data.typlen}}{% endif %}{% if data.typbyval %},
|
||||
PASSEDBYVALUE{% endif %}{% if data.typalign %},
|
||||
ALIGNMENT = {{data.typalign}}{% endif %}{% if data.typstorage %},
|
||||
STORAGE = {{data.typstorage}}{% endif %}{% if data.typcategory %},
|
||||
CATEGORY = {{data.typcategory|qtLiteral(conn)}}{% endif %}{% if data.typispreferred %},
|
||||
PREFERRED = {{data.typispreferred}}{% endif %}{% if data.typdefault %},
|
||||
DEFAULT = {{data.typdefault|qtLiteral(conn)}}{% endif %}{% if data.element %},
|
||||
ELEMENT = {{data.element}}{% endif %}{% if data.typdelim %},
|
||||
DELIMITER = {{data.typdelim|qtLiteral(conn)}}{% endif %}{% if data.is_collatable %},
|
||||
COLLATABLE = {{data.is_collatable}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{### Type Owner ###}
|
||||
{% if data and data.typeowner %}
|
||||
|
||||
ALTER TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %}
|
||||
|
||||
OWNER TO {{ conn|qtIdent(data.typeowner) }};
|
||||
{% endif %}
|
||||
{### Type Comments ###}
|
||||
{% if data and data.description %}
|
||||
|
||||
COMMENT ON TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %}
|
||||
|
||||
IS {{data.description|qtLiteral(conn)}};
|
||||
{% endif %}
|
||||
{### ACL ###}
|
||||
{% if data.typacl %}
|
||||
|
||||
{% for priv in data.typacl %}
|
||||
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{### Security Lables ###}
|
||||
{% if data.seclabels %}
|
||||
|
||||
{% for r in data.seclabels %}
|
||||
{% if r.provider and r.label %}
|
||||
{{ SECLABEL.SET(conn, 'TYPE', data.name, r.provider, r.label, data.schema) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,19 @@
|
||||
SELECT t.oid, t.typname AS name, des.description, ra.rngmultitypid as rngmultirangetype
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT OUTER JOIN pg_catalog.pg_type e ON e.oid=t.typelem
|
||||
LEFT OUTER JOIN pg_catalog.pg_range ra ON ra.rngtypid=t.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = t.typnamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)
|
||||
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' AND t.typnamespace = {{scid}}::oid
|
||||
{% if tid %}
|
||||
AND t.oid = {{tid}}::oid
|
||||
{% endif %}
|
||||
{% if not show_system_objects %}
|
||||
AND ct.oid is NULL
|
||||
{% endif %}
|
||||
{% if schema_diff %}
|
||||
AND CASE WHEN (SELECT COUNT(*) FROM pg_catalog.pg_depend
|
||||
WHERE objid = t.oid AND deptype = 'e') > 0 THEN FALSE ELSE TRUE END
|
||||
{% endif %}
|
||||
ORDER BY t.typname;
|
||||
@@ -0,0 +1,45 @@
|
||||
SELECT t.oid, t.typname AS name,
|
||||
(CASE WHEN CAST(coalesce(t.typcollation, '0') AS integer) = 100 THEN true ElSE false END) AS is_collatable,
|
||||
t.typacl AS type_acl,
|
||||
t.typnamespace, t.typowner, t.typlen, t.typbyval, t.typtype,
|
||||
t.typcategory, t.typispreferred, t.typisdefined, t.typdelim,
|
||||
t.typrelid, t.typelem, t.typarray, t.typalign, t.typstorage,
|
||||
t.typnotnull, t.typbasetype, t.typtypmod, t.typndims,
|
||||
t.typcollation, t.typdefaultbin, t.typdefault,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typinput::oid) AS typinput,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typoutput::oid) AS typoutput,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typreceive::oid) AS typreceive,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typsend::oid) AS typsend,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typmodin::oid) AS typmodin,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typmodout::oid) AS typmodout,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typanalyze::oid) AS typanalyze,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typsubscript::oid) AS typsubscript,
|
||||
pg_catalog.format_type(t.oid, null) AS alias,
|
||||
pg_catalog.pg_get_userbyid(t.typowner) as typeowner, e.typname as element,
|
||||
description, ct.oid AS taboid,
|
||||
nsp.nspname AS schema,
|
||||
--MinimumVersion 9.1 START
|
||||
(SELECT pg_catalog.array_agg(provider || '=' || label) FROM pg_catalog.pg_seclabel sl1 WHERE sl1.objoid=t.oid) AS seclabels,
|
||||
-- END
|
||||
(CASE WHEN (t.oid <= {{ datlastsysoid}}::oid OR ct.oid != 0) THEN true ElSE false END) AS is_sys_type
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT OUTER JOIN pg_catalog.pg_type e ON e.oid=t.typelem
|
||||
LEFT OUTER JOIN pg_catalog.pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = t.typnamespace
|
||||
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' AND t.typnamespace = {{scid}}::oid
|
||||
{% if tid %}
|
||||
AND t.oid = {{tid}}::oid
|
||||
{% endif %}
|
||||
{% if not show_system_objects %}
|
||||
AND ct.oid is NULL
|
||||
{% endif %}
|
||||
ORDER BY t.typname;
|
||||
@@ -0,0 +1,183 @@
|
||||
{% import 'macros/schemas/security.macros' as SECLABEL %}
|
||||
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %}
|
||||
{#======================================#}
|
||||
{# Below will change object owner #}
|
||||
{% if data.typeowner and data.typeowner != o_data.typeowner %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
OWNER TO {{ conn|qtIdent(data.typeowner) }};
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Below will change objects comment #}
|
||||
{% if data.description is defined and data.description != o_data.description %}
|
||||
COMMENT ON TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update composite type ###}
|
||||
{% if data.composite and data.composite|length > 0 %}
|
||||
{% set composite = data.composite %}
|
||||
{% if 'deleted' in composite and composite.deleted|length > 0 %}
|
||||
{% for r in composite.deleted %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
DROP ATTRIBUTE {{conn|qtIdent(r.member_name)}};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'added' in composite and composite.added|length > 0 %}
|
||||
{% for r in composite.added %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ADD ATTRIBUTE {{conn|qtIdent(r.member_name)}} {{ GET_TYPE.CREATE_TYPE_SQL(conn, r.cltype, r.tlength, r.precision, r.hasSqrBracket) }}{% if r.collation %}
|
||||
COLLATE {{r.collation}}{% endif %};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'changed' in composite and composite.changed|length > 0 %}
|
||||
{% for r in composite.changed %}
|
||||
{% for o in o_data.composite %}
|
||||
{##### Variables for the loop #####}
|
||||
{% set member_name = o.member_name %}
|
||||
{% set cltype = o.cltype %}
|
||||
{% set tlength = o.tlength %}
|
||||
{% set precision = o.precision %}
|
||||
{% set hasSqrBracket = o.hasSqrBracket %}
|
||||
{##### If member name changed #####}
|
||||
{% if o.attnum == r.attnum %}
|
||||
{% if r.member_name and o.member_name != r.member_name %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME ATTRIBUTE {{o.member_name}} TO {{r.member_name}};
|
||||
{% set member_name = r.member_name %}
|
||||
{% endif %}
|
||||
{##### If type changed #####}
|
||||
{% if r.cltype and cltype != r.cltype %}
|
||||
{% set cltype = r.cltype %}
|
||||
{% set hasSqrBracket = r.hasSqrBracket %}
|
||||
{##### If length is not allowed on type #####}
|
||||
{% if not r.is_tlength %}
|
||||
{% set tlength = 0 %}
|
||||
{% set precision = 0 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{##### If length changed #####}
|
||||
{% if r.tlength and tlength != r.tlength %}
|
||||
{% set tlength = r.tlength %}
|
||||
{% endif %}
|
||||
{##### If precision changed #####}
|
||||
{% if tlength and r.precision and precision != r.precision %}
|
||||
{% set precision = r.precision %}
|
||||
{% endif %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ALTER ATTRIBUTE {{conn|qtIdent(member_name)}} SET DATA TYPE {{ GET_TYPE.CREATE_TYPE_SQL(conn, cltype, tlength, precision, hasSqrBracket) }}{% if r.collation %}
|
||||
COLLATE {{r.collation}}{% endif %};
|
||||
{% endif%}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update enum type ###}
|
||||
{% if data.enum and data.enum|length > 0 %}
|
||||
{% set enum = data.enum %}
|
||||
{% set o_enum_len = o_data.enum|length %}
|
||||
{# We need actual list index from length #}
|
||||
{% set o_enum_len = o_enum_len - 1 %}
|
||||
{% if 'added' in enum and enum.added|length > 0 %}
|
||||
{% for r in enum.added %}
|
||||
{% set c_idx = loop.index %}
|
||||
{% if c_idx == 1 %}
|
||||
{# if first new element then add it after old data enum list#}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ADD VALUE {{r.label|qtLiteral(conn)}} {% if o_enum_len > 0 %}AFTER {{o_data.enum[o_enum_len].label|qtLiteral(conn) }}{% endif %};
|
||||
{% else %}
|
||||
{# if first new element then add it after new data enum list#}
|
||||
{% set p_idx = loop.index - 2 %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ADD VALUE {{r.label|qtLiteral(conn)}} AFTER {{enum.added[p_idx].label|qtLiteral(conn)}};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'changed' in enum and enum.changed|length > 0 %}
|
||||
{% for r in enum.changed %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME VALUE {{r.old_label|qtLiteral(conn)}} TO {{r.label|qtLiteral(conn)}};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update External type ###}
|
||||
{% if (data.typreceive is defined and data.typreceive != o_data.typreceive) or (data.typsend is defined and data.typsend != o_data.typsend) or (data.typmodin is defined and data.typmodin != o_data.typmodin) or (data.typmodout is defined and data.typmodout != o_data.typmodout) or (data.typanalyze is defined and data.typanalyze != o_data.typanalyze) or (data.typsubscript is defined and data.typsubscript != o_data.typsubscript) or (data.typstorage is defined and data.typstorage != o_data.typstorage)%}
|
||||
{% set ns = namespace(add_comma=false) %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }} SET (
|
||||
{% if data.typreceive is defined %}RECEIVE = {{data.typreceive}}{% set ns.add_comma = true%}{% endif %}{% if data.typsend is defined %}{% if ns.add_comma %},
|
||||
{% endif %}SEND = {{data.typsend}}{% set ns.add_comma = true%}{% endif %}{% if data.typmodin is defined %}{% if ns.add_comma %},
|
||||
{% endif %}TYPMOD_IN = {{data.typmodin}}{% set ns.add_comma = true%}{% endif %}{% if data.typmodout is defined %}{% if ns.add_comma %},
|
||||
{% endif %}TYPMOD_OUT = {{data.typmodout}}{% set ns.add_comma = true%}{% endif %}{% if data.typanalyze is defined %}{% if ns.add_comma %},
|
||||
{% endif %}ANALYZE = {{data.typanalyze}}{% set ns.add_comma = true%}{% endif %}{% if data.typsubscript is defined %}{% if ns.add_comma %},
|
||||
{% endif %}SUBSCRIPT = {{data.typsubscript}}{% set ns.add_comma = true%}{% endif %}{% if data.typstorage is defined %}{% if ns.add_comma %},
|
||||
{% endif %}STORAGE = {{data.typstorage}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# The SQL generated below will change Security Label #}
|
||||
{% if data.seclabels and data.seclabels|length > 0 %}
|
||||
{% set seclabels = data.seclabels %}
|
||||
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
|
||||
{% for r in seclabels.deleted %}
|
||||
{{ SECLABEL.UNSET(conn, 'TYPE', o_data.name, r.provider, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'added' in seclabels and seclabels.added|length > 0 %}
|
||||
{% for r in seclabels.added %}
|
||||
{{ SECLABEL.SET(conn, 'TYPE', o_data.name, r.provider, r.label, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
|
||||
{% for r in seclabels.changed %}
|
||||
{{ SECLABEL.SET(conn, 'TYPE', o_data.name, r.provider, r.label, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Change the privileges #}
|
||||
{% if data.typacl and data.typacl|length > 0 %}
|
||||
{% if 'deleted' in data.typacl %}
|
||||
{% for priv in data.typacl.deleted %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.grantee, o_data.name, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'changed' in data.typacl %}
|
||||
{% for priv in data.typacl.changed %}
|
||||
{% if priv.grantee != priv.old_grantee %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.old_grantee, o_data.name, o_data.schema) }}
|
||||
{% else %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.grantee, o_data.name, o_data.schema) }}
|
||||
{% endif %}
|
||||
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, o_data.name, priv.without_grant, priv.with_grant, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'added' in data.typacl %}
|
||||
{% for priv in data.typacl.added %}
|
||||
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, o_data.name, priv.without_grant, priv.with_grant, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Below will change object name #}
|
||||
{% if data.name and data.name != o_data.name %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Below will change the schema for object #}
|
||||
{# with extra if condition we will also make sure that object has correct name #}
|
||||
{% if data.schema and data.schema != o_data.schema %}
|
||||
ALTER TYPE {% if data.name and data.name != o_data.name %}{{ conn|qtIdent(o_data.schema, data.name) }}
|
||||
{% else %}{{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
{% endif %}
|
||||
SET SCHEMA {{ conn|qtIdent(data.schema) }};
|
||||
{% endif %}
|
||||
@@ -1,6 +1,6 @@
|
||||
SELECT COUNT(*)
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT OUTER JOIN pg_catalog.pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
|
||||
LEFT OUTER JOIN pg_catalog.pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
|
||||
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' AND t.typnamespace = {{scid}}::oid
|
||||
{% if not showsysobj %}
|
||||
AND ct.oid is NULL
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{### Input/Output/Send/Receive/Analyze function list also append into TypModeIN/TypModOUT ###}
|
||||
{% if extfunc %}
|
||||
SELECT proname, nspname,
|
||||
CASE WHEN (length(nspname::text) > 0 AND nspname != 'public') and length(proname::text) > 0 THEN
|
||||
CASE WHEN length(nspname::text) > 0 and length(proname::text) > 0 THEN
|
||||
pg_catalog.concat(pg_catalog.quote_ident(nspname), '.', pg_catalog.quote_ident(proname))
|
||||
WHEN length(proname::text) > 0 THEN
|
||||
pg_catalog.quote_ident(proname)
|
||||
|
||||
@@ -1,7 +1,26 @@
|
||||
SELECT t.oid, t.typname AS name,
|
||||
(CASE WHEN CAST(coalesce(t.typcollation, '0') AS integer) = 100 THEN true ElSE false END) AS is_collatable,
|
||||
t.typacl AS type_acl,
|
||||
t.*, pg_catalog.format_type(t.oid, null) AS alias,
|
||||
t.typnamespace, t.typowner, t.typlen, t.typbyval, t.typtype,
|
||||
t.typcategory, t.typispreferred, t.typisdefined, t.typdelim,
|
||||
t.typrelid, t.typelem, t.typarray, t.typalign, t.typstorage,
|
||||
t.typnotnull, t.typbasetype, t.typtypmod, t.typndims,
|
||||
t.typcollation, t.typdefaultbin, t.typdefault,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typinput::oid) AS typinput,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typoutput::oid) AS typoutput,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typreceive::oid) AS typreceive,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typsend::oid) AS typsend,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typmodin::oid) AS typmodin,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typmodout::oid) AS typmodout,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typanalyze::oid) AS typanalyze,
|
||||
pg_catalog.format_type(t.oid, null) AS alias,
|
||||
pg_catalog.pg_get_userbyid(t.typowner) as typeowner, e.typname as element,
|
||||
description, ct.oid AS taboid,
|
||||
nsp.nspname AS schema,
|
||||
|
||||
@@ -97,6 +97,27 @@ ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'changed' in enum and enum.changed|length > 0 %}
|
||||
{% for r in enum.changed %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME VALUE {{r.old_label|qtLiteral(conn)}} TO {{r.label|qtLiteral(conn)}};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update External type ###}
|
||||
{% if (data.typreceive is defined and data.typreceive != o_data.typreceive) or (data.typsend is defined and data.typsend != o_data.typsend) or (data.typmodin is defined and data.typmodin != o_data.typmodin) or (data.typmodout is defined and data.typmodout != o_data.typmodout) or (data.typanalyze is defined and data.typanalyze != o_data.typanalyze) or (data.typstorage is defined and data.typstorage != o_data.typstorage)%}
|
||||
{% set ns = namespace(add_comma=false) %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }} SET (
|
||||
{% if data.typreceive is defined %}RECEIVE = {{data.typreceive}}{% set ns.add_comma = true%}{% endif %}{% if data.typsend is defined %}{% if ns.add_comma %},
|
||||
{% endif %}SEND = {{data.typsend}}{% set ns.add_comma = true%}{% endif %}{% if data.typmodin is defined %}{% if ns.add_comma %},
|
||||
{% endif %}TYPMOD_IN = {{data.typmodin}}{% set ns.add_comma = true%}{% endif %}{% if data.typmodout is defined %}{% if ns.add_comma %},
|
||||
{% endif %}TYPMOD_OUT = {{data.typmodout}}{% set ns.add_comma = true%}{% endif %}{% if data.typanalyze is defined %}{% if ns.add_comma %},
|
||||
{% endif %}ANALYZE = {{data.typanalyze}}{% set ns.add_comma = true%}{% endif %}{% if data.typstorage is defined %}{% if ns.add_comma %},
|
||||
{% endif %}STORAGE = {{data.typstorage}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# The SQL generated below will change Security Label #}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
{# The SQL given below will fetch composite type#}
|
||||
{% if typtype == 'c' %}
|
||||
SELECT attnum, attname, pg_catalog.format_type(t.oid,NULL) AS typname, attndims, atttypmod, nsp.nspname,
|
||||
(SELECT COUNT(1) from pg_catalog.pg_type t2 WHERE t2.typname=t.typname) > 1 AS isdup,
|
||||
collname, nspc.nspname as collnspname, att.attrelid,
|
||||
pg_catalog.format_type(t.oid, att.atttypmod) AS fulltype,
|
||||
CASE WHEN t.typelem > 0 THEN t.typelem ELSE t.oid END as elemoid
|
||||
FROM pg_catalog.pg_attribute att
|
||||
JOIN pg_catalog.pg_type t ON t.oid=atttypid
|
||||
JOIN pg_catalog.pg_namespace nsp ON t.typnamespace=nsp.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_type b ON t.typelem=b.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_collation c ON att.attcollation=c.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nspc ON c.collnamespace=nspc.oid
|
||||
WHERE att.attrelid = {{typrelid}}::oid
|
||||
ORDER by attnum;
|
||||
{% endif %}
|
||||
|
||||
{# The SQL given below will fetch enum type#}
|
||||
{% if typtype == 'e' %}
|
||||
SELECT enumlabel
|
||||
FROM pg_catalog.pg_enum
|
||||
WHERE enumtypid={{tid}}::oid
|
||||
ORDER by enumsortorder
|
||||
{% endif %}
|
||||
|
||||
{# The SQL given below will fetch range type#}
|
||||
{% if typtype == 'r' %}
|
||||
SELECT rngsubtype, st.typname,
|
||||
rngcollation, mt.typname as rngmultirangetype,
|
||||
CASE WHEN n.nspname IS NOT NULL THEN pg_catalog.concat(pg_catalog.quote_ident(n.nspname), '.', pg_catalog.quote_ident(col.collname)) ELSE col.collname END AS collname,
|
||||
rngsubopc, opc.opcname,
|
||||
rngcanonical, rngsubdiff as rngsubdiff_proc,
|
||||
CASE WHEN length(ns.nspname::text) > 0 AND length(pgpr.proname::text) > 0 THEN
|
||||
pg_catalog.concat(quote_ident(ns.nspname), '.', pg_catalog.quote_ident(pgpr.proname))
|
||||
ELSE '' END AS rngsubdiff
|
||||
FROM pg_catalog.pg_range
|
||||
LEFT JOIN pg_catalog.pg_type st ON st.oid=rngsubtype
|
||||
LEFT JOIN pg_catalog.pg_type mt ON mt.oid=rngmultitypid
|
||||
LEFT JOIN pg_catalog.pg_collation col ON col.oid=rngcollation
|
||||
LEFT JOIN pg_catalog.pg_namespace n ON col.collnamespace=n.oid
|
||||
LEFT JOIN pg_catalog.pg_opclass opc ON opc.oid=rngsubopc
|
||||
LEFT JOIN pg_catalog.pg_proc pgpr ON pgpr.oid = rngsubdiff
|
||||
LEFT JOIN pg_catalog.pg_namespace ns ON ns.oid=pgpr.pronamespace
|
||||
WHERE rngtypid={{tid}}::oid;
|
||||
{% endif %}
|
||||
|
||||
{# The SQL given below will fetch enum type#}
|
||||
{% if typtype == 'N' or typtype == 'V' %}
|
||||
SELECT t.typname AS typname,
|
||||
CASE WHEN t.typelem > 0 THEN t.typelem ELSE t.oid END AS elemoid,
|
||||
t.typtypmod,
|
||||
t.typtype,
|
||||
t.typndims,
|
||||
pg_catalog.format_type(e.oid,NULL) AS type,
|
||||
pg_catalog.format_type(e.oid, t.typtypmod) AS fulltype,
|
||||
nsp.nspname as typnspname,
|
||||
e.typname as type,
|
||||
(SELECT COUNT(1) FROM pg_catalog.pg_type t2 WHERE t2.typname = t.typname) > 1 AS isdup,
|
||||
CASE WHEN t.typcollation != 0 THEN TRUE ELSE FALSE END AS is_collatable
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nsp ON typnamespace=nsp.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_type e ON e.oid=t.typelem
|
||||
WHERE t.oid={{tid}}::oid;
|
||||
{% endif %}
|
||||
@@ -0,0 +1,96 @@
|
||||
{% import 'macros/schemas/security.macros' as SECLABEL %}
|
||||
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %}
|
||||
{## If user selected shell type then just create type template ##}
|
||||
{% if data and data.typtype == 'p' %}
|
||||
CREATE TYPE {{ conn|qtIdent(data.schema, data.name) }};
|
||||
{% endif %}
|
||||
{### Composite Type ###}
|
||||
{% if data and data.typtype == 'c' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS
|
||||
({{"\n\t"}}{% if data.composite %}{% for d in data.composite %}{% if loop.index != 1 %},{{"\n\t"}}{% endif %}{{ conn|qtIdent(d.member_name) }} {% if is_sql %}{{ d.fulltype }}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, d.cltype, d.tlength, d.precision, d.hasSqrBracket) }}{% endif %}{% if d.collation %} COLLATE {{d.collation}}{% endif %}{% endfor %}{% endif %}{{"\n"}});
|
||||
{% endif %}
|
||||
{### Enum Type ###}
|
||||
{% if data and data.typtype == 'e' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS ENUM
|
||||
({% for e in data.enum %}{% if loop.index != 1 %}, {% endif %}{{ e.label|qtLiteral(conn) }}{% endfor %});
|
||||
{% endif %}
|
||||
{### Range Type ###}
|
||||
{% if data and data.typtype == 'r' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS RANGE
|
||||
(
|
||||
{% if data.typname %}SUBTYPE={{ conn|qtTypeIdent(data.typname) }}{% endif %}{% if data.collname %},
|
||||
COLLATION = {{ data.collname }}{% endif %}{% if data.opcname %},
|
||||
SUBTYPE_OPCLASS = {{ data.opcname }}{% endif %}{% if data.rngcanonical %},
|
||||
CANONICAL = {{ data.rngcanonical }}{% endif %}{% if data.rngsubdiff %},
|
||||
SUBTYPE_DIFF = {{ data.rngsubdiff }}{% endif %}{% if data.rngmultirangetype %},
|
||||
MULTIRANGE_TYPE_NAME = {{ data.rngmultirangetype }}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{### External Type ###}
|
||||
{% if data and data.typtype == 'b' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %}
|
||||
|
||||
(
|
||||
{% if data.typinput %}INPUT = {{data.typinput}}{% endif %}{% if data.typoutput %},
|
||||
OUTPUT = {{ data.typoutput }}{% endif %}{% if data.typreceive %},
|
||||
RECEIVE = {{data.typreceive}}{% endif %}{% if data.typsend %},
|
||||
SEND = {{data.typsend}}{% endif %}{% if data.typmodin %},
|
||||
TYPMOD_IN = {{data.typmodin}}{% endif %}{% if data.typmodout %},
|
||||
TYPMOD_OUT = {{data.typmodout}}{% endif %}{% if data.typanalyze %},
|
||||
ANALYZE = {{data.typanalyze}}{% endif %}{% if data.typsubscript %},
|
||||
SUBSCRIPT = {{data.typsubscript}}{% endif %}{% if data.typlen %},
|
||||
INTERNALLENGTH = {{data.typlen}}{% endif %}{% if data.typbyval %},
|
||||
PASSEDBYVALUE{% endif %}{% if data.typalign %},
|
||||
ALIGNMENT = {{data.typalign}}{% endif %}{% if data.typstorage %},
|
||||
STORAGE = {{data.typstorage}}{% endif %}{% if data.typcategory %},
|
||||
CATEGORY = {{data.typcategory|qtLiteral(conn)}}{% endif %}{% if data.typispreferred %},
|
||||
PREFERRED = {{data.typispreferred}}{% endif %}{% if data.typdefault %},
|
||||
DEFAULT = {{data.typdefault|qtLiteral(conn)}}{% endif %}{% if data.element %},
|
||||
ELEMENT = {{data.element}}{% endif %}{% if data.typdelim %},
|
||||
DELIMITER = {{data.typdelim|qtLiteral(conn)}}{% endif %}{% if data.is_collatable %},
|
||||
COLLATABLE = {{data.is_collatable}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{### Nested-table Type ###}
|
||||
{% if data and data.typtype == 'N' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS TABLE OF
|
||||
{% if is_sql %}{{ data.fulltype }}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, data.cltype, data.tlength, data.precision, data.hasSqrBracket) }}{% endif %};
|
||||
{% endif %}
|
||||
{### VARRAY Type ###}
|
||||
{% if data and data.typtype == 'V' %}
|
||||
CREATE TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %} AS VARRAY({{data.maxsize}}) OF
|
||||
{% if is_sql %}{{ data.fulltype }}{% else %}{{ GET_TYPE.CREATE_TYPE_SQL(conn, data.cltype, data.tlength, data.precision, data.hasSqrBracket) }}{% endif %};
|
||||
{% endif %}
|
||||
|
||||
{### Type Owner ###}
|
||||
{% if data and data.typeowner %}
|
||||
ALTER TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %}
|
||||
|
||||
OWNER TO {{ conn|qtIdent(data.typeowner) }};
|
||||
{% endif %}
|
||||
{### Type Comments ###}
|
||||
{% if data and data.description %}
|
||||
|
||||
COMMENT ON TYPE {% if data.schema %}{{ conn|qtIdent(data.schema, data.name) }}{% else %}{{ conn|qtIdent(data.name) }}{% endif %}
|
||||
|
||||
IS {{data.description|qtLiteral(conn)}};
|
||||
{% endif %}
|
||||
{### ACL ###}
|
||||
{% if data.typacl %}
|
||||
|
||||
{% for priv in data.typacl %}
|
||||
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, data.name, priv.without_grant, priv.with_grant, data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{### Security Lables ###}
|
||||
{% if data.seclabels %}
|
||||
|
||||
{% for r in data.seclabels %}
|
||||
{% if r.provider and r.label %}
|
||||
{{ SECLABEL.SET(conn, 'TYPE', data.name, r.provider, r.label, data.schema) }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,19 @@
|
||||
SELECT t.oid, t.typname AS name, des.description, ra.rngmultitypid as rngmultirangetype
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT OUTER JOIN pg_catalog.pg_type e ON e.oid=t.typelem
|
||||
LEFT OUTER JOIN pg_catalog.pg_range ra ON ra.rngtypid=t.oid
|
||||
LEFT OUTER JOIN pg_catalog.pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = t.typnamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)
|
||||
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' AND t.typnamespace = {{scid}}::oid
|
||||
{% if tid %}
|
||||
AND t.oid = {{tid}}::oid
|
||||
{% endif %}
|
||||
{% if not show_system_objects %}
|
||||
AND ct.oid is NULL
|
||||
{% endif %}
|
||||
{% if schema_diff %}
|
||||
AND CASE WHEN (SELECT COUNT(*) FROM pg_catalog.pg_depend
|
||||
WHERE objid = t.oid AND deptype = 'e') > 0 THEN FALSE ELSE TRUE END
|
||||
{% endif %}
|
||||
ORDER BY t.typname;
|
||||
@@ -0,0 +1,45 @@
|
||||
SELECT t.oid, t.typname AS name,
|
||||
(CASE WHEN CAST(coalesce(t.typcollation, '0') AS integer) = 100 THEN true ElSE false END) AS is_collatable,
|
||||
t.typacl AS type_acl,
|
||||
t.typnamespace, t.typowner, t.typlen, t.typbyval, t.typtype,
|
||||
t.typcategory, t.typispreferred, t.typisdefined, t.typdelim,
|
||||
t.typrelid, t.typelem, t.typarray, t.typalign, t.typstorage,
|
||||
t.typnotnull, t.typbasetype, t.typtypmod, t.typndims,
|
||||
t.typcollation, t.typdefaultbin, t.typdefault,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typinput::oid) AS typinput,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typoutput::oid) AS typoutput,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typreceive::oid) AS typreceive,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typsend::oid) AS typsend,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typmodin::oid) AS typmodin,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typmodout::oid) AS typmodout,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typanalyze::oid) AS typanalyze,
|
||||
(SELECT pg_catalog.concat(nspname, '.', proname,'') FROM pg_proc pr JOIN pg_namespace nsp ON pr.pronamespace = nsp.oid
|
||||
WHERE pr.oid = t.typsubscript::oid) AS typsubscript,
|
||||
pg_catalog.format_type(t.oid, null) AS alias,
|
||||
pg_catalog.pg_get_userbyid(t.typowner) as typeowner, e.typname as element,
|
||||
description, ct.oid AS taboid,
|
||||
nsp.nspname AS schema,
|
||||
--MinimumVersion 9.1 START
|
||||
(SELECT pg_catalog.array_agg(provider || '=' || label) FROM pg_catalog.pg_seclabel sl1 WHERE sl1.objoid=t.oid) AS seclabels,
|
||||
-- END
|
||||
(CASE WHEN (t.oid <= {{ datlastsysoid}}::oid OR ct.oid != 0) THEN true ElSE false END) AS is_sys_type
|
||||
FROM pg_catalog.pg_type t
|
||||
LEFT OUTER JOIN pg_catalog.pg_type e ON e.oid=t.typelem
|
||||
LEFT OUTER JOIN pg_catalog.pg_class ct ON ct.oid=t.typrelid AND ct.relkind <> 'c'
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=t.oid AND des.classoid='pg_type'::regclass)
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace nsp ON nsp.oid = t.typnamespace
|
||||
WHERE t.typtype != 'd' AND t.typname NOT LIKE E'\\_%' AND t.typnamespace = {{scid}}::oid
|
||||
{% if tid %}
|
||||
AND t.oid = {{tid}}::oid
|
||||
{% endif %}
|
||||
{% if not show_system_objects %}
|
||||
AND ct.oid is NULL
|
||||
{% endif %}
|
||||
ORDER BY t.typname;
|
||||
@@ -0,0 +1,183 @@
|
||||
{% import 'macros/schemas/security.macros' as SECLABEL %}
|
||||
{% import 'macros/schemas/privilege.macros' as PRIVILEGE %}
|
||||
{% import 'types/macros/get_full_type_sql_format.macros' as GET_TYPE %}
|
||||
{#======================================#}
|
||||
{# Below will change object owner #}
|
||||
{% if data.typeowner and data.typeowner != o_data.typeowner %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
OWNER TO {{ conn|qtIdent(data.typeowner) }};
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Below will change objects comment #}
|
||||
{% if data.description is defined and data.description != o_data.description %}
|
||||
COMMENT ON TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
IS {{ data.description|qtLiteral(conn) }};
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update composite type ###}
|
||||
{% if data.composite and data.composite|length > 0 %}
|
||||
{% set composite = data.composite %}
|
||||
{% if 'deleted' in composite and composite.deleted|length > 0 %}
|
||||
{% for r in composite.deleted %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
DROP ATTRIBUTE {{conn|qtIdent(r.member_name)}};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'added' in composite and composite.added|length > 0 %}
|
||||
{% for r in composite.added %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ADD ATTRIBUTE {{conn|qtIdent(r.member_name)}} {{ GET_TYPE.CREATE_TYPE_SQL(conn, r.cltype, r.tlength, r.precision, r.hasSqrBracket) }}{% if r.collation %}
|
||||
COLLATE {{r.collation}}{% endif %};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'changed' in composite and composite.changed|length > 0 %}
|
||||
{% for r in composite.changed %}
|
||||
{% for o in o_data.composite %}
|
||||
{##### Variables for the loop #####}
|
||||
{% set member_name = o.member_name %}
|
||||
{% set cltype = o.cltype %}
|
||||
{% set tlength = o.tlength %}
|
||||
{% set precision = o.precision %}
|
||||
{% set hasSqrBracket = o.hasSqrBracket %}
|
||||
{##### If member name changed #####}
|
||||
{% if o.attnum == r.attnum %}
|
||||
{% if r.member_name and o.member_name != r.member_name %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME ATTRIBUTE {{o.member_name}} TO {{r.member_name}};
|
||||
{% set member_name = r.member_name %}
|
||||
{% endif %}
|
||||
{##### If type changed #####}
|
||||
{% if r.cltype and cltype != r.cltype %}
|
||||
{% set cltype = r.cltype %}
|
||||
{% set hasSqrBracket = r.hasSqrBracket %}
|
||||
{##### If length is not allowed on type #####}
|
||||
{% if not r.is_tlength %}
|
||||
{% set tlength = 0 %}
|
||||
{% set precision = 0 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{##### If length changed #####}
|
||||
{% if r.tlength and tlength != r.tlength %}
|
||||
{% set tlength = r.tlength %}
|
||||
{% endif %}
|
||||
{##### If precision changed #####}
|
||||
{% if tlength and r.precision and precision != r.precision %}
|
||||
{% set precision = r.precision %}
|
||||
{% endif %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ALTER ATTRIBUTE {{conn|qtIdent(member_name)}} SET DATA TYPE {{ GET_TYPE.CREATE_TYPE_SQL(conn, cltype, tlength, precision, hasSqrBracket) }}{% if r.collation %}
|
||||
COLLATE {{r.collation}}{% endif %};
|
||||
{% endif%}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update enum type ###}
|
||||
{% if data.enum and data.enum|length > 0 %}
|
||||
{% set enum = data.enum %}
|
||||
{% set o_enum_len = o_data.enum|length %}
|
||||
{# We need actual list index from length #}
|
||||
{% set o_enum_len = o_enum_len - 1 %}
|
||||
{% if 'added' in enum and enum.added|length > 0 %}
|
||||
{% for r in enum.added %}
|
||||
{% set c_idx = loop.index %}
|
||||
{% if c_idx == 1 %}
|
||||
{# if first new element then add it after old data enum list#}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ADD VALUE {{r.label|qtLiteral(conn)}} {% if o_enum_len > 0 %}AFTER {{o_data.enum[o_enum_len].label|qtLiteral(conn) }}{% endif %};
|
||||
{% else %}
|
||||
{# if first new element then add it after new data enum list#}
|
||||
{% set p_idx = loop.index - 2 %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
ADD VALUE {{r.label|qtLiteral(conn)}} AFTER {{enum.added[p_idx].label|qtLiteral(conn)}};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if 'changed' in enum and enum.changed|length > 0 %}
|
||||
{% for r in enum.changed %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME VALUE {{r.old_label|qtLiteral(conn)}} TO {{r.label|qtLiteral(conn)}};
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{### The sql given below will update External type ###}
|
||||
{% if (data.typreceive is defined and data.typreceive != o_data.typreceive) or (data.typsend is defined and data.typsend != o_data.typsend) or (data.typmodin is defined and data.typmodin != o_data.typmodin) or (data.typmodout is defined and data.typmodout != o_data.typmodout) or (data.typanalyze is defined and data.typanalyze != o_data.typanalyze) or (data.typsubscript is defined and data.typsubscript != o_data.typsubscript) or (data.typstorage is defined and data.typstorage != o_data.typstorage)%}
|
||||
{% set ns = namespace(add_comma=false) %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }} SET (
|
||||
{% if data.typreceive is defined %}RECEIVE = {{data.typreceive}}{% set ns.add_comma = true%}{% endif %}{% if data.typsend is defined %}{% if ns.add_comma %},
|
||||
{% endif %}SEND = {{data.typsend}}{% set ns.add_comma = true%}{% endif %}{% if data.typmodin is defined %}{% if ns.add_comma %},
|
||||
{% endif %}TYPMOD_IN = {{data.typmodin}}{% set ns.add_comma = true%}{% endif %}{% if data.typmodout is defined %}{% if ns.add_comma %},
|
||||
{% endif %}TYPMOD_OUT = {{data.typmodout}}{% set ns.add_comma = true%}{% endif %}{% if data.typanalyze is defined %}{% if ns.add_comma %},
|
||||
{% endif %}ANALYZE = {{data.typanalyze}}{% set ns.add_comma = true%}{% endif %}{% if data.typsubscript is defined %}{% if ns.add_comma %},
|
||||
{% endif %}SUBSCRIPT = {{data.typsubscript}}{% set ns.add_comma = true%}{% endif %}{% if data.typstorage is defined %}{% if ns.add_comma %},
|
||||
{% endif %}STORAGE = {{data.typstorage}}{% endif %}
|
||||
|
||||
);
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# The SQL generated below will change Security Label #}
|
||||
{% if data.seclabels and data.seclabels|length > 0 %}
|
||||
{% set seclabels = data.seclabels %}
|
||||
{% if 'deleted' in seclabels and seclabels.deleted|length > 0 %}
|
||||
{% for r in seclabels.deleted %}
|
||||
{{ SECLABEL.UNSET(conn, 'TYPE', o_data.name, r.provider, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'added' in seclabels and seclabels.added|length > 0 %}
|
||||
{% for r in seclabels.added %}
|
||||
{{ SECLABEL.SET(conn, 'TYPE', o_data.name, r.provider, r.label, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'changed' in seclabels and seclabels.changed|length > 0 %}
|
||||
{% for r in seclabels.changed %}
|
||||
{{ SECLABEL.SET(conn, 'TYPE', o_data.name, r.provider, r.label, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Change the privileges #}
|
||||
{% if data.typacl and data.typacl|length > 0 %}
|
||||
{% if 'deleted' in data.typacl %}
|
||||
{% for priv in data.typacl.deleted %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.grantee, o_data.name, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'changed' in data.typacl %}
|
||||
{% for priv in data.typacl.changed %}
|
||||
{% if priv.grantee != priv.old_grantee %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.old_grantee, o_data.name, o_data.schema) }}
|
||||
{% else %}
|
||||
{{ PRIVILEGE.UNSETALL(conn, 'TYPE', priv.grantee, o_data.name, o_data.schema) }}
|
||||
{% endif %}
|
||||
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, o_data.name, priv.without_grant, priv.with_grant, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'added' in data.typacl %}
|
||||
{% for priv in data.typacl.added %}
|
||||
{{ PRIVILEGE.SET(conn, 'TYPE', priv.grantee, o_data.name, priv.without_grant, priv.with_grant, o_data.schema) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Below will change object name #}
|
||||
{% if data.name and data.name != o_data.name %}
|
||||
ALTER TYPE {{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
RENAME TO {{ conn|qtIdent(data.name) }};
|
||||
|
||||
{% endif %}
|
||||
{#======================================#}
|
||||
{# Below will change the schema for object #}
|
||||
{# with extra if condition we will also make sure that object has correct name #}
|
||||
{% if data.schema and data.schema != o_data.schema %}
|
||||
ALTER TYPE {% if data.name and data.name != o_data.name %}{{ conn|qtIdent(o_data.schema, data.name) }}
|
||||
{% else %}{{ conn|qtIdent(o_data.schema, o_data.name) }}
|
||||
{% endif %}
|
||||
SET SCHEMA {{ conn|qtIdent(data.schema) }};
|
||||
{% endif %}
|
||||