diff --git a/README.md b/README.md index f355c52..329ea0c 100644 --- a/README.md +++ b/README.md @@ -265,11 +265,11 @@ Find the column metadata returned from a query: ### Notices And Notifications -PostgreSQL [notices] -(https://www.postgresql.org/docs/current/static/plpgsql-errors-and-messages.html) are +PostgreSQL [notices +](https://www.postgresql.org/docs/current/static/plpgsql-errors-and-messages.html) are stored in a deque called `Connection.notices` and added using the `append()` method. -Similarly there are `Connection.notifications` for [notifications] -(https://www.postgresql.org/docs/current/static/sql-notify.html). Here's an example: +Similarly there are `Connection.notifications` for [notifications +](https://www.postgresql.org/docs/current/static/sql-notify.html). Here's an example: ```python >>> import pg8000.native @@ -290,8 +290,8 @@ Similarly there are `Connection.notifications` for [notifications] ### Parameter Statuses [Certain parameter values are reported by the server automatically at connection startup or whenever -their values change] -(https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQPARAMETERSTATUS>) and +their values change +](https://www.postgresql.org/docs/current/libpq-status.html#LIBPQ-PQPARAMETERSTATUS>) and pg8000 stores the latest values in a dict called `Connection.parameter_statuses`. Here's an example where we set the `aplication_name` parameter and then read it from the `parameter_statuses`: @@ -356,8 +356,8 @@ pg8000.exceptions.DatabaseError: ... >>> con.close() ``` -instead you can write it using the [unnest] -(https://www.postgresql.org/docs/current/functions-array.html) function: +instead you can write it using the [unnest +](https://www.postgresql.org/docs/current/functions-array.html) function: ```python >>> import pg8000.native @@ -376,8 +376,8 @@ and you can do the same for `NOT IN`. ### Many SQL Statements Can't Be Parameterized -In PostgreSQL parameters can only be used for [data values, not identifiers] -(https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS). +In PostgreSQL parameters can only be used for [data values, not identifiers +](https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-FUNCTION-ARGUMENTS). Sometimes this might not work as expected, for example the following fails: ```python @@ -522,8 +522,8 @@ parameters. ### Quoted Identifiers in SQL Say you had a column called `My Column`. Since it's case sensitive and contains a space, -you'd have to [surround it by double quotes] -(https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIER). +you'd have to [surround it by double quotes +](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIER). But you can't do: ```python @@ -539,8 +539,8 @@ SyntaxError: invalid syntax... ``` since Python uses double quotes to delimit string literals, so one solution is -to use Python's [triple quotes] -(https://docs.python.org/3/tutorial/introduction.html#strings) to delimit the string +to use Python's [triple quotes +](https://docs.python.org/3/tutorial/introduction.html#strings) to delimit the string instead: ```python @@ -573,8 +573,8 @@ SELECT 'hello' as "My Column" >>> con.close() ``` -this approach guards against [SQL injection attacks] -(https://en.wikipedia.org/wiki/SQL_injection). One thing to note if you're using +this approach guards against [SQL injection attacks +](https://en.wikipedia.org/wiki/SQL_injection). One thing to note if you're using explicit schemas (eg. `pg_catalog.pg_language`) is that the schema name and table name are both separate identifiers. So to escape them you'd do: @@ -756,8 +756,8 @@ You might want to use the current user as the database username for example: >>> connection.close() ``` -or perhaps you may want to use some of the same [environment variables that libpg uses] -(https://www.postgresql.org/docs/current/libpq-envars.html): +or perhaps you may want to use some of the same [environment variables that libpg uses +](https://www.postgresql.org/docs/current/libpq-envars.html): ```python >>> import pg8000.native @@ -779,8 +779,8 @@ or perhaps you may want to use some of the same [environment variables that libp ``` It might be asked, why doesn't pg8000 have this behaviour built in? The thinking -follows the second aphorism of [The Zen of Python] -(https://www.python.org/dev/peps/pep-0020/): +follows the second aphorism of [The Zen of Python +](https://www.python.org/dev/peps/pep-0020/): > Explicit is better than implicit. @@ -831,8 +831,8 @@ connection = pg8000.native.Connection( ### Server-Side Cursors -You can use the SQL commands [DECLARE] -(https://www.postgresql.org/docs/current/sql-declare.html), +You can use the SQL commands [DECLARE +](https://www.postgresql.org/docs/current/sql-declare.html), [FETCH](https://www.postgresql.org/docs/current/sql-fetch.html), [MOVE](https://www.postgresql.org/docs/current/sql-move.html) and [CLOSE](https://www.postgresql.org/docs/current/sql-close.html) to manipulate @@ -858,8 +858,8 @@ server-side cursors. For example: ### BLOBs (Binary Large Objects) -There's a set of [SQL functions] -(https://www.postgresql.org/docs/current/lo-funcs.html) for manipulating BLOBs. +There's a set of [SQL functions +](https://www.postgresql.org/docs/current/lo-funcs.html) for manipulating BLOBs. Here's an example: ```python @@ -900,8 +900,8 @@ Here's an example: ### Replication Protocol -The PostgreSQL [Replication Protocol] -(https://www.postgresql.org/docs/current/protocol-replication.html) is supported using +The PostgreSQL [Replication Protocol +](https://www.postgresql.org/docs/current/protocol-replication.html) is supported using the `replication` keyword when creating a connection: ```python @@ -988,8 +988,8 @@ A query that returns the PostgreSQL interval type: ### Point Type -A round-trip with a [PostgreSQL point] -(https://www.postgresql.org/docs/current/datatype-geometric.html) type: +A round-trip with a [PostgreSQL point +](https://www.postgresql.org/docs/current/datatype-geometric.html) type: ```python >>> import pg8000.dbapi @@ -1157,8 +1157,8 @@ be used to copy from and to a file or file-like object: ### Server-Side Cursors -You can use the SQL commands [DECLARE] -(https://www.postgresql.org/docs/current/sql-declare.html), +You can use the SQL commands [DECLARE +](https://www.postgresql.org/docs/current/sql-declare.html), [FETCH](https://www.postgresql.org/docs/current/sql-fetch.html), [MOVE](https://www.postgresql.org/docs/current/sql-move.html) and [CLOSE](https://www.postgresql.org/docs/current/sql-close.html) to manipulate @@ -1188,8 +1188,8 @@ server-side cursors. For example: ### BLOBs (Binary Large Objects) -There's a set of [SQL functions] -(https://www.postgresql.org/docs/current/lo-funcs.html) for manipulating BLOBs. +There's a set of [SQL functions +](https://www.postgresql.org/docs/current/lo-funcs.html) for manipulating BLOBs. Here's an example: ```python @@ -1249,8 +1249,8 @@ Traceback (most recent call last): struct.error: 'H' format requires 0 <= number <= 65535 ``` -One way of working round this problem is to use the [unnest] -(https://www.postgresql.org/docs/current/functions-array.html) function: +One way of working round this problem is to use the [unnest +](https://www.postgresql.org/docs/current/functions-array.html) function: ```python >>> import pg8000.dbapi @@ -1315,8 +1315,8 @@ possible to change the default mapping using adapters (see the examples). pg8000 is designed to be used with one thread per connection. -Pg8000 communicates with the database using the [PostgreSQL Frontend/Backend Protocol] -(https://www.postgresql.org/docs/current/protocol.html) (FEBE). If a query has no +pg8000 communicates with the database using the [PostgreSQL Frontend/Backend Protocol +](https://www.postgresql.org/docs/current/protocol.html) (FEBE). If a query has no parameters, pg8000 uses the 'simple query protocol'. If a query does have parameters, pg8000 uses the 'extended query protocol' with unnamed prepared statements. The steps for a query with parameters are: @@ -1338,8 +1338,8 @@ front, and then only the BIND and EXECUTE steps are repeated subsequently. There are a lot of PostgreSQL data types, but few primitive data types in Python. By default, pg8000 doesn't send PostgreSQL data type information in the PARSE step, in which case PostgreSQL assumes the types implied by the SQL statement. In some cases -PostgreSQL can't work out a parameter type and so an [explicit cast] -(https://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS) +PostgreSQL can't work out a parameter type and so an [explicit cast +](https://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-TYPE-CASTS) can be used in the SQL. In the FEBE protocol, each query parameter can be sent to the server either as binary @@ -1347,8 +1347,8 @@ or text according to the format code. In pg8000 the parameters are always sent a Occasionally, the network connection between pg8000 and the server may go down. If pg8000 encounters a network problem it'll raise an `InterfaceError` with the message -`network error` and with the original exception set as the [cause] -(https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement). +`network error` and with the original exception set as the [cause +](https://docs.python.org/3/reference/simple_stmts.html#the-raise-statement). ## Native API Docs @@ -1363,8 +1363,8 @@ pg8000 encounters a network problem it'll raise an `InterfaceError` with the mes ## Design Decisions -For the `Range` type, the constructor follows the [PostgreSQL range constructor functions] -(https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-CONSTRUCT) +For the `Range` type, the constructor follows the [PostgreSQL range constructor functions +](https://www.postgresql.org/docs/current/rangetypes.html#RANGETYPES-CONSTRUCT) which makes [[closed, open)](https://fhur.me/posts/always-use-closed-open-intervals) the easiest to express: