228 lines
3.9 KiB
C
228 lines
3.9 KiB
C
/*--------
|
|
* Module: lobj.c
|
|
*
|
|
* Description: This module contains routines related to manipulating
|
|
* large objects.
|
|
*
|
|
* Classes: none
|
|
*
|
|
* API functions: none
|
|
*
|
|
* Comments: See "readme.txt" for copyright and license information.
|
|
*--------
|
|
*/
|
|
|
|
#include "lobj.h"
|
|
|
|
#include "connection.h"
|
|
|
|
|
|
OID
|
|
odbc_lo_creat(ConnectionClass *conn, int mode)
|
|
{
|
|
LO_ARG argv[1];
|
|
Int4 retval, result_len;
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = mode;
|
|
|
|
if (!CC_send_function(conn, "lo_creat", &retval, &result_len, 1, argv, 1))
|
|
return 0; /* invalid oid */
|
|
else
|
|
return (OID) retval;
|
|
}
|
|
|
|
|
|
int
|
|
odbc_lo_open(ConnectionClass *conn, int lobjId, int mode)
|
|
{
|
|
int fd;
|
|
int result_len;
|
|
LO_ARG argv[2];
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = lobjId;
|
|
|
|
argv[1].isint = 1;
|
|
argv[1].len = 4;
|
|
argv[1].u.integer = mode;
|
|
|
|
if (!CC_send_function(conn, "lo_open", &fd, &result_len, 1, argv, 2))
|
|
return -1;
|
|
|
|
if (fd >= 0 && odbc_lo_lseek64(conn, fd, 0L, SEEK_SET) < 0)
|
|
return -1;
|
|
|
|
return fd;
|
|
}
|
|
|
|
|
|
int
|
|
odbc_lo_close(ConnectionClass *conn, int fd)
|
|
{
|
|
LO_ARG argv[1];
|
|
int retval,
|
|
result_len;
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
if (!CC_send_function(conn, "lo_close", &retval, &result_len, 1, argv, 1))
|
|
return -1;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
|
|
Int4
|
|
odbc_lo_read(ConnectionClass *conn, int fd, char *buf, Int4 len)
|
|
{
|
|
LO_ARG argv[2];
|
|
Int4 result_len;
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
argv[1].isint = 1;
|
|
argv[1].len = 4;
|
|
argv[1].u.integer = len;
|
|
|
|
if (!CC_send_function(conn, "loread", (int *) buf, &result_len, 0, argv, 2))
|
|
return -1;
|
|
else
|
|
return result_len;
|
|
}
|
|
|
|
|
|
Int4
|
|
odbc_lo_write(ConnectionClass *conn, int fd, char *buf, Int4 len)
|
|
{
|
|
LO_ARG argv[2];
|
|
Int4 retval,
|
|
result_len;
|
|
|
|
if (len <= 0)
|
|
return 0;
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
argv[1].isint = 0;
|
|
argv[1].len = len;
|
|
argv[1].u.ptr = (char *) buf;
|
|
|
|
if (!CC_send_function(conn, "lowrite", &retval, &result_len, 1, argv, 2))
|
|
return -1;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
|
|
Int4
|
|
odbc_lo_lseek(ConnectionClass *conn, int fd, int offset, Int4 whence)
|
|
{
|
|
LO_ARG argv[3];
|
|
Int4 retval,
|
|
result_len;
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
argv[1].isint = 1;
|
|
argv[1].len = 4;
|
|
argv[1].u.integer = offset;
|
|
|
|
argv[2].isint = 1;
|
|
argv[2].len = 4;
|
|
argv[2].u.integer = whence;
|
|
|
|
/* We use lo_lseek64 */
|
|
if (!CC_send_function(conn, "lo_lseek", &retval, &result_len, 1, argv, 3))
|
|
return -1;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
|
|
Int4
|
|
odbc_lo_tell(ConnectionClass *conn, int fd)
|
|
{
|
|
LO_ARG argv[1];
|
|
Int4 retval, result_len;
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
/* We use lo_tell64 */
|
|
if (!CC_send_function(conn, "lo_tell", &retval, &result_len, 1, argv, 1))
|
|
return -1;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
Int8
|
|
odbc_lo_lseek64(ConnectionClass *conn, int fd, Int8 offset, Int4 whence)
|
|
{
|
|
LO_ARG argv[3];
|
|
Int8 retval;
|
|
Int4 result_len;
|
|
|
|
if (PG_VERSION_LT(conn, 9.3))
|
|
{
|
|
Int4 offset32;
|
|
|
|
offset32 = (Int4) offset;
|
|
if (offset != (Int8) offset32)
|
|
{
|
|
CC_set_error(conn, CONN_VALUE_OUT_OF_RANGE, "large object lseek64 is unavailable for the server", __FUNCTION__);
|
|
return -1;
|
|
}
|
|
return (Int8) odbc_lo_lseek(conn, fd, offset32, whence);
|
|
}
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
argv[1].isint = 2;
|
|
argv[1].len = sizeof(offset);
|
|
argv[1].u.integer64 = offset;
|
|
|
|
argv[2].isint = 1;
|
|
argv[2].len = 4;
|
|
argv[2].u.integer = whence;
|
|
|
|
if (!CC_send_function(conn, "lo_lseek64", &retval, &result_len, 2, argv, 3))
|
|
return -1;
|
|
else
|
|
return retval;
|
|
}
|
|
|
|
|
|
Int8
|
|
odbc_lo_tell64(ConnectionClass *conn, int fd)
|
|
{
|
|
LO_ARG argv[1];
|
|
Int8 retval;
|
|
Int4 result_len;
|
|
|
|
if (PG_VERSION_LT(conn, 9.3))
|
|
return (Int8) odbc_lo_tell(conn, fd);
|
|
|
|
argv[0].isint = 1;
|
|
argv[0].len = 4;
|
|
argv[0].u.integer = fd;
|
|
|
|
if (!CC_send_function(conn, "lo_tell64", &retval, &result_len, 2, argv, 1))
|
|
return -1;
|
|
else
|
|
return retval;
|
|
}
|