mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-01-31 09:24:07 +03:00
Various fixes, now all examples work.
This commit is contained in:
parent
8274a032b1
commit
d6e232e2b9
10
ChangeLog
10
ChangeLog
|
@ -1,5 +1,15 @@
|
||||||
|
2007-04-14 Federico Di Gregorio <fog@initd.org>
|
||||||
|
|
||||||
|
* psycopg/psycopg.h: fixed probable typo in definition of
|
||||||
|
CONV_CODE_PY_SSIZE_T: d -> i for Python < 2.5.
|
||||||
|
|
||||||
|
* Fixed some of the examples.
|
||||||
|
|
||||||
2007-04-13 Federico Di Gregorio <fog@initd.org>
|
2007-04-13 Federico Di Gregorio <fog@initd.org>
|
||||||
|
|
||||||
|
* Applied slighly modified patch from daniel (#176). Made
|
||||||
|
buffer size a compile-time parameter.
|
||||||
|
|
||||||
* Applied patch from David Rushby: typecast_binary.c cleanup.
|
* Applied patch from David Rushby: typecast_binary.c cleanup.
|
||||||
|
|
||||||
* Applied patch from David Rushby for int->size_t transition.
|
* Applied patch from David Rushby for int->size_t transition.
|
||||||
|
|
19
NEWS
19
NEWS
|
@ -1,22 +1,21 @@
|
||||||
What's new in psycopg 2.0.6
|
What's new in psycopg 2.0.6
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
* Full support for PostgreSQL 8.2, including NULLs in arrays.
|
* Better support for PostgreSQL, Python and win32:
|
||||||
|
- full support for PostgreSQL 8.2, including NULLs in arrays
|
||||||
* Full support for Python 2.5 and 64 bit architectures.
|
- support for almost all existing PostgreSQL encodings
|
||||||
|
- full list of PostgreSQL error codes available by importing the
|
||||||
* Support for almost all PostgreSQL encodings.
|
psycopg2.errorcodes module
|
||||||
|
- full support for Python 2.5 and 64 bit architectures
|
||||||
* Better management of times and dates both from Python and in Zope.
|
- better build support on win32 platform
|
||||||
|
|
||||||
* Support for per-connection type-casters (used by ZPsycopgDA too, this
|
* Support for per-connection type-casters (used by ZPsycopgDA too, this
|
||||||
fixes a long standing bug that made different connections use a random
|
fixes a long standing bug that made different connections use a random
|
||||||
set of date/time type-casters instead of the configured one.)
|
set of date/time type-casters instead of the configured one.)
|
||||||
|
|
||||||
* We now have a full list of PostgreSQL error codes available by
|
* Better management of times and dates both from Python and in Zope.
|
||||||
importing the psycopg2.errorcodes module.
|
|
||||||
|
|
||||||
* Better build support on win32 platform.
|
* copy_to and copy_from now take an extra "columns" parameter.
|
||||||
|
|
||||||
* Fixed some small buglets and build glitches:
|
* Fixed some small buglets and build glitches:
|
||||||
- removed double mutex destroy
|
- removed double mutex destroy
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
# See the LICENSE file for details.
|
# See the LICENSE file for details.
|
||||||
|
|
||||||
|
|
||||||
ALLOWED_PSYCOPG_VERSIONS = ('2.0.5', '2.0.6b2', '2.0.6')
|
ALLOWED_PSYCOPG_VERSIONS = ('2.0.6',)
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
|
@ -45,8 +45,8 @@ conn.commit()
|
||||||
|
|
||||||
io = open('copy_from.txt', 'wr')
|
io = open('copy_from.txt', 'wr')
|
||||||
data = ['Tom\tJenkins\t37\n',
|
data = ['Tom\tJenkins\t37\n',
|
||||||
'Madonna\t\N\t45\n',
|
'Madonna\t\\N\t45\n',
|
||||||
'Federico\tDi Gregorio\t\N\n']
|
'Federico\tDi Gregorio\t\\N\n']
|
||||||
io.writelines(data)
|
io.writelines(data)
|
||||||
io.close()
|
io.close()
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ typedef struct {
|
||||||
PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
|
PyObject *copyfile; /* file-like used during COPY TO/FROM ops */
|
||||||
Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */
|
Py_ssize_t copysize; /* size of the copy buffer during COPY TO/FROM ops */
|
||||||
#define DEFAULT_COPYSIZE 16384
|
#define DEFAULT_COPYSIZE 16384
|
||||||
|
#define DEFAULT_COPYBUFF 1024
|
||||||
|
|
||||||
PyObject *tuple_factory; /* factory for result tuples */
|
PyObject *tuple_factory; /* factory for result tuples */
|
||||||
PyObject *tzinfo_factory; /* factory for tzinfo objects */
|
PyObject *tzinfo_factory; /* factory for tzinfo objects */
|
||||||
|
|
|
@ -88,15 +88,6 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
||||||
c = PyString_AsString(fmt);
|
c = PyString_AsString(fmt);
|
||||||
|
|
||||||
while(*c) {
|
while(*c) {
|
||||||
/* check if some crazy guy mixed formats */
|
|
||||||
if (kind == 2) {
|
|
||||||
Py_XDECREF(n);
|
|
||||||
psyco_set_error(ProgrammingError, (PyObject*)conn,
|
|
||||||
"argument formats can't be mixed", NULL, NULL);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
kind = 1;
|
|
||||||
|
|
||||||
/* handle plain percent symbol in format string */
|
/* handle plain percent symbol in format string */
|
||||||
if (c[0] == '%' && c[1] == '%') {
|
if (c[0] == '%' && c[1] == '%') {
|
||||||
c+=2; force = 1;
|
c+=2; force = 1;
|
||||||
|
@ -110,6 +101,15 @@ _mogrify(PyObject *var, PyObject *fmt, connectionObject *conn, PyObject **new)
|
||||||
*/
|
*/
|
||||||
else if (c[0] == '%' && c[1] == '(') {
|
else if (c[0] == '%' && c[1] == '(') {
|
||||||
|
|
||||||
|
/* check if some crazy guy mixed formats */
|
||||||
|
if (kind == 2) {
|
||||||
|
Py_XDECREF(n);
|
||||||
|
psyco_set_error(ProgrammingError, (PyObject*)conn,
|
||||||
|
"argument formats can't be mixed", NULL, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
kind = 1;
|
||||||
|
|
||||||
/* let's have d point the end of the argument */
|
/* let's have d point the end of the argument */
|
||||||
for (d = c + 2; *d && *d != ')'; d++);
|
for (d = c + 2; *d && *d != ')'; d++);
|
||||||
|
|
||||||
|
@ -1076,6 +1076,55 @@ psyco_curs_scroll(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
|
||||||
#ifdef PSYCOPG_EXTENSIONS
|
#ifdef PSYCOPG_EXTENSIONS
|
||||||
|
|
||||||
|
#define COPY_BUFFER_SIZE 1024
|
||||||
|
|
||||||
|
static int _psyco_curs_copy_columns(PyObject *columns, char *columnlist)
|
||||||
|
{
|
||||||
|
PyObject *col, *coliter;
|
||||||
|
Py_ssize_t collen;
|
||||||
|
char* colname;
|
||||||
|
int offset = 1;
|
||||||
|
|
||||||
|
columnlist[0] = '\0';
|
||||||
|
if (columns == NULL || columns == Py_None) return 0;
|
||||||
|
|
||||||
|
coliter = PyObject_GetIter(columns);
|
||||||
|
if (coliter == NULL) return 0;
|
||||||
|
|
||||||
|
columnlist[0] = '(';
|
||||||
|
|
||||||
|
while ((col = PyIter_Next(coliter)) != NULL) {
|
||||||
|
if (!PyString_Check(col)) {
|
||||||
|
Py_DECREF(col);
|
||||||
|
Py_DECREF(coliter);
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"elements in column list must be strings");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PyString_AsStringAndSize(col, &colname, &collen);
|
||||||
|
if (offset + collen > DEFAULT_COPYBUFF - 2) {
|
||||||
|
Py_DECREF(col);
|
||||||
|
Py_DECREF(coliter);
|
||||||
|
PyErr_SetString(PyExc_ValueError, "column list too long");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strncpy(&columnlist[offset], colname, collen);
|
||||||
|
offset += collen;
|
||||||
|
columnlist[offset++] = ',';
|
||||||
|
Py_DECREF(col);
|
||||||
|
}
|
||||||
|
Py_DECREF(coliter);
|
||||||
|
|
||||||
|
if (offset == 2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
columnlist[offset - 1] = ')';
|
||||||
|
columnlist[offset] = '\0';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* extension: copy_from - implements COPY FROM */
|
/* extension: copy_from - implements COPY FROM */
|
||||||
|
|
||||||
#define psyco_curs_copy_from_doc \
|
#define psyco_curs_copy_from_doc \
|
||||||
|
@ -1100,12 +1149,12 @@ _psyco_curs_has_read_check(PyObject* o, void* var)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
char query[1024];
|
char query[DEFAULT_COPYBUFF];
|
||||||
char *table_name;
|
char *table_name;
|
||||||
char *sep = "\t", *null = NULL;
|
char *sep = "\t", *null = NULL;
|
||||||
Py_ssize_t bufsize = DEFAULT_COPYSIZE;
|
Py_ssize_t bufsize = DEFAULT_COPYBUFF;
|
||||||
PyObject *file, *columns = NULL, *res = NULL;
|
PyObject *file, *columns = NULL, *res = NULL;
|
||||||
char columnlist[1024] = "";
|
char columnlist[DEFAULT_COPYBUFF];
|
||||||
|
|
||||||
static char *kwlist[] = {"file", "table", "sep", "null", "size",
|
static char *kwlist[] = {"file", "table", "sep", "null", "size",
|
||||||
"columns", NULL};
|
"columns", NULL};
|
||||||
|
@ -1119,58 +1168,19 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (columns != NULL && columns != Py_None) {
|
if (_psyco_curs_copy_columns(columns, columnlist) == -1)
|
||||||
PyObject* collistiter = PyObject_GetIter(columns);
|
|
||||||
PyObject* col;
|
|
||||||
Py_ssize_t collistlen = 2;
|
|
||||||
Py_ssize_t colitemlen;
|
|
||||||
char* colname;
|
|
||||||
if (collistiter == NULL) {
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
strcpy(columnlist, " (");
|
|
||||||
while ((col = PyIter_Next(collistiter)) != NULL) {
|
|
||||||
if (!PyString_Check(col)) {
|
|
||||||
Py_DECREF(col);
|
|
||||||
Py_DECREF(collistiter);
|
|
||||||
PyErr_SetString(PyExc_ValueError,
|
|
||||||
"Elements in column list must be strings");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
PyString_AsStringAndSize(col, &colname, &colitemlen);
|
|
||||||
if (collistlen + colitemlen > 1022) {
|
|
||||||
Py_DECREF(col);
|
|
||||||
Py_DECREF(collistiter);
|
|
||||||
PyErr_SetString(PyExc_ValueError, "Column list too long");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
strncpy(&columnlist[collistlen], colname, colitemlen);
|
|
||||||
collistlen += colitemlen;
|
|
||||||
columnlist[collistlen++] = ',';
|
|
||||||
Py_DECREF(col);
|
|
||||||
}
|
|
||||||
Py_DECREF(collistiter);
|
|
||||||
|
|
||||||
if (collistlen == 2) { /* empty list; we printed no comma */
|
|
||||||
collistlen++;
|
|
||||||
}
|
|
||||||
|
|
||||||
columnlist[collistlen - 1] = ')';
|
|
||||||
columnlist[collistlen] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PyErr_Occurred()) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
|
|
||||||
if (null) {
|
if (null) {
|
||||||
PyOS_snprintf(query, 1023, "COPY %s%s FROM stdin USING DELIMITERS '%s'"
|
PyOS_snprintf(query, DEFAULT_COPYBUFF-1,
|
||||||
|
"COPY %s%s FROM stdin USING DELIMITERS '%s'"
|
||||||
" WITH NULL AS '%s'", table_name, columnlist, sep, null);
|
" WITH NULL AS '%s'", table_name, columnlist, sep, null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyOS_snprintf(query, 1023, "COPY %s%s FROM stdin USING DELIMITERS '%s'",
|
PyOS_snprintf(query, DEFAULT_COPYBUFF-1,
|
||||||
|
"COPY %s%s FROM stdin USING DELIMITERS '%s'",
|
||||||
table_name, columnlist, sep);
|
table_name, columnlist, sep);
|
||||||
}
|
}
|
||||||
Dprintf("psyco_curs_copy_from: query = %s", query);
|
Dprintf("psyco_curs_copy_from: query = %s", query);
|
||||||
|
@ -1188,8 +1198,10 @@ psyco_curs_copy_from(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* extension: copy_to - implements COPY TO */
|
||||||
|
|
||||||
#define psyco_curs_copy_to_doc \
|
#define psyco_curs_copy_to_doc \
|
||||||
"copy_to(file, table, sep='\\t', null='\\N') -- Copy table to file."
|
"copy_to(file, table, sep='\\t', null='\\N', columns=None) -- Copy table to file."
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_psyco_curs_has_write_check(PyObject* o, void* var)
|
_psyco_curs_has_write_check(PyObject* o, void* var)
|
||||||
|
@ -1209,28 +1221,34 @@ _psyco_curs_has_write_check(PyObject* o, void* var)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
psyco_curs_copy_to(cursorObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
char query[256];
|
char query[DEFAULT_COPYBUFF];
|
||||||
|
char columnlist[DEFAULT_COPYBUFF];
|
||||||
char *table_name;
|
char *table_name;
|
||||||
char *sep = "\t", *null = NULL;
|
char *sep = "\t", *null = NULL;
|
||||||
PyObject *file, *res = NULL;
|
PyObject *file, *columns = NULL, *res = NULL;
|
||||||
|
|
||||||
static char *kwlist[] = {"file", "table", "sep", "null", NULL};
|
static char *kwlist[] = {"file", "table", "sep", "null", "columns", NULL};
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|ss", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&s|ssO", kwlist,
|
||||||
_psyco_curs_has_write_check, &file,
|
_psyco_curs_has_write_check, &file,
|
||||||
&table_name, &sep, &null)) {
|
&table_name, &sep, &null, &columns)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_psyco_curs_copy_columns(columns, columnlist) == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
EXC_IF_CURS_CLOSED(self);
|
EXC_IF_CURS_CLOSED(self);
|
||||||
|
|
||||||
if (null) {
|
if (null) {
|
||||||
PyOS_snprintf(query, 255, "COPY %s TO stdout USING DELIMITERS '%s'"
|
PyOS_snprintf(query, DEFAULT_COPYBUFF-1,
|
||||||
" WITH NULL AS '%s'", table_name, sep, null);
|
"COPY %s%s TO stdout USING DELIMITERS '%s'"
|
||||||
|
" WITH NULL AS '%s'", table_name, columnlist, sep, null);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyOS_snprintf(query, 255, "COPY %s TO stdout USING DELIMITERS '%s'",
|
PyOS_snprintf(query, DEFAULT_COPYBUFF-1,
|
||||||
table_name, sep);
|
"COPY %s%s TO stdout USING DELIMITERS '%s'",
|
||||||
|
table_name, columnlist, sep);
|
||||||
}
|
}
|
||||||
|
|
||||||
self->copysize = 0;
|
self->copysize = 0;
|
||||||
|
|
|
@ -48,7 +48,7 @@ extern "C" {
|
||||||
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 5
|
#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 5
|
||||||
#define CONV_CODE_PY_SSIZE_T "n"
|
#define CONV_CODE_PY_SSIZE_T "n"
|
||||||
#else
|
#else
|
||||||
#define CONV_CODE_PY_SSIZE_T "d"
|
#define CONV_CODE_PY_SSIZE_T "i"
|
||||||
|
|
||||||
typedef int Py_ssize_t;
|
typedef int Py_ssize_t;
|
||||||
#define PY_SSIZE_T_MIN INT_MIN
|
#define PY_SSIZE_T_MIN INT_MIN
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[build_ext]
|
[build_ext]
|
||||||
define=PSYCOPG_EXTENSIONS,PSYCOPG_DISPLAY_SIZE,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3
|
define=PSYCOPG_EXTENSIONS,PSYCOPG_DISPLAY_SIZE,PSYCOPG_NEW_BOOLEAN,HAVE_PQFREEMEM,HAVE_PQPROTOCOL3,PSYCOPG_DEBUG
|
||||||
# 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
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -54,7 +54,7 @@ from distutils.command.build_ext import build_ext
|
||||||
from distutils.sysconfig import get_python_inc
|
from distutils.sysconfig import get_python_inc
|
||||||
from distutils.ccompiler import get_default_compiler
|
from distutils.ccompiler import get_default_compiler
|
||||||
|
|
||||||
PSYCOPG_VERSION = '2.0.6b2'
|
PSYCOPG_VERSION = '2.0.6'
|
||||||
version_flags = []
|
version_flags = []
|
||||||
|
|
||||||
PLATFORM_IS_WINDOWS = sys.platform.lower().startswith('win')
|
PLATFORM_IS_WINDOWS = sys.platform.lower().startswith('win')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user