summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml57
-rw-r--r--.github/workflows/codeql.yml41
-rw-r--r--.gitignore3
-rw-r--r--.pre-commit-config.yaml4
-rw-r--r--AUTHORS15
-rw-r--r--DEVELOP.rst46
-rw-r--r--README.rst46
-rw-r--r--RELEASES.md24
-rw-r--r--changelog.rst125
-rw-r--r--pgcli/__init__.py2
-rw-r--r--pgcli/auth.py60
-rw-r--r--pgcli/completion_refresher.py8
-rw-r--r--pgcli/explain_output_formatter.py19
-rw-r--r--pgcli/key_bindings.py10
-rw-r--r--pgcli/magic.py2
-rw-r--r--pgcli/main.py452
-rw-r--r--pgcli/packages/formatter/__init__.py1
-rw-r--r--pgcli/packages/formatter/sqlformatter.py74
-rw-r--r--pgcli/packages/parseutils/__init__.py48
-rw-r--r--pgcli/packages/parseutils/tables.py20
-rw-r--r--pgcli/packages/prompt_utils.py14
-rw-r--r--pgcli/packages/sqlcompletion.py5
-rw-r--r--pgcli/pgbuffer.py11
-rw-r--r--pgcli/pgclirc59
-rw-r--r--pgcli/pgcompleter.py46
-rw-r--r--pgcli/pgexecute.py414
-rw-r--r--pgcli/pgstyle.py2
-rw-r--r--pgcli/pgtoolbar.py17
-rw-r--r--pgcli/pyev.py439
-rw-r--r--pyproject.toml3
-rw-r--r--release.py4
-rw-r--r--release_procedure.txt13
-rw-r--r--requirements-dev.txt14
-rw-r--r--screenshots/kharkiv-destroyed.jpgbin0 -> 187337 bytes
-rw-r--r--setup.py28
-rw-r--r--tests/features/basic_commands.feature25
-rw-r--r--tests/features/crud_database.feature2
-rw-r--r--tests/features/crud_table.feature29
-rw-r--r--tests/features/db_utils.py37
-rw-r--r--tests/features/environment.py50
-rw-r--r--tests/features/expanded.feature6
-rw-r--r--tests/features/pgbouncer.feature12
-rw-r--r--tests/features/steps/auto_vertical.py10
-rw-r--r--tests/features/steps/basic_commands.py111
-rw-r--r--tests/features/steps/crud_database.py2
-rw-r--r--tests/features/steps/crud_table.py83
-rw-r--r--tests/features/steps/expanded.py12
-rw-r--r--tests/features/steps/pgbouncer.py22
-rw-r--r--tests/features/steps/specials.py7
-rw-r--r--tests/features/steps/wrappers.py16
-rw-r--r--tests/formatter/__init__.py1
-rw-r--r--tests/formatter/test_sqlformatter.py111
-rw-r--r--tests/parseutils/test_parseutils.py56
-rw-r--r--tests/test_auth.py40
-rw-r--r--tests/test_completion_refresher.py18
-rw-r--r--tests/test_exceptionals.py0
-rw-r--r--tests/test_main.py138
-rw-r--r--tests/test_pgcompleter.py76
-rw-r--r--tests/test_pgexecute.py245
-rw-r--r--tests/test_plan.wiki38
-rw-r--r--tests/test_prompt_utils.py9
-rw-r--r--tests/test_rowlimit.py2
-rw-r--r--tests/test_sqlcompletion.py2
-rw-r--r--tests/test_ssh_tunnel.py188
-rw-r--r--tests/utils.py17
-rw-r--r--tox.ini3
66 files changed, 2858 insertions, 636 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index ce54d6f5..42582e4f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,17 +1,25 @@
name: pgcli
on:
+ push:
+ branches:
+ - main
pull_request:
paths-ignore:
- '**.rst'
jobs:
build:
- runs-on: ubuntu-latest
+ #runs-on: [ubuntu-latest, windows-latest]
+ runs-on: [windows-latest]
strategy:
matrix:
- python-version: [3.6, 3.7, 3.8, 3.9]
+ # FIXME: DEBUG ONLY: minimize matrix while we test
+ #os: [ubuntu-latest, windows-latest]
+ os: [windows-latest]
+ #python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+ python-version: ["3.11"]
services:
postgres:
@@ -28,22 +36,55 @@ jobs:
--health-retries 5
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python@v2
+ uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
+ - name: Install pgbouncer
+ run: |
+ sudo apt install pgbouncer -y
+
+ sudo chmod 666 /etc/pgbouncer/*.*
+
+ cat <<EOF > /etc/pgbouncer/userlist.txt
+ "postgres" "postgres"
+ EOF
+
+ cat <<EOF > /etc/pgbouncer/pgbouncer.ini
+ [databases]
+ * = host=localhost port=5432
+ [pgbouncer]
+ listen_port = 6432
+ listen_addr = localhost
+ auth_type = trust
+ auth_file = /etc/pgbouncer/userlist.txt
+ logfile = pgbouncer.log
+ pidfile = pgbouncer.pid
+ admin_users = postgres
+ EOF
+
+ sudo systemctl stop pgbouncer
+
+ pgbouncer -d /etc/pgbouncer/pgbouncer.ini
+
+ psql -h localhost -U postgres -p 6432 pgbouncer -c 'show help'
+
+ - name: Install beta version of pendulum
+ run: pip install pendulum==3.0.0b1
+ if: matrix.python-version == '3.12'
+
- name: Install requirements
run: |
pip install -U pip setuptools
- pip install --no-cache-dir .
+ pip install --no-cache-dir ".[sshtunnel]"
pip install -r requirements-dev.txt
pip install keyrings.alt>=3.1
- name: Run unit tests
- run: coverage run --source pgcli -m py.test
+ run: coverage run --source pgcli -m pytest
- name: Run integration tests
env:
@@ -56,8 +97,8 @@ jobs:
run: rst2html.py --halt=warning changelog.rst >/dev/null
- name: Run Black
- run: pip install black && black --check .
- if: matrix.python-version == '3.6'
+ run: black --check .
+ if: matrix.python-version == '3.8'
- name: Coverage
run: |
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 00000000..c9232c71
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,41 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [ "main" ]
+ pull_request:
+ branches: [ "main" ]
+ schedule:
+ - cron: "29 13 * * 1"
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+ permissions:
+ actions: read
+ contents: read
+ security-events: write
+
+ strategy:
+ fail-fast: false
+ matrix:
+ language: [ python ]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v2
+ with:
+ languages: ${{ matrix.language }}
+ queries: +security-and-quality
+
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v2
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v2
+ with:
+ category: "/language:${{ matrix.language }}"
diff --git a/.gitignore b/.gitignore
index 170585df..b993cb9a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,3 +69,6 @@ target/
.vscode/
venv/
+
+.ropeproject/
+
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 9e27ab8e..8462cc2c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,7 +1,5 @@
repos:
- repo: https://github.com/psf/black
- rev: 21.5b0
+ rev: 23.3.0
hooks:
- id: black
- language_version: python3.7
-
diff --git a/AUTHORS b/AUTHORS
index bcfba6a3..9d1be5bb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -116,8 +116,21 @@ Contributors:
* Kevin Marsh (kevinmarsh)
* Eero Ruohola (ruohola)
* Miroslav Šedivý (eumiro)
- * Eric R Young (ERYoung11)
+ * Eric R Young (ERYoung11)
* Paweł Sacawa (psacawa)
+ * Bruno Inec (sweenu)
+ * Daniele Varrazzo
+ * Daniel Kukula (dkuku)
+ * Kian-Meng Ang (kianmeng)
+ * Liu Zhao (astroshot)
+ * Rigo Neri (rigoneri)
+ * Anna Glasgall (annathyst)
+ * Andy Schoenberger (andyscho)
+ * Damien Baty (dbaty)
+ * blag
+ * Rob Berry (rob-b)
+ * Sharon Yogev (sharonyogev)
+ * Hollis Wu (holi0317)
Creator:
--------
diff --git a/DEVELOP.rst b/DEVELOP.rst
index e262823d..aed2cf8a 100644
--- a/DEVELOP.rst
+++ b/DEVELOP.rst
@@ -48,6 +48,10 @@ Create a virtualenv (let's call it pgcli-dev). Activate it:
source ./pgcli-dev/bin/activate
+ or
+
+ .\pgcli-dev\scripts\activate (for Windows)
+
Once the virtualenv is activated, `cd` into the local clone of pgcli folder
and install pgcli using pip as follows:
@@ -73,6 +77,37 @@ If you want to work on adding new meta-commands (such as `\dp`, `\ds`, `dy`),
you need to contribute to `pgspecial <https://github.com/dbcli/pgspecial/>`_
project.
+Visual Studio Code Debugging
+-----------------------------
+To set up Visual Studio Code to debug pgcli requires a launch.json file.
+
+Within the project, create a file: .vscode\\launch.json like below.
+
+::
+
+ {
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Python: Module",
+ "type": "python",
+ "request": "launch",
+ "module": "pgcli.main",
+ "justMyCode": false,
+ "console": "externalTerminal",
+ "env": {
+ "PGUSER": "postgres",
+ "PGPASS": "password",
+ "PGHOST": "localhost",
+ "PGPORT": "5432"
+ }
+ }
+ ]
+ }
+
Building RPM and DEB packages
-----------------------------
@@ -130,8 +165,9 @@ in the ``tests`` directory. An example::
First, install the requirements for testing:
::
-
- $ pip install -r requirements-dev.txt
+ $ pip install -U pip setuptools
+ $ pip install --no-cache-dir ".[sshtunnel]"
+ $ pip install -r requirements-dev.txt
Ensure that the database user has permissions to create and drop test databases
by checking your ``pg_hba.conf`` file. The default user should be ``postgres``
@@ -145,6 +181,7 @@ service for the changes to take effect.
$ sudo service postgresql restart
After that, tests in the ``/pgcli/tests`` directory can be run with:
+(Note that these ``behave`` tests do not currently work when developing on Windows due to pexpect incompatibility.)
::
@@ -176,3 +213,8 @@ Coding Style
------------
``pgcli`` uses `black <https://github.com/ambv/black>`_ to format the source code. Make sure to install black.
+
+Releases
+--------
+
+If you're the person responsible for releasing `pgcli`, `this guide <https://github.com/dbcli/pgcli/blob/main/RELEASES.md>`_ is for you.
diff --git a/README.rst b/README.rst
index 95137f7c..56695cc4 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,30 @@
+We stand with Ukraine
+---------------------
+
+Ukrainian people are fighting for their country. A lot of civilians, women and children, are suffering. Hundreds were killed and injured, and thousands were displaced.
+
+This is an image from my home town, Kharkiv. This place is right in the old city center.
+
+.. image:: screenshots/kharkiv-destroyed.jpg
+
+Picture by @fomenko_ph (Telegram).
+
+Please consider donating or volunteering.
+
+* https://bank.gov.ua/en/
+* https://savelife.in.ua/en/donate/
+* https://www.comebackalive.in.ua/donate
+* https://www.globalgiving.org/projects/ukraine-crisis-relief-fund/
+* https://www.savethechildren.org/us/where-we-work/ukraine
+* https://www.facebook.com/donate/1137971146948461/
+* https://donate.wck.org/give/393234#!/donation/checkout
+* https://atlantaforukraine.com/
+
+
A REPL for Postgres
-------------------
-|Build Status| |CodeCov| |PyPI| |Landscape|
+|Build Status| |CodeCov| |PyPI| |netlify|
This is a postgres client that does auto-completion and syntax highlighting.
@@ -29,10 +52,7 @@ If you already know how to install python packages, then you can simply do:
If you don't know how to install python packages, please check the
`detailed instructions`_.
-If you are restricted to using psycopg2 2.7.x then pip will try to install it from a binary. There are some known issues with the psycopg2 2.7 binary - see the `psycopg docs`_ for more information about this and how to force installation from source. psycopg2 2.8 has fixed these problems, and will build from source.
-
.. _`detailed instructions`: https://github.com/dbcli/pgcli#detailed-installation-instructions
-.. _`psycopg docs`: http://initd.org/psycopg/docs/install.html#change-in-binary-packages-between-psycopg-2-7-and-2-8
Usage
-----
@@ -137,8 +157,9 @@ get this running in a development setup.
https://github.com/dbcli/pgcli/blob/master/DEVELOP.rst
-Please feel free to reach out to me if you need help.
-My email: amjith.r@gmail.com, Twitter: `@amjithr <http://twitter.com/amjithr>`_
+Please feel free to reach out to us if you need help.
+* Amjith, pgcli author: amjith.r@gmail.com, Twitter: `@amjithr <http://twitter.com/amjithr>`_
+* Irina, pgcli maintainer: i.chernyavska@gmail.com, Twitter: `@irinatruong <http://twitter.com/irinatruong>`_
Detailed Installation Instructions:
-----------------------------------
@@ -331,8 +352,7 @@ choice:
In [3]: my_result = _
-Pgcli only runs on Python3.6+ since 2.2.0, if you use an old version of Python,
-you should use install ``pgcli <= 2.2.0``.
+Pgcli dropped support for Python<3.8 as of 4.0.0. If you need it, install ``pgcli <= 4.0.0``.
Thanks:
-------
@@ -346,14 +366,14 @@ of this app.
`Click <http://click.pocoo.org/>`_ is used for command line option parsing
and printing error messages.
-Thanks to `psycopg <http://initd.org/psycopg/>`_ for providing a rock solid
+Thanks to `psycopg <https://www.psycopg.org/>`_ for providing a rock solid
interface to Postgres database.
Thanks to all the beta testers and contributors for your time and patience. :)
-.. |Build Status| image:: https://github.com/dbcli/pgcli/workflows/pgcli/badge.svg
- :target: https://github.com/dbcli/pgcli/actions?query=workflow%3Apgcli
+.. |Build Status| image:: https://github.com/dbcli/pgcli/actions/workflows/ci.yml/badge.svg?branch=main
+ :target: https://github.com/dbcli/pgcli/actions/workflows/ci.yml
.. |CodeCov| image:: https://codecov.io/gh/dbcli/pgcli/branch/master/graph/badge.svg
:target: https://codecov.io/gh/dbcli/pgcli
@@ -366,3 +386,7 @@ Thanks to all the beta testers and contributors for your time and patience. :)
.. |PyPI| image:: https://img.shields.io/pypi/v/pgcli.svg
:target: https://pypi.python.org/pypi/pgcli/
:alt: Latest Version
+
+.. |netlify| image:: https://api.netlify.com/api/v1/badges/3a0a14dd-776d-445d-804c-3dd74fe31c4e/deploy-status
+ :target: https://app.netlify.com/sites/pgcli/deploys
+ :alt: Netlify
diff --git a/RELEASES.md b/RELEASES.md
new file mode 100644
index 00000000..526c260e
--- /dev/null
+++ b/RELEASES.md
@@ -0,0 +1,24 @@
+Releasing pgcli
+---------------
+
+You have been made the maintainer of `pgcli`? Congratulations! We have a release script to help you:
+
+```sh
+> python release.py --help
+Usage: release.py [options]
+
+Options:
+ -h, --help show this help message and exit
+ -c, --confirm-steps Confirm every step. If the step is not confirmed, it
+ will be skipped.
+ -d, --dry-run Print out, but not actually run any steps.
+```
+
+The script can be run with `-c` to confirm or skip steps. There's also a `--dry-run` option that only prints out the steps.
+
+To release a new version of the package:
+
+* Create and merge a PR to bump the version in the changelog ([example PR](https://github.com/dbcli/pgcli/pull/1325)).
+* Pull `main` and bump the version number inside `pgcli/__init__.py`. Do not check in - the release script will do that.
+* Make sure you have the dev requirements installed: `pip install -r requirements-dev.txt -U --upgrade-strategy only-if-needed`.
+* Finally, run the release script: `python release.py`.
diff --git a/changelog.rst b/changelog.rst
index 21941499..d1b9f72a 100644
--- a/changelog.rst
+++ b/changelog.rst
@@ -1,5 +1,119 @@
-TBD
-===
+==================
+4.0.1 (2023-10-30)
+==================
+
+Internal:
+---------
+* Allow stable version of pendulum.
+
+==================
+4.0.0 (2023-10-27)
+==================
+
+Features:
+---------
+
+* Ask for confirmation when quitting cli while a transaction is ongoing.
+* New `destructive_statements_require_transaction` config option to refuse to execute a
+ destructive SQL statement if outside a transaction. This option is off by default.
+* Changed the `destructive_warning` config to be a list of commands that are considered
+ destructive. This would allow you to be warned on `create`, `grant`, or `insert` queries.
+* Destructive warnings will now include the alias dsn connection string name if provided (-D option).
+* pgcli.magic will now work with connection URLs that use TLS client certificates for authentication
+* Have config option to retry queries on operational errors like connections being lost.
+ Also prevents getting stuck in a retry loop.
+* Config option to not restart connection when cancelling a `destructive_warning` query. By default,
+ it will now not restart.
+* Config option to always run with a single connection.
+* Add comment explaining default LESS environment variable behavior and change example pager setting.
+* Added `\echo` & `\qecho` special commands. ([issue 1335](https://github.com/dbcli/pgcli/issues/1335)).
+
+Bug fixes:
+----------
+
+* Fix `\ev` not producing a correctly quoted "schema"."view"
+* Fix 'invalid connection option "dsn"' ([issue 1373](https://github.com/dbcli/pgcli/issues/1373)).
+* Fix explain mode when used with `expand`, `auto_expand`, or `--explain-vertical-output` ([issue 1393](https://github.com/dbcli/pgcli/issues/1393)).
+* Fix sql-insert format emits NULL as 'None' ([issue 1408](https://github.com/dbcli/pgcli/issues/1408)).
+* Improve check for prompt-toolkit 3.0.6 ([issue 1416](https://github.com/dbcli/pgcli/issues/1416)).
+* Allow specifying an `alias_map_file` in the config that will use
+ predetermined table aliases instead of generating aliases programmatically on
+ the fly
+* Fixed SQL error when there is a comment on the first line: ([issue 1403](https://github.com/dbcli/pgcli/issues/1403))
+* Fix wrong usage of prompt instead of confirm when confirm execution of destructive query
+
+Internal:
+---------
+
+* Drop support for Python 3.7 and add 3.12.
+
+3.5.0 (2022/09/15):
+===================
+
+Features:
+---------
+
+* New formatter is added to export query result to sql format (such as sql-insert, sql-update) like mycli.
+
+Bug fixes:
+----------
+
+* Fix exception when retrieving password from keyring ([issue 1338](https://github.com/dbcli/pgcli/issues/1338)).
+* Fix using comments with special commands ([issue 1362](https://github.com/dbcli/pgcli/issues/1362)).
+* Small improvements to the Windows developer experience
+* Fix submitting queries in safe multiline mode ([1360](https://github.com/dbcli/pgcli/issues/1360)).
+
+Internal:
+---------
+
+* Port to psycopg3 (https://github.com/psycopg/psycopg).
+* Fix typos
+
+3.4.1 (2022/03/19)
+==================
+
+Bug fixes:
+----------
+
+* Fix the bug with Redshift not displaying word count in status ([related issue](https://github.com/dbcli/pgcli/issues/1320)).
+* Show the error status for CSV output format.
+
+
+3.4.0 (2022/02/21)
+==================
+
+Features:
+---------
+
+* Add optional support for automatically creating an SSH tunnel to a machine with access to the remote database ([related issue](https://github.com/dbcli/pgcli/issues/459)).
+
+3.3.1 (2022/01/18)
+==================
+
+Bug fixes:
+----------
+
+* Prompt for password when -W is provided even if there is a password in keychain. Fixes #1307.
+* Upgrade cli_helpers to 2.2.1
+
+3.3.0 (2022/01/11)
+==================
+
+Features:
+---------
+
+* Add `max_field_width` setting to config, to enable more control over field truncation ([related issue](https://github.com/dbcli/pgcli/issues/1250)).
+* Re-run last query via bare `\watch`. (Thanks: `Saif Hakim`_)
+
+Bug fixes:
+----------
+
+* Pin the version of pygments to prevent breaking change
+
+3.2.0
+=====
+
+Release date: 2021/08/23
Features:
---------
@@ -8,6 +122,7 @@ Features:
`destructive_warning` setting to `all|moderate|off`, vs `true|false`. (#1239)
* Skip initial comment in .pg_session even if it doesn't start with '#'
* Include functions from schemas in search_path. (`Amjith Ramanujam`_)
+* Easy way to show explain output under F5
Bug fixes:
----------
@@ -19,6 +134,7 @@ Bug fixes:
* Fix pager not being used when output format is set to csv. (#1238)
* Add function literals random, generate_series, generate_subscripts
* Fix ANSI escape codes in first line make the cli choose expanded output incorrectly
+* Fix pgcli crashing with virtual `pgbouncer` database. (#1093)
3.1.0
=====
@@ -720,7 +836,7 @@ Internal Changes:
* Added code coverage to the tests. (Thanks: `Irina Truong`_)