mirror of
				https://github.com/psycopg/psycopg2.git
				synced 2025-11-04 09:47:30 +03:00 
			
		
		
		
	Merge changes from psycopg2/trunk via psycopg2.r243.
This commit is contained in:
		
						commit
						938c456cee
					
				
							
								
								
									
										13
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								ChangeLog
									
									
									
									
									
								
							| 
						 | 
					@ -1,3 +1,16 @@
 | 
				
			||||||
 | 
					2006-09-01  Federico Di Gregorio  <fog@initd.org>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* psycopg/connection_type.c: merged in double mutex destroy patch
 | 
				
			||||||
 | 
						from Joerg Sonnenberger.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* Implemented large objects support.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* psycopg/connection_int.c: removed increment of self->mark,
 | 
				
			||||||
 | 
						now it is done directly in pqpath.c to make sure even the
 | 
				
			||||||
 | 
						large object support gets it.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* Starting 2.1 development.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2008-04-21  James Henstridge  <james@jamesh.id.au>
 | 
					2008-04-21  James Henstridge  <james@jamesh.id.au>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	* tests/test_quote.py (QuotingTestCase.test_unicode): If the
 | 
						* tests/test_quote.py (QuotingTestCase.test_unicode): If the
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										79
									
								
								examples/lobject.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								examples/lobject.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,79 @@
 | 
				
			||||||
 | 
					# lobject.py - lobject example
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (C) 2001-2006 Federico Di Gregorio  <fog@debian.org>
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## put in DSN your DSN string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DSN = 'dbname=test'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## don't modify anything below this line (except for experimenting)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import psycopg2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if len(sys.argv) > 1:
 | 
				
			||||||
 | 
					    DSN = sys.argv[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print "Opening connection using dns:", DSN
 | 
				
			||||||
 | 
					conn = psycopg2.connect(DSN)
 | 
				
			||||||
 | 
					print "Encoding for this connection is", conn.encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# this will create a large object with a new random oid, we'll
 | 
				
			||||||
 | 
					# use it to make some basic tests about read/write and seek.
 | 
				
			||||||
 | 
					lobj = conn.lobject()
 | 
				
			||||||
 | 
					loid = lobj.oid
 | 
				
			||||||
 | 
					print "Created a new large object with oid", loid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print "Manually importing some binary data into the object:"
 | 
				
			||||||
 | 
					data = open("somehackers.jpg").read()
 | 
				
			||||||
 | 
					len = lobj.write(data)
 | 
				
			||||||
 | 
					print "  imported", len, "bytes of data"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					conn.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print "Trying to (re)open large object with oid", loid
 | 
				
			||||||
 | 
					lobj = conn.lobject(loid)
 | 
				
			||||||
 | 
					print "Manually exporting the data from the lobject:"
 | 
				
			||||||
 | 
					data1 = lobj.read()
 | 
				
			||||||
 | 
					len = lobj.tell()
 | 
				
			||||||
 | 
					lobj.seek(0, 0)
 | 
				
			||||||
 | 
					data2 = lobj.read()
 | 
				
			||||||
 | 
					if data1 != data2:
 | 
				
			||||||
 | 
					    print "ERROR: read after seek returned different data"
 | 
				
			||||||
 | 
					open("somehackers_lobject1.jpg", 'wb').write(data1)
 | 
				
			||||||
 | 
					print "  written", len, "bytes of data to somehackers_lobject1.jpg"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lobj.unlink()
 | 
				
			||||||
 | 
					print "Large object with oid", loid, "removed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					conn.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# now we try to use the import and export functions to do the same
 | 
				
			||||||
 | 
					lobj = conn.lobject(0, 'n', 0, "somehackers.jpg")
 | 
				
			||||||
 | 
					loid = lobj.oid
 | 
				
			||||||
 | 
					print "Imported a new large object with oid", loid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					conn.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print "Trying to (re)open large object with oid", loid
 | 
				
			||||||
 | 
					lobj = conn.lobject(loid, 'n')
 | 
				
			||||||
 | 
					print "Using export() to export the data from the large object:"
 | 
				
			||||||
 | 
					lobj.export("somehackers_lobject2.jpg")
 | 
				
			||||||
 | 
					print "  exported large object to somehackers_lobject2.jpg"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lobj.unlink()
 | 
				
			||||||
 | 
					print "Large object with oid", loid, "removed"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					conn.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					print "\nNow try to load the new images, to check it worked!"
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ This module holds all the extensions to the DBAPI-2.0 provided by psycopg.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- `connection` -- the new-type inheritable connection class
 | 
					- `connection` -- the new-type inheritable connection class
 | 
				
			||||||
- `cursor` -- the new-type inheritable cursor class
 | 
					- `cursor` -- the new-type inheritable cursor class
 | 
				
			||||||
 | 
					- `lobject` -- the new-type inheritable large object class
 | 
				
			||||||
- `adapt()` -- exposes the PEP-246_ compatible adapting mechanism used
 | 
					- `adapt()` -- exposes the PEP-246_ compatible adapting mechanism used
 | 
				
			||||||
  by psycopg to adapt Python types to PostgreSQL ones
 | 
					  by psycopg to adapt Python types to PostgreSQL ones
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
| 
						 | 
					@ -38,7 +39,7 @@ try:
 | 
				
			||||||
except:
 | 
					except:
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from _psycopg import adapt, adapters, encodings, connection, cursor
 | 
					from _psycopg import adapt, adapters, encodings, connection, cursor, lobject
 | 
				
			||||||
from _psycopg import string_types, binary_types, new_type, register_type
 | 
					from _psycopg import string_types, binary_types, new_type, register_type
 | 
				
			||||||
from _psycopg import ISQLQuote
 | 
					from _psycopg import ISQLQuote
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -246,7 +246,6 @@ conn_commit(connectionObject *self)
 | 
				
			||||||
    int res;
 | 
					    int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = pq_commit(self);
 | 
					    res = pq_commit(self);
 | 
				
			||||||
    self->mark++;
 | 
					 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,7 +257,6 @@ conn_rollback(connectionObject *self)
 | 
				
			||||||
    int res;
 | 
					    int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res = pq_abort(self);
 | 
					    res = pq_abort(self);
 | 
				
			||||||
    self->mark++;
 | 
					 | 
				
			||||||
    return res;
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -283,7 +281,6 @@ conn_switch_isolation_level(connectionObject *self, int level)
 | 
				
			||||||
        res = pq_abort_locked(self, &pgres, &error);
 | 
					        res = pq_abort_locked(self, &pgres, &error);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    self->isolation_level = level;
 | 
					    self->isolation_level = level;
 | 
				
			||||||
    self->mark++;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Dprintf("conn_switch_isolation_level: switched to level %d", level);
 | 
					    Dprintf("conn_switch_isolation_level: switched to level %d", level);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,6 +33,7 @@
 | 
				
			||||||
#include "psycopg/psycopg.h"
 | 
					#include "psycopg/psycopg.h"
 | 
				
			||||||
#include "psycopg/connection.h"
 | 
					#include "psycopg/connection.h"
 | 
				
			||||||
#include "psycopg/cursor.h"
 | 
					#include "psycopg/cursor.h"
 | 
				
			||||||
 | 
					#include "psycopg/lobject.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** DBAPI methods **/
 | 
					/** DBAPI methods **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,7 +179,7 @@ psyco_conn_set_isolation_level(connectionObject *self, PyObject *args)
 | 
				
			||||||
    return Py_None;
 | 
					    return Py_None;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* set_isolation_level method - switch connection isolation level */
 | 
					/* set_client_encoding method - set client encoding */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define psyco_conn_set_client_encoding_doc \
 | 
					#define psyco_conn_set_client_encoding_doc \
 | 
				
			||||||
"set_client_encoding(encoding) -- Set client encoding to ``encoding``."
 | 
					"set_client_encoding(encoding) -- Set client encoding to ``encoding``."
 | 
				
			||||||
| 
						 | 
					@ -215,7 +216,7 @@ psyco_conn_set_client_encoding(connectionObject *self, PyObject *args)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* set_isolation_level method - switch connection isolation level */
 | 
					/* get_transaction_status method - Get backend transaction status */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define psyco_conn_get_transaction_status_doc \
 | 
					#define psyco_conn_get_transaction_status_doc \
 | 
				
			||||||
"get_transaction_status() -- Get backend transaction status."
 | 
					"get_transaction_status() -- Get backend transaction status."
 | 
				
			||||||
| 
						 | 
					@ -230,6 +231,82 @@ psyco_conn_get_transaction_status(connectionObject *self, PyObject *args)
 | 
				
			||||||
    return PyInt_FromLong((long)PQtransactionStatus(self->pgconn));
 | 
					    return PyInt_FromLong((long)PQtransactionStatus(self->pgconn));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject method - allocate a new lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_conn_lobject_doc \
 | 
				
			||||||
 | 
					"cursor(oid=0, mode=0, new_oid=0, new_file=None,\n"                         \
 | 
				
			||||||
 | 
					"       lobject_factory=extensions.lobject) -- new lobject\n\n"             \
 | 
				
			||||||
 | 
					"Return a new lobject.\n\nThe ``lobject_factory`` argument can be used\n"   \
 | 
				
			||||||
 | 
					"to create non-standard lobjects by passing a class different from the\n"   \
 | 
				
			||||||
 | 
					"default. Note that the new class *should* be a sub-class of\n"             \
 | 
				
			||||||
 | 
					"`extensions.lobject`.\n\n"                                                 \
 | 
				
			||||||
 | 
					":rtype: `extensions.lobject`"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_conn_lobject(connectionObject *self, PyObject *args, PyObject *keywds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Oid oid=InvalidOid, new_oid=InvalidOid;
 | 
				
			||||||
 | 
					    char *smode = NULL, *new_file = NULL;
 | 
				
			||||||
 | 
					    int mode=0;
 | 
				
			||||||
 | 
					    PyObject *obj, *factory = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static char *kwlist[] = {"oid", "mode", "new_oid", "new_file",
 | 
				
			||||||
 | 
					                             "cursor_factory", NULL};
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|izizO", kwlist,
 | 
				
			||||||
 | 
					                                     &oid, &smode, &new_oid, &new_file, 
 | 
				
			||||||
 | 
									     &factory)) {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXC_IF_CONN_CLOSED(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Dprintf("psyco_conn_lobject: new lobject for connection at %p", self);
 | 
				
			||||||
 | 
					    Dprintf("psyco_conn_lobject:     parameters: oid = %d, mode = %s",
 | 
				
			||||||
 | 
					            oid, smode);
 | 
				
			||||||
 | 
					    Dprintf("psyco_conn_lobject:     parameters: new_oid = %d, new_file = %s",
 | 
				
			||||||
 | 
					            new_oid, new_file);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /* build a mode number out of the mode string: right now we only accept
 | 
				
			||||||
 | 
					       'r', 'w' and 'rw' (but note that 'w' implies 'rw' because PostgreSQL
 | 
				
			||||||
 | 
					       backend does that. */
 | 
				
			||||||
 | 
					    if (smode) {
 | 
				
			||||||
 | 
					        if (strncmp("rw", smode, 2) == 0)
 | 
				
			||||||
 | 
					            mode = INV_READ+INV_WRITE;
 | 
				
			||||||
 | 
					        else if (smode[0] == 'r')
 | 
				
			||||||
 | 
					           mode = INV_READ;
 | 
				
			||||||
 | 
					        else if (smode[0] == 'w')
 | 
				
			||||||
 | 
					           mode = INV_WRITE;
 | 
				
			||||||
 | 
						else if (smode[0] == 'n')
 | 
				
			||||||
 | 
						   mode = -1;
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
 | 
					                "mode should be one of 'r', 'w' or 'rw'");
 | 
				
			||||||
 | 
						    return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (factory == NULL) factory = (PyObject *)&lobjectType;
 | 
				
			||||||
 | 
					    if (new_file)
 | 
				
			||||||
 | 
					        obj = PyObject_CallFunction(factory, "Oiiis", 
 | 
				
			||||||
 | 
						    self, oid, mode, new_oid, new_file);    
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        obj = PyObject_CallFunction(factory, "Oiii",
 | 
				
			||||||
 | 
						    self, oid, mode, new_oid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (obj == NULL) return NULL;
 | 
				
			||||||
 | 
					    if (PyObject_IsInstance(obj, (PyObject *)&lobjectType) == 0) {
 | 
				
			||||||
 | 
					        PyErr_SetString(PyExc_TypeError,
 | 
				
			||||||
 | 
					            "lobject factory must be subclass of psycopg2._psycopg.lobject");
 | 
				
			||||||
 | 
					        Py_DECREF(obj);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Dprintf("psyco_conn_lobject: new lobject at %p: refcnt = %d",
 | 
				
			||||||
 | 
					            obj, obj->ob_refcnt);
 | 
				
			||||||
 | 
					    return obj;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
| 
						 | 
					@ -262,7 +339,8 @@ static struct PyMethodDef connectionObject_methods[] = {
 | 
				
			||||||
     METH_VARARGS, psyco_conn_set_client_encoding_doc},
 | 
					     METH_VARARGS, psyco_conn_set_client_encoding_doc},
 | 
				
			||||||
    {"get_transaction_status", (PyCFunction)psyco_conn_get_transaction_status,
 | 
					    {"get_transaction_status", (PyCFunction)psyco_conn_get_transaction_status,
 | 
				
			||||||
     METH_VARARGS, psyco_conn_get_transaction_status_doc},
 | 
					     METH_VARARGS, psyco_conn_get_transaction_status_doc},
 | 
				
			||||||
#endif
 | 
					    {"lobject", (PyCFunction)psyco_conn_lobject,
 | 
				
			||||||
 | 
					     METH_VARARGS|METH_KEYWORDS, psyco_conn_lobject_doc},
 | 
				
			||||||
    {NULL}
 | 
					    {NULL}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										89
									
								
								psycopg/lobject.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								psycopg/lobject.h
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,89 @@
 | 
				
			||||||
 | 
					/* lobject.h - definition for the psycopg lobject type
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2006 Federico Di Gregorio <fog@debian.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of psycopg.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef PSYCOPG_LOBJECT_H
 | 
				
			||||||
 | 
					#define PSYCOPG_LOBJECT_H 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Python.h>
 | 
				
			||||||
 | 
					#include <libpq-fe.h>
 | 
				
			||||||
 | 
					#include <libpq/libpq-fs.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "psycopg/connection.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern PyTypeObject lobjectType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    PyObject HEAD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connectionObject *conn; /* connection owning the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int closed;              /* 1 if the lobject is closed */
 | 
				
			||||||
 | 
					    int mode;                /* numeric mode, tells if lobject was opened */
 | 
				
			||||||
 | 
					    char *smode;             /* string mode if lobject was opened */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    long int mark;           /* copied from conn->mark */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Oid oid;                 /* the oid for this lobject */
 | 
				
			||||||
 | 
					    int fd;                  /* the file descriptor for file-like ops */
 | 
				
			||||||
 | 
					} lobjectObject;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					/* functions exported from lobject_int.c */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern int lobject_open(lobjectObject *self, connectionObject *conn,
 | 
				
			||||||
 | 
					                         Oid oid, int mode, Oid new_oid, char *new_file);
 | 
				
			||||||
 | 
					extern int lobject_unlink(lobjectObject *self);
 | 
				
			||||||
 | 
					extern int lobject_export(lobjectObject *self, char *filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern size_t lobject_read(lobjectObject *self, char *buf, size_t len);
 | 
				
			||||||
 | 
					extern size_t lobject_write(lobjectObject *self, char *buf, size_t len);
 | 
				
			||||||
 | 
					extern int lobject_seek(lobjectObject *self, int pos, int whence);
 | 
				
			||||||
 | 
					extern int lobject_tell(lobjectObject *self);
 | 
				
			||||||
 | 
					extern void lobject_close(lobjectObject *self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* exception-raising macros */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EXC_IF_LOBJ_CLOSED(self) \
 | 
				
			||||||
 | 
					if ((self)->closed || ((self)->conn && (self)->conn->closed)) { \
 | 
				
			||||||
 | 
					    PyErr_SetString(InterfaceError, "lobject already closed");  \
 | 
				
			||||||
 | 
					    return NULL; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define EXC_IF_LOBJ_LEVEL0(self) \
 | 
				
			||||||
 | 
					if (self->conn->isolation_level == 0) {                             \
 | 
				
			||||||
 | 
					    psyco_set_error(ProgrammingError, (PyObject*)self,              \
 | 
				
			||||||
 | 
					        "can't use a lobject outside of transactions", NULL, NULL); \
 | 
				
			||||||
 | 
					    return NULL;                                                    \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#define EXC_IF_LOBJ_UNMARKED(self) \
 | 
				
			||||||
 | 
					if (self->conn->mark != self->mark) {                  \
 | 
				
			||||||
 | 
					    psyco_set_error(ProgrammingError, (PyObject*)self, \
 | 
				
			||||||
 | 
					        "lobject isn't valid anymore", NULL, NULL);    \
 | 
				
			||||||
 | 
					    return NULL;                                       \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* !defined(PSYCOPG_LOBJECT_H) */
 | 
				
			||||||
							
								
								
									
										244
									
								
								psycopg/lobject_int.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								psycopg/lobject_int.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,244 @@
 | 
				
			||||||
 | 
					/* lobject_int.c - code used by the lobject object
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2006 Federico Di Gregorio <fog@debian.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of psycopg.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Python.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PSYCOPG_MODULE
 | 
				
			||||||
 | 
					#include "psycopg/config.h"
 | 
				
			||||||
 | 
					#include "psycopg/psycopg.h"
 | 
				
			||||||
 | 
					#include "psycopg/connection.h"
 | 
				
			||||||
 | 
					#include "psycopg/lobject.h"
 | 
				
			||||||
 | 
					#include "psycopg/pqpath.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef PSYCOPG_EXTENSIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_open - create a new/open an existing lo */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					lobject_open(lobjectObject *self, connectionObject *conn,
 | 
				
			||||||
 | 
					              Oid oid, int mode, Oid new_oid, char *new_file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pq_begin(self->conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* if the oid is InvalidOid we create a new lob before opening it
 | 
				
			||||||
 | 
					       or we import a file from the FS, depending on the value of
 | 
				
			||||||
 | 
					       new_name */
 | 
				
			||||||
 | 
					    if (oid == InvalidOid) {
 | 
				
			||||||
 | 
					        if (new_file)
 | 
				
			||||||
 | 
					            self->oid = lo_import(self->conn->pgconn, new_file);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            self->oid = lo_create(self->conn->pgconn, new_oid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Dprintf("lobject_open: large object created with oid = %d",
 | 
				
			||||||
 | 
					                self->oid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (self->oid == InvalidOid) goto end;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        mode = INV_WRITE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        self->oid = oid;
 | 
				
			||||||
 | 
					        if (mode == 0) mode = INV_READ;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* if the oid is a real one we try to open with the given mode,
 | 
				
			||||||
 | 
					       unless the mode is -1, meaning "don't open!" */
 | 
				
			||||||
 | 
					    if (mode != -1) {
 | 
				
			||||||
 | 
					        self->fd = lo_open(self->conn->pgconn, self->oid, mode);
 | 
				
			||||||
 | 
					        Dprintf("lobject_open: large object opened with fd = %d",
 | 
				
			||||||
 | 
					            self->fd);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        /* this is necessary to make sure no function that needs and
 | 
				
			||||||
 | 
						   fd is called on unopened lobjects */
 | 
				
			||||||
 | 
					        self->closed = 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 end:
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* here we check for errors before returning 0 */
 | 
				
			||||||
 | 
					    if ((self->fd == -1 && mode != -1) || self->oid == InvalidOid) {
 | 
				
			||||||
 | 
					        pq_raise(conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        /* set the mode for future reference and return */
 | 
				
			||||||
 | 
						self->mode = mode;
 | 
				
			||||||
 | 
						switch (mode) {
 | 
				
			||||||
 | 
					            case -1:
 | 
				
			||||||
 | 
					                self->smode = "n"; break;
 | 
				
			||||||
 | 
					            case INV_READ:
 | 
				
			||||||
 | 
					                self->smode = "r"; break;
 | 
				
			||||||
 | 
					            case INV_WRITE:
 | 
				
			||||||
 | 
					                self->smode = "w"; break;
 | 
				
			||||||
 | 
					            case INV_READ+INV_WRITE:
 | 
				
			||||||
 | 
					                self->smode = "rw"; break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_unlink - remove an lo from database */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					lobject_unlink(lobjectObject *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* first we make sure the lobject is closed and then we unlink */
 | 
				
			||||||
 | 
					    lobject_close(self);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pq_begin(self->conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res = lo_unlink(self->conn->pgconn, self->oid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (res == -1)
 | 
				
			||||||
 | 
					        pq_raise(self->conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_close - close an existing lo */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void
 | 
				
			||||||
 | 
					lobject_close(lobjectObject *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (self->conn->isolation_level > 0
 | 
				
			||||||
 | 
					        && self->conn->mark == self->mark) {
 | 
				
			||||||
 | 
					        if (self->fd != -1)
 | 
				
			||||||
 | 
					            lo_close(self->conn->pgconn, self->fd);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_write - write bytes to a lo */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					lobject_write(lobjectObject *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size_t written;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    written = lo_write(self->conn->pgconn, self->fd, buf, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (written < 0)
 | 
				
			||||||
 | 
					        pq_raise(self->conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    return written;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_read - read bytes from a lo */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size_t
 | 
				
			||||||
 | 
					lobject_read(lobjectObject *self, char *buf, size_t len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    size_t readed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    readed = lo_read(self->conn->pgconn, self->fd, buf, len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (readed < 0)
 | 
				
			||||||
 | 
					        pq_raise(self->conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    return readed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_seek - move the current position in the lo */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					lobject_seek(lobjectObject *self, int pos, int whence)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int where;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    where = lo_lseek(self->conn->pgconn, self->fd, pos, whence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (where < 0)
 | 
				
			||||||
 | 
					        pq_raise(self->conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    return where;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_tell - tell the current position in the lo */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					lobject_tell(lobjectObject *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int where;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    where = lo_tell(self->conn->pgconn, self->fd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (where < 0)
 | 
				
			||||||
 | 
					        pq_raise(self->conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    return where;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* lobject_export - export to a local file */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int
 | 
				
			||||||
 | 
					lobject_export(lobjectObject *self, char *filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
 | 
					    pthread_mutex_lock(&(self->conn->lock));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res = lo_export(self->conn->pgconn, self->oid, filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pthread_mutex_unlock(&(self->conn->lock));
 | 
				
			||||||
 | 
					    Py_END_ALLOW_THREADS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (res < 0)
 | 
				
			||||||
 | 
					        pq_raise(self->conn, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										389
									
								
								psycopg/lobject_type.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								psycopg/lobject_type.c
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,389 @@
 | 
				
			||||||
 | 
					/* lobject_type.c - python interface to lobject objects
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2003-2006 Federico Di Gregorio <fog@debian.org>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This file is part of psycopg.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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
 | 
				
			||||||
 | 
					 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					 * GNU General Public License for more details.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You should have received a copy of the GNU General Public Likcense
 | 
				
			||||||
 | 
					 * along with this program; if not, write to the Free Software
 | 
				
			||||||
 | 
					 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <Python.h>
 | 
				
			||||||
 | 
					#include <structmember.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PSYCOPG_MODULE
 | 
				
			||||||
 | 
					#include "psycopg/config.h"
 | 
				
			||||||
 | 
					#include "psycopg/python.h"
 | 
				
			||||||
 | 
					#include "psycopg/psycopg.h"
 | 
				
			||||||
 | 
					#include "psycopg/lobject.h"
 | 
				
			||||||
 | 
					#include "psycopg/connection.h"
 | 
				
			||||||
 | 
					#include "psycopg/microprotocols.h"
 | 
				
			||||||
 | 
					#include "psycopg/microprotocols_proto.h"
 | 
				
			||||||
 | 
					#include "psycopg/pqpath.h"
 | 
				
			||||||
 | 
					#include "pgversion.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef PSYCOPG_EXTENSIONS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** public methods **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* close method - close the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_close_doc \
 | 
				
			||||||
 | 
					"close() -- Close the lobject."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_close(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "")) return NULL;
 | 
				
			||||||
 | 
					   
 | 
				
			||||||
 | 
					    /* file-like objects can be closed multiple times and remember that
 | 
				
			||||||
 | 
					       closing the current transaction is equivalent to close all the 
 | 
				
			||||||
 | 
					       opened large objects */
 | 
				
			||||||
 | 
					    if (!self->closed
 | 
				
			||||||
 | 
					        && self->conn->isolation_level > 0
 | 
				
			||||||
 | 
						&& self->conn->mark == self->mark)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        self->closed = 1;
 | 
				
			||||||
 | 
					        lobject_close(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Dprintf("psyco_lobj_close: lobject at %p closed", self);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_INCREF(Py_None);
 | 
				
			||||||
 | 
					    return Py_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* write method - write data to the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_write_doc \
 | 
				
			||||||
 | 
					"write(str) -- Write a string to the large object."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_write(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int len, res=0;
 | 
				
			||||||
 | 
					    char *buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "s#", &buffer, &len)) return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_CLOSED(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_LEVEL0(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_UNMARKED(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((res = lobject_write(self, buffer, len)) < 0) return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return PyInt_FromLong((long)res);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* read method - read data from the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_read_doc \
 | 
				
			||||||
 | 
					"read(size=-1) -- Read at most size bytes or to the end of the large object."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_read(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int where, end, size = -1;
 | 
				
			||||||
 | 
					    char *buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "|i", &size)) return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_CLOSED(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_LEVEL0(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_UNMARKED(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (size < 0) {
 | 
				
			||||||
 | 
					        if ((where = lobject_tell(self)) < 0) return NULL;
 | 
				
			||||||
 | 
					        if ((end = lobject_seek(self, 0, SEEK_END)) < 0) return NULL;
 | 
				
			||||||
 | 
					        if (lobject_seek(self, where, SEEK_SET) < 0) return NULL;
 | 
				
			||||||
 | 
					        size = end - where;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((buffer = PyMem_Malloc(size)) == NULL) return NULL;
 | 
				
			||||||
 | 
					    if ((size = lobject_read(self, buffer, size)) < 0) {
 | 
				
			||||||
 | 
					        PyMem_Free(buffer);
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return PyString_FromStringAndSize(buffer, size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* seek method - seek in the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_seek_doc \
 | 
				
			||||||
 | 
					"seek(offset, whence=0) -- Set the lobject's current position."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_seek(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int offset, whence=0;
 | 
				
			||||||
 | 
					    int pos=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "i|i", &offset, &whence))
 | 
				
			||||||
 | 
					    	return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_CLOSED(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_LEVEL0(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_UNMARKED(self);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    if ((pos = lobject_seek(self, pos, whence)) < 0)
 | 
				
			||||||
 | 
					    	return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return PyInt_FromLong((long)pos);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* tell method - tell current position in the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_tell_doc \
 | 
				
			||||||
 | 
					"tell() -- Return the lobject's current position."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_tell(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int pos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "")) return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_CLOSED(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_LEVEL0(self);
 | 
				
			||||||
 | 
					    EXC_IF_LOBJ_UNMARKED(self);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if ((pos = lobject_tell(self)) < 0)
 | 
				
			||||||
 | 
					    	return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return PyInt_FromLong((long)pos);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* unlink method - unlink (destroy) the lobject */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_unlink_doc \
 | 
				
			||||||
 | 
					"unlink() -- Close and then remove the lobject."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_unlink(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "")) return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (lobject_unlink(self) < 0)
 | 
				
			||||||
 | 
					    	return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Py_INCREF(Py_None);
 | 
				
			||||||
 | 
					    return Py_None;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* export method - export lobject's content to given file */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define psyco_lobj_export_doc \
 | 
				
			||||||
 | 
					"export(filename) -- Export large object to given file."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					psyco_lobj_export(lobjectObject *self, PyObject *args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *filename;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "s", &filename))
 | 
				
			||||||
 | 
					    	return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (lobject_export(self, filename) < 0)
 | 
				
			||||||
 | 
					    	return NULL;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Py_INCREF(Py_None);
 | 
				
			||||||
 | 
					    return Py_None;  
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** the lobject object **/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* object method list */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct PyMethodDef lobjectObject_methods[] = {
 | 
				
			||||||
 | 
					    {"read", (PyCFunction)psyco_lobj_read,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_read_doc},
 | 
				
			||||||
 | 
					    {"write", (PyCFunction)psyco_lobj_write,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_write_doc},
 | 
				
			||||||
 | 
					    {"seek", (PyCFunction)psyco_lobj_seek,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_seek_doc},
 | 
				
			||||||
 | 
					    {"tell", (PyCFunction)psyco_lobj_tell,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_tell_doc},
 | 
				
			||||||
 | 
					    {"close", (PyCFunction)psyco_lobj_close,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_close_doc},
 | 
				
			||||||
 | 
					    {"unlink",(PyCFunction)psyco_lobj_unlink,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_unlink_doc},
 | 
				
			||||||
 | 
					    {"export",(PyCFunction)psyco_lobj_export,
 | 
				
			||||||
 | 
					     METH_VARARGS, psyco_lobj_export_doc},
 | 
				
			||||||
 | 
					    {NULL}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* object member list */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct PyMemberDef lobjectObject_members[] = {
 | 
				
			||||||
 | 
					    {"oid", T_LONG, offsetof(lobjectObject, oid), RO,
 | 
				
			||||||
 | 
					        "The backend OID associated to this lobject."},
 | 
				
			||||||
 | 
					    {"closed", T_LONG, offsetof(lobjectObject, closed), RO,
 | 
				
			||||||
 | 
					        "The if the large object is closed (no file-like methods)."},
 | 
				
			||||||
 | 
					    {"mode", T_STRING, offsetof(lobjectObject, smode), RO,
 | 
				
			||||||
 | 
					        "Open mode ('r', 'w', 'rw' or 'n')."},
 | 
				
			||||||
 | 
					    {NULL}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* initialization and finalization methods */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					lobject_setup(lobjectObject *self, connectionObject *conn,
 | 
				
			||||||
 | 
					              Oid oid, int mode, Oid new_oid, char *new_file)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Dprintf("lobject_setup: init lobject object at %p", self);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (conn->isolation_level == 0) {
 | 
				
			||||||
 | 
					        psyco_set_error(ProgrammingError, (PyObject*)self, 
 | 
				
			||||||
 | 
					            "can't use a lobject outside of transactions", NULL, NULL);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    self->conn = conn;
 | 
				
			||||||
 | 
					    self->mark = conn->mark;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_INCREF((PyObject*)self->conn);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    self->closed = 0;
 | 
				
			||||||
 | 
					    self->oid = InvalidOid;
 | 
				
			||||||
 | 
					    self->fd = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (lobject_open(self, conn, oid, mode, new_oid, new_file) == -1)
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					   Dprintf("lobject_setup: good lobject object at %p, refcnt = %d",
 | 
				
			||||||
 | 
					       self, ((PyObject *)self)->ob_refcnt);
 | 
				
			||||||
 | 
					   Dprintf("lobject_setup:    oid = %d, fd = %d", self->oid, self->fd);
 | 
				
			||||||
 | 
					   return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					lobject_dealloc(PyObject* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    lobjectObject *self = (lobjectObject *)obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lobject_close(self);
 | 
				
			||||||
 | 
					    Py_XDECREF((PyObject*)self->conn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Dprintf("lobject_dealloc: deleted lobject object at %p, refcnt = %d",
 | 
				
			||||||
 | 
					            obj, obj->ob_refcnt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    obj->ob_type->tp_free(obj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					lobject_init(PyObject *obj, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Oid oid=InvalidOid, new_oid=InvalidOid;
 | 
				
			||||||
 | 
					    int mode=0;
 | 
				
			||||||
 | 
					    char *new_file = NULL;
 | 
				
			||||||
 | 
					    PyObject *conn;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (!PyArg_ParseTuple(args, "O|iiis",
 | 
				
			||||||
 | 
					         &conn, &oid, &mode, &new_oid, &new_file))
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return lobject_setup((lobjectObject *)obj,
 | 
				
			||||||
 | 
					        (connectionObject *)conn, oid, mode, new_oid, new_file);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					lobject_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return type->tp_alloc(type, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					lobject_del(PyObject* self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    PyObject_Del(self);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyObject *
 | 
				
			||||||
 | 
					lobject_repr(lobjectObject *self)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return PyString_FromFormat(
 | 
				
			||||||
 | 
					        "<lobject object at %p; closed: %d>", self, self->closed);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* object type */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define lobjectType_doc \
 | 
				
			||||||
 | 
					"A database large object."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PyTypeObject lobjectType = {
 | 
				
			||||||
 | 
					    PyObject_HEAD_INIT(NULL)
 | 
				
			||||||
 | 
					    0,
 | 
				
			||||||
 | 
					    "psycopg2._psycopg.lobject",
 | 
				
			||||||
 | 
					    sizeof(lobjectObject),
 | 
				
			||||||
 | 
					    0,
 | 
				
			||||||
 | 
					    lobject_dealloc, /*tp_dealloc*/
 | 
				
			||||||
 | 
					    0,          /*tp_print*/  
 | 
				
			||||||
 | 
					    0,          /*tp_getattr*/
 | 
				
			||||||
 | 
					    0,          /*tp_setattr*/
 | 
				
			||||||
 | 
					    0,          /*tp_compare*/
 | 
				
			||||||
 | 
					    (reprfunc)lobject_repr, /*tp_repr*/
 | 
				
			||||||
 | 
					    0,          /*tp_as_number*/
 | 
				
			||||||
 | 
					    0,          /*tp_as_sequence*/
 | 
				
			||||||
 | 
					    0,          /*tp_as_mapping*/
 | 
				
			||||||
 | 
					    0,          /*tp_hash */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    0,          /*tp_call*/
 | 
				
			||||||
 | 
					    (reprfunc)lobject_repr, /*tp_str*/
 | 
				
			||||||
 | 
					    0,          /*tp_getattro*/
 | 
				
			||||||
 | 
					    0,          /*tp_setattro*/
 | 
				
			||||||
 | 
					    0,          /*tp_as_buffer*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
 | 
				
			||||||
 | 
					    lobjectType_doc, /*tp_doc*/
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    0,          /*tp_traverse*/
 | 
				
			||||||
 | 
					    0,          /*tp_clear*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    0,          /*tp_richcompare*/
 | 
				
			||||||
 | 
					    0,          /*tp_weaklistoffset*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    0,          /*tp_iter*/
 | 
				
			||||||
 | 
					    0,          /*tp_iternext*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Attribute descriptor and subclassing stuff */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lobjectObject_methods, /*tp_methods*/
 | 
				
			||||||
 | 
					    lobjectObject_members, /*tp_members*/
 | 
				
			||||||
 | 
					    0,          /*tp_getset*/
 | 
				
			||||||
 | 
					    0,          /*tp_base*/
 | 
				
			||||||
 | 
					    0,          /*tp_dict*/
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    0,          /*tp_descr_get*/
 | 
				
			||||||
 | 
					    0,          /*tp_descr_set*/
 | 
				
			||||||
 | 
					    0,          /*tp_dictoffset*/
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    lobject_init, /*tp_init*/
 | 
				
			||||||
 | 
					    0, /*tp_alloc  Will be set to PyType_GenericAlloc in module init*/
 | 
				
			||||||
 | 
					    lobject_new, /*tp_new*/
 | 
				
			||||||
 | 
					    (freefunc)lobject_del, /*tp_free  Low-level free-memory routine */
 | 
				
			||||||
 | 
					    0,          /*tp_is_gc For PyObject_IS_GC */
 | 
				
			||||||
 | 
					    0,          /*tp_bases*/
 | 
				
			||||||
 | 
					    0,          /*tp_mro method resolution order */
 | 
				
			||||||
 | 
					    0,          /*tp_cache*/
 | 
				
			||||||
 | 
					    0,          /*tp_subclasses*/
 | 
				
			||||||
 | 
					    0           /*tp_weaklist*/
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -416,6 +416,7 @@ pq_commit(connectionObject *conn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Py_BEGIN_ALLOW_THREADS;
 | 
					    Py_BEGIN_ALLOW_THREADS;
 | 
				
			||||||
    pthread_mutex_lock(&conn->lock);
 | 
					    pthread_mutex_lock(&conn->lock);
 | 
				
			||||||
 | 
					    conn->mark += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pq_clear_async(conn);
 | 
					    pq_clear_async(conn);
 | 
				
			||||||
    retvalue = pq_execute_command_locked(conn, "COMMIT", &pgres, &error);
 | 
					    retvalue = pq_execute_command_locked(conn, "COMMIT", &pgres, &error);
 | 
				
			||||||
| 
						 | 
					@ -446,6 +447,7 @@ pq_abort_locked(connectionObject *conn, PGresult **pgres, char **error)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    conn->mark += 1;
 | 
				
			||||||
    pq_clear_async(conn);
 | 
					    pq_clear_async(conn);
 | 
				
			||||||
    retvalue = pq_execute_command_locked(conn, "ROLLBACK", pgres, error);
 | 
					    retvalue = pq_execute_command_locked(conn, "ROLLBACK", pgres, error);
 | 
				
			||||||
    if (retvalue == 0)
 | 
					    if (retvalue == 0)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,7 @@
 | 
				
			||||||
#include "psycopg/psycopg.h"
 | 
					#include "psycopg/psycopg.h"
 | 
				
			||||||
#include "psycopg/connection.h"
 | 
					#include "psycopg/connection.h"
 | 
				
			||||||
#include "psycopg/cursor.h"
 | 
					#include "psycopg/cursor.h"
 | 
				
			||||||
 | 
					#include "psycopg/lobject.h"
 | 
				
			||||||
#include "psycopg/typecast.h"
 | 
					#include "psycopg/typecast.h"
 | 
				
			||||||
#include "psycopg/microprotocols.h"
 | 
					#include "psycopg/microprotocols.h"
 | 
				
			||||||
#include "psycopg/microprotocols_proto.h"
 | 
					#include "psycopg/microprotocols_proto.h"
 | 
				
			||||||
| 
						 | 
					@ -719,6 +720,11 @@ init_psycopg(void)
 | 
				
			||||||
    if (PyType_Ready(&listType) == -1) return;
 | 
					    if (PyType_Ready(&listType) == -1) return;
 | 
				
			||||||
    if (PyType_Ready(&chunkType) == -1) return;
 | 
					    if (PyType_Ready(&chunkType) == -1) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef PSYCOPG_EXTENSIONS
 | 
				
			||||||
 | 
					    lobjectType.ob_type    = &PyType_Type;
 | 
				
			||||||
 | 
					    if (PyType_Ready(&lobjectType) == -1) return;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_PYBOOL
 | 
					#ifdef HAVE_PYBOOL
 | 
				
			||||||
    pbooleanType.ob_type   = &PyType_Type;
 | 
					    pbooleanType.ob_type   = &PyType_Type;
 | 
				
			||||||
    if (PyType_Ready(&pbooleanType) == -1) return;
 | 
					    if (PyType_Ready(&pbooleanType) == -1) return;
 | 
				
			||||||
| 
						 | 
					@ -794,6 +800,9 @@ init_psycopg(void)
 | 
				
			||||||
    PyModule_AddObject(module, "connection", (PyObject*)&connectionType);
 | 
					    PyModule_AddObject(module, "connection", (PyObject*)&connectionType);
 | 
				
			||||||
    PyModule_AddObject(module, "cursor", (PyObject*)&cursorType);
 | 
					    PyModule_AddObject(module, "cursor", (PyObject*)&cursorType);
 | 
				
			||||||
    PyModule_AddObject(module, "ISQLQuote", (PyObject*)&isqlquoteType);
 | 
					    PyModule_AddObject(module, "ISQLQuote", (PyObject*)&isqlquoteType);
 | 
				
			||||||
 | 
					#ifdef PSYCOPG_EXTENSIONS
 | 
				
			||||||
 | 
					    PyModule_AddObject(module, "lobject", (PyObject*)&lobjectType);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* encodings dictionary in module dictionary */
 | 
					    /* encodings dictionary in module dictionary */
 | 
				
			||||||
    PyModule_AddObject(module, "encodings", psycoEncodings);
 | 
					    PyModule_AddObject(module, "encodings", psycoEncodings);
 | 
				
			||||||
| 
						 | 
					@ -820,6 +829,10 @@ init_psycopg(void)
 | 
				
			||||||
    listType.tp_alloc = PyType_GenericAlloc;
 | 
					    listType.tp_alloc = PyType_GenericAlloc;
 | 
				
			||||||
    chunkType.tp_alloc = PyType_GenericAlloc;
 | 
					    chunkType.tp_alloc = PyType_GenericAlloc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef PSYCOPG_EXTENSIONS
 | 
				
			||||||
 | 
					    lobjectType.tp_alloc = PyType_GenericAlloc;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef HAVE_PYDATETIME
 | 
					#ifdef HAVE_PYDATETIME
 | 
				
			||||||
    pydatetimeType.tp_alloc = PyType_GenericAlloc;
 | 
					    pydatetimeType.tp_alloc = PyType_GenericAlloc;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								setup.py
									
									
									
									
									
								
							| 
						 | 
					@ -326,6 +326,7 @@ sources = [
 | 
				
			||||||
    'psycopgmodule.c', 'pqpath.c',  'typecast.c',
 | 
					    'psycopgmodule.c', 'pqpath.c',  'typecast.c',
 | 
				
			||||||
    'microprotocols.c', 'microprotocols_proto.c',
 | 
					    'microprotocols.c', 'microprotocols_proto.c',
 | 
				
			||||||
    'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
 | 
					    'connection_type.c', 'connection_int.c', 'cursor_type.c', 'cursor_int.c',
 | 
				
			||||||
 | 
					    'lobject_type.c', 'lobject_int.c',
 | 
				
			||||||
    'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c',
 | 
					    'adapter_qstring.c', 'adapter_pboolean.c', 'adapter_binary.c',
 | 
				
			||||||
    'adapter_asis.c', 'adapter_list.c']
 | 
					    'adapter_asis.c', 'adapter_list.c']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user