mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-10 19:16:34 +03:00
Use lseek64 and ltell64 to support large object greater than 2gb in size.
This commit is contained in:
parent
85ba098cd8
commit
e13ec67da3
|
@ -60,8 +60,8 @@ RAISES_NEG HIDDEN int lobject_export(lobjectObject *self, const char *filename);
|
|||
RAISES_NEG HIDDEN Py_ssize_t lobject_read(lobjectObject *self, char *buf, size_t len);
|
||||
RAISES_NEG HIDDEN Py_ssize_t lobject_write(lobjectObject *self, const char *buf,
|
||||
size_t len);
|
||||
RAISES_NEG HIDDEN int lobject_seek(lobjectObject *self, int pos, int whence);
|
||||
RAISES_NEG HIDDEN int lobject_tell(lobjectObject *self);
|
||||
RAISES_NEG HIDDEN long lobject_seek(lobjectObject *self, long pos, int whence);
|
||||
RAISES_NEG HIDDEN long lobject_tell(lobjectObject *self);
|
||||
RAISES_NEG HIDDEN int lobject_truncate(lobjectObject *self, size_t len);
|
||||
RAISES_NEG HIDDEN int lobject_close(lobjectObject *self);
|
||||
|
||||
|
|
|
@ -376,21 +376,21 @@ lobject_read(lobjectObject *self, char *buf, size_t len)
|
|||
|
||||
/* lobject_seek - move the current position in the lo */
|
||||
|
||||
RAISES_NEG int
|
||||
lobject_seek(lobjectObject *self, int pos, int whence)
|
||||
RAISES_NEG long
|
||||
lobject_seek(lobjectObject *self, long pos, int whence)
|
||||
{
|
||||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
int where;
|
||||
long where;
|
||||
|
||||
Dprintf("lobject_seek: fd = %d, pos = %d, whence = %d",
|
||||
Dprintf("lobject_seek: fd = %d, pos = %Ld, whence = %d",
|
||||
self->fd, pos, whence);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&(self->conn->lock));
|
||||
|
||||
where = lo_lseek(self->conn->pgconn, self->fd, pos, whence);
|
||||
Dprintf("lobject_seek: where = %d", where);
|
||||
where = lo_lseek64(self->conn->pgconn, self->fd, pos, whence);
|
||||
Dprintf("lobject_seek: where = %Ld", where);
|
||||
if (where < 0)
|
||||
collect_error(self->conn, &error);
|
||||
|
||||
|
@ -404,20 +404,20 @@ lobject_seek(lobjectObject *self, int pos, int whence)
|
|||
|
||||
/* lobject_tell - tell the current position in the lo */
|
||||
|
||||
RAISES_NEG int
|
||||
RAISES_NEG long
|
||||
lobject_tell(lobjectObject *self)
|
||||
{
|
||||
PGresult *pgres = NULL;
|
||||
char *error = NULL;
|
||||
int where;
|
||||
long where;
|
||||
|
||||
Dprintf("lobject_tell: fd = %d", self->fd);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS;
|
||||
pthread_mutex_lock(&(self->conn->lock));
|
||||
|
||||
where = lo_tell(self->conn->pgconn, self->fd);
|
||||
Dprintf("lobject_tell: where = %d", where);
|
||||
where = lo_tell64(self->conn->pgconn, self->fd);
|
||||
Dprintf("lobject_tell: where = %Ld", where);
|
||||
if (where < 0)
|
||||
collect_error(self->conn, &error);
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ static PyObject *
|
|||
psyco_lobj_read(lobjectObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *res;
|
||||
int where, end;
|
||||
long where, end;
|
||||
Py_ssize_t size = -1;
|
||||
char *buffer;
|
||||
|
||||
|
@ -165,10 +165,10 @@ psyco_lobj_read(lobjectObject *self, PyObject *args)
|
|||
static PyObject *
|
||||
psyco_lobj_seek(lobjectObject *self, PyObject *args)
|
||||
{
|
||||
int offset, whence=0;
|
||||
int pos=0;
|
||||
long offset, pos=0;
|
||||
int whence=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i|i", &offset, &whence))
|
||||
if (!PyArg_ParseTuple(args, "l|i", &offset, &whence))
|
||||
return NULL;
|
||||
|
||||
EXC_IF_LOBJ_CLOSED(self);
|
||||
|
@ -178,7 +178,7 @@ psyco_lobj_seek(lobjectObject *self, PyObject *args)
|
|||
if ((pos = lobject_seek(self, offset, whence)) < 0)
|
||||
return NULL;
|
||||
|
||||
return PyInt_FromLong((long)pos);
|
||||
return PyLong_FromLong(pos);
|
||||
}
|
||||
|
||||
/* tell method - tell current position in the lobject */
|
||||
|
@ -189,7 +189,7 @@ psyco_lobj_seek(lobjectObject *self, PyObject *args)
|
|||
static PyObject *
|
||||
psyco_lobj_tell(lobjectObject *self, PyObject *args)
|
||||
{
|
||||
int pos;
|
||||
long pos;
|
||||
|
||||
EXC_IF_LOBJ_CLOSED(self);
|
||||
EXC_IF_LOBJ_LEVEL0(self);
|
||||
|
@ -198,7 +198,7 @@ psyco_lobj_tell(lobjectObject *self, PyObject *args)
|
|||
if ((pos = lobject_tell(self)) < 0)
|
||||
return NULL;
|
||||
|
||||
return PyInt_FromLong((long)pos);
|
||||
return PyLong_FromLong(pos);
|
||||
}
|
||||
|
||||
/* unlink method - unlink (destroy) the lobject */
|
||||
|
|
|
@ -225,6 +225,24 @@ class LargeObjectTests(LargeObjectTestCase):
|
|||
self.assertEqual(lo.seek(-2, 2), length - 2)
|
||||
self.assertEqual(lo.read(), "ta")
|
||||
|
||||
def test_seek_tell_greater_than_2gb(self):
|
||||
lo = self.conn.lobject()
|
||||
|
||||
# write chunks until its 3gb
|
||||
length = 0
|
||||
for _ in range(24):
|
||||
# each chunk is written with 128mb
|
||||
length += lo.write("data" * (1 << 25))
|
||||
self.assertEqual(lo.tell(), length)
|
||||
lo.close()
|
||||
lo = self.conn.lobject(lo.oid)
|
||||
|
||||
# seek to 3gb - 4, last written text should be data
|
||||
offset = (1 << 31) + (1 << 30) - 4 # 2gb + 1gb - 4
|
||||
self.assertEqual(lo.seek(offset, 0), offset)
|
||||
self.assertEqual(lo.tell(), offset)
|
||||
self.assertEqual(lo.read(), "data")
|
||||
|
||||
def test_unlink(self):
|
||||
lo = self.conn.lobject()
|
||||
lo.unlink()
|
||||
|
|
Loading…
Reference in New Issue
Block a user