├── pgmanage ├── app │ ├── __init__.py │ ├── bgjob │ │ └── __init__.py │ ├── include │ │ ├── __init__.py │ │ ├── Spartacus │ │ │ └── __init__.py │ │ └── OmniDatabase │ │ │ └── sql_templates │ │ │ └── __init__.py │ ├── plugins │ │ ├── .gitkeep │ │ └── temp_loaded │ │ │ └── .gitkeep │ ├── static │ │ ├── temp │ │ │ └── .gitkeep │ │ ├── plugins │ │ │ ├── .gitkeep │ │ │ └── temp_loaded │ │ │ │ └── .gitkeep │ │ └── pgmanage_frontend │ │ │ ├── src │ │ │ ├── index.js │ │ │ ├── emitter.js │ │ │ ├── assets │ │ │ │ ├── images │ │ │ │ │ ├── .directory │ │ │ │ │ ├── right.png │ │ │ │ │ ├── pgmanage_16.png │ │ │ │ │ ├── db_icons │ │ │ │ │ │ ├── mssql_large.png │ │ │ │ │ │ ├── mysql_large.png │ │ │ │ │ │ ├── mariadb_large.png │ │ │ │ │ │ ├── mysql_medium.png │ │ │ │ │ │ ├── oracle_large.png │ │ │ │ │ │ ├── oracle_medium.png │ │ │ │ │ │ ├── sqlite_large.png │ │ │ │ │ │ ├── sqlite_medium.png │ │ │ │ │ │ ├── mariadb_medium.png │ │ │ │ │ │ ├── postgresql_large.png │ │ │ │ │ │ ├── postgresql_medium.png │ │ │ │ │ │ └── oracle.svg │ │ │ │ │ ├── supporters │ │ │ │ │ │ └── command_prompt_inc.png │ │ │ │ │ ├── oracle.svg │ │ │ │ │ └── mariadb.svg │ │ │ │ ├── scss │ │ │ │ │ ├── components │ │ │ │ │ │ ├── tables.scss │ │ │ │ │ │ ├── data-editor-tab.scss │ │ │ │ │ │ ├── list-group.scss │ │ │ │ │ │ ├── pagination.scss │ │ │ │ │ │ ├── card.scss │ │ │ │ │ │ ├── floating-toolbar.scss │ │ │ │ │ │ ├── search-modal.scss │ │ │ │ │ │ ├── bootstrap-tooltips.scss │ │ │ │ │ │ ├── snippets.scss │ │ │ │ │ │ └── schema-editor.scss │ │ │ │ │ ├── libs │ │ │ │ │ │ ├── alert.scss │ │ │ │ │ │ ├── pev2 │ │ │ │ │ │ │ ├── pev2.scss │ │ │ │ │ │ │ ├── tweaks.scss │ │ │ │ │ │ │ ├── copy-button.scss │ │ │ │ │ │ │ ├── variables.scss │ │ │ │ │ │ │ └── plan-grid.scss │ │ │ │ │ │ └── toasts.scss │ │ │ │ │ └── common │ │ │ │ │ │ ├── typography.scss │ │ │ │ │ │ └── ui-elements.scss │ │ │ │ ├── fonts │ │ │ │ │ ├── Roboto │ │ │ │ │ │ ├── Roboto-Bold.ttf │ │ │ │ │ │ ├── Roboto-Thin.ttf │ │ │ │ │ │ ├── Roboto-Black.ttf │ │ │ │ │ │ ├── Roboto-Italic.ttf │ │ │ │ │ │ ├── Roboto-Light.ttf │ │ │ │ │ │ ├── Roboto-Medium.ttf │ │ │ │ │ │ ├── Roboto-Regular.ttf │ │ │ │ │ │ ├── Roboto-BlackItalic.ttf │ │ │ │ │ │ ├── Roboto-BoldItalic.ttf │ │ │ │ │ │ ├── Roboto-LightItalic.ttf │ │ │ │ │ │ ├── Roboto-MediumItalic.ttf │ │ │ │ │ │ └── Roboto-ThinItalic.ttf │ │ │ │ │ ├── RobotoMono │ │ │ │ │ │ ├── RobotoMono-Bold.ttf │ │ │ │ │ │ ├── RobotoMono-Thin.ttf │ │ │ │ │ │ ├── RobotoMono-Italic.ttf │ │ │ │ │ │ ├── RobotoMono-Light.ttf │ │ │ │ │ │ ├── RobotoMono-Medium.ttf │ │ │ │ │ │ ├── RobotoMono-Regular.ttf │ │ │ │ │ │ ├── RobotoMono-BoldItalic.ttf │ │ │ │ │ │ ├── RobotoMono-LightItalic.ttf │ │ │ │ │ │ ├── RobotoMono-ThinItalic.ttf │ │ │ │ │ │ └── RobotoMono-MediumItalic.ttf │ │ │ │ │ ├── Poppins │ │ │ │ │ │ ├── poppins-v20-latin-500.woff │ │ │ │ │ │ ├── poppins-v20-latin-500.woff2 │ │ │ │ │ │ ├── poppins-v20-latin-700.woff │ │ │ │ │ │ ├── poppins-v20-latin-700.woff2 │ │ │ │ │ │ ├── poppins-v20-latin-regular.woff │ │ │ │ │ │ └── poppins-v20-latin-regular.woff2 │ │ │ │ │ └── UbuntuMono │ │ │ │ │ │ ├── ubuntumono-regular-webfont.woff │ │ │ │ │ │ └── ubuntumono-regular-webfont.woff2 │ │ │ │ └── css │ │ │ │ │ ├── font-ubuntu-mono.css │ │ │ │ │ └── font-poppins.css │ │ │ ├── stores │ │ │ │ ├── snippets.js │ │ │ │ ├── utility_jobs.js │ │ │ │ ├── celldata_modal.js │ │ │ │ ├── commands_history.js │ │ │ │ ├── utilities_menu.js │ │ │ │ ├── file_manager.js │ │ │ │ ├── message_modal.js │ │ │ │ ├── stores_initializer.js │ │ │ │ └── db_metadata.js │ │ │ ├── mixins │ │ │ │ ├── humanize_duration_mixin.js │ │ │ │ ├── power_tree_pin_database_mixin.js │ │ │ │ └── tabs_utils_mixin.js │ │ │ ├── logging │ │ │ │ ├── utils.js │ │ │ │ └── logger_setup.js │ │ │ ├── ace_extras │ │ │ │ ├── mode-mysql-extended.js │ │ │ │ └── mode-pgsql-extended.js │ │ │ ├── components │ │ │ │ ├── ConfirmableButton.vue │ │ │ │ ├── BlockSizeSelector.vue │ │ │ │ ├── ExplainTabContent.vue │ │ │ │ ├── CancelSQLButton.vue │ │ │ │ └── ConfigTabGroup.vue │ │ │ ├── tree_context_functions │ │ │ │ └── tree_mssql.js │ │ │ ├── login.js │ │ │ └── utils.js │ │ │ ├── test │ │ │ ├── global_setup.js │ │ │ ├── stores │ │ │ │ ├── snippets.test.js │ │ │ │ ├── celldata_modal.test.js │ │ │ │ ├── utitlity_jobs.test.js │ │ │ │ └── commands_history.test.js │ │ │ └── components │ │ │ │ ├── MonitoringWidgetsModal.test.js │ │ │ │ ├── SideBarTabs.test.js │ │ │ │ ├── TreePropertiesDDL.test.js │ │ │ │ ├── BlockSizeSelector.test.js │ │ │ │ └── AboutModal.test.js │ │ │ ├── .gitignore │ │ │ └── public │ │ │ └── vite.svg │ ├── utils │ │ ├── __init__.py │ │ ├── key_manager.py │ │ └── postgresql_utilities.py │ ├── file_manager │ │ └── __init__.py │ ├── migrations │ │ ├── __init__.py │ │ ├── 0028_merge_20250821_0702.py │ │ ├── 0017_merge_20240209_1300.py │ │ ├── 0023_remove_userdetails_welcome_closed.py │ │ ├── 0006_userdetails_binary_path.py │ │ ├── 0018_userdetails_restore_tabs.py │ │ ├── 0020_connection_color_label.py │ │ ├── 0003_userdetails_masterpass_check.py │ │ ├── 0012_userdetails_autocomplete.py │ │ ├── 0019_userdetails_scroll_tree.py │ │ ├── 0013_connection_last_access_date.py │ │ ├── 0010_connection_last_used_database.py │ │ ├── 0011_userdetails_pigz_path.py │ │ ├── 0008_userdetails_date_format.py │ │ ├── 0030_populate_mssql-technology.py │ │ ├── 0026_connection_pinned_databases.py │ │ ├── 0002_3_0_1.py │ │ ├── 0026_alter_monwidgets_script_chart.py │ │ ├── 0024_drop_old_dashboard_settings.py │ │ ├── 0014_auto_20231222_1353.py │ │ ├── 0016_replace_is_default_with_editable.py │ │ ├── 0015_rename_monunits_and_monunitsconnections.py │ │ ├── 0015_query_and_console_history_database.py │ │ ├── 0025_monwidgetsconnections_position_and_more.py │ │ ├── 0022_alter_userdetails_csv_delimiter.py │ │ ├── 0029_auto_20250904_1353.py │ │ ├── 0027_erdlayout.py │ │ ├── 0009_tab_database.py │ │ ├── 0004_confighistory.py │ │ ├── 0021_group_unique_user_group_name.py │ │ ├── 0007_connection_connection_params.py │ │ └── 0005_job.py │ ├── models │ │ └── __init__.py │ ├── models.py │ ├── admin.py │ ├── client_manager │ │ └── __init__.py │ ├── apps.py │ ├── tests.old │ │ ├── webdrivers │ │ │ └── geckodriver │ │ ├── postgresql │ │ │ ├── dellstore2-normal-1.0.tar.gz │ │ │ └── restore.sh │ │ ├── __init__.py │ │ ├── vagrant │ │ │ ├── xl-10 │ │ │ │ ├── start.sh │ │ │ │ ├── install.sh │ │ │ │ ├── setup.sh │ │ │ │ ├── README.md │ │ │ │ └── init.sh │ │ │ ├── xl-9.5 │ │ │ │ ├── start.sh │ │ │ │ ├── install.sh │ │ │ │ ├── setup.sh │ │ │ │ ├── README.md │ │ │ │ └── init.sh │ │ │ ├── postgresql-10-2nodes │ │ │ │ └── Vagrantfile │ │ │ ├── postgresql-bdr-9.4-2nodes │ │ │ │ └── Vagrantfile │ │ │ └── pglogical-2-postgresql-10-2nodes │ │ │ │ └── Vagrantfile │ │ ├── oracle │ │ │ ├── listener.ora │ │ │ ├── oracle-xe-18c.conf.tmpl │ │ │ ├── tnsnames.ora │ │ │ └── Dockerfile │ │ ├── README.md │ │ ├── mysql │ │ │ └── README.md │ │ └── mariadb │ │ │ └── README.md │ ├── tests │ │ ├── dellstore2-normal-1.0.sql │ │ ├── __init__.py │ │ ├── test-db.sh │ │ └── docker-compose.yml │ ├── converters.py │ ├── views │ │ ├── __init__.py │ │ ├── logging.py │ │ └── bgjob.py │ ├── middleware.py │ └── serializers.py ├── pgmanage │ ├── __init__.py │ ├── logging_filter.py │ ├── custom_settings.py │ ├── wsgi.py │ ├── startup.py │ └── urls.py ├── deploy.old │ ├── lib │ │ ├── libXss.so.1 │ │ └── libnss3.so │ ├── app_centos7 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── app_debian8 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── plugin_centos6 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── plugin_centos7 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── plugin_debian8 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── server_centos6 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── server_centos7 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ ├── server_debian8 │ │ ├── clone.sh │ │ ├── Dockerfile │ │ └── README.md │ └── plugin_freebsd │ │ ├── Vagrantfile │ │ └── test_instructions.txt ├── manage.py ├── process_executor-lin.spec ├── process_executor-mac.spec ├── process_executor-win.spec └── config.py ├── .dockerignore ├── artwork ├── showcase.gif ├── pgmanage_128.png ├── pgmanage_16.png ├── pgmanage_24.png ├── pgmanage_256.png ├── pgmanage_32.png ├── pgmanage_48.png ├── pgmanage_512.png ├── pgmanage_64.png ├── pgmanage_96.png └── readme_banner.png ├── deploy ├── macosx │ ├── mac-icon.icns │ └── README.md ├── windows │ ├── win-icon.ico │ ├── install_header.bmp │ └── license.txt ├── app │ ├── pgmanage_icon.png │ ├── package.json │ └── pgmanage.desktop └── linux │ ├── pkgbuild │ ├── icons.tar.gz │ └── Dockerfile │ ├── build_images.sh │ └── deploy.sh ├── .gitignore ├── AUTHORS.md ├── requirements.txt ├── pyproject.toml ├── LICENSE ├── tests └── uat │ ├── ubuntu16 │ └── Vagrantfile │ ├── ubuntu18 │ └── Vagrantfile │ ├── opensuse │ └── Vagrantfile │ ├── debian10 │ └── Vagrantfile │ ├── debian9 │ └── Vagrantfile │ ├── fedora31 │ └── Vagrantfile │ ├── centos7 │ └── Vagrantfile │ ├── centos8 │ └── Vagrantfile │ └── centos6 │ └── Vagrantfile └── DEVELOPMENT.MD /pgmanage/app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/bgjob/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/include/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/static/temp/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/pgmanage/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/file_manager/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/static/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/include/Spartacus/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/plugins/temp_loaded/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/static/plugins/temp_loaded/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .main import * 2 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/index.js: -------------------------------------------------------------------------------- 1 | // template file -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | .gitignore 3 | Vagrantfile 4 | 5 | *.txt 6 | *.xlsx 7 | -------------------------------------------------------------------------------- /pgmanage/app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /artwork/showcase.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/showcase.gif -------------------------------------------------------------------------------- /pgmanage/app/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /pgmanage/app/client_manager/__init__.py: -------------------------------------------------------------------------------- 1 | from .client_manager import client_manager, Client 2 | -------------------------------------------------------------------------------- /artwork/pgmanage_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_128.png -------------------------------------------------------------------------------- /artwork/pgmanage_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_16.png -------------------------------------------------------------------------------- /artwork/pgmanage_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_24.png -------------------------------------------------------------------------------- /artwork/pgmanage_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_256.png -------------------------------------------------------------------------------- /artwork/pgmanage_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_32.png -------------------------------------------------------------------------------- /artwork/pgmanage_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_48.png -------------------------------------------------------------------------------- /artwork/pgmanage_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_512.png -------------------------------------------------------------------------------- /artwork/pgmanage_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_64.png -------------------------------------------------------------------------------- /artwork/pgmanage_96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/pgmanage_96.png -------------------------------------------------------------------------------- /artwork/readme_banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/artwork/readme_banner.png -------------------------------------------------------------------------------- /deploy/macosx/mac-icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/deploy/macosx/mac-icon.icns -------------------------------------------------------------------------------- /deploy/windows/win-icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/deploy/windows/win-icon.ico -------------------------------------------------------------------------------- /deploy/app/pgmanage_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/deploy/app/pgmanage_icon.png -------------------------------------------------------------------------------- /deploy/linux/pkgbuild/icons.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/deploy/linux/pkgbuild/icons.tar.gz -------------------------------------------------------------------------------- /deploy/windows/install_header.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/deploy/windows/install_header.bmp -------------------------------------------------------------------------------- /pgmanage/deploy.old/lib/libXss.so.1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/deploy.old/lib/libXss.so.1 -------------------------------------------------------------------------------- /pgmanage/deploy.old/lib/libnss3.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/deploy.old/lib/libnss3.so -------------------------------------------------------------------------------- /pgmanage/app/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class PgmanageAppConfig(AppConfig): 5 | name = 'app' 6 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/emitter.js: -------------------------------------------------------------------------------- 1 | import mitt from 'mitt' 2 | 3 | const emitter = mitt() 4 | 5 | export { emitter } -------------------------------------------------------------------------------- /pgmanage/app/tests.old/webdrivers/geckodriver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/tests.old/webdrivers/geckodriver -------------------------------------------------------------------------------- /pgmanage/app/tests/dellstore2-normal-1.0.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/tests/dellstore2-normal-1.0.sql -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | PreviewsShown=true 3 | Timestamp=2018,5,24,13,57,28 4 | Version=4 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/app_centos7/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/app_debian8/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_centos6/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_centos7/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_debian8/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/server_centos6/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/server_centos7/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/server_debian8/clone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | rm -rf ~/OmniDB 4 | git clone --depth 1 --branch dev https://github.com/OmniDB/OmniDB ~/OmniDB 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.pot 3 | *.pyc 4 | *__pycache__/ 5 | *db.sqlite3 6 | *.python-version 7 | *pgmanage.db 8 | *.vagrant 9 | *.idea 10 | *.DS_Store 11 | venv 12 | enterprise -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/tables.scss: -------------------------------------------------------------------------------- 1 | .table { 2 | & > :not(caption) > * > * { 3 | background-color: transparent; 4 | } 5 | } -------------------------------------------------------------------------------- /pgmanage/app/tests.old/postgresql/dellstore2-normal-1.0.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/tests.old/postgresql/dellstore2-normal-1.0.tar.gz -------------------------------------------------------------------------------- /pgmanage/app/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from . import ( 2 | test_postgresql12, 3 | test_views, 4 | test_monitoring_dashboard, 5 | test_bgjob, 6 | test_pgextras 7 | ) 8 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/right.png -------------------------------------------------------------------------------- /deploy/linux/build_images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd tarbuild 4 | docker build -t pgmanage/tarbuild . 5 | cd .. 6 | 7 | #cd pkgbuild 8 | #docker build -t omnidb/pkgbuild . 9 | #cd .. 10 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/pgmanage_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/pgmanage_16.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Bold.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Thin.ttf -------------------------------------------------------------------------------- /pgmanage/app/converters.py: -------------------------------------------------------------------------------- 1 | class SignedIntConverter: 2 | regex = '-?\d+' 3 | 4 | def to_python(self, value): 5 | return int(value) 6 | 7 | def to_url(self, value): 8 | return '%d' % value -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Black.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Italic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Light.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Medium.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-Regular.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mssql_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mssql_large.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mysql_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mysql_large.png -------------------------------------------------------------------------------- /pgmanage/app/tests.old/__init__.py: -------------------------------------------------------------------------------- 1 | from . import ( 2 | test_postgresql10, 3 | test_postgresql96, 4 | test_postgresql95, 5 | test_postgresql94, 6 | test_postgresql93, 7 | test_views 8 | ) 9 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mariadb_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mariadb_large.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mysql_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mysql_medium.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/oracle_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/oracle_large.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/oracle_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/oracle_medium.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/sqlite_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/sqlite_large.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/sqlite_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/sqlite_medium.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-BlackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-BlackItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-BoldItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-LightItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-MediumItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Roboto/Roboto-ThinItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Bold.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Thin.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mariadb_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/mariadb_medium.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/postgresql_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/postgresql_large.png -------------------------------------------------------------------------------- /deploy/app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PgManage", 3 | "main": "index.html", 4 | "window": { 5 | "frame": false, 6 | "transparent": false, 7 | "show": false, 8 | "icon": "pgmanage_icon.png" 9 | } 10 | } -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Italic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Light.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Medium.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/postgresql_medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/db_icons/postgresql_medium.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-500.woff -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-500.woff2 -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-700.woff -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-700.woff2 -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/supporters/command_prompt_inc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/images/supporters/command_prompt_inc.png -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-BoldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-BoldItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-LightItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-LightItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-ThinItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-ThinItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/tests/test-db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL 5 | CREATE DATABASE pgmanage_test; 6 | ALTER SYSTEM set wal_level to "logical" 7 | EOSQL -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-regular.woff -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/Poppins/poppins-v20-latin-regular.woff2 -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-MediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/RobotoMono/RobotoMono-MediumItalic.ttf -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/libs/alert.scss: -------------------------------------------------------------------------------- 1 | .alert { 2 | .close { 3 | color: inherit; 4 | outline: none; 5 | } 6 | 7 | table { 8 | color: $primaryDark; 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/UbuntuMono/ubuntumono-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/UbuntuMono/ubuntumono-regular-webfont.woff -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/fonts/UbuntuMono/ubuntumono-regular-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/commandprompt/pgmanage/HEAD/pgmanage/app/static/pgmanage_frontend/src/assets/fonts/UbuntuMono/ubuntumono-regular-webfont.woff2 -------------------------------------------------------------------------------- /deploy/linux/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker run -e VERSION="$1" -v $PWD:/deploy --rm pgmanage/tarbuild 4 | 5 | sudo chown $USER:$USER *.tar.gz 6 | sudo chown $USER:$USER *.AppImage 7 | # sudo chown $USER:$USER *.deb 8 | # sudo chown $USER:$USER *.rpm 9 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/test/global_setup.js: -------------------------------------------------------------------------------- 1 | // Define all global stubs here 2 | import { vi } from "vitest"; 3 | 4 | vi.stubGlobal("app_base_path", "test_folder"); 5 | vi.stubGlobal("v_csrf_cookie_name", "csrf_token_stub"); 6 | 7 | vi.mock("axios"); 8 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/xl-10/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $1 = "gtm" ] 4 | then 5 | su - postgres -c "/usr/local/pgsql/bin/gtm -D /usr/local/pgsql/data >logfile 2>&1 &" 6 | else 7 | su - postgres -c "/usr/local/pgsql/bin/postgres --$1 -D /usr/local/pgsql/data >logfile 2>&1 &" 8 | fi 9 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/xl-9.5/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $1 = "gtm" ] 4 | then 5 | su - postgres -c "/usr/local/pgsql/bin/gtm -D /usr/local/pgsql/data >logfile 2>&1 &" 6 | else 7 | su - postgres -c "/usr/local/pgsql/bin/postgres --$1 -D /usr/local/pgsql/data >logfile 2>&1 &" 8 | fi 9 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/snippets.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | 3 | const useSnippetsStore = defineStore("snippets", { 4 | state: () => ({ 5 | id: null, 6 | files: [], 7 | folders: [], 8 | }), 9 | }); 10 | 11 | export { useSnippetsStore }; 12 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/libs/pev2/pev2.scss: -------------------------------------------------------------------------------- 1 | @import "variables"; 2 | @import "base"; 3 | @import "plan"; 4 | @import "plan-diagram"; 5 | @import "plan-node"; 6 | @import "copy-button"; 7 | @import "tippy"; 8 | @import "pev2-tables"; 9 | @import "plan-grid"; 10 | @import "tweaks"; 11 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/data-editor-tab.scss: -------------------------------------------------------------------------------- 1 | .data-editor { 2 | &__footer { 3 | position: absolute; 4 | bottom: 0; 5 | width: 100%; 6 | margin-left: -0.5rem; 7 | 8 | @include themify() { 9 | background: themed($surfaceBgTertiary); 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /pgmanage/app/migrations/0028_merge_20250821_0702.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.23 on 2025-08-21 07:02 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0026_alter_monwidgets_script_chart'), 10 | ('app', '0027_erdlayout'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/list-group.scss: -------------------------------------------------------------------------------- 1 | .list-group { 2 | &-item { 3 | @include themify() { 4 | background-color: themed($cardListGroupItem); 5 | border-color: themed($borderColor) !important; 6 | } 7 | 8 | & + .list-group-item.active { 9 | margin-top: 0; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/libs/pev2/tweaks.scss: -------------------------------------------------------------------------------- 1 | // hides pev2 "report a bug" link and neighboring text 2 | div.d-flex.align-items-center:has(a[href^='https://github.com/dalibo/pev2/issues/'][class='btn btn-primary ms-auto']), 3 | div.result-div div.card.align-self-center.border-danger.w-50 div.card-body p.card-text.text-body-dark { 4 | display: none !important; 5 | } 6 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0017_merge_20240209_1300.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2024-02-09 13:00 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0015_query_and_console_history_database'), 10 | ('app', '0016_replace_is_default_with_editable'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # Current Developers and Contributors 2 | - Eugene Dubinin (dev) 3 | - Valerii Herman (dev) 4 | - Julia Yurkina (ux) 5 | - Debbie Cerda (docs) 6 | - Joshua (JD) Drake (docs) 7 | - Maria Camargo (docs) 8 | 9 | # Historic Developers 10 | - Denis Lussier 11 | - Rafael Thofehrn Castro 12 | - William Ivanski 13 | - Israel Barth Rubio 14 | - Luis Felipe Thofehrn Castro 15 | 16 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | coverage -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/libs/pev2/copy-button.scss: -------------------------------------------------------------------------------- 1 | * > .copy { 2 | display: none; 3 | } 4 | 5 | *:hover > .copy { 6 | display: block; 7 | } 8 | 9 | .copy { 10 | top: $spaceLg !important; 11 | right: $spaceLg !important; 12 | 13 | .btn-outline-secondary.bg-light:hover { 14 | color: $bgSurfaceLight !important; 15 | background-color: $secondaryGrey !important; 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /pgmanage/pgmanage/logging_filter.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import re 3 | 4 | 5 | class MaskedDataFilter(logging.Filter): 6 | def filter(self, record): 7 | # TODO: add more data masking rules 8 | rules = [('password":"\S*"', 'password":"[redacted]"')] 9 | 10 | if hasattr(record, "msg"): 11 | for old, new in rules: 12 | record.msg = re.sub(old, new, record.msg) 13 | 14 | return True 15 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/css/font-ubuntu-mono.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Ubuntu Mono'; 3 | font-style: normal; 4 | font-weight: 400; 5 | font-display: swap; 6 | src: local(''), 7 | url('../fonts/UbuntuMono/ubuntumono-regular-webfont.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 8 | url('../fonts/UbuntuMono/ubuntumono-regular-webfont.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 9 | } -------------------------------------------------------------------------------- /pgmanage/app/tests/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | 3 | services: 4 | 5 | test_db: 6 | image: postgres:15.5 7 | restart: always 8 | environment: 9 | POSTGRES_USER: postgres 10 | POSTGRES_PASSWORD: postgres 11 | POSTGRES_DB: dellstore 12 | ports: 13 | - 5433:5432 14 | volumes: 15 | - ./dellstore2-normal-1.0.sql:/docker-entrypoint-initdb.d/db.sql 16 | - ./test-db.sh:/docker-entrypoint-initdb.d/initdb.sh -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/mixins/humanize_duration_mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | humanizeDuration(value) { 4 | let fullMin = Math.floor(value / 60) 5 | let rem = value % 60 6 | if(fullMin && rem) { 7 | return `${fullMin}m${rem}s` 8 | } 9 | if(fullMin) { 10 | return `${fullMin}m` 11 | } 12 | 13 | return `${value}s` 14 | } 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /deploy/app/pgmanage.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=PgManage 3 | Exec=AppRun 4 | Terminal=false 5 | Type=Application 6 | Icon=pgmanage_icon 7 | StartupWMClass=pgmanage 8 | X-AppImage-Version=dev 9 | Comment=PgManage - a lightweight database management tool 10 | MimeType=application/vnd.sqlite3;x-scheme-handler/mariadb;x-scheme-handler/mysql;x-scheme-handler/postgresql;x-scheme-handler/postgres;x-scheme-handler/psql;x-scheme-handler/sqlite; 11 | Categories=Development; 12 | -------------------------------------------------------------------------------- /pgmanage/pgmanage/custom_settings.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | # PgManage settings 4 | PGMANAGE_VERSION = 'Dev' 5 | PGMANAGE_SHORT_VERSION = 'dev' 6 | DEV_MODE = True 7 | DESKTOP_MODE = False 8 | APP_TOKEN = None 9 | PATH = '' 10 | HOME_DIR = Path(__file__).resolve().parent.parent 11 | BASE_DIR = Path(__file__).resolve().parent.parent 12 | MAX_UPLOAD_SIZE = 1024**2 * 500 13 | 14 | # Django settings 15 | SESSION_COOKIE_SECURE = False 16 | CSRF_COOKIE_SECURE = False -------------------------------------------------------------------------------- /deploy/linux/pkgbuild/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:stretch-slim 2 | 3 | USER root 4 | ENV HOME /root 5 | WORKDIR /root 6 | SHELL ["/bin/bash", "-c"] 7 | 8 | ENV DEBIAN_FRONTEND=noninteractive 9 | 10 | RUN apt-get -y update \ 11 | && apt-get -y install rubygems ruby-dev build-essential rpm \ 12 | && gem install fpm 13 | 14 | ARG VERSION="3.0.6" 15 | 16 | ENV VERSION=$VERSION 17 | 18 | COPY icons.tar.gz $HOME 19 | COPY entrypoint.sh $HOME 20 | 21 | ENTRYPOINT ["/root/entrypoint.sh"] 22 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0023_remove_userdetails_welcome_closed.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.16 on 2024-10-16 08:33 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0022_alter_userdetails_csv_delimiter'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='userdetails', 15 | name='welcome_closed', 16 | ), 17 | ] 18 | -------------------------------------------------------------------------------- /pgmanage/app/views/__init__.py: -------------------------------------------------------------------------------- 1 | from . import ( 2 | backup, 3 | bgjob, 4 | commands_history, 5 | configuration, 6 | connections, 7 | file_manager, 8 | login, 9 | monitoring_dashboard, 10 | plugins, 11 | polling, 12 | restore, 13 | tree_mariadb, 14 | tree_mysql, 15 | tree_oracle, 16 | pgextras, 17 | tree_postgresql, 18 | tree_snippets, 19 | tree_sqlite, 20 | workspace, 21 | logging, 22 | tree_mssql 23 | ) 24 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0006_userdetails_binary_path.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.28 on 2023-03-28 12:50 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0005_job'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='binary_path', 16 | field=models.CharField(max_length=256, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0018_userdetails_restore_tabs.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2024-02-27 14:30 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0017_merge_20240209_1300'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='restore_tabs', 16 | field=models.BooleanField(default=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0020_connection_color_label.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.11 on 2024-06-18 16:07 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0019_userdetails_scroll_tree'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='connection', 15 | name='color_label', 16 | field=models.IntegerField(default=0), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0003_userdetails_masterpass_check.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.28 on 2022-11-01 08:00 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0002_3_0_1'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='masterpass_check', 16 | field=models.CharField(default='', max_length=256), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0012_userdetails_autocomplete.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-10-17 12:00 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0011_userdetails_pigz_path'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='autocomplete', 16 | field=models.BooleanField(default=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0019_userdetails_scroll_tree.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2024-02-28 12:40 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0018_userdetails_restore_tabs'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='scroll_tree', 16 | field=models.BooleanField(default=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0013_connection_last_access_date.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-11-16 16:17 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0012_userdetails_autocomplete'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='connection', 15 | name='last_access_date', 16 | field=models.DateTimeField(null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/utility_jobs.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | 3 | const useUtilityJobsStore = defineStore("utilityJob", { 4 | state: () => ({ 5 | selectedJob: {}, 6 | }), 7 | actions: { 8 | clearSelected() { 9 | this.selectedJob = {}; 10 | }, 11 | setJob(job) { 12 | this.selectedJob = job; 13 | }, 14 | setDuration(duration) { 15 | this.selectedJob.duration = duration; 16 | }, 17 | }, 18 | }); 19 | 20 | export { useUtilityJobsStore }; 21 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0010_connection_last_used_database.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-06-06 11:49 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0009_tab_database'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='connection', 15 | name='last_used_database', 16 | field=models.CharField(max_length=200, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0011_userdetails_pigz_path.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-06-09 13:20 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0010_connection_last_used_database'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='pigz_path', 16 | field=models.CharField(max_length=256, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0008_userdetails_date_format.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-05-23 11:32 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0007_connection_connection_params'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='userdetails', 15 | name='date_format', 16 | field=models.CharField(max_length=200, null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0030_populate_mssql-technology.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.23 on 2025-09-05 12:47 2 | 3 | from django.db import migrations 4 | 5 | def populate_technologies(apps, schema_editor): 6 | Technology = apps.get_model('app', 'Technology') 7 | Technology(name='mssql').save() 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | dependencies = [ 13 | ('app', '0029_auto_20250904_1353'), 14 | ] 15 | 16 | operations = [ 17 | migrations.RunPython(populate_technologies) 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0026_connection_pinned_databases.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.19 on 2025-05-19 14:40 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0025_monwidgetsconnections_position_and_more'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='connection', 15 | name='pinned_databases', 16 | field=models.JSONField(default=list), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/logging/utils.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import { logger } from "./logger_setup"; 3 | import { showToast } from "../notification_control"; 4 | 5 | export function handleError(error) { 6 | if (axios.isAxiosError(error)) { 7 | showToast("error", error.response?.data?.data || error.message); 8 | } else { 9 | // Handle general JavaScript errors 10 | logger.error(`[JS Error] ${error.stack}`); 11 | showToast("error", error.message || "An unexpected error occurred."); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0002_3_0_1.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.1 on 2020-11-06 13:43 2 | 3 | from django.db import migrations 4 | 5 | 6 | def populate_technologies(apps, schema_editor): 7 | Technology = apps.get_model('app', 'Technology') 8 | Technology(name='sqlite').save() 9 | 10 | 11 | class Migration(migrations.Migration): 12 | 13 | dependencies = [ 14 | ('app', '0001_3_0_0'), 15 | ] 16 | 17 | operations = [ 18 | migrations.RunPython( 19 | code=populate_technologies, 20 | ) 21 | ] 22 | -------------------------------------------------------------------------------- /pgmanage/app/views/logging.py: -------------------------------------------------------------------------------- 1 | import logging 2 | 3 | from app.utils.decorators import user_authenticated 4 | from django.http import HttpResponse 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | 9 | @user_authenticated 10 | def log_message(request): 11 | for log in request.data.get("logs", []): 12 | extra = {"request_id": log.pop("request_id")} 13 | level = log.get("level", "error") 14 | message = log.get("msg") 15 | getattr(logger, level)(message, extra=extra) 16 | 17 | return HttpResponse(status=200) 18 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0026_alter_monwidgets_script_chart.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.23 on 2025-08-12 08:35 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0025_monwidgetsconnections_position_and_more'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='monwidgets', 15 | name='script_chart', 16 | field=models.TextField(blank=True, default=''), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/oracle/listener.ora: -------------------------------------------------------------------------------- 1 | # listener.ora Network Configuration File: 2 | 3 | SID_LIST_LISTENER = 4 | (SID_LIST = 5 | (SID_DESC = 6 | (SID_NAME = PLSExtProc) 7 | (ORACLE_HOME = /opt/oracle/product/18c/dbhomeXE) 8 | (PROGRAM = extproc) 9 | ) 10 | ) 11 | 12 | LISTENER = 13 | (DESCRIPTION_LIST = 14 | (DESCRIPTION = 15 | (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC_FOR_XE)) 16 | (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521)) 17 | ) 18 | ) 19 | 20 | DEFAULT_SERVICE_LISTENER = (XE) 21 | -------------------------------------------------------------------------------- /pgmanage/pgmanage/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for OmniDB project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | from . import startup 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | 15 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pgmanage.settings") 16 | 17 | application = get_wsgi_application() 18 | 19 | # Startup Procedure 20 | #startup.startup_procedure() 21 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/pagination.scss: -------------------------------------------------------------------------------- 1 | .pagination { 2 | &__btn { 3 | background: transparent; 4 | border: 0; 5 | color: $primaryBlue; 6 | font-weight: 600; 7 | border: 2px solid transparent; 8 | transition: .1s all ease-in; 9 | border-radius: $borderRadius; 10 | 11 | &:focus { 12 | outline: none; 13 | } 14 | 15 | &:hover { 16 | border-color: $primaryBlue; 17 | } 18 | } 19 | 20 | &__pages { 21 | font-weight: 600; 22 | } 23 | } -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/oracle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0024_drop_old_dashboard_settings.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-05-26 14:38 2 | 3 | from django.db import migrations, models 4 | 5 | def delete_old_settings(apps, schema_editor): 6 | MonWidgetsConnections = apps.get_model("app", "MonWidgetsConnections") 7 | MonWidgetsConnections.objects.all().delete() 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | dependencies = [ 13 | ('app', '0023_remove_userdetails_welcome_closed'), 14 | ] 15 | 16 | operations = [ 17 | migrations.RunPython(delete_old_settings, migrations.RunPython.noop) 18 | ] 19 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cryptography==45.0.5 2 | Django==4.2.23 3 | CherryPy==18.10.0 4 | sqlparse==0.5.3 5 | psycopg2==2.9.11 6 | openpyxl==3.1.3 7 | RestrictedPython==8.0 8 | oracledb==3.2 9 | pymysql==1.1.1 10 | pymssql==2.3.7 11 | pgspecial==1.13.0 12 | sshtunnel==0.4.0 13 | psutil==6.1.1 14 | django-vite==3.0.4 15 | prettytable==3.16.0 16 | # portend and tempora are indirect dependencies of cherrypy 17 | # pinned because newer versions caused pyinstaller issues with dateutil 18 | portend==3.1 19 | tempora==5.6 20 | # paramiko is indirect dependency of sshtunnel 21 | # pinned because newer versions caused pyinstaller issues 22 | paramiko==3.5.1 23 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0014_auto_20231222_1353.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-12-22 13:53 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0013_connection_last_access_date'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='userdetails', 15 | name='autocomplete', 16 | ), 17 | migrations.AddField( 18 | model_name='connection', 19 | name='autocomplete', 20 | field=models.BooleanField(default=True), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/ace_extras/mode-mysql-extended.js: -------------------------------------------------------------------------------- 1 | ace.define( 2 | "ace/mode/mysql_extended", 3 | ["require", "exports", "ace/lib/oop", "ace/mode/text", "ace/range"], 4 | function (acequire, exports) { 5 | const oop = acequire("ace/lib/oop"); 6 | const MysqlMode = acequire("ace/mode/mysql").Mode; 7 | const SqlFoldMode = acequire("./folding/sql").FoldMode; 8 | 9 | const ExtendedMysqlMode = function () { 10 | MysqlMode.call(this); 11 | this.foldingRules = new SqlFoldMode(); 12 | }; 13 | oop.inherits(ExtendedMysqlMode, MysqlMode); 14 | 15 | exports.Mode = ExtendedMysqlMode; 16 | } 17 | ); 18 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0016_replace_is_default_with_editable.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2024-01-29 08:58 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0015_rename_monunits_and_monunitsconnections'), 10 | ] 11 | 12 | operations = [ 13 | migrations.RemoveField( 14 | model_name='monwidgets', 15 | name='is_default', 16 | ), 17 | migrations.AddField( 18 | model_name='monwidgets', 19 | name='editable', 20 | field=models.BooleanField(default=True), 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0015_rename_monunits_and_monunitsconnections.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2024-01-29 08:58 2 | 3 | from django.conf import settings 4 | from django.db import migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 11 | ('app', '0014_auto_20231222_1353'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RenameModel( 16 | old_name='MonUnits', 17 | new_name='MonWidgets', 18 | ), 19 | migrations.RenameModel( 20 | old_name='MonUnitsConnections', 21 | new_name='MonWidgetsConnections', 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0015_query_and_console_history_database.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2024-02-08 13:33 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0014_auto_20231222_1353'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='consolehistory', 15 | name='database', 16 | field=models.CharField(max_length=200, null=True), 17 | ), 18 | migrations.AddField( 19 | model_name='queryhistory', 20 | name='database', 21 | field=models.CharField(max_length=200, null=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0025_monwidgetsconnections_position_and_more.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.16 on 2025-03-12 13:04 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('app', '0024_drop_old_dashboard_settings'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='monwidgetsconnections', 15 | name='position', 16 | field=models.IntegerField(default=0), 17 | ), 18 | migrations.AddField( 19 | model_name='monwidgetsconnections', 20 | name='visible', 21 | field=models.BooleanField(default=True), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/celldata_modal.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | 3 | const useCellDataModalStore = defineStore("cellDataModal", { 4 | state: () => ({ 5 | visible: false, 6 | cellContent: null, 7 | cellType: null, 8 | showControls: false, 9 | }), 10 | actions: { 11 | showModal(cellContent, cellType, showControls) { 12 | this.cellContent = cellContent; 13 | this.cellType = cellType; 14 | this.visible = true; 15 | this.showControls = showControls ?? false; 16 | }, 17 | hideModal() { 18 | this.visible = false; 19 | this.cellContent = null; 20 | this.cellType = null; 21 | }, 22 | }, 23 | }); 24 | 25 | export { useCellDataModalStore }; 26 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_debian8/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:jessie-slim 2 | MAINTAINER William Ivanski 3 | 4 | USER root 5 | ENV HOME /root 6 | WORKDIR /root 7 | SHELL ["/bin/bash", "-c"] 8 | 9 | RUN apt-get update -y \ 10 | && apt install -y wget \ 11 | && echo "deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main" > /etc/apt/sources.list.d/pgdg.list \ 12 | && wget --quiet -O - https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add - \ 13 | && apt-get update -y \ 14 | && apt-get -y install build-essential git postgresql-server-dev-9.4 postgresql-server-dev-9.5 postgresql-server-dev-9.6 postgresql-server-dev-10 postgresql-server-dev-11 postgresql-server-dev-12 libpq-dev 15 | 16 | COPY clone.sh $HOME/ 17 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/commands_history.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | 3 | const useCommandsHistoryStore = defineStore("commandsHistoryModal", { 4 | state: () => ({ 5 | visible: false, 6 | tabId: null, 7 | databaseIndex: null, 8 | tabType: null, 9 | }), 10 | actions: { 11 | showModal(tabId, databaseIndex, tabType) { 12 | this.tabId = tabId; 13 | this.databaseIndex = databaseIndex; 14 | this.tabType = tabType; 15 | this.visible = true; 16 | }, 17 | reset() { 18 | this.tabId = null; 19 | this.databaseIndex = null; 20 | this.tabType = null; 21 | this.visible = false; 22 | }, 23 | }, 24 | }); 25 | 26 | export { useCommandsHistoryStore }; 27 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_freebsd/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | $script = < 39 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/card.scss: -------------------------------------------------------------------------------- 1 | .card { 2 | border-radius: $borderRadius; 3 | overflow: hidden; 4 | background-color: initial; 5 | 6 | @include themify() { 7 | border: themed($border); 8 | background-color: themed($surfaceBgSecondary); 9 | } 10 | 11 | &-header { 12 | background-color: rgba($primaryBlue, .2); 13 | 14 | &:first-child { 15 | border-radius: 0; 16 | } 17 | 18 | @include themify() { 19 | border-bottom: themed($border) !important; 20 | } 21 | } 22 | 23 | &-body { 24 | padding: 24px; 25 | 26 | @include themify() { 27 | background-color: themed($surfaceBgSecondary); 28 | } 29 | 30 | .btn-close { 31 | position: absolute; 32 | right: 20px; 33 | top: 20px; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/file_manager.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | 3 | const useFileManagerStore = defineStore("fileManager", { 4 | state: () => ({ 5 | onChange: () => {}, 6 | dialogType: null, 7 | file: null, 8 | visible: false, 9 | desktopMode: null, 10 | }), 11 | actions: { 12 | showModal(desktopMode, onChange, dialogType) { 13 | this.visible = true; 14 | this.desktopMode = desktopMode; 15 | this.onChange = onChange; 16 | this.dialogType = dialogType; 17 | }, 18 | changeFile(file) { 19 | this.file = file; 20 | }, 21 | hideModal() { 22 | this.visible = false; 23 | this.reset(); 24 | }, 25 | reset() { 26 | this.onChange = () => {}; 27 | this.dialogType = null; 28 | this.file = null; 29 | this.desktopMode = null; 30 | }, 31 | }, 32 | }); 33 | 34 | export { useFileManagerStore }; 35 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/components/BlockSizeSelector.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 41 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0027_erdlayout.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.19 on 2025-07-10 10:43 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('app', '0026_connection_pinned_databases'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='ERDLayout', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('name', models.CharField(max_length=200)), 19 | ('layout', models.JSONField()), 20 | ('connection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.connection')), 21 | ], 22 | options={ 23 | 'unique_together': {('connection', 'name')}, 24 | }, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /pgmanage/app/middleware.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | 4 | class DataUnpackMiddleware: 5 | """ 6 | Middleware to unpack JSON data in Django views. 7 | 8 | This middleware checks the content type of incoming POST requests. If the content type is 'application/json', 9 | it unpacks the JSON data from the request body and assigns it to `request.data`. Otherwise, it unpacks the 10 | JSON data from the 'data' POST parameter and assigns it to `request.data`. 11 | """ 12 | 13 | def __init__(self, get_response): 14 | self.get_response = get_response 15 | 16 | def __call__(self, request): 17 | if request.method == "POST": 18 | if request.content_type == "application/json": 19 | request.data = json.loads(request.body) 20 | else: 21 | request.data = json.loads(request.POST.get("data", "{}")) 22 | 23 | response = self.get_response(request) 24 | 25 | return response 26 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/postgresql-10-2nodes/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | #config.vbguest.auto_update = false 3 | config.vm.define "node1" do |node1| 4 | node1.vm.box = "debian/stretch64" 5 | node1.vm.hostname = 'node1' 6 | node1.vm.network :private_network, ip: '10.33.2.114' 7 | node1.vm.provider :virtualbox do |v| 8 | v.customize ["modifyvm", :id, "--name", "omnidb_pg10_node1"] 9 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 10 | end 11 | end 12 | config.vm.define "node2" do |node2| 13 | node2.vm.box = "debian/stretch64" 14 | node2.vm.hostname = 'node2' 15 | node2.vm.network :private_network, ip: '10.33.2.115' 16 | node2.vm.provider :virtualbox do |v| 17 | v.customize ["modifyvm", :id, "--name", "omnidb_pg10_node2"] 18 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 19 | end 20 | end 21 | config.vm.provision :shell, :path => "bootstrap.sh" 22 | end 23 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/app_centos7/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | MAINTAINER William Ivanski 3 | 4 | USER root 5 | ENV HOME /root 6 | WORKDIR /root 7 | SHELL ["/bin/bash", "-c"] 8 | 9 | ENV PYTHON_VERSION=3.6.5 10 | 11 | RUN yum install -y gcc gcc-c++ make git patch openssl-devel zlib-devel readline-devel sqlite-devel bzip2-devel rpm-build curl epel-release \ 12 | && yum groupinstall -y "GNOME Desktop" \ 13 | && git clone --depth 1 https://github.com/pyenv/pyenv.git ~/.pyenv \ 14 | && echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc \ 15 | && echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc \ 16 | && echo 'eval "$(pyenv init -)"' >> ~/.bashrc \ 17 | && source ~/.bashrc \ 18 | && env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install $PYTHON_VERSION \ 19 | && pyenv global $PYTHON_VERSION \ 20 | && curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash - \ 21 | && yum -y install nodejs 22 | 23 | COPY clone.sh $HOME/ 24 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/postgresql-bdr-9.4-2nodes/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | #config.vbguest.auto_update = false 3 | config.vm.define "node1" do |node1| 4 | node1.vm.box = "debian/stretch64" 5 | node1.vm.hostname = 'node1' 6 | node1.vm.network :private_network, ip: '10.33.4.114' 7 | node1.vm.provider :virtualbox do |v| 8 | v.customize ["modifyvm", :id, "--name", "omnidb_bdr_node1"] 9 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 10 | end 11 | end 12 | config.vm.define "node2" do |node2| 13 | node2.vm.box = "debian/stretch64" 14 | node2.vm.hostname = 'node2' 15 | node2.vm.network :private_network, ip: '10.33.4.115' 16 | node2.vm.provider :virtualbox do |v| 17 | v.customize ["modifyvm", :id, "--name", "omnidb_bdr_node2"] 18 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 19 | end 20 | end 21 | config.vm.provision :shell, :path => "bootstrap.sh" 22 | end 23 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/pglogical-2-postgresql-10-2nodes/Vagrantfile: -------------------------------------------------------------------------------- 1 | Vagrant.configure("2") do |config| 2 | #config.vbguest.auto_update = false 3 | config.vm.define "node1" do |node1| 4 | node1.vm.box = "centos/7" 5 | node1.vm.hostname = 'node1' 6 | node1.vm.network :private_network, ip: '10.33.3.114' 7 | node1.vm.provider :virtualbox do |v| 8 | v.customize ["modifyvm", :id, "--name", "omnidb_pglogical_node1"] 9 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 10 | end 11 | end 12 | config.vm.define "node2" do |node2| 13 | node2.vm.box = "centos/7" 14 | node2.vm.hostname = 'node2' 15 | node2.vm.network :private_network, ip: '10.33.3.115' 16 | node2.vm.provider :virtualbox do |v| 17 | v.customize ["modifyvm", :id, "--name", "omnidb_pglogical_node2"] 18 | v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] 19 | end 20 | end 21 | config.vm.provision :shell, :path => "bootstrap.sh" 22 | end 23 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/floating-toolbar.scss: -------------------------------------------------------------------------------- 1 | .floating-toolbar { 2 | position: absolute; 3 | z-index: 2; 4 | border-radius: $borderRadius; 5 | background-color: #16243C; 6 | overflow: hidden; 7 | 8 | &__content { 9 | display: flex; 10 | align-items: center; 11 | background-color: rgba($primaryBlue, 0.15); 12 | } 13 | 14 | &--filled { 15 | @include themify() { 16 | background-color: themed($surfaceBgSecondary); 17 | } 18 | } 19 | 20 | &--right-top { 21 | right: 0.5rem; 22 | top: 0.5rem; 23 | } 24 | 25 | .btn-icon-secondary { 26 | @include themify() { 27 | color: themed($buttonIconSecondaryColor) !important; 28 | } 29 | } 30 | 31 | .divider { 32 | display: block; 33 | width: 1px; 34 | height: 1.5rem; 35 | background-color: $secondaryGrey; 36 | opacity: 0.5; 37 | } 38 | } -------------------------------------------------------------------------------- /pgmanage/deploy.old/app_debian8/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:jessie-slim 2 | MAINTAINER William Ivanski 3 | 4 | USER root 5 | ENV HOME /root 6 | WORKDIR /root 7 | SHELL ["/bin/bash", "-c"] 8 | 9 | ENV PYTHON_VERSION=3.6.5 10 | 11 | RUN apt-get update -y \ 12 | && apt-get install -y git make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev xz-utils libgconf-2-4 gnome-core unzip \ 13 | && git clone --depth 1 https://github.com/pyenv/pyenv.git ~/.pyenv \ 14 | && echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc \ 15 | && echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc \ 16 | && echo 'eval "$(pyenv init -)"' >> ~/.bashrc \ 17 | && source ~/.bashrc \ 18 | && env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install $PYTHON_VERSION \ 19 | && pyenv global $PYTHON_VERSION \ 20 | && curl -sL https://deb.nodesource.com/setup_8.x | bash - \ 21 | && apt-get install -y nodejs 22 | 23 | COPY clone.sh $HOME/ 24 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0009_tab_database.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-05-26 14:38 2 | 3 | from django.db import migrations, models 4 | 5 | def update_tab_database_values(apps, schema_editor): 6 | # We can't import the Person model directly as it may be a newer 7 | # version than this migration expects. We use the historical version. 8 | Tab = apps.get_model("app", "Tab") 9 | 10 | for tab in Tab.objects.all(): 11 | if tab.database is None: 12 | tab.database = tab.connection.database 13 | tab.save() 14 | 15 | 16 | class Migration(migrations.Migration): 17 | 18 | dependencies = [ 19 | ('app', '0008_userdetails_date_format'), 20 | ] 21 | 22 | operations = [ 23 | migrations.AddField( 24 | model_name='tab', 25 | name='database', 26 | field=models.CharField(max_length=200, null=True), 27 | ), 28 | migrations.RunPython(update_tab_database_values, migrations.RunPython.noop) 29 | ] 30 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/README.md: -------------------------------------------------------------------------------- 1 | # Tests with PostgreSQL 2 | 3 | There are vagrant scripts to automatically: 4 | 5 | - Create a Debian 9 VM 6 | - Install the specific version of PostgreSQL into the VM 7 | - Restore tests/database/dellstore2-normal-1.0.sql into the specific version of PostgreSQL 8 | 9 | Make sure you have the following installed in your computer: 10 | 11 | - VirtualBox 12 | - vagrant 13 | - vagrant plugin vbguest 14 | 15 | So, choose a specific version of PostgreSQL to run the tests, and then: 16 | 17 | - cd into the folder tests/vagrant/postgresql-xx 18 | - vagrant up 19 | - ./restore.sh 20 | - cd ../../../../ 21 | - python manage.py test OmniDB_app.tests.test_postgresqlxx 22 | 23 | When you are done with the tests, you can run: 24 | 25 | - cd OmniDB_app/tests/vagrant/postgresql-xx/ 26 | - vagrant halt 27 | 28 | 29 | # Tests with Selenium (automating use of browsers) 30 | 31 | - Put file OmniDB_app/tests/webdrivers/geckodriver in your PATH 32 | - Run python manage.py test OmniDB_app.tests.test_selenium 33 | -------------------------------------------------------------------------------- /pgmanage/process_executor-lin.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['app/bgjob/process_executor.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='process_executor', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | ) 45 | -------------------------------------------------------------------------------- /pgmanage/process_executor-mac.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['app/bgjob/process_executor.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='process_executor', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=True, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=True, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | ) 45 | -------------------------------------------------------------------------------- /pgmanage/pgmanage/urls.py: -------------------------------------------------------------------------------- 1 | """PgManage URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/4.2/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.contrib import admin 17 | from django.urls import path, include 18 | from pgmanage.settings import ENTERPRISE_EDITION 19 | 20 | urlpatterns = [ 21 | path('', include('app.urls')) 22 | ] 23 | 24 | if ENTERPRISE_EDITION: 25 | from enterprise.urls_enterprise import urlpatterns as enterprise_urls 26 | urlpatterns = enterprise_urls + urlpatterns -------------------------------------------------------------------------------- /pgmanage/process_executor-win.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis( 8 | ['app/bgjob/process_executor.py'], 9 | pathex=[], 10 | binaries=[], 11 | datas=[], 12 | hiddenimports=[], 13 | hookspath=[], 14 | hooksconfig={}, 15 | runtime_hooks=[], 16 | excludes=[], 17 | win_no_prefer_redirects=False, 18 | win_private_assemblies=False, 19 | cipher=block_cipher, 20 | noarchive=False, 21 | ) 22 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 23 | 24 | exe = EXE( 25 | pyz, 26 | a.scripts, 27 | a.binaries, 28 | a.zipfiles, 29 | a.datas, 30 | [], 31 | name='process_executor', 32 | debug=False, 33 | bootloader_ignore_signals=False, 34 | strip=False, 35 | upx=False, 36 | upx_exclude=[], 37 | runtime_tmpdir=None, 38 | console=False, 39 | disable_windowed_traceback=False, 40 | argv_emulation=False, 41 | target_arch=None, 42 | codesign_identity=None, 43 | entitlements_file=None, 44 | ) 45 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/tree_context_functions/tree_mssql.js: -------------------------------------------------------------------------------- 1 | import { emitter } from "../emitter"; 2 | import { tabsStore } from "../stores/stores_initializer"; 3 | import axios from "axios"; 4 | import { handleError } from "../logging/utils"; 5 | 6 | function TemplateSelectMssql(schema, table, kind) { 7 | axios 8 | .post("/template_select_mssql/", { 9 | database_index: 10 | tabsStore.selectedPrimaryTab.metaData.selectedDatabaseIndex, 11 | workspace_id: tabsStore.selectedPrimaryTab.id, 12 | table: table, 13 | schema: schema, 14 | kind: kind, 15 | }) 16 | .then((resp) => { 17 | let tab_name = `${tabsStore.selectedPrimaryTab.metaData.selectedDatabase}@${schema}.${table}`; 18 | tabsStore.createQueryTab(tab_name, null, null, resp.data.template); 19 | setTimeout(() => { 20 | emitter.emit( 21 | `${tabsStore.selectedPrimaryTab.metaData.selectedTab.id}_run_query` 22 | ); 23 | }, 200); 24 | }) 25 | .catch((error) => { 26 | handleError(error); 27 | }); 28 | } 29 | 30 | export { TemplateSelectMssql }; 31 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/mysql/README.md: -------------------------------------------------------------------------------- 1 | #### Requirements 2 | 3 | Download MySQL 8 base image: 4 | 5 | ``` 6 | docker pull mysql:8 7 | ``` 8 | 9 | For more information about MySQL official docker images, please check here: 10 | 11 | https://hub.docker.com/_/mysql 12 | 13 | 14 | #### Starting the container 15 | 16 | To test OmniDB, start a container from the test image, and a shell into the container: 17 | 18 | ``` 19 | docker run -it --rm -p 3306:3306 -e MYSQL_ROOT_PASSWORD=omnidb -e MYSQL_DATABASE=omnidb_tests -e MYSQL_USER=omnidb -e MYSQL_PASSWORD=omnidb mysql:8 --bind-address=0.0.0.0 20 | ``` 21 | 22 | 23 | #### Running the tests 24 | 25 | To run the tests, outside of the container, execute: 26 | 27 | ``` 28 | cd OmniDB/OmniDB/ 29 | python manage.py test OmniDB_app.tests.test_mysql 30 | ``` 31 | 32 | 33 | #### Destroying the container 34 | 35 | Because you used `--rm` above, the container will be destroyed once it is stopped. 36 | 37 | First you need to list the containers: 38 | 39 | ``` 40 | docker container ls 41 | ``` 42 | 43 | Then you can remove with: 44 | 45 | ``` 46 | docker container rm 47 | ``` 48 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/mariadb/README.md: -------------------------------------------------------------------------------- 1 | #### Requirements 2 | 3 | Download MariaDB 10.4 base image: 4 | 5 | ``` 6 | docker pull mariadb:10.4 7 | ``` 8 | 9 | For more information about MariaDB official docker images, please check here: 10 | 11 | https://hub.docker.com/_/mariadb 12 | 13 | 14 | #### Starting the container 15 | 16 | To test OmniDB, start a container from the test image, and a shell into the container: 17 | 18 | ``` 19 | docker run -it --rm -p 3306:3306 -e MYSQL_ROOT_PASSWORD=omnidb -e MYSQL_DATABASE=omnidb_tests -e MYSQL_USER=omnidb -e MYSQL_PASSWORD=omnidb mariadb:10.4 --bind-address=0.0.0.0 20 | ``` 21 | 22 | 23 | #### Running the tests 24 | 25 | To run the tests, outside of the container, execute: 26 | 27 | ``` 28 | cd OmniDB/OmniDB/ 29 | python manage.py test OmniDB_app.tests.test_mariadb 30 | ``` 31 | 32 | 33 | #### Destroying the container 34 | 35 | Because you used `--rm` above, the container will be destroyed once it is stopped. 36 | 37 | First you need to list the containers: 38 | 39 | ``` 40 | docker container ls 41 | ``` 42 | 43 | Then you can remove with: 44 | 45 | ``` 46 | docker container rm 47 | ``` 48 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_centos6/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:6 2 | MAINTAINER William Ivanski 3 | 4 | USER root 5 | ENV HOME /root 6 | WORKDIR /root 7 | SHELL ["/bin/bash", "-c"] 8 | 9 | RUN yum -y update \ 10 | && yum -y install epel-release \ 11 | && yum -y install gcc gcc-c++ make git patch rpm-build \ 12 | && rpm -ivh https://download.postgresql.org/pub/repos/yum/reporpms/EL-6-x86_64/pgdg-redhat-repo-latest.noarch.rpm \ 13 | && yum -y install postgresql94 postgresql94-server postgresql94-libs postgresql94-contrib postgresql94-devel \ 14 | && yum -y install postgresql95 postgresql95-server postgresql95-libs postgresql95-contrib postgresql95-devel \ 15 | && yum -y install postgresql96 postgresql96-server postgresql96-libs postgresql96-contrib postgresql96-devel \ 16 | && yum -y install postgresql10 postgresql10-server postgresql10-libs postgresql10-contrib postgresql10-devel \ 17 | && yum -y install postgresql11 postgresql11-server postgresql11-libs postgresql11-contrib postgresql11-devel \ 18 | && yum -y install postgresql12 postgresql12-server postgresql12-libs postgresql12-contrib postgresql12-devel 19 | 20 | COPY clone.sh $HOME/ 21 | -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_centos7/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos:7 2 | MAINTAINER William Ivanski 3 | 4 | USER root 5 | ENV HOME /root 6 | WORKDIR /root 7 | SHELL ["/bin/bash", "-c"] 8 | 9 | RUN yum -y update \ 10 | && yum -y install epel-release \ 11 | && yum -y install gcc gcc-c++ make git patch rpm-build \ 12 | && rpm -ivh https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm \ 13 | && yum -y install postgresql94 postgresql94-server postgresql94-libs postgresql94-contrib postgresql94-devel \ 14 | && yum -y install postgresql95 postgresql95-server postgresql95-libs postgresql95-contrib postgresql95-devel \ 15 | && yum -y install postgresql96 postgresql96-server postgresql96-libs postgresql96-contrib postgresql96-devel \ 16 | && yum -y install postgresql10 postgresql10-server postgresql10-libs postgresql10-contrib postgresql10-devel \ 17 | && yum -y install postgresql11 postgresql11-server postgresql11-libs postgresql11-contrib postgresql11-devel \ 18 | && yum -y install postgresql12 postgresql12-server postgresql12-libs postgresql12-contrib postgresql12-devel 19 | 20 | COPY clone.sh $HOME/ 21 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0004_confighistory.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.28 on 2023-01-04 14:52 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('app', '0003_userdetails_masterpass_check'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='ConfigHistory', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('start_time', models.DateTimeField()), 21 | ('config_snapshot', models.TextField()), 22 | ('commit_comment', models.TextField(blank=True)), 23 | ('connection', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.Connection')), 24 | ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 25 | ], 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/images/mariadb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/test/stores/celldata_modal.test.js: -------------------------------------------------------------------------------- 1 | import { setActivePinia, createPinia } from "pinia"; 2 | import { describe, it, expect, beforeEach } from "vitest"; 3 | import { useCellDataModalStore } from "@src/stores/celldata_modal"; 4 | 5 | describe("cellDataModal store", () => { 6 | beforeEach(() => { 7 | setActivePinia(createPinia()); 8 | }); 9 | 10 | it("initializes with default state", () => { 11 | const store = useCellDataModalStore(); 12 | expect(store.visible).toBe(false); 13 | expect(store.cellContent).toBe(null); 14 | }); 15 | 16 | it("shows modal and sets the correct state", () => { 17 | const store = useCellDataModalStore(); 18 | const cellContent = "Sample cell content"; 19 | 20 | store.showModal(cellContent); 21 | 22 | expect(store.visible).toBe(true); 23 | expect(store.cellContent).toBe(cellContent); 24 | }); 25 | 26 | it("hides modal and resets the state", () => { 27 | const store = useCellDataModalStore(); 28 | 29 | store.showModal("Sample cell content"); 30 | store.hideModal(); 31 | 32 | expect(store.visible).toBe(false); 33 | expect(store.cellContent).toBe(null); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0021_group_unique_user_group_name.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 4.2.16 on 2024-09-23 07:40 2 | 3 | import uuid 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | def update_group_names(apps, schema_editor): 9 | Group = apps.get_model("app", "Group") 10 | duplicate_group_names = ( 11 | Group.objects.values("name") 12 | .annotate(models.Count("id")) 13 | .filter(id__count__gt=1) 14 | ) 15 | duplicate_groups = Group.objects.filter( 16 | name__in=[item["name"] for item in duplicate_group_names] 17 | ) 18 | 19 | for group in duplicate_groups: 20 | unique_group_name = f"{group.name}-{uuid.uuid4()}" 21 | group.name = unique_group_name 22 | group.save() 23 | 24 | 25 | class Migration(migrations.Migration): 26 | 27 | dependencies = [ 28 | ("app", "0020_connection_color_label"), 29 | ] 30 | 31 | operations = [ 32 | migrations.RunPython(update_group_names, migrations.RunPython.noop), 33 | migrations.AddConstraint( 34 | model_name="group", 35 | constraint=models.UniqueConstraint( 36 | fields=("user", "name"), name="unique_user_group_name" 37 | ), 38 | ), 39 | ] 40 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0007_connection_connection_params.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.2.18 on 2023-05-15 07:30 2 | 3 | from django.db import migrations, models 4 | 5 | def set_default_connection_params(apps, schema_editor): 6 | # We can't import the Person model directly as it may be a newer 7 | # version than this migration expects. We use the historical version. 8 | Connection = apps.get_model("app", "Connection") 9 | 10 | default_params = { 11 | "postgresql": {"sslmode": "prefer"}, 12 | "mysql": {"ssl": {"ssl": True}}, 13 | "mariadb": {"ssl": {"ssl": True}}, 14 | "oracle": {"protocol": "tcps"} 15 | } 16 | 17 | for conn in Connection.objects.all(): 18 | conn.connection_params = default_params.get(conn.technology.name, {}) 19 | conn.save() 20 | 21 | 22 | class Migration(migrations.Migration): 23 | 24 | dependencies = [ 25 | ('app', '0006_userdetails_binary_path'), 26 | ] 27 | 28 | operations = [ 29 | migrations.AddField( 30 | model_name='connection', 31 | name='connection_params', 32 | field=models.JSONField(default=dict), 33 | ), 34 | migrations.RunPython(set_default_connection_params, migrations.RunPython.noop) 35 | ] 36 | -------------------------------------------------------------------------------- /pgmanage/app/utils/key_manager.py: -------------------------------------------------------------------------------- 1 | from pgmanage import settings 2 | 3 | 4 | class KeyManager: 5 | 6 | __users = dict() 7 | 8 | def get(self, current_user): 9 | user = self.__users.get(current_user.id, None) 10 | if user is not None: 11 | return user.get("key", None) 12 | return None 13 | 14 | def set(self, current_user, _key): 15 | user = self.__users.get(current_user.id, None) 16 | if user is None: 17 | self.__users[current_user.id] = dict(key=_key) 18 | else: 19 | user["key"] = _key 20 | 21 | def remove(self, current_user): 22 | user = self.__users.get(current_user.id, None) 23 | if user is not None: 24 | del self.__users[current_user.id] 25 | 26 | 27 | key_manager = KeyManager() 28 | 29 | if settings.DEBUG: 30 | import os 31 | from django.contrib.auth import get_user_model 32 | 33 | user_keys_env = os.getenv("PGMANAGE_USER_KEYS") 34 | if user_keys_env: 35 | for user_key_pair in user_keys_env.split("|"): 36 | username, user_key = user_key_pair.split(":") 37 | user = get_user_model().objects.filter(username=username).first() 38 | if user: 39 | key_manager.set(user, user_key) 40 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/test/components/MonitoringWidgetsModal.test.js: -------------------------------------------------------------------------------- 1 | import { mount } from "@vue/test-utils"; 2 | import { beforeEach, describe, test, vi, expect, beforeAll } from "vitest"; 3 | import MonitoringWidgetsModal from "../../src/components/MonitoringWidgetsModal.vue"; 4 | import axios from "axios"; 5 | 6 | vi.mock("tabulator-tables", () => { 7 | const TabulatorFull = vi.fn(); 8 | return { TabulatorFull }; 9 | }); 10 | 11 | describe("MonitoringWidgetsModal", () => { 12 | let wrapper; 13 | 14 | beforeAll(() => { 15 | axios.post.mockResolvedValue({ 16 | data: { 17 | data: [ 18 | { 19 | id: 1, 20 | title: "test data", 21 | editable: true, 22 | type: "grid", 23 | interval: 10, 24 | }, 25 | ], 26 | }, 27 | }); 28 | }); 29 | 30 | beforeEach(() => { 31 | wrapper = mount(MonitoringWidgetsModal, { 32 | attachTo: document.body, 33 | props: { 34 | widgetsModalVisible: false, 35 | }, 36 | }); 37 | }); 38 | test("should render MonitoringWidgetsModal component with expected elements", () => { 39 | expect(wrapper.html()).toContain("Monitoring Widgets"); 40 | expect(wrapper.html()).toContain("New Widget"); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/search-modal.scss: -------------------------------------------------------------------------------- 1 | .search-modal { 2 | height: 100%; 3 | width: 100%; 4 | z-index: 1050; 5 | 6 | &::after{ 7 | content: ''; 8 | display: block; 9 | width: 100%; 10 | height: 100%; 11 | background-color: rgba(0, 0, 0, 0.517); 12 | } 13 | 14 | &__container { 15 | margin-top: 35px; 16 | box-shadow: $dropdownBoxShadow; 17 | border-radius: $borderRadius; 18 | width: 700px; 19 | position: absolute; 20 | left: 50%; 21 | transform: translateX(-50%); 22 | 23 | @include themify() { 24 | background: themed($tabsSurfaceBg); 25 | } 26 | } 27 | 28 | &__results { 29 | border-radius: 0; 30 | 31 | &:has(li) { 32 | margin-top: 1rem; 33 | } 34 | 35 | &_item.list-group-item { 36 | border: none; 37 | border-radius: $borderRadius; 38 | 39 | &.selected { 40 | background-color: rgba($primaryBlue, 0.15); 41 | } 42 | 43 | &:hover:not(.selected) { 44 | background-color: rgba($secondaryGrey, 0.15); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /pgmanage/deploy.old/plugin_freebsd/test_instructions.txt: -------------------------------------------------------------------------------- 1 | pkg install zerotier nano wget 2 | pkg install postgresql11-server-11.0_2 postgresql11-contrib-11.0 postgresql11-client-11.0 3 | 4 | su postgres 5 | cd 6 | wget --no-check-certificate https://omnidb.org/dist/2.17.0/omnidb-plugin_2.17.0-freebsd-amd64.tar.gz 7 | tar -xzvf omnidb-plugin_2.17.0-freebsd-amd64.tar.gz 8 | exit 9 | 10 | cp /var/db/postgres/omnidb-plugin_2.17.0-freebsd-amd64/omnidb_plugin_10.so /usr/local/lib/postgresql/omnidb_plugin.so 11 | 12 | service zerotier onestart 13 | zerotier-cli join 14 | 15 | /usr/local/etc/rc.d/postgresql oneinitdb 16 | 17 | nano /var/db/postgres/data10/postgresql.conf 18 | listen_addresses = '*' 19 | shared_preload_libraries = 'omnidb_plugin' 20 | 21 | nano /var/db/postgres/data10/pg_hba.conf 22 | 23 | su postgres 24 | cd 25 | /usr/local/bin/pg_ctl -D /var/db/postgres/data10 -l logfile start 26 | 27 | psql 28 | create user omnidb with password 'omnidb'; 29 | create database omnidb_tests owner omnidb; 30 | 31 | cd ~/omnidb-plugin_2.17.0-freebsd-amd64 32 | psql -d omnidb_tests -f debugger_schema.sql 33 | psql -d omnidb_tests -f sample_functions.sql 34 | psql -d omnidb_tests -c 'grant all on schema omnidb to omnidb' 35 | psql -d omnidb_tests -c 'grant all on all tables in schema omnidb to omnidb' 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Portions Copyright (c) 2022-2025, CommandPrompt Inc. 4 | Portions Copyright (c) 2021-2022, Denis Lussier 5 | Portions Copyright (c) 2015-2019, The OmniDB Team 6 | Portions Copyright (c) 2017-2019, 2ndQuadrant Limited 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/css/font-poppins.css: -------------------------------------------------------------------------------- 1 | /* poppins-regular - latin */ 2 | @font-face { 3 | font-family: 'Poppins'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: local(''), 7 | url('../fonts/Poppins/poppins-v20-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 8 | url('../fonts/Poppins/poppins-v20-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 9 | } 10 | 11 | /* poppins-500 - latin */ 12 | @font-face { 13 | font-family: 'Poppins'; 14 | font-style: normal; 15 | font-weight: 500; 16 | src: local(''), 17 | url('../fonts/Poppins/poppins-v20-latin-500.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 18 | url('../fonts/Poppins/poppins-v20-latin-500.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 19 | } 20 | 21 | /* poppins-700 - latin */ 22 | @font-face { 23 | font-family: 'Poppins'; 24 | font-style: normal; 25 | font-weight: 700; 26 | src: local(''), 27 | url('../fonts/Poppins/poppins-v20-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */ 28 | url('../fonts/Poppins/poppins-v20-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */ 29 | } 30 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/components/ExplainTabContent.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 44 | 45 | 54 | -------------------------------------------------------------------------------- /deploy/windows/license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Portions Copyright (c) 2022-2025, CommandPrompt Inc. 4 | Portions Copyright (c) 2021-2022, Denis Lussier 5 | Portions Copyright (c) 2015-2019, The OmniDB Team 6 | Portions Copyright (c) 2017-2019, 2ndQuadrant Limited 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/test/stores/utitlity_jobs.test.js: -------------------------------------------------------------------------------- 1 | import { setActivePinia, createPinia } from "pinia"; 2 | import { describe, it, expect, beforeEach } from "vitest"; 3 | import { useUtilityJobsStore } from "@src/stores/utility_jobs"; 4 | 5 | describe("utilityJobs store", () => { 6 | beforeEach(() => { 7 | setActivePinia(createPinia()); 8 | }); 9 | 10 | it("initializes with an empty selectedJob object", () => { 11 | const store = useUtilityJobsStore(); 12 | expect(store.selectedJob).toEqual({}); 13 | }); 14 | 15 | it("clears the selectedJob object", () => { 16 | const store = useUtilityJobsStore(); 17 | store.selectedJob = { id: 1, name: "Test Job" }; 18 | 19 | store.clearSelected(); 20 | expect(store.selectedJob).toEqual({}); 21 | }); 22 | 23 | it("sets the selectedJob object", () => { 24 | const store = useUtilityJobsStore(); 25 | const job = { id: 1, name: "Test Job" }; 26 | 27 | store.setJob(job); 28 | expect(store.selectedJob).toEqual(job); 29 | }); 30 | 31 | it("sets the duration of the selectedJob object", () => { 32 | const store = useUtilityJobsStore(); 33 | const job = { id: 1, name: "Test Job", duration: 0 }; 34 | 35 | store.setJob(job); 36 | store.setDuration(120); 37 | expect(store.selectedJob.duration).toBe(120); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/ace_extras/mode-pgsql-extended.js: -------------------------------------------------------------------------------- 1 | ace.define( 2 | "ace/mode/pgsql_extended", 3 | ["require", "exports", "ace/lib/oop", "ace/mode/text", "ace/range"], 4 | function (acequire, exports) { 5 | const oop = acequire("ace/lib/oop"); 6 | const PgsqlMode = acequire("ace/mode/pgsql").Mode; 7 | const SqlFoldMode = acequire("./folding/sql").FoldMode; 8 | const PgsqlHighlightRules = acequire( 9 | "ace/mode/pgsql_highlight_rules" 10 | ).PgsqlHighlightRules; 11 | 12 | const CustomPgsqlHighlightRules = function () { 13 | PgsqlHighlightRules.call(this); 14 | 15 | this.$rules.start.unshift( 16 | { 17 | token: "comment", 18 | regex: /--.*(?=https?:\/\/)/, 19 | }, 20 | { 21 | token: "url", 22 | regex: /https?:\/\/www\.postgresql\.org\/docs\/[^\s"']+/, 23 | }, 24 | { 25 | token: "comment", 26 | regex: /--.*$/, 27 | } 28 | ); 29 | }; 30 | 31 | oop.inherits(CustomPgsqlHighlightRules, PgsqlHighlightRules); 32 | const ExtendedPgsqlMode = function () { 33 | PgsqlMode.call(this); 34 | this.foldingRules = new SqlFoldMode(); 35 | this.HighlightRules = CustomPgsqlHighlightRules; 36 | }; 37 | oop.inherits(ExtendedPgsqlMode, PgsqlMode); 38 | 39 | exports.Mode = ExtendedPgsqlMode; 40 | } 41 | ); 42 | -------------------------------------------------------------------------------- /pgmanage/app/views/bgjob.py: -------------------------------------------------------------------------------- 1 | from app.bgjob.jobs import BatchJob 2 | from app.utils.decorators import user_authenticated 3 | from django.http import HttpResponse, JsonResponse 4 | 5 | 6 | @user_authenticated 7 | def index(request): 8 | job_list = BatchJob.list(request.user) 9 | return JsonResponse(data={"data": job_list}) 10 | 11 | 12 | @user_authenticated 13 | def delete_job(request, job_id): 14 | try: 15 | BatchJob.delete(job_id, request.user) 16 | return HttpResponse(status=204) 17 | except LookupError as exc: 18 | return JsonResponse(data={"data": str(exc)}, status=410) 19 | 20 | 21 | @user_authenticated 22 | def details(request, job_id, out=-1, err=-1): 23 | try: 24 | job = BatchJob(id=job_id) 25 | if job.user.id != request.user.id: 26 | return JsonResponse( 27 | data={"data": "Permission denied."}, 28 | status=403, 29 | ) 30 | 31 | return JsonResponse(data={"data": job.status(out, err)}) 32 | except LookupError as exc: 33 | return JsonResponse(data={"data": str(exc)}, status=410) 34 | 35 | 36 | @user_authenticated 37 | def stop_job(request, job_id): 38 | try: 39 | BatchJob.stop_job(job_id, request.user) 40 | return HttpResponse(status=204) 41 | except LookupError as exc: 42 | return JsonResponse(data={"data": str(exc)}, status=410) 43 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/components/bootstrap-tooltips.scss: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | --bs-tooltip-arrow-width: 1rem; 3 | --bs-tooltip-arrow-height: 0.6rem; 4 | 5 | &-inner { 6 | border-radius: 6px; 7 | padding: 8px; 8 | box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15); 9 | 10 | @include themify() { 11 | color: themed($color); 12 | background-color: themed($tooltipBg); 13 | } 14 | 15 | ul { 16 | padding-left: 20px; 17 | } 18 | } 19 | 20 | &.show { 21 | opacity: 1 !important; 22 | } 23 | } 24 | 25 | .bs-tooltip { 26 | &-top, 27 | &-auto[data-popper-placement^=top] { 28 | .tooltip-arrow::before { 29 | @include themify() { 30 | border-top-color: themed($tooltipBg); 31 | } 32 | } 33 | } 34 | 35 | &-end, 36 | &-auto[data-popper-placement^=right] { 37 | .tooltip-arrow::before { 38 | @include themify() { 39 | border-right-color: themed($tooltipBg); 40 | } 41 | } 42 | } 43 | 44 | &-bottom, 45 | &-auto[data-popper-placement^=bottom] { 46 | .tooltip-arrow::before { 47 | @include themify() { 48 | border-bottom-color: themed($tooltipBg); 49 | } 50 | } 51 | } 52 | 53 | &-start, 54 | &-auto[data-popper-placement^=left] { 55 | .tooltip-arrow:before { 56 | @include themify() { 57 | border-left-color: themed($tooltipBg); 58 | } 59 | } 60 | } 61 | } -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/xl-10/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $(hostname) = "xlcoord" ] 4 | then 5 | 6 | echo "ALTER NODE xlcoord WITH (TYPE = 'coordinator', HOST = 'localhost', PORT = 5432);" > /tmp/script.sql 7 | echo "CREATE NODE xldata1 WITH (TYPE = 'datanode', HOST = '$2', PORT = 5432);" >> /tmp/script.sql 8 | echo "CREATE NODE xldata2 WITH (TYPE = 'datanode', HOST = '$3', PORT = 5432);" >> /tmp/script.sql 9 | echo "SELECT pgxc_pool_reload();" >> /tmp/script.sql 10 | 11 | else 12 | if [ $(hostname) = "xldata1" ] 13 | then 14 | 15 | echo "ALTER NODE xldata1 WITH (TYPE = 'datanode', HOST = 'localhost', PORT = 5432);" > /tmp/script.sql 16 | echo "CREATE NODE xlcoord WITH (TYPE = 'coordinator', HOST = '$1', PORT = 5432);" >> /tmp/script.sql 17 | echo "CREATE NODE xldata2 WITH (TYPE = 'datanode', HOST = '$3', PORT = 5432);" >> /tmp/script.sql 18 | echo "SELECT pgxc_pool_reload();" >> /tmp/script.sql 19 | 20 | else 21 | 22 | echo "ALTER NODE xldata2 WITH (TYPE = 'datanode', HOST = 'localhost', PORT = 5432);" > /tmp/script.sql 23 | echo "CREATE NODE xlcoord WITH (TYPE = 'coordinator', HOST = '$1', PORT = 5432);" >> /tmp/script.sql 24 | echo "CREATE NODE xldata1 WITH (TYPE = 'datanode', HOST = '$2', PORT = 5432);" >> /tmp/script.sql 25 | echo "SELECT pgxc_pool_reload();" >> /tmp/script.sql 26 | 27 | fi 28 | fi 29 | 30 | chmod 777 /tmp/script.sql 31 | sudo su - postgres -c "/usr/local/pgsql/bin/psql -f /tmp/script.sql" 32 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/xl-9.5/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $(hostname) = "xlcoord" ] 4 | then 5 | 6 | echo "ALTER NODE xlcoord WITH (TYPE = 'coordinator', HOST = 'localhost', PORT = 5432);" > /tmp/script.sql 7 | echo "CREATE NODE xldata1 WITH (TYPE = 'datanode', HOST = '$2', PORT = 5432);" >> /tmp/script.sql 8 | echo "CREATE NODE xldata2 WITH (TYPE = 'datanode', HOST = '$3', PORT = 5432);" >> /tmp/script.sql 9 | echo "SELECT pgxc_pool_reload();" >> /tmp/script.sql 10 | 11 | else 12 | if [ $(hostname) = "xldata1" ] 13 | then 14 | 15 | echo "ALTER NODE xldata1 WITH (TYPE = 'datanode', HOST = 'localhost', PORT = 5432);" > /tmp/script.sql 16 | echo "CREATE NODE xlcoord WITH (TYPE = 'coordinator', HOST = '$1', PORT = 5432);" >> /tmp/script.sql 17 | echo "CREATE NODE xldata2 WITH (TYPE = 'datanode', HOST = '$3', PORT = 5432);" >> /tmp/script.sql 18 | echo "SELECT pgxc_pool_reload();" >> /tmp/script.sql 19 | 20 | else 21 | 22 | echo "ALTER NODE xldata2 WITH (TYPE = 'datanode', HOST = 'localhost', PORT = 5432);" > /tmp/script.sql 23 | echo "CREATE NODE xlcoord WITH (TYPE = 'coordinator', HOST = '$1', PORT = 5432);" >> /tmp/script.sql 24 | echo "CREATE NODE xldata1 WITH (TYPE = 'datanode', HOST = '$2', PORT = 5432);" >> /tmp/script.sql 25 | echo "SELECT pgxc_pool_reload();" >> /tmp/script.sql 26 | 27 | fi 28 | fi 29 | 30 | chmod 777 /tmp/script.sql 31 | sudo su - postgres -c "/usr/local/pgsql/bin/psql -f /tmp/script.sql" 32 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/xl-10/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | This creates a Postgres-XL 10 cluster with 4 nodes: 4 | 5 | - xlgtm: 10.33.1.114 6 | - xlcoord: 10.33.1.115 7 | - xldata1: 10.33.1.116 8 | - xldata2: 10.33.1.117 9 | 10 | You can replace the IP address in the `Vagranfile` if you want. 11 | 12 | 13 | ## Create the VMs 14 | 15 | ``` 16 | vagrant up 17 | ``` 18 | 19 | It will take a long while. In my machine it takes around 1h. After it is done: 20 | 21 | ``` 22 | vagrant ssh xlcoord -c '/vagrant/setup.sh 10.33.1.115 10.33.1.116 10.33.1.117' 23 | vagrant ssh xldata1 -c '/vagrant/setup.sh 10.33.1.115 10.33.1.116 10.33.1.117' 24 | vagrant ssh xldata2 -c '/vagrant/setup.sh 10.33.1.115 10.33.1.116 10.33.1.117' 25 | ``` 26 | 27 | 28 | ## Access the cluster 29 | 30 | Best way is to first SSH to the coordinator, then become postgres: 31 | 32 | ``` 33 | vagrant ssh xlcoord 34 | sudo su 35 | su postgres 36 | cd 37 | psql 38 | ``` 39 | 40 | But you can do it in a single command too: 41 | 42 | ``` 43 | vagrant ssh xlcoord -c 'sudo su - postgres -c /usr/local/pgsql/bin/psql' 44 | ``` 45 | 46 | Or remotely, if you have defined a password for the postgres user: 47 | 48 | ``` 49 | psql -h 10.33.1.115 -U postgres 50 | ``` 51 | 52 | 53 | ## Restarting the VMs 54 | 55 | You can shutdown the VMs with: 56 | 57 | ``` 58 | vagrant halt 59 | ``` 60 | 61 | And then start them with: 62 | 63 | ``` 64 | vagrant up 65 | ``` 66 | 67 | And vagrant will start the cluster for you. 68 | -------------------------------------------------------------------------------- /pgmanage/app/migrations/0005_job.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 2.2.28 on 2023-02-15 11:11 2 | 3 | from django.conf import settings 4 | from django.db import migrations, models 5 | import django.db.models.deletion 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('app', '0004_confighistory'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Job', 18 | fields=[ 19 | ('id', models.TextField(primary_key=True, serialize=False)), 20 | ('command', models.TextField()), 21 | ('description', models.TextField()), 22 | ('arguments', models.TextField(blank=True)), 23 | ('logdir', models.TextField()), 24 | ('start_time', models.DateTimeField(null=True)), 25 | ('end_time', models.DateTimeField(null=True)), 26 | ('exit_code', models.IntegerField(null=True)), 27 | ('utility_pid', models.IntegerField(null=True)), 28 | ('process_state', models.IntegerField(null=True)), 29 | ('connection', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='app.Connection')), 30 | ('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 31 | ], 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/vagrant/xl-9.5/README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | This creates a Postgres-XL 9.5 cluster with 4 nodes: 4 | 5 | - xlgtm: 10.33.1.114 6 | - xlcoord: 10.33.1.115 7 | - xldata1: 10.33.1.116 8 | - xldata2: 10.33.1.117 9 | 10 | You can replace the IP address in the `Vagranfile` if you want. 11 | 12 | 13 | ## Create the VMs 14 | 15 | ``` 16 | vagrant up 17 | ``` 18 | 19 | It will take a long while. In my machine it takes around 1h. After it is done: 20 | 21 | ``` 22 | vagrant ssh xlcoord -c '/vagrant/setup.sh 10.33.1.115 10.33.1.116 10.33.1.117' 23 | vagrant ssh xldata1 -c '/vagrant/setup.sh 10.33.1.115 10.33.1.116 10.33.1.117' 24 | vagrant ssh xldata2 -c '/vagrant/setup.sh 10.33.1.115 10.33.1.116 10.33.1.117' 25 | ``` 26 | 27 | 28 | ## Access the cluster 29 | 30 | Best way is to first SSH to the coordinator, then become postgres: 31 | 32 | ``` 33 | vagrant ssh xlcoord 34 | sudo su 35 | su postgres 36 | cd 37 | psql 38 | ``` 39 | 40 | But you can do it in a single command too: 41 | 42 | ``` 43 | vagrant ssh xlcoord -c 'sudo su - postgres -c /usr/local/pgsql/bin/psql' 44 | ``` 45 | 46 | Or remotely, if you have defined a password for the postgres user: 47 | 48 | ``` 49 | psql -h 10.33.1.115 -U postgres 50 | ``` 51 | 52 | 53 | ## Restarting the VMs 54 | 55 | You can shutdown the VMs with: 56 | 57 | ``` 58 | vagrant halt 59 | ``` 60 | 61 | And then start them with: 62 | 63 | ``` 64 | vagrant up 65 | ``` 66 | 67 | And vagrant will start the cluster for you. 68 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/test/components/SideBarTabs.test.js: -------------------------------------------------------------------------------- 1 | import { 2 | describe, 3 | test, 4 | expect, 5 | beforeEach, 6 | afterEach, 7 | beforeAll, 8 | } from "vitest"; 9 | import { mount, enableAutoUnmount } from "@vue/test-utils"; 10 | 11 | import SideBarTabs from "../../src/components/SideBarTabs.vue"; 12 | import "bootstrap"; 13 | import { nextTick } from "vue"; 14 | import { useTabsStore } from "../../src/stores/tabs"; 15 | import { useConnectionsStore } from "../../src/stores/connections"; 16 | 17 | const connectionMock = { 18 | id: 1, 19 | alias: "TestConnection", 20 | technology: "postgresql", 21 | }; 22 | 23 | describe("SideBarTabs.vue", () => { 24 | enableAutoUnmount(afterEach); 25 | let tabsStore, connectionsStore; 26 | 27 | beforeAll(() => { 28 | connectionsStore = useConnectionsStore(); 29 | connectionsStore.$patch({ connections: [connectionMock] }); 30 | }); 31 | 32 | beforeEach(() => { 33 | tabsStore = useTabsStore(); 34 | }); 35 | 36 | afterEach(() => { 37 | tabsStore.$reset(); 38 | }); 39 | test("renders a component", async () => { 40 | let wrapper = mount(SideBarTabs, { 41 | shallow: true, 42 | }); 43 | 44 | expect(wrapper.html()).toContain("omnidb__tab-menu--container--primary"); 45 | await nextTick(); 46 | 47 | expect(wrapper.html()).toContain("Snippets"); 48 | expect(wrapper.html()).toContain("Connections"); 49 | expect(wrapper.html()).toContain("Welcome"); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/message_modal.js: -------------------------------------------------------------------------------- 1 | // stores/modal.js 2 | import { defineStore } from "pinia"; 3 | 4 | const useMessageModalStore = defineStore("messageModal", { 5 | state: () => ({ 6 | visible: false, 7 | message: "", 8 | successFunc: () => {}, 9 | cancelFunc: () => {}, 10 | closable: true, 11 | checkboxes: [], 12 | }), 13 | actions: { 14 | showModal( 15 | message, 16 | successFunc, 17 | cancelFunc, 18 | closable = true, 19 | checkboxes = [] 20 | ) { 21 | this.message = message; 22 | this.successFunc = successFunc; 23 | this.cancelFunc = cancelFunc; 24 | this.closable = closable; 25 | this.checkboxes = checkboxes; 26 | this.visible = true; 27 | }, 28 | hideModal() { 29 | this.visible = false; 30 | this.resetModal(); 31 | }, 32 | executeSuccess() { 33 | if (!!this.successFunc && typeof this.successFunc === "function") { 34 | this.successFunc(); 35 | } 36 | this.hideModal(); 37 | }, 38 | executeCancel() { 39 | if (!!this.cancelFunc && typeof this.cancelFunc === "function") { 40 | this.cancelFunc(); 41 | } 42 | this.hideModal(); 43 | }, 44 | resetModal() { 45 | this.message = ""; 46 | this.successFunc = () => {}; 47 | this.cancelFunc = () => {}; 48 | this.closable = true; 49 | this.checkboxes = []; 50 | }, 51 | }, 52 | }); 53 | 54 | export { useMessageModalStore }; 55 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/test/stores/commands_history.test.js: -------------------------------------------------------------------------------- 1 | import { setActivePinia, createPinia } from "pinia"; 2 | import { describe, it, expect, beforeEach } from "vitest"; 3 | import { useCommandsHistoryStore } from "@src/stores/commands_history"; 4 | 5 | describe("commandsHistoryModal store", () => { 6 | beforeEach(() => { 7 | setActivePinia(createPinia()); 8 | }); 9 | 10 | it("initializes with default state", () => { 11 | const store = useCommandsHistoryStore(); 12 | expect(store.visible).toBe(false); 13 | expect(store.tabId).toBe(null); 14 | expect(store.databaseIndex).toBe(null); 15 | expect(store.tabType).toBe(null); 16 | }); 17 | 18 | it("shows modal and sets the correct state", () => { 19 | const store = useCommandsHistoryStore(); 20 | const tabId = 1; 21 | const databaseIndex = 2; 22 | const tabType = "Query"; 23 | 24 | store.showModal(tabId, databaseIndex, tabType); 25 | 26 | expect(store.visible).toBe(true); 27 | expect(store.tabId).toBe(tabId); 28 | expect(store.databaseIndex).toBe(databaseIndex); 29 | expect(store.tabType).toBe(tabType); 30 | }); 31 | 32 | it("resets the state to default values", () => { 33 | const store = useCommandsHistoryStore(); 34 | 35 | store.showModal(1, 2, "Query"); 36 | store.reset(); 37 | 38 | expect(store.visible).toBe(false); 39 | expect(store.tabId).toBe(null); 40 | expect(store.databaseIndex).toBe(null); 41 | expect(store.tabType).toBe(null); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/uat/ubuntu16/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | $script = < 47 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/mixins/power_tree_pin_database_mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | pinDatabase(node) { 4 | const pinned = !node.data.pinned; 5 | this.api 6 | .post("/pin_database/", { 7 | database_name: node.title, 8 | pinned: pinned, 9 | }) 10 | .then((resp) => { 11 | this.$refs.tree.updateNode(node.path, { 12 | data: { 13 | ...node.data, 14 | pinned: pinned, 15 | }, 16 | }); 17 | const parentNode = this.getParentNode(node); 18 | this.sortPinnedNodes(parentNode); 19 | }) 20 | .catch((error) => { 21 | this.nodeOpenError(error, node); 22 | }); 23 | }, 24 | sortPinnedNodes(node) { 25 | if (!node || !node.children) return; 26 | 27 | const children = node.children; 28 | 29 | const pinned = []; 30 | const unpinned = []; 31 | 32 | for (const child of children) { 33 | (child.data.pinned ? pinned : unpinned).push(child); 34 | } 35 | 36 | pinned.sort((a, b) => { 37 | return a.title.localeCompare(b.title); 38 | }); 39 | 40 | unpinned.sort((a, b) => { 41 | return a.title.localeCompare(b.title); 42 | }); 43 | 44 | // Combine back: pinned DBs first, then unpinned DBs 45 | const reordered = [...pinned, ...unpinned]; 46 | 47 | this.$refs.tree.updateNode(node.path, { 48 | children: reordered, 49 | }); 50 | }, 51 | }, 52 | }; 53 | -------------------------------------------------------------------------------- /pgmanage/app/utils/postgresql_utilities.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | from typing import Union 4 | 5 | from app.models.main import UserDetails 6 | from django.contrib.auth.models import User 7 | 8 | 9 | def check_utility_path( 10 | utility: str, binary_path: Union[str, os.PathLike] 11 | ) -> Union[os.PathLike, None]: 12 | path = ( 13 | shutil.which(utility) 14 | if not binary_path 15 | else os.path.join(binary_path, f"{utility}.exe" if os.name == "nt" else utility) 16 | ) 17 | return path 18 | 19 | 20 | def get_utility_path(utility: str, current_user: User) -> os.PathLike: 21 | user_details = UserDetails.objects.get(user=current_user) 22 | 23 | if utility == "pigz": 24 | binary_path = user_details.pigz_path 25 | else: 26 | binary_path = user_details.binary_path 27 | 28 | utility_path = check_utility_path(utility=utility, binary_path=binary_path) 29 | 30 | if utility_path is None or not os.path.exists(utility_path): 31 | error_msg = f"{utility_path if utility_path else utility} not found." 32 | if utility == "pigz": 33 | error_msg += "
Please make sure that you have pigz installed." 34 | else: 35 | error_msg += "
Please make sure that you have Postgresql Client installed.
\ 36 | More information: Postgresql Client Installation" 37 | raise FileNotFoundError(error_msg) 38 | return utility_path 39 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/logging/logger_setup.js: -------------------------------------------------------------------------------- 1 | import * as log from "loglevel"; 2 | import prefix from "loglevel-plugin-prefix"; 3 | import remote from "loglevel-plugin-remote"; 4 | import { getCookie } from "../ajax_control"; 5 | import { vueHooks, axiosHooks } from "./service"; 6 | import axios from "axios"; 7 | 8 | const DEFAULT_LOGLEVEL = "trace"; 9 | const DEFAULT_LOGLEVEL_REMOTE = "warn"; 10 | const logger = log.noConflict(); 11 | 12 | logger.setLevel(DEFAULT_LOGLEVEL); // my default log level 13 | 14 | prefix.reg(logger); // prefix every print with : 15 | prefix.apply(logger); 16 | 17 | const getCounter = () => { 18 | let count = 1; 19 | return () => count++; 20 | }; 21 | 22 | const counter = getCounter(); 23 | 24 | const customPlain = (log) => log.message; 25 | 26 | const customJSON = (log) => ({ 27 | request_id: counter(), 28 | msg: customPlain(log), 29 | level: log.level.label, 30 | }); 31 | 32 | remote.apply(logger, { 33 | url: `${app_base_path}/log/`, 34 | method: "POST", 35 | level: DEFAULT_LOGLEVEL_REMOTE, 36 | headers: { "X-CSRFToken": getCookie(v_csrf_cookie_name) }, 37 | token: "", 38 | onUnauthorized: () => {}, 39 | timeout: 0, 40 | backoff: { 41 | multiplier: 2, 42 | jitter: 0.1, 43 | limit: 30000, 44 | }, 45 | capacity: 500, 46 | stacktrace: { 47 | depth: 10, 48 | }, 49 | timestamp: () => new Date().toISOString(), 50 | format: customJSON, 51 | }); 52 | 53 | export function setupLogger(app, stores) { 54 | vueHooks(logger, app, stores); 55 | axiosHooks(logger, axios); 56 | } 57 | 58 | export { logger }; 59 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/libs/pev2/plan-grid.scss: -------------------------------------------------------------------------------- 1 | $grid-progress-padding-x: 0.5rem; 2 | $grid-progress-padding-y: 0.75rem; 3 | $grid-progress-margin: 1px; 4 | $progress-gutter: 2px; 5 | 6 | .plan-grid { 7 | line-height: 0.85em; 8 | > table { 9 | border-collapse: separate; 10 | border-spacing: 0; 11 | > tbody, > thead, & { 12 | > tr { 13 | > th, > td { 14 | min-width: 20px; 15 | padding-left: $grid-progress-padding-x; 16 | padding-right: $grid-progress-padding-x; 17 | padding-top: $grid-progress-padding-y; 18 | padding-bottom: $grid-progress-padding-y; 19 | } 20 | } 21 | } 22 | } 23 | 24 | .detailed { 25 | line-height: initial; 26 | margin: 5px; 27 | width: calc(100% - 10px) !important; 28 | max-width: 700px; 29 | } 30 | 31 | .tree-lines { 32 | font-family: 'monospace'; 33 | } 34 | 35 | tr.node { 36 | cursor: pointer; 37 | .bg-light { 38 | background-color: $primaryLight !important; 39 | color: $primaryDark !important; 40 | } 41 | } 42 | .grid-progress-cell { 43 | position: relative; 44 | // Without this bottom border disappareas on Firefox 45 | background-color: transparent; 46 | 47 | .grid-progress { 48 | margin-top: 1px; 49 | } 50 | } 51 | .grid-progress { 52 | position: absolute; 53 | left: calc(0.5rem - 2px); 54 | top: calc(1px * -1 + 0.75rem - 2px); 55 | height: calc(1em + 2px * 2); 56 | width: calc(100% - 0.5rem * 2 + 2px * 2); 57 | z-index: 0; 58 | font-size: inherit; 59 | } 60 | } -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/assets/scss/common/typography.scss: -------------------------------------------------------------------------------- 1 | .h1, h1 { 2 | font-size: 1.5rem; 3 | line-height: 2rem; 4 | } 5 | .h2, h2 { 6 | font-size: 1.25rem; 7 | line-height: 1.75rem; 8 | } 9 | .h3, h3 { 10 | font-size: 1rem; 11 | line-height: 1.5rem; 12 | } 13 | .h4, h4 { 14 | font-size: .875rem; 15 | line-height: 1.25rem; 16 | } 17 | .h5, h5 { 18 | font-size: .75rem; 19 | line-height: 1rem; 20 | } 21 | .h6, h6 { 22 | font-size: .625rem; 23 | line-height: 1rem; 24 | } 25 | p { 26 | font-size: .875rem; 27 | margin-top: 0; 28 | margin-bottom: .3rem; 29 | } 30 | 31 | span.text-muted { 32 | font-size: .75rem; 33 | } 34 | 35 | pre { 36 | font-family: $fontFamilyMonospace; 37 | font-size: inherit; 38 | } 39 | 40 | .muted-text { 41 | color: $primaryMutedColor; 42 | } 43 | 44 | .text-danger { 45 | color: $dangerColor!important; 46 | } 47 | 48 | .text-success { 49 | color: $successColor!important; 50 | } 51 | 52 | .text-warning { 53 | color: $warningColor!important; 54 | } 55 | 56 | .text-info { 57 | color: $infoColor!important; 58 | } 59 | 60 | //only for single line text 61 | .clipped-text { 62 | overflow: hidden; 63 | text-overflow: ellipsis; 64 | } 65 | 66 | //for multiline text 67 | .line-clamp-text { 68 | display: -webkit-box; 69 | -webkit-line-clamp: 2; //number of visible rows 70 | -webkit-box-orient: vertical; 71 | overflow: hidden; 72 | word-wrap: break-word; 73 | } 74 | 75 | .font-weight-semibold { 76 | font-weight: 600; 77 | } 78 | 79 | .invalid-feedback { 80 | font-size: .6rem; 81 | } -------------------------------------------------------------------------------- /tests/uat/debian10/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | $script = < 61 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/utils.js: -------------------------------------------------------------------------------- 1 | function truncateText(text, maxLength) { 2 | if (!text) return ""; 3 | if (text.length <= maxLength) { 4 | return text; 5 | } else if (text.indexOf("/") !== -1) { 6 | const ellipsis = "..."; 7 | const parts = text.split("/"); 8 | const firstPart = parts[0]; 9 | const lastPart = parts[parts.length - 1]; 10 | const middleParts = parts.slice(1, parts.length - 1); 11 | let truncatedText = firstPart + "/"; 12 | for (let i = 0; i < middleParts.length; i++) { 13 | if ( 14 | truncatedText.length + middleParts[i].length + ellipsis.length > 15 | maxLength 16 | ) { 17 | truncatedText += ellipsis; 18 | break; 19 | } 20 | truncatedText += middleParts[i] + "/"; 21 | } 22 | truncatedText += "/" + lastPart; 23 | return truncatedText; 24 | } else { 25 | const ellipsis = "..."; 26 | const truncatedText = text.slice(0, maxLength - ellipsis.length) + ellipsis; 27 | return truncatedText; 28 | } 29 | } 30 | 31 | function extractOrderByClause(queryFilter) { 32 | const orderByRegex = /\bORDER\s+BY\s+([\w\s",.]+)$/i; 33 | const match = queryFilter.match(orderByRegex); 34 | 35 | if (!match) return { queryFilterCleaned: queryFilter, orderByClause: "" }; 36 | 37 | const queryFilterCleaned = queryFilter.replace(orderByRegex, "").trim(); 38 | return { queryFilterCleaned, orderByClause: `ORDER BY ${match[1]}` }; 39 | } 40 | 41 | function findNode(node, predicate) { 42 | if (predicate(node)) return node; 43 | for (let child of node.children || []) { 44 | const found = findNode(child, predicate); 45 | if (found) return found; 46 | } 47 | return null; 48 | } 49 | 50 | function findChild(node, type) { 51 | return (node.children || []).find((child) => child.data?.type === type); 52 | } 53 | 54 | export { truncateText, extractOrderByClause, findChild, findNode }; 55 | -------------------------------------------------------------------------------- /pgmanage/app/static/pgmanage_frontend/src/stores/db_metadata.js: -------------------------------------------------------------------------------- 1 | import { defineStore } from "pinia"; 2 | import axios from "axios"; 3 | 4 | const useDbMetadataStore = defineStore("dbMetadata", { 5 | state: () => ({ 6 | initialized: 'false', 7 | dbMeta: {}, 8 | databases: {}, 9 | }), 10 | actions: { 11 | getDbMeta(conn_id, db_name) { 12 | if(this.dbMeta[conn_id]) 13 | if(this.dbMeta[conn_id][db_name]) 14 | return this.dbMeta[conn_id][db_name] 15 | }, 16 | getDatabases(conn_id) { 17 | return this.databases[conn_id] ?? []; 18 | }, 19 | async fetchDbMeta(conn_id, workspace_id, db_name) { 20 | if(this.dbMeta[conn_id]) 21 | if(this.dbMeta[conn_id][db_name]) 22 | return 23 | const meta_response = await axios.post('/get_database_meta/', { 24 | database_index: conn_id, 25 | workspace_id: workspace_id, 26 | database_name: db_name 27 | }) 28 | 29 | if(!this.dbMeta[conn_id]) 30 | this.dbMeta[conn_id] = {} 31 | this.dbMeta[conn_id][db_name] = meta_response.data.schemas 32 | this.databases[conn_id] = meta_response.data.databases 33 | return meta_response 34 | }, 35 | async refreshDBMeta(conn_id, workspace_id, db_name) { 36 | const meta_response = await axios.post("/get_database_meta/", { 37 | database_index: conn_id, 38 | workspace_id: workspace_id, 39 | database_name: db_name, 40 | }); 41 | 42 | if (!this.dbMeta[conn_id]) this.dbMeta[conn_id] = {}; 43 | 44 | this.dbMeta[conn_id][db_name] = meta_response.data.schemas; 45 | this.databases[conn_id] = meta_response.data.databases; 46 | 47 | return meta_response; 48 | }, 49 | deleteDbMeta(conn_id) { 50 | if (this.dbMeta[conn_id]) { 51 | delete this.dbMeta[conn_id]; 52 | } 53 | }, 54 | }, 55 | }); 56 | 57 | export { useDbMetadataStore }; 58 | -------------------------------------------------------------------------------- /pgmanage/app/tests.old/postgresql/restore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | tar -xzvf $HOME/dellstore2-normal-1.0.tar.gz 4 | 5 | PG_USER=omnidb 6 | PG_PASS=omnidb 7 | PG_DATABASE=omnidb_tests 8 | PG_DUMP=$HOME/dellstore2-normal-1.0/dellstore2-normal-1.0.sql 9 | 10 | PG_PORT=5494 11 | 12 | psql -p $PG_PORT -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASS' SUPERUSER" 13 | psql -p $PG_PORT -c "CREATE DATABASE $PG_DATABASE WITH OWNER=$PG_USER" 14 | PGPASSWORD=$PG_PASS psql -h localhost -p $PG_PORT -d $PG_DATABASE -U $PG_USER -f $PG_DUMP 15 | 16 | PG_PORT=5495 17 | 18 | psql -p $PG_PORT -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASS' SUPERUSER" 19 | psql -p $PG_PORT -c "CREATE DATABASE $PG_DATABASE WITH OWNER=$PG_USER" 20 | PGPASSWORD=$PG_PASS psql -h localhost -p $PG_PORT -d $PG_DATABASE -U $PG_USER -f $PG_DUMP 21 | 22 | PG_PORT=5496 23 | 24 | psql -p $PG_PORT -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASS' SUPERUSER" 25 | psql -p $PG_PORT -c "CREATE DATABASE $PG_DATABASE WITH OWNER=$PG_USER" 26 | PGPASSWORD=$PG_PASS psql -h localhost -p $PG_PORT -d $PG_DATABASE -U $PG_USER -f $PG_DUMP 27 | 28 | PG_PORT=5410 29 | 30 | psql -p $PG_PORT -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASS' SUPERUSER" 31 | psql -p $PG_PORT -c "CREATE DATABASE $PG_DATABASE WITH OWNER=$PG_USER" 32 | PGPASSWORD=$PG_PASS psql -h localhost -p $PG_PORT -d $PG_DATABASE -U $PG_USER -f $PG_DUMP 33 | 34 | PG_PORT=5411 35 | 36 | psql -p $PG_PORT -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASS' SUPERUSER" 37 | psql -p $PG_PORT -c "CREATE DATABASE $PG_DATABASE WITH OWNER=$PG_USER" 38 | PGPASSWORD=$PG_PASS psql -h localhost -p $PG_PORT -d $PG_DATABASE -U $PG_USER -f $PG_DUMP 39 | 40 | PG_PORT=5412 41 | 42 | psql -p $PG_PORT -c "CREATE USER $PG_USER WITH PASSWORD '$PG_PASS' SUPERUSER" 43 | psql -p $PG_PORT -c "CREATE DATABASE $PG_DATABASE WITH OWNER=$PG_USER" 44 | PGPASSWORD=$PG_PASS psql -h localhost -p $PG_PORT -d $PG_DATABASE -U $PG_USER -f $PG_DUMP 45 | 46 | rm -rf $HOME/dellstore2-normal-1.0/ 47 | --------------------------------------------------------------------------------