From b92601306e9bf7627ee7a19382492fa4bf511d57 Mon Sep 17 00:00:00 2001 From: Federico Di Gregorio Date: Fri, 19 Sep 2008 21:25:16 +0200 Subject: [PATCH] Added suppport for UUID and related test. --- ChangeLog | 5 + ZPsycopgDA/DA.py | 2 +- lib/extras.py | 43 +++++++- psycopg2.mdp | 241 +++++++++++++++++++++--------------------- setup.cfg | 2 +- setup.py | 2 +- tests/types_basic.py | 2 +- tests/types_extras.py | 54 ++++++++++ 8 files changed, 226 insertions(+), 125 deletions(-) create mode 100644 tests/types_extras.py diff --git a/ChangeLog b/ChangeLog index 8dba00c1..5912c973 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-09-19 Federico Di Gregorio + + * lib/extras.py: added UUID support, modeled after the code + sent by Brian Sutherland. + 2008-09-16 Federico Di Gregorio * Release 2.0.8. diff --git a/ZPsycopgDA/DA.py b/ZPsycopgDA/DA.py index 05bb6f08..f29ca514 100644 --- a/ZPsycopgDA/DA.py +++ b/ZPsycopgDA/DA.py @@ -18,7 +18,7 @@ # See the LICENSE file for details. -ALLOWED_PSYCOPG_VERSIONS = ('2.0.7',) +ALLOWED_PSYCOPG_VERSIONS = ('2.0.7','2.0.8') import sys import time diff --git a/lib/extras.py b/lib/extras.py index 2db28fd0..91ab9ab6 100644 --- a/lib/extras.py +++ b/lib/extras.py @@ -24,7 +24,8 @@ try: import logging except: logging = None - + +from psycopg2 import extensions as _ext from psycopg2.extensions import cursor as _cursor from psycopg2.extensions import connection as _connection from psycopg2.extensions import adapt as _A @@ -281,3 +282,43 @@ class MinTimeLoggingCursor(LoggingCursor): self.timestamp = time.time() return LoggingCursor.execute(self, procname, vars) + +# a dbtype and adapter for Python UUID type + +try: + import uuid + + class UUID_adapter(object): + """Adapt Python's uuid.UUID type to PostgreSQL's uuid.""" + + def __init__(self, uuid): + self._uuid = uuid + + def prepare(self, conn): + pass + + def getquoted(self): + return "'"+str(self._uuid)+"'::uuid" + + __str__ = getquoted + + def register_uuid(oid=None): + """Create the UUID type and an uuid.UUID adapter.""" + if not oid: oid = 2950 + _ext.UUID = _ext.new_type((oid, ), "UUID", + lambda data, cursor: uuid.UUID(data)) + _ext.register_type(_ext.UUID) + _ext.register_adapter(uuid.UUID, UUID_adapter) + return _ext.UUID + +except ImportError, e: + def register_uuid(oid=None): + """Create the UUID type and an uuid.UUID adapter. + + This is a fake function that will always raise an error because the + import of the uuid module failed. + """ + raise e + + +__all__ = [ k for k in locals().keys() if not k.startswith('_') ] \ No newline at end of file diff --git a/psycopg2.mdp b/psycopg2.mdp index 4c562f5c..e2f2f6ce 100644 --- a/psycopg2.mdp +++ b/psycopg2.mdp @@ -1,138 +1,139 @@ - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup.cfg b/setup.cfg index da79b776..77247f3c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [build_ext] -define=PSYCOPG_EXTENSIONS,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3 +define=PSYCOPG_EXTENSIONS,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3,PSYCOPG_DEBUG # PSYCOPG_EXTENSIONS enables extensions to PEP-249 (you really want this) # PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower) diff --git a/setup.py b/setup.py index c0307150..1ff6b36b 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ from distutils.command.build_ext import build_ext from distutils.sysconfig import get_python_inc from distutils.ccompiler import get_default_compiler -PSYCOPG_VERSION = '2.0.7' +PSYCOPG_VERSION = '2.0.8' version_flags = [] PLATFORM_IS_WINDOWS = sys.platform.lower().startswith('win') diff --git a/tests/types_basic.py b/tests/types_basic.py index 160455ec..323f5fbf 100755 --- a/tests/types_basic.py +++ b/tests/types_basic.py @@ -25,7 +25,7 @@ import tests class TypesBasicTests(unittest.TestCase): - """Test presence of mandatory attributes and methods.""" + """Test that all type conversions are working.""" def setUp(self): self.conn = psycopg2.connect(tests.dsn) diff --git a/tests/types_extras.py b/tests/types_extras.py new file mode 100644 index 00000000..94b99271 --- /dev/null +++ b/tests/types_extras.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# types_extras.py - tests for extras types conversions +# +# Copyright (C) 2008 Federico Di Gregorio +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any later +# version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. + +try: + import decimal +except: + pass +import sys +import unittest + +import psycopg2 +import psycopg2.extras +import tests + + +class TypesBasicTests(unittest.TestCase): + """Test that all type conversions are working.""" + + def setUp(self): + self.conn = psycopg2.connect(tests.dsn) + + def execute(self, *args): + curs = self.conn.cursor() + curs.execute(*args) + return curs.fetchone()[0] + + def testUUID(self): + try: + import uuid + psycopg2.extras.register_uuid() + except: + return + u = uuid.UUID('9c6d5a77-7256-457e-9461-347b4358e350'); + s = self.execute("SELECT %s AS foo", (u,)) + self.failUnless(u == s) + +def test_suite(): + return unittest.TestLoader().loadTestsFromName(__name__) + +if __name__ == "__main__": + unittest.main() +