mirror of
https://github.com/gnustep/libs-sqlclient.git
synced 2025-02-21 02:41:07 +00:00
Optimisation tweaks
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/sqlclient/trunk@38467 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
19a68d1abd
commit
d70286f339
3 changed files with 280 additions and 180 deletions
|
@ -1,9 +1,16 @@
|
||||||
|
2015-04-30 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
|
* Postgres.m:
|
||||||
|
* testPostgres.m:
|
||||||
|
Fix error parsing timestamps in arrays when the server quoters them.
|
||||||
|
Also optimise string allocation, and add some tests.
|
||||||
|
|
||||||
2015-04-28 Richard Frith-Macdonald <rfm@gnu.org>
|
2015-04-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* SQLClient.h:
|
* SQLClient.h:
|
||||||
* SQLClient.m:
|
* SQLClient.m:
|
||||||
* Postgres.m:
|
* Postgres.m:
|
||||||
Deprecate trtansaction merging.
|
Deprecate transaction merging.
|
||||||
Rewrite SQLRecord concrete class to use a new SQLRecordKeys object
|
Rewrite SQLRecord concrete class to use a new SQLRecordKeys object
|
||||||
shared between all the records produced by a query (as a performance
|
shared between all the records produced by a query (as a performance
|
||||||
enhancement for large queries).
|
enhancement for large queries).
|
||||||
|
|
377
Postgres.m
377
Postgres.m
|
@ -73,14 +73,193 @@ typedef struct {
|
||||||
static NSDate *future = nil;
|
static NSDate *future = nil;
|
||||||
static NSNull *null = nil;
|
static NSNull *null = nil;
|
||||||
|
|
||||||
|
#if defined(GNUSTEP)
|
||||||
|
static NSString *placeholder = nil;
|
||||||
|
#else
|
||||||
|
static Class stringClass = Nil;
|
||||||
|
static SEL allocStringSel = 0;
|
||||||
|
static IMP allocStringImp = 0;
|
||||||
|
#endif
|
||||||
|
static SEL initStringSel = 0;
|
||||||
|
static IMP initStringImp = 0;
|
||||||
|
|
||||||
static NSTimeZone *zones[47]; // For -23 to +23 hours
|
static NSTimeZone *zones[47]; // For -23 to +23 hours
|
||||||
|
|
||||||
|
static inline NSString*
|
||||||
|
newString(const char *b, int l, NSStringEncoding e)
|
||||||
|
{
|
||||||
|
#if defined(GNUSTEP)
|
||||||
|
return (*initStringImp)(placeholder, initStringSel, b, l, e);
|
||||||
|
#else
|
||||||
|
NSString *s = (*allocStringImp)(stringClass, allocStringSel);
|
||||||
|
return (*initStringImp)(s, initStringSel, b, l, e);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static NSDate*
|
||||||
|
newDateFromBuffer(const char *b, int l)
|
||||||
|
{
|
||||||
|
NSCalendarDate *d;
|
||||||
|
NSTimeZone *zone;
|
||||||
|
int milliseconds = 0;
|
||||||
|
int timezone = 0;
|
||||||
|
int day;
|
||||||
|
int month;
|
||||||
|
int year;
|
||||||
|
int hour;
|
||||||
|
int minute;
|
||||||
|
int second;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
year = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
year = year * 10 + b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
year = year * 10 + b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
year = year * 10 + b[i++] - '0';
|
||||||
|
|
||||||
|
if (i >= l || b[i++] != '-') return nil;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
month = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
month = month * 10 + b[i++] - '0';
|
||||||
|
if (month < 1 || month > 12) return nil;
|
||||||
|
|
||||||
|
if (i >= l || b[i++] != '-') return nil;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
day = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
day = day * 10 + b[i++] - '0';
|
||||||
|
if (day < 1 || day > 31) return nil;
|
||||||
|
|
||||||
|
if (i == l)
|
||||||
|
{
|
||||||
|
hour = 0;
|
||||||
|
minute = 0;
|
||||||
|
second = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i >= l || b[i++] != ' ') return nil;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
hour = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
hour = hour * 10 + b[i++] - '0';
|
||||||
|
if (hour < 0 || hour > 23) return nil;
|
||||||
|
|
||||||
|
if (i >= l || b[i++] != ':') return nil;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
minute = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
minute = minute * 10 + b[i++] - '0';
|
||||||
|
if (minute < 0 || minute > 59) return nil;
|
||||||
|
|
||||||
|
if (i >= l || b[i++] != ':') return nil;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
second = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
second = second * 10 + b[i++] - '0';
|
||||||
|
if (second < 0 || second > 60) return nil;
|
||||||
|
|
||||||
|
if (i < l && '.' == b[i])
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
milliseconds = b[i++] - '0';
|
||||||
|
milliseconds *=- 10;
|
||||||
|
if (i < l && isdigit(b[i]))
|
||||||
|
milliseconds += b[i++] - '0';
|
||||||
|
milliseconds *=- 10;
|
||||||
|
if (i < l && isdigit(b[i]))
|
||||||
|
milliseconds += b[i++] - '0';
|
||||||
|
while (i < l && isdigit(b[i]))
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < l && ('+' == b[i] || '-' == b[i]))
|
||||||
|
{
|
||||||
|
char sign = b[i++];
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
timezone = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
timezone = timezone * 10 + b[i++] - '0';
|
||||||
|
if (timezone < 0 || timezone > 23) return nil;
|
||||||
|
timezone *= 60; // Convert to minutes
|
||||||
|
if (i < l && ':' == b[i])
|
||||||
|
{
|
||||||
|
int tzmin;
|
||||||
|
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
tzmin = b[i++] - '0';
|
||||||
|
if (i >= l || !isdigit(b[i])) return nil;
|
||||||
|
tzmin = tzmin * 10 + b[i++] - '0';
|
||||||
|
if (tzmin < 0 || tzmin > 59) return nil;
|
||||||
|
|
||||||
|
timezone += tzmin;
|
||||||
|
}
|
||||||
|
if ('-' == sign)
|
||||||
|
timezone = -timezone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (timezone % 60 == 0)
|
||||||
|
{
|
||||||
|
zone = zones[timezone / 60];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zone = [NSTimeZone timeZoneForSecondsFromGMT: timezone * 60];
|
||||||
|
}
|
||||||
|
|
||||||
|
d = [[NSCalendarDate alloc] initWithYear: year
|
||||||
|
month: month
|
||||||
|
day: day
|
||||||
|
hour: hour
|
||||||
|
minute: minute
|
||||||
|
second: second
|
||||||
|
timeZone: zone];
|
||||||
|
|
||||||
|
if (milliseconds > 0)
|
||||||
|
{
|
||||||
|
NSTimeInterval ti;
|
||||||
|
|
||||||
|
ti = milliseconds;
|
||||||
|
ti /= 1000.0;
|
||||||
|
ti += [d timeIntervalSinceReferenceDate];
|
||||||
|
d = [d initWithTimeIntervalSinceReferenceDate: ti];
|
||||||
|
[d setTimeZone: zone];
|
||||||
|
}
|
||||||
|
[d setCalendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
@implementation SQLClientPostgres
|
@implementation SQLClientPostgres
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
if (future == nil)
|
if (future == nil)
|
||||||
{
|
{
|
||||||
|
initStringSel = @selector(initWithBytes:length:encoding:);
|
||||||
|
#if defined(GNUSTEP)
|
||||||
|
placeholder = [NSString alloc];
|
||||||
|
initStringImp
|
||||||
|
= [[placeholder class] instanceMethodForSelector: initStringSel];
|
||||||
|
#else
|
||||||
|
stringClass = [NSString class];
|
||||||
|
allocStringSel = @selector(alloc);
|
||||||
|
allocStringImp = [stringClass methodForSelector: allocStringSel];
|
||||||
|
initStringImp = [stringClass instanceMethodForSelector: initStringSel];
|
||||||
|
#endif
|
||||||
|
|
||||||
future = [NSCalendarDate dateWithString: @"9999-01-01 00:00:00 +0000"
|
future = [NSCalendarDate dateWithString: @"9999-01-01 00:00:00 +0000"
|
||||||
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
calendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
||||||
locale: nil];
|
locale: nil];
|
||||||
|
@ -89,7 +268,8 @@ static NSTimeZone *zones[47]; // For -23 to +23 hours
|
||||||
[null retain];
|
[null retain];
|
||||||
for (int i = -23; i <= 23; i++)
|
for (int i = -23; i <= 23; i++)
|
||||||
{
|
{
|
||||||
zones[i + 23] = [[NSTimeZone timeZoneForSecondsFromGMT: i * 60 * 60] retain];
|
zones[i + 23]
|
||||||
|
= [[NSTimeZone timeZoneForSecondsFromGMT: i * 60 * 60] retain];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,7 +709,22 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
}
|
}
|
||||||
if (len == (p - start))
|
if (len == (p - start))
|
||||||
{
|
{
|
||||||
v = [[NSString alloc] initWithUTF8String: start];
|
if ('T' == t)
|
||||||
|
{
|
||||||
|
/* This is expected to be a timestamp
|
||||||
|
*/
|
||||||
|
v = newDateFromBuffer(start, p - start);
|
||||||
|
}
|
||||||
|
else if ('D' == t)
|
||||||
|
{
|
||||||
|
/* This is expected to be bytea data
|
||||||
|
*/
|
||||||
|
v = [[self dataFromBLOB: start] retain];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = newString(start, p - start, NSUTF8StringEncoding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -549,7 +744,13 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
buf[i++] = *ptr++;
|
buf[i++] = *ptr++;
|
||||||
}
|
}
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
if ('D' == t)
|
if ('T' == t)
|
||||||
|
{
|
||||||
|
/* This is expected to be a timestamp
|
||||||
|
*/
|
||||||
|
v = newDateFromBuffer(buf, len);
|
||||||
|
}
|
||||||
|
else if ('D' == t)
|
||||||
{
|
{
|
||||||
/* This is expected to be bytea data
|
/* This is expected to be bytea data
|
||||||
*/
|
*/
|
||||||
|
@ -588,7 +789,7 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
}
|
}
|
||||||
else if ('T' == t)
|
else if ('T' == t)
|
||||||
{
|
{
|
||||||
v = [[self dbToDateFromBuffer: start length: len] retain];
|
v = newDateFromBuffer(start, len);
|
||||||
}
|
}
|
||||||
else if ('D' == t)
|
else if ('D' == t)
|
||||||
{
|
{
|
||||||
|
@ -603,7 +804,7 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v = [[NSString alloc] initWithUTF8String: start];
|
v = newString(start, p - start, NSUTF8StringEncoding);
|
||||||
}
|
}
|
||||||
*p = save;
|
*p = save;
|
||||||
}
|
}
|
||||||
|
@ -631,17 +832,15 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
switch (t)
|
switch (t)
|
||||||
{
|
{
|
||||||
case 1082: // Date
|
case 1082: // Date
|
||||||
return [self newDateFromBuffer: p length: trim(p, s)];
|
return newDateFromBuffer(p, trim(p, s));
|
||||||
|
|
||||||
case 1083: // Time (treat as string)
|
case 1083: // Time (treat as string)
|
||||||
s = trim(p, s);
|
s = trim(p, s);
|
||||||
return [[NSString alloc] initWithBytes: p
|
return newString(p, s, NSASCIIStringEncoding);
|
||||||
length: s
|
|
||||||
encoding: NSASCIIStringEncoding];
|
|
||||||
|
|
||||||
case 1114: // Timestamp without time zone.
|
case 1114: // Timestamp without time zone.
|
||||||
case 1184: // Timestamp with time zone.
|
case 1184: // Timestamp with time zone.
|
||||||
return [self newDateFromBuffer: p length: trim(p, s)];
|
return newDateFromBuffer(p, trim(p, s));
|
||||||
|
|
||||||
case 16: // BOOL
|
case 16: // BOOL
|
||||||
if (*p == 't')
|
if (*p == 't')
|
||||||
|
@ -657,18 +856,13 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
return [[self dataFromBLOB: p] retain];
|
return [[self dataFromBLOB: p] retain];
|
||||||
|
|
||||||
case 18: // "char"
|
case 18: // "char"
|
||||||
return [[NSString alloc] initWithBytes: p
|
return newString(p, s, NSUTF8StringEncoding);
|
||||||
length: s
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
|
|
||||||
case 20: // INT8
|
case 20: // INT8
|
||||||
case 21: // INT2
|
case 21: // INT2
|
||||||
case 23: // INT4
|
case 23: // INT4
|
||||||
s = trim(p, s);
|
s = trim(p, s);
|
||||||
return [[NSString alloc] initWithBytes: p
|
return newString(p, s, NSASCIIStringEncoding);
|
||||||
length: s
|
|
||||||
encoding: NSASCIIStringEncoding];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1182: // DATE ARRAY
|
case 1182: // DATE ARRAY
|
||||||
case 1115: // TS without TZ ARRAY
|
case 1115: // TS without TZ ARRAY
|
||||||
|
@ -706,9 +900,7 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
{
|
{
|
||||||
s = trim(p, s);
|
s = trim(p, s);
|
||||||
}
|
}
|
||||||
return [[NSString alloc] initWithBytes: p
|
return newString(p, s, NSUTF8StringEncoding);
|
||||||
length: s
|
|
||||||
encoding: NSUTF8StringEncoding];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1229,151 +1421,6 @@ static inline unsigned int trim(char *str, unsigned len)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDate*) newDateFromBuffer: (char*)b length: (int)l
|
|
||||||
{
|
|
||||||
NSCalendarDate *d;
|
|
||||||
NSTimeZone *zone;
|
|
||||||
int milliseconds = 0;
|
|
||||||
int timezone = 0;
|
|
||||||
int day;
|
|
||||||
int month;
|
|
||||||
int year;
|
|
||||||
int hour;
|
|
||||||
int minute;
|
|
||||||
int second;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
year = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
year = year * 10 + b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
year = year * 10 + b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
year = year * 10 + b[i++] - '0';
|
|
||||||
|
|
||||||
if (i >= l || b[i++] != '-') return nil;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
month = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
month = month * 10 + b[i++] - '0';
|
|
||||||
if (month < 1 || month > 12) return nil;
|
|
||||||
|
|
||||||
if (i >= l || b[i++] != '-') return nil;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
day = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
day = day * 10 + b[i++] - '0';
|
|
||||||
if (day < 1 || day > 31) return nil;
|
|
||||||
|
|
||||||
if (i == l)
|
|
||||||
{
|
|
||||||
hour = 0;
|
|
||||||
minute = 0;
|
|
||||||
second = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (i >= l || b[i++] != ' ') return nil;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
hour = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
hour = hour * 10 + b[i++] - '0';
|
|
||||||
if (hour < 0 || hour > 23) return nil;
|
|
||||||
|
|
||||||
if (i >= l || b[i++] != ':') return nil;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
minute = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
minute = minute * 10 + b[i++] - '0';
|
|
||||||
if (minute < 0 || minute > 59) return nil;
|
|
||||||
|
|
||||||
if (i >= l || b[i++] != ':') return nil;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
second = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
second = second * 10 + b[i++] - '0';
|
|
||||||
if (second < 0 || second > 60) return nil;
|
|
||||||
|
|
||||||
if (i < l && '.' == b[i])
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
milliseconds = b[i++] - '0';
|
|
||||||
milliseconds *=- 10;
|
|
||||||
if (i < l && isdigit(b[i]))
|
|
||||||
milliseconds += b[i++] - '0';
|
|
||||||
milliseconds *=- 10;
|
|
||||||
if (i < l && isdigit(b[i]))
|
|
||||||
milliseconds += b[i++] - '0';
|
|
||||||
while (i < l && isdigit(b[i]))
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < l && ('+' == b[i] || '-' == b[i]))
|
|
||||||
{
|
|
||||||
char sign = b[i++];
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
timezone = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
timezone = timezone * 10 + b[i++] - '0';
|
|
||||||
if (timezone < 0 || timezone > 23) return nil;
|
|
||||||
timezone *= 60; // Convert to minutes
|
|
||||||
if (i < l && ':' == b[i])
|
|
||||||
{
|
|
||||||
int tzmin;
|
|
||||||
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
tzmin = b[i++] - '0';
|
|
||||||
if (i >= l || !isdigit(b[i])) return nil;
|
|
||||||
tzmin = tzmin * 10 + b[i++] - '0';
|
|
||||||
if (tzmin < 0 || tzmin > 59) return nil;
|
|
||||||
|
|
||||||
timezone += tzmin;
|
|
||||||
}
|
|
||||||
if ('-' == sign)
|
|
||||||
timezone = -timezone;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timezone % 60 == 0)
|
|
||||||
{
|
|
||||||
zone = zones[timezone / 60];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zone = [NSTimeZone timeZoneForSecondsFromGMT: timezone * 60];
|
|
||||||
}
|
|
||||||
|
|
||||||
d = [[NSCalendarDate alloc] initWithYear: year
|
|
||||||
month: month
|
|
||||||
day: day
|
|
||||||
hour: hour
|
|
||||||
minute: minute
|
|
||||||
second: second
|
|
||||||
timeZone: zone];
|
|
||||||
|
|
||||||
if (milliseconds > 0)
|
|
||||||
{
|
|
||||||
NSTimeInterval ti;
|
|
||||||
|
|
||||||
ti = milliseconds;
|
|
||||||
ti /= 1000.0;
|
|
||||||
ti += [d timeIntervalSinceReferenceDate];
|
|
||||||
d = [d initWithTimeIntervalSinceReferenceDate: ti];
|
|
||||||
[d setTimeZone: zone];
|
|
||||||
}
|
|
||||||
[d setCalendarFormat: @"%Y-%m-%d %H:%M:%S %z"];
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
if (extra != 0)
|
if (extra != 0)
|
||||||
|
|
|
@ -229,6 +229,7 @@ main()
|
||||||
{
|
{
|
||||||
NSString *oddChars;
|
NSString *oddChars;
|
||||||
NSString *nonLatin;
|
NSString *nonLatin;
|
||||||
|
id e1, e2, e3, e4, e5;
|
||||||
id r0;
|
id r0;
|
||||||
id r1;
|
id r1;
|
||||||
|
|
||||||
|
@ -249,6 +250,7 @@ main()
|
||||||
|
|
||||||
[db begin];
|
[db begin];
|
||||||
[db execute: @"create table xxx ( "
|
[db execute: @"create table xxx ( "
|
||||||
|
@"id int, "
|
||||||
@"k char(40), "
|
@"k char(40), "
|
||||||
@"char1 char(1), "
|
@"char1 char(1), "
|
||||||
@"boolval BOOL, "
|
@"boolval BOOL, "
|
||||||
|
@ -264,9 +266,9 @@ main()
|
||||||
@")",
|
@")",
|
||||||
nil];
|
nil];
|
||||||
|
|
||||||
if (1 != [db execute: @"insert into xxx (k, char1, boolval, intval,"
|
if (1 != [db execute: @"insert into xxx (id, k, char1, boolval, intval,"
|
||||||
@" when1, when2, b, extra1, extra2, extra3, extra4, extra5) "
|
@" when1, when2, b, extra1, extra2, extra3, extra4, extra5) "
|
||||||
@"values ("
|
@"values (1,"
|
||||||
@"'{hello', "
|
@"'{hello', "
|
||||||
@"'X', "
|
@"'X', "
|
||||||
@"TRUE, "
|
@"TRUE, "
|
||||||
|
@ -275,23 +277,23 @@ main()
|
||||||
@"CURRENT_TIMESTAMP, ",
|
@"CURRENT_TIMESTAMP, ",
|
||||||
data, @", ",
|
data, @", ",
|
||||||
[db quoteArray:
|
[db quoteArray:
|
||||||
[NSArray arrayWithObjects: @"1", @"2", [NSNull null], nil]
|
(e1 = [NSArray arrayWithObjects: @"1", @"2", [NSNull null], nil])
|
||||||
toString: nil
|
toString: nil
|
||||||
quotingStrings: NO], @", ",
|
quotingStrings: NO], @", ",
|
||||||
[db quoteArray:
|
[db quoteArray:
|
||||||
[NSArray arrayWithObjects: @"on,e", @"t'wo", @"many", nil]
|
(e2 = [NSArray arrayWithObjects: @"on,e", @"t'wo", @"many", nil])
|
||||||
toString: nil
|
toString: nil
|
||||||
quotingStrings: YES], @", ",
|
quotingStrings: YES], @", ",
|
||||||
[db quoteArray:
|
[db quoteArray:
|
||||||
[NSArray arrayWithObjects: data, nil]
|
(e3 = [NSArray arrayWithObjects: data, nil])
|
||||||
toString: nil
|
toString: nil
|
||||||
quotingStrings: YES], @", ",
|
quotingStrings: YES], @", ",
|
||||||
[db quoteArray:
|
[db quoteArray:
|
||||||
[NSArray arrayWithObjects: @"TRUE", @"FALSE", nil]
|
(e4 =[NSArray arrayWithObjects: @"TRUE", @"FALSE", nil])
|
||||||
toString: nil
|
toString: nil
|
||||||
quotingStrings: NO], @", ",
|
quotingStrings: NO], @", ",
|
||||||
[db quoteArray:
|
[db quoteArray:
|
||||||
[NSArray arrayWithObjects: [NSDate date], nil]
|
(e5 = [NSArray arrayWithObjects: [NSDate date], nil])
|
||||||
toString: nil
|
toString: nil
|
||||||
quotingStrings: YES], @")",
|
quotingStrings: YES], @")",
|
||||||
nil])
|
nil])
|
||||||
|
@ -304,8 +306,8 @@ main()
|
||||||
[db setDebugging: 0];
|
[db setDebugging: 0];
|
||||||
|
|
||||||
[db execute: @"insert into xxx "
|
[db execute: @"insert into xxx "
|
||||||
@"(k, char1, boolval, intval, when1, when2, b) "
|
@"(id, k, char1, boolval, intval, when1, when2, b) "
|
||||||
@"values ("
|
@"values (2,"
|
||||||
@"'hello', "
|
@"'hello', "
|
||||||
@"'X', "
|
@"'X', "
|
||||||
@"TRUE, "
|
@"TRUE, "
|
||||||
|
@ -316,8 +318,8 @@ main()
|
||||||
@")",
|
@")",
|
||||||
nil];
|
nil];
|
||||||
[db execute: @"insert into xxx "
|
[db execute: @"insert into xxx "
|
||||||
@"(k, char1, boolval, intval, when1, when2, b) "
|
@"(id, k, char1, boolval, intval, when1, when2, b) "
|
||||||
@"values (",
|
@"values (3,",
|
||||||
[db quote: oddChars],
|
[db quote: oddChars],
|
||||||
@", ",
|
@", ",
|
||||||
[db quote: nonLatin],
|
[db quote: nonLatin],
|
||||||
|
@ -330,11 +332,11 @@ main()
|
||||||
nil];
|
nil];
|
||||||
[db commit];
|
[db commit];
|
||||||
|
|
||||||
r0 = [db cache: 1 query: @"select * from xxx", nil];
|
r0 = [db cache: 1 query: @"select * from xxx order by id", nil];
|
||||||
r1 = [db cache: 1 query: @"select * from xxx", nil];
|
r1 = [db cache: 1 query: @"select * from xxx order by id", nil];
|
||||||
NSCAssert([r0 lastObject] == [r1 lastObject], @"Cache failed");
|
NSCAssert([r0 lastObject] == [r1 lastObject], @"Cache failed");
|
||||||
[NSThread sleepForTimeInterval: 2.0];
|
[NSThread sleepForTimeInterval: 2.0];
|
||||||
records = [db cache: 1 query: @"select * from xxx", nil];
|
records = [db cache: 1 query: @"select * from xxx order by id", nil];
|
||||||
NSCAssert([r0 lastObject] != [records lastObject], @"Lifetime failed");
|
NSCAssert([r0 lastObject] != [records lastObject], @"Lifetime failed");
|
||||||
|
|
||||||
[db addObserver: l
|
[db addObserver: l
|
||||||
|
@ -372,6 +374,50 @@ main()
|
||||||
{
|
{
|
||||||
NSLog(@"Retrieved odd chars (%@) does not match saved string (%@)", o, oddChars);
|
NSLog(@"Retrieved odd chars (%@) does not match saved string (%@)", o, oddChars);
|
||||||
}
|
}
|
||||||
|
record = [records objectAtIndex: 0];
|
||||||
|
o = [record objectForKey: @"extra1"];
|
||||||
|
if ([o isEqual: e1] == NO)
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra1 (%@) does not match saved (%@)", o, e1);
|
||||||
|
}
|
||||||
|
o = [record objectForKey: @"extra2"];
|
||||||
|
if ([o isEqual: e2] == NO)
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra2 (%@) does not match saved (%@)", o, e2);
|
||||||
|
}
|
||||||
|
o = [record objectForKey: @"extra3"];
|
||||||
|
if ([o isEqual: e3] == NO)
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra3 (%@) does not match saved (%@)", o, e3);
|
||||||
|
}
|
||||||
|
o = [record objectForKey: @"extra4"];
|
||||||
|
if ([o count] != [e4 count])
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra4 (%@) does not match saved (%@)", o, e4);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < [o count]; i++)
|
||||||
|
{
|
||||||
|
if ([[o objectAtIndex: i] boolValue]
|
||||||
|
!= [[e4 objectAtIndex: i] boolValue])
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra4 (%@) does not match saved (%@)",
|
||||||
|
o, e4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
o = [record objectForKey: @"extra5"];
|
||||||
|
if ([o count] != [e5 count])
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra5 (%@) does not match saved (%@)", o, e5);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < [o count]; i++)
|
||||||
|
{
|
||||||
|
if (floor([[o objectAtIndex: i] timeIntervalSinceReferenceDate])
|
||||||
|
!= floor([[e5 objectAtIndex: i] timeIntervalSinceReferenceDate]))
|
||||||
|
{
|
||||||
|
NSLog(@"Retrieved extra5 (%@) does not match saved (%@)",
|
||||||
|
o, e5);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"Records - %@", [GSCache class]);
|
NSLog(@"Records - %@", [GSCache class]);
|
||||||
|
|
Loading…
Reference in a new issue