mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-06-01 09:42:28 +00:00
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLValues.h/m:
Remove files. * EOAdaptors/PostgreSQLAdaptor/PostgreSQLPrivate.h/m Remove references to PostgreSQLValues. * EOAdaptors/PostgreSQLAdaptor/PostgreSQLExpression.m: Ditto. * EOAdaptors/PostgreSQLAdaptor/GNUmakefile.in: Ditto. * EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m (attrRespondsToValueClass, attrRespondsToValueTypeChar) (newValueForNumberTypeLengthAttribute) (newValueForCharactersTypeLengthAttribute) (newValueForBytesTypeLengthAttribute) (newValueForDateTypeLengthAttribute) (newValueForBytesLengthAttribute) ... to static inline functions here. (getDigits): New support function. (__dummy_function_used_for_linking) Remove link hack. (initialize): Initialize new static variables. Use new static inline functions instead of PostgreSQLValues. (newValueForDateTypeLengthAttribute): Adapt to stricter NSDate parsing behavior. (NSS_SWF): Remove macro in favor of real method name. * EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.h (encoding): New instance variable. * EOAdaptors/PostgreSQLAdaptor/PostgreSQLAdaptor.h (PostgreSQLException): Move declation for documentation. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@24298 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
5e23f34dbd
commit
3317f1cc5e
11 changed files with 386 additions and 563 deletions
31
ChangeLog
31
ChangeLog
|
@ -1,3 +1,34 @@
|
||||||
|
2006-12-31 David Ayers <ayers@fsfe.org>
|
||||||
|
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLValues.h/m:
|
||||||
|
Remove files.
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLPrivate.h/m
|
||||||
|
Remove references to PostgreSQLValues.
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLExpression.m:
|
||||||
|
Ditto.
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/GNUmakefile.in: Ditto.
|
||||||
|
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m
|
||||||
|
(attrRespondsToValueClass, attrRespondsToValueTypeChar)
|
||||||
|
(newValueForNumberTypeLengthAttribute)
|
||||||
|
(newValueForCharactersTypeLengthAttribute)
|
||||||
|
(newValueForBytesTypeLengthAttribute)
|
||||||
|
(newValueForDateTypeLengthAttribute)
|
||||||
|
(newValueForBytesLengthAttribute)
|
||||||
|
... to static inline functions here.
|
||||||
|
(getDigits): New support function.
|
||||||
|
(__dummy_function_used_for_linking) Remove link hack.
|
||||||
|
(initialize): Initialize new static variables.
|
||||||
|
Use new static inline functions instead of PostgreSQLValues.
|
||||||
|
|
||||||
|
(NSS_SWF): Remove macro in favor of real method name.
|
||||||
|
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.h
|
||||||
|
(encoding): New instance variable.
|
||||||
|
|
||||||
|
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLAdaptor.h
|
||||||
|
(PostgreSQLException): Move declation for documentation.
|
||||||
|
|
||||||
2006-12-30 David Ayers <ayers@fsfe.org>
|
2006-12-30 David Ayers <ayers@fsfe.org>
|
||||||
|
|
||||||
* EOControl/GNUmakefile: Simplify documentation declarations.
|
* EOControl/GNUmakefile: Simplify documentation declarations.
|
||||||
|
|
|
@ -42,15 +42,13 @@ PostgreSQLAdaptor.m \
|
||||||
PostgreSQLContext.m \
|
PostgreSQLContext.m \
|
||||||
PostgreSQLChannel.m \
|
PostgreSQLChannel.m \
|
||||||
PostgreSQLExpression.m \
|
PostgreSQLExpression.m \
|
||||||
PostgreSQLValues.m \
|
|
||||||
PostgreSQLPrivate.m
|
PostgreSQLPrivate.m
|
||||||
|
|
||||||
PostgreSQLEOAdaptor_HEADER_FILES = \
|
PostgreSQLEOAdaptor_HEADER_FILES = \
|
||||||
PostgreSQLAdaptor.h \
|
PostgreSQLAdaptor.h \
|
||||||
PostgreSQLContext.h \
|
PostgreSQLContext.h \
|
||||||
PostgreSQLChannel.h \
|
PostgreSQLChannel.h \
|
||||||
PostgreSQLExpression.h \
|
PostgreSQLExpression.h
|
||||||
PostgreSQLValues.h
|
|
||||||
|
|
||||||
|
|
||||||
PostgreSQLEOAdaptor_AUTOGSDOC_HEADERS = $(PostgreSQLEOAdaptor_HEADER_FILES)
|
PostgreSQLEOAdaptor_AUTOGSDOC_HEADERS = $(PostgreSQLEOAdaptor_HEADER_FILES)
|
||||||
|
|
|
@ -70,6 +70,8 @@
|
||||||
extern int
|
extern int
|
||||||
postgresClientVersion();
|
postgresClientVersion();
|
||||||
|
|
||||||
|
extern NSString *PostgreSQLException;
|
||||||
|
|
||||||
@interface PostgreSQLAdaptor : EOAdaptor
|
@interface PostgreSQLAdaptor : EOAdaptor
|
||||||
{
|
{
|
||||||
NSMutableArray *_pgConnPool;
|
NSMutableArray *_pgConnPool;
|
||||||
|
@ -103,8 +105,6 @@ postgresClientVersion();
|
||||||
- (void)setPrimaryKeySequenceNameFormat: (NSString*)format;
|
- (void)setPrimaryKeySequenceNameFormat: (NSString*)format;
|
||||||
- (NSString*)primaryKeySequenceNameFormat;
|
- (NSString*)primaryKeySequenceNameFormat;
|
||||||
|
|
||||||
extern NSString *PostgreSQLException;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* __PostgreSQLAdaptor_h__ */
|
#endif /* __PostgreSQLAdaptor_h__ */
|
||||||
|
|
|
@ -74,7 +74,6 @@ RCS_ID("$Id$")
|
||||||
#include "PostgreSQLContext.h"
|
#include "PostgreSQLContext.h"
|
||||||
#include "PostgreSQLChannel.h"
|
#include "PostgreSQLChannel.h"
|
||||||
#include "PostgreSQLExpression.h"
|
#include "PostgreSQLExpression.h"
|
||||||
#include "PostgreSQLValues.h"
|
|
||||||
|
|
||||||
#include "PostgreSQLPrivate.h"
|
#include "PostgreSQLPrivate.h"
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
BOOL _fetchBlobsOid;
|
BOOL _fetchBlobsOid;
|
||||||
NSArray *_pkAttributeArray;
|
NSArray *_pkAttributeArray;
|
||||||
int _pgVersion;
|
int _pgVersion;
|
||||||
|
NSStringEncoding encoding;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned int postgresInsertedRowOid:1;
|
unsigned int postgresInsertedRowOid:1;
|
||||||
|
|
|
@ -44,14 +44,17 @@ RCS_ID("$Id$")
|
||||||
|
|
||||||
#ifdef GNUSTEP
|
#ifdef GNUSTEP
|
||||||
#include <Foundation/NSArray.h>
|
#include <Foundation/NSArray.h>
|
||||||
|
#include <Foundation/NSAutoreleasePool.h>
|
||||||
|
#include <Foundation/NSCalendarDate.h>
|
||||||
|
#include <Foundation/NSData.h>
|
||||||
|
#include <Foundation/NSDebug.h>
|
||||||
#include <Foundation/NSDictionary.h>
|
#include <Foundation/NSDictionary.h>
|
||||||
|
#include <Foundation/NSException.h>
|
||||||
|
#include <Foundation/NSObjCRuntime.h>
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
#include <Foundation/NSSet.h>
|
#include <Foundation/NSSet.h>
|
||||||
#include <Foundation/NSObjCRuntime.h>
|
#include <Foundation/NSTimeZone.h>
|
||||||
#include <Foundation/NSUtilities.h>
|
#include <Foundation/NSUtilities.h>
|
||||||
#include <Foundation/NSException.h>
|
|
||||||
#include <Foundation/NSAutoreleasePool.h>
|
|
||||||
#include <Foundation/NSDebug.h>
|
|
||||||
#else
|
#else
|
||||||
#include <Foundation/Foundation.h>
|
#include <Foundation/Foundation.h>
|
||||||
#include <GNUstepBase/GSCategories.h>
|
#include <GNUstepBase/GSCategories.h>
|
||||||
|
@ -76,21 +79,19 @@ RCS_ID("$Id$")
|
||||||
#include "PostgreSQLAdaptor.h"
|
#include "PostgreSQLAdaptor.h"
|
||||||
#include "PostgreSQLChannel.h"
|
#include "PostgreSQLChannel.h"
|
||||||
#include "PostgreSQLContext.h"
|
#include "PostgreSQLContext.h"
|
||||||
#include "PostgreSQLValues.h"
|
|
||||||
|
|
||||||
#include "PostgreSQLPrivate.h"
|
#include "PostgreSQLPrivate.h"
|
||||||
|
|
||||||
static void __dummy_function_used_for_linking(void)
|
@interface EOAttribute (private)
|
||||||
{
|
- (Class)_valueClass;
|
||||||
extern void __postgres_values_linking_function(void);
|
- (char)_valueTypeChar;
|
||||||
|
@end
|
||||||
|
|
||||||
__postgres_values_linking_function();
|
static BOOL attrRespondsToValueClass = NO;
|
||||||
__dummy_function_used_for_linking();
|
static BOOL attrRespondsToValueTypeChar = NO;
|
||||||
}
|
|
||||||
|
|
||||||
#define EOAdaptorDebugLog(format, args...) \
|
#define EOAdaptorDebugLog(format, args...) \
|
||||||
do { if ([self isDebugEnabled]) { NSLog(format , ## args); } } while (0)
|
do { if ([self isDebugEnabled]) { NSLog(format , ## args); } } while (0)
|
||||||
#define NSS_SWF NSString stringWithFormat
|
|
||||||
|
|
||||||
static NSDictionary *
|
static NSDictionary *
|
||||||
pgResultDictionary(PGresult *pgResult)
|
pgResultDictionary(PGresult *pgResult)
|
||||||
|
@ -154,8 +155,8 @@ pgResultDictionary(PGresult *pgResult)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSString *fmt;
|
NSString *fmt;
|
||||||
fmt = [NSS_SWF: @"%%%ds", PQgetlength(pgResult, i, j)];
|
fmt = [NSString stringWithFormat: @"%%%ds", PQgetlength(pgResult, i, j)];
|
||||||
tupleInfo = [NSS_SWF: fmt, PQgetvalue(pgResult, i, j)];
|
tupleInfo = [NSString stringWithFormat: fmt, PQgetvalue(pgResult, i, j)];
|
||||||
}
|
}
|
||||||
[tuple setObject: tupleInfo forKey: tupleKey];
|
[tuple setObject: tupleInfo forKey: tupleKey];
|
||||||
}
|
}
|
||||||
|
@ -165,21 +166,315 @@ pgResultDictionary(PGresult *pgResult)
|
||||||
statusType = PQresultStatus(pgResult);
|
statusType = PQresultStatus(pgResult);
|
||||||
|
|
||||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
[NSS_SWF:@"%d", statusType], @"PQresultStatus",
|
[NSString stringWithFormat:@"%d", statusType], @"PQresultStatus",
|
||||||
[NSS_SWF:@"%s", PQresStatus(statusType)], @"PQresStatus",
|
[NSString stringWithFormat:@"%s", PQresStatus(statusType)], @"PQresStatus",
|
||||||
[NSS_SWF:@"%s", PQresultErrorMessage(pgResult)], @"PQresultErrorMessage",
|
[NSString stringWithFormat:@"%s", PQresultErrorMessage(pgResult)], @"PQresultErrorMessage",
|
||||||
[NSS_SWF:@"%d", ntuples], @"PQntuples",
|
[NSString stringWithFormat:@"%d", ntuples], @"PQntuples",
|
||||||
[NSS_SWF:@"%d", nfields], @"PQnfields",
|
[NSString stringWithFormat:@"%d", nfields], @"PQnfields",
|
||||||
[NSS_SWF:@"%d", PQbinaryTuples(pgResult)], @"PQbinaryTuples",
|
[NSString stringWithFormat:@"%d", PQbinaryTuples(pgResult)], @"PQbinaryTuples",
|
||||||
[NSS_SWF:@"%s", PQcmdStatus(pgResult)], @"PQcmdStatus",
|
[NSString stringWithFormat:@"%s", PQcmdStatus(pgResult)], @"PQcmdStatus",
|
||||||
[NSS_SWF:@"%s", PQoidStatus(pgResult)], @"PQoidStatus",
|
[NSString stringWithFormat:@"%s", PQoidStatus(pgResult)], @"PQoidStatus",
|
||||||
[NSS_SWF:@"%d", PQoidValue(pgResult)], @"PQoidValue",
|
[NSString stringWithFormat:@"%d", PQoidValue(pgResult)], @"PQoidValue",
|
||||||
[NSS_SWF:@"%s", PQcmdTuples(pgResult)], @"PQcmdTuples",
|
[NSString stringWithFormat:@"%s", PQcmdTuples(pgResult)], @"PQcmdTuples",
|
||||||
tuples, @"tuples",
|
tuples, @"tuples",
|
||||||
fields, @"fields",
|
fields, @"fields",
|
||||||
nil];
|
nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read up to the specified number of characters, terminating at a non-digit
|
||||||
|
* except for leading whitespace characters.
|
||||||
|
*/
|
||||||
|
static inline int getDigits(const char *from, char *to, int limit, BOOL *error)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
BOOL foundDigit = NO;
|
||||||
|
|
||||||
|
while (i < limit)
|
||||||
|
{
|
||||||
|
if (isdigit(from[i]))
|
||||||
|
{
|
||||||
|
to[j++] = from[i];
|
||||||
|
foundDigit = YES;
|
||||||
|
}
|
||||||
|
else if (isspace(from[i]))
|
||||||
|
{
|
||||||
|
if (foundDigit == YES)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
to[j] = '\0';
|
||||||
|
if (j == 0)
|
||||||
|
{
|
||||||
|
*error = YES; // No digits read
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static id
|
||||||
|
newValueForNumberTypeLengthAttribute(const void *bytes,
|
||||||
|
int length,
|
||||||
|
EOAttribute *attribute,
|
||||||
|
NSStringEncoding encoding)
|
||||||
|
{
|
||||||
|
id value = nil;
|
||||||
|
NSString* externalType=nil;
|
||||||
|
|
||||||
|
externalType=[attribute externalType];
|
||||||
|
|
||||||
|
if (length==1 // avoid -isEqualToString if we can :-)
|
||||||
|
&& [externalType isEqualToString: @"bool"])
|
||||||
|
{
|
||||||
|
if (((char *)bytes)[0] == 't' && ((char *)bytes)[1] == 0)
|
||||||
|
value=RETAIN(PSQLA_NSNumberBool_Yes);
|
||||||
|
else if (((char *)bytes)[0] == 'f' && ((char *)bytes)[1] == 0)
|
||||||
|
value=RETAIN(PSQLA_NSNumberBool_No);
|
||||||
|
else
|
||||||
|
NSCAssert1(NO, @"Bad boolean: %@",
|
||||||
|
AUTORELEASE([[NSString alloc] initWithBytes: bytes
|
||||||
|
length: length
|
||||||
|
encoding: encoding]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Class valueClass = attrRespondsToValueClass
|
||||||
|
? [attribute _valueClass]
|
||||||
|
: NSClassFromString ([attribute valueClassName]);
|
||||||
|
|
||||||
|
if (valueClass==PSQLA_NSDecimalNumberClass)
|
||||||
|
{
|
||||||
|
//TODO: Optimize without creating NSString instance
|
||||||
|
NSString* str = [PSQLA_alloc(NSString) initWithCString:bytes
|
||||||
|
length:length];
|
||||||
|
|
||||||
|
value = [PSQLA_alloc(NSDecimalNumber) initWithString: str];
|
||||||
|
|
||||||
|
RELEASE(str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char valueTypeChar = attrRespondsToValueTypeChar
|
||||||
|
? [attribute _valueTypeChar]
|
||||||
|
: [[attribute valueType] cString][0];
|
||||||
|
switch(valueTypeChar)
|
||||||
|
{
|
||||||
|
case 'i':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithInt: atoi(bytes)];
|
||||||
|
break;
|
||||||
|
case 'I':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithUnsignedInt:(unsigned int)atol(bytes)];
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithChar: atoi(bytes)];
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithUnsignedChar: (unsigned char)atoi(bytes)];
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithShort: (short)atoi(bytes)];
|
||||||
|
break;
|
||||||
|
case 'S':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithUnsignedShort: (unsigned short)atoi(bytes)];
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithLong: atol(bytes)];
|
||||||
|
break;
|
||||||
|
case 'L':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithUnsignedLong:strtoul(bytes,NULL,10)];
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithLongLong:atoll(bytes)];
|
||||||
|
break;
|
||||||
|
case 'U':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithUnsignedLongLong:strtoull(bytes,NULL,10)];
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithFloat: (float)strtod(bytes,NULL)];
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case '\0':
|
||||||
|
value = [PSQLA_alloc(NSNumber) initWithDouble: strtod(bytes,NULL)];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NSCAssert2(NO,@"Unknown attribute valueTypeChar: %c for attribute: %@",
|
||||||
|
valueTypeChar,attribute);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static id
|
||||||
|
newValueForCharactersTypeLengthAttribute (const void *bytes,
|
||||||
|
int length,
|
||||||
|
EOAttribute *attribute,
|
||||||
|
NSStringEncoding encoding)
|
||||||
|
{
|
||||||
|
return [attribute newValueForBytes: bytes
|
||||||
|
length: length
|
||||||
|
encoding: encoding];
|
||||||
|
}
|
||||||
|
|
||||||
|
static id
|
||||||
|
newValueForBytesTypeLengthAttribute (const void *bytes,
|
||||||
|
int length,
|
||||||
|
EOAttribute *attribute,
|
||||||
|
NSStringEncoding encoding)
|
||||||
|
{
|
||||||
|
size_t newLength = length;
|
||||||
|
unsigned char *decodedBytes = 0;
|
||||||
|
id data = nil;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static id
|
||||||
|
newValueForDateTypeLengthAttribute (const void *bytes,
|
||||||
|
int length,
|
||||||
|
EOAttribute *attribute,
|
||||||
|
NSStringEncoding encoding)
|
||||||
|
{
|
||||||
|
int year = 0;
|
||||||
|
unsigned month = 0;
|
||||||
|
unsigned day = 0;
|
||||||
|
unsigned hour = 0;
|
||||||
|
unsigned minute = 0;
|
||||||
|
unsigned second = 0;
|
||||||
|
unsigned millisecond = 0;
|
||||||
|
int tz = 0;
|
||||||
|
NSTimeZone *timezone = nil;
|
||||||
|
NSCalendarDate *date = nil;
|
||||||
|
const char *str = bytes;
|
||||||
|
BOOL error;
|
||||||
|
|
||||||
|
/* We assume ISO date format:
|
||||||
|
2006-12-31 00:45:21.2531419+01
|
||||||
|
012345678911234567892123456789
|
||||||
|
where the milliseconds have variable length. */
|
||||||
|
if (length > 3)
|
||||||
|
{
|
||||||
|
char tmpString[5];
|
||||||
|
getDigits(&str[0],tmpString,4,&error);
|
||||||
|
year = atoi(tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 6)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
getDigits(&str[5],tmpString,2,&error);
|
||||||
|
month = atoi(tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 9)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
getDigits(&str[8],tmpString,2,&error);
|
||||||
|
day = atoi(tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 12)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
getDigits(&str[11],tmpString,2,&error);
|
||||||
|
hour = atoi(tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 15)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
getDigits(&str[14],tmpString,2,&error);
|
||||||
|
minute = atoi(tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 18)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
getDigits(&str[17],tmpString,2,&error);
|
||||||
|
second = atoi(tmpString);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 18)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
getDigits(&str[17],tmpString,2,&error);
|
||||||
|
second = atoi(tmpString);
|
||||||
|
}
|
||||||
|
if (length > 19)
|
||||||
|
{
|
||||||
|
char tmpString[8];
|
||||||
|
tz = getDigits(&str[17],tmpString,7,&error);
|
||||||
|
second = atoi(tmpString);
|
||||||
|
}
|
||||||
|
if (tz)
|
||||||
|
{
|
||||||
|
char tmpString[3];
|
||||||
|
int sign = (str[tz]) == '-' ? -1 : 1;
|
||||||
|
getDigits(&str[tz+1],tmpString,2,&error);
|
||||||
|
tz = atoi(tmpString);
|
||||||
|
if (tz < 100) tz *= 100;
|
||||||
|
tz = sign * ((tz / 100) * 60 + (tz % 100)) * 60;
|
||||||
|
timezone = [NSTimeZone timeZoneForSecondsFromGMT: tz];
|
||||||
|
}
|
||||||
|
|
||||||
|
date = [attribute newDateForYear: year
|
||||||
|
month: month
|
||||||
|
day: day
|
||||||
|
hour: hour
|
||||||
|
minute: minute
|
||||||
|
second: second
|
||||||
|
millisecond: millisecond
|
||||||
|
timezone: timezone
|
||||||
|
zone: 0];
|
||||||
|
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
static id
|
||||||
|
newValueForBytesLengthAttribute (const void *bytes,
|
||||||
|
int length,
|
||||||
|
EOAttribute *attribute,
|
||||||
|
NSStringEncoding encoding)
|
||||||
|
{
|
||||||
|
switch ([attribute adaptorValueType])
|
||||||
|
{
|
||||||
|
case EOAdaptorNumberType:
|
||||||
|
return newValueForNumberTypeLengthAttribute(bytes, length, attribute, encoding);
|
||||||
|
case EOAdaptorCharactersType:
|
||||||
|
return newValueForCharactersTypeLengthAttribute(bytes, length, attribute, encoding);
|
||||||
|
case EOAdaptorBytesType:
|
||||||
|
return newValueForBytesTypeLengthAttribute(bytes, length, attribute, encoding);
|
||||||
|
case EOAdaptorDateType:
|
||||||
|
return newValueForDateTypeLengthAttribute(bytes, length, attribute, encoding);
|
||||||
|
default:
|
||||||
|
NSCAssert2(NO,
|
||||||
|
@"Bad (%d) adaptor type for attribute : %@",
|
||||||
|
(int)[attribute adaptorValueType],attribute);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@implementation PostgreSQLChannel
|
@implementation PostgreSQLChannel
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
|
@ -187,10 +482,14 @@ pgResultDictionary(PGresult *pgResult)
|
||||||
static BOOL initialized=NO;
|
static BOOL initialized=NO;
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
{
|
{
|
||||||
Class aClass=Nil;
|
|
||||||
PSQLA_PrivInit();
|
PSQLA_PrivInit();
|
||||||
|
|
||||||
aClass=[PostgreSQLValues class]; // Force Initialize;
|
attrRespondsToValueClass
|
||||||
|
= [EOAttribute instancesRespondToSelector: @selector(_valueClass)];
|
||||||
|
attrRespondsToValueTypeChar
|
||||||
|
= [EOAttribute instancesRespondToSelector: @selector(_valueTypeChar)];
|
||||||
|
|
||||||
|
initialized = YES;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -230,6 +529,8 @@ pgResultDictionary(PGresult *pgResult)
|
||||||
|
|
||||||
ASSIGN(_pkAttributeArray, [NSArray arrayWithObject: attr]);
|
ASSIGN(_pkAttributeArray, [NSArray arrayWithObject: attr]);
|
||||||
RELEASE(attr);
|
RELEASE(attr);
|
||||||
|
//TODO: set encoding via connection dictionary and use throught adaptor.
|
||||||
|
encoding = [NSString defaultCStringEncoding];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -366,8 +667,9 @@ pgResultDictionary(PGresult *pgResult)
|
||||||
{
|
{
|
||||||
char *szName = PQfname(res,i);
|
char *szName = PQfname(res,i);
|
||||||
unsigned length = szName ? strlen(szName) : 0;
|
unsigned length = szName ? strlen(szName) : 0;
|
||||||
NSString *name = [(PSQLA_alloc(NSString)) initWithCString: szName
|
NSString *name = [(PSQLA_alloc(NSString)) initWithBytes: szName
|
||||||
length: length];
|
length: length
|
||||||
|
encoding: encoding];
|
||||||
PSQLA_AddObjectWithImpPtr(names,&namesAO,name);
|
PSQLA_AddObjectWithImpPtr(names,&namesAO,name);
|
||||||
RELEASE(name);
|
RELEASE(name);
|
||||||
}
|
}
|
||||||
|
@ -472,8 +774,8 @@ zone:zone
|
||||||
{
|
{
|
||||||
string = [self _readBinaryDataRow: (Oid)atol(string)
|
string = [self _readBinaryDataRow: (Oid)atol(string)
|
||||||
length:&length zone: zone];
|
length:&length zone: zone];
|
||||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
|
||||||
values[i] = PSQLA_PostgreSQLValues_newValueForBytesLengthAttribute(string,length,attr);
|
values[i] = newValueForBytesLengthAttribute(string,length,attr,encoding);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -491,7 +793,7 @@ zone:zone
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||||
values[i] = PSQLA_PostgreSQLValues_newValueForBytesLengthAttribute(string,length,attr);
|
values[i] = newValueForBytesLengthAttribute(string,length,attr,encoding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,11 +811,15 @@ zone:zone
|
||||||
forAttributes: _attributes
|
forAttributes: _attributes
|
||||||
zone: zone];
|
zone: zone];
|
||||||
|
|
||||||
/* NO: For efficiency reasons, the returned value is NOT autoreleased !
|
/* The caller of newValue methods/funnction is
|
||||||
|
responsible for releasing the values. An adaptor can
|
||||||
|
optimize allocation by taking that into account yet
|
||||||
|
the retain balance must be kept. */
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
[values[i] release];
|
{
|
||||||
*/
|
[values[i] release];
|
||||||
|
}
|
||||||
|
|
||||||
if (values != valueBuffer)
|
if (values != valueBuffer)
|
||||||
NSZoneFree(zone, values);
|
NSZoneFree(zone, values);
|
||||||
|
|
||||||
|
@ -1577,7 +1883,7 @@ each key
|
||||||
[entity setClassName: @"EOGenericRecord"];
|
[entity setClassName: @"EOGenericRecord"];
|
||||||
[model addEntity: entity];
|
[model addEntity: entity];
|
||||||
|
|
||||||
stmt = [NSS_SWF: @"SELECT oid FROM pg_class "
|
stmt = [NSString stringWithFormat: @"SELECT oid FROM pg_class "
|
||||||
@"WHERE relname = '%@' AND relkind = 'r'",tableName];
|
@"WHERE relname = '%@' AND relkind = 'r'",tableName];
|
||||||
|
|
||||||
EOAdaptorDebugLog(@"PostgreSQLAdaptor: execute command:\n%@", stmt);
|
EOAdaptorDebugLog(@"PostgreSQLAdaptor: execute command:\n%@", stmt);
|
||||||
|
@ -1601,7 +1907,7 @@ each key
|
||||||
tableOid = [NSString stringWithCString: PQgetvalue(_pgResult,0,0)];
|
tableOid = [NSString stringWithCString: PQgetvalue(_pgResult,0,0)];
|
||||||
[entity setUserInfo: [NSDictionary dictionaryWithObject:tableOid
|
[entity setUserInfo: [NSDictionary dictionaryWithObject:tableOid
|
||||||
forKey: @"tableOid"]];
|
forKey: @"tableOid"]];
|
||||||
stmt = [NSS_SWF: @"SELECT attname,typname,attnum "
|
stmt = [NSString stringWithFormat: @"SELECT attname,typname,attnum "
|
||||||
@"FROM pg_attribute LEFT JOIN pg_type ON atttypid = oid "
|
@"FROM pg_attribute LEFT JOIN pg_type ON atttypid = oid "
|
||||||
@"WHERE attnum > 0 AND attrelid=%@"
|
@"WHERE attnum > 0 AND attrelid=%@"
|
||||||
@"AND attisdropped IS FALSE", tableOid];
|
@"AND attisdropped IS FALSE", tableOid];
|
||||||
|
@ -1679,7 +1985,7 @@ each key
|
||||||
PQclear(_pgResult);
|
PQclear(_pgResult);
|
||||||
|
|
||||||
/* Determint primary key. */
|
/* Determint primary key. */
|
||||||
stmt = [NSS_SWF: @"SELECT indkey FROM pg_index "
|
stmt = [NSString stringWithFormat: @"SELECT indkey FROM pg_index "
|
||||||
@"WHERE indrelid='%@' AND indisprimary = 't'",
|
@"WHERE indrelid='%@' AND indisprimary = 't'",
|
||||||
tableOid];
|
tableOid];
|
||||||
|
|
||||||
|
@ -1692,7 +1998,7 @@ each key
|
||||||
pkAttNum = [pkAttNum stringByReplacingString:@" "
|
pkAttNum = [pkAttNum stringByReplacingString:@" "
|
||||||
withString: @", "];
|
withString: @", "];
|
||||||
|
|
||||||
stmt = [NSS_SWF: @"SELECT attname FROM pg_attribute "
|
stmt = [NSString stringWithFormat: @"SELECT attname FROM pg_attribute "
|
||||||
@"WHERE attrelid='%@' and attnum in (%@)",
|
@"WHERE attrelid='%@' and attnum in (%@)",
|
||||||
tableOid, pkAttNum];
|
tableOid, pkAttNum];
|
||||||
PQclear(_pgResult);
|
PQclear(_pgResult);
|
||||||
|
@ -1742,7 +2048,7 @@ each key
|
||||||
unsigned int i, j, n, m;
|
unsigned int i, j, n, m;
|
||||||
|
|
||||||
tableOid = [[entity userInfo] objectForKey: @"tableOid"];
|
tableOid = [[entity userInfo] objectForKey: @"tableOid"];
|
||||||
stmt = [NSS_SWF: @"SELECT tgargs FROM pg_trigger "
|
stmt = [NSString stringWithFormat: @"SELECT tgargs FROM pg_trigger "
|
||||||
@"WHERE tgtype=21 AND tgisconstraint='t' AND tgrelid=%@",
|
@"WHERE tgtype=21 AND tgisconstraint='t' AND tgrelid=%@",
|
||||||
tableOid];
|
tableOid];
|
||||||
|
|
||||||
|
@ -1786,14 +2092,14 @@ each key
|
||||||
srcEntity = [model entityNamed: srcEntityName];
|
srcEntity = [model entityNamed: srcEntityName];
|
||||||
dstEntity = [model entityNamed: dstEntityName];
|
dstEntity = [model entityNamed: dstEntityName];
|
||||||
|
|
||||||
relationshipName = [NSS_SWF:@"to%@", dstEntityName];
|
relationshipName = [NSString stringWithFormat:@"to%@", dstEntityName];
|
||||||
|
|
||||||
for (j = 1;
|
for (j = 1;
|
||||||
([srcEntity anyAttributeNamed: relationshipName] != nil ||
|
([srcEntity anyAttributeNamed: relationshipName] != nil ||
|
||||||
[srcEntity anyRelationshipNamed: relationshipName] != nil);
|
[srcEntity anyRelationshipNamed: relationshipName] != nil);
|
||||||
j++)
|
j++)
|
||||||
{
|
{
|
||||||
relationshipName = [NSS_SWF:@"to%@_%d", dstEntityName, j];
|
relationshipName = [NSString stringWithFormat:@"to%@_%d", dstEntityName, j];
|
||||||
}
|
}
|
||||||
|
|
||||||
relationship = AUTORELEASE([EORelationship new]);
|
relationship = AUTORELEASE([EORelationship new]);
|
||||||
|
@ -1917,7 +2223,7 @@ each key
|
||||||
- (NSArray *)describeDatabaseNames
|
- (NSArray *)describeDatabaseNames
|
||||||
{
|
{
|
||||||
NSMutableArray *databaseNames = [NSMutableArray array];
|
NSMutableArray *databaseNames = [NSMutableArray array];
|
||||||
NSString *stmt = [NSS_SWF:@"SELECT datname FROM pg_database LEFT JOIN pg_user "
|
NSString *stmt = [NSString stringWithFormat:@"SELECT datname FROM pg_database LEFT JOIN pg_user "
|
||||||
@"ON datdba = usesysid ORDER BY 1"];
|
@"ON datdba = usesysid ORDER BY 1"];
|
||||||
int i;
|
int i;
|
||||||
_pgResult = PQexec(_pgConn, [stmt cString]);
|
_pgResult = PQexec(_pgConn, [stmt cString]);
|
||||||
|
@ -1930,7 +2236,7 @@ each key
|
||||||
|
|
||||||
- (BOOL) userNameIsAdministrative:(NSString *)userName
|
- (BOOL) userNameIsAdministrative:(NSString *)userName
|
||||||
{
|
{
|
||||||
NSString *stmt = [NSS_SWF:@"SELECT usecreatedb FROM pg_user WHERE "
|
NSString *stmt = [NSString stringWithFormat:@"SELECT usecreatedb FROM pg_user WHERE "
|
||||||
@"usename = '%@'",userName];
|
@"usename = '%@'",userName];
|
||||||
_pgResult = PQexec(_pgConn, [stmt cString]);
|
_pgResult = PQexec(_pgConn, [stmt cString]);
|
||||||
if (_pgResult != NULL)
|
if (_pgResult != NULL)
|
||||||
|
@ -2013,7 +2319,7 @@ each key
|
||||||
length = PQgetlength(_pgResult, _currentResultRow, 0);
|
length = PQgetlength(_pgResult, _currentResultRow, 0);
|
||||||
|
|
||||||
attr = [_pkAttributeArray objectAtIndex: 0];
|
attr = [_pkAttributeArray objectAtIndex: 0];
|
||||||
pkValue = AUTORELEASE(PSQLA_PostgreSQLValues_newValueForBytesLengthAttribute(string,length,attr));
|
pkValue = AUTORELEASE(newValueForBytesLengthAttribute(string,length,attr,encoding));
|
||||||
|
|
||||||
NSAssert(pkValue, @"no pk value");
|
NSAssert(pkValue, @"no pk value");
|
||||||
key = [[entity primaryKeyAttributeNames] objectAtIndex: 0];
|
key = [[entity primaryKeyAttributeNames] objectAtIndex: 0];
|
||||||
|
|
|
@ -63,7 +63,6 @@ RCS_ID("$Id$")
|
||||||
|
|
||||||
#include "PostgreSQLExpression.h"
|
#include "PostgreSQLExpression.h"
|
||||||
#include "PostgreSQLAdaptor.h"
|
#include "PostgreSQLAdaptor.h"
|
||||||
#include "PostgreSQLValues.h"
|
|
||||||
|
|
||||||
#include "PostgreSQLCompatibility.h"
|
#include "PostgreSQLCompatibility.h"
|
||||||
#include "PostgreSQLPrivate.h"
|
#include "PostgreSQLPrivate.h"
|
||||||
|
|
|
@ -38,7 +38,6 @@ extern Class PSQLA_NSCalendarDateClass;
|
||||||
extern Class PSQLA_NSDateClass;
|
extern Class PSQLA_NSDateClass;
|
||||||
extern Class PSQLA_NSMutableArrayClass;
|
extern Class PSQLA_NSMutableArrayClass;
|
||||||
extern Class PSQLA_EOAttributeClass;
|
extern Class PSQLA_EOAttributeClass;
|
||||||
extern Class PSQLA_PostgreSQLValuesClass;
|
|
||||||
|
|
||||||
// ==== IMPs ====
|
// ==== IMPs ====
|
||||||
extern IMP PSQLA_NSNumber_allocWithZoneIMP;
|
extern IMP PSQLA_NSNumber_allocWithZoneIMP;
|
||||||
|
@ -47,7 +46,6 @@ extern IMP PSQLA_NSString_allocWithZoneIMP;
|
||||||
extern IMP PSQLA_NSCalendarDate_allocWithZoneIMP;
|
extern IMP PSQLA_NSCalendarDate_allocWithZoneIMP;
|
||||||
extern IMP PSQLA_NSMutableArray_allocWithZoneIMP;
|
extern IMP PSQLA_NSMutableArray_allocWithZoneIMP;
|
||||||
extern IMP PSQLA_EOAttribute_allocWithZoneIMP;
|
extern IMP PSQLA_EOAttribute_allocWithZoneIMP;
|
||||||
extern IMP PSQLA_PostgreSQLValues_newValueForBytesLengthAttributeIMP;
|
|
||||||
|
|
||||||
// ==== Constants ====
|
// ==== Constants ====
|
||||||
extern NSNumber *PSQLA_NSNumberBool_Yes;
|
extern NSNumber *PSQLA_NSNumberBool_Yes;
|
||||||
|
@ -71,16 +69,6 @@ _isNilOrEONull(id obj)
|
||||||
return (obj == nil || obj == PSQLA_EONull) ? YES : NO;
|
return (obj == nil || obj == PSQLA_EONull) ? YES : NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- PostgreSQLValues newValueForBytes:length:attribute ----
|
|
||||||
#define PSQLA_PostgreSQLValues_newValueForBytesLengthAttribute(bytes, \
|
|
||||||
length, \
|
|
||||||
attribute) \
|
|
||||||
(*PSQLA_PostgreSQLValues_newValueForBytesLengthAttributeIMP) \
|
|
||||||
(PSQLA_PostgreSQLValuesClass, \
|
|
||||||
@selector(newValueForBytes:length:attribute:), \
|
|
||||||
(bytes), (length), (attribute))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ---- NSEnumerator nextObject ----
|
// ---- NSEnumerator nextObject ----
|
||||||
static inline id
|
static inline id
|
||||||
|
|
|
@ -44,8 +44,6 @@ RCS_ID("$Id$")
|
||||||
#include <EOControl/EONull.h>
|
#include <EOControl/EONull.h>
|
||||||
#include <EOAccess/EOAttribute.h>
|
#include <EOAccess/EOAttribute.h>
|
||||||
|
|
||||||
#include "PostgreSQLValues.h"
|
|
||||||
|
|
||||||
// ==== Classes ====
|
// ==== Classes ====
|
||||||
Class PSQLA_NSStringClass=Nil;
|
Class PSQLA_NSStringClass=Nil;
|
||||||
Class PSQLA_NSNumberClass=Nil;
|
Class PSQLA_NSNumberClass=Nil;
|
||||||
|
@ -54,7 +52,6 @@ Class PSQLA_NSCalendarDateClass=Nil;
|
||||||
Class PSQLA_NSDateClass=Nil;
|
Class PSQLA_NSDateClass=Nil;
|
||||||
Class PSQLA_NSMutableArrayClass;
|
Class PSQLA_NSMutableArrayClass;
|
||||||
Class PSQLA_EOAttributeClass=Nil;
|
Class PSQLA_EOAttributeClass=Nil;
|
||||||
Class PSQLA_PostgreSQLValuesClass=Nil;
|
|
||||||
|
|
||||||
// ==== IMPs ====
|
// ==== IMPs ====
|
||||||
IMP PSQLA_NSNumber_allocWithZoneIMP=NULL;
|
IMP PSQLA_NSNumber_allocWithZoneIMP=NULL;
|
||||||
|
@ -63,7 +60,6 @@ IMP PSQLA_NSString_allocWithZoneIMP=NULL;
|
||||||
IMP PSQLA_NSCalendarDate_allocWithZoneIMP=NULL;
|
IMP PSQLA_NSCalendarDate_allocWithZoneIMP=NULL;
|
||||||
IMP PSQLA_NSMutableArray_allocWithZoneIMP=NULL;
|
IMP PSQLA_NSMutableArray_allocWithZoneIMP=NULL;
|
||||||
IMP PSQLA_EOAttribute_allocWithZoneIMP=NULL;
|
IMP PSQLA_EOAttribute_allocWithZoneIMP=NULL;
|
||||||
IMP PSQLA_PostgreSQLValues_newValueForBytesLengthAttributeIMP=NULL;
|
|
||||||
|
|
||||||
// ==== Constants ====
|
// ==== Constants ====
|
||||||
NSNumber *PSQLA_NSNumberBool_Yes=nil;
|
NSNumber *PSQLA_NSNumberBool_Yes=nil;
|
||||||
|
@ -90,7 +86,6 @@ PSQLA_PrivInit(void)
|
||||||
PSQLA_NSCalendarDateClass=[NSCalendarDate class];
|
PSQLA_NSCalendarDateClass=[NSCalendarDate class];
|
||||||
PSQLA_NSDateClass=[NSDate class];
|
PSQLA_NSDateClass=[NSDate class];
|
||||||
PSQLA_EOAttributeClass = [EOAttribute class];
|
PSQLA_EOAttributeClass = [EOAttribute class];
|
||||||
PSQLA_PostgreSQLValuesClass = [PostgreSQLValues class];
|
|
||||||
|
|
||||||
// ==== IMPs ====
|
// ==== IMPs ====
|
||||||
PSQLA_NSNumber_allocWithZoneIMP=
|
PSQLA_NSNumber_allocWithZoneIMP=
|
||||||
|
@ -111,8 +106,6 @@ PSQLA_PrivInit(void)
|
||||||
PSQLA_EOAttribute_allocWithZoneIMP=
|
PSQLA_EOAttribute_allocWithZoneIMP=
|
||||||
[PSQLA_EOAttributeClass methodForSelector:@selector(allocWithZone:)];
|
[PSQLA_EOAttributeClass methodForSelector:@selector(allocWithZone:)];
|
||||||
|
|
||||||
PSQLA_PostgreSQLValues_newValueForBytesLengthAttributeIMP=
|
|
||||||
[PSQLA_PostgreSQLValuesClass methodForSelector:@selector(newValueForBytes:length:attribute:)];
|
|
||||||
|
|
||||||
// ==== Constants ====
|
// ==== Constants ====
|
||||||
ASSIGN(PSQLA_NSNumberBool_Yes,[PSQLA_NSNumberClass numberWithBool:YES]);
|
ASSIGN(PSQLA_NSNumberBool_Yes,[PSQLA_NSNumberClass numberWithBool:YES]);
|
||||||
|
|
|
@ -1,71 +0,0 @@
|
||||||
/*
|
|
||||||
PostgreSQLValues.h
|
|
||||||
|
|
||||||
Copyright (C) 2000,2002,2003,2004,2005 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
Author: Mirko Viviani <mirko.viviani@gmail.com
|
|
||||||
Date: February 2000
|
|
||||||
|
|
||||||
This file is part of the GNUstep Database Library.
|
|
||||||
|
|
||||||
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,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __PostgreSQLValues_h__
|
|
||||||
#define __PostgreSQLValues_h__
|
|
||||||
|
|
||||||
#ifdef GNUSTEP
|
|
||||||
#include <Foundation/NSString.h>
|
|
||||||
#include <Foundation/NSValue.h>
|
|
||||||
#include <Foundation/NSData.h>
|
|
||||||
#include <Foundation/NSDate.h>
|
|
||||||
#include <Foundation/NSCalendarDate.h>
|
|
||||||
#else
|
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@class EOAttribute;
|
|
||||||
@class PostgreSQLChannel;
|
|
||||||
|
|
||||||
|
|
||||||
@interface PostgreSQLValues:NSObject
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id)newValueForBytes: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute;
|
|
||||||
|
|
||||||
|
|
||||||
+ (id)newValueForNumberType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute;
|
|
||||||
|
|
||||||
+ (id)newValueForCharactersType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute;
|
|
||||||
|
|
||||||
+ (id)newValueForBytesType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute;
|
|
||||||
|
|
||||||
+ (id)newValueForDateType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* __PostgreSQLValues_h__ */
|
|
|
@ -1,421 +0,0 @@
|
||||||
/**
|
|
||||||
PostgreSQLValues.m
|
|
||||||
|
|
||||||
Copyright (C) 2000-2002,2003,2004,2005 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
Author: Mirko Viviani <mirko.viviani@gmail.com
|
|
||||||
Date: February 2000
|
|
||||||
|
|
||||||
$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,
|
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
</license>
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
RCS_ID("$Id$")
|
|
||||||
|
|
||||||
#ifdef GNUSTEP
|
|
||||||
#include <Foundation/NSData.h>
|
|
||||||
#include <Foundation/NSDate.h>
|
|
||||||
#include <Foundation/NSString.h>
|
|
||||||
#include <Foundation/NSValue.h>
|
|
||||||
#include <Foundation/NSDecimalNumber.h>
|
|
||||||
#include <Foundation/NSException.h>
|
|
||||||
#include <Foundation/NSDebug.h>
|
|
||||||
#else
|
|
||||||
#include <Foundation/Foundation.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef GNUSTEP
|
|
||||||
#include <GNUstepBase/GNUstep.h>
|
|
||||||
#include <GNUstepBase/GSCategories.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <EOAccess/EOAttribute.h>
|
|
||||||
|
|
||||||
#include "PostgreSQLEOAdaptor/PostgreSQLAdaptor.h"
|
|
||||||
#include "PostgreSQLEOAdaptor/PostgreSQLChannel.h"
|
|
||||||
#include "PostgreSQLEOAdaptor/PostgreSQLValues.h"
|
|
||||||
|
|
||||||
#include "PostgreSQLCompatibility.h"
|
|
||||||
#include "PostgreSQLPrivate.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void __postgres_values_linking_function (void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL attrRespondsToValueClass = NO;
|
|
||||||
static BOOL attrRespondsToValueTypeChar = NO;
|
|
||||||
static NSStringEncoding LPSQLA_StringDefaultCStringEncoding;
|
|
||||||
|
|
||||||
@interface EOAttribute (private)
|
|
||||||
- (Class)_valueClass;
|
|
||||||
- (char)_valueTypeChar;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation PostgreSQLValues
|
|
||||||
|
|
||||||
+ (void) initialize
|
|
||||||
{
|
|
||||||
static BOOL initialized=NO;
|
|
||||||
if (!initialized)
|
|
||||||
{
|
|
||||||
PSQLA_PrivInit();
|
|
||||||
|
|
||||||
attrRespondsToValueClass
|
|
||||||
= [EOAttribute instancesRespondToSelector: @selector(_valueClass)];
|
|
||||||
attrRespondsToValueTypeChar
|
|
||||||
= [EOAttribute instancesRespondToSelector: @selector(_valueTypeChar)];
|
|
||||||
LPSQLA_StringDefaultCStringEncoding = [NSString defaultCStringEncoding];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
+ (id)newValueForBytes: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute
|
|
||||||
{
|
|
||||||
switch ([attribute adaptorValueType])
|
|
||||||
{
|
|
||||||
case EOAdaptorNumberType:
|
|
||||||
return [self newValueForNumberType: bytes
|
|
||||||
length: length
|
|
||||||
attribute: attribute];
|
|
||||||
case EOAdaptorCharactersType:
|
|
||||||
return [self newValueForCharactersType: bytes
|
|
||||||
length: length
|
|
||||||
attribute: attribute];
|
|
||||||
case EOAdaptorBytesType:
|
|
||||||
return [self newValueForBytesType: bytes
|
|
||||||
length: length
|
|
||||||
attribute: attribute];
|
|
||||||
case EOAdaptorDateType:
|
|
||||||
return [self newValueForDateType: bytes
|
|
||||||
length: length
|
|
||||||
attribute: attribute];
|
|
||||||
default:
|
|
||||||
NSAssert2(NO,
|
|
||||||
@"Bad (%d) adaptor type for attribute : %@",
|
|
||||||
(int)[attribute adaptorValueType],attribute);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
For efficiency reasons, the returned value is NOT autoreleased !
|
|
||||||
bytes is null terminated (cf PostgreSQLql doc) and length is equivalent
|
|
||||||
to strlen(bytes)
|
|
||||||
**/
|
|
||||||
+ (id)newValueForNumberType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute
|
|
||||||
{
|
|
||||||
id value = nil;
|
|
||||||
NSString* externalType=nil;
|
|
||||||
|
|
||||||
externalType=[attribute externalType];
|
|
||||||
|
|
||||||
if (length==1 // avoid -isEqualToString if we can :-)
|
|
||||||
&& [externalType isEqualToString: @"bool"])
|
|
||||||
{
|
|
||||||
if (((char *)bytes)[0] == 't' && ((char *)bytes)[1] == 0)
|
|
||||||
value=RETAIN(PSQLA_NSNumberBool_Yes);
|
|
||||||
else if (((char *)bytes)[0] == 'f' && ((char *)bytes)[1] == 0)
|
|
||||||
value=RETAIN(PSQLA_NSNumberBool_No);
|
|
||||||
else
|
|
||||||
NSAssert1(NO,@"Bad boolean: %@",[NSString stringWithCString:bytes
|
|
||||||
length:length]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Class valueClass = attrRespondsToValueClass
|
|
||||||
? [attribute _valueClass]
|
|
||||||
: NSClassFromString ([attribute valueClassName]);
|
|
||||||
|
|
||||||
if (valueClass==PSQLA_NSDecimalNumberClass)
|
|
||||||
{
|
|
||||||
//TODO: Optimize without creating NSString instance
|
|
||||||
NSString* str = [PSQLA_alloc(NSString) initWithCString:bytes
|
|
||||||
length:length];
|
|
||||||
|
|
||||||
value = [PSQLA_alloc(NSDecimalNumber) initWithString: str];
|
|
||||||
|
|
||||||
RELEASE(str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char valueTypeChar = attrRespondsToValueTypeChar
|
|
||||||
? [attribute _valueTypeChar]
|
|
||||||
: [[attribute valueType] cString][0];
|
|
||||||
switch(valueTypeChar)
|
|
||||||
{
|
|
||||||
case 'i':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithInt: atoi(bytes)];
|
|
||||||
break;
|
|
||||||
case 'I':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithUnsignedInt:(unsigned int)atol(bytes)];
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithChar: atoi(bytes)];
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithUnsignedChar: (unsigned char)atoi(bytes)];
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithShort: (short)atoi(bytes)];
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithUnsignedShort: (unsigned short)atoi(bytes)];
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithLong: atol(bytes)];
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithUnsignedLong:strtoul(bytes,NULL,10)];
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithLongLong:atoll(bytes)];
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithUnsignedLongLong:strtoull(bytes,NULL,10)];
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithFloat: (float)strtod(bytes,NULL)];
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case '\0':
|
|
||||||
value = [PSQLA_alloc(NSNumber) initWithDouble: strtod(bytes,NULL)];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NSAssert2(NO,@"Unknown attribute valueTypeChar: %c for attribute: %@",
|
|
||||||
valueTypeChar,attribute);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
For efficiency reasons, the returned value is NOT autoreleased !
|
|
||||||
**/
|
|
||||||
+ (id)newValueForCharactersType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute
|
|
||||||
{
|
|
||||||
return [attribute newValueForBytes: bytes
|
|
||||||
length: length
|
|
||||||
encoding: LPSQLA_StringDefaultCStringEncoding];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
For efficiency reasons, the returned value is NOT autoreleased !
|
|
||||||
**/
|
|
||||||
+ (id)newValueForBytesType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute
|
|
||||||
{
|
|
||||||
size_t newLength = length;
|
|
||||||
unsigned char *decodedBytes = 0;
|
|
||||||
id data = nil;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
For efficiency reasons, the returned value is NOT autoreleased !
|
|
||||||
**/
|
|
||||||
+ (id)newValueForDateType: (const void *)bytes
|
|
||||||
length: (int)length
|
|
||||||
attribute: (EOAttribute *)attribute
|
|
||||||
{
|
|
||||||
id date=nil;
|
|
||||||
NSString *str = [PSQLA_alloc(NSString) initWithCString:(const char *)bytes
|
|
||||||
length:length];
|
|
||||||
|
|
||||||
NSDebugMLLog(@"gsdb",@"str=%@ format=%@",str,PSQLA_postgresCalendarFormat);
|
|
||||||
|
|
||||||
date = [PSQLA_alloc(NSCalendarDate) initWithString: str
|
|
||||||
calendarFormat: PSQLA_postgresCalendarFormat];
|
|
||||||
|
|
||||||
NSDebugMLLog(@"gsdb",@"str=%@ d=%@ dtz=%@ format=%@",
|
|
||||||
str,date,[date timeZone],PSQLA_postgresCalendarFormat);
|
|
||||||
|
|
||||||
//We may have some 'invalid' date so it's better to stop here
|
|
||||||
NSAssert2(date,
|
|
||||||
@"No date created for string '%@' for attribute: %@",
|
|
||||||
str,attribute);
|
|
||||||
|
|
||||||
RELEASE(str);
|
|
||||||
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@end
|
|
||||||
/*
|
|
||||||
@implementation NSString (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
|
|
||||||
For efficiency reasons, the returned value is NOT autoreleased !
|
|
||||||
|
|
||||||
- stringValueForPostgreSQLType:(NSString*)type
|
|
||||||
attribute:(EOAttribute*)attribute
|
|
||||||
{
|
|
||||||
if ([type isEqual:@"bytea"])
|
|
||||||
return [[NSData alloc]initWithBytes:[self cString]
|
|
||||||
length:[self cStringLength]]
|
|
||||||
stringValueForPostgreSQLType:type
|
|
||||||
attribute:attribute];
|
|
||||||
else
|
|
||||||
return [[[[EOQuotedExpression alloc]
|
|
||||||
initWithExpression:self
|
|
||||||
quote:@"'"
|
|
||||||
escape:@"\\'"]
|
|
||||||
autorelease]
|
|
||||||
expressionValueForContext:nil];
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end // NSString (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSNumber (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
- stringValueForPostgreSQLType:(NSString*)type
|
|
||||||
attribute:(EOAttribute*)attribute;
|
|
||||||
{
|
|
||||||
if ([[attribute externalType] isEqualToString:@"bool"])
|
|
||||||
return [self boolValue] ? @"'t'" : @"'f'";
|
|
||||||
|
|
||||||
return [self description];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end // NSNumber (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSData (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
|
|
||||||
- stringValueForPostgreSQLType:(NSString*)type
|
|
||||||
attribute:(EOAttribute*)attribute
|
|
||||||
{
|
|
||||||
if ([[attribute externalType] isEqualToString:@"bytea"]) {
|
|
||||||
const char* bytes = [self bytes];
|
|
||||||
int length = [self length];
|
|
||||||
int final_length;
|
|
||||||
char *description, *temp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!length)
|
|
||||||
return @"''";
|
|
||||||
|
|
||||||
final_length = 4 + 2 * length + 1;
|
|
||||||
description = Malloc (final_length);
|
|
||||||
temp = description + 3;
|
|
||||||
|
|
||||||
description[0] = 0;
|
|
||||||
strcat (description, "'0x");
|
|
||||||
for (i = 0; i < length; i++, temp += 2)
|
|
||||||
sprintf (temp, "%02X", (unsigned char)bytes[i]);
|
|
||||||
temp[0] = '\'';
|
|
||||||
temp[1] = 0;
|
|
||||||
|
|
||||||
return [[[NSString alloc]
|
|
||||||
initWithCStringNoCopy:description
|
|
||||||
length:final_length-1
|
|
||||||
freeWhenDone:YES]
|
|
||||||
autorelease];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [[NSString stringWithCString:[self bytes] length:[self length]]
|
|
||||||
stringValueForPostgreSQLType:type attribute:attribute];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end // NSData (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
@implementation NSCalendarDate (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
+ (NSString*)postgresFormat
|
|
||||||
{
|
|
||||||
NSLog(@"%@ - is deprecated. The adaptor always uses ISO format.",
|
|
||||||
NSStringFromSelector(_cmd));
|
|
||||||
return PSQLA_postgresCalendarFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end // NSCalendarDate (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
@implementation EONull (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
- stringValueForPostgreSQLType:(NSString*)type
|
|
||||||
attribute:(EOAttribute*)attribute
|
|
||||||
{
|
|
||||||
return @"NULL";
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSObject (PostgreSQLValueCreation)
|
|
||||||
|
|
||||||
- stringValueForPostgreSQLType:(NSString*)type
|
|
||||||
attribute:(EOAttribute*)attribute
|
|
||||||
{
|
|
||||||
if ([self respondsToSelector:@selector(stringForType:)])
|
|
||||||
return [[self stringForType:[attribute valueType]]
|
|
||||||
stringValueForPostgreSQLType:type attribute:attribute];
|
|
||||||
else if ([self respondsToSelector:@selector(dataForType:)])
|
|
||||||
return [[self dataForType:[attribute valueType]]
|
|
||||||
stringValueForPostgreSQLType:type attribute:attribute];
|
|
||||||
else
|
|
||||||
THROW([[DataTypeMappingNotSupportedException alloc]
|
|
||||||
initWithFormat:@"PostgreSQL cannot map value class %@ "
|
|
||||||
@"because its instances does not responds to either "
|
|
||||||
@" `stringForType:' or `dataForType:'. ",
|
|
||||||
NSStringFromClass([self class])]);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end // NSObject (PostgreSQLValueCreation)
|
|
||||||
*/
|
|
Loading…
Add table
Add a link
Reference in a new issue