diff --git a/AUTHORS b/AUTHORS index a037334..65bef17 100644 --- a/AUTHORS +++ b/AUTHORS @@ -119,6 +119,7 @@ Contributors: * Eric R Young (ERYoung11) * Paweł Sacawa (psacawa) * Bruno Inec (sweenu) + * Daniele Varrazzo Creator: -------- diff --git a/README.rst b/README.rst index 95137f7..c8ab822 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,29 @@ +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://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. @@ -366,3 +388,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/changelog.rst b/changelog.rst index 1f0bc59..18f6661 100644 --- a/changelog.rst +++ b/changelog.rst @@ -1,7 +1,10 @@ -TBD -=== +3.4.1 (2022/03/19) +================== -* [List new changes here]. +Bug fixes: +---------- + +* Fix the bug with Redshift not displaying word count in status ([related issue](https://github.com/dbcli/pgcli/issues/1320)). 3.4.0 (2022/02/21) ================== diff --git a/pgcli/__init__.py b/pgcli/__init__.py index 903a158..a5cfdf5 100644 --- a/pgcli/__init__.py +++ b/pgcli/__init__.py @@ -1 +1 @@ -__version__ = "3.4.0" +__version__ = "3.4.1" diff --git a/pgcli/main.py b/pgcli/main.py index a72f708..2d7edfa 100644 --- a/pgcli/main.py +++ b/pgcli/main.py @@ -80,6 +80,8 @@ except ImportError: from getpass import getuser from psycopg2 import OperationalError, InterfaceError + +# pg3: https://www.psycopg.org/psycopg3/docs/api/conninfo.html from psycopg2.extensions import make_dsn, parse_dsn import psycopg2 @@ -1545,6 +1547,14 @@ def format_output(title, cur, headers, status, settings): return data, headers + def format_status(cur, status): + # redshift does not return rowcount as part of status. + # See https://github.com/dbcli/pgcli/issues/1320 + if cur and hasattr(cur, "rowcount") and cur.rowcount is not None: + if status and not status.endswith(str(cur.rowcount)): + status += " %s" % cur.rowcount + return status + output_kwargs = { "sep_title": "RECORD {n}", "sep_character": "-", @@ -1580,12 +1590,15 @@ def format_output(title, cur, headers, status, settings): if hasattr(cur, "description"): column_types = [] for d in cur.description: + # pg3: type_name = cur.adapters.types[d.type_code].name if ( + # pg3: type_name in ("numeric", "float4", "float8") d[1] in psycopg2.extensions.DECIMAL.values or d[1] in psycopg2.extensions.FLOAT.values ): column_types.append(float) if ( + # pg3: type_name in ("int2", "int4", "int8") d[1] == psycopg2.extensions.INTEGER.values or d[1] in psycopg2.extensions.LONGINTEGER.values ): @@ -1614,7 +1627,7 @@ def format_output(title, cur, headers, status, settings): # Only print the status if it's not None and we are not producing CSV if status and table_format != "csv": - output = itertools.chain(output, [status]) + output = itertools.chain(output, [format_status(cur, status)]) return output diff --git a/pgcli/pgexecute.py b/pgcli/pgexecute.py index 22e9ea4..4808630 100644 --- a/pgcli/pgexecute.py +++ b/pgcli/pgexecute.py @@ -16,6 +16,7 @@ _logger = logging.getLogger(__name__) # Cast all database input to unicode automatically. # See http://initd.org/psycopg/docs/usage.html#unicode-handling for more info. +# pg3: These should be automatic: unicode is the default ext.register_type(ext.UNICODE) ext.register_type(ext.UNICODEARRAY) ext.register_type(ext.new_type((705,), "UNKNOWN", ext.UNICODE)) @@ -32,6 +33,8 @@ _WAIT_SELECT_TIMEOUT = 1 _wait_callback_is_set = False +# pg3: it is already "green" but Ctrl-C breaks the query +# pg3: This should be fixed upstream: https://github.com/psycopg/psycopg/issues/231 def _wait_select(conn): """ copy-pasted from psycopg2.extras.wait_select @@ -74,6 +77,8 @@ def _set_wait_callback(is_virtual_database): ext.set_wait_callback(_wait_select) +# pg3: You can do something like: +# pg3: cnn.adapters.register_loader("date", psycopg.types.string.TextLoader) def register_date_typecasters(connection): """ Casts date and timestamp values to string, resolves issues with out of @@ -124,6 +129,7 @@ def register_json_typecasters(conn, loads_fn): return available +# pg3: Probably you don't need this because by default unknown -> unicode def register_hstore_typecaster(conn): """ Instead of using register_hstore() which converts hstore into a python @@ -142,6 +148,7 @@ def register_hstore_typecaster(conn): pass +# pg3: I don't know what is this class ProtocolSafeCursor(psycopg2.extensions.cursor): def __init__(self, *args, **kwargs): self.protocol_error = False @@ -392,6 +399,7 @@ class PGExecute: return json_data def failed_transaction(self): + # pg3: self.conn.info.transaction_status == psycopg.pq.TransactionStatus.INERROR status = self.conn.get_transaction_status() return status == ext.TRANSACTION_STATUS_INERROR @@ -541,6 +549,8 @@ class PGExecute: def view_definition(self, spec): """Returns the SQL defining views described by `spec`""" + # pg3: you may want to use `psycopg.sql` for client-side composition + # pg3: (also available in psycopg2 by the way) template = "CREATE OR REPLACE {6} VIEW {0}.{1} AS \n{3}" # 2: relkind, v or m (materialized) # 4: reloptions, null diff --git a/release.py b/release.py index e83d239..4237efd 100644 --- a/release.py +++ b/release.py @@ -74,7 +74,7 @@ def upload_distribution_files(): def push_to_github(): - run_step("git", "push", "origin", "master") + run_step("git", "push", "origin", "main") def push_tags_to_github(): diff --git a/screenshots/kharkiv-destroyed.jpg b/screenshots/kharkiv-destroyed.jpg new file mode 100644 index 0000000..4f95783 Binary files /dev/null and b/screenshots/kharkiv-destroyed.jpg differ diff --git a/setup.py b/setup.py index ed6fb3c..975819b 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from pgcli import __version__ description = "CLI for Postgres Database. With auto-completion and syntax highlighting." install_requirements = [ - "pgspecial>=1.11.8", + "pgspecial>=1.13.1,<2.0.0", "click >= 4.1", "Pygments>=2.0", # Pygments has to be Capitalcased. WTF? # We still need to use pt-2 unless pt-3 released on Fedora32 @@ -34,6 +34,9 @@ setup( version=__version__, license="BSD", url="http://pgcli.com", + project_urls={ + "Source": "https://github.com/dbcli/pgcli", + }, packages=find_packages(), package_data={"pgcli": ["pgclirc", "packages/pgliterals/pgliterals.json"]}, description=description,