Dropped support for protocol 2.

Dropped both the setup constant allowing conditional compiling and the
code specific to V2 protocol (mostly COPY and error handling).
This commit is contained in:
Daniele Varrazzo 2010-11-16 01:06:27 +00:00
parent 73265e7ece
commit a88d7ab424
6 changed files with 10 additions and 156 deletions

View File

@ -2,6 +2,10 @@
* psycopg/connection_int.c: abort connection to protocol 2 server. * psycopg/connection_int.c: abort connection to protocol 2 server.
* psycopg/pqpath.c
* psycopg/connection_int.c: dropped support for protocol 2 at compile
time and protocol 2-specific code.
2010-11-11 Daniele Varrazzo <daniele.varrazzo@gmail.com> 2010-11-11 Daniele Varrazzo <daniele.varrazzo@gmail.com>
* lib/extras.py: build the namedtuple only once per execution, not once * lib/extras.py: build the namedtuple only once per execution, not once

View File

@ -266,13 +266,7 @@ int
conn_get_protocol_version(PGconn *pgconn) conn_get_protocol_version(PGconn *pgconn)
{ {
int ret; int ret;
#ifdef HAVE_PQPROTOCOL3
ret = PQprotocolVersion(pgconn); ret = PQprotocolVersion(pgconn);
#else
ret = 2;
#endif
Dprintf("conn_connect: using protocol %d", ret); Dprintf("conn_connect: using protocol %d", ret);
return ret; return ret;
} }

View File

@ -780,7 +780,7 @@ static struct PyMemberDef connectionObject_members[] = {
"A set of typecasters to convert binary values."}, "A set of typecasters to convert binary values."},
{"protocol_version", T_INT, {"protocol_version", T_INT,
offsetof(connectionObject, protocol), RO, offsetof(connectionObject, protocol), RO,
"Protocol version (2 or 3) used for this connection."}, "Protocol version used for this connection. Currently always 3."},
{"server_version", T_INT, {"server_version", T_INT,
offsetof(connectionObject, server_version), RO, offsetof(connectionObject, server_version), RO,
"Server version."}, "Server version."},

View File

@ -173,11 +173,9 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult *pgres)
if (pgres) { if (pgres) {
err = PQresultErrorMessage(pgres); err = PQresultErrorMessage(pgres);
#ifdef HAVE_PQPROTOCOL3 if (err != NULL) {
if (err != NULL && conn->protocol == 3) {
code = PQresultErrorField(pgres, PG_DIAG_SQLSTATE); code = PQresultErrorField(pgres, PG_DIAG_SQLSTATE);
} }
#endif
} }
if (err == NULL) if (err == NULL)
err = PQerrorMessage(conn->pgconn); err = PQerrorMessage(conn->pgconn);
@ -196,25 +194,6 @@ pq_raise(connectionObject *conn, cursorObject *curs, PGresult *pgres)
exc = exception_from_sqlstate(code); exc = exception_from_sqlstate(code);
} }
/* if exc is still NULL psycopg was not built with HAVE_PQPROTOCOL3 or the
connection is using protocol 2: in both cases we default to comparing
error messages */
if (exc == NULL) {
if (!strncmp(err, "ERROR: Cannot insert a duplicate key", 37)
|| !strncmp(err, "ERROR: ExecAppend: Fail to add null", 36)
|| strstr(err, "referential integrity violation"))
exc = IntegrityError;
else if (strstr(err, "could not serialize") ||
strstr(err, "deadlock detected"))
#ifdef PSYCOPG_EXTENSIONS
exc = TransactionRollbackError;
#else
exc = OperationalError;
#endif
else
exc = ProgrammingError;
}
/* try to remove the initial "ERROR: " part from the postgresql error */ /* try to remove the initial "ERROR: " part from the postgresql error */
err2 = strip_severity(err); err2 = strip_severity(err);
@ -1063,7 +1042,6 @@ _pq_fetch_tuples(cursorObject *curs)
Py_END_ALLOW_THREADS; Py_END_ALLOW_THREADS;
} }
#ifdef HAVE_PQPROTOCOL3
static int static int
_pq_copy_in_v3(cursorObject *curs) _pq_copy_in_v3(cursorObject *curs)
{ {
@ -1155,57 +1133,7 @@ exit:
Py_XDECREF(size); Py_XDECREF(size);
return (error == 0 ? 1 : -1); return (error == 0 ? 1 : -1);
} }
#endif
static int
_pq_copy_in(cursorObject *curs)
{
/* COPY FROM implementation when protocol 3 is not available: this
function can't fail but the backend will send an ERROR notice that will
be catched by our notice collector */
PyObject *o, *func = NULL;
int ret = -1;
if (!(func = PyObject_GetAttrString(curs->copyfile, "readline"))) {
Dprintf("_pq_copy_in: can't get o.readline");
goto exit;
}
while (1) {
int rv;
o = PyObject_CallFunction(func, NULL);
if (o == NULL) goto exit;
if (o == Py_None || PyString_GET_SIZE(o) == 0) break;
Py_BEGIN_ALLOW_THREADS;
rv = PQputline(curs->conn->pgconn, PyString_AS_STRING(o));
Py_END_ALLOW_THREADS;
Py_DECREF(o);
if (0 != rv) goto exit;
}
Py_XDECREF(o);
Py_BEGIN_ALLOW_THREADS;
PQputline(curs->conn->pgconn, "\\.\n");
PQendcopy(curs->conn->pgconn);
Py_END_ALLOW_THREADS;
/* if for some reason we're using a protocol 3 libpq to connect to a
protocol 2 backend we still need to cycle on the result set */
IFCLEARPGRES(curs->pgres);
while ((curs->pgres = PQgetResult(curs->conn->pgconn)) != NULL) {
if (PQresultStatus(curs->pgres) == PGRES_FATAL_ERROR)
pq_raise(curs->conn, curs, NULL);
IFCLEARPGRES(curs->pgres);
}
ret = 1;
exit:
Py_XDECREF(func);
return ret;
}
#ifdef HAVE_PQPROTOCOL3
static int static int
_pq_copy_out_v3(cursorObject *curs) _pq_copy_out_v3(cursorObject *curs)
{ {
@ -1258,66 +1186,6 @@ exit:
Py_XDECREF(func); Py_XDECREF(func);
return ret; return ret;
} }
#endif
static int
_pq_copy_out(cursorObject *curs)
{
PyObject *tmp = NULL, *func;
char buffer[4096];
int status = -1, ll = 0;
Py_ssize_t len;
if (!(func = PyObject_GetAttrString(curs->copyfile, "write"))) {
Dprintf("_pq_copy_out: can't get o.write");
goto exit;
}
while (1) {
Py_BEGIN_ALLOW_THREADS;
status = PQgetline(curs->conn->pgconn, buffer, 4096);
Py_END_ALLOW_THREADS;
if (status == 0) {
if (!ll && buffer[0] == '\\' && buffer[1] == '.') break;
len = (Py_ssize_t) strlen(buffer);
buffer[len++] = '\n';
ll = 0;
}
else if (status == 1) {
len = 4096-1;
ll = 1;
}
else {
goto exit;
}
tmp = PyObject_CallFunction(func, "s#", buffer, len);
if (tmp == NULL) {
goto exit;
} else {
Py_DECREF(tmp);
}
}
status = 1;
if (PQendcopy(curs->conn->pgconn) != 0)
status = -1;
/* if for some reason we're using a protocol 3 libpq to connect to a
protocol 2 backend we still need to cycle on the result set */
IFCLEARPGRES(curs->pgres);
while ((curs->pgres = PQgetResult(curs->conn->pgconn)) != NULL) {
if (PQresultStatus(curs->pgres) == PGRES_FATAL_ERROR)
pq_raise(curs->conn, curs, NULL);
IFCLEARPGRES(curs->pgres);
}
exit:
Py_XDECREF(func);
return status;
}
int int
pq_fetch(cursorObject *curs) pq_fetch(cursorObject *curs)
@ -1368,12 +1236,7 @@ pq_fetch(cursorObject *curs)
case PGRES_COPY_OUT: case PGRES_COPY_OUT:
Dprintf("pq_fetch: data from a COPY TO (no tuples)"); Dprintf("pq_fetch: data from a COPY TO (no tuples)");
#ifdef HAVE_PQPROTOCOL3 ex = _pq_copy_out_v3(curs);
if (curs->conn->protocol == 3)
ex = _pq_copy_out_v3(curs);
else
#endif
ex = _pq_copy_out(curs);
curs->rowcount = -1; curs->rowcount = -1;
/* error caught by out glorious notice handler */ /* error caught by out glorious notice handler */
if (PyErr_Occurred()) ex = -1; if (PyErr_Occurred()) ex = -1;
@ -1382,12 +1245,7 @@ pq_fetch(cursorObject *curs)
case PGRES_COPY_IN: case PGRES_COPY_IN:
Dprintf("pq_fetch: data from a COPY FROM (no tuples)"); Dprintf("pq_fetch: data from a COPY FROM (no tuples)");
#ifdef HAVE_PQPROTOCOL3 ex = _pq_copy_in_v3(curs);
if (curs->conn->protocol == 3)
ex = _pq_copy_in_v3(curs);
else
#endif
ex = _pq_copy_in(curs);
curs->rowcount = -1; curs->rowcount = -1;
/* error caught by out glorious notice handler */ /* error caught by out glorious notice handler */
if (PyErr_Occurred()) ex = -1; if (PyErr_Occurred()) ex = -1;

View File

@ -1,10 +1,9 @@
[build_ext] [build_ext]
define=PSYCOPG_EXTENSIONS,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3 define=PSYCOPG_EXTENSIONS,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM
# PSYCOPG_EXTENSIONS enables extensions to PEP-249 (you really want this) # PSYCOPG_EXTENSIONS enables extensions to PEP-249 (you really want this)
# PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower) # PSYCOPG_DISPLAY_SIZE enable display size calculation (a little slower)
# HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.4 # HAVE_PQFREEMEM should be defined on PostgreSQL >= 7.4
# HAVE_PQPROTOCOL3 should be defined on PostgreSQL >= 7.4
# PSYCOPG_DEBUG can be added to enable verbose debug information # PSYCOPG_DEBUG can be added to enable verbose debug information
# PSYCOPG_NEW_BOOLEAN to format booleans as true/false vs 't'/'f' # PSYCOPG_NEW_BOOLEAN to format booleans as true/false vs 't'/'f'

View File

@ -393,11 +393,10 @@ else:
sys.exit(1) sys.exit(1)
# generate a nice version string to avoid confusion when users report bugs # generate a nice version string to avoid confusion when users report bugs
version_flags.append('pq3') # no more a choice
for have in parser.get('build_ext', 'define').split(','): for have in parser.get('build_ext', 'define').split(','):
if have == 'PSYCOPG_EXTENSIONS': if have == 'PSYCOPG_EXTENSIONS':
version_flags.append('ext') version_flags.append('ext')
elif have == 'HAVE_PQPROTOCOL3':
version_flags.append('pq3')
if version_flags: if version_flags:
PSYCOPG_VERSION_EX = PSYCOPG_VERSION + " (%s)" % ' '.join(version_flags) PSYCOPG_VERSION_EX = PSYCOPG_VERSION + " (%s)" % ' '.join(version_flags)
else: else: