diff --git a/ChangeLog b/ChangeLog
index 0bcdb79..c812a8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,112 @@
+2014-04-26 Manuel Guesdon
+ * EOAccess/EOAdaptorChannel.m
+ call delegate -adaptorChannel:willPerformOperations:
+ * EOAccess/EODatabaseContext.m:
+ propagate delegate to channel
+ fix objectsForSourceGlobalID:relationshipName:editingContext:
+ isToManyToOne case
+ * EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m:
+ call delegate methods
+ adding assert to catch bad dates
+ use adaptor -primaryKeySequenceNameFormat
+ * EOAccess/EOrelationship.m
+ implement -isParentRelationship
+ verify/clean -isReciprocalToRelationship:
+ implement -qualifierWithSourceRow:
+ small fix on -removeJoin:
+ use batch faulting when -setNumberOfToManyFaultsToBatchFetch:
+ improve -setIsMandatory
+ fix exception message -validateValue:
+ clean -_intermediateAttributes
+ clean -isMultiHop
+ implement -primaryKeyForTargetRowFromSourceDBSnapshot:
+ implement -_setSourceToDestinationKeyMap:
+ implement -qualifierForDBSnapshot:
+ fix/implement -isToManyToOne
+ fix -foreignKeyInDestination
+ implement -isPropagatesPrimaryKeyPossible
+ implement -qualifierOmittingAuxiliaryQualifierWithSourceRow
+ implement -auxiliaryQualifier
+ implement -setAuxiliaryQualifier:
+ clean -_sourceRowToForeignKeyMapping
+ add comment in -_sourceAttributeNames
+ fix -joinForAttribute:
+ fix -_flushCache
+ fix -_stringFromDeleteRule:
+ implement -_rightSideKeyMap
+ implement -_leftSideKeyMap
+ implement -_substitutionRelationshipForRow:
+ fix -isFlattened
+ remove _componentRelationships
+ * EOAccess/EORelationship.h
+ remove _componentRelationships
+ * EOAccess/EOEntityPriv.[hm]
+ fix _hiddenRelationships return type
+ * EOAccess/Entity.m:
+ implement -_mapAttribute:toDestinationAttributeInLastComponentOfRelationshipPath:
+ implement -_inverseRelationshipPathForPath:
+ implement -_relationshipPathHasIdenticalKeys:
+ rewrite & fix -_keyMapForRelationshipPath:
+ rewrite & fix -_keyMapForIdenticalKeyRelationshipPath:
+ implement -valueForSQLExpression:
+ fix -validateObjectForDelete:
+ implement -qualifierForDBSnapshot:
+ fix -_addAttributesToFetchForRelationshipPath:atts:
+ fix -_parsePropertyName:
+ implement -fetchSpecificationNamed:
+ implement +externalNameForInternalName:separatorString:useAllCaps:
+ implement +nameForExternalName:separatorString:initialCaps:
+ implement -stringByMarkingUpcaseTransitionsWithDelimiter
+ implement -snapshotKeyForAttributeName:
+ implement -_flattenedAttNameToSnapshotKeyMapping
+ fix -_attributesToFetch
+ fix -_attributesToSave
+ * EOAccess/Entity.h:
+ fix _inverseRelationshipPathForPath:
+ fix -_relationshipPathHasIdenticalKey:
+ add _flgas.isSingleTableEntity
+ * EOAccess/EntityPriv.h:
+ fix -qualifierForDBSnapshot:
+ * EOAccess/EOPrivate.[hm]
+ add GDL2_EORelationshipClass
+ add GDL2_EOEntityClass
+ * EOAccess/EOModel.m:
+ cache [EOEntity class]
+ add -propertyListForEntity:name: to enable subclassing
+ * EOAccess/EOAttribute.m
+ fix -isFlattened
+ implement -targetAttribute
+ implement -relationshipPath
+ fix -_setDefinitionWithoutFlushingCaches:
+ fix -_normalizeDefinition:path:
+ fix -isReadOnly
+ implement -_setOverrideForKeyEnum:
+ implement -_hasAnyOverrides
+ implement -_isKeyEnumOverriden:
+ implement -_prototypeKeys
+ fix -initWithPropertyList:owner:
+ fix -readFormat
+ fix -writeFormat
+ fix -scale
+ fix -precision
+ fix -width
+ fix -allowsNull
+ fix -isReadOnly
+ fix -valueClassName
+ fix -externalType
+ fix -valueType
+ implement -_setValuesFromTargetAttribute
+ * EOAccess/EOAttribute.h
+ declare -targetAttribute
+ declare -relationshipPath
+ * EOAccess/EOAttributePriv.h
+ declare EOAttributeProtoOverrideBits enum
+ fix method arguments
+ declare _setValuesFromTargetAttribute()
+ * EOAccess/EOExpressionArray.h
+ declare -_isPropertyPath
+ * EOAccess/EOExpressionArray.m
+ implement -_isPropertyPath
2014-03-09 Sebastian Reitenbach
* EOControl/EOCheapArray.m
* EOControl/EODebug.m
diff --git a/EOAccess/EOAdaptorChannel.m b/EOAccess/EOAdaptorChannel.m
index 51ffedf..32220f3 100644
--- a/EOAccess/EOAdaptorChannel.m
+++ b/EOAccess/EOAdaptorChannel.m
@@ -599,6 +599,10 @@ prepareInsertExpressionWithRow:changedValues
int i = 0;
int count = 0;
+ if (_delegateRespondsTo.willPerformOperations)
+ adaptorOperations=[_delegate adaptorChannel: self
+ willPerformOperations: adaptorOperations];
+
count=[adaptorOperations count];
for(i = 0; i < count; i++)
diff --git a/EOAccess/EOAttribute.h b/EOAccess/EOAttribute.h
index f7da6a9..dce9054 100644
--- a/EOAccess/EOAttribute.h
+++ b/EOAccess/EOAttribute.h
@@ -68,7 +68,7 @@ typedef enum {
EOInOutParameter
} EOParameterDirection;
-
+#define EOATTRIBUTE_PROTO_OVERRIDE_BITS_COUNT 18
@interface EOAttribute : NSObject
{
NSString *_name;
@@ -94,7 +94,7 @@ typedef enum {
unsigned int allowsNull:1;
unsigned int isReadOnly:1;
unsigned int isParentAnEOEntity:1;
- unsigned int protoOverride:18;
+ unsigned int protoOverride:EOATTRIBUTE_PROTO_OVERRIDE_BITS_COUNT;
unsigned int isAttributeValueInitialized:1;
unsigned int unused : 10;
} _flags;
@@ -107,6 +107,7 @@ typedef enum {
NSString *_docComment;
id _parent; /* unretained */
+ NSString *_prototypeName;
EOAttribute *_prototype;
EOExpressionArray *_definitionArray;
EOAttribute *_realAttribute; // if the attribute is flattened //Not in EOF !
@@ -166,8 +167,6 @@ typedef enum {
- (NSString *)docComment;
-- (BOOL)isKeyDefinedByPrototype: (NSString *)key;
-
/**
* Returns YES if the attribute references aProperty, NO otherwise.
*/
@@ -176,6 +175,12 @@ typedef enum {
- (void)setParent: (id)parent;
+- (void)setEntity:(EOEntity*)entity;
+
+- (NSString*)relationshipPath;
+
+- (EOAttribute*)targetAttribute;
+
@end
@@ -219,8 +224,8 @@ typedef enum {
- (void)setDocComment: (NSString *)docComment;
-- (id)_normalizeDefinition: (EOExpressionArray *)definition
- path: (id)path;
+- (id)_normalizeDefinition: (id)definition
+ path: (NSArray *)path;
@end
diff --git a/EOAccess/EOAttribute.m b/EOAccess/EOAttribute.m
index 9b0b4e5..a654ee9 100644
--- a/EOAccess/EOAttribute.m
+++ b/EOAccess/EOAttribute.m
@@ -64,6 +64,7 @@ RCS_ID("$Id$")
#include
#include
#include
+#include
#include
#include
@@ -79,6 +80,7 @@ RCS_ID("$Id$")
#include "EOEntityPriv.h"
#include "EOAttributePriv.h"
+static NSArray* staticPrototypeKeys=nil;
@implementation EOAttribute
@@ -88,7 +90,21 @@ RCS_ID("$Id$")
if (!initialized)
{
initialized=YES;
-
+ //Order is important (Cf overide ProtoOverrideBits)
+ ASSIGN(staticPrototypeKeys,
+ ([NSArray arrayWithObjects:
+ @"externalType", @"columnName", @"readOnly",
+ @"valueClassName", @"valueType", @"width",
+ @"precision", @"scale", @"writeFormat",
+ @"readFormat",@"userInfo", @"serverTimeZone",
+ @"valueFactoryMethodName",
+ @"adaptorValueConversionMethodName",
+ @"factoryMethodArgumentType", @"allowsNull",
+ @"parameterDirection", @"_internalInfo", nil]));
+ NSAssert(EOATTRIBUTE_PROTO_OVERRIDE_BITS_COUNT==EOAttributeProtoOverrideBits__count,
+ @"Mismatch ProtoOverrideBits count");
+ NSAssert(EOATTRIBUTE_PROTO_OVERRIDE_BITS_COUNT==[staticPrototypeKeys count],
+ @"Mismatch ProtoOverrideBits keys count");
GDL2_EOAccessPrivateInit();
}
}
@@ -105,11 +121,12 @@ RCS_ID("$Id$")
{
EOAttribute * attr = [[[self alloc] init] autorelease];
- if (attr) {
- [attr setName: def];
- [attr setParent: parent];
- [attr setDefinition: def];
- }
+ if (attr)
+ {
+ [attr setName: def];
+ [attr setParent: parent];
+ [attr setDefinition: def];
+ }
return attr;
}
@@ -124,13 +141,24 @@ RCS_ID("$Id$")
// set this first so the name can validate against the parent.
[self setParent: owner];
+
[self setName: [propertyList objectForKey: @"name"]];
+ //Next set prototyName so prototype override can work
+ tmpString = [propertyList objectForKey: @"prototypeName"];
+ if (tmpString)
+ {
+ EOAttribute *attr = [[_parent model] prototypeAttributeNamed: tmpString];
+
+ if (attr)
+ [self setPrototype: attr];
+ }
+
[self setExternalType: [propertyList objectForKey: @"externalType"]];
tmpString = [propertyList objectForKey: @"allowsNull"];
- if (tmpString)
- [self setAllowsNull: [tmpString boolValue]];
+ if (tmpString || _prototypeName==nil)
+ [self setAllowsNull: tmpString!=nil && [tmpString boolValue]];
[self setValueType: [propertyList objectForKey: @"valueType"]];
[self setValueClassName: [propertyList objectForKey: @"valueClassName"]];
@@ -251,33 +279,26 @@ RCS_ID("$Id$")
- (void)awakeWithPropertyList: (NSDictionary *)propertyList
{
- //Seems OK
- NSString *definition;
- NSString *columnName;
- NSString *tmpString;
-
- definition = [propertyList objectForKey: @"definition"];
-
+ NSString *definition = [propertyList objectForKey: @"definition"];
if (definition)
- [self setDefinition: definition];
-
- columnName = [propertyList objectForKey: @"columnName"];
-
- if (columnName)
- [self setColumnName: columnName];
-
- tmpString = [propertyList objectForKey: @"prototypeName"];
-
- if (tmpString)
{
- EOAttribute *attr = [[_parent model] prototypeAttributeNamed: tmpString];
-
- if (attr)
- [self setPrototype: attr];
+ [self _setDefinitionWithoutFlushingCaches: definition];
+ [_parent _setIsEdited];
+ }
+ else
+ {
+ NSString *columnName=[propertyList objectForKey: @"columnName"];
+ if (columnName)
+ [self setColumnName: columnName];
+ else
+ {
+ NSString *externalName=[propertyList objectForKey: @"externalName"];
+ if ([externalName isKindOfClass:[NSString class]])
+ [self setColumnName: externalName];
+ else if ([externalName isKindOfClass:[NSDictionary class]])
+ ASSIGN(_definitionArray,[self _objectForPList:(NSDictionary*)externalName]);
+ }
}
-
- EOFLOGObjectLevelArgs(@"gsdb", @"Attribute %@ awakeWithPropertyList:%@",
- self, propertyList);
}
- (void)encodeIntoPropertyList: (NSMutableDictionary *)propertyList
@@ -303,7 +324,7 @@ RCS_ID("$Id$")
if (_valueFactoryMethodName)
{
- NSString *methodArg;
+ NSString *methodArg = nil;
[propertyList setObject: _valueFactoryMethodName
forKey: @"valueFactoryMethodName"];
@@ -371,6 +392,7 @@ RCS_ID("$Id$")
- (void)dealloc
{
DESTROY(_name);
+ DESTROY(_prototypeName);
DESTROY(_prototype);
DESTROY(_columnName);
DESTROY(_externalType);
@@ -454,27 +476,17 @@ RCS_ID("$Id$")
- (NSString *)definition
{
- NSString *definition = nil;
-
- definition = [_definitionArray valueForSQLExpression: nil];
-
- return definition;
+ return [_definitionArray valueForSQLExpression: nil];
}
- (NSString *)readFormat
{
- if (_readFormat)
- return _readFormat;
-
- return [_prototype readFormat];
+ return _readFormat;
}
- (NSString *)writeFormat
{
- if (_writeFormat)
- return _writeFormat;
-
- return [_prototype writeFormat];
+ return _writeFormat;
}
- (NSDictionary *)userInfo
@@ -482,6 +494,11 @@ RCS_ID("$Id$")
return _userInfo;
}
+- (NSDictionary *)internalInfo
+{
+ return _internalInfo;
+}
+
- (NSString *)docComment
{
return _docComment;
@@ -496,35 +513,17 @@ RCS_ID("$Id$")
*/
- (int)scale
{
- if (_scale)
- return _scale;
-
- if (_prototype)
- return [_prototype scale];
-
- return 0;
+ return _scale;
}
- (unsigned)precision
{
- if (_precision)
- return _precision;
-
- if (_prototype)
- return [_prototype precision];
-
- return 0;
+ return _precision;
}
- (unsigned)width
{
- if (_width)
- return _width;
-
- if (_prototype)
- return [_prototype width];
-
- return 0;
+ return _width;
}
- (id)parent
@@ -549,18 +548,7 @@ RCS_ID("$Id$")
- (BOOL)allowsNull
{
- if (_flags.allowsNull)
- return _flags.allowsNull;
-
- if (_prototype)
- return [_prototype allowsNull];
-
- return NO;
-}
-
-- (BOOL)isKeyDefinedByPrototype:(NSString *)key
-{
- return NO; // TODO
+ return _flags.allowsNull;
}
- (EOStoredProcedure *)storedProcedure
@@ -573,14 +561,12 @@ RCS_ID("$Id$")
- (BOOL)isReadOnly
{
-//call isDerived
if (_flags.isReadOnly)
- return _flags.isReadOnly;
-
- if (_prototype)
- return [_prototype isReadOnly];
-
- return NO;
+ return YES;
+ else if ([self isDerived] && ![self isFlattened])
+ return YES;
+ else
+ return NO;
}
/**
@@ -592,11 +578,7 @@ RCS_ID("$Id$")
**/
- (BOOL)isDerived
{
- //Seems OK
- if(_definitionArray)
- return YES;
-
- return NO;
+ return (_definitionArray==nil ? NO : YES);
}
@@ -608,12 +590,28 @@ RCS_ID("$Id$")
**/
- (BOOL)isFlattened
{
- BOOL isFlattened = NO;
- // Seems OK
-
- if(_definitionArray)
- isFlattened = [_definitionArray isFlattened];
-
+ //TODO cahe result ?
+ BOOL isFlattened=NO;
+ if (_definitionArray!=nil)
+ {
+ int definitionArrayCount=[_definitionArray count];
+ if (definitionArrayCount>=2)
+ {
+ BOOL cont=YES;
+ int i=0;
+ for(i=0;i0)
+ [s appendString:@"."];
+ [s appendString:[[_definitionArray objectAtIndex:i] name]];
+ }
+ return [NSString stringWithString:s];
+ }
+ else
+ return nil;
+}
+
+- (EOAttribute*)targetAttribute
+{
+ if([self isFlattened])
+ return [_definitionArray lastObject];
+ else
+ return nil;
}
@end
@@ -735,11 +765,8 @@ RCS_ID("$Id$")
NSString *value=nil;
if (sqlExpression != nil)
- {
- return [sqlExpression sqlStringForAttribute:self];
- }
-
- if (_definitionArray)
+ value=[sqlExpression sqlStringForAttribute:self];
+ else if (_definitionArray)
value = [_definitionArray valueForSQLExpression: sqlExpression];
else
value = [self name];
@@ -756,8 +783,11 @@ RCS_ID("$Id$")
const char *p, *s = [name cString];
int exc = 0;
- if ([_name isEqual:name]) return nil;
- if (!name || ![name length]) exc++;
+ if ([_name isEqual:name])
+ return nil;
+
+ if (!name || ![name length])
+ exc++;
if (!exc)
{
@@ -832,83 +862,143 @@ RCS_ID("$Id$")
{
if ([_name isEqual: name]==NO)
{
- NSString *oldName = nil;
[[self validateName: name] raise];
- oldName = AUTORELEASE(RETAIN(_name));
+ AUTORELEASE(RETAIN(_name));
[self willChange];
ASSIGNCOPY(_name, name);
if (_flags.isParentAnEOEntity)
- {
- [_parent _setIsEdited];
- }
+ [_parent _setIsEdited];
}
-
}
- (void)setPrototype: (EOAttribute *)prototype
{
- [self willChange];
- ASSIGN(_prototype, prototype);
+ if(_prototype != prototype
+ && ![_prototypeName isEqualToString:[prototype name]])
+ {
+ [self willChange];
+ _flags.protoOverride = 0;
+ ASSIGN(_prototypeName, [prototype name]);
+ if (_prototypeName != nil)
+ {
+ ASSIGN(_prototype,[[self _parentModel]prototypeAttributeNamed:_prototypeName]);
+ if(_prototype == nil)
+ ASSIGN(_prototype,prototype);
+ [self _updateFromPrototype];
+ }
+ else
+ {
+ DESTROY(_prototype);
+ };
+ };
}
- (void)setColumnName: (NSString *)columnName
{
- //seems OK
- [self willChange];
+ if (columnName!=nil
+ || _columnName!=nil)
+ {
+ [self willChange];
- ASSIGNCOPY(_columnName, columnName);
- DESTROY(_definitionArray);
-
- [_parent _setIsEdited];
- [self _setOverrideForKeyEnum:1];
+ ASSIGNCOPY(_columnName, columnName);
+ DESTROY(_definitionArray);
+
+ [_parent _setIsEdited];
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_columnName];
+ }
}
-- (void)_setDefinitionWithoutFlushingCaches: (NSString *)definition
+-(id)_normalizeDefinition: (id)definition
+ path: (NSArray*)path
{
- EOExpressionArray *expressionArray=nil;
-
- [self willChange];
- expressionArray = [_parent _parseDescription: definition
- isFormat: NO
- arguments: NULL];
-
- expressionArray = [self _normalizeDefinition: expressionArray
- path: nil];
- /*
- //TODO finish
- l un est code
-
- entity primaryKeyAttributes (code)
- ??
-
- [self _removeFromEntityArray:code selector:setPrimaryKeyAttributes:
- */
-
- ASSIGN(_definitionArray, expressionArray);
+ id result=nil;
+ if ([definition isKindOfClass:[NSString class]])
+ result=definition;
+ else if ([definition isKindOfClass:GDL2_EOAttributeClass])
+ {
+ EOAttribute* attribute = (EOAttribute*)definition;
+ if (attribute == self)
+ result=nil;
+ else
+ {
+ if ([attribute isDerived])
+ {
+ result = [self _normalizeDefinition:[attribute _definitionArray]
+ path:path];
+ }
+ else if ([path count] == 0)
+ {
+ result = attribute;
+ }
+ else
+ {
+ EOExpressionArray* exprArray = [EOExpressionArray expressionArray];
+ [exprArray setInfix:@"."];
+ if (path!=nil)
+ [exprArray addObjectsFromArray:path];
+ [exprArray addObject:attribute];
+ result = exprArray;
+ }
+ }
+ }
+ else if ([(EOExpressionArray*)definition _isPropertyPath])
+ {
+ int count = [(EOExpressionArray*)definition count];
+ int i=0;
+ EOExpressionArray* exprArray = [EOExpressionArray expressionArray];
+ [exprArray setInfix:@"."];
+ if (path!=nil)
+ [exprArray addObjectsFromArray:path];
+
+ for(i=0; i < count-1; i++)
+ [exprArray addObject:[(EOExpressionArray*)definition objectAtIndex:i]];
+
+ EOAttribute* attribute = [(EOExpressionArray*)definition lastObject];
+ if ([attribute isDerived])
+ {
+ result=[self _normalizeDefinition:[attribute _definitionArray]
+ path:exprArray];
+ }
+ else
+ {
+ [exprArray addObject:attribute];
+ result = exprArray;
+ }
+ }
+ else
+ {
+ int count = [(EOExpressionArray*)definition count];
+ int i=0;
+ EOExpressionArray* exprArray = [EOExpressionArray expressionArray];
+ for(i = 0; i < count; i++)
+ {
+ id aDef = [self _normalizeDefinition:[(EOExpressionArray*)definition objectAtIndex:i]
+ path:path];
+ if (aDef == nil)
+ {
+ result=nil;
+ break;
+ }
+ else if ([aDef isKindOfClass:[EOExpressionArray class]]
+ && ![(EOExpressionArray*)aDef _isPropertyPath])
+ {
+ int aDefCount = [(EOExpressionArray*)aDef count];
+ int j=0;
+ for(j=0;jSets the definition of a derived attribute.
@@ -922,52 +1012,62 @@ return nexexp
*/
- (void)setDefinition:(NSString *)definition
{
- if(definition)
+ if (definition!=nil
+ || _definitionArray!=nil)
{
[self willChange];
[self _setDefinitionWithoutFlushingCaches: definition];
- DESTROY(_columnName);
[_parent _setIsEdited];
}
}
- (void)setReadOnly: (BOOL)yn
{
- if(!yn && ([self isDerived] && ![self isFlattened]))
- [NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p: cannot set to NO while the attribute is derived but not flattened.",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self];
-
- [self willChange];
- _flags.isReadOnly = yn;
+ if (yn!=_flags.isReadOnly)
+ {
+ if(!yn && ([self isDerived] && ![self isFlattened]))
+ [NSException raise: NSInvalidArgumentException
+ format: @"%@ -- %@ 0x%p: cannot set to NO while the attribute is derived but not flattened.",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self];
+
+ [self willChange];
+ _flags.isReadOnly = yn;
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_readOnly];
+ }
}
- (void)setExternalType: (NSString *)type
{
- //OK
- [self willChange];
+ if (_externalType==nil
+ || ![_externalType isEqualToString:type])
+ {
+ [self willChange];
- ASSIGNCOPY(_externalType, type);
-
- [_parent _setIsEdited];
- [self _setOverrideForKeyEnum: 0];//TODO
+ ASSIGNCOPY(_externalType, type);
+
+ [_parent _setIsEdited];
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_externalType];
+ }
}
- (void)setValueType: (NSString *)type
{
- //OK
- [self willChange];
+ if (_valueType==nil
+ || ![_valueType isEqualToString:type])
+ {
+ [self willChange];
- ASSIGNCOPY(_valueType, type);
-
- if ([_valueType length]==1)
- _valueTypeCharacter = [_valueType characterAtIndex:0];
- else
- _valueTypeCharacter = '\0';
-
- [self _setOverrideForKeyEnum: 4];//TODO
+ ASSIGNCOPY(_valueType, type);
+
+ if ([_valueType length]==1)
+ _valueTypeCharacter = [_valueType characterAtIndex:0];
+ else
+ _valueTypeCharacter = '\0';
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_valueType];
+ }
}
- (void)setValueClassName: (NSString *)name
@@ -980,53 +1080,66 @@ return nexexp
_flags.isAttributeValueInitialized = NO;
- [self _setOverrideForKeyEnum: 3];//TODO
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_valueClassName];
}
- (void)setWidth: (unsigned)length
{
[self willChange];
_width = length;
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_width];
}
- (void)setPrecision: (unsigned)precision
{
[self willChange];
_precision = precision;
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_precision];
}
- (void)setScale: (int)scale
{
[self willChange];
_scale = scale;
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_scale];
}
- (void)setAllowsNull: (BOOL)allowsNull
{
- //OK
- [self willChange];
+ if (allowsNull!=_flags.allowsNull)
+ {
+ [self willChange];
- _flags.allowsNull = allowsNull;
-
- [self _setOverrideForKeyEnum: 15];//TODO
+ _flags.allowsNull = allowsNull;
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_allowsNull];
+ }
}
- (void)setWriteFormat: (NSString *)string
{
[self willChange];
ASSIGNCOPY(_writeFormat, string);
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_writeFormat];
}
- (void)setReadFormat: (NSString *)string
{
[self willChange];
ASSIGNCOPY(_readFormat, string);
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_readFormat];
}
- (void)setParameterDirection: (EOParameterDirection)parameterDirection
{
[self willChange];
_parameterDirection = parameterDirection;
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_parameterDirection];
}
- (void)setUserInfo: (NSDictionary *)dictionary
@@ -1037,7 +1150,7 @@ return nexexp
ASSIGN(_userInfo, dictionary);
[_parent _setIsEdited];
- [self _setOverrideForKeyEnum: 10];//TODO
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_userInfo];
}
- (void)setInternalInfo: (NSDictionary *)dictionary
@@ -1046,7 +1159,7 @@ return nexexp
[self willChange];
ASSIGN(_internalInfo, dictionary);
[_parent _setIsEdited];
- [self _setOverrideForKeyEnum: 10]; //TODO
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_internalInfo];
}
- (void)setDocComment: (NSString *)docComment
@@ -1128,6 +1241,8 @@ return nexexp
{
[self willChange];
ASSIGN(_serverTimeZone, tz);
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_serverTimeZone];
}
@end
@@ -1152,7 +1267,8 @@ return nexexp
NSData *value = nil;
Class valueClass = [self _valueClass];
- if (valueClass != Nil && valueClass != GDL2_NSDataClass)
+ if (valueClass != Nil
+ && valueClass != GDL2_NSDataClass)
{
switch (_argumentType)
{
@@ -1161,7 +1277,7 @@ return nexexp
//For efficiency reasons, the returned value is NOT autoreleased !
value = [GDL2_alloc(NSData) initWithBytes: bytes length: length];
- // If we have a value factiry method, call it to get the final value
+ // If we have a value factory method, call it to get the final value
if(_valueFactoryMethod != NULL)
{
NSData* tmp = value;
@@ -1261,7 +1377,7 @@ return nexexp
length: length
encoding: encoding];
- // If we have a value factiry method, call it to get the final value
+ // If we have a value factory method, call it to get the final value
if(_valueFactoryMethod != NULL)
{
value = [((id)valueClass) performSelector: _valueFactoryMethod
@@ -1593,6 +1709,8 @@ See also: -setFactoryMethodArgumentType:
[self willChange];
ASSIGNCOPY(_valueFactoryMethodName, factoryMethodName);
_valueFactoryMethod = NSSelectorFromString(_valueFactoryMethodName);
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_valueFactoryMethodName];
}
/**
@@ -1609,6 +1727,8 @@ See also: -setFactoryMethodArgumentType:
_adaptorValueConversionMethod
= NSSelectorFromString(_adaptorValueConversionMethodName);
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_adaptorValueConversionMethodName];
}
/** Set the type of argument needed by the factoryMethod.
@@ -1631,6 +1751,8 @@ See also: -setValueFactoryMethodName:, -factoryMethodArgumentType
{
[self willChange];
_argumentType = argumentType;
+
+ [self _setOverrideForKeyEnum: EOAttributeProtoOverrideBits_factoryMethodArgumentType];
}
@end
@@ -1935,42 +2057,228 @@ More details:
return valueTypeCharacter;
};
+- (void)_setDefinitionWithoutFlushingCaches: (NSString *)definition
+{
+ if (_parent != nil)
+ {
+ [self willChange];
+ DESTROY(_columnName);
+ if (definition==nil)
+ {
+ DESTROY(_definitionArray);
+ }
+ else
+ {
+ EOExpressionArray* exprArray = [_parent _parseDescription: definition
+ isFormat: NO
+ arguments: NULL];
+ if (exprArray!=nil)
+ {
+ if (![exprArray isKindOfClass:[EOExpressionArray class]])
+ exprArray=[EOExpressionArray arrayWithObject:exprArray];
+ exprArray = [self _normalizeDefinition: exprArray
+ path: nil];
+ }
+ ASSIGN(_definitionArray,exprArray);
+ [self _removeFromEntityArray:[_parent primaryKeyAttributes]
+ selector:@selector(setPrimaryKeyAttributes:)];
+ }
+ }
+}
+
+- (EOModel*)_parentModel
+{
+ return [_parent model];
+}
+
+- (void)_removeFromEntityArray:(NSArray*)entityArray
+ selector:(SEL)setSelector
+{
+ if ([entityArray indexOfObject:self]!=NSNotFound)
+ {
+ NSMutableArray* a = AUTORELEASE([entityArray mutableCopy]);
+ [a removeObjectIdenticalTo:self];
+ [[self entity] performSelector:setSelector
+ withObject:a];
+ }
+}
+
+-(EOExpressionArray*)_objectForPList:(NSDictionary*)pList
+{
+ EOExpressionArray* result=nil;
+ if ([pList isKindOfClass:[NSString class]])
+ result=(EOExpressionArray*)pList;
+ else if(![pList isKindOfClass:[NSDictionary class]])
+ result=nil;
+ else
+ {
+ NSDictionary* pListDict = (NSDictionary*)pList;
+ NSString* tmpString=nil;
+
+ tmpString=[pListDict objectForKey:@"name"];
+ if (tmpString!=nil)
+ result=[[self entity] _parsePropertyName:tmpString];
+ else
+ {
+ tmpString=[pListDict objectForKey:@"path"];
+ if (tmpString!=nil)
+ result=[[self entity]_parsePropertyName:tmpString];
+ else
+ {
+ NSArray* array=[pListDict objectForKey:@"array"];
+ if (array==nil)
+ result=nil;
+ else
+ {
+ int count = [array count];
+ EOExpressionArray* exprArray = [EOExpressionArray expressionArray];
+
+ tmpString=[pListDict objectForKey:@"prefix"];
+ if (tmpString!=nil)
+ [exprArray setPrefix:tmpString];
+
+ tmpString=[pListDict objectForKey:@"infix"];
+ if (tmpString!=nil)
+ [exprArray setInfix:tmpString];
+
+ tmpString=[pListDict objectForKey:@"suffix"];
+ if (tmpString!=nil)
+ [exprArray setSuffix:tmpString];
+
+ if (count>0)
+ {
+ int i=0;
+ for(i=0;i
#include
#endif
+#include
#include
#include
@@ -81,6 +82,7 @@ RCS_ID("$Id$")
#include
#include
#include
+#include
#include "EOPrivate.h"
#include "EOEntityPriv.h"
@@ -556,7 +558,6 @@ NSString *EONextPrimaryKeyProcedureOperation = @"EONextPrimaryKeyProcedureOperat
- (id) init
{
- //OK
if ((self = [super init]))
{
_attributes = [NSMutableArray new];
@@ -591,9 +592,9 @@ static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL select
performSelectorOnArrayWithEachObjectOfClass(_subEntities, @selector(_setParentEntity:),
nil, [EOEntity class]);
performSelectorOnArrayWithEachObjectOfClass(_attributes, @selector(setParent:),
- nil, [EOAttribute class]);
+ nil, GDL2_EOAttributeClass);
performSelectorOnArrayWithEachObjectOfClass(_relationships, @selector(setEntity:),
- nil, [EORelationship class]);
+ nil, GDL2_EORelationshipClass);
if (_classDescription) [[EOClassDescription class] invalidateClassDescriptionCache];
@@ -607,6 +608,7 @@ static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL select
DESTROY(_attributesByName);
DESTROY(_attributesToFetch);
DESTROY(_attributesToSave);
+ DESTROY(_flattenedAttNameToSnapshotKeyMapping);
DESTROY(_attributesUsedForLocking);
DESTROY(_classDescription);
DESTROY(_classForInstances);
@@ -980,7 +982,7 @@ static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL select
{
NSDictionary *relPList = [relationshipPLists
objectAtIndex: i];
- if ([relPList isKindOfClass: [EORelationship class]])
+ if ([relPList isKindOfClass: GDL2_EORelationshipClass])
continue;
{
@@ -1445,7 +1447,7 @@ static void performSelectorOnArrayWithEachObjectOfClass(NSArray *arr, SEL select
id thePropertyName;
if (!([property isKindOfClass: GDL2_EOAttributeClass]
- || [property isKindOfClass: [EORelationship class]]))
+ || [property isKindOfClass: GDL2_EORelationshipClass]))
return NO;
thePropertyName = [(EOAttribute *)property name];
@@ -2750,9 +2752,8 @@ createInstanceWithEditingContext:globalID:zone:
[self notImplemented: _cmd];
}
-- (NSArray*) _hiddenRelationships
+- (NSMutableArray*) _hiddenRelationships
{
- //OK
if (!_hiddenRelationships)
_hiddenRelationships = [NSMutableArray new];
@@ -2761,7 +2762,6 @@ createInstanceWithEditingContext:globalID:zone:
- (NSArray*) _propertyNames
{
- //OK
NSMutableArray *propertyNames = nil;
NSArray *attributes = [self attributes];
NSArray *attributeNames = [attributes resultsOfPerformingSelector:
@@ -2776,36 +2776,51 @@ createInstanceWithEditingContext:globalID:zone:
return propertyNames;
}
-- (id) _flattenAttribute: (id)param0
- relationshipPath: (id)param1
- currentAttributes: (id)param2
+- (EOAttribute*) _flattenAttribute: (EOAttribute*)attribute
+ relationshipPath: (NSString*)relationshipPath
+ currentAttributes: (NSDictionary*)currentAttributes
{
- //TODO
- return [self notImplemented: _cmd];
+ EOAttribute* flattenAttribute=nil;
+
+ //Find first available attribute name like NeededByEOF%d
+ NSMutableString* aName = [NSMutableString stringWithCapacity:14];//NeededByEOF+some space
+ int i = 0;
+ do
+ {
+ [aName appendFormat:@"NeededByEOF%d",i];
+ if ([currentAttributes objectForKey:aName]==nil)
+ break;
+ else
+ [aName setString:@""];
+ } while(1);
+
+ //Now create temporary attribute
+ flattenAttribute = AUTORELEASE([EOAttribute new]);
+ [flattenAttribute setName:aName];
+ [flattenAttribute setEntity:self];
+ [flattenAttribute _setDefinitionWithoutFlushingCaches:
+ [[relationshipPath stringByAppendingString:@"."]
+ stringByAppendingString:[attribute name]]];
+ [flattenAttribute setEntity:nil];
+ [flattenAttribute _setValuesFromTargetAttribute];
+ [flattenAttribute setEntity:self];
+ return flattenAttribute;
}
- (NSString*) snapshotKeyForAttributeName: (NSString*)attributeName
{
- NSString *attName = [self _flattenedAttNameToSnapshotKeyMapping];
-
- if (attName)
- {
- NSEmitTODO(); //TODO
- [self notImplemented: _cmd];
- }
- else
- attName = attributeName; //TODO-VERIFY
-
- return attName;
+ NSDictionary* map = [self _flattenedAttNameToSnapshotKeyMapping];
+ NSString* key = [map objectForKey:attributeName];
+ if (key==nil)
+ key=attributeName;
+ return key;
}
-- (id) _flattenedAttNameToSnapshotKeyMapping
+- (NSDictionary*) _flattenedAttNameToSnapshotKeyMapping
{
- // NSArray *attributesToSave = [self _attributesToSave];
-
- //NSEmitTODO(); //TODO
-
- return nil; //[self notImplemented:_cmd]; //TODO
+ if (_flattenedAttNameToSnapshotKeyMapping==nil)
+ [self _attributesToSave];//Build the map
+ return _flattenedAttNameToSnapshotKeyMapping;
}
- (EOMKKDSubsetMapping*) _snapshotToAdaptorRowSubsetMapping
@@ -2886,7 +2901,7 @@ returns nil if there's no key in the instanceDictionaryInitializer
{
EORelationship *classProperty = [classProperties objectAtIndex: i];
- if ([classProperty isKindOfClass: [EORelationship class]])
+ if ([classProperty isKindOfClass: GDL2_EORelationshipClass])
{
EORelationship *relsubs = [classProperty
_substitutionRelationshipForRow: row];
@@ -2933,16 +2948,20 @@ returns nil if there's no key in the instanceDictionaryInitializer
- (NSArray*) _attributesToSave
{
- //Near OK
EOFLOGObjectLevelArgs(@"EOEntity",
@"START Entity _attributesToSave entityname=%@",
[self name]);
if (!_attributesToSave)
{
+ EOAttribute* attribute=nil;
NSArray *attributesToFetch = [self _attributesToFetch];
- int i, count = [attributesToFetch count];
- NSMutableArray *attributesToSave = [NSMutableArray arrayWithCapacity:count];
+ int attributesToFetchCount = [attributesToFetch count];
+ int i=0;
+ NSMutableString* aName = [NSMutableString stringWithCapacity:128];
+ NSMutableDictionary* attrToSaveByName = [NSMutableDictionary dictionaryWithCapacity:attributesToFetchCount];
+ NSMutableDictionary* flattenAttrByPath = nil;
+ NSMutableSet* processedPathes = nil;
NSAssert3(!attributesToFetch
|| [attributesToFetch isKindOfClass: [NSArray class]],
@@ -2951,35 +2970,135 @@ returns nil if there's no key in the instanceDictionaryInitializer
[_attributesToFetch class],
_attributesToFetch);
- for (i = 0; i < count; i++)
- {
- EOAttribute *attribute = [attributesToFetch objectAtIndex: i];
- BOOL isFlattened = [attribute isFlattened];
+ for(i=attributesToFetchCount-1;i>=0;i--)
+ {
+ attribute = [attributesToFetch objectAtIndex:i];
+ [attrToSaveByName setObject:attribute
+ forKey:[attribute name]];
+ if ([attribute isFlattened])
+ {
+ if(flattenAttrByPath == nil)
+ flattenAttrByPath = [NSMutableDictionary dictionary];
+ [aName setString:@""];
+ [aName appendString:[attribute relationshipPath]];
+ [aName appendString:@"."];
+ [aName appendString:[[attribute targetAttribute]name]];
+ [flattenAttrByPath setObject:attribute
+ forKey:[NSString stringWithString:aName]];
+ };
+ }
- if (!isFlattened)
- [attributesToSave addObject: attribute];
- }
- ASSIGN(_attributesToSave, attributesToSave);
+ //Also build _flattenedAttNameToSnapshotKeyMapping !
+ if (_flattenedAttNameToSnapshotKeyMapping)
+ [_flattenedAttNameToSnapshotKeyMapping removeAllObjects];
+ else
+ _flattenedAttNameToSnapshotKeyMapping=[NSMutableDictionary new];
+
+ //We may modify the dictionary so enumerate on -allValues
+ NSEnumerator* objectEnumerator=[[attrToSaveByName allValues]objectEnumerator];
+ while((attribute=[objectEnumerator nextObject]))
+ {
+ if ([attribute isFlattened])
+ {
+ NSString* relationshipPath = [attribute relationshipPath];
+ if (![processedPathes containsObject:relationshipPath])
+ {
+ if (processedPathes == nil)
+ processedPathes = [NSMutableSet set];
+
+ [processedPathes addObject:relationshipPath];
+
+ EOEntity* destinationEntity = [[self relationshipForPath:relationshipPath] destinationEntity];
+ NSArray* dstPKAttrs = [destinationEntity primaryKeyAttributes];
+ int dstPKAttrsCount = [dstPKAttrs count];
+
+ if(dstPKAttrs == nil)
+ {
+ [NSException raise: @"NSIllegalStateException"
+ format: @"%@: entity '%@' has no primary key",
+ NSStringFromSelector(_cmd),
+ [destinationEntity name]];
+ }
+
+
+ for(i=dstPKAttrsCount-1;i>=0;i--)
+ {
+ EOAttribute* dstPKAttr = [dstPKAttrs objectAtIndex:i];
+ [aName setString:@""];
+ [aName appendString:relationshipPath];
+ [aName appendString:@"."];
+ [aName appendString:[dstPKAttr name]];
+ if ([flattenAttrByPath objectForKey:aName]==nil)
+ {
+ EOAttribute* flattenAttr = [self _flattenAttribute: dstPKAttr
+ relationshipPath: relationshipPath
+ currentAttributes: attrToSaveByName];
+ [attrToSaveByName setObject:flattenAttr
+ forKey:[flattenAttr name]];
+
+ [flattenAttrByPath setObject:flattenAttr
+ forKey:[NSString stringWithString:aName]];
+
+ NSDictionary* map = [attribute _sourceToDestinationKeyMap];
+ NSArray* destinationKeys = [map objectForKey:@"destinationKeys"];
+ if (destinationKeys != nil)
+ {
+ NSUInteger index=[destinationKeys indexOfObject:[dstPKAttr name]];
+ if (index!=NSNotFound)
+ {
+ NSString* sourceKey = [[map objectForKey:@"sourceKeys"] objectAtIndex:index];
+ [_flattenedAttNameToSnapshotKeyMapping setObject:sourceKey
+ forKey:[flattenAttr name]];
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ ASSIGN(_attributesToSave,([[attrToSaveByName allValues] sortedArrayUsingSelector:@selector(eoCompareOnName:)]));
}
-
- EOFLOGObjectLevelArgs(@"EOEntity", @"STOP Entity _attributesToSave entityname=%@ attrs:%@",
- [self name], _attributesToSave);
-
return _attributesToSave;
}
+-(NSArray*) _extraSingleTableAttributesToFetch:(NSArray*)alreadyFetchedAttributes
+{
+ NSMutableArray* extraAttributes = [NSMutableArray array];
+ NSArray* subEntities = [self subEntities];
+ int subEntitiesCount = [subEntities count];
+ if (subEntitiesCount>0)
+ {
+ NSMutableSet* seenAttributeNames =
+ [NSMutableSet setWithArray:[alreadyFetchedAttributes
+ resultsOfPerformingSelector:@selector(name)]];
+ int i=0;
+ for(i=0;i0)
+ {
+ int j=0;
+ for(j=0;j0)
+ {
+ NSMutableSet* processed = [NSMutableSet set];
+ NSEnumerator* enumerator = [flattenAttrsAndRels objectEnumerator];
+ id propertyName=nil;
+ while((propertyName=[enumerator nextObject]))
+ {
+ id property=[self anyAttributeNamed:propertyName];
+ if (property==nil)
+ property=[self anyRelationshipNamed:propertyName];
+ NSString* relationshipPath = [property relationshipPath];
+ NSAssert1(relationshipPath,@"No relationshipPath for %@",property);
+ if (![processed containsObject:relationshipPath])
+ {
+ [self _addAttributesToFetchForRelationshipPath:relationshipPath
+ atts: attrsByName];
+ [processed addObject:relationshipPath];
+ }
+ }
+ }
+
+ if (_flags.isSingleTableEntity)
+ {
+ NSArray* attributesToFetch = [[attrsByName allValues]sortedArrayUsingSelector:@selector(eoCompareOnName:)];
+ NSArray* extraAttrs = [self _extraSingleTableAttributesToFetch:attributesToFetch];
+ int extraAttrsCount = [extraAttrs count];
+ if (extraAttrsCount>0)
+ {
+ for(i=0;i0)
+ {
+ EOEntity* entity = self;
+ int i=0;
+ for(i=0;i0)
+ joins = [relationship joins];
+ joinsCount = [joins count];
+ if (joinsCount>0)
{
int i=0;
- IMP joinsOAI=NULL;
- IMP sanAO=NULL;
- IMP danAO=NULL;
-
- for (i = 0; i < count; i++)
- {
- EOJoin *join = GDL2_ObjectAtIndexWithImpPtr(joins,&joinsOAI,i);
- EOAttribute *sourceAttribute = [join sourceAttribute];
- EOAttribute *destinationAttribute =
+ for(i=joinsCount-1;i>=0;i--)
+ {
+ EOJoin* join = [joins objectAtIndex:i];
+ EOAttribute* sourceAttribute = [join sourceAttribute];
+ EOAttribute* destinationAttribute =
[self _mapAttribute:sourceAttribute
toDestinationAttributeInLastComponentOfRelationshipPath: path];
-
- GDL2_AddObjectWithImpPtr(sourceAttributeNames,&sanAO,
- [sourceAttribute name]);
-
- GDL2_AddObjectWithImpPtr(destinationAttributeNames,&danAO,
- [destinationAttribute name]);
- }
- };
-
- keyMap = [NSDictionary dictionaryWithObjectsAndKeys:
- sourceAttributeNames, @"sourceKeys",
- destinationAttributeNames, @"destinationKeys",
- nil, nil];
- //return something like {destinationKeys = (code); sourceKeys = (languageCode); }
-
- return keyMap;
+ [sourceKeys addObject:[sourceAttribute name]];
+ [destinationKeys addObject:[destinationAttribute name]];
+ }
+ }
+ return [NSDictionary dictionaryWithObjectsAndKeys:
+ sourceKeys, @"sourceKeys",
+ destinationKeys, @"destinationKeys",
+ nil, nil];
}
+- (NSDictionary *)_keyMapForRelationshipPath: (NSString *)path
+{
+ NSDictionary* keyMap=nil;
+ NSMutableArray* sourceKeys = nil;
+ NSMutableArray* destinationKeys = nil;
+
+ NSRange dotPos=[path rangeOfString:@"."
+ options:NSBackwardsSearch];
+ if (dotPos.length==0)//Not multihop relationshipPath
+ {
+ EORelationship* relationship = [self anyRelationshipNamed:path];
+ NSArray* joins = [relationship joins];
+ int i=0;
+ sourceKeys = [NSMutableArray array];
+ destinationKeys = [NSMutableArray array];
+ for(i=[joins count]-1;i>=0;i--)
+ {
+ EOJoin* join = [joins objectAtIndex:i];
+ [sourceKeys addObject:[[join sourceAttribute] name]];
+ [destinationKeys addObject:[[join destinationAttribute] name]];
+ }
+ }
+ else
+ {
+ if ([self _relationshipPathHasIdenticalKeys:path])
+ keyMap=[self _keyMapForIdenticalKeyRelationshipPath:path];
+ else
+ {
+ NSArray* attributesToFetch = [self _attributesToFetch];
+ int attributesToFetchCount=[attributesToFetch count];
+ EORelationship* relationship = [self relationshipForPath:path];
+ NSArray* joins = [relationship joins];
+ int joinsCount = [joins count];
+ int i = 0;
+
+ sourceKeys = [NSMutableArray array];
+ destinationKeys = [NSMutableArray array];
+
+ //Path without last component
+ NSString* beginingPath = [path substringToIndex:dotPos.location];
+
+ for(i=joinsCount-1;i>=0;i--)
+ {
+ EOJoin* join = [joins objectAtIndex:i];
+ EOAttribute* sourceAttribute = [join sourceAttribute];
+ EOAttribute* destinationAttribute = [join destinationAttribute];
+ EOAttribute* finalSourceAttribute = nil;
+ int j=0;
+ for(j=attributesToFetchCount-1;j>=0;j--)
+ {
+ finalSourceAttribute = [attributesToFetch objectAtIndex:j];
+ if ([finalSourceAttribute targetAttribute] == sourceAttribute
+ && [[finalSourceAttribute relationshipPath] isEqualToString:beginingPath]
+ && ![finalSourceAttribute isReadOnly])
+ break;
+ }
+
+ if (finalSourceAttribute == nil)
+ {
+ [NSException raise: @"NSIllegalStateException"
+ format: @"%@ entity '%@' is unable to build internal key map for relationship path '%@'",
+ NSStringFromSelector(_cmd),
+ [self name],
+ path];
+ }
+ [sourceKeys addObject:[finalSourceAttribute name]];
+ [destinationKeys addObject:[destinationAttribute name]];
+ }
+ }
+ }
+ if (!keyMap)
+ {
+ keyMap=[NSDictionary dictionaryWithObjectsAndKeys:
+ sourceKeys, @"sourceKeys",
+ destinationKeys, @"destinationKeys",
+ nil];
+ }
+ return keyMap;
+ }
+
- (EOAttribute *)_mapAttribute: (EOAttribute *)attribute
toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
{
+ EOAttribute* resultAttribute=attribute;
NSArray *components = nil;
- EORelationship *rel = nil;
- NSArray *sourceAttributes = nil;
- NSArray *destinationAttributes = nil;
- EOEntity *destinationEntity = nil;
NSAssert(attribute, @"No attribute");
NSAssert(path, @"No path");
NSAssert([path length] > 0, @"Empty path");
components = [path componentsSeparatedByString: @"."];
- NSAssert([components count] > 0, @"Empty components array");
- rel = [self relationshipNamed: [components lastObject]];
- sourceAttributes = [rel sourceAttributes];
- destinationAttributes = [rel destinationAttributes];
- destinationEntity = [rel destinationEntity];
+ int componentsCount=[components count];
+ if (componentsCount>0)
+ {
+ EOEntity *entity = self;
+ int i=0;
+ for(i=0;i0)
{
- NSArray *joins = [relationship joins];
- int count = [joins count];
-
- if (count>0)
- {
- int i=0;
- IMP joinsOAI=NULL;
- IMP skAO=NULL;
- IMP dkAO=NULL;
-
- for(i = 0; i < count; i++)
+ EOEntity* entity = self;
+ NSArray* destinationAttributes = nil;
+ int i = 0;
+ for(i=0;i0)
{
- EOJoin *join = GDL2_ObjectAtIndexWithImpPtr(joins,&joinsOAI,i);
- EOAttribute *sourceAttribute = [join sourceAttribute];
- EOAttribute *destinationAttribute = [join destinationAttribute];
-
- GDL2_AddObjectWithImpPtr(sourceKeys,&skAO,[sourceAttribute name]);
- GDL2_AddObjectWithImpPtr(destinationKeys,&dkAO,[destinationAttribute name]);
+ NSArray* sourceAttributes = [relationship sourceAttributes];
+ if(![destinationAttributes containsIdenticalObjectsWithArray:sourceAttributes]);
+ {
+ has=NO;
+ break;
+ }
}
- };
+ destinationAttributes = [relationship destinationAttributes];
+ entity = [relationship destinationEntity];
+ }
}
-
- return [NSDictionary dictionaryWithObjectsAndKeys:
- sourceKeys, @"sourceKeys",
- destinationKeys, @"destinationKeys",
- nil];
-//{destinationKeys = (code); sourceKeys = (countryCode); }
+ return has;
}
-
+
@end
@implementation EOEntity (EOEntitySQLExpression)
- (NSString*) valueForSQLExpression: (EOSQLExpression*)sqlExpression
{
- return [self notImplemented: _cmd]; //TODO
-}
-
-+ (NSString*) valueForSQLExpression: (EOSQLExpression*)sqlExpression
-{
- return [self notImplemented: _cmd]; //TODO
+ if (sqlExpression == nil)
+ return _externalName;
+ else
+ return [sqlExpression sqlStringForSchemaObjectName:_externalName];
}
@end
@@ -3435,34 +3624,53 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
- (NSException *)validateObjectForDelete: (id)object
{
-//OK ??
- NSArray *relationships = nil;
- NSEnumerator *relEnum = nil;
- EORelationship *relationship = nil;
- NSMutableArray *expArray = nil;
-
- relationships = [self relationships];
- relEnum = [relationships objectEnumerator];
-
- while ((relationship = [relEnum nextObject]))
+ NSMutableArray* exceptions = nil;
+ NSArray* relationships = [self relationships];
+ int relationshipsCount = [relationships count];
+ if (relationshipsCount>0)
{
-//classproperties
-
-//rien pour nullify
- if ([relationship deleteRule] == EODeleteRuleDeny)
+ NSArray* classProperties = [self classProperties];
+ int i=0;
+ for(i=0;i0)
+ {
+ if (!exceptions)
+ exceptions = [NSMutableArray arrayWithCapacity:5];
- [expArray addObject:
- [NSException validationExceptionWithFormat:
- @"delete operation for relationship key %@ refused",
- [relationship name]]];
- }
+ [exceptions addObject:
+ [NSException validationExceptionWithFormat:
+ @"Removal of '%@' object denied: in its '%@' relationship because there are related objects",
+ [object entityName],
+ [relationship name]]];
+ }
+ }
+ else
+ {
+ if (!exceptions)
+ exceptions = [NSMutableArray arrayWithCapacity:5];
+
+ [exceptions addObject:
+ [NSException validationExceptionWithFormat:
+ @"Removal of '%@' object denied: in its '%@' relationship because there is a related object",
+ [object entityName],
+ [relationship name]]];
+ }
+ }
+ }
+ }
}
-
- if (expArray)
- return [NSException aggregateExceptionWithExceptions:expArray];
+ if (exceptions)
+ return [NSException aggregateExceptionWithExceptions:exceptions];
else
return nil;
}
@@ -3470,7 +3678,6 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
/** Retain an array of name of all EOAttributes **/
- (NSArray*) classPropertyAttributeNames
{
- //Should be OK
if (!_classPropertyAttributeNames)
{
int i=0;
@@ -3487,9 +3694,6 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
[(NSMutableArray*)_classPropertyAttributeNames
addObject: [property name]];
};
-
- EOFLOGObjectLevelArgs(@"EOEntity", @"_classPropertyAttributeNames=%@",
- _classPropertyAttributeNames);
}
return _classPropertyAttributeNames;
@@ -3497,12 +3701,10 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
- (NSArray*) classPropertyToManyRelationshipNames
{
- //Should be OK
if (!_classPropertyToManyRelationshipNames)
{
NSArray *classProperties = [self classProperties];
int i, count = [classProperties count];
- Class relClass = [EORelationship class];
_classPropertyToManyRelationshipNames = [NSMutableArray new];
@@ -3510,7 +3712,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
{
EORelationship *property = [classProperties objectAtIndex: i];
- if ([property isKindOfClass: relClass]
+ if ([property isKindOfClass:GDL2_EORelationshipClass]
&& [property isToMany])
[(NSMutableArray*)_classPropertyToManyRelationshipNames
addObject: [property name]];
@@ -3522,12 +3724,10 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
- (NSArray*) classPropertyToOneRelationshipNames
{
- //Should be OK
if (!_classPropertyToOneRelationshipNames)
{
NSArray *classProperties = [self classProperties];
int i, count = [classProperties count];
- Class relClass = [EORelationship class];
_classPropertyToOneRelationshipNames = [NSMutableArray new]; //or GC ?
@@ -3535,7 +3735,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
{
EORelationship *property = [classProperties objectAtIndex: i];
- if ([property isKindOfClass: relClass]
+ if ([property isKindOfClass:GDL2_EORelationshipClass]
&& ![property isToMany])
[(NSMutableArray*)_classPropertyToOneRelationshipNames
addObject: [property name]];
@@ -3545,56 +3745,78 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
return _classPropertyToOneRelationshipNames;
}
-- (id) qualifierForDBSnapshot:(id)param0
+- (EOQualifier*) qualifierForDBSnapshot:(NSDictionary*)dbSnapshot
{
- return [self notImplemented: _cmd]; //TODO
+ return [self qualifierForPrimaryKey:dbSnapshot];
}
- (void) _addAttributesToFetchForRelationshipPath: (NSString*)relPath
atts: (NSMutableDictionary*)attributes
{
- NSArray *parts = nil;
- EORelationship *rel = nil;
-
- NSAssert([relPath length] > 0, @"Empty relationship path");
-
- //Verify when multi part path and not _relationshipPathIsToMany:path
- parts = [relPath componentsSeparatedByString: @"."];
- rel = [self relationshipNamed: [parts objectAtIndex: 0]];
-
- if (!rel)
+ NSRange r=[relPath rangeOfString:@"."];
+ BOOL isMultiHopRelPath = (r.length>0);
+ if (!isMultiHopRelPath
+ || [self _relationshipPathIsToMany:relPath]
+ || [self _relationshipPathHasIdenticalKeys:relPath])
{
- NSEmitTODO(); //TODO
- //TODO
+ NSString* firstPathComponent =
+ (isMultiHopRelPath ? [relPath substringToIndex:r.location] : relPath);
+ EORelationship* relationship = [self relationshipNamed:firstPathComponent];
+ NSArray* joins = [relationship joins];
+ int joinsCount = [joins count];
+ if (joinsCount>0)
+ {
+ int i = 0;
+ for(i=0;i0)
- {
- int i=0;
- IMP joinsOAI=NULL;
- IMP attributesSOFK=NULL;
-
- for (i = 0; i < count; i++)
- {
- EOJoin *join = GDL2_ObjectAtIndexWithImpPtr(joins,&joinsOAI,i);
- EOAttribute *attribute = [join sourceAttribute];
-
- GDL2_SetObjectForKeyWithImpPtr(attributes,&attributesSOFK,
- attribute,[attribute name]);
- }
- };
+ EORelationship* relationship = [self relationshipForPath:relPath];
+ NSRange rLast=[relPath rangeOfString:@"."
+ options:NSBackwardsSearch];
+ NSString* firstPathComponents = [relPath substringToIndex:rLast.location];
+ NSArray* joins = [relationship joins];
+ int joinsCount = [joins count];
+ if (joinsCount>0)
+ {
+ EOAttribute* attribute = nil;
+ int i = 0;
+ for(i=0;i 0, @"Path is empty (%p)", path);
expressionArray = [EOExpressionArray expressionArrayWithPrefix: nil
@@ -3833,7 +4046,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
if (relationship)
{
- NSAssert2([relationship isKindOfClass: [EORelationship class]],
+ NSAssert2([relationship isKindOfClass: GDL2_EORelationshipClass],
@"relationship is not a EORelationship but a %@. relationship:\n%@",
[relationship class],
relationship);
@@ -3898,8 +4111,6 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p expressionArray=%@",
self, expressionArray);
-
-
return expressionArray;
}
@@ -3910,8 +4121,6 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
NSArray *components = nil;
int i, count = 0;
-
-
EOFLOGObjectLevelArgs(@"EOEntity", @"self=%p self name=%@ propertyName=%@",
self, [self name], propertyName);
@@ -3936,15 +4145,14 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
if (relationship)
{
- NSAssert2([relationship isKindOfClass: [EORelationship class]],
+ NSAssert2([relationship isKindOfClass: GDL2_EORelationshipClass],
@"relationship is not a EORelationship but a %@. relationship:\n%@",
[relationship class],
relationship);
if ([relationship isFlattened])
{
- NSEmitTODO(); //TODO
- [self notImplemented: _cmd];//TODO
+ [expressionArray addObjectsFromArray: [relationship _definitionArray]];
}
else
{
@@ -4029,13 +4237,6 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
- (void) dealloc
{
- //OK
- EOFLOGObjectLevelArgs(@"EOEntity", @"Deallocate EOEntityClassDescription %p",
- self);
-
- fflush(stdout);
- fflush(stderr);
-
DESTROY(_entity);
[super dealloc];
@@ -4056,9 +4257,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
- (EOFetchSpecification *)fetchSpecificationNamed: (NSString *)name
{
- NSEmitTODO(); //TODO
- [self notImplemented: _cmd];
- return nil;
+ return [_entity fetchSpecificationNamed:name];
}
- (NSString *)entityName
@@ -4170,26 +4369,9 @@ fromInsertionInEditingContext: (EOEditingContext *)context
- (EOClassDescription *)classDescriptionForDestinationKey: (NSString *)detailKey
{
- EOClassDescription *cd = nil;
- EOEntity *destEntity = nil;
- EORelationship *rel = nil;
-
-
-
- EOFLOGObjectLevelArgs(@"EOEntity", @"detailKey=%@", detailKey);
- EOFLOGObjectLevelArgs(@"EOEntity", @"_entity name=%@", [_entity name]);
-
- rel = [_entity relationshipNamed: detailKey];
- EOFLOGObjectLevelArgs(@"EOEntity", @"rel=%@", rel);
-
- destEntity = [rel destinationEntity];
- EOFLOGObjectLevelArgs(@"EOEntity", @"destEntity name=%@", [destEntity name]);
-
- cd = [destEntity classDescriptionForInstances];
- EOFLOGObjectLevelArgs(@"EOEntity", @"cd=%@", cd);
-
-
-
+ EORelationship *rel = [_entity relationshipNamed: detailKey];
+ EOEntity *destEntity = [rel destinationEntity];
+ EOClassDescription *cd = [destEntity classDescriptionForInstances];
return cd;
}
@@ -4208,12 +4390,12 @@ fromInsertionInEditingContext: (EOEditingContext *)context
globalID, [_entity name]);
if (objectClass)
- {
- obj = AUTORELEASE([[objectClass allocWithZone:zone]
- initWithEditingContext: editingContext
- classDescription: self
- globalID: globalID]);
- }
+ {
+ obj = AUTORELEASE([[objectClass allocWithZone:zone]
+ initWithEditingContext: editingContext
+ classDescription: self
+ globalID: globalID]);
+ }
return obj;
}
@@ -4232,18 +4414,8 @@ fromInsertionInEditingContext: (EOEditingContext *)context
- (EODeleteRule)deleteRuleForRelationshipKey: (NSString *)relationshipKey
{
- EORelationship *rel = nil;
- EODeleteRule deleteRule = 0;
-
-
-
- rel = [_entity relationshipNamed: relationshipKey];
- EOFLOGObjectLevelArgs(@"EOEntity", @"relationship %p=%@", rel, rel);
-
- deleteRule = [rel deleteRule];
- EOFLOGObjectLevelArgs(@"EOEntity", @"deleteRule=%d", (int)deleteRule);
-
-
+ EORelationship *rel = [_entity relationshipNamed: relationshipKey];
+ EODeleteRule deleteRule = [rel deleteRule];
return deleteRule;
}
@@ -4378,22 +4550,112 @@ returns nil if there's no key in the instanceDictionaryInitializer
separatorString: (NSString *)separatorString
initialCaps: (BOOL)initialCaps
{
- NSEmitTODO(); //TODO
- [self notImplemented: _cmd];
- return nil;
+ NSString* name=nil;
+ NSRange dotPos=[externalName rangeOfString:@"."];
+ if (dotPos.length==0
+ && ![externalName isEqualToString:[externalName lowercaseString]]
+ && ![externalName isEqualToString:[externalName uppercaseString]])
+ {
+ if(!initialCaps
+ && uni_toupper([externalName characterAtIndex:0])==[externalName characterAtIndex:0])//is uppercase first character ?
+ {
+ name=[[[externalName substringToIndex:1] lowercaseString]
+ stringByAppendingString:[externalName substringFromIndex:1]];
+ }
+ else
+ name=externalName;
+ }
+ else
+ {
+ name=[NSMutableString stringWithCapacity:[externalName length]];
+ NSArray* parts = [externalName componentsSeparatedByString: separatorString];
+ int partsCount = [parts count];
+ int i=0;
+ BOOL isFirst = YES;
+ for(i = 0; i < partsCount; i++)
+ {
+ NSString* part = [parts objectAtIndex:i];
+ if ([part length]>0)
+ {
+ if(!initialCaps
+ && isFirst)
+ {
+ part = [part lowercaseString];
+ isFirst = NO;
+ }
+ else
+ {
+ part = [part capitalizedString];
+ }
+ [(NSMutableString*)name appendString:part];
+ }
+ }
+ name=[NSString stringWithString:name];
+ }
+ return name;
+}
+
+- (NSString*)stringByMarkingUpcaseTransitionsWithDelimiter:(NSString*)delimiter
+{
+ NSString* result=nil;
+ int len = [self length];
+ if (len==0)
+ result=[NSString string];
+ else
+ {
+ int sepLen = [delimiter length];
+ int i, outlen = 0;
+ unichar* selfChars=malloc(sizeof(unichar));
+ unichar* resultChars=NULL;
+ BOOL lastWasLower = NO;
+
+ NSAssert(selfChars,@"Can't alloc");
+
+ resultChars=malloc(sizeof(unichar)*len*(sepLen+1));
+ if (resultChars==NULL)
+ {
+ free(selfChars);
+ NSAssert(NO,@"Can't alloc");
+ }
+
+
+ [self getCharacters:selfChars];
+
+ // We insert separator at all lower to upper transitions
+ for (i = 0; i < len; i++)
+ {
+ unichar c = selfChars[i];
+ if (c==uni_toupper(c))
+ {
+ if (lastWasLower
+ && i != 0)
+ {
+ // lower to UPPER transition!
+ [delimiter getCharacters:resultChars+outlen];
+ outlen += sepLen;
+ }
+ lastWasLower = NO;
+ }
+ else
+ lastWasLower = YES;
+ resultChars[outlen++] = c;
+ }
+ result = [NSString stringWithCharacters:resultChars
+ length:outlen];
+ }
+ return result;
}
+ (NSString *)externalNameForInternalName: (NSString *)internalName
separatorString: (NSString *)separatorString
useAllCaps: (BOOL)allCaps
{
- NSEmitTODO(); //TODO
- [self notImplemented: _cmd];
- return nil;
+ NSString* s = [internalName stringByMarkingUpcaseTransitionsWithDelimiter:separatorString];
+ return (allCaps ? [s uppercaseString] : [s lowercaseString]);
}
-@end
+@end
@implementation NSObject (EOEntity)
/** should returns a set of property names to exclude from entity
diff --git a/EOAccess/EOEntityPriv.h b/EOAccess/EOEntityPriv.h
index 396bc21..e0fbbe1 100644
--- a/EOAccess/EOEntityPriv.h
+++ b/EOAccess/EOEntityPriv.h
@@ -63,13 +63,13 @@
- (NSArray *)relationshipsPlist;
- (id)rootParent;
- (void)_setParent: (id)param0;
-- (NSArray *)_hiddenRelationships;
+- (NSMutableArray *)_hiddenRelationships;
- (NSArray *)_propertyNames;
-- (id)_flattenAttribute: (id)param0
- relationshipPath: (id)param1
- currentAttributes: (id)param2;
+- (EOAttribute*) _flattenAttribute: (EOAttribute*)attribute
+ relationshipPath: (NSString*)relationshipPath
+ currentAttributes: (NSDictionary*)currentAttributes;
- (NSString *)snapshotKeyForAttributeName: (NSString *)attributeName;
-- (id)_flattenedAttNameToSnapshotKeyMapping;
+- (NSDictionary*)_flattenedAttNameToSnapshotKeyMapping;
- (EOMKKDSubsetMapping *)_snapshotToAdaptorRowSubsetMapping;
- (EOMutableKnownKeyDictionary *)_dictionaryForPrimaryKey;
- (EOMutableKnownKeyDictionary *)_dictionaryForProperties;
@@ -93,19 +93,18 @@
@end
@interface EOEntity (EOEntityRelationshipPrivate)
-- (EORelationship *)_inverseRelationshipPathForPath: (NSString *)path;
+- (NSString *)_inverseRelationshipPathForPath: (NSString *)path;
- (NSDictionary *)_keyMapForRelationshipPath: (NSString *)path;
- (NSDictionary*)_keyMapForIdenticalKeyRelationshipPath: (NSString *)path;
- (EOAttribute*)_mapAttribute: (EOAttribute*)attribute
toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path;
- (BOOL)_relationshipPathIsToMany: (NSString *)relPath;
-- (BOOL)_relationshipPathHasIdenticalKeys: (id)param0;
+- (BOOL)_relationshipPathHasIdenticalKeys: (NSString*)path;
@end
@interface EOEntity (EOEntitySQLExpression)
- (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression;
-+ (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression;
@end
@interface EOEntity (EOEntityPrivateXX)
@@ -123,7 +122,7 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path;
- (NSArray *)classPropertyAttributeNames;
- (NSArray *)classPropertyToManyRelationshipNames;
- (NSArray *)classPropertyToOneRelationshipNames;
-- (id)qualifierForDBSnapshot: (id)param0;
+- (EOQualifier*) qualifierForDBSnapshot:(NSDictionary*)dbSnapshot;
- (void)_addAttributesToFetchForRelationshipPath: (NSString *)path
atts: (NSMutableDictionary *)atts;
- (NSArray *)dbSnapshotKeys;
diff --git a/EOAccess/EOExpressionArray.h b/EOAccess/EOExpressionArray.h
index 23bb5a1..43d1868 100644
--- a/EOAccess/EOExpressionArray.h
+++ b/EOAccess/EOExpressionArray.h
@@ -98,6 +98,8 @@
- (NSString *)valueForSQLExpression: (EOSQLExpression *)sqlExpression;
+- (BOOL)_isPropertyPath;
+
@end /* EOExpressionArray */
diff --git a/EOAccess/EOExpressionArray.m b/EOAccess/EOExpressionArray.m
index fbb2d73..a76a809 100644
--- a/EOAccess/EOExpressionArray.m
+++ b/EOAccess/EOExpressionArray.m
@@ -66,6 +66,7 @@ RCS_ID("$Id$")
#include
#include
#include
+#include "EOPrivate.h"
static SEL eqSel;
@@ -164,7 +165,7 @@ static SEL eqSel;
- (NSString *)expressionValueForContext: (id)ctx
{
if (ctx && [self count]
- && [[self objectAtIndex: 0] isKindOfClass: [EORelationship class]])
+ && [[self objectAtIndex: 0] isKindOfClass: GDL2_EORelationshipClass])
return [ctx expressionValueForAttributePath: self];
else
{
@@ -334,17 +335,10 @@ static SEL eqSel;
- (BOOL)_isPropertyPath
{
-/*
- int i=0;
- int count=0;
-
- count=[self count];
-objectAtIndex:i
-if it's a string return NO
-*/
-//TODO
-
- return NO;
+ if ([self count]<=0)
+ return NO;
+ else
+ return [[self objectAtIndex:0] isKindOfClass:GDL2_EORelationshipClass];
}
- (NSString *)valueForSQLExpression: (EOSQLExpression*)sqlExpression
diff --git a/EOAccess/EOModel.m b/EOAccess/EOModel.m
index 73e8109..c7d597a 100644
--- a/EOAccess/EOModel.m
+++ b/EOAccess/EOModel.m
@@ -91,9 +91,17 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
@end /* EOModel (EOModelPrivate) */
-
@implementation EOModel
++ (void)initialize
+{
+ static BOOL initialized=NO;
+ if (!initialized)
+ {
+ initialized=YES;
+ };
+};
+
+ (EOModel*) model
{
return AUTORELEASE([[self alloc] init]);
@@ -199,8 +207,6 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
- (id)init
{
-
-
if ((self = [super init]))
{
// Turbocat
@@ -219,7 +225,6 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
name: EOClassDescriptionNeededNotification
object: nil];
- //No ?
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(_classDescriptionNeeded:)
@@ -1344,7 +1349,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
for (; refIdx < refCount; refIdx++) {
id refObj = [references objectAtIndex:refIdx];
- if ([refObj class] == [EOAttribute class])
+ if ([refObj class] == GDL2_EOAttributeClass)
{
[[(EOAttribute*) refObj entity] removeAttribute:refObj];
} else {
@@ -1404,7 +1409,7 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
NSString *entityName = nil;
NSString *entityClassName = nil;
- if ([entity isKindOfClass: [EOEntity class]])
+ if ([entity isKindOfClass:GDL2_EOEntityClass])
{
entityName = [entity name];
entityClassName = [entity className];
@@ -1895,17 +1900,49 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
return returnPath;
}
+-(NSDictionary*)propertyListForEntity:(id)entity
+ name:(NSString*)name
+{
+ NSDictionary* propList=nil;
+
+ NSString* plistPathName = [[[self path] stringByAppendingPathComponent: name]
+ stringByAppendingPathExtension: @"plist"];
+
+ EOFLOGObjectLevelArgs(@"gsdb", @"entity plistPathName =%@",
+ plistPathName);
+
+ propList = [NSDictionary dictionaryWithContentsOfFile: plistPathName];
+ EOFLOGObjectLevelArgs(@"gsdb", @"entity propList=%@", propList);
+
+ if (!propList)
+ {
+ if ([[NSFileManager defaultManager]
+ fileExistsAtPath: plistPathName])
+ {
+ NSAssert1(NO,
+ @"%@ is not a dictionary or is not readable.",
+ plistPathName);
+ }
+ else
+ {
+ propList = entity;
+ NSWarnLog(@"%@ doesn't exists. Using %@",
+ plistPathName, propList);
+ }
+ }
+ return propList;
+}
+
- (EOEntity *) _verifyBuiltEntityObject: (id)entity
named: (NSString*)name
{
- if ([entity isKindOfClass: [EOEntity class]] == NO)
+ if ([entity isKindOfClass:GDL2_EOEntityClass] == NO)
{
[EOObserverCenter suppressObserverNotification];
NS_DURING
{
NSString *basePath = nil;
- NSString *plistPathName = nil;
NSDictionary *propList = nil;
EOFLOGObjectLevelArgs(@"gsdb", @"name=%@", name);
@@ -1928,32 +1965,8 @@ NSString *EOEntityLoadedNotification = @"EOEntityLoadedNotification";
}
else
{
- plistPathName = [[basePath stringByAppendingPathComponent: name]
- stringByAppendingPathExtension: @"plist"];
-
- EOFLOGObjectLevelArgs(@"gsdb", @"entity plistPathName =%@",
- plistPathName);
-
- propList
- = [NSDictionary dictionaryWithContentsOfFile: plistPathName];
- EOFLOGObjectLevelArgs(@"gsdb", @"entity propList=%@", propList);
-
- if (!propList)
- {
- if ([[NSFileManager defaultManager]
- fileExistsAtPath: plistPathName])
- {
- NSAssert1(NO,
- @"%@ is not a dictionary or is not readable.",
- plistPathName);
- }
- else
- {
- propList = entity;
- NSWarnLog(@"%@ doesn't exists. Using %@",
- plistPathName, propList);
- }
- }
+ propList=[self propertyListForEntity:entity
+ name:name];
}
[self _removeEntity: entity];
diff --git a/EOAccess/EOModelGroup.h b/EOAccess/EOModelGroup.h
index eaf871b..e33332d 100644
--- a/EOAccess/EOModelGroup.h
+++ b/EOAccess/EOModelGroup.h
@@ -50,7 +50,7 @@
{
NSMutableDictionary *_modelsByName;
id _delegate;
-
+@public //EORelationship need access to relationshipForRow
struct {
unsigned int entityNamed:1;
unsigned int relationshipForRow:1;
diff --git a/EOAccess/EOPrivate.h b/EOAccess/EOPrivate.h
index 23a67fd..fddd40a 100644
--- a/EOAccess/EOPrivate.h
+++ b/EOAccess/EOPrivate.h
@@ -38,6 +38,8 @@
// ==== Classes ====
GDL2ACCESS_EXPORT Class GDL2_EODatabaseContextClass;
GDL2ACCESS_EXPORT Class GDL2_EOAttributeClass;
+GDL2ACCESS_EXPORT Class GDL2_EORelationshipClass;
+GDL2ACCESS_EXPORT Class GDL2_EOEntityClass;
// ==== IMPs ====
GDL2ACCESS_EXPORT IMP GDL2_EODatabaseContext_snapshotForGlobalIDIMP;
diff --git a/EOAccess/EOPrivate.m b/EOAccess/EOPrivate.m
index 83b7fd3..a1edae1 100644
--- a/EOAccess/EOPrivate.m
+++ b/EOAccess/EOPrivate.m
@@ -44,6 +44,7 @@ RCS_ID("$Id$")
#include
#include
#include
+#include
#include
#include "EOPrivate.h"
@@ -51,6 +52,8 @@ RCS_ID("$Id$")
// ==== Classes ====
Class GDL2_EODatabaseContextClass=Nil;
Class GDL2_EOAttributeClass=Nil;
+Class GDL2_EORelationshipClass=Nil;
+Class GDL2_EOEntityClass=Nil;
// ==== IMPs ====
IMP GDL2_EODatabaseContext_snapshotForGlobalIDIMP=NULL;
@@ -69,6 +72,8 @@ void GDL2_EOAccessPrivateInit()
// ==== Classes ====
GDL2_EODatabaseContextClass = [EODatabaseContext class];
GDL2_EOAttributeClass = [EOAttribute class];
+ GDL2_EORelationshipClass = [EORelationship class];
+ GDL2_EOEntityClass = [EOEntity class];
GDL2_EODatabaseContext_snapshotForGlobalIDIMP=[GDL2_EODatabaseContextClass instanceMethodForSelector:@selector(snapshotForGlobalID:)];
diff --git a/EOAccess/EORelationship.h b/EOAccess/EORelationship.h
index 9043fbd..7f5837f 100644
--- a/EOAccess/EORelationship.h
+++ b/EOAccess/EORelationship.h
@@ -95,7 +95,6 @@ typedef enum {
/* Computed values */
NSArray *_sourceAttributes;
NSArray *_destinationAttributes;
- NSMutableArray *_componentRelationships;//Used ????
}
+ (id)relationshipWithPropertyList: (NSDictionary *)propertyList
@@ -192,9 +191,9 @@ typedef enum {
- (EORelationship *)firstRelationship;
- (EOEntity*) intermediateEntity;
- (BOOL)isMultiHop;
-- (void)_setSourceToDestinationKeyMap: (id)param0;
-- (id)qualifierForDBSnapshot: (id)param0;
-- (id)primaryKeyForTargetRowFromSourceDBSnapshot: (id)param0;
+- (void)_setSourceToDestinationKeyMap:(NSDictionary *)sourceToDestinationKeyMap;
+- (EOQualifier*)qualifierForDBSnapshot:(NSDictionary *)dbSnapshot;
+- (NSDictionary *)primaryKeyForTargetRowFromSourceDBSnapshot:(NSDictionary *)dbSnapshot;
- (NSString *)relationshipPath;
- (BOOL)isToManyToOne;
- (NSDictionary *)_sourceToDestinationKeyMap;
@@ -203,9 +202,9 @@ typedef enum {
@interface EORelationship (EORelationshipPrivate2)
- (BOOL)isPropagatesPrimaryKeyPossible;
-- (id)qualifierOmittingAuxiliaryQualifierWithSourceRow: (id)param0;
-- (id)auxiliaryQualifier;
-- (void)setAuxiliaryQualifier: (id)param0;
+- (EOQualifier*)qualifierOmittingAuxiliaryQualifierWithSourceRow: (NSDictionary *)row;
+- (EOQualifier*)auxiliaryQualifier;
+- (void)setAuxiliaryQualifier: (EOQualifier*)qualifier;
- (EOMutableKnownKeyDictionary *)_foreignKeyForSourceRow: (NSDictionary *)row;
- (EOMKKDSubsetMapping *)_sourceRowToForeignKeyMapping;
- (NSArray *)_sourceAttributeNames;
diff --git a/EOAccess/EORelationship.m b/EOAccess/EORelationship.m
index 36b1a5d..2d192a8 100644
--- a/EOAccess/EORelationship.m
+++ b/EOAccess/EORelationship.m
@@ -56,6 +56,7 @@ RCS_ID("$Id$")
#include
#include
+#include
#include
#include
#include
@@ -201,24 +202,18 @@ RCS_ID("$Id$")
//Near OK
if ((self = [self init]))
{
- NSString *joinSemanticString = nil;
- EOModel *model;
+ EOModel* model = [owner model];
+ NSString* relationshipName = [propertyList objectForKey: @"name"];
+ NSString* joinSemanticString = nil;
NSString* destinationEntityName = nil;
EOEntity* destinationEntity = nil;
NSString* deleteRuleString = nil;
- NSString* relationshipName;
-
-
-
- model = [owner model];
- relationshipName = [propertyList objectForKey: @"name"];
/* so setName: can validate against the owner */
[self setEntity: owner];
[self setName: relationshipName];
destinationEntityName = [propertyList objectForKey: @"destination"];
-
if (destinationEntityName) //If not, this is because it's a definition
{
destinationEntity = [model entityNamed: destinationEntityName];
@@ -295,14 +290,7 @@ RCS_ID("$Id$")
- (void)awakeWithPropertyList: (NSDictionary *)propertyList //TODO
{
- //OK for definition
- NSString *definition;
-
-
-
- EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@", self);
-
- definition = [propertyList objectForKey: @"definition"];
+ NSString *definition = [propertyList objectForKey: @"definition"];
EOFLOGObjectLevelArgs(@"EORelationship", @"definition=%@", definition);
@@ -334,40 +322,32 @@ RCS_ID("$Id$")
for (i = 0; i < count; i++)
{
- NSDictionary *joinPList;
- NSString *joinSemantic;
- NSString *sourceAttributeName;
- EOAttribute *sourceAttribute;
- EOEntity *destinationEntity;
- NSString *destinationAttributeName = nil;
- EOAttribute *destinationAttribute = nil;
+ NSDictionary *joinPList =
+ [joins objectAtIndex: i];
+ /*NSString *joinSemantic =
+ [joinPList objectForKey: @"joinSemantic"];*/
+ NSString *sourceAttributeName =
+ [joinPList objectForKey:@"sourceAttribute"];
+ EOAttribute *sourceAttribute =
+ [_entity attributeNamed:sourceAttributeName];
+ EOEntity *destinationEntity =
+ [self destinationEntity];
+ NSString *destinationAttributeName =
+ [joinPList objectForKey:@"destinationAttribute"];
+ EOAttribute *destinationAttribute =
+ [destinationEntity attributeNamed:destinationAttributeName];
EOJoin *join = nil;
- joinPList = [joins objectAtIndex: i];
- joinSemantic = [joinPList objectForKey: @"joinSemantic"];
-
- sourceAttributeName = [joinPList objectForKey:
- @"sourceAttribute"];
- sourceAttribute = [_entity attributeNamed:
- sourceAttributeName];
-
NSAssert4(sourceAttribute, @"No sourceAttribute named \"%@\" in entity \"%@\" in relationship %@\nEntity: %@",
sourceAttributeName,
[_entity name],
self,
_entity);
- destinationEntity = [self destinationEntity];
NSAssert3(destinationEntity,@"No destination entity for relationship named '%@' in entity named '%@': %@",
[self name],
[[self entity]name],
self);
- destinationAttributeName = [joinPList
- objectForKey:
- @"destinationAttribute"];
- destinationAttribute = [destinationEntity
- attributeNamed:
- destinationAttributeName];
NSAssert4(destinationAttribute, @"No destinationAttribute named \"%@\" in entity \"%@\" in relationship %@\nEntity: %@",
destinationAttributeName,
@@ -621,12 +601,20 @@ destination entity of the last relationship in definition. **/
- (BOOL) isParentRelationship
{
- BOOL isParentRelationship = NO;
- /*EOEntity *destinationEntity = [self destinationEntity];
- EOEntity *parentEntity = [_entity parentEntity];*///nil
-
- NSEmitTODO(); //TODO
- // [self notImplemented:_cmd]; //TODO...
+ BOOL isParentRelationship=NO;
+ EOEntity *destinationEntity = [self destinationEntity];
+ if(destinationEntity != nil
+ && destinationEntity == [_entity parentEntity])
+ {
+ NSArray* attributes = [self sourceAttributes];
+ NSArray* pkAttributes = [_entity primaryKeyAttributes];
+ if([attributes containsIdenticalObjectsWithArray:pkAttributes])
+ {
+ attributes = [self destinationAttributes];
+ pkAttributes = [_destination primaryKeyAttributes];
+ isParentRelationship=[attributes containsIdenticalObjectsWithArray:pkAttributes];
+ }
+ }
return isParentRelationship;
}
@@ -636,10 +624,7 @@ destination entity of the last relationship in definition. **/
**/
- (BOOL)isFlattened
{
- if (_definitionArray)
- return [_definitionArray isFlattened];
- else
- return NO;
+ return (_definitionArray==nil ? NO : YES);
}
/** return YES if the relation if a to-many one, NO otherwise (please read books
@@ -664,7 +649,6 @@ to know what to-many mean :-) **/
- (NSArray *)sourceAttributes
{
- //OK
if (!_sourceAttributes)
{
int i, count = [_joins count];
@@ -684,7 +668,6 @@ to know what to-many mean :-) **/
- (NSArray *)destinationAttributes
{
- //OK
if (!_destinationAttributes)
{
int i, count = [_joins count];
@@ -723,19 +706,7 @@ to know what to-many mean :-) **/
*/
- (NSArray *)componentRelationships
{
- /* FIXME:TODO: Have this method deterimne the components dynamically
- without caching them in the ivar. Possibly add some tracing code to
- see if caching the values can actually improve performance.
- (Unlikely that it's worth the trouble this may cause for entity
- edititng). */
- if (!_componentRelationships)
- {
- return _definitionArray; //OK ??????
- NSEmitTODO(); //TODO
- [self notImplemented: _cmd]; //TODO
- }
-
- return _componentRelationships;
+ return _definitionArray;
}
- (NSDictionary *)userInfo
@@ -829,16 +800,9 @@ to know what to-many mean :-) **/
- (BOOL)isReciprocalToRelationship: (EORelationship *)relationship
{
- //Should be OK
- //Ayers: Review
BOOL isReciprocal = NO;
- EOEntity *entity;
- EOEntity *relationshipDestinationEntity = nil;
-
-
-
- entity = [self entity]; //OK
- relationshipDestinationEntity = [relationship destinationEntity];
+ EOEntity *entity = [self entity];
+ EOEntity *relationshipDestinationEntity = [relationship destinationEntity];
EOFLOGObjectLevelArgs(@"EORelationship", @"entity %p name=%@",
entity, [entity name]);
@@ -847,11 +811,11 @@ to know what to-many mean :-) **/
relationshipDestinationEntity,
[relationshipDestinationEntity name]);
- if (entity == relationshipDestinationEntity) //Test like that ?
+ if (entity == relationshipDestinationEntity)
{
- if ([self isFlattened]) //OK
+ if ([self isFlattened])
{
- if ([relationship isFlattened]) //OK
+ if ([relationship isFlattened])
{
//Now compare each components in reversed order
NSArray *selfComponentRelationships =
@@ -887,25 +851,10 @@ to know what to-many mean :-) **/
isReciprocal = YES;
}
}
- else
- {
- //Just do nothing and try another relationship.
- // Is it the good way ?
- /*
- NSEmitTODO(); //TODO
- NSDebugMLog(@"entity %p name=%@ self name=%@ relationship name=%@ relationshipDestinationEntity %p name=%@",
- entity, [entity name],
- [self name],
- [relationship name],
- relationshipDestinationEntity,
- [relationshipDestinationEntity name]);
- [self notImplemented: _cmd]; //TODO
- */
- }
}
else
{
- //WO doens't test inverses entity
+ //WO doesn't test inverses entity; we does.
EOEntity *relationshipEntity = [relationship entity];
EOEntity *destinationEntity = [self destinationEntity];
@@ -984,8 +933,6 @@ to know what to-many mean :-) **/
}
}
-
-
return isReciprocal;
}
@@ -993,21 +940,11 @@ to know what to-many mean :-) **/
relationships. Nil if none" **/
- (EORelationship *)inverseRelationship
{
- //OK
-
-
if (!_inverseRelationship)
{
- EOEntity *destinationEntity;
- NSArray *destinationEntityRelationships;
-
- destinationEntity = [self destinationEntity];
- NSDebugLog(@"destinationEntity name=%@", [destinationEntity name]);
-
- destinationEntityRelationships = [destinationEntity relationships];
-
- NSDebugLog(@"destinationEntityRelationships=%@",
- destinationEntityRelationships);
+ EOEntity* destinationEntity = [self destinationEntity];
+ NSArray* destinationEntityRelationships =
+ [destinationEntity relationships];
if ([destinationEntityRelationships count] > 0)
{
@@ -1018,20 +955,14 @@ relationships. Nil if none" **/
EORelationship *testRelationship =
[destinationEntityRelationships objectAtIndex: i];
- NSDebugLog(@"testRelationship=%@", testRelationship);
-
if ([self isReciprocalToRelationship: testRelationship])
{
ASSIGN(_inverseRelationship, testRelationship);
}
}
}
-
- NSDebugLog(@"_inverseRelationship=%@", _inverseRelationship);
}
-
-
return _inverseRelationship;
}
@@ -1043,8 +974,6 @@ relationships. Nil if none" **/
NSString *name = nil;
int i, count;
-
-
NSAssert([self isFlattened], @"Not Flatten Relationship");
EOFLOGObjectLevel(@"EORelationship", @"add joins");
@@ -1084,21 +1013,16 @@ relationships. Nil if none" **/
[inverseRelationship _setInverseRelationship: self];
-
-
return inverseRelationship;
}
- (EORelationship*) _makeInverseRelationship
{
- //OK
EORelationship *inverseRelationship;
NSString *name;
NSArray *joins = nil;
unsigned int i, count;
-
-
NSAssert(![self isFlattened], @"Flatten Relationship");
inverseRelationship = [[EORelationship new] autorelease];
@@ -1137,15 +1061,11 @@ relationships. Nil if none" **/
/* call this last to avoid calls to [_destination _setIsEdited] */
[inverseRelationship setEntity: _destination];
-
return inverseRelationship;
}
- (EORelationship*) hiddenInverseRelationship
{
- //OK
-
-
if (!_hiddenInverseRelationship)
{
if ([self isFlattened])
@@ -1154,14 +1074,11 @@ relationships. Nil if none" **/
_hiddenInverseRelationship = [self _makeInverseRelationship];
}
-
-
return _hiddenInverseRelationship;
}
- (EORelationship *)anyInverseRelationship
{
- //OK
EORelationship *inverseRelationship = [self inverseRelationship];
if (!inverseRelationship)
@@ -1182,8 +1099,19 @@ relationships. Nil if none" **/
- (EOQualifier *)qualifierWithSourceRow: (NSDictionary *)sourceRow
{
- [self notImplemented: _cmd];//TODO
- return nil;
+ EOQualifier* q = nil;
+ EOQualifier* q1 = [self qualifierOmittingAuxiliaryQualifierWithSourceRow:sourceRow];
+ EOQualifier* q2 = [self auxiliaryQualifier];
+ if (q1 != nil)
+ {
+ if (q2!=nil)
+ q=[EOAndQualifier qualifierWithQualifiers:q1,q2,nil];
+ else
+ q=q1;
+ }
+ else
+ q=q2;
+ return q;
}
@end /* EORelationship */
@@ -1193,12 +1121,13 @@ relationships. Nil if none" **/
- (NSException *)validateName: (NSString *)name
{
- //Seems OK
const char *p, *s = [name cString];
int exc = 0;
NSArray *storedProcedures = nil;
- if ([_name isEqual:name]) return nil;
+ if ([_name isEqual:name])
+ return nil;
+
if (!name || ![name length])
exc++;
if (!exc)
@@ -1272,7 +1201,6 @@ relationships. Nil if none" **/
- (void)setToMany: (BOOL)flag
{
- //OK
if ([self isFlattened])
[NSException raise: NSInvalidArgumentException
format: @"%@ -- %@ 0x%p: receiver is a flattened relationship",
@@ -1290,7 +1218,6 @@ relationships. Nil if none" **/
- (void)setName: (NSString *)name
{
- //OK
[[self validateName: name] raise];
[self willChange];
[_entity _setIsEdited];
@@ -1300,9 +1227,6 @@ relationships. Nil if none" **/
- (void)setDefinition: (NSString *)definition
{
- //Near OK
-
-
EOFLOGObjectLevelArgs(@"EORelationship", @"definition=%@", definition);
[self _flushCache];
@@ -1334,7 +1258,7 @@ relationships. Nil if none" **/
{
EORelationship *rel = [_definitionArray objectAtIndex: i];
- if ([rel isKindOfClass: [EORelationship class]])
+ if ([rel isKindOfClass: GDL2_EORelationshipClass])
{
if ([rel isToMany])
_flags.isToMany = YES;
@@ -1366,7 +1290,6 @@ relationships. Nil if none" **/
*/
- (void)setEntity: (EOEntity *)entity
{
- //OK
if (entity != _entity)
{
[self _flushCache];
@@ -1374,18 +1297,12 @@ relationships. Nil if none" **/
if (_entity)
{
- NSString *relationshipName;
- EORelationship *relationship;
-
/* Check if we are still in the entities arrays to
avoid recursive loop when removeRelationship:
calls this method. */
- relationshipName = [self name];
- relationship = [_entity relationshipNamed: relationshipName];
- if (self == relationship)
- {
- [_entity removeRelationship: self];
- }
+ NSString *relationshipName = [self name];
+ if (self == [_entity relationshipNamed: relationshipName])
+ [_entity removeRelationship: self];
}
_entity = entity;
}
@@ -1395,7 +1312,6 @@ relationships. Nil if none" **/
- (void)setUserInfo: (NSDictionary *)dictionary
{
- //OK
[self willChange];
ASSIGN(_userInfo, dictionary);
/* Ayers: Not sure what justifies this. */
@@ -1404,7 +1320,6 @@ relationships. Nil if none" **/
- (void)setInternalInfo: (NSDictionary *)dictionary
{
- //OK
[self willChange];
ASSIGN(_internalInfo, dictionary);
/* Ayers: Not sure what justifies this. */
@@ -1413,7 +1328,6 @@ relationships. Nil if none" **/
- (void)setDocComment: (NSString *)docComment
{
- //OK
[self willChange];
ASSIGNCOPY(_docComment, docComment);
/* Ayers: Not sure what justifies this. */
@@ -1422,7 +1336,6 @@ relationships. Nil if none" **/
- (void)setPropagatesPrimaryKey: (BOOL)flag
{
- //OK
if (_flags.propagatesPrimaryKey != flag)
[self willChange];
@@ -1431,7 +1344,6 @@ relationships. Nil if none" **/
- (void)setIsBidirectional: (BOOL)flag
{
- //OK
if (_flags.isBidirectional != flag)
[self willChange];
@@ -1447,187 +1359,171 @@ relationships. Nil if none" **/
}
- (void)addJoin: (EOJoin *)join
-{
- EOAttribute *sourceAttribute = nil;
- EOAttribute *destinationAttribute = nil;
-
-
-
+{
EOFLOGObjectLevelArgs(@"EORelationship", @"Add join: %@\nto %@", join, self);
if ([self isFlattened] == YES)
- [NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p: receiver is a flattened relationship",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self];
- else
- {
- EOEntity *destinationEntity = [self destinationEntity];
- EOEntity *sourceEntity = [self entity];
-
- EOFLOGObjectLevelArgs(@"EORelationship", @"destinationEntity=%@", destinationEntity);
-
- if (!destinationEntity)
{
-#warning checkme: do we need this? -- dw
- //NSEmitTODO(); //TODO
- //EOFLOGObjectLevelArgs(@"EORelationship", @"self=%@", self);
- //TODO ??
- };
-
- sourceAttribute = [join sourceAttribute];
-
- NSAssert3(sourceAttribute, @"No source attribute in join %@ in relationship %@ of entity %@",
- join,
- self,
- sourceEntity);
-
- destinationAttribute = [join destinationAttribute];
-
- NSAssert3(destinationAttribute, @"No destination attribute in join %@ in relationship %@ of entity %@",
- join,
- self,
- sourceEntity);
-
- if ([sourceAttribute isFlattened] == YES
- || [destinationAttribute isFlattened] == YES)
[NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p: join's attributes are flattened",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self];
- else
- {
- EOEntity *joinDestinationEntity = [destinationAttribute entity];
- EOEntity *joinSourceEntity = [sourceAttribute entity];
-
- /* if (destinationEntity && ![[destinationEntity name] isEqual:[joinSourceEntity name]])
- {
- [NSException raise:NSInvalidArgumentException
- format:@"%@ -- %@ 0x%x: join source entity (%@) is not equal to last join entity (%@)",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self,
- [joinSourceEntity name],
- [destinationEntity name]];
- }*/
-
- if (sourceEntity
- && ![[joinSourceEntity name] isEqual: [sourceEntity name]])
- [NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p (%@): join source entity (%@) is not equal to relationship entity (%@)",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self,
- [self name],
- [joinSourceEntity name],
- [sourceEntity name]];
- else if (destinationEntity
- && ![[joinDestinationEntity name]
- isEqual: [destinationEntity name]])
- [NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p (%@): join destination entity (%@) is not equal to relationship destination entity (%@)",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self,
- [self name],
- [joinDestinationEntity name],
- [destinationEntity name]];
- else
- {
- if ([_sourceAttributes count])
- {
- EOAttribute *sourceAttribute = [join sourceAttribute];
- EOAttribute *destinationAttribute;
-
- destinationAttribute = [join destinationAttribute];
-
- if (([_sourceAttributes indexOfObject: sourceAttribute]
- != NSNotFound)
- && ([_destinationAttributes
- indexOfObject: destinationAttribute]
- != NSNotFound))
- [NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p: TODO",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self];
- }
-
- [self _flushCache];
- // do we still need willChange when we are not putting EORelationships into ECs? -- dw
- [self willChange];
- // needed for KV bbserving
- [self willChangeValueForKey:@"joins"];
-
- EOFLOGObjectLevel(@"EORelationship", @"really add");
- EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@",
- _joins, [_joins class]);
-
- if (!_joins)
- _joins = [NSMutableArray new];
-
- [(NSMutableArray *)_joins addObject: join];
-
- EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@",
- _joins, [_joins class]);
-
- EOFLOGObjectLevel(@"EORelationship", @"added");
-
- [self _joinsChanged];
- [self didChangeValueForKey:@"joins"];
-
- /* Ayers: Not sure what justifies this. */
- [_entity _setIsEdited];
- }
+ format: @"%@ -- %@ 0x%p: receiver is a flattened relationship",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self];
+ }
+ else
+ {
+ EOEntity *destinationEntity = [self destinationEntity];
+ EOEntity *sourceEntity = [self entity];
+ EOAttribute *sourceAttribute = [join sourceAttribute];
+ EOAttribute *destinationAttribute = [join destinationAttribute];
+
+ EOFLOGObjectLevelArgs(@"EORelationship", @"destinationEntity=%@", destinationEntity);
+
+ NSAssert3(sourceAttribute, @"No source attribute in join %@ in relationship %@ of entity %@",
+ join,
+ self,
+ sourceEntity);
+
+ NSAssert3(destinationAttribute, @"No destination attribute in join %@ in relationship %@ of entity %@",
+ join,
+ self,
+ sourceEntity);
+
+ if ([sourceAttribute isFlattened] == YES
+ || [destinationAttribute isFlattened] == YES)
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"%@ -- %@ 0x%p: join's attributes are flattened",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self];
+ }
+ else
+ {
+ EOEntity *joinDestinationEntity = [destinationAttribute entity];
+ EOEntity *joinSourceEntity = [sourceAttribute entity];
+
+ /* if (destinationEntity && ![[destinationEntity name] isEqual:[joinSourceEntity name]])
+ {
+ [NSException raise:NSInvalidArgumentException
+ format:@"%@ -- %@ 0x%x: join source entity (%@) is not equal to last join entity (%@)",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self,
+ [joinSourceEntity name],
+ [destinationEntity name]];
+ }*/
+
+ if (sourceEntity
+ && ![[joinSourceEntity name] isEqual: [sourceEntity name]])
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"%@ -- %@ 0x%p (%@): join source entity (%@) is not equal to relationship entity (%@)",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self,
+ [self name],
+ [joinSourceEntity name],
+ [sourceEntity name]];
+ }
+ else if (destinationEntity
+ && ![[joinDestinationEntity name]
+ isEqual: [destinationEntity name]])
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"%@ -- %@ 0x%p (%@): join destination entity (%@) is not equal to relationship destination entity (%@)",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self,
+ [self name],
+ [joinDestinationEntity name],
+ [destinationEntity name]];
+ }
+ else
+ {
+ if ([_sourceAttributes count])
+ {
+ EOAttribute *sourceAttribute = [join sourceAttribute];
+ EOAttribute *destinationAttribute;
+
+ destinationAttribute = [join destinationAttribute];
+
+ if (([_sourceAttributes indexOfObject: sourceAttribute]
+ != NSNotFound)
+ && ([_destinationAttributes
+ indexOfObject: destinationAttribute]
+ != NSNotFound))
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"%@ -- %@ 0x%p: TODO",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self];
+ }
+ }
+
+ [self _flushCache];
+ // do we still need willChange when we are not putting EORelationships into ECs? -- dw
+ [self willChange];
+ // needed for KV bbserving
+ [self willChangeValueForKey:@"joins"];
+
+ EOFLOGObjectLevel(@"EORelationship", @"really add");
+ EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@",
+ _joins, [_joins class]);
+
+ if (!_joins)
+ _joins = [NSMutableArray new];
+
+ [(NSMutableArray *)_joins addObject: join];
+
+ EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@",
+ _joins, [_joins class]);
+
+ EOFLOGObjectLevel(@"EORelationship", @"added");
+
+ [self _joinsChanged];
+ [self didChangeValueForKey:@"joins"];
+
+ /* Ayers: Not sure what justifies this. MGuesdon: EOF seems to do it */
+ [_entity _setIsEdited];
+ }
+ }
}
- }
-
-
}
- (void)removeJoin: (EOJoin *)join
{
-
-
- [self _flushCache];
-
if ([self isFlattened] == YES)
- [NSException raise: NSInvalidArgumentException
- format: @"%@ -- %@ 0x%p: receiver is a flattened relationship",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self];
+ {
+ [NSException raise: NSInvalidArgumentException
+ format: @"%@ -- %@ 0x%p: receiver is a flattened relationship",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self];
+ }
else
{
+ [self _flushCache];
+
[self willChangeValueForKey:@"joins"];
[self willChange];
[(NSMutableArray *)_joins removeObject: join];
- /*NO: will be recomputed [(NSMutableArray *)_sourceAttributes
- removeObject:[join sourceAttribute]];
- [(NSMutableArray *)_destinationAttributes
- removeObject:[join destinationAttribute]];
- */
-
EOFLOGObjectLevelArgs(@"EORelationship", @"XXjoins %p class%@",
_joins, [_joins class]);
[self _joinsChanged];
- /* Ayers: Not sure what justifies this. */
+ /* Ayers: Not sure what justifies this. MGuesdon: EOF seems to do it */
[_entity _setIsEdited];
[self didChangeValueForKey:@"joins"];
}
-
-
}
- (void)setJoinSemantic: (EOJoinSemantic)joinSemantic
{
- //OK
[self willChange];
_joinSemantic = joinSemantic;
}
@@ -1680,6 +1576,7 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
- (void)setNumberOfToManyFaultsToBatchFetch: (unsigned int)size
{
[self willChange];
+ _flags.useBatchFaulting=YES;
_batchCount = size;
}
@@ -1695,8 +1592,8 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
- (void)setIsMandatory: (BOOL)isMandatory
{
- //OK
- [self willChange];
+ if (_flags.isMandatory!=isMandatory)
+ [self willChange];
_flags.isMandatory = isMandatory;
}
@@ -1715,33 +1612,44 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
*/
- (NSException *)validateValue: (id*)valueP
{
- //OK
NSException *exception = nil;
-
-
NSAssert(valueP, @"No value pointer");
if ([self isMandatory])
{
BOOL isToMany = [self isToMany];
- if ((isToMany == NO && _isNilOrEONull(*valueP))
- || (isToMany == YES && [*valueP count] == 0))
- {
- EOEntity *destinationEntity = [self destinationEntity];
- EOEntity *entity = [self entity];
-
- exception = [NSException validationExceptionWithFormat:
- @"The %@ property of %@ must have a %@ assigned",
- [self name],
- [entity name],
- [destinationEntity name]];
- }
+ if (isToMany == NO)
+ {
+ if (_isNilOrEONull(*valueP))
+ {
+ EOEntity *destinationEntity = [self destinationEntity];
+ EOEntity *entity = [self entity];
+
+ exception = [NSException validationExceptionWithFormat:
+ @"The %@ property of %@ must have a %@ assigned",
+ [self name],
+ [entity name],
+ [destinationEntity name]];
+ }
+ }
+ else
+ {
+ if ([*valueP count] == 0)
+ {
+ EOEntity *destinationEntity = [self destinationEntity];
+ EOEntity *entity = [self entity];
+
+ exception = [NSException validationExceptionWithFormat:
+ @"The %@ property of %@ must have at least one %@",
+ [self name],
+ [entity name],
+ [destinationEntity name]];
+ }
+ }
}
-
-
return exception;
}
@@ -1768,26 +1676,16 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
- (NSArray*) _intermediateAttributes
{
- //Verify !!
- NSMutableArray *intermediateAttributes;
- EORelationship *rel;
- NSArray *joins;
+ NSMutableArray *intermediateAttributes=[NSMutableArray array];
+ NSArray* firstRelJoins=[[self firstRelationship] joins];
+ NSArray* lastRelJoins=[[self lastRelationship] joins];
- //all this works on flattened and non flattened relationship.
- intermediateAttributes = [NSMutableArray array];
- rel = [self firstRelationship];
- joins = [rel joins];
- //??
[intermediateAttributes addObjectsFromArray:
- [joins resultsOfPerformingSelector:
+ [firstRelJoins resultsOfPerformingSelector:
@selector(destinationAttribute)]];
- rel = [self lastRelationship];
- joins = [rel joins];
- // attribute = [joins sourceAttribute];
- //??
[intermediateAttributes addObjectsFromArray:
- [joins resultsOfPerformingSelector:
+ [lastRelJoins resultsOfPerformingSelector:
@selector(sourceAttribute)]];
return [NSArray arrayWithArray: intermediateAttributes];
@@ -1833,7 +1731,6 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
- (EOEntity*) intermediateEntity
{
- //TODO verify
id intermediateEntity = nil;
if ([self isToManyToOne])
@@ -1854,41 +1751,99 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
- (BOOL) isMultiHop
{
- //TODO verify
- BOOL isMultiHop = NO;
+ return [self isFlattened];
+}
- if ([self isFlattened])
+- (void) _setSourceToDestinationKeyMap: (NSDictionary*)sourceToDestinationKeyMap
+{
+ ASSIGN(_sourceToDestinationKeyMap,sourceToDestinationKeyMap);
+}
+
+- (EOQualifier*) qualifierForDBSnapshot: (NSDictionary*)dbSnapshot
+{
+ EOQualifier* qualifier = nil;
+
+ EORelationship* relationship = self;
+ NSMutableArray* qualifiers = nil;
+ BOOL isFlattenedToMany = NO;
+ NSString* relationshipPath = nil;
+
+ if([self isFlattened])
{
- isMultiHop = YES;
+ if ([self isToMany])
+ {
+ relationshipPath = [[self anyInverseRelationship]relationshipPath];
+ isFlattenedToMany = true;
+ relationship = [self firstRelationship];
+ }
+ else
+ relationship = [self lastRelationship];
}
- return isMultiHop;
+ NSDictionary* sourceToDestinationKeyMap = [self _sourceToDestinationKeyMap];
+ NSArray* sourceKeys = [sourceToDestinationKeyMap objectForKey:@"sourceKeys"];
+ NSArray* destinationKeys = [sourceToDestinationKeyMap objectForKey:@"destinationKeys"];
+ NSArray* joins = [relationship joins];
+ int joinsCount=[joins count];
+ int i = 0;
+
+ for(i=0;i0)
+ {
+ if ([qualifiers count] > 1)
+ qualifier = [EOAndQualifier qualifierWithQualifierArray:qualifiers];
+ else
+ qualifier = [qualifiers objectAtIndex:0];
+ }
+ return qualifier;
+
}
-- (void) _setSourceToDestinationKeyMap: (id)param0
+- (NSDictionary*) primaryKeyForTargetRowFromSourceDBSnapshot:(NSDictionary*)dbSnapshot
{
- [self notImplemented: _cmd]; // TODO
-}
-
-- (id) qualifierForDBSnapshot: (id)param0
-{
- return [self notImplemented: _cmd]; // TODO
-}
-
-- (id) primaryKeyForTargetRowFromSourceDBSnapshot: (id)param0
-{
- return [self notImplemented:_cmd]; // TODO
+ NSDictionary* sourceToDestinationKeyMap = [self _sourceToDestinationKeyMap];
+ NSArray* sourceKeys = [sourceToDestinationKeyMap objectForKey:@"sourceKeys"];
+ NSArray* destinationKeys = [sourceToDestinationKeyMap objectForKey:@"destinationKeys"];
+ NSMutableDictionary* pk = [NSMutableDictionary dictionaryWithDictionary:dbSnapshot
+ keys:sourceKeys];
+ [pk translateFromKeys:sourceKeys
+ toKeys:destinationKeys];
+ return pk;
}
/** Return relationship path (like toRel1.toRel2) if self is flattened, slef name otherwise.
**/
- (NSString*)relationshipPath
{
- //Seems OK
NSString *relationshipPath = nil;
-
-
if ([self isFlattened])
{
int i, count = [_definitionArray count];
@@ -1909,8 +1864,6 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
else
relationshipPath = [self name];
-
-
return relationshipPath;
}
@@ -1918,72 +1871,47 @@ becomes "name", and "FIRST_NAME" becomes "firstName".*/
{
BOOL isToManyToOne = NO;
-
-
if ([self isFlattened])
{
- BOOL isToMany = YES;
+ int l=0;
int count = [_definitionArray count];
-
- if (count >= 2)
- {
- EORelationship *firstRelationship = [_definitionArray
- objectAtIndex: 0];
-
- isToMany = [firstRelationship isToMany];
-
- if (!isToMany)
+ int i=0;
+ for(i=0;i 0 && primaryKeyAttributesCount > 0)
+ if([self isToMany])
+ foreignKeyInDestination=YES;
+ else
{
- NSUInteger i;
-
- for (i = 0;
- !foreignKeyInDestination && i < destAttributesCount;
- i++)
+ NSArray* sourceAttributes = [self sourceAttributes];
+ NSArray* pkAttributes = [_entity primaryKeyAttributes];
+ int sourceAttributesCount=[sourceAttributes count];
+ int pkAttributesCount=[pkAttributes count];
+ if (sourceAttributesCount==pkAttributesCount)
{
- EOAttribute *attribute = [destAttributes objectAtIndex: i];
- NSUInteger pkAttrIndex = [primaryKeyAttributes
- indexOfObjectIdenticalTo: attribute];
-
- foreignKeyInDestination = (pkAttrIndex == NSNotFound);
+ foreignKeyInDestination=YES;
+ int i=0;
+ for(i=0;foreignKeyInDestination && i0)
{
- EOJoin *aJoin = [_joins objectAtIndex: i];
- EOAttribute *sourceAttribute = [aJoin sourceAttribute];
-
- if ([attribute isEqual: sourceAttribute])
- join = aJoin;
+ int i=0;
+ for (i = 0; !join && i < count; i++)
+ {
+ EOJoin *aJoin = [_joins objectAtIndex: i];
+ if ([attribute isEqual: [aJoin sourceAttribute]]
+ || [attribute isEqual: [aJoin destinationAttribute]])
+ {
+ join = aJoin;
+ }
+ }
}
return join;
@@ -2203,15 +2078,22 @@ dst entity primaryKeyAttributeNames
- (void) _flushCache
{
- //VERIFY
- //[self notImplemented:_cmd]; // TODO
DESTROY(_sourceAttributes);
DESTROY(_destinationAttributes);
- DESTROY(_inverseRelationship);
- DESTROY(_hiddenInverseRelationship);
- DESTROY(_componentRelationships);
- _destination = nil;
+ EORelationship* inverseRelationship=AUTORELEASE(RETAIN(_inverseRelationship));
+ DESTROY(_inverseRelationship);
+ if (inverseRelationship!=nil)
+ [inverseRelationship _flushCache];
+
+ if (_hiddenInverseRelationship!=nil)
+ {
+ [[[self destinationEntity]_hiddenRelationships] removeObjectIdenticalTo:_hiddenInverseRelationship];
+ DESTROY(_hiddenInverseRelationship);
+ }
+
+ DESTROY(_sourceRowToForeignKeyMapping);
+ _destination = nil;
}
- (EOExpressionArray*) _definitionArray
@@ -2226,16 +2108,16 @@ dst entity primaryKeyAttributeNames
switch(deleteRule)
{
case EODeleteRuleNullify:
- deleteRuleString = @"";
+ deleteRuleString = @"EODeleteRuleNullify";
break;
case EODeleteRuleCascade:
- deleteRuleString = @"";
+ deleteRuleString = @"EODeleteRuleCascade";
break;
case EODeleteRuleDeny:
- deleteRuleString = @"";
+ deleteRuleString = @"EODeleteRuleDeny";
break;
case EODeleteRuleNoAction:
- deleteRuleString = @"";
+ deleteRuleString = @"EODeleteRuleNoAction";
break;
default:
[NSException raise: NSInvalidArgumentException
@@ -2279,29 +2161,38 @@ dst entity primaryKeyAttributeNames
{
NSDictionary *keyMap = nil;
- NSEmitTODO(); //TODO
-
- [self notImplemented: _cmd]; // TODO
-
if ([self isToManyToOne])
- {
- int count = [_definitionArray count];
-
- if (count >= 2) //??
+ {
+ int definitionArrayCount=[_definitionArray count];
+ EOEntity* entity = nil;
+ NSMutableString* relationshipPath = nil;
+ int k = 0;
+ int i = 0;
+ for(i=0; i < definitionArrayCount; i++)
{
- EORelationship *rel0 = [_definitionArray objectAtIndex: 0];
-
- if ([rel0 isToMany]) //??
+ EORelationship* relationship = [_definitionArray objectAtIndex:i];
+ switch(k)
{
- EOEntity *entity = [rel0 destinationEntity];
- EORelationship *rel1 = [_definitionArray objectAtIndex: 1];
-
- keyMap = [entity _keyMapForIdenticalKeyRelationshipPath:
- [rel1 name]];
+ case 0:
+ if([relationship isToMany])
+ {
+ k = 1;
+ entity=[relationship destinationEntity];
+ }
+ break;
+ case 1:
+ if (relationshipPath)
+ [relationshipPath appendString: @"."];
+ else
+ relationshipPath = [NSMutableString string];
+ [relationshipPath appendString: [relationship name]];
+ break;
+ default:
+ break;
}
}
+ keyMap=[entity _keyMapForIdenticalKeyRelationshipPath:relationshipPath];
}
-
return keyMap;
}
@@ -2309,26 +2200,24 @@ dst entity primaryKeyAttributeNames
{
NSDictionary *keyMap = nil;
- NSEmitTODO(); //TODO
-
- [self notImplemented: _cmd]; // TODO
-
if ([self isToManyToOne])
- {
- int count = [_definitionArray count];
-
- if (count >= 2) //??
+ {
+ int definitionArrayCount=[_definitionArray count];
+ NSMutableString* relationshipPath = nil;
+ int i = 0;
+ for(i=0; i < definitionArrayCount; i++)
{
- EORelationship *rel = [_definitionArray objectAtIndex: 0];
-
- if ([rel isToMany]) //??
- {
- EOEntity *entity = [rel entity];
-
- keyMap = [entity _keyMapForIdenticalKeyRelationshipPath:
- [rel name]];
- }
+ EORelationship* relationship = [_definitionArray objectAtIndex:i];
+ if (relationshipPath)
+ [relationshipPath appendString: @"."];
+ else
+ relationshipPath = [NSMutableString string];
+ [relationshipPath appendString: [relationship name]];
+ if ([relationship isToMany])
+ break;
}
+
+ keyMap=[[self entity]_keyMapForIdenticalKeyRelationshipPath:relationshipPath];
}
return keyMap;
@@ -2336,30 +2225,22 @@ dst entity primaryKeyAttributeNames
- (EORelationship*)_substitutionRelationshipForRow: (NSDictionary*)row
{
- EOEntity *entity = [self entity];
- EOModel *model = [entity model];
- EOModelGroup *modelGroup = [model modelGroup];
-
- if (modelGroup)
+ EOEntity* entity = [self entity];
+ EOModelGroup* modelGroup = [[entity model]modelGroup];
+ EORelationship* relationship = self;
+ if(modelGroup != nil
+ && modelGroup->_delegateRespondsTo.relationshipForRow)
{
- //??
- //NSEmitTODO(); //TODO
+ relationship = [[modelGroup delegate] entity:entity
+ relationshipForRow:row
+ relationship:self];
}
-
- return self;
+ return relationship;
}
- (void) _joinsChanged
{
- //VERIFIED DA
- int count = [_joins count];
-
-
-
-
- EOFLOGObjectLevelArgs(@"EORelationship", @"_joinsChanged:%@\nin %@", _joins, self);
-
- if (count > 0)
+ if ([_joins count] > 0)
{
EOJoin *join = [_joins objectAtIndex: 0];
EOAttribute *destinationAttribute = [join destinationAttribute];
@@ -2371,8 +2252,6 @@ dst entity primaryKeyAttributeNames
{
_destination = nil;
}
-
-
}
@end
diff --git a/EOAccess/EOSQLExpression.m b/EOAccess/EOSQLExpression.m
index a7cc23a..ebe54ca 100644
--- a/EOAccess/EOSQLExpression.m
+++ b/EOAccess/EOSQLExpression.m
@@ -2053,7 +2053,7 @@ else if([attribute isDerived] == YES)
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"[path objectAtIndex:%d]=%@",
i, relationship);
- NSAssert2([relationship isKindOfClass:[EORelationship class]],
+ NSAssert2([relationship isKindOfClass:GDL2_EORelationshipClass],
@"'%@' is not a relationship but a %@",
relationship,
[relationship class]);
diff --git a/EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m b/EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m
index 1eb64ac..39f4582 100644
--- a/EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m
+++ b/EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m
@@ -320,7 +320,6 @@ newValueForNumberTypeLengthAttribute(const void *bytes,
};
};
};
-
return value;
}
@@ -397,11 +396,15 @@ newValueForDateTypeLengthAttribute (const void *bytes,
{
getDigits(&str[5],tmpString,2,&error);
month = atoi(tmpString);
+ //Postgres can return bad dates sometimes (it accept bad date in insert/update)
+ NSCAssert2(month>0,@"Bad month in date %*s",length,bytes);
if (length > 9)
{
getDigits(&str[8],tmpString,2,&error);
day = atoi(tmpString);
+ //Postgres can return bad dates sometimes (it accept bad date in insert/update)
+ NSCAssert2(day>0,@"Bad day in date %*s",length,bytes);
if (length > 12)
{
@@ -1140,13 +1143,29 @@ each key
insertStatementForRow: nrow
entity: entity];
- if ([self _evaluateExpression: sqlexpr withAttributes: nil] == 0) //call evaluateExpression:
- [NSException raise: EOGeneralAdaptorException
- format: @"%@ -- %@ 0x%p: cannot insert row for entity '%@'",
- NSStringFromSelector(_cmd),
- NSStringFromClass([self class]),
- self,
- [entity name]];
+ if (!_delegateRespondsTo.shouldEvaluateExpression
+ || [_delegate adaptorChannel: self
+ shouldEvaluateExpression: sqlexpr])
+ {
+ if ([self _evaluateExpression: sqlexpr
+ withAttributes: nil] == 0)
+ {
+ [NSException raise: EOGeneralAdaptorException
+ format: @"%@ -- %@ 0x%p: cannot insert row for entity '%@'",
+ NSStringFromSelector(_cmd),
+ NSStringFromClass([self class]),
+ self,
+ [entity name]];
+ }
+ else
+ {
+ if (_delegateRespondsTo.didEvaluateExpression)
+ {
+ [_delegate adaptorChannel: self
+ didEvaluateExpression: sqlexpr];
+ }
+ }
+ }
}
[_adaptorContext autoCommitTransaction];
@@ -1191,8 +1210,19 @@ each key
deleteStatementWithQualifier: qualifier
entity: entity];
- rows = [self _evaluateExpression: sqlexpr withAttributes: nil];
-
+ if (!_delegateRespondsTo.shouldEvaluateExpression
+ || [_delegate adaptorChannel: self
+ shouldEvaluateExpression: sqlexpr])
+ {
+ rows = [self _evaluateExpression: sqlexpr
+ withAttributes: nil];
+ if (_delegateRespondsTo.didEvaluateExpression)
+ {
+ [_delegate adaptorChannel: self
+ didEvaluateExpression: sqlexpr];
+ }
+ }
+
[adaptorContext autoCommitTransaction];
return rows;
@@ -1262,8 +1292,18 @@ each key
fetchSpecification: fetchSpecification
entity: entity];
- [self _evaluateExpression: sqlExpr
- withAttributes: attributes];
+ if (!_delegateRespondsTo.shouldEvaluateExpression
+ || [_delegate adaptorChannel: self
+ shouldEvaluateExpression: sqlExpr])
+ {
+ [self _evaluateExpression: sqlExpr
+ withAttributes: attributes];
+ if (_delegateRespondsTo.didEvaluateExpression)
+ {
+ [_delegate adaptorChannel: self
+ didEvaluateExpression: sqlExpr];
+ }
+ }
[_adaptorContext autoCommitTransaction];
@@ -2198,6 +2238,7 @@ each key
EOAttribute *primAttribute;
NSString *sqlString;
NSNumber *pkValue = nil;
+ NSString *sqlFormat = nil;
const char *string = NULL;
int length = 0;
@@ -2211,9 +2252,12 @@ each key
{
return nil; // We support only number keys
}
-
- sqlString = [NSString stringWithFormat: @"SELECT nextval('%@_SEQ')",
- [entity primaryKeyRootName]];
+
+ sqlFormat=[NSString stringWithFormat: @"SELECT nextval('%@')",
+ [[[self adaptorContext]adaptor] primaryKeySequenceNameFormat]];
+
+ sqlString = [NSString stringWithFormat: sqlFormat,
+ [entity primaryKeyRootName]];
if ([self isDebugEnabled])
{