* config.h.in (HAVE_DECL_PQFREEMEM, HAVE_DECL_PQUNESCAPEBYTEA):

Added new test markers.
        * config/postgres.m4; Add tests for new markers.
        * configure: Regenerated.
        * EOAdaptors/Postgres95/Postgres95Compatibility.h: New file.

        * EOAdaptors/Postgres95/Postgres95Adaptor.m: Change default
	data type for NSData to bytea.
        * EOAdaptors/Postgres95/Postgres95SQLExpression.m
        ([Postgres95SQLExpression formatValue:forAttribute:])
        Format bytea data.
        * EOAdaptors/Postgres95/Postgres95Values.m
        ([Postgres95Values newValueForBytesType:length:attribute:]):
        Decode bytea data.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@20042 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ayers 2004-09-09 10:40:50 +00:00
parent 77c1bef3ee
commit 6dcc4a8a7d
8 changed files with 433 additions and 11 deletions

View file

@ -1,3 +1,21 @@
2004-05-07 Simon Stapleton <simon@tufty.co.uk>
David Ayers <d.ayers@inode.at>
* config.h.in (HAVE_DECL_PQFREEMEM, HAVE_DECL_PQUNESCAPEBYTEA):
Added new test markers.
* config/postgres.m4; Add tests for new markers.
* configure: Regenerated.
* EOAdaptors/Postgres95/Postgres95Compatibility.h: New file.
* EOAdaptors/Postgres95/Postgres95Adaptor.m: Change default data
type for NSData to bytea.
* EOAdaptors/Postgres95/Postgres95SQLExpression.m
([Postgres95SQLExpression formatValue:forAttribute:])
Format bytea data.
* EOAdaptors/Postgres95/Postgres95Values.m
([Postgres95Values newValueForBytesType:length:attribute:]):
Decode bytea data.
2004-09-08 David Ayers <d.ayers@inode.at>
* EOAccess/EOAttribute.m (-[copyWithZone:]): Override

View file

@ -178,14 +178,16 @@ postgresClientVersion()
*/
static NSString *externalTypeNames[] = {
#warning (stephane@sente.ch) Needs to be updated!!!
@"numeric", @"varchar", @"bpchar", @"date",
@"numeric", @"varchar", @"bytea", @"date",
@"boolean", @"bool",
@"char", @"char2", @"char4", @"char8", @"char16", @"filename",
@"reltime", @"time", @"tinterval", @"abstime", @"timestamp",
@"real", @"double precision", @"float4", @"float8",
@"bigint", @"int8", @"int4", @"int2",
@"oid", @"oid8", @"oidint2", @"oidint4", @"oidchar16",
@"decimal", @"cid", @"tid", @"xid",
@"decimal", @"cid",
@"tid", @"xid",
@"bpchar",
nil
};
@ -197,7 +199,9 @@ static NSString *internalTypeNames[] = {
@"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber",
@"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber",
@"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber", @"NSNumber",
@"NSDecimalNumber", @"NSDecimalNumber", @"NSDecimalNumber", @"NSDecimalNumber",
@"NSDecimalNumber", @"NSDecimalNumber",
@"NSDecimalNumber", @"NSDecimalNumber",
@"NSData",
nil
};

View file

@ -0,0 +1,150 @@
/**
Postgres95Compatibility.h
Copyright (C) 2004 Free Software Foundation, Inc.
Adapted: David Ayers <d.ayers@inode.at>
Date: September 2004
$Revision$
$Date$
<abstract></abstract>
This file is part of the GNUstep Database Library.
<license>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
</license>
**/
#if !HAVE_DECL_PQFREEMEM
#define PQfreemem free
#endif
#if !HAVE_DECL_PQUNESCAPEBYTEA
#include <stdlib.h>
#include <string.h>
/*
* PQunescapeBytea - converts the null terminated string representation
* of a bytea, strtext, into binary, filling a buffer. It returns a
* pointer to the buffer which is NULL on error, and the size of the
* buffer in retbuflen. The pointer may subsequently be used as an
* argument to the function free(3). It is the reverse of PQescapeBytea.
*
* The following transformations are reversed:
* '\0' == ASCII 0 == \000
* '\'' == ASCII 39 == \'
* '\\' == ASCII 92 == \\
*
* States:
* 0 normal 0->1->2->3->4
* 1 \ 1->5
* 2 \0 1->6
* 3 \00
* 4 \000
* 5 \'
* 6 \\
*/
#define PSQL_ATTRIB_UNUSED __attribute__ ((unused))
static unsigned char *
PQunescapeBytea(unsigned char *strtext, size_t *retbuflen) PSQL_ATTRIB_UNUSED;
static unsigned char *
PQunescapeBytea(unsigned char *strtext, size_t *retbuflen)
{
size_t buflen;
unsigned char *buffer, *sp,*bp;
unsigned int state = 0;
if (strtext == NULL)
return NULL;
buflen = strlen(strtext); /* will shrink, also we discover if
* strtext */
buffer = (unsigned char *) malloc(buflen); /* isn't NULL terminated */
if (buffer == NULL)
return NULL;
for (bp = buffer, sp = strtext; *sp != '\0'; bp++, sp++)
{
switch (state)
{
case 0:
if (*sp == '\\')
state = 1;
*bp = *sp;
break;
case 1:
if (*sp == '\'') /* state=5 */
{ /* replace \' with 39 */
bp--;
*bp = '\'';
buflen--;
state = 0;
}
else if (*sp == '\\') /* state=6 */
{ /* replace \\ with 92 */
bp--;
*bp = '\\';
buflen--;
state = 0;
}
else
{
if (isdigit(*sp))
state = 2;
else
state = 0;
*bp = *sp;
}
break;
case 2:
if (isdigit(*sp))
state = 3;
else
state = 0;
*bp = *sp;
break;
case 3:
if (isdigit(*sp)) /* state=4 */
{
int v;
bp -= 3;
sscanf(sp - 2, "%03o", &v);
*bp = v;
buflen -= 3;
state = 0;
}
else
{
*bp = *sp;
state = 0;
}
break;
}
}
buffer = realloc(buffer, buflen);
if (buffer == NULL)
return NULL;
*retbuflen = buflen;
return buffer;
}
#endif

View file

@ -57,9 +57,11 @@ RCS_ID("$Id$")
#include <EOAccess/EOModel.h>
#include <EOAccess/EOSchemaGeneration.h>
#include <Postgres95EOAdaptor/Postgres95SQLExpression.h>
#include <Postgres95EOAdaptor/Postgres95Adaptor.h>
#include <Postgres95EOAdaptor/Postgres95Values.h>
#include "Postgres95SQLExpression.h"
#include "Postgres95Adaptor.h"
#include "Postgres95Values.h"
#include "Postgres95Compatibility.h"
/* These methods are undocumented but exist in GDL2 and WO4.5.
Ayers: Review (Don't rely on them) */
@ -218,6 +220,26 @@ RCS_ID("$Id$")
else
formatted = [NSString stringWithFormat: @"'%@'",value];
}
else if ([externalType isEqualToString: @"bytea"])
{
unsigned char *escapedString;
size_t newLength;
EOFLOGObjectLevelArgs(@"EOSQLExpression",
@"bytea case - value=%@ class=%@",
value, [value class]);
escapedString = PQescapeBytea ((unsigned char *)[value bytes],
[value length],
&newLength);
/* Note that the value returned in newLength is unreliable. */
formatted = [NSString stringWithFormat: @"'%s'", escapedString];
if (escapedString)
{
PQfreemem (escapedString);
}
}
else
{
int length = 0;

View file

@ -57,10 +57,11 @@ RCS_ID("$Id$")
#include <EOAccess/EOAttribute.h>
#include <EOControl/EONSAddOns.h>
#include <Postgres95EOAdaptor/Postgres95Adaptor.h>
#include <Postgres95EOAdaptor/Postgres95Channel.h>
#include <Postgres95EOAdaptor/Postgres95Values.h>
#include "Postgres95EOAdaptor/Postgres95Adaptor.h"
#include "Postgres95EOAdaptor/Postgres95Channel.h"
#include "Postgres95EOAdaptor/Postgres95Values.h"
#include "Postgres95Compatibility.h"
void __postgres95_values_linking_function (void)
{
@ -167,8 +168,23 @@ For efficiency reasons, the returned value is NOT autoreleased !
length: (int)length
attribute: (EOAttribute *)attribute
{
return [attribute newValueForBytes: bytes
length: length];
size_t newLength = length;
unsigned char *decodedBytes = 0;
id data;
if ([[attribute externalType] isEqualToString: @"bytea"])
{
decodedBytes = PQunescapeBytea((unsigned char *)bytes, &newLength);
bytes = decodedBytes;
}
data = [attribute newValueForBytes: bytes
length: newLength];
if (decodedBytes)
{
PQfreemem (decodedBytes);
}
return data;
}

View file

@ -27,6 +27,8 @@
#ifndef __config_h__
#define __config_h__
#undef HAVE_DECL_PQFREEMEM
#undef HAVE_DECL_PQUNESCAPEBYTEA
/* Define if Foundation implements KeyValueCoding. */
#define FOUNDATION_HAS_KVC 1

View file

@ -48,6 +48,14 @@ AC_DEFUN(AM_PATH_PGSQL,[
ifelse([$2], , :, [$2])
fi
if test $POSTGRES_DATABASE = yes; then
AC_CHECK_DECLS(PQfreemem, , ,[
#include <libpq-fe.h>])
AC_CHECK_DECLS(PQunescapeBytea, , ,[
#include <libpq-fe.h>])
fi
CPPFLAGS="$cppflags_temp"
LIBS="$libs_temp"

202
configure vendored
View file

@ -2617,6 +2617,208 @@ echo "${ECHO_T}no" >&6
enable_pgsql=no
fi
if test $POSTGRES_DATABASE = yes; then
echo "$as_me:$LINENO: checking whether PQfreemem is declared" >&5
echo $ECHO_N "checking whether PQfreemem is declared... $ECHO_C" >&6
if test "${ac_cv_have_decl_PQfreemem+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include <libpq-fe.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int
main ()
{
#ifndef PQfreemem
char *p = (char *) PQfreemem;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_have_decl_PQfreemem=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_have_decl_PQfreemem=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_have_decl_PQfreemem" >&5
echo "${ECHO_T}$ac_cv_have_decl_PQfreemem" >&6
if test $ac_cv_have_decl_PQfreemem = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PQFREEMEM 1
_ACEOF
else
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PQFREEMEM 0
_ACEOF
fi
echo "$as_me:$LINENO: checking whether PQunescapeBytea is declared" >&5
echo $ECHO_N "checking whether PQunescapeBytea is declared... $ECHO_C" >&6
if test "${ac_cv_have_decl_PQunescapeBytea+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include <libpq-fe.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int
main ()
{
#ifndef PQunescapeBytea
char *p = (char *) PQunescapeBytea;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_have_decl_PQunescapeBytea=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_have_decl_PQunescapeBytea=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_have_decl_PQunescapeBytea" >&5
echo "${ECHO_T}$ac_cv_have_decl_PQunescapeBytea" >&6
if test $ac_cv_have_decl_PQunescapeBytea = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PQUNESCAPEBYTEA 1
_ACEOF
else
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PQUNESCAPEBYTEA 0
_ACEOF
fi
echo "$as_me:$LINENO: checking whether PQresultStatus is declared" >&5
echo $ECHO_N "checking whether PQresultStatus is declared... $ECHO_C" >&6
if test "${ac_cv_have_decl_PQresultStatus+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include <libpq-fe.h>
#ifdef F77_DUMMY_MAIN
# ifdef __cplusplus
extern "C"
# endif
int F77_DUMMY_MAIN() { return 1; }
#endif
int
main ()
{
#ifndef PQresultStatus
char *p = (char *) PQresultStatus;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_have_decl_PQresultStatus=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_have_decl_PQresultStatus=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_have_decl_PQresultStatus" >&5
echo "${ECHO_T}$ac_cv_have_decl_PQresultStatus" >&6
if test $ac_cv_have_decl_PQresultStatus = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PQRESULTSTATUS 1
_ACEOF
else
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_PQRESULTSTATUS 0
_ACEOF
fi
fi
CPPFLAGS="$cppflags_temp"
LIBS="$libs_temp"