/* PrimaryKeyGeneration */
- (NSDictionary *)primaryKeyForNewRowWithEntity:(EOEntity *)_entity {
+ NSException *error;
NSArray *pkeys;
MySQL4Adaptor *adaptor;
NSString *seqName, *seq;
+ NSArray *seqs;
NSDictionary *pkey;
-
+ unsigned i, count;
+ id key;
+
pkeys = [_entity primaryKeyAttributeNames];
adaptor = (id)[[self adaptorContext] adaptor];
seqName = [adaptor primaryKeySequenceName];
pkey = nil;
seq = nil;
-
- NSLog(@"TODO(%s): implement primary keys for MySQL", __PRETTY_FUNCTION__);
-
- seq = ([seqName length] > 0)
- ? [NSString stringWithFormat:@"SELECT NEXTVAL ('%@')", seqName]
- : [adaptor newKeyExpression];
- NS_DURING {
- if ([self evaluateExpression:seq]) {
- id key = nil;
-
- NSLog(@"ERROR: new key creation is not implemented in MySQL4 yet!");
- if ([self isFetchInProgress]) {
- NSLog(@"Primary key eval returned results ..");
- }
- // TODO
- NSLog(@"%s: PKEY GEN NOT IMPLEMENTED!", __PRETTY_FUNCTION__);
- [self cancelFetch];
+ if ([seqName length] > 0) {
+ // TODO: if we do this, we also need to make the 'id' configurable ...
+ seq = [@"UPDATE " stringByAppendingString:seqName];
+ seq = [seq stringByAppendingString:@" SET id=LAST_INSERT_ID(id+1)"];
+ seqs = [NSArray arrayWithObjects:
+ seq, @"SELECT_LAST_INSERT_ID()", nil];
+ }
+ else
+ seqs = [[adaptor newKeyExpression] componentsSeparatedByString:@";"];
- if (key != nil) {
- pkey = [NSDictionary dictionaryWithObject:key
- forKey:[pkeys objectAtIndex:0]];
- }
+ if ((count = [seqs count]) == 0) {
+ NSLog(@"ERROR(%@): got no primary key expressions %@: %@",
+ self, seqName, _entity);
+ return nil;
+ }
+
+ for (i = 0; i < count - 1; i++) {
+ if ((error = [self evaluateExpressionX:[seqs objectAtIndex:i]]) != nil) {
+ NSLog(@"ERROR(%@): could not prepare next pkey value %@: %@",
+ self, [seqs objectAtIndex:i], error);
+ return nil;
}
}
- NS_HANDLER {
- pkey = nil;
+
+ seq = [seqs lastObject];
+ if ((error = [self evaluateExpressionX:seq]) != nil) {
+ NSLog(@"ERROR(%@): could not select next pkey value from sequence %@: %@",
+ self, seqName, error);
+ return nil;
}
- NS_ENDHANDLER;
-
+
+ if (![self isFetchInProgress]) {
+ NSLog(@"ERROR(%@): primary key expression returned no result: '%@'",
+ self, seq);
+ return nil;
+ }
+
+ // TODO: this is kinda slow
+ key = [self describeResults];
+ pkey = [self fetchAttributes:key withZone:NULL];
+
+ [self cancelFetch];
+
+ if (pkey != nil) {
+ pkey = [[pkey allValues] lastObject];
+ pkey = [NSDictionary dictionaryWithObject:pkey
+ forKey:[pkeys objectAtIndex:0]];
+ }
+
return pkey;
}
}
switch (_type) {
- case FIELD_TYPE_TINY:
- // ??: SQLClient => v = [NSString stringWithFormat: @"%u", *p];
- ; /* fall through */
+ case FIELD_TYPE_TINY: return [self initWithChar:atoi(_v)];
+ case FIELD_TYPE_SHORT: return [self initWithShort:atoi(_v)];
+ case FIELD_TYPE_LONG: return [self initWithLong:strtol(_v, NULL, 10)];
+
+ case FIELD_TYPE_LONGLONG:
+ return [self initWithLongLong:strtoll(_v, NULL, 10)];
+
+ case FIELD_TYPE_FLOAT: return [self initWithFloat:atof(_v)];
+ case FIELD_TYPE_DOUBLE: return [self initWithDouble:atof(_v)];
+
default:
- NSLog(@"ERROR: unsupported MySQL type: %i", _type);
+ NSLog(@"ERROR(%s): unsupported MySQL type: %i (len=%d)",
+ __PRETTY_FUNCTION__, _type, _len);
[self release];
return nil;
}
}
-#if 0
-- (id)initWithMySQL4Int:(int)_value {
- return [self initWithInt:_value];
-}
-- (id)initWithMySQL4Double:(double)_value {
- return [self initWithDouble:_value];
-}
-- (id)initWithMySQL4Text:(const unsigned char *)_value {
- return index(_value, '.') != NULL
- ? [self initWithDouble:atof(_value)]
- : [self initWithInt:atoi(_value)];
-}
-
-- (id)initWithMySQL4Data:(const void *)_value length:(int)_length {
- switch (_length) {
- case 1: return [self initWithUnsignedChar:*(char *)_value];
- case 2: return [self initWithShort:*(short *)_value];
- case 4: return [self initWithInt:*(int *)_value];
- case 8: return [self initWithDouble:*(double *)_value];
- }
-
- [self release];
- return nil;
-}
-#endif
-
/* generation */
- (NSString *)stringValueForMySQL4Type:(NSString *)_type