From e1688431e04357b56277144fc1a9ddf0207c991b Mon Sep 17 00:00:00 2001 From: Federico Di Gregorio Date: Sat, 8 Oct 2005 03:04:40 +0000 Subject: [PATCH] Isolation level changes. --- ChangeLog | 13 +++++++++++++ lib/extensions.py | 9 +++++++++ lib/psycopg1.py | 5 +++-- psycopg/connection_int.c | 31 ++++++++++++++++++++++++++++--- psycopg/connection_type.c | 1 - psycopg/pqpath.c | 1 - setup.py | 2 +- 7 files changed, 54 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 710d4dd4..a9d1681b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-10-08 Federico Di Gregorio + + * lib/psycopg1.py: explicitly set isolation level to 2 on .connect() + to mimic psycopg 1 behaviour. + + * psycopg/connection_int.c: now set isolation level from + default_transaction_isolation backend environment value. + + * psycopg/pqpath.c: removed serialization level 3: now everybody + (except me) has to use the mnemonics defined in psycopg2.extensions. + + * lib/extensions.py: Added mnemonics for serialization levels. + 2005-10-02 Federico Di Gregorio * psycopg/cursor_type.c (psyco_curs_callproc): applied callproc diff --git a/lib/extensions.py b/lib/extensions.py index 6a18878f..d5d1ac62 100644 --- a/lib/extensions.py +++ b/lib/extensions.py @@ -41,6 +41,15 @@ from _psycopg import adapt, adapters, encodings, connection, cursor from _psycopg import string_types, binary_types, new_type, register_type from _psycopg import ISQLQuote +"""Isolation level values.""" +ISOLATION_LEVEL_AUTOCOMMIT = 0 +ISOLATION_LEVEL_READ_COMMITED = 1 +ISOLATION_LEVEL_SERIALIZABLE = 2 + +# Postgresql maps the the other standard values to already defined levels +ISOLATION_LEVEL_REPEATABLE_READ = ISOLATION_LEVEL_SERIALIZABLE +ISOLATION_LEVEL_READ UNCOMMITTED = ISOLATION_LEVEL_READ_COMMITED + def register_adapter(typ, callable): """Register 'callable' as an ISQLQuote adapter for type 'typ'.""" diff --git a/lib/psycopg1.py b/lib/psycopg1.py index d953b11e..76fd788a 100644 --- a/lib/psycopg1.py +++ b/lib/psycopg1.py @@ -31,8 +31,9 @@ del connect def connect(*args, **kwargs): """connect(dsn, ...) -> new psycopg 1.1.x compatible connection object""" kwargs['connection_factory'] = connection - return _2psycopg.connect(*args, **kwargs) - + conn = _2psycopg.connect(*args, **kwargs) + conn.set_isolation_level(2) + return conn class connection(_2connection): """psycopg 1.1.x connection.""" diff --git a/psycopg/connection_int.c b/psycopg/connection_int.c index e99b8d3b..916eae3d 100644 --- a/psycopg/connection_int.c +++ b/psycopg/connection_int.c @@ -53,11 +53,18 @@ conn_connect(connectionObject *self) { PGconn *pgconn; PGresult *pgres; - + char *data; + /* we need the initial date style to be ISO, for typecasters; if the user later change it, she must know what she's doing... */ const char *datestyle = "SET DATESTYLE TO 'ISO'"; const char *encoding = "SHOW client_encoding"; + const char *isolevel = "SHOW default_transaction_isolation"; + + const char *lvl1a = "read uncommitted"; + const char *lvl1b = "read committed"; + const char *lvl2a = "repeatable read"; + const char *lvl2b = "serializable"; Py_BEGIN_ALLOW_THREADS; pgconn = PQconnectdb(self->dsn); @@ -86,7 +93,6 @@ conn_connect(connectionObject *self) Py_END_ALLOW_THREADS; if (pgres == NULL || PQresultStatus(pgres) != PGRES_COMMAND_OK ) { - Dprintf("conn_connect: setting datestyle to iso FAILED"); PyErr_SetString(OperationalError, "can't set datestyle to ISO"); PQfinish(pgconn); IFCLEARPGRES(pgres); @@ -99,7 +105,6 @@ conn_connect(connectionObject *self) Py_END_ALLOW_THREADS; if (pgres == NULL || PQresultStatus(pgres) != PGRES_TUPLES_OK) { - Dprintf("conn_connect: fetching current client_encoding FAILED"); PyErr_SetString(OperationalError, "can't fetch client_encoding"); PQfinish(pgconn); IFCLEARPGRES(pgres); @@ -107,6 +112,26 @@ conn_connect(connectionObject *self) } self->encoding = strdup(PQgetvalue(pgres, 0, 0)); CLEARPGRES(pgres); + + Py_BEGIN_ALLOW_THREADS; + pgres = PQexec(pgconn, isolevel); + Py_END_ALLOW_THREADS; + + if (pgres == NULL || PQresultStatus(pgres) != PGRES_TUPLES_OK) { + PyErr_SetString(OperationalError, + "can't fetch default_isolation_level"); + PQfinish(pgconn); + IFCLEARPGRES(pgres); + return -1; + } + data = PQgetvalue(pgres, 0, 0); + if ((strncmp(lvl1a, data, strlen(lvl1a)) == 0) + || (strncmp(lvl1b, data, strlen(lvl1b)) == 0)) + self->isolation_level = 1; + else if ((strncmp(lvl2a, data, strlen(lvl2a)) == 0) + || (strncmp(lvl2b, data, strlen(lvl2b)) == 0)) + self->isolation_level = 2; + CLEARPGRES(pgres); if (PQsetnonblocking(pgconn, 1) != 0) { Dprintf("conn_connect: PQsetnonblocking() FAILED"); diff --git a/psycopg/connection_type.c b/psycopg/connection_type.c index e537a38d..bff66f67 100644 --- a/psycopg/connection_type.c +++ b/psycopg/connection_type.c @@ -257,7 +257,6 @@ connection_setup(connectionObject *self, char *dsn) self->dsn = strdup(dsn); self->notice_list = PyList_New(0); self->closed = 0; - self->isolation_level = 1; self->status = CONN_STATUS_READY; self->critical = NULL; self->async_cursor = NULL; diff --git a/psycopg/pqpath.c b/psycopg/pqpath.c index c9271871..f304816e 100644 --- a/psycopg/pqpath.c +++ b/psycopg/pqpath.c @@ -186,7 +186,6 @@ pq_begin(connectionObject *conn) const char *query[] = { NULL, "BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITTED", - "BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE", "BEGIN; SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"}; int pgstatus, retvalue = -1; diff --git a/setup.py b/setup.py index 1f044af9..140ecaa3 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,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.0b4' +PSYCOPG_VERSION = '2.0rc1' version_flags = [] # to work around older distutil limitations