summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>2018-10-15 00:58:32 +0100
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>2018-10-15 00:58:32 +0100
commitb205764fdde4549c48c27841aa17e6c7f499e808 (patch)
tree1475eb57dc854ea4a1dc93c1c6a567e6fc584e5c /lib
parente7227ce87b8da75fef1a3376ebb47e2bf20f6063 (diff)
parent7a5edff6c66a0410d6fecd4445980aabafc3ab4a (diff)
downloadpsycopg2-b205764fdde4549c48c27841aa17e6c7f499e808.tar.gz
Merge branch 'master' into errors-moduleerrors-module
Diffstat (limited to 'lib')
-rw-r--r--lib/__init__.py6
-rw-r--r--lib/_range.py13
-rw-r--r--lib/errorcodes.py3
-rw-r--r--lib/extensions.py2
-rw-r--r--lib/extras.py10
-rw-r--r--lib/sql.py46
-rw-r--r--lib/tz.py2
7 files changed, 63 insertions, 19 deletions
diff --git a/lib/__init__.py b/lib/__init__.py
index cbec98f..b88d59c 100644
--- a/lib/__init__.py
+++ b/lib/__init__.py
@@ -8,8 +8,8 @@ small and fast, and stable as a rock.
Homepage: http://initd.org/projects/psycopg2
-.. _PostgreSQL: http://www.postgresql.org/
-.. _Python: http://www.python.org/
+.. _PostgreSQL: https://www.postgresql.org/
+.. _Python: https://www.python.org/
:Groups:
* `Connections creation`: connect
@@ -43,7 +43,7 @@ Homepage: http://initd.org/projects/psycopg2
# Note: the first internal import should be _psycopg, otherwise the real cause
# of a failed loading of the C module may get hidden, see
-# http://archives.postgresql.org/psycopg/2011-02/msg00044.php
+# https://archives.postgresql.org/psycopg/2011-02/msg00044.php
# Import the DBAPI-2.0 stuff into top-level module.
diff --git a/lib/_range.py b/lib/_range.py
index fd15a76..e72c878 100644
--- a/lib/_range.py
+++ b/lib/_range.py
@@ -62,6 +62,19 @@ class Range(object):
return "%s(%r, %r, %r)" % (self.__class__.__name__,
self._lower, self._upper, self._bounds)
+ def __str__(self):
+ if self._bounds is None:
+ return 'empty'
+
+ items = [
+ self._bounds[0],
+ str(self._lower),
+ ', ',
+ str(self._upper),
+ self._bounds[1]
+ ]
+ return ''.join(items)
+
@property
def lower(self):
"""The lower bound of the range. `!None` if empty or unbound."""
diff --git a/lib/errorcodes.py b/lib/errorcodes.py
index b8742f5..beee37c 100644
--- a/lib/errorcodes.py
+++ b/lib/errorcodes.py
@@ -26,7 +26,7 @@ This module contains symbolic names for all PostgreSQL error codes.
#
# Based on:
#
-# http://www.postgresql.org/docs/current/static/errcodes-appendix.html
+# https://www.postgresql.org/docs/current/static/errcodes-appendix.html
#
@@ -182,6 +182,7 @@ INVALID_XML_PROCESSING_INSTRUCTION = '2200T'
INVALID_INDICATOR_PARAMETER_VALUE = '22010'
SUBSTRING_ERROR = '22011'
DIVISION_BY_ZERO = '22012'
+INVALID_PRECEDING_OR_FOLLOWING_SIZE = '22013'
INVALID_ARGUMENT_FOR_NTILE_FUNCTION = '22014'
INTERVAL_FIELD_OVERFLOW = '22015'
INVALID_ARGUMENT_FOR_NTH_VALUE_FUNCTION = '22016'
diff --git a/lib/extensions.py b/lib/extensions.py
index 3661e6c..3111d41 100644
--- a/lib/extensions.py
+++ b/lib/extensions.py
@@ -8,7 +8,7 @@ This module holds all the extensions to the DBAPI-2.0 provided by psycopg.
- `adapt()` -- exposes the PEP-246_ compatible adapting mechanism used
by psycopg to adapt Python types to PostgreSQL ones
-.. _PEP-246: http://www.python.org/peps/pep-0246.html
+.. _PEP-246: https://www.python.org/dev/peps/pep-0246/
"""
# psycopg/extensions.py - DBAPI-2.0 extensions specific to psycopg
#
diff --git a/lib/extras.py b/lib/extras.py
index ff32ab6..af59d2f 100644
--- a/lib/extras.py
+++ b/lib/extras.py
@@ -404,7 +404,7 @@ class NamedTupleCursor(_cursor):
class LoggingConnection(_connection):
"""A connection that logs all queries to a file or logger__ object.
- .. __: http://docs.python.org/library/logging.html
+ .. __: https://docs.python.org/library/logging.html
"""
def initialize(self, logobj):
@@ -638,8 +638,8 @@ class ReplicationCursor(_replicationCursor):
class UUID_adapter(object):
"""Adapt Python's uuid.UUID__ type to PostgreSQL's uuid__.
- .. __: http://docs.python.org/library/uuid.html
- .. __: http://www.postgresql.org/docs/current/static/datatype-uuid.html
+ .. __: https://docs.python.org/library/uuid.html
+ .. __: https://www.postgresql.org/docs/current/static/datatype-uuid.html
"""
def __init__(self, uuid):
@@ -759,8 +759,8 @@ def wait_select(conn):
The function is an example of a wait callback to be registered with
`~psycopg2.extensions.set_wait_callback()`. This function uses
- :py:func:`~select.select()` to wait for data available.
-
+ :py:func:`~select.select()` to wait for data to become available, and
+ therefore is able to handle/receive SIGINT/KeyboardInterrupt.
"""
import select
from psycopg2.extensions import POLL_OK, POLL_READ, POLL_WRITE
diff --git a/lib/sql.py b/lib/sql.py
index 7ba9295..241b827 100644
--- a/lib/sql.py
+++ b/lib/sql.py
@@ -290,7 +290,7 @@ class SQL(Composable):
class Identifier(Composable):
"""
- A `Composable` representing an SQL identifer.
+ A `Composable` representing an SQL identifer or a dot-separated sequence.
Identifiers usually represent names of database objects, such as tables or
fields. PostgreSQL identifiers follow `different rules`__ than SQL string
@@ -307,20 +307,50 @@ class Identifier(Composable):
>>> print(sql.SQL(', ').join([t1, t2, t3]).as_string(conn))
"foo", "ba'r", "ba""z"
+ Multiple strings can be passed to the object to represent a qualified name,
+ i.e. a dot-separated sequence of identifiers.
+
+ Example::
+
+ >>> query = sql.SQL("select {} from {}").format(
+ ... sql.Identifier("table", "field"),
+ ... sql.Identifier("schema", "table"))
+ >>> print(query.as_string(conn))
+ select "table"."field" from "schema"."table"
+
"""
- def __init__(self, string):
- if not isinstance(string, string_types):
- raise TypeError("SQL identifiers must be strings")
+ def __init__(self, *strings):
+ if not strings:
+ raise TypeError("Identifier cannot be empty")
+
+ for s in strings:
+ if not isinstance(s, string_types):
+ raise TypeError("SQL identifier parts must be strings")
- super(Identifier, self).__init__(string)
+ super(Identifier, self).__init__(strings)
@property
- def string(self):
- """The string wrapped by the `Identifier`."""
+ def strings(self):
+ """A tuple with the strings wrapped by the `Identifier`."""
return self._wrapped
+ @property
+ def string(self):
+ """The string wrapped by the `Identifier`.
+ """
+ if len(self._wrapped) == 1:
+ return self._wrapped[0]
+ else:
+ raise AttributeError(
+ "the Identifier wraps more than one than one string")
+
+ def __repr__(self):
+ return "%s(%s)" % (
+ self.__class__.__name__,
+ ', '.join(map(repr, self._wrapped)))
+
def as_string(self, context):
- return ext.quote_ident(self._wrapped, context)
+ return '.'.join(ext.quote_ident(s, context) for s in self._wrapped)
class Literal(Composable):
diff --git a/lib/tz.py b/lib/tz.py
index d593175..97f3857 100644
--- a/lib/tz.py
+++ b/lib/tz.py
@@ -44,7 +44,7 @@ class FixedOffsetTimezone(datetime.tzinfo):
offset and name that instance will be returned. This saves memory and
improves comparability.
- .. __: http://docs.python.org/library/datetime.html#datetime-tzinfo
+ .. __: https://docs.python.org/library/datetime.html
"""
_name = None
_offset = ZERO