mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-04-22 12:55:44 +00:00
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m:
fix newValueForDateTypeLengthAttribute * EOAccess/EOEntityPriv.h declare -_isSingleTableEntity declare -_assertNoPropagateKeyCycleWithEntities:relationships: * EOAccess/EOEntity.m fix _flattenAttribute:relationshipPath:currentAttributes: use relationshipPathBy...Component make _addAttributesToFetchForRelationshipPath:atts: more understandable implement -_assertNoPropagateKeyCycleWithEntities:relationships: implement -_isSingleTableEntity fix validateValue:forKey: * EOAccess/EOExpressionArray.m implement -valueWithSQLExpressionElement:forSQLExpression: fix -valueForSQLExpression: * EOAccess/EODatabaseContext.m reformat -batchNewPrimaryKeysWithEntity:count: reformat -prepareForSaveWithCoordinator:editingContext: reformat and fix -recordChangesInEditingContext: reformat -recordUpdateForObject:changes: fix -valuesForKeys:object: fix -nullifyAttributesInRelationship:sourceObject:destinationObject: add -_mutableValuesForKeys:object: add -_recordInsertForIntermediateRowFromSourceObject:... fix -relayAttributesInRelationship:sourceObject:destinationObject: fix -relayPrimaryKey:sourceObject:destObject:relationship: fix -relayPrimaryKey:object:entity: fix -createAdaptorOperationsForDatabaseOperation: fix -_buildPrimaryKeyGeneratorListForEditingContext: * EOAccess/EODatabaseOperation.m clean code * EOAccess/EODatabaseChannel.m fix -_propertiesToFetch * EOControl/EONSAddOns.[hm] add NSString (EORelationshipPath) git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@37902 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
f4d5a358b0
commit
ea4c7676b6
13 changed files with 1238 additions and 1376 deletions
36
ChangeLog
36
ChangeLog
|
@ -1,3 +1,39 @@
|
|||
2014-05-22 Manuel Guesdon <mguesdon@orange-concept.com>
|
||||
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m:
|
||||
fix newValueForDateTypeLengthAttribute
|
||||
* EOAccess/EOEntityPriv.h
|
||||
declare -_isSingleTableEntity
|
||||
declare -_assertNoPropagateKeyCycleWithEntities:relationships:
|
||||
* EOAccess/EOEntity.m
|
||||
fix _flattenAttribute:relationshipPath:currentAttributes:
|
||||
use relationshipPathBy...Component
|
||||
make _addAttributesToFetchForRelationshipPath:atts: more understandable
|
||||
implement -_assertNoPropagateKeyCycleWithEntities:relationships:
|
||||
implement -_isSingleTableEntity
|
||||
fix validateValue:forKey:
|
||||
* EOAccess/EOExpressionArray.m
|
||||
implement -valueWithSQLExpressionElement:forSQLExpression:
|
||||
fix -valueForSQLExpression:
|
||||
* EOAccess/EODatabaseContext.m
|
||||
reformat -batchNewPrimaryKeysWithEntity:count:
|
||||
reformat -prepareForSaveWithCoordinator:editingContext:
|
||||
reformat and fix -recordChangesInEditingContext:
|
||||
reformat -recordUpdateForObject:changes:
|
||||
fix -valuesForKeys:object:
|
||||
fix -nullifyAttributesInRelationship:sourceObject:destinationObject:
|
||||
add -_mutableValuesForKeys:object:
|
||||
add -_recordInsertForIntermediateRowFromSourceObject:...
|
||||
fix -relayAttributesInRelationship:sourceObject:destinationObject:
|
||||
fix -relayPrimaryKey:sourceObject:destObject:relationship:
|
||||
fix -relayPrimaryKey:object:entity:
|
||||
fix -createAdaptorOperationsForDatabaseOperation:
|
||||
fix -_buildPrimaryKeyGeneratorListForEditingContext:
|
||||
* EOAccess/EODatabaseOperation.m
|
||||
clean code
|
||||
* EOAccess/EODatabaseChannel.m
|
||||
fix -_propertiesToFetch
|
||||
* EOControl/EONSAddOns.[hm]
|
||||
add NSString (EORelationshipPath)
|
||||
2014-04-30 Manuel Guesdon <mguesdon@orange-concept.com>
|
||||
* EOAdaptors/PostgreSQLAdaptor/PostgreSQLChannel.m:
|
||||
Handle Custom class in newValueForNumberTypeLengthAttribute()
|
||||
|
|
|
@ -543,14 +543,10 @@ RCS_ID("$Id$")
|
|||
{
|
||||
//OK
|
||||
NSArray *attributesToFetch=nil;
|
||||
|
||||
|
||||
|
||||
attributesToFetch = [_currentEntity _attributesToFetch];
|
||||
|
||||
NSAssert(_currentEntity, @"No current Entity");
|
||||
|
||||
|
||||
if(_currentEntity == nil)
|
||||
attributesToFetch= [_adaptorChannel describeResults];
|
||||
else
|
||||
attributesToFetch = [_currentEntity _attributesToFetch];
|
||||
|
||||
return attributesToFetch;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -53,6 +53,7 @@ RCS_ID("$Id$")
|
|||
#endif
|
||||
|
||||
#include <EOControl/EODebug.h>
|
||||
#include <EOControl/EOPrivate.h>
|
||||
|
||||
#include <EOAccess/EODatabaseOperation.h>
|
||||
#include <EOAccess/EOAttribute.h>
|
||||
|
@ -105,29 +106,15 @@ RCS_ID("$Id$")
|
|||
|
||||
- (NSDictionary *)dbSnapshot
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return _dbSnapshot;
|
||||
}
|
||||
|
||||
- (void)setDBSnapshot: (NSDictionary *)dbSnapshot
|
||||
{
|
||||
|
||||
|
||||
ASSIGN(_dbSnapshot, dbSnapshot);
|
||||
|
||||
|
||||
|
||||
if (dbSnapshot)
|
||||
[_newRow addEntriesFromDictionary: dbSnapshot];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *)newRow
|
||||
|
@ -188,16 +175,9 @@ RCS_ID("$Id$")
|
|||
|
||||
- (NSDictionary *)rowDiffs
|
||||
{
|
||||
//OK
|
||||
NSMutableDictionary *row = nil;
|
||||
NSEnumerator *newRowEnum = nil;
|
||||
NSString *key = nil;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
newRowEnum= [_newRow keyEnumerator];
|
||||
NSEnumerator *newRowEnum = [_newRow keyEnumerator];
|
||||
|
||||
while ((key = [newRowEnum nextObject]))
|
||||
{
|
||||
|
@ -216,10 +196,6 @@ RCS_ID("$Id$")
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
|
@ -227,9 +203,7 @@ RCS_ID("$Id$")
|
|||
{
|
||||
NSMutableDictionary *row = nil;
|
||||
EOAttribute *attr = nil;
|
||||
NSEnumerator *attrsEnum = nil;
|
||||
|
||||
attrsEnum = [attributes objectEnumerator];
|
||||
NSEnumerator *attrsEnum = [attributes objectEnumerator];
|
||||
while ((attr = [attrsEnum nextObject]))
|
||||
{
|
||||
NSString *name = [attr name];
|
||||
|
@ -279,16 +253,10 @@ RCS_ID("$Id$")
|
|||
|
||||
- (void)addAdaptorOperation: (EOAdaptorOperation *)adaptorOperation
|
||||
{
|
||||
//OK
|
||||
if (!_adaptorOps)
|
||||
_adaptorOps = [NSMutableArray new];
|
||||
|
||||
if (!adaptorOperation)
|
||||
{
|
||||
//TODO raise exception
|
||||
}
|
||||
else
|
||||
[_adaptorOps addObject: adaptorOperation];
|
||||
[_adaptorOps addObject: adaptorOperation];
|
||||
}
|
||||
|
||||
- (void)removeAdaptorOperation: (EOAdaptorOperation *)adaptorOperation
|
||||
|
@ -299,16 +267,16 @@ RCS_ID("$Id$")
|
|||
- (void)recordToManySnapshot: (NSArray *)gids
|
||||
relationshipName: (NSString *)name
|
||||
{
|
||||
//OK ??
|
||||
if (gids == nil)
|
||||
gids=(NSArray*)GDL2_EONull;
|
||||
|
||||
if (_toManySnapshots)
|
||||
[_toManySnapshots setObject: gids
|
||||
forKey: name];//TODO VERIFY
|
||||
else
|
||||
{
|
||||
_toManySnapshots = [NSMutableDictionary dictionaryWithObject: gids
|
||||
forKey: name];
|
||||
|
||||
RETAIN(_toManySnapshots);
|
||||
ASSIGN(_toManySnapshots,([NSMutableDictionary dictionaryWithObject: gids
|
||||
forKey: name]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -323,8 +291,6 @@ RCS_ID("$Id$")
|
|||
NSString *operatorString = nil;
|
||||
NSString *desc = nil;
|
||||
|
||||
|
||||
|
||||
switch (_databaseOperator)
|
||||
{
|
||||
case EODatabaseNothingOperator:
|
||||
|
@ -361,8 +327,6 @@ RCS_ID("$Id$")
|
|||
_dbSnapshot,
|
||||
_dbSnapshot];
|
||||
|
||||
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
|
|
|
@ -2791,7 +2791,10 @@ createInstanceWithEditingContext:globalID:zone:
|
|||
if ([currentAttributes objectForKey:aName]==nil)
|
||||
break;
|
||||
else
|
||||
[aName setString:@""];
|
||||
{
|
||||
[aName setString:@""];
|
||||
i++;
|
||||
}
|
||||
} while(1);
|
||||
|
||||
//Now create temporary attribute
|
||||
|
@ -3196,6 +3199,7 @@ returns nil if there's no key in the instanceDictionaryInitializer
|
|||
ASSIGN(_attributesToFetch,[[attrsByName allValues]sortedArrayUsingSelector:@selector(eoCompareOnName:)]);
|
||||
}
|
||||
}
|
||||
|
||||
return _attributesToFetch;
|
||||
}
|
||||
|
||||
|
@ -3772,43 +3776,47 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
|
|||
EOAttribute* sourceAttribute =[[joins objectAtIndex:i] sourceAttribute];
|
||||
NSString* sourceAttributeName = [sourceAttribute name];
|
||||
if ([attributes objectForKey:sourceAttributeName]==nil)
|
||||
[attributes setObject:sourceAttribute
|
||||
forKey:sourceAttributeName];
|
||||
{
|
||||
[attributes setObject:sourceAttribute
|
||||
forKey:sourceAttributeName];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EORelationship* relationship = [self relationshipForPath:relPath];
|
||||
NSRange rLast=[relPath rangeOfString:@"."
|
||||
options:NSBackwardsSearch];
|
||||
NSString* firstPathComponents = [relPath substringToIndex:rLast.location];
|
||||
NSString* firstPathComponents = [relPath relationshipPathByDeletingLastComponent];
|
||||
NSArray* joins = [relationship joins];
|
||||
int joinsCount = [joins count];
|
||||
if (joinsCount>0)
|
||||
{
|
||||
EOAttribute* attribute = nil;
|
||||
int i = 0;
|
||||
for(i=0;i<joinsCount;i++)
|
||||
{
|
||||
EOAttribute* sourceAttribute = [[joins objectAtIndex:i] sourceAttribute];
|
||||
NSEnumerator* attributesEnum = [attributes objectEnumerator];
|
||||
EOAttribute* attribute = nil;
|
||||
EOAttribute* foundAttribute = nil;
|
||||
while((attribute=[attributesEnum nextObject]))
|
||||
{
|
||||
EOAttribute* targetAttribute = [attribute targetAttribute];
|
||||
if (targetAttribute == sourceAttribute
|
||||
&& [[attribute relationshipPath] isEqual:firstPathComponents]
|
||||
&& ![attribute isReadOnly])
|
||||
break;
|
||||
{
|
||||
foundAttribute = attribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (attribute == nil)
|
||||
|
||||
if (foundAttribute == nil)
|
||||
{
|
||||
attribute = [self _flattenAttribute:sourceAttribute
|
||||
relationshipPath:firstPathComponents
|
||||
currentAttributes:attributes];
|
||||
[attributes setObject:attribute
|
||||
forKey: [attribute name]];
|
||||
EOAttribute* anAttribute = [self _flattenAttribute:sourceAttribute
|
||||
relationshipPath:firstPathComponents
|
||||
currentAttributes:attributes];
|
||||
[attributes setObject:anAttribute
|
||||
forKey: [anAttribute name]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4206,6 +4214,56 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path
|
|||
return expressionArray;
|
||||
}
|
||||
|
||||
+(void) _assertNoPropagateKeyCycleWithEntities:(NSMutableArray*)entities
|
||||
relationships:(NSMutableArray*)relationships
|
||||
{
|
||||
EOEntity* entity = [entities lastObject];
|
||||
NSArray* entityRelationships = [entity relationships];
|
||||
int i=0;
|
||||
for(i = [entityRelationships count] - 1; i >= 0; i--)
|
||||
{
|
||||
EORelationship* relationship = [entityRelationships objectAtIndex:i];
|
||||
if ([relationship propagatesPrimaryKey])
|
||||
{
|
||||
EOEntity* dstEntity=[relationship destinationEntity];
|
||||
if ([entities containsObject:dstEntity])
|
||||
{
|
||||
NSMutableString* tmpString=[NSMutableString string];
|
||||
int j=0;
|
||||
int c=[relationships count];
|
||||
for(j = 0; j < c; j++)
|
||||
{
|
||||
[tmpString appendFormat:@"\n\tEntity: %@ Relationship: %@ => ",
|
||||
[[entities objectAtIndex:j] name],
|
||||
[[relationships objectAtIndex:j] name]];
|
||||
}
|
||||
|
||||
[tmpString appendFormat:@"\n\tEntity: %@ Relationship: %@ => \n\tEntity: %@",
|
||||
[[entities lastObject] name],
|
||||
[relationship name],
|
||||
[dstEntity name]];
|
||||
[NSException raise: @"NSIllegalStateException"
|
||||
format:@"%@ EOEntity propagation cycle discovered in model group while attempting to save. Check your model group and break the following cycle: %@",
|
||||
NSStringFromSelector(_cmd),
|
||||
tmpString];
|
||||
}
|
||||
[relationships addObject:relationship];
|
||||
[entities addObject:dstEntity];
|
||||
[self _assertNoPropagateKeyCycleWithEntities:entities
|
||||
relationships:relationships];
|
||||
[relationships removeLastObject];
|
||||
[entities removeLastObject];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation EOEntity (EOEntityPrivateSingleEntity)
|
||||
- (BOOL) _isSingleTableEntity
|
||||
{
|
||||
return _flags.isSingleTableEntity;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation EOEntity (Deprecated)
|
||||
|
@ -4487,29 +4545,18 @@ fromInsertionInEditingContext: (EOEditingContext *)context
|
|||
forKey: (NSString *)key
|
||||
{
|
||||
NSException *exception = nil;
|
||||
EOAttribute *attr;
|
||||
EORelationship *relationship;
|
||||
EOAttribute *attr = nil;
|
||||
|
||||
NSAssert(valueP, @"No value pointer");
|
||||
|
||||
attr = [_entity attributeNamed: key];
|
||||
|
||||
if (attr)
|
||||
{
|
||||
exception = [attr validateValue: valueP];
|
||||
}
|
||||
exception = [attr validateValue: valueP];
|
||||
else
|
||||
{
|
||||
relationship = [_entity relationshipNamed: key];
|
||||
|
||||
EORelationship* relationship = [_entity relationshipNamed: key];
|
||||
if (relationship)
|
||||
{
|
||||
exception = [relationship validateValue: valueP];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSEmitTODO(); //TODO
|
||||
}
|
||||
exception = [relationship validateValue: valueP];
|
||||
}
|
||||
|
||||
return exception;
|
||||
|
|
|
@ -113,6 +113,8 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path;
|
|||
arguments: (char *)param2;
|
||||
- (EOExpressionArray *)_parseRelationshipPath: (NSString *)path;
|
||||
- (id)_parsePropertyName: (NSString *)propertyName;
|
||||
+(void) _assertNoPropagateKeyCycleWithEntities:(NSMutableArray*)entities
|
||||
relationships:(NSMutableArray*)relationships;
|
||||
//- (id)_newStringWithBuffer: (unsigned short *)param0
|
||||
// length: (unsigned int *)param1;
|
||||
@end
|
||||
|
@ -129,4 +131,8 @@ toDestinationAttributeInLastComponentOfRelationshipPath: (NSString *)path;
|
|||
- (NSArray *)flattenedAttributes;
|
||||
@end
|
||||
|
||||
@interface EOEntity (EOEntityPrivateSingleEntity)
|
||||
- (BOOL) _isSingleTableEntity;
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
|
@ -341,40 +341,65 @@ static SEL eqSel;
|
|||
return [[self objectAtIndex:0] isKindOfClass:GDL2_EORelationshipClass];
|
||||
}
|
||||
|
||||
- (NSString *)valueWithSQLExpressionElement:(EOSQLExpression*)element
|
||||
forSQLExpression:(EOSQLExpression*)sqlExpression
|
||||
{
|
||||
NSString* value=nil;
|
||||
if ([element respondsToSelector:@selector(valueForSQLExpression:)])
|
||||
value=[element valueForSQLExpression:sqlExpression];
|
||||
else if ([element isKindOfClass:[NSNumber class]])
|
||||
value=[element stringValue];
|
||||
else if ([element isKindOfClass:[NSString class]])
|
||||
value=(NSString*)element;
|
||||
else if (element == GDL2_EONull)
|
||||
value = @"NULL";
|
||||
else
|
||||
value=[element description];
|
||||
return value;
|
||||
}
|
||||
|
||||
- (NSString *)valueForSQLExpression: (EOSQLExpression*)sqlExpression
|
||||
{
|
||||
//TODO verify
|
||||
NSMutableString *value = [NSMutableString string];
|
||||
volatile int i;
|
||||
int count;
|
||||
NSString* value = nil;
|
||||
|
||||
NS_DURING //Just for debugging
|
||||
int count=[self count];
|
||||
if (count>0)
|
||||
{
|
||||
count = [self count];
|
||||
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
id obj = [self objectAtIndex: i];
|
||||
NSString *relValue;
|
||||
|
||||
relValue = [obj valueForSQLExpression: sqlExpression];
|
||||
|
||||
if (i > 0 && _infix)
|
||||
[value appendString: _infix];
|
||||
|
||||
[value appendString: relValue];
|
||||
}
|
||||
if (sqlExpression != nil
|
||||
&& [[self firstObject] isKindOfClass:GDL2_EORelationshipClass])
|
||||
{
|
||||
value = [sqlExpression sqlStringForAttributePath:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMutableString* buffer = [NSMutableString string];
|
||||
if (_prefix!=nil)
|
||||
[buffer appendString: _prefix];
|
||||
BOOL isFirst=YES;
|
||||
int i=0;
|
||||
for(i=0; i < count; i++)
|
||||
{
|
||||
NSObject* component = [self objectAtIndex:i];
|
||||
NSString* aValue = [self valueWithSQLExpressionElement:component
|
||||
forSQLExpression:sqlExpression];
|
||||
if ([aValue length]>0)
|
||||
{
|
||||
if (isFirst)
|
||||
isFirst=NO;
|
||||
else if (_infix != nil)
|
||||
[buffer appendString:_infix];
|
||||
[buffer appendString:aValue];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isFirst)
|
||||
{
|
||||
if(_suffix != nil)
|
||||
[buffer appendString:_suffix];
|
||||
value=[NSString stringWithString:buffer];
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
NSLog(@"exception in EOExpressionArray valueForSQLExpression: self=%p class=%@ i=%d", self, [self class], i);
|
||||
NSLog(@"exception in EOExpressionArray valueForSQLExpression: self=%@ class=%@ i=%d", self, [self class], i);
|
||||
NSLog(@"exception=%@", localException);
|
||||
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,6 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
[sqlExpression prepareSelectExpressionWithAttributes: attributes
|
||||
lock: flag
|
||||
fetchSpecification: fetchSpecification];
|
||||
|
||||
return sqlExpression;
|
||||
}
|
||||
|
||||
|
@ -582,183 +581,91 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
_whereClauseString : nil)]);
|
||||
}
|
||||
|
||||
/*
|
||||
//TC:
|
||||
- (void)prepareSelectExpressionWithAttributes:(NSArray *)attributes
|
||||
lock:(BOOL)flag
|
||||
fetchSpecification:(EOFetchSpecification *)fetchSpecification
|
||||
{
|
||||
NSEnumerator *attrEnum, *sortEnum;
|
||||
EOAttribute *attribute;
|
||||
EOSortOrdering *sort;
|
||||
NSString *tableList;
|
||||
NSString *lockClause = nil;
|
||||
NSArray *sortOrderings;
|
||||
|
||||
EOFLOGObjectFnStartCond(@"EOSQLExpression");
|
||||
|
||||
// Turbocat (RawRow Additions)
|
||||
if ([fetchSpecification rawRowKeyPaths]) {
|
||||
|
||||
// fill _aliasesByRelationshipPath before calling addSelectListAttribute
|
||||
|
||||
NSEnumerator *keyPathEnum = [[fetchSpecification rawRowKeyPaths] objectEnumerator];
|
||||
NSString *keyPath;
|
||||
EOExpressionArray *expressionArray;
|
||||
|
||||
while (keyPath = [keyPathEnum nextObject]) {
|
||||
if([keyPath isNameOfARelationshipPath]) {
|
||||
|
||||
// get relationships
|
||||
NSString *newKeyPath = [keyPath stringByDeletingPathExtension]; // cut attributename
|
||||
|
||||
if (![_aliasesByRelationshipPath objectForKey:newKeyPath]) {
|
||||
//int count = [[_aliasesByRelationshipPath allKeys] count];
|
||||
NSString *prefix = [NSString stringWithFormat:@"t%d",_alias++];
|
||||
|
||||
[_aliasesByRelationshipPath setObject:prefix forKey:newKeyPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
//NSLog(@"_aliasesByRelationshipPath = %@", _aliasesByRelationshipPath);
|
||||
} // Turbocat (RawRow Additions)
|
||||
|
||||
attrEnum = [attributes objectEnumerator];
|
||||
while((attribute = [attrEnum nextObject]))
|
||||
{
|
||||
[self addSelectListAttribute:attribute];
|
||||
}
|
||||
|
||||
ASSIGN(_whereClauseString, [(id)[fetchSpecification qualifier]
|
||||
sqlStringForSQLExpression:self]);
|
||||
|
||||
sortOrderings = [fetchSpecification sortOrderings];
|
||||
|
||||
sortEnum = [sortOrderings objectEnumerator];
|
||||
while((sort = [sortEnum nextObject]))
|
||||
[self addOrderByAttributeOrdering:sort];
|
||||
|
||||
[self joinExpression];
|
||||
tableList = [self tableListWithRootEntity:_entity];
|
||||
if(flag) lockClause = [self lockClause];
|
||||
|
||||
ASSIGN(_statement, [self assembleSelectStatementWithAttributes:attributes
|
||||
lock:flag
|
||||
qualifier:[fetchSpecification qualifier]
|
||||
fetchOrder:sortOrderings
|
||||
selectString:nil //TODO
|
||||
columnList:_listString
|
||||
tableList:tableList
|
||||
whereClause:([_whereClauseString length] ?
|
||||
_whereClauseString : nil)
|
||||
joinClause:([_joinClauseString length] ?
|
||||
_joinClauseString : nil)
|
||||
orderByClause:([_orderByString length] ?
|
||||
_orderByString : nil)
|
||||
lockClause:lockClause]);
|
||||
|
||||
EOFLOGObjectFnStopCond(@"EOSQLExpression");
|
||||
}
|
||||
*/
|
||||
|
||||
- (void)prepareSelectExpressionWithAttributes: (NSArray *)attributes
|
||||
lock: (BOOL)flag
|
||||
fetchSpecification: (EOFetchSpecification *)fetchSpecification
|
||||
{
|
||||
BOOL useAliases=NO;
|
||||
int attributesCount=[attributes count];
|
||||
EOQualifier *fetchQualifier = nil;
|
||||
EOQualifier *restrictingQualifier = nil;
|
||||
NSString *whereClauseString = nil;
|
||||
EOQualifier *finalQualifier = nil;
|
||||
NSArray *sortOrderings = nil;
|
||||
int sortOrderingsCount = 0;
|
||||
EOEntity *rootEntity = nil;
|
||||
NSString *tableList = nil;
|
||||
NSString *lockClauseString = nil;
|
||||
BOOL usesDistinct = NO;
|
||||
NSString *statement = nil;
|
||||
NSString *selectCommand = nil;
|
||||
//Add Attributes to listString
|
||||
int i, count = [attributes count];
|
||||
NSString *selectString = nil;
|
||||
int i=0;
|
||||
|
||||
EOFLOGObjectFnStartCond(@"EOSQLExpression");
|
||||
|
||||
//OK
|
||||
for (i = 0; i < count; i++)
|
||||
NSString* firstRelationshipPath=nil;
|
||||
//Search if we should use aliases
|
||||
for(i=0;i<attributesCount;i++)
|
||||
{
|
||||
EOAttribute *attribute = [attributes objectAtIndex: i];
|
||||
|
||||
/* Add non-relationship definitions such as aggregates. */
|
||||
if ([attribute isFlattened])
|
||||
EOAttribute* attribute = [attributes objectAtIndex:i];
|
||||
if (![attribute isFlattened])
|
||||
{
|
||||
NSMutableString *listString = [self listString];
|
||||
NSString *definition = [attribute definition];
|
||||
|
||||
if (definition)
|
||||
{
|
||||
NSRange range = [definition rangeOfString:@"."];
|
||||
|
||||
if (range.length == 0)
|
||||
{
|
||||
[self appendItem: definition
|
||||
toListString: listString];
|
||||
}
|
||||
}
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"flattened attribute=%@",
|
||||
attribute);
|
||||
}
|
||||
useAliases = YES;
|
||||
break;
|
||||
}
|
||||
else if (firstRelationshipPath == nil)
|
||||
{
|
||||
firstRelationshipPath = [attribute relationshipPath];
|
||||
// continue
|
||||
}
|
||||
else if ([firstRelationshipPath isEqualToString:[attribute relationshipPath]])
|
||||
{
|
||||
// still same relationshipPath: continue
|
||||
}
|
||||
else
|
||||
[self addSelectListAttribute: attribute];
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_listString=%@",
|
||||
_listString);
|
||||
{
|
||||
useAliases = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
[self setUseAliases:useAliases];
|
||||
|
||||
//Add attributes
|
||||
for(i=0;i<attributesCount;i++)
|
||||
[self addSelectListAttribute:[attributes objectAtIndex:i]];
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_listString=%@", _listString);
|
||||
|
||||
fetchQualifier = [fetchSpecification qualifier]; //OK
|
||||
//call fetchSpecification -isDeep
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"fetchQualifier=%@",
|
||||
fetchQualifier);
|
||||
//Build Where Clause
|
||||
fetchQualifier = [fetchSpecification qualifier];
|
||||
if ([fetchSpecification isDeep]
|
||||
&& [_entity _isSingleTableEntity])
|
||||
finalQualifier = [_entity _singleTableRestrictingQualifier];
|
||||
else
|
||||
finalQualifier = [_entity restrictingQualifier];
|
||||
|
||||
restrictingQualifier = [_entity restrictingQualifier];
|
||||
|
||||
if (fetchQualifier && restrictingQualifier)
|
||||
if (finalQualifier != nil)
|
||||
{
|
||||
fetchQualifier = [[EOAndQualifier alloc] initWithQualifiers:fetchQualifier, restrictingQualifier, nil];
|
||||
AUTORELEASE(fetchQualifier);
|
||||
if (fetchQualifier != nil)
|
||||
finalQualifier=[EOAndQualifier qualifierWithQualifiers:finalQualifier, fetchQualifier, nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
fetchQualifier = fetchQualifier ? fetchQualifier : restrictingQualifier;
|
||||
}
|
||||
finalQualifier = fetchQualifier;
|
||||
|
||||
//Build Where Clause
|
||||
whereClauseString = [(id<EOQualifierSQLGeneration>)fetchQualifier sqlStringForSQLExpression: self];
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"whereClauseString=%@",
|
||||
whereClauseString);
|
||||
ASSIGN(_whereClauseString, whereClauseString);
|
||||
ASSIGN(_whereClauseString,([(id<EOQualifierSQLGeneration>)finalQualifier sqlStringForSQLExpression: self]));
|
||||
|
||||
//Build Ordering Clause
|
||||
sortOrderings = [fetchSpecification sortOrderings];
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sortOrderings=%@",
|
||||
sortOrderings);
|
||||
|
||||
if ([sortOrderings count] > 0)
|
||||
sortOrderingsCount = [sortOrderings count];
|
||||
if (sortOrderingsCount>0)
|
||||
{
|
||||
int i, count = [sortOrderings count];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
for (i = 0; i < sortOrderingsCount; i++)
|
||||
{
|
||||
EOSortOrdering *order = [sortOrderings objectAtIndex: i];
|
||||
EOSortOrdering *sortOrdering = [sortOrderings objectAtIndex: i];
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"order=%@", order);
|
||||
NSAssert3([order isKindOfClass: [EOSortOrdering class]],
|
||||
NSAssert3([sortOrdering isKindOfClass: [EOSortOrdering class]],
|
||||
@"order is not a EOSortOrdering but a %@: %p %@",
|
||||
[order class],
|
||||
order,
|
||||
order);
|
||||
[sortOrdering class],
|
||||
sortOrdering,
|
||||
sortOrdering);
|
||||
|
||||
[self addOrderByAttributeOrdering: order];
|
||||
[self addOrderByAttributeOrdering: sortOrdering];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -767,11 +674,11 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_joinClauseString=%@",
|
||||
_joinClauseString);
|
||||
|
||||
//Build Table List
|
||||
rootEntity = [self _rootEntityForExpression];
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"rootEntity=%@",
|
||||
[rootEntity name]);
|
||||
|
||||
//Build Table List
|
||||
tableList = [self tableListWithRootEntity: rootEntity];
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"tableList=%@", tableList);
|
||||
|
||||
|
@ -786,16 +693,16 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"usesDistinct=%d", usesDistinct);
|
||||
|
||||
if (usesDistinct)
|
||||
selectCommand = @"SELECT distinct ";
|
||||
selectString = @"SELECT distinct ";
|
||||
else
|
||||
selectCommand = @"SELECT ";
|
||||
selectString = @"SELECT ";
|
||||
|
||||
//Now Build Statement
|
||||
statement = [self assembleSelectStatementWithAttributes: attributes
|
||||
lock: flag
|
||||
qualifier: fetchQualifier
|
||||
qualifier: finalQualifier
|
||||
fetchOrder: sortOrderings
|
||||
selectString: selectCommand
|
||||
selectString: selectString
|
||||
columnList: _listString
|
||||
tableList: tableList
|
||||
whereClause: ([_whereClauseString length] > 0
|
||||
|
@ -1088,7 +995,6 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
|
||||
- (void)addSelectListAttribute: (EOAttribute *)attribute
|
||||
{
|
||||
//OK
|
||||
NSMutableString *listString;
|
||||
NSString *string;
|
||||
NSString *sqlStringForAttribute = [self sqlStringForAttribute:attribute];
|
||||
|
@ -1883,7 +1789,7 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
- (NSString *)sqlStringForAttribute: (EOAttribute *)attribute
|
||||
{
|
||||
NSString *sqlString = nil;
|
||||
|
||||
EOExpressionArray* definition = nil;
|
||||
EOFLOGObjectFnStartCond(@"EOSQLExpression");
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"attribute=%@",
|
||||
|
@ -1898,6 +1804,32 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"_definitionArray count=%d",
|
||||
[[attribute _definitionArray]count]);
|
||||
|
||||
definition = [attribute _definitionArray];
|
||||
if ([definition count]>1)
|
||||
{
|
||||
sqlString = [definition valueForSQLExpression:self];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString* columnName = [attribute columnName];
|
||||
if (columnName == nil)
|
||||
{
|
||||
[NSException raise: @"NSIllegalStateException"
|
||||
format: @"sqlStringForAttribute: attempt to generate SQL for attribute '%@' on entity '%@' with undefined column name. You must define a column name for this attribute before attempting a database operation.",
|
||||
[attribute name],
|
||||
[[attribute entity] name]];
|
||||
}
|
||||
if (![self useAliases])
|
||||
sqlString = columnName;
|
||||
else
|
||||
sqlString = [@"t0." stringByAppendingString:[self sqlStringForSchemaObjectName:columnName]];
|
||||
}
|
||||
|
||||
EOFLOGObjectLevelArgs(@"EOSQLExpression", @"sqlString=%@", sqlString);
|
||||
EOFLOGObjectFnStopCond(@"EOSQLExpression");
|
||||
|
||||
return sqlString;
|
||||
/*
|
||||
if ([attribute isFlattened])
|
||||
{
|
||||
sqlString = [self sqlStringForAttributePath:
|
||||
|
@ -1907,10 +1839,8 @@ NSString *EOBindVariableColumnKey = @"EOBindVariableColumnKey";
|
|||
attribute);
|
||||
}
|
||||
//mirko:
|
||||
/*
|
||||
else if([attribute isDerived] == YES)
|
||||
return [attribute definition];
|
||||
*/
|
||||
// else if([attribute isDerived] == YES)
|
||||
// return [attribute definition];
|
||||
else
|
||||
{
|
||||
if (![self useAliases])//OK
|
||||
|
@ -2017,6 +1947,7 @@ else if([attribute isDerived] == YES)
|
|||
EOFLOGObjectFnStopCond(@"EOSQLExpression");
|
||||
|
||||
return sqlString;
|
||||
*/
|
||||
}
|
||||
|
||||
- (NSString *)sqlStringForAttributePath: (NSArray *)path
|
||||
|
|
|
@ -370,6 +370,7 @@ newValueForBytesTypeLengthAttribute (const void *bytes,
|
|||
return data;
|
||||
}
|
||||
|
||||
//If you make changes in this function, PLEASE make tests (see +initialize method below). mguesdon
|
||||
static id
|
||||
newValueForDateTypeLengthAttribute (const void *bytes,
|
||||
int length,
|
||||
|
@ -383,7 +384,7 @@ newValueForDateTypeLengthAttribute (const void *bytes,
|
|||
unsigned minute = 0;
|
||||
unsigned second = 0;
|
||||
unsigned millisecond = 0;
|
||||
int tz = 0;
|
||||
int tzIndex = 0;
|
||||
NSTimeZone *timezone = nil;
|
||||
NSCalendarDate *date = nil;
|
||||
const char *str = bytes;
|
||||
|
@ -399,54 +400,66 @@ newValueForDateTypeLengthAttribute (const void *bytes,
|
|||
getDigits(&str[0],tmpString,4,&error);
|
||||
year = atoi(tmpString);
|
||||
|
||||
if (length > 6)
|
||||
{
|
||||
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)
|
||||
{
|
||||
getDigits(&str[11],tmpString,2,&error);
|
||||
hour = atoi(tmpString);
|
||||
|
||||
if (length > 15)
|
||||
{
|
||||
getDigits(&str[14],tmpString,2,&error);
|
||||
minute = atoi(tmpString);
|
||||
|
||||
if (length > 18)
|
||||
{
|
||||
getDigits(&str[17],tmpString,2,&error);
|
||||
second = atoi(tmpString);
|
||||
|
||||
if (length > 19)
|
||||
{
|
||||
tz = getDigits(&str[17],tmpString,7,&error);
|
||||
millisecond = atoi(tmpString);
|
||||
if (length > 6)
|
||||
{
|
||||
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)
|
||||
{
|
||||
getDigits(&str[11],tmpString,2,&error);
|
||||
hour = atoi(tmpString);
|
||||
|
||||
if (length > 15)
|
||||
{
|
||||
getDigits(&str[14],tmpString,2,&error);
|
||||
minute = atoi(tmpString);
|
||||
|
||||
if (length > 18)
|
||||
{
|
||||
getDigits(&str[17],tmpString,2,&error);
|
||||
second = atoi(tmpString);
|
||||
|
||||
if (length > 20)
|
||||
{
|
||||
if (str[19]=='.')
|
||||
{
|
||||
tzIndex = 20+getDigits(&str[20],tmpString,7,&error);
|
||||
millisecond = atoi(tmpString);
|
||||
}
|
||||
else
|
||||
tzIndex=19;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tz)
|
||||
if (tzIndex)
|
||||
{
|
||||
int sign = (str[tz]) == '-' ? -1 : 1;
|
||||
getDigits(&str[tz+1],tmpString,2,&error);
|
||||
tz = atoi(tmpString);
|
||||
if (tz < 100) tz *= 100;
|
||||
tz = sign * ((tz / 100) * 60 + (tz % 100)) * 60;
|
||||
timezone = [NSTimeZone timeZoneForSecondsFromGMT: tz];
|
||||
while(isspace(str[tzIndex])
|
||||
&& tzIndex<length)
|
||||
tzIndex++;
|
||||
if (tzIndex<length)
|
||||
{
|
||||
int sign = (str[tzIndex]) == '-' ? -1 : 1;
|
||||
int charsCount=getDigits(&str[tzIndex+1],tmpString,4,&error);
|
||||
int tz = atoi(tmpString);
|
||||
if (charsCount<=2)
|
||||
tz *= 100;
|
||||
tz = sign * ((tz / 100) * 60 + (tz % 100)) * 60;
|
||||
timezone = [NSTimeZone timeZoneForSecondsFromGMT: tz];
|
||||
}
|
||||
}
|
||||
|
||||
date = [attribute newDateForYear: year
|
||||
|
@ -458,7 +471,6 @@ newValueForDateTypeLengthAttribute (const void *bytes,
|
|||
millisecond: millisecond
|
||||
timezone: timezone
|
||||
zone: 0];
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
|
@ -501,6 +513,62 @@ newValueForBytesLengthAttribute (const void *bytes,
|
|||
= [EOAttribute instancesRespondToSelector: @selector(_valueTypeCharacter)];
|
||||
|
||||
initialized = YES;
|
||||
|
||||
/*
|
||||
EOAttribute* anAttribute=AUTORELEASE([EOAttribute new]);
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21.2531419+01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21.2531419+01",
|
||||
strlen("2006-12-31 00:45:21.2531419+01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21.2531419-01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21.2531419-01",
|
||||
strlen("2006-12-31 00:45:21.2531419-01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21.25314+01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21.25314+01",
|
||||
strlen("2006-12-31 00:45:21.25314+01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21.25314-01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21.25314-01",
|
||||
strlen("2006-12-31 00:45:21.25314-01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21+01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21+01",
|
||||
strlen("2006-12-31 00:45:21+01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21-01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21-01",
|
||||
strlen("2006-12-31 00:45:21-01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21.25314 +01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21.25314 +01",
|
||||
strlen("2006-12-31 00:45:21.25314 +01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21.25314 -01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21.25314 -01",
|
||||
strlen("2006-12-31 00:45:21.25314 -01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21 +01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21 +01",
|
||||
strlen("2006-12-31 00:45:21 +01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
NSLog(@"TEST DATES: 2006-12-31 00:45:21 -01 => %@",
|
||||
newValueForDateTypeLengthAttribute ("2006-12-31 00:45:21 -01",
|
||||
strlen("2006-12-31 00:45:21 -01"),
|
||||
anAttribute,
|
||||
NSUTF8StringEncoding));
|
||||
*/
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -2667,7 +2667,6 @@ _mergeValueForKey(id obj, id value,
|
|||
|
||||
[_objectStore saveChangesInEditingContext: self];
|
||||
|
||||
|
||||
[self didSaveChanges];
|
||||
|
||||
|
||||
|
|
|
@ -164,4 +164,12 @@ GDL2_Activate(Class sup, Class cls);
|
|||
|
||||
@end
|
||||
|
||||
@interface NSString (EORelationshipPath)
|
||||
- (NSString*) relationshipPathByDeletingFirstComponent;
|
||||
- (NSString*) firstComponentFromRelationshipPath;
|
||||
- (NSString*) relationshipPathByDeletingLastComponent;
|
||||
- (NSString*) lastComponentFromRelationshipPath;
|
||||
- (BOOL) relationshipPathIsMultiHop;
|
||||
@end
|
||||
|
||||
#endif /* __EONSAddOns_h__ */
|
||||
|
|
|
@ -803,3 +803,52 @@ GDL2_Activate(Class sup, Class cls)
|
|||
|
||||
@end
|
||||
|
||||
@implementation NSString (EORelationshipPath)
|
||||
|
||||
- (NSString*) relationshipPathByDeletingFirstComponent
|
||||
{
|
||||
NSRange r=[self rangeOfString:@"."];
|
||||
if (r.length==0)
|
||||
return nil;
|
||||
else
|
||||
return [self substringFromIndex:r.location+r.length];
|
||||
}
|
||||
|
||||
- (NSString*) firstComponentFromRelationshipPath
|
||||
{
|
||||
NSRange r=[self rangeOfString:@"."];
|
||||
if (r.length==0)
|
||||
return nil;
|
||||
else
|
||||
return [self substringToIndex:r.location];
|
||||
}
|
||||
|
||||
- (NSString*) relationshipPathByDeletingLastComponent;
|
||||
{
|
||||
NSRange r=[self rangeOfString:@"."
|
||||
options:NSBackwardsSearch];
|
||||
if (r.length==0)
|
||||
return nil;
|
||||
else
|
||||
return [self substringToIndex:r.location];
|
||||
}
|
||||
|
||||
- (NSString*) lastComponentFromRelationshipPath
|
||||
{
|
||||
NSRange r=[self rangeOfString:@"."
|
||||
options:NSBackwardsSearch];
|
||||
if (r.length==0)
|
||||
return nil;
|
||||
else
|
||||
return [self substringFromIndex:r.location+r.length];
|
||||
}
|
||||
|
||||
- (BOOL) relationshipPathIsMultiHop
|
||||
{
|
||||
NSRange r=[self rangeOfString:@"."];
|
||||
return (r.length>0 ? YES : NO);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ static inline void GDL2_AddObjectWithImpPtr(id object,IMP* impPtr,id objectToAdd
|
|||
#define GDL2_ObjectAtIndexWithImp(array,methodIMP,index) \
|
||||
(*(methodIMP))((array),@selector(objectAtIndex:),(index))
|
||||
|
||||
static inline id GDL2_ObjectAtIndexWithImpPtr(id object,IMP* impPtr,int index)
|
||||
static inline id GDL2_ObjectAtIndexWithImpPtr(id object,IMP* impPtr,NSUInteger index)
|
||||
{
|
||||
if (object)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue