diff options
author | rowanbeentje <rowan@beent.je> | 2012-02-23 02:13:56 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2012-02-23 02:13:56 +0000 |
commit | 05f1612cbb7e33cf9135a346fc2505cc0e87e853 (patch) | |
tree | 785824be4e44a61389271343d958851fa4ff7dd0 /Frameworks/MCPKit/MCPEntrepriseKit | |
parent | a889340b9cb1eca0d3ff022e8e6e2c718480bf44 (diff) | |
download | sequelpro-05f1612cbb7e33cf9135a346fc2505cc0e87e853.tar.gz sequelpro-05f1612cbb7e33cf9135a346fc2505cc0e87e853.tar.bz2 sequelpro-05f1612cbb7e33cf9135a346fc2505cc0e87e853.zip |
Warning: this branch commit is largely untested, and known to throw exceptions as database structure retrieval is currently missing!
Further work on SPMySQLFramework integration:
- Improve SPMySQL framework build settings including correct ppc builds and a Distribution configuration for the build distributions to match
- Add new convenience querying and result methods to the framework
- Amend Sequel Pro source to use the new SPMySQL.framework methods everywhere, replacing MCPKit methods where they differ and improving some functions
- Remove MCPKit from the source
- Fix a number of warnings on Release-style builds
Diffstat (limited to 'Frameworks/MCPKit/MCPEntrepriseKit')
20 files changed, 0 insertions, 4162 deletions
diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPAttribute.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPAttribute.h deleted file mode 100644 index 469d0808..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPAttribute.h +++ /dev/null @@ -1,106 +0,0 @@ -// -// $Id$ -// -// MCPAttribute.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -@class MCPModel; -@class MCPClassDescription; -@class MCPRelation; -@class MCPJoin; - -@interface MCPAttribute : NSObject < NSCoding > -{ -@protected - MCPClassDescription *classDescription; // ClassDescription of which the attribute is attribute - NSString *name; // Name of the attribute (Obj-C side) - Class valueClass; // Class used by the attribute (or NULL if the internal type is not an object) - NSString *internalType; // Name of the class, or type used for the class definition - NSString *externalName; // Name of the corresponding column in the DB - NSString *externalType; // Type used to store the attribute (in the DB) - NSUInteger width; // Width (for storing by the DB) - BOOL allowsNull; // Attribute can be null - BOOL autoGenerated; // Attribute is auto generated by the DB - BOOL isPartOfKey; // Attribute is part of theprimary key of the class description - BOOL isPartOfIdentity; // Attribute is part of the idclass description of the class description - BOOL hasAccessor; // Does this attribute have an accessor - id defaultValue; // Default value of the attribute - NSMutableArray *joins; // An array of the joins using this attribute -} - -#pragma mark Class methods -+ (void) initialize; - -#pragma mark Life cycle -- (id) initForClassDescription:(MCPClassDescription *) iClassDescription withName:(NSString *) iName; -- (void) dealloc; - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder; -- (void) encodeWithCoder:(NSCoder *) encoder; - -#pragma mark Setters -- (void) setName:(NSString *) iName; -- (void) setValueClass:(Class) iValueClass; -- (void) setInternalType:(NSString *) iInternalType; -- (void) setExternalType:(NSString *) iExternalType; -- (void) setExternalName:(NSString *) iExternalName; -- (void) setWidth:(NSUInteger) iWidth; -- (void) setAllowsNull:(BOOL) iAllowsNull; -- (void) setAutoGenerated:(BOOL) iAutoGenerated; -- (void) setIsPartOfKey:(BOOL) iIsPartOfKey; -- (void) setIsPartOfIdentity:(BOOL) iIsPartOfIdentity; -- (void) setHasAccessor:(BOOL) iHasAccessor; -- (void) setDefaultValue:(id) iDefaultValue; -- (void) insertObject:(MCPJoin *) iJoin inJoinsAtIndex:(NSUInteger) index; -- (void) removeObjectFromJoinsAtIndex:(NSUInteger) index; -//- (void) addRelation:(MCPRelation *) iRelation; -//- (void) removeRelation:(MCPRelation *) iRelation; - -#pragma mark Getters -- (MCPClassDescription *) classDescription; -- (NSString *) name; -- (Class) valueClass; -- (NSString *) valueClassName; -- (NSString *) internalType; -- (NSString *) externalName; -- (NSString *) externalType; -- (NSUInteger) width; -- (BOOL) allowsNull; -- (BOOL) autoGenerated; -- (BOOL) isPartOfKey; -- (BOOL) isPartOfIdentity; -- (BOOL) hasAccessor; -- (id) defaultValue; -- (NSUInteger) countOfJoins; -- (MCPJoin *) objectInJoinsAtIndex:(NSUInteger) index; -- (NSUInteger) indexOfJoinIdenticalTo:(id) iJoin; - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPAttribute.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPAttribute.m deleted file mode 100644 index 085c1114..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPAttribute.m +++ /dev/null @@ -1,466 +0,0 @@ -// -// $Id$ -// -// MCPAttribute.m -// MCPkit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPAttribute.h" - -#import "MCPEntrepriseNotifications.h" - -#import "MCPModel.h" -#import "MCPClassDescription.h" -#import "MCPRelation.h" -#import "MCPJoin.h" - -static NSArray *MCPRecognisedInternalType; - -@interface MCPAttribute (Private) - -- (void)setValueClassName:(NSString *) iClassName; - -@end - -@implementation MCPAttribute - -#pragma mark Class methods -+ (void) initialize -{ - if (self == [MCPAttribute class]) { - [self setVersion:010101]; // Ma.Mi.Re -> MaMiRe - MCPRecognisedInternalType = [[NSArray alloc] initWithObjects:@"NSCalendarDate", @"NSData", @"NSNumber", @"NSString", nil]; - [self setKeys:[NSArray arrayWithObject:@"internalType"] triggerChangeNotificationsForDependentKey:@"valueClassName"]; - [self setKeys:[NSArray arrayWithObject:@"valueClassName"] triggerChangeNotificationsForDependentKey:@"internalType"]; - } - return; -} - - -#pragma mark Life cycle -- (id) initForClassDescription:(MCPClassDescription *) iClassDescription withName:(NSString *) iName -{ - self = [super init]; - { - classDescription = iClassDescription; - [self setName:iName]; -// relations = (NSMutableArray *)(CFArrayCreateMutable (kCFAllocatorDefault, 0, NULL)); - joins = [[NSMutableArray alloc] init]; - } - return self; -} - -- (void) dealloc -{ -// NSArray *theRelations; -// unsigned int i; - - [name release]; - [internalType release]; - [externalName release]; - [externalType release]; - [defaultValue release]; -/* - while ([relations count]) { - [(MCPRelation *)[relations objectAtIndex:0] unjoinAttribute:self]; - } -// By now relation should be empty anyway... - [relations release]; - */ - while ([joins count]) { - [[self objectInJoinsAtIndex:0] invalidate]; - } - // By now the joins array should be empty - [joins release]; - [super dealloc]; -} - - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder -{ - self = [super init]; - if ((self) && ([decoder allowsKeyedCoding])) { - NSString *theClassName = [decoder decodeObjectForKey:@"MCPvalueClassName"]; - - classDescription = [decoder decodeObjectForKey:@"MCPclassDescription"]; - [self setName:[decoder decodeObjectForKey:@"MCPname"]]; - if (theClassName) { - [self setValueClass:NSClassFromString(theClassName)]; - } - [self setInternalType:[decoder decodeObjectForKey:@"MCPinternalType"]]; - [self setExternalName:[decoder decodeObjectForKey:@"MCPexternalName"]]; - [self setExternalType:[decoder decodeObjectForKey:@"MCPexternalType"]]; - [self setWidth:(NSUInteger)[decoder decodeInt32ForKey:@"MCPwidth"]]; - [self setAllowsNull:[decoder decodeBoolForKey:@"MCPallowsNull"]]; - [self setAutoGenerated:[decoder decodeBoolForKey:@"MCPautoGenerated"]]; - [self setIsPartOfKey:[decoder decodeBoolForKey:@"MCPisPartOfKey"]]; - [self setIsPartOfIdentity:[decoder decodeBoolForKey:@"MCPisPartOfIdentity"]]; - [self setHasAccessor:[decoder decodeBoolForKey:@"MCPhasAccessor"]]; - [self setDefaultValue:[decoder decodeObjectForKey:@"MCPdefaultValue"]]; -// Not sure that the next line is working (getting an array holding weak references), hence doing the thing expelcitly: -// relations = [[decoder decodeObjectForKey:@"MCPrelations"] retain]; -// relations = (NSMutableArray *)(CFArrayCreateMutable (kCFAllocatorDefault, 0, NULL)); -// [relations addObjectsFromArray:[decoder decodeObjectForKey:@"MCPrelations"]]; - joins = [[NSMutableArray alloc] init]; // Will be filled in when the relations are read in. - } - else { - NSLog(@"For some reason, unable to decode MCPAttribute from the coder!!!"); - } -// NSLog(@"MAKING a new object : %@", self); - return self; -} - -- (void) encodeWithCoder:(NSCoder *) encoder -{ - NSString *theValueClassName; - - if (! [encoder allowsKeyedCoding]) { - NSLog(@"In MCPAttribute -encodeWithCoder : Unable to encode to a non-keyed encoder!!, will not perform encoding!!"); - return; - } -// theValueClassName = (valueClass) ? [valueClass className] : nil; - theValueClassName = (valueClass) ? NSStringFromClass(valueClass) : nil; - [encoder encodeObject:[self classDescription] forKey:@"MCPclassDescription"]; - [encoder encodeObject:[self name] forKey:@"MCPname"]; - if (theValueClassName) { - [encoder encodeObject:theValueClassName forKey:@"MCPvalueClassName"]; - } - [encoder encodeObject:[self internalType] forKey:@"MCPinternalType"]; - [encoder encodeObject:[self externalName] forKey:@"MCPexternalName"]; - [encoder encodeObject:[self externalType] forKey:@"MCPexternalType"]; - [encoder encodeInt32:(int32_t)[self width] forKey:@"MCPwidth"]; - [encoder encodeBool:[self allowsNull] forKey:@"MCPallowsNull"]; - [encoder encodeBool:[self autoGenerated] forKey:@"MCPautoGenerated"]; - [encoder encodeBool:[self isPartOfKey] forKey:@"MCPisPartOfKey"]; - [encoder encodeBool:[self isPartOfIdentity] forKey:@"MCPisPartOfIdentity"]; - [encoder encodeBool:[self hasAccessor] forKey:@"MCPhasAccessor"]; - [encoder encodeObject:[self defaultValue] forKey:@"MCPdefaultValue"]; -// [encoder encodeObject:relations forKey:@"MCPrelation"]; - // We don't have to save the joins here ... the joins are saving there attributes. - // The links are recreated when the joins are decoded. -} - -#pragma mark Setters -- (void) setName:(NSString *) iName -{ - if (iName != name) { - [name release]; - name = [iName retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setValueClass:(Class) iValueClass -{ - if (iValueClass != valueClass) { - valueClass = iValueClass; - if (valueClass) { // Not nil : set the internalType accrodingly. - // [internalType release]; - // internalType = [[valueClass className] copy]; -// [self setValue:[NSString stringWithString:[valueClass className]] forKey:@"internalType"]; - [self setValue:[NSString stringWithString:NSStringFromClass(valueClass)] forKey:@"internalType"]; - } - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setInternalType:(NSString *) iInternalType -{ - if (iInternalType != internalType) { - [internalType release]; - internalType = [iInternalType retain]; - if ([MCPRecognisedInternalType containsObject:internalType]) { - [self setValueClass:NSClassFromString(internalType)]; -// By itself does NOT provide observers the update. -// but see setKeys:triggerChangeNotificationsForDependentKey... (in +initialize). - } - else { - [self setValueClass:nil]; - } - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setExternalType:(NSString *) iExternalType -{ - if (iExternalType != externalType) { - [externalType release]; - externalType = [iExternalType retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setExternalName:(NSString *) iExternalName -{ - if (iExternalName != externalName) { - [externalName release]; - externalName = [iExternalName retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setWidth:(NSUInteger) iWidth -{ - if (iWidth != width) { - width = iWidth; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setAllowsNull:(BOOL) iAllowsNull -{ - if (iAllowsNull != allowsNull) { - allowsNull = iAllowsNull; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setAutoGenerated:(BOOL) iAutoGenerated -{ - if (iAutoGenerated != autoGenerated) { - autoGenerated = iAutoGenerated; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setIsPartOfKey:(BOOL) iIsPartOfKey -{ - if (iIsPartOfKey != isPartOfKey) { - isPartOfKey = iIsPartOfKey; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setIsPartOfIdentity:(BOOL) iIsPartOfIdentity -{ - if (iIsPartOfIdentity != isPartOfIdentity) { - isPartOfIdentity = iIsPartOfIdentity; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setHasAccessor:(BOOL) iHasAccessor -{ - if (iHasAccessor != hasAccessor) { - hasAccessor = iHasAccessor; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) setDefaultValue:(id) iDefaultValue -{ - if (iDefaultValue != defaultValue) { - [defaultValue release]; - defaultValue = [iDefaultValue retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[classDescription model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:classDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPAttributeChangedNotification object:self]; - } -} - -- (void) insertObject:(MCPJoin *) iJoin inJoinsAtIndex:(NSUInteger) index -{ - [joins insertObject:iJoin atIndex:index]; -} - -- (void) removeObjectFromJoinsAtIndex:(NSUInteger) index -{ - [joins removeObjectAtIndex:index]; -} - -/* -- (void) addRelation:(MCPRelation *) iRelation -{ -// Following implementation make sure that a given relation is only added once... but I don't see the reason for that to be true. - /* if (NSNotFound == [relations indexOfObjectIdenticalTo:iRelation]) { - [relations addObject:iRelation]; - } - *//* - [relations addObject:iRelation]; -} - -- (void) removeRelation:(MCPRelation *) iRelation -{ -// Following implementation needs only one reference to a given relation to be working properly (not true) -// [relations removeObjectIdenticalTo:iRelation]; - unsigned int i; - - i = [relations indexOfObjectIdenticalTo:iRelation]; - if (NSNotFound != i) { - [relations removeObjectAtIndex:i]; - } -// If the relation is there more than once, remove it only once. -} -*/ - -#pragma mark Getters -- (MCPClassDescription *) classDescription -{ - return classDescription; -} - -- (NSString *) name -{ - return name; -} - -- (Class) valueClass -{ - return valueClass; -} - -- (NSString *) valueClassName -{ - return NSStringFromClass(valueClass); -} - -- (NSString *) internalType -{ - return internalType; -} - -- (NSString *) externalName -{ - return externalName; -} - -- (NSString *) externalType -{ - return externalType; -} - -- (NSUInteger) width -{ - return width; -} - -- (BOOL) allowsNull -{ - return allowsNull; -} - -- (BOOL) autoGenerated -{ - return autoGenerated; -} - -- (BOOL) isPartOfKey -{ - return isPartOfKey; -} - -- (BOOL) isPartOfIdentity -{ - return isPartOfIdentity; -} - -- (BOOL) hasAccessor -{ - return hasAccessor; -} - -- (id) defaultValue -{ - return defaultValue; -} - -- (NSUInteger) countOfJoins -{ - return [joins count]; -} - -- (MCPJoin *) objectInJoinsAtIndex:(NSUInteger) index -{ - return (MCPJoin *)((NSNotFound != index) ? [joins objectAtIndex:index] : nil); -} - -- (NSUInteger) indexOfJoinIdenticalTo:(id) iJoin -{ - return [joins indexOfObjectIdenticalTo:iJoin]; -} - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject -// Equal to another attribute, if they have the same name and same class description. -// Equal to a string (NSString), if the name of the attribute is equal to the string. -{ - if ([iObject isKindOfClass:[MCPAttribute class]]) { - MCPAttribute *theAttribute = (MCPAttribute *) iObject; - - return ([name isEqualToString:[theAttribute name]]) && ([classDescription isEqual:[theAttribute classDescription]]); - } - if ([iObject isKindOfClass:[NSString class]]) { - return [name isEqualToString:(NSString *)iObject]; - } - return NO; -} - -#pragma mark For debugging the retain counting -- (id) retain -{ - [super retain]; - return self; -} - -- (void) release -{ - [super release]; - return; -} - -@end - -@implementation MCPAttribute (Private) - -- (void)setValueClassName:(NSString *) iClassName -{ - if (NSClassFromString(iClassName) != valueClass) { - [self setValueClass:NSClassFromString(iClassName)]; - } -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+MCPEntreprise.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+MCPEntreprise.h deleted file mode 100644 index 052eeadb..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+MCPEntreprise.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// $Id$ -// -// MCPClassDescription+MCPEntreprise.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 01/11/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> -#import "MCPClassDescription.h" - -@interface MCPClassDescription (MCPEntreprise) - -#pragma mark Pseudo getters (for NSClassDescription overload) -- (NSArray *) attributeKeys; -- (NSString *) inverseRelationshipKey:(NSString *) relationshipKey; -- (NSArray *) toManyRelationshipKeys; -- (NSArray *) toOneRelationshipKeys; - -#pragma mark Specifics for MCPObject -- (NSArray *) primaryKeyAttributes; -- (NSArray *) identityAttributes; -- (MCPAttribute *) attributeWithName: (NSString *) iName; -- (MCPRelation *) relationWithName:(NSString *) iRelationName; -- (BOOL) singleIntAutoGenKey; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+MCPEntreprise.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+MCPEntreprise.m deleted file mode 100644 index 71a25911..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+MCPEntreprise.m +++ /dev/null @@ -1,186 +0,0 @@ -// -// $Id$ -// -// MCPClassDescription+MCPEntreprise.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 01/11/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPClassDescription+MCPEntreprise.h" - -#import "MCPAttribute.h" -#import "MCPRelation.h" - -@implementation MCPClassDescription (MCPEntreprise) - -#pragma mark Pseudo getters (for NSClassDescription overload) -- (NSArray *) attributeKeys -{ - NSArray *theRet; - NSMutableArray *theKeys =[[NSMutableArray alloc] init]; - NSUInteger i; - - for (i=0; i != [self countOfAttributes]; ++i) { - [theKeys insertObject:[(MCPAttribute *)[self objectInAttributesAtIndex:i] name] atIndex:i]; - } - theRet = [NSArray arrayWithArray:theKeys]; - [theKeys release]; - return theRet; -} - -- (NSString *) inverseRelationshipKey:(NSString *) relationshipKey -{ - NSUInteger index = [self indexOfRelation:relationshipKey]; - - if (NSNotFound != index) { - MCPRelation *theRelation; - - theRelation = (MCPRelation *)[self objectInRelationsAtIndex:index]; - return [[theRelation inverseRelation] name]; - } - return nil; -} - -- (NSArray *) toManyRelationshipKeys -{ - NSArray *theRet; - NSMutableArray *theToManyRel = [[NSMutableArray alloc] init]; - NSUInteger i, j; - - j=0; - for (i=0; i != [self countOfRelations]; ++i) { - MCPRelation *theRelation = (MCPRelation *)[self objectInRelationsAtIndex:i]; - - if ([theRelation isToMany]) { - [theToManyRel insertObject:[theRelation name] atIndex:j]; - ++j; - } - } - theRet = [NSArray arrayWithArray:theToManyRel]; - [theToManyRel release]; - return theRet; -} - -- (NSArray *) toOneRelationshipKeys; -{ - NSArray *theRet; - NSMutableArray *theToOneRel = [[NSMutableArray alloc] init]; - NSUInteger i, j; - - j=0; - for (i=0; i != [self countOfRelations]; ++i) { - MCPRelation *theRelation = (MCPRelation *)[self objectInRelationsAtIndex:i]; - - if (! [theRelation isToMany]) { - [theToOneRel insertObject:[theRelation name] atIndex:j]; - ++j; - } - } - theRet = [NSArray arrayWithArray:theToOneRel]; - [theToOneRel release]; - return theRet; -} - -#pragma mark Specifics for MCPObject -- (NSArray *) primaryKeyAttributes -{ - NSMutableArray *theRet = [NSMutableArray array]; - NSUInteger i, j; - - j = 0; - for (i=0; i != [self countOfAttributes]; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *)[self objectInAttributesAtIndex:i]; - - if ([theAttribute isPartOfKey]) { - [theRet insertObject:theAttribute atIndex:j]; - ++j; - } - } - return (NSArray *)theRet; -} - -- (NSArray *) identityAttributes -{ - NSMutableArray *theRet = [NSMutableArray array]; - NSUInteger i, j; - - j = 0; - for (i=0; i != [self countOfAttributes]; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *)[self objectInAttributesAtIndex:i]; - - if ([theAttribute isPartOfIdentity]) { - [theRet insertObject:theAttribute atIndex:j]; - ++j; - } - } - return (NSArray *)theRet; -} - -- (MCPAttribute *) attributeWithName: (NSString *) iName -{ -// This type of implementation is NOT working : most likely the isEqual method is called on iName rather than on the objects of the array -/* - unsigned int index = [self indexOfAttribute:iName]; - - return (NSNotFound != index) ? (MCPAttribute *)[self objectInAttributesAtIndex:index] : nil ; -*/ - NSUInteger i; - - for (i = 0; [attributes count] != i; ++i) { - if ([[(MCPAttribute *)[attributes objectAtIndex:i] name] isEqualToString:iName]) { - return (MCPAttribute *)[attributes objectAtIndex:i]; - } - } - return nil; -} - -- (MCPRelation *) relationWithName:(NSString *) iRelationName -{ -// This type of implementation is NOT working : most likely the isEqual method is called on iName rather than on the objects of the array -/* unsigned int index = [relations indexOfObject:iRelationName]; - - return (NSNotFound != index) ? (MCPRelation *)[relations objectAtIndex:index] : nil; -*/ - NSUInteger i; - - for (i = 0; [relations count] != i; ++i) { - if ([[(MCPRelation *)[relations objectAtIndex:i] name] isEqualToString:iRelationName]) { - return (MCPRelation *)[relations objectAtIndex:i]; - } - } - return nil; -} - -- (BOOL) singleIntAutoGenKey -{ - NSArray *theKeys = [self primaryKeyAttributes]; - - if (1 == [theKeys count]) { - MCPAttribute *theSingleKey = (MCPAttribute *)[theKeys objectAtIndex:0]; - - return [theSingleKey autoGenerated] && [[theSingleKey externalType] isEqualToString:@"INT"]; - } - return NO; -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+Private.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+Private.h deleted file mode 100644 index df86b763..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription+Private.h +++ /dev/null @@ -1,45 +0,0 @@ -// -// $Id$ -// -// MCPClassDescription+Private.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPClassDescription.h" - -@interface MCPClassDescription (Private) - -#pragma mark Setters -- (void) setAttributes:(NSArray *) iAttributes; -- (void) setRelations:(NSArray *) iRelations; -- (void) insertObject:(MCPRelation *) iRelation inIncomingsAtIndex:(NSUInteger) index; -- (void) removeObjectFromIncomingsAtIndex:(NSUInteger) index; - -#pragma mark Getters -- (NSArray *) incomings; -- (NSUInteger) countOfIncomings; -- (MCPRelation *) objectInIncomingsAtIndex:(NSUInteger) index; -- (NSUInteger) indexOfIncoming:(id) iRelation; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription.h deleted file mode 100644 index cff3cf17..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// $Id$ -// -// MCPClassDescription.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -@class MCPModel; -@class MCPAttribute; -@class MCPRelation; -@class MCPRelation; - -@interface MCPClassDescription : NSClassDescription <NSCoding> -{ -@protected - MCPModel *model; // The model where we stand - NSString *name; // Name of the class (can not use className, as it is already used by NSObject). - NSString *externalName; // Name of the table for storage - NSMutableArray *attributes; // array of the attributes of the class description - NSMutableArray *relations; // array of the relations of the class description (both origin and destination) - NSMutableArray *incomings; // array if the INCOMMING relation (just to be sure we are able to invalidate those if necessary) - Class representedClass; // the class object that the description represents. -} - -// This correspond to the method singleIntAutoGenKey in the category MCPEntreprise... which name should I change... - -#pragma mark Class methods -+ (void) initialize; - -#pragma mark Life cycle -- (id) initInModel:(MCPModel *) iModel withName:(NSString *) iName; -- (void) dealloc; - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder; -- (void) encodeWithCoder:(NSCoder *) encoder; - -#pragma mark Making new attributes and relations -- (MCPAttribute *) addNewAttributeWithName:(NSString *) iName inPosition:(NSInteger) index; -- (MCPRelation *) addNewRelationTo:(MCPClassDescription *) iTo name:(NSString *) iName inPostion:(NSInteger) index; - -#pragma mark Setters -- (void) setName:(NSString *) iName; -- (void) setExternalName:(NSString *) iExternalName; -- (void) insertObject:(MCPAttribute *) iAttribute inAttributesAtIndex:(NSUInteger) index; -- (void) removeObjectFromAttributesAtIndex:(NSUInteger) index; -- (void) insertObject:(MCPRelation *) iRelation inRelationsAtIndex:(NSUInteger) index; -- (void) removeObjectFromRelationsAtIndex:(NSUInteger) index; - -#pragma mark Getters -- (MCPModel *) model; -- (NSString *) name; -- (NSString *) externalName; -- (NSArray *) attributes; -- (NSUInteger) countOfAttributes; -- (MCPAttribute *) objectInAttributesAtIndex:(NSUInteger) index; -- (NSUInteger) indexOfAttribute:(id) iAttribute; -- (NSArray *) relations; -- (NSUInteger) countOfRelations; -- (MCPRelation *) objectInRelationsAtIndex:(NSUInteger) index; -- (NSUInteger) indexOfRelation:(id) iRelation; -- (Class) representedClass; - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject; - -#pragma mark Output for logging -- (NSString *) descriptionWithLocale:(NSDictionary *) locale; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription.m deleted file mode 100644 index 9f2ad18d..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPClassDescription.m +++ /dev/null @@ -1,373 +0,0 @@ -// -// $Id$ -// -// MCPClassDescription.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPClassDescription.h" -#import "MCPClassDescription+Private.h" - -#import "MCPEntrepriseNotifications.h" - -#import "MCPModel.h" -#import "MCPAttribute.h" -#import "MCPRelation.h" - -@implementation MCPClassDescription - -#pragma mark Class methods -+ (void) initialize -{ - if (self = [MCPClassDescription class]) { - [self setVersion:010101]; // Major.Minor.Revision -> MaMiRe - } - return; -} - -#pragma mark Life cycle -- (id) initInModel:(MCPModel *) iModel withName:(NSString *) iName -{ - self = [super init]; - if (self) { - model = iModel; - [self setName:iName]; - attributes = [[NSMutableArray alloc] init]; - relations = [[NSMutableArray alloc] init]; - incomings = [[NSMutableArray alloc] init]; - representedClass = nil; - // NSLog(@"MAKING a new object : %@", self); - } - return self; -} - -- (void) dealloc -{ -// NSArray *theRelations; -// unsigned int i; - - [name release]; - [externalName release]; - [attributes release]; - while ([relations count]) { - [(MCPRelation *)[relations objectAtIndex:0] invalidateRelation]; - } - [relations release]; - while ([incomings count]) { - [(MCPRelation *)[incomings objectAtIndex:0] invalidateRelation]; - } - [incomings release]; - [super dealloc]; -} - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder -{ - self = [super init]; - if ((self) && ([decoder allowsKeyedCoding])) { - model = [decoder decodeObjectForKey:@"MCPmodel"]; -// NSLog(@"in MCPClassDescription initWithCoder, model = %@ (pointer = %p)", model, model); - [self setName:[decoder decodeObjectForKey:@"MCPname"]]; - [self setExternalName:[decoder decodeObjectForKey:@"MCPexternalName"]]; - [self setAttributes:[decoder decodeObjectForKey:@"MCPattributes"]]; -// [self setRelations:[decoder decodeObjectForKey:@"MCPrelations"]]; - relations = [[NSMutableArray alloc] init]; - incomings = [[NSMutableArray alloc] init]; - representedClass = nil; - [decoder decodeObjectForKey:@"MCPrelations"]; // The relation get linked properly while initted. - } - else { - NSLog(@"For some reason, unable to decode MCPClassDescription from the coder!!!"); - } - - return self; -} - -- (void) encodeWithCoder:(NSCoder *) encoder -{ - if (! [encoder allowsKeyedCoding]) { - NSLog(@"In MCPClassDescription -encodeWithCoder : Unable to encode to a non-keyed encoder!!, will not perform encoding!!"); - return; - } -// [encoder encodeObject:[self model] forKey:@"MCPmodel"]; - [encoder encodeConditionalObject:[self model] forKey:@"MCPmodel"]; - [encoder encodeObject:[self name] forKey:@"MCPname"]; - [encoder encodeObject:[self externalName] forKey:@"MCPexternalName"]; - [encoder encodeObject:[self attributes] forKey:@"MCPattributes"]; - [encoder encodeObject:[self relations] forKey:@"MCPrelations"]; - [encoder encodeObject:@"1.1.1" forKey:@"MCPversion"]; - return; -} - -#pragma mark Making new attributes and relations -- (MCPAttribute *) addNewAttributeWithName:(NSString *) iName inPosition:(NSInteger) index -{ - MCPAttribute *theAttribute = [[MCPAttribute alloc] initForClassDescription:self withName:iName]; - -// [self addAttribute:theAttribute]; - [self insertObject:theAttribute inAttributesAtIndex:(index < 0) ? ([self countOfAttributes] + index + 1) : index]; - [theAttribute release]; - return theAttribute; -} - -- (MCPRelation *) addNewRelationTo:(MCPClassDescription *) iTo name:(NSString *) iName inPostion:(NSInteger) index -{ - MCPRelation *theRelation = [[MCPRelation alloc] initWithName:iName from:self to:iTo]; - - [theRelation release]; - return theRelation; -} - -#pragma mark Setters -- (void) setName:(NSString *) iName -{ - if (iName != name) { - [name release]; - name = [iName retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; - representedClass = nil; - } -} - -- (void) setExternalName:(NSString *) iExternalName -{ - if (iExternalName != externalName) { - [externalName release]; - externalName = [iExternalName retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; - } -} - -- (void) insertObject:(MCPAttribute *) iAttribute inAttributesAtIndex:(NSUInteger) index -{ - [attributes insertObject:iAttribute atIndex:index]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; -} - -- (void) removeObjectFromAttributesAtIndex:(NSUInteger) index -{ - [attributes removeObjectAtIndex:index]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; -} - -- (void) insertObject:(MCPRelation *) iRelation inRelationsAtIndex:(NSUInteger) index -{ - [relations insertObject:iRelation atIndex:index]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; -} - -- (void) removeObjectFromRelationsAtIndex:(NSUInteger) index -{ - [relations removeObjectAtIndex:index]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; -} - -#pragma mark Getters -- (MCPModel *) model -{ - return model; -} - -- (NSString *) name -{ - return name; -} - -- (NSString *) externalName -{ - return externalName; -} - -- (NSArray *) attributes -{ - return [NSArray arrayWithArray:attributes]; -} - -- (NSUInteger) countOfAttributes -{ - return [attributes count]; -} - -- (MCPAttribute *) objectInAttributesAtIndex:(NSUInteger) index -{ - return (MCPAttribute *)((NSNotFound != index) ? [attributes objectAtIndex:index] : nil); -} - -- (NSUInteger) indexOfAttribute:(id) iAttribute -{ - return [attributes indexOfObject:iAttribute]; -} - -- (NSArray *) relations -{ - return [NSArray arrayWithArray:relations]; -} - -- (NSUInteger) countOfRelations -{ - return [relations count]; -} - -- (MCPRelation *) objectInRelationsAtIndex:(NSUInteger) index -{ - return (MCPRelation *)((NSNotFound != index) ? [relations objectAtIndex:index] : nil); -} - -- (NSUInteger) indexOfRelation:(id) iRelation -{ - return [relations indexOfObject:iRelation]; -} - -- (Class) representedClass -{ - if (representedClass) { - return representedClass; - } - representedClass = NSClassFromString(name); - return representedClass; -} - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject -// Equal to another class description if they have the same name. -// Equal to a string if the string is equal to the className of the class description. -{ - if ([iObject isKindOfClass:[MCPClassDescription class]]) { - return [name isEqualToString:[(MCPClassDescription *)iObject name]]; - } - if ([iObject isKindOfClass:[NSString class]]) { - return [name isEqualToString:(NSString *)iObject]; - } - return NO; -} - -/* -- (NSString *) description -{ - return [NSString stringWithFormat:@"<MCPClassDescription for class named %@ : %p>", [self name], self]; -} - -- (NSString *) descriptionWithLocale:(NSDictionary *) locale -{ - return [self description]; -} -*/ - -#pragma mark Output for logging - -- (NSString *)descriptionWithLocale:(NSDictionary *) locale -{ - NSUInteger i; - NSMutableString *theOutput = [NSMutableString string]; - - [theOutput appendFormat:@"MCPClassDescription for class : %@ (table : %@)\n", [self name], [self externalName]]; - for (i=0; [attributes count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *) [attributes objectAtIndex:i]; - - [theOutput appendFormat:@"attribute %u, name = %@, column = %@. Allows null : %c\n", i, [theAttribute name], [theAttribute externalName], ([theAttribute allowsNull] ? 'Y' : 'N')]; - } - return theOutput; -} - -#pragma mark For debugging the retain counting -- (id) retain -{ - [super retain]; - return self; -} - -- (void) release -{ - [super release]; - return; -} - -@end - -@implementation MCPClassDescription (Private) - -#pragma mark Setters -- (void) setAttributes:(NSArray *) iAttributes -{ - if (iAttributes != attributes) { - [attributes release]; - attributes = [[NSMutableArray alloc] initWithArray:iAttributes]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; - } -} - -- (void) setRelations:(NSArray *) iRelations -{ - if (iRelations != relations) { - [relations release]; - relations = [[NSMutableArray alloc] initWithArray:iRelations]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:model]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:self]; - } -} - -- (void) insertObject:(MCPRelation *) iRelation inIncomingsAtIndex:(NSUInteger) index -{ - if ([iRelation destination] == self) { - [incomings insertObject:iRelation atIndex:index]; - } - else { - NSLog(@"in -[MCPClassDescription+Private insertObject:inIncomingsAtIndex:]. ERRROR : self is NOT the destination of the relation"); - } -} - -- (void) removeObjectFromIncomingsAtIndex:(NSUInteger) index -{ - [incomings removeObjectAtIndex:index]; -} - -#pragma mark Getters -- (NSArray *) incomings -{ - return [NSArray arrayWithArray:incomings]; -} - -- (NSUInteger) countOfIncomings -{ - return [incomings count]; -} - -- (MCPRelation *) objectInIncomingsAtIndex:(NSUInteger) index -{ - return (MCPRelation *)[incomings objectAtIndex:index]; -} - -- (NSUInteger) indexOfIncoming:(id) iRelation -{ - return [incomings indexOfObject:iRelation]; -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPEntrepriseNotifications.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPEntrepriseNotifications.h deleted file mode 100644 index 1bb903c4..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPEntrepriseNotifications.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// $Id$ -// -// MCPEnterpriseNotifications.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -#pragma mark Name for notification - -extern NSString *MCPModelChangedNotification; -extern NSString *MCPClassDescriptionChangedNotification; -extern NSString *MCPAttributeChangedNotification; -extern NSString *MCPRelationChangedNotification; diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPEntrepriseNotifications.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPEntrepriseNotifications.m deleted file mode 100644 index ec4f3793..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPEntrepriseNotifications.m +++ /dev/null @@ -1,34 +0,0 @@ -// -// $Id$ -// -// MCPEnterpriseNotifications.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -NSString *MCPModelChangedNotification = @"Model has changed"; -NSString *MCPClassDescriptionChangedNotification = @"ClassDescription has changed"; -NSString *MCPAttributeChangedNotification = @"Attribute has changed"; -NSString *MCPRelationChangedNotification = @"Relation has changed"; diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPJoin.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPJoin.h deleted file mode 100644 index 05e99f8d..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPJoin.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// $Id$ -// -// MCPJoin.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 18/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -@class MCPModel; -@class MCPClassDescription; -@class MCPAttribute; -@class MCPRelation; -@class MCPRelation; - -@interface MCPJoin : NSObject <NSCoding> -{ -@protected - // Note that NONE of these attributes are retained!!! - // Instead all these objects are notified of the existence of the join - // and are responsible to invalidate/delete it if necessary. - MCPRelation *relation; - MCPAttribute *origin; - MCPAttribute *destination; -} - -#pragma mark Class methods -+ (void) initialize; - -#pragma mark Life cycle -- (id) initForRelation:(MCPRelation *) iRelation from:(MCPAttribute *) iOrigin to:(MCPAttribute *) iDestination; -- (void) invalidate; -- (void) dealloc; - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder; -- (void) encodeWithCoder:(NSCoder *) encoder; - -#pragma mark Setters -// No setter for relation : should be set at init time! -- (void) setOrigin:(MCPAttribute *) iOrigin; -- (void) setDestination:(MCPAttribute *) iDestination; - -#pragma mark Getters -- (MCPRelation *) relation; -- (MCPAttribute *) origin; -- (MCPAttribute *) destination; -- (NSUInteger) index; - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPJoin.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPJoin.m deleted file mode 100644 index 576b1e10..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPJoin.m +++ /dev/null @@ -1,183 +0,0 @@ -// -// $Id$ -// -// MCPJoin.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 18/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPJoin.h" - -#import "MCPModel.h" -#import "MCPClassDescription.h" -#import "MCPAttribute.h" -#import "MCPRelation.h" -#import "MCPRelation.h" - -@implementation MCPJoin - -#pragma mark Class methods -+ (void) initialize -{ - if (self = [MCPJoin class]) { - [self setVersion:010101]; // Ma.Mi.Re -> MaMiRe - } - return; -} - -#pragma mark Life cycle -- (id) initForRelation:(MCPRelation *) iRelation from:(MCPAttribute *) iOrigin to:(MCPAttribute *) iDestination; -{ - self = [super init]; - if (self) { - relation = iRelation; - [self setOrigin:iOrigin]; - [self setDestination:iDestination]; - } - return self; -} - -- (void) invalidate -{ - [self retain]; - NSLog(@"Enterring -[MCPJoin invalidate], retain count is %ld (after retaining : should be 4)", [self retainCount]); - [origin removeObjectFromJoinsAtIndex:[origin indexOfJoinIdenticalTo:self]]; - [destination removeObjectFromJoinsAtIndex:[destination indexOfJoinIdenticalTo:self]]; - [relation removeObjectFromJoinsAtIndex:[relation indexOfJoinIdenticalTo:self]]; - NSLog(@"Enterring -[MCPJoin invalidate], retain count is %ld (before releasing : should be 1)", [self retainCount]); - [self release]; - return; -} - -- (void) dealloc -{ - // Nothing to release, because the attributes are NOT retained. - [super dealloc]; -} - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder -{ - self = [super init]; - if ((self) && ([decoder allowsKeyedCoding])) { - relation = [decoder decodeObjectForKey:@"MCPrelation"]; - [self setOrigin:[decoder decodeObjectForKey:@"MCPorigin"]]; - [self setDestination:[decoder decodeObjectForKey:@"MCPdestination"]]; - } - else { - NSLog(@"For some reason, unable to decode MCPJoin from the coder!!!"); - } - return self; -} - -- (void) encodeWithCoder:(NSCoder *) encoder -{ - if (! [encoder allowsKeyedCoding]) { - NSLog(@"In MCPJoin -encodeWithCoder : Unable to encode to a non-keyed encoder!!, will not perform encoding!!"); - return; - } - [encoder encodeObject:[self relation] forKey:@"MCPrelation"]; - [encoder encodeObject:[self origin] forKey:@"MCPorigin"]; - [encoder encodeObject:[self destination] forKey:@"MCPdestination"]; -} - -#pragma mark Setters -- (void) setOrigin:(MCPAttribute *) iOrigin -{ - if (origin != iOrigin) { - if (origin) { - [origin removeObjectFromJoinsAtIndex:[origin indexOfJoinIdenticalTo:self]]; - } - origin = iOrigin; - if (origin) { - [origin insertObject:self inJoinsAtIndex:[origin countOfJoins]]; - } - } -} - -- (void) setDestination:(MCPAttribute *) iDestination -{ - if (destination != iDestination) { - if (destination) { - [destination removeObjectFromJoinsAtIndex:[destination indexOfJoinIdenticalTo:self]]; - } - destination = iDestination; - if (destination) { - [destination insertObject:self inJoinsAtIndex:[destination countOfJoins]]; - } - } -} - -#pragma mark Getters -- (MCPRelation *) relation -{ - return relation; -} - -- (MCPAttribute *) origin -{ - return origin; -} - -- (MCPAttribute *) destination -{ - return destination; -} - -- (NSUInteger) index -{ - return [relation indexOfJoinIdenticalTo:self]; -} - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject -{ - if ([iObject isKindOfClass:[MCPJoin class]]) { - MCPJoin *theJoin = (MCPJoin *)iObject; - - return ([relation isEqual:[theJoin relation]]) && ([origin isEqual:[theJoin origin]]) && ([destination isEqual:[theJoin destination]]); - } - if ([iObject isKindOfClass:[NSDictionary class]]) { - NSDictionary *theDict = (NSDictionary *)iObject; - - return ([relation isEqual:[theDict valueForKey:@"relation"]]) && ([origin isEqual:[theDict valueForKey:@"origin"]]) && ([destination isEqual:[theDict valueForKey:@"destination"]]); - } - return NO; -} - -#pragma mark For debugging the retain counting -- (id) retain -{ - [super retain]; - - return self; -} - -- (void) release -{ - [super release]; - - return; -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel+MCPEntreprise.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel+MCPEntreprise.h deleted file mode 100644 index 15aa9ed3..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel+MCPEntreprise.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// $Id$ -// -// MCPModel+MCPEntreprise.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 01/11/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPModel.h" - -@interface MCPModel (MCPEntreprise) - -- (void) registerAsClassDescriptionServer; -- (void) registerDescriptionForClass:(NSNotification *) notification; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel+MCPEntreprise.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel+MCPEntreprise.m deleted file mode 100644 index 2652f0dc..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel+MCPEntreprise.m +++ /dev/null @@ -1,57 +0,0 @@ -// -// $Id$ -// -// MCPModel+MCPEntreprise.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 01/11/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPModel+MCPEntreprise.h" - -#import "MCPObject.h" - -@implementation MCPModel (MCPEntreprise) - -#pragma mark Work as a class description server - -- (void) registerAsClassDescriptionServer -{ - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registerDescriptionForClass:) name:NSClassDescriptionNeededForClassNotification object:nil]; -} - -- (void) registerDescriptionForClass:(NSNotification *) notification -{ - Class theClass = [notification object]; - - if ([theClass isSubclassOfClass:[MCPObject class]]) { - - NSString *theClassName = NSStringFromClass(theClass); - NSUInteger index = [self indexOfClassDescription:theClassName]; - - if (NSNotFound != index) { - [NSClassDescription registerClassDescription:(NSClassDescription *)[self objectInClassDescriptionsAtIndex:index] forClass:theClass]; - } - } -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel.h deleted file mode 100644 index 0a6c6afd..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel.h +++ /dev/null @@ -1,84 +0,0 @@ -// -// $Id$ -// -// MCPModel.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -@class MCPClassDescription; -@class MCPAttribute; -@class MCPRelation; - -@interface MCPModel : NSObject <NSCoding> -{ -@protected - NSString *name; // Name of the model ... useless. - NSMutableArray *classDescriptions; // Order of the class descriptions in the model. - BOOL usesInnoDBTables; // The database should use InnoDB tables. - // Might add a string holding définition of tables. - // Might also add some sort of template for generated files (at least the header). -} - -#pragma mark Class methods -+ (void) initialize; - -#pragma mark Life cycle -- (id) initWithName:(NSString *) iName; -- (void) dealloc; - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder; -- (void) encodeWithCoder:(NSCoder *) encoder; - -#pragma mark Making new class description -- (MCPClassDescription *) addNewClassDescriptionWithName:(NSString *) iName inPosition:(NSInteger) index; - -#pragma mark Setters -- (void) setName:(NSString *) iName; -- (void) setClassDescriptions:(NSArray *) iClassDescriptions; -- (void) insertObject:(MCPClassDescription *) iClassDescription inClassDescriptionsAtIndex:(NSUInteger) index; -- (void) removeObjectFromClassDescriptionsAtIndex:(NSUInteger) index; -- (void) setUsesInnoDBTables:(BOOL) iUsesInnoDB; - -// Deprecated : non KVC -//- (void) removeClassDescription:(MCPClassDescription *) iClassDescription; -//- (void) addClassDescription:(MCPClassDescription *) iClassDescription; - -#pragma mark Getters -- (NSString *) name; -- (NSArray *) classDescriptions; -- (NSUInteger) countOfClassDescriptions; -- (MCPClassDescription *) objectInClassDescriptionsAtIndex:(NSUInteger) index; -- (NSUInteger) indexOfClassDescription:(id) iClassDescription; -- (BOOL) usesInnoDBTables; - -// Deprecated : non KVC -//- (MCPClassDescription *) classDescriptionWithClassName:(NSString *) iClassDescriptionClassName; - -#pragma mark Output for logging -- (NSString *) descriptionWithLocale:(NSDictionary *) locale; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel.m deleted file mode 100644 index 7c73eff1..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPModel.m +++ /dev/null @@ -1,230 +0,0 @@ -// -// $Id$ -// -// MCPModel.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 09/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPModel.h" - -#import "MCPEntrepriseNotifications.h" - -#import "MCPClassDescription.h" -#import "MCPAttribute.h" -#import "MCPRelation.h" - -@implementation MCPModel - -#pragma mark Class methods -+ (void) initialize -{ - if (self = [MCPModel class]) { - [self setVersion:010101]; // Ma.Mi.Re -> MaMiRe - } - return; -} - -#pragma mark Life cycle -- (id) initWithName:(NSString *) iName -{ - self = [super init]; - if (self) { - [self setName:iName]; - classDescriptions = [[NSMutableArray alloc] init]; - } - - return self; -} - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - [name release]; - [classDescriptions release]; - [super dealloc]; -} - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder -{ - self = [super init]; - if ((self) && ([decoder allowsKeyedCoding])) { - [self setName:[decoder decodeObjectForKey:@"MCPname"]]; - [self setClassDescriptions:[decoder decodeObjectForKey:@"MCPclassDescriptions"]]; - [self setUsesInnoDBTables:[decoder decodeBoolForKey:@"MCPusesInnoDBTables"]]; - } - else { - NSLog(@"For some reason, unable to decode MCPModel from the coder!!!"); - } - - return self; -} - -- (void) encodeWithCoder:(NSCoder *) encoder -{ - if (! [encoder allowsKeyedCoding]) { - NSLog(@"In MCPModel -encodeWithCoder : Unable to encode to a non-keyed encoder!!, will not perform encoding!!"); - return; - } -// [super encodeWithCoder:encoder]; - [encoder encodeObject:[self name] forKey:@"MCPname"]; - [encoder encodeObject:[self classDescriptions] forKey:@"MCPclassDescriptions"]; - [encoder encodeBool:[self usesInnoDBTables] forKey:@"MCPusesInnoDBTables"]; - [encoder encodeObject:@"1.1.1" forKey:@"MCPversion"]; - return; -} - -#pragma mark Making new class description -- (MCPClassDescription *) addNewClassDescriptionWithName:(NSString *) iName inPosition:(NSInteger) index; -{ - MCPClassDescription *theClassDescription = [[MCPClassDescription alloc] initInModel:self withName:iName]; - -// [self addClassDescription:theClassDescription]; - [self insertObject:theClassDescription inClassDescriptionsAtIndex:(index < 0) ? ([self countOfClassDescriptions] + index + 1) : index]; - [theClassDescription release]; - return theClassDescription; -} - -#pragma mark Setters -- (void) setName:(NSString *) iName -{ - if (iName != name) { - [name release]; - name = [iName retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; - } -} - -- (void) setClassDescriptions:(NSArray *) iClassDescriptions -{ - if (iClassDescriptions != classDescriptions) { - [classDescriptions release]; - classDescriptions = [[NSMutableArray alloc] initWithArray:iClassDescriptions]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; - } -} - -- (void) insertObject:(MCPClassDescription *) iClassDescription inClassDescriptionsAtIndex:(NSUInteger) index -{ - [classDescriptions insertObject:iClassDescription atIndex:index]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; -} - -- (void) removeObjectFromClassDescriptionsAtIndex:(NSUInteger) index -{ - [classDescriptions removeObjectAtIndex:index]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; -} - -- (void) setUsesInnoDBTables:(BOOL) iUsesInnoDB -{ - usesInnoDBTables = iUsesInnoDB; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; -} - -// Deprecated : non KVC -/* -- (void) removeClassDescription:(MCPClassDescription *) iClassDescription -{ - [classDescriptions removeObject:iClassDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; -} - - - (void) addClassDescription:(MCPClassDescription *) iClassDescription - { - [classDescriptions addObject:iClassDescription]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:self]; - } - - */ - -#pragma mark Getters -- (NSString *) name -{ - return name; -// return [NSString stringWithString:name]; -} - -- (NSArray *) classDescriptions -{ - return [NSArray arrayWithArray:classDescriptions]; -} - -- (NSUInteger) countOfClassDescriptions -{ - return [classDescriptions count]; -} - -- (MCPClassDescription *) objectInClassDescriptionsAtIndex:(NSUInteger) index -{ - return (MCPClassDescription *)((NSNotFound != index) ? [classDescriptions objectAtIndex:index] : nil); -} - -- (MCPClassDescription *) classDescriptionWithClassName:(NSString *) iClassDescriptionClassName -{ -// Given the implementation of isEqual: for the MCPClassDescription, one should be able to use NSArray method directly: - /* unsigned int i; - - for (i=0; ([classDescriptions count] != i) && (! [iClassDescriptionClassName isEqualToString:[(MCPClassDescription *) [classDescriptions objectAtIndex:i] className]]); ++i ) { - } - return (i == [classDescriptions count]) ? nil : (MCPClassDescription *)[classDescriptions objectAtIndex:i]; - */ - NSUInteger theIndex = [classDescriptions indexOfObject:iClassDescriptionClassName]; - return (NSNotFound == theIndex) ? nil : [classDescriptions objectAtIndex:theIndex]; -} - -- (NSUInteger) indexOfClassDescription:(id) iClassDescription -{ - return [classDescriptions indexOfObject:iClassDescription]; -} - -- (BOOL) usesInnoDBTables -{ - return usesInnoDBTables; -} - -// Deprecated : non KVC - -#pragma mark Output for logging -- (NSString *) descriptionWithLocale:(NSDictionary *) locale -{ - return [NSString stringWithFormat:@"<MCPModel with name %@ : %p>", [self name], self]; -} - -#pragma mark For debugging the retain counting -- (id) retain -{ - [super retain]; - - return self; -} - -- (void) release -{ - [super release]; - - return; -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPObject.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPObject.h deleted file mode 100644 index 4f126928..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPObject.h +++ /dev/null @@ -1,127 +0,0 @@ -// -// $Id$ -// -// MCPObject.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 19/05/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -/*" Possible return code on some operations of the database interaction. "*/ -enum { - MCPDBReturnUnknown = 0, /*"Unknown state, should not happen."*/ - MCPDBReturnDeleted = 1, /*"The entry have been successfuly deleted from DB."*/ - MCPDBReturnUsed = 2, /*"The entry can not be removed, because some entries are still connected to it (some delete restrict/inhibit delete)."*/ - MCPDBReturnNone = 3, /*"No entry exist with this Id."*/ - MCPDBReturnNew = 4, /*"The entry was indeed new and inserted in the database."*/ - MCPDBReturnUpdated = 5, /*"The entry was updated in the DB."*/ - MCPDBReturnIncompleteKey = 6, /*"Part of the primary key is missing, action not taken."*/ - MCPDBReturnMultiple = 7, /*"Multiple rows are found with a query supposed to return at most one row."*/ - MCPDBReturnNoIdentity = 8, /*"The object does not have attributes that defines identity."*/ - MCPDBReturnNoKey = 9, /*"There is no primary key defined for this entity."*/ - MCPDBReturnNoConnection = 10, /*"The MCPObject is not having a connection."*/ - MCPDBReturnWrongRelationOrigin = 11, /*"Looking for a relation not which origin is not of the specified class."*/ - MCPDBReturnWrongRelationCardinality = 12, /*"Using a method assuming a cardinality of the relation while the relation as the other one."*/ - MCPDBReturnNoSuchRelation = 13, /*"There is no relation with such a name starting from this class."*/ - MCPDBReturnNotTarget = 14, /*"Tried to remove an object from a relation, while the objects does NOT belong to the relation."*/ - MCPDBReturnOK = 100 /*"Everything went OK."*/ -}; -typedef NSUInteger MCPDBReturnCode; - -@class MCPConnection; -@class MCPClassDescription; -@class MCPRelation; - -@interface MCPObject : NSObject { - MCPClassDescription *classDescription; - MCPConnection *connection; -} - -#pragma mark Life of the Object -/*" Life of the object "*/ -- (id) init; -- (id) initWithDictionary:(NSDictionary *) dictionary; - -- (void) dealloc; - -- (void) setAttributesToDefault; - -#pragma mark Accessors -/*" Accessor(s) "*/ -- (MCPClassDescription *) classDescription; -- (MCPConnection *) connection; - -- (void) setConnection:(MCPConnection *) iConnection; - -#pragma mark Database interface -/*" Database interface "*/ -- (id) readFromDBRow:(NSDictionary *) iDictionary withTableName:(NSString *) iTableName; -- (MCPDBReturnCode) setPrimaryKey:(id) iDictionary andFetchFromDB:(MCPConnection *) iConnection; -//- (MCPDBReturnCode) setPrimaryKey:(NSDictionary *) iDictionary andFetchFromDB:(MCPConnection *) iConnection; -- (NSDictionary *) checkDBId; // the returned dictionary contains a MCPDBReturnCode key with the return code. -- (NSDictionary *) saveInDB; // the returned dictionary contains a MCPDBReturnCode key with the return code. -- (MCPDBReturnCode) getAutoGenerated; -- (MCPDBReturnCode) updateInDB; -- (MCPDBReturnCode) deleteInDB; -+ (MCPDBReturnCode) deleteInDBUsingConnection:(MCPConnection *) iConnection withId:(id) iId; - -#pragma mark Handling relations -/*" Handling realtions "*/ -- (id) getTargetOfRelation:(MCPRelation *) iRelation; -- (id) getTargetOfRelationNamed:(NSString *) iRelationName; -- (MCPDBReturnCode) setTarget:(id) iTarget forRelation:(MCPRelation *) iRelation; -- (MCPDBReturnCode) setTarget:(id) iTarget forRelationNamed:(NSString *) iRelationName; -- (NSUInteger) countTargetForRelation:(MCPRelation *) iRelation; -- (NSUInteger) countTargetForRelationNamed:(NSString *) iRelationName; -- (MCPObject *) getTargetOfRelation:(MCPRelation *) iRelation atIndex:(NSUInteger) iIndex; -- (MCPObject *) getTargetOfRelationNamed:(NSString *) iRelationName atIndex:(NSUInteger) iIndex; -- (MCPDBReturnCode) addTarget:(MCPObject *) iTarget toRelation:(MCPRelation *) iRelation; -- (MCPDBReturnCode) addTarget:(MCPObject *) iTarget toRelationNamed:(NSString *) iRelationName; -- (MCPDBReturnCode) removeTarget:(MCPObject *) iTarget toRelation:(MCPRelation *) iRelation; -- (MCPDBReturnCode) removeTarget:(MCPObject *) iTarget toRelationNamed:(NSString *) iRelationName; -- (MCPDBReturnCode) removeTargetToRelation:(MCPRelation *) iRelation atIndex:(NSUInteger) iIndex; -- (MCPDBReturnCode) removeTargetToRelationNamed:(NSString *) iRelationName atIndex:(NSUInteger) iIndex; -- (NSUInteger) indexOfTarget:(MCPObject *) iTarget inRelation:(MCPRelation *) iRelation; -- (NSUInteger) indexOfTarget:(MCPObject *) iTarget inRelationNamed:(NSString *) iRelationName; - -#pragma mark Utilities -/*" Utility methods "*/ -- (id) defaultValueForKey:(NSString *) iKey; -- (NSDictionary *) primaryKey; - -/*" Testing equality (VERY important for relation management)"*/ -- (BOOL) isEqual:(id) iObject; - -#pragma mark Output -/*" Output : "*/ -- (NSString *) description; -- (NSString *) descriptionWithLocale:(NSDictionary *) locale; - -#pragma mark Ordering the array for relations -- (NSString *) orderSQLForClassDescription:(MCPClassDescription *) iClassDescription; - -/*" Anti-crash method... "*/ -- (void) setNilValueForKey:(NSString *) iKey; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPObject.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPObject.m deleted file mode 100644 index dba963c6..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPObject.m +++ /dev/null @@ -1,1342 +0,0 @@ -// -// $Id$ -// -// MCPObject.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 19/05/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPObject.h" - -#import <MCPKit/MCPKit.h> - -#import "MCPClassDescription.h" -#import "MCPClassDescription+MCPEntreprise.h" -#import "MCPAttribute.h" -#import "MCPRelation.h" -#import "MCPJoin.h" - -@implementation MCPObject - -#pragma mark Life of the object -- (id) init -/*" Taking care of getting the class description for self (after passing the message up). "*/ -{ -// NSArray theAttributes; -// unsigned int i; - - if (self = [super init]) { - classDescription = [[NSClassDescription classDescriptionForClass:[self class]] retain]; - [self setAttributesToDefault]; -/* - theAttributes = [classDescription attributeKeys]; - for (i=0; [theAttributes count] != i; ++i) { // setting the attributtes with proper defaults. - NSString *theKey = (NSString *) [theAttributes objectAtIndex:i]; - - [self setValue:[self defaultValueForKey:theKey] forKey:theKey]; - } - */ - } - return self; -} - -- (id) initWithDictionary:(NSDictionary *) dictionary -/*" This method will use the class description to fetch in the dictionary the values of the attributes of the object.... - Should try to get this description a bit clearer."*/ -{ - self = [super init]; - if (self) { - NSUInteger i; - NSArray *attrArray; - - classDescription = [[NSClassDescription classDescriptionForClass:[self class]] retain]; - [self setAttributesToDefault]; - attrArray = [classDescription attributes]; - for (i=0; [attrArray count] != i; ++i) { - MCPAttribute *currentAttribute = (MCPAttribute *)[attrArray objectAtIndex:i]; - id currentValue = [dictionary objectForKey:[currentAttribute name]]; - - if (! currentValue) { - currentValue = [dictionary objectForKey:[currentAttribute externalName]]; - } - if (currentValue) { - [self setValue:currentValue forKey:[currentAttribute name]]; - } - } - } - return self; -} - -- (void) dealloc -/*" Deallocating the class description, then passes the message to super. "*/ -{ -// unsigned int i; -// NSArray *tmpAttributes = [classDescription attributes]; - -/* for (i=0; [tmpAttributes count] != i; ++i) { - MCPAttribute *tmpAttr = [tmpAttributes objectAtIndex:i]; - if ([tmpAttr valueClass]) { - [self setValue:nil forKey:[tmpAttr name]]; - } - } -*/ - [classDescription release]; - [connection release]; - [super dealloc]; -} - -- (void) setAttributesToDefault -/*" Set all the attributes to default values, except for auto-generated and primary key attributes, which are set to NULL. - - NOTE : !! In the current version the auto-generated and key are ALSO set to default values!!. - "*/ -{ - NSArray *theAttributes = [classDescription attributes]; -// NSArray *thePrimKeys = [classDescription primaryKeyAttributes]; - NSUInteger i; - - for (i=0; [theAttributes count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *) [theAttributes objectAtIndex:i]; - NSString *theKey = [theAttribute name]; - - if (! [theAttribute autoGenerated]) { - [self setValue:[self defaultValueForKey:theKey] forKey:theKey]; - } - else { // Auto-generated attribute ... set it to NULL: - [self setValue:[self defaultValueForKey:theKey] forKey:theKey]; - } - } -/* - for (i=0; [thePrimKeys count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *) [thePrimKeys objectAtIndex:i]; - if (! [theAttribute autoGenerated]) { - NSString *theKey = [theAttribute name]; - - [[self valueForKey:theKey] release]; - [self setValue:NULL forKey:theKey]; - } - } - */ - return; -} - -#pragma mark Accessor(s) -- (MCPClassDescription *) classDescription -{ - return classDescription; -} - -- (MCPConnection *) connection -{ - if ((! connection) || (! [connection checkConnection])) { - [self setConnection:nil]; - } - return connection; -} - -- (void) setConnection:(MCPConnection *) iConnection -{ - if (iConnection != connection) { - [connection release]; - connection = [iConnection retain]; - } -} - - - -#pragma mark Database interface -- (id) readFromDBRow:(NSDictionary *) iDictionary withTableName:(NSString *) iTableName -/*" Uses a query result row (described as a NSDictionary) to set the instance variables of self. If - the result contains columns from multiple tables, the iTableName can be used to specify the alias - used for the table name corresponding to the class. - -If iTableName == nil, the columns will be searched first without table name (column_name) and if - not found then with the table name in front (from the class description : table_name.column_name). - -Otherwise, the search will be performed in the following order : iTableName.column_name, column_name, - table_name.column_name. - "*/ -{ - NSArray *theAttributeKeys = [classDescription attributeKeys]; - NSArray *thePrefixArray; - NSUInteger i; - -// Depending on the value of iTableName, get the search order. - if ((nil == iTableName) || ([@"" isEqualToString:iTableName])) { - thePrefixArray = [NSArray arrayWithObjects:@"", [NSMutableString stringWithFormat:@"%@.", [classDescription externalName]], nil]; - } - else { - thePrefixArray = [NSArray arrayWithObjects:[NSString stringWithFormat:@"%@.", iTableName], [NSMutableString stringWithFormat:@"%@.", [classDescription externalName]], @"", nil]; - } - for (i=0; [theAttributeKeys count] != i; ++i) { - id theValue = nil; - MCPAttribute *theAttribute = [classDescription attributeWithName:[theAttributeKeys objectAtIndex:i]]; - NSUInteger j; - - for (j=0; [thePrefixArray count] != j; ++j) { - if (theValue = [iDictionary objectForKey:[NSString stringWithFormat:@"%@%@", [thePrefixArray objectAtIndex:j], [theAttribute externalName]]]) { - break; - } - } - if (theValue) { - [self takeValue:theValue forKey:[theAttribute name]]; - } - } - return self; -} - - -//- (MCPDBReturnCode) setPrimaryKey:(NSDictionary *) iDictionary andFetchFromDB:(MCPConnection *) iConnection -- (MCPDBReturnCode) setPrimaryKey:(id) iDictionary andFetchFromDB:(MCPConnection *) iConnection -/*" This method is used to retrieve an object from the DB given its precise primary key. It will return self. - If the object is not found in the DB, then all instance variable are set to the default - (and autogenerated/primary-key attributes are set to null)."*/ -{ - BOOL missingKey = NO; - NSArray *theKeyAttr = [classDescription primaryKeyAttributes]; - NSUInteger i; - NSMutableString *query = [NSMutableString stringWithFormat:@"SELECT * FROM %@ WHERE ", [classDescription externalName]]; - MCPResult *result; - NSDictionary *row; - - [self setConnection:iConnection]; - if (! iConnection) { - return MCPDBReturnNoConnection; - } - for (i=0; [theKeyAttr count] != i; ++i) { - MCPAttribute *theAttr = [classDescription attributeWithName:[(MCPAttribute *)[theKeyAttr objectAtIndex:i] name]]; - id theKeyValue; - -// if (theKeyValue = [iDictionary objectForKey:[theAttr name]]) { - if (theKeyValue = [iDictionary valueForKey:[theAttr name]]) { - if (i != 0) { - [query appendString:@" and "]; - } -// Implies the iDictionary IS a dictionary: -// [query appendFormat:@"(%@ = %@)", [theAttr externalName], [iConnection quoteObject:[iDictionary objectForKey:[theAttr name]]]]; -// If the iDictionary is just an object complying with NSValueCodeing: - [query appendFormat:@"(%@ = %@)", [theAttr externalName], [iConnection quoteObject:theKeyValue]]; - } - else { // Part of the primary key is missing... look for the DB name of the attribute - if (theKeyValue = [iDictionary valueForKey:[theAttr externalName]]) { - if (i != 0) { - [query appendString:@" and "]; - } - [query appendFormat:@"(%@ = %@)", [theAttr externalName], [iConnection quoteObject:theKeyValue]]; - } - else { // Not able to find the value for this attribute !!! - missingKey = YES; - NSLog(@"Unable to find the value for attribute %@ of object of class %@, will make it default", [theAttr name], [self className]); - break; - } - } - } // Now the query is prepared... or a key part is missing: - if (missingKey) { - [self setAttributesToDefault]; - return MCPDBReturnIncompleteKey; - } - result = [iConnection queryString:query]; - if ([result numOfRows] == 0) { - [self setAttributesToDefault]; - return MCPDBReturnNone; - } - row = [result fetchRowAsDictionary]; - [self readFromDBRow:row withTableName:@""]; - if ([result numOfRows] != 1) { - NSLog(@"Got more than one row when querying : %@.... will take only the first one!!! that an IMPORTANT flaw in your data model!!!", query); - return MCPDBReturnMultiple; - } - return MCPDBReturnOK; -} - - -- (NSDictionary *) checkDBId -/*" Using the identity properties of the class, this method will check if self already exists in the DB, - in which case it will set the primary key attributes to match the DB entry. If the object is not present - in the DB, the primary key attributes are set to null if they are declared as aut-generated (untouched otherwise). - -The returned dictionary contains the values of the primary key attributes. It also contains one entry with - key MCPDBReturnCode, which contains the result of the operation (was the object in DB?). - -If the identityAttributes of the class description is empty, the entry will always be considered not to be - in the DB, AND the primary key attributes of the object will be left unchnaged and returned as they are at - call time."*/ -{ - NSArray *theIdAttr = [classDescription identityAttributes]; - NSMutableDictionary *theKeys = [NSMutableDictionary dictionary]; - NSArray *theKeyAttr = [classDescription primaryKeyAttributes]; - MCPConnection *theConnection = [self connection]; - MCPResult *theResult; - NSUInteger i; - - if (! theConnection) { - return [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInteger:MCPDBReturnNoConnection], @"MCPDBReturnCode", nil]; - } - if (! [theKeyAttr count]) { // There is no primary key for this object. - [theKeys setObject:[NSNumber numberWithInteger:MCPDBReturnNoKey] forKey:@"MCPDBReturnCode"]; - return [NSDictionary dictionaryWithDictionary:theKeys]; - } - if (! [theIdAttr count]) { // Identity is not defined for this object. - [theKeys setObject:[NSNumber numberWithInteger:MCPDBReturnNoIdentity] forKey:@"MCPDBReturnCode"]; - for (i=0; [theKeyAttr count] != i; ++i) { - NSString *theKey = [(MCPAttribute*)[theKeyAttr objectAtIndex:i] name]; - [theKeys setObject:[self valueForKey:theKey] forKey:theKey]; - } - return [NSDictionary dictionaryWithDictionary:theKeys]; - } -// Do the fetch in the DB. - NSMutableString *theQuery = [NSMutableString stringWithString:@"SELECT "]; - - for (i = 0; [theKeyAttr count] != i; ++i) { - if (i) { - [theQuery appendString:@", "]; - } - [theQuery appendString:[(MCPAttribute *)[theKeyAttr objectAtIndex:i] externalName]]; - } - [theQuery appendFormat:@" FROM %@ WHERE ", [classDescription externalName]]; - for (i = 0; [theIdAttr count] != i; ++i) { - if (i) { - [theQuery appendString:@" AND "]; - } -/* - if ([[(MCPAttribute *)[theIdAttr objectAtIndex:i] valueClass] isSubclassOfClass:[NSString class]]) { - if ([(MCPAttribute *)[theIdAttr objectAtIndex:i] width] != 0) { - [theQuery appendFormat:@"(BINARY %@ = SUBSTRING(%@ FROM 1 FOR %u)", [(MCPAttribute *)[theIdAttr objectAtIndex:i] externalName], [theConnection quoteObject:[self valueForKey:[(MCPAttribute *)[theIdAttr objectAtIndex:i] name]]], [(MCPAttribute *)[theIdAttr objectAtIndex:i] width]]; - } - else { - [theQuery appendFormat:@"(BINARY %@ = %@)", [(MCPAttribute *)[theIdAttr objectAtIndex:i] externalName], [theConnection quoteObject:[self valueForKey:[(MCPAttribute *)[theIdAttr objectAtIndex:i] name]]]]; - } - } - */ - if (([[(MCPAttribute *)[theIdAttr objectAtIndex:i] valueClass] isSubclassOfClass:[NSString class]]) && ([(MCPAttribute *)[theIdAttr objectAtIndex:i] width] != 0)) { - [theQuery appendFormat:@"(%@ = SUBSTRING(%@ FROM 1 FOR %ld))", [(MCPAttribute *)[theIdAttr objectAtIndex:i] externalName], [theConnection quoteObject:[self valueForKey:[(MCPAttribute *)[theIdAttr objectAtIndex:i] name]]], [(MCPAttribute *)[theIdAttr objectAtIndex:i] width]]; - } - else { - [theQuery appendFormat:@"(%@ = %@)", [(MCPAttribute *)[theIdAttr objectAtIndex:i] externalName], [theConnection quoteObject:[self valueForKey:[(MCPAttribute *)[theIdAttr objectAtIndex:i] name]]]]; - } - } - [theQuery appendString:@" ORDER BY "]; - for (i = 0; [theKeyAttr count] != i; ++i) { - if (i) { - [theQuery appendString:@", "]; - } - [theQuery appendString:[(MCPAttribute *)[theKeyAttr objectAtIndex:i] externalName]]; - } - theResult = [theConnection queryString:theQuery]; - if ([theResult numOfRows]) { // the object was found. - NSDictionary *theFirstRow = [theResult fetchRowAsDictionary]; - if ([theResult numOfRows] != 1) { - NSLog(@"in MCPObject -checkDBIdWithConnection: method.... not only one (as expected) but %ld results were found, will take the first one."); - [theKeys setObject:[NSNumber numberWithInteger:MCPDBReturnMultiple] forKey:@"MCPDBReturnCode"]; - } - else { - [theKeys setObject:[NSNumber numberWithInteger:MCPDBReturnOK] forKey:@"MCPDBReturnCode"]; - } - [theKeys addEntriesFromDictionary:theFirstRow]; -// Setting the value of self for the primary key to the one just found. - for (i=0; [theKeyAttr count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *) [theKeyAttr objectAtIndex:i]; - - [self setValue:[theFirstRow objectForKey:[theAttribute externalName]] forKey:[theAttribute name]]; - } - } - else { // Object not found in the DB. - for (i = 0; [theKeyAttr count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *)[theKeyAttr objectAtIndex:i]; - - if ([theAttribute autoGenerated]) { - [self setValue:[self defaultValueForKey:[theAttribute name]] forKey:[theAttribute name]]; - } - [theKeys setObject:[self valueForKey:[theAttribute name]] forKey:[theAttribute name]]; - } - [theKeys setObject:[NSNumber numberWithInteger:MCPDBReturnNone] forKey:@"MCPDBReturnCode"]; -// Setting the value of self for the primary key to the default values. -/* - for (i=0; [theKeyAttr count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *) [theKeyAttr objectAtIndex:i]; - - [self setValue:[self defaultValueForKey:[theAttribute name]] forKey:[theAttribute name]]; - } -*/ - } - return [NSDictionary dictionaryWithDictionary:theKeys]; -} - - -- (NSDictionary *) saveInDB -/*" First will use the checkDBIdWithConnection method to check if the entry is already in the database. If this is the case, - it will use the updateInDB... method to update the current DB instance. Otherwise it will make an insert into the database - to save the entry, than it makes a select to get the value of autogenerated column, and use them (if necessary) to return - the primary key (as NSDictionary). - - As for checkDBId... the returned dictionary also have a MCPDBReturnCode key with a NSNumber as value containing the - return code of the operation."*/ -{ - MCPConnection *theConnection = [self connection]; - NSDictionary *theCheckReturn = [self checkDBId]; - NSMutableDictionary *theRet; - NSInteger theCheckCode = [(NSNumber *)[theCheckReturn objectForKey:@"MCPDBReturnCode"] integerValue]; - NSUInteger i; - NSUInteger j; - NSMutableString *theQuery = [NSMutableString string]; - NSArray *theAttr = [classDescription attributes]; - - switch (theCheckCode) { - case MCPDBReturnNoIdentity : // For this object the identity is not set... so we try to save. - break; - - case MCPDBReturnOK : // Object already in the DB (found using checkDBId... method). - // NSLog(@"in saveUsingConnection: the entry already existed so will update the one with key : %@", theCheckReturn); - theCheckCode = [self updateInDB]; - theRet = [NSMutableDictionary dictionaryWithDictionary:[self primaryKey]]; - [theRet setObject:[NSNumber numberWithInteger:theCheckCode] forKey:@"MCPDBReturnCode"]; - return [NSDictionary dictionaryWithDictionary:theRet]; - break; - - case MCPDBReturnMultiple : // Multiple were found, the first one will be updated. - NSLog(@"Multiple entries found with the same identity ... will update the first one."); - theCheckCode = [self updateInDB]; - theRet = [NSMutableDictionary dictionaryWithDictionary:[self primaryKey]]; - [theRet setObject:[NSNumber numberWithInteger:theCheckCode] forKey:@"MCPDBReturnCode"]; - return [NSDictionary dictionaryWithDictionary:theRet]; - break; - - case MCPDBReturnNone : // The entry is not already in the DB, save it... - break; - - case MCPDBReturnNoConnection : // Self does not have a connection. - NSLog(@"Can not save when the connection is not working..."); - break; - - default : // We should not arrive here anyway. - NSLog(@"For some resons we got a unexpected result from checkDBId : %ld", theCheckCode); - break; - } - -// Generate the INSERT query: - [theQuery appendFormat:@"INSERT INTO %@ (", [classDescription externalName]]; - j = 0; - for (i=0; [theAttr count] != i; ++i) { - if (! [(MCPAttribute *)[theAttr objectAtIndex:i] autoGenerated]) { - if (j) { - [theQuery appendString:@", "]; - } - [theQuery appendString:[(MCPAttribute *)[theAttr objectAtIndex:i] externalName]]; - ++j; - } - } - [theQuery appendString:@") VALUES ("]; - j = 0; - for (i=0; [theAttr count] != i; ++i) { - if (! [(MCPAttribute *)[theAttr objectAtIndex:i] autoGenerated]) { - if (j) { - [theQuery appendString:@", "]; - } - [theQuery appendString:[theConnection quoteObject:[self valueForKey:[(MCPAttribute *)[theAttr objectAtIndex:i] name]]]]; - ++j; - } - } - [theQuery appendString:@")"]; -// Finished preparing the query. - -// Now we perform the query... - [theConnection queryString:theQuery]; - if (1 != (i = [theConnection affectedRows])) { // More than one row affected ... Should NEVER occure. - NSLog(@"Problem while saving a MCPObject to the database : number of inserted rows is : %ld !!!", i); - NSLog(@"Maybe there is an error : %@ ", [theConnection getLastErrorMessage]); - NSLog(@"The class of the object is : %@, and it's description is :\n%@", [self className], [self descriptionWithLocale:nil]); - theCheckCode = (i == 0) ? MCPDBReturnNone : MCPDBReturnMultiple; - } - else { - theCheckCode = MCPDBReturnOK; - } - -// Finally we get the primary key of the inserted object: - if ([classDescription singleIntAutoGenKey]) { - NSString *thePrimKey = [(MCPAttribute *) [[classDescription primaryKeyAttributes] objectAtIndex:0] name]; - - [self setValue:[NSNumber numberWithLongLong:[theConnection insertId]] forKey:thePrimKey]; - } - [self getAutoGenerated]; - theRet = [NSMutableDictionary dictionaryWithDictionary:[self primaryKey]]; - [theRet setObject:[NSNumber numberWithInteger:theCheckCode] forKey:@"MCPDBReturnCode"]; - - return [NSDictionary dictionaryWithDictionary:theRet]; -} - - - -- (MCPDBReturnCode) getAutoGenerated -/*" This method will use the Identity attributes of the object to retrieve the autogenerated -attributes from the database. - -If the identity is not defined for this class/entity, then it will try to use the primary key -to get the auto-generated values. - -Obviously this might generate a bug if one of the Identity attributes is autogenerated. -This will create a trouble if some object does not have an identity defined but still contains -some auto-generated attributes. -"*/ -{ - NSMutableArray *theAutoAttr = [NSMutableArray array]; - NSArray *theAttr = [classDescription attributes]; - NSArray *theKeyAttr = [classDescription primaryKeyAttributes]; - NSUInteger i,j; - NSMutableString *theQuery; - NSInteger theCheckCode; - MCPResult *theResult; - NSDictionary *theRow; - MCPConnection *theConnection = [self connection]; - - if (! theConnection) { - return MCPDBReturnNoConnection; - } - - if (0 != [[classDescription identityAttributes] count]) { - theCheckCode = [(NSNumber *)[[self checkDBId] objectForKey:@"MCPDBReturnCode"] integerValue]; - if ((MCPDBReturnOK != theCheckCode) && (MCPDBReturnMultiple != theCheckCode)) { - NSLog(@"Unable to get the primary key for the object, will abort now the fetch of autoGenerated attributes (left unchanged)!"); - return theCheckCode; - } - if (MCPDBReturnMultiple == theCheckCode) { - NSLog(@"Will get the autoGenerated values for the first entry...."); - } - } - j = 0; - for (i=0; [theAttr count] != i; ++i) { // generate the array with autoGenerated attributes. - if ([(MCPAttribute *)[theAttr objectAtIndex:i] autoGenerated]) { - [theAutoAttr insertObject:[theAttr objectAtIndex:i] atIndex:j]; - ++j; - } - } - if (0 == [theAutoAttr count]) { - return MCPDBReturnOK; - } - -// Make the query: - theQuery = [NSMutableString stringWithString:@"SELECT "]; - for (i=0; [theAutoAttr count] != i; ++i) { - if (i) { - [theQuery appendString:@", "]; - } - [theQuery appendString:[(MCPAttribute *)[theAutoAttr objectAtIndex:i] externalName]]; - } - [theQuery appendFormat:@" FROM %@ WHERE ", [classDescription externalName]]; -// Preparing the Where Clause: - for (i=0; [theKeyAttr count] != i; ++i) { - if (i) { - [theQuery appendString:@" AND "]; - } - [theQuery appendFormat:@"( %@ = %@ )", [(MCPAttribute*)[theKeyAttr objectAtIndex:i] externalName], [theConnection quoteObject:[self valueForKey:[(MCPAttribute*)[theKeyAttr objectAtIndex:i] name]]]]; - } -// Query is ready: - theResult = [theConnection queryString:theQuery]; - if (! theResult) { - NSLog(@"While fetching the auto-generated part of the object, got an error -a nil MCPResult-. Will report that as a MCPDBReturnNone."); - return MCPDBReturnNone; - } - if (0 == [theResult numOfRows]) { // The entry was not found in the DB. - if (0 == [[classDescription identityAttributes] count]) { - NSLog(@"It seems that the object is not in the DB... but the identity is not defined so there might be a trouble with having the proper ID."); - } - return MCPDBReturnNone; - } -// Getting the values from the DB select: - theRow = [theResult fetchRowAsDictionary]; - for (i=0; [theAutoAttr count] != i; ++i) { - [self setValue:[theRow objectForKey:[(MCPAttribute*)[theAutoAttr objectAtIndex:i] externalName]] forKey:[(MCPAttribute*)[theAutoAttr objectAtIndex:i] name]]; - } -// Returning the proper value: - if (1 != [theResult numOfRows]) { - NSLog(@"Multiple entries (or none : %llu), got the values for the first one...", [theResult numOfRows]); - return MCPDBReturnMultiple; - } - return MCPDBReturnOK; -} - - -- (MCPDBReturnCode) updateInDB -/*"This method will use the primary key value held by the object to modify the object that is saved in the DB. - - (NO YET IMPLEMENTED) If the primary key is not complete (some of the attributes are to null or 0) and the identityAttributes - (from class description) is not an empty list then it will perform a checkDBId... to try to retrieve the - missing part of the primary key. - "*/ -{ - NSArray *theAttributes = [classDescription attributes]; - NSArray *thePrimKeyAttributes = [classDescription primaryKeyAttributes]; - NSMutableString *theQuery = [NSMutableString string]; - NSInteger theCheckCode; - NSUInteger i, j; - MCPConnection *theConnection = [self connection]; - - if (! theConnection) { - return MCPDBReturnNoConnection; - } -// Generate the query - [theQuery appendFormat:@"UPDATE %@ SET ", [classDescription externalName]]; - // Prepare the value key pairs: - j=0; - for (i=0 ; [theAttributes count] != i; ++i) { - id theValue = [self valueForKey:[(MCPAttribute *)[theAttributes objectAtIndex:i] name]]; - - if ((theValue) && (! [(MCPAttribute *)[theAttributes objectAtIndex:i] autoGenerated])) { - if (j) { - [theQuery appendString:@", "]; - } - [theQuery appendFormat:@"%@ = %@ ", [(MCPAttribute *)[theAttributes objectAtIndex:i] externalName], [theConnection quoteObject:theValue]]; - ++j; - } - } - if (0 == j) { // Nothing has to be updated in this entry.... - NSLog(@"Tried to update a row from an object that does NOT contain any information!!"); - return MCPDBReturnNone; - } - // Prepare the WHERE clause: - [theQuery appendFormat:@" WHERE "]; - j = 0; - for (i=0; [thePrimKeyAttributes count] != i; ++i) { - id theValue = [self valueForKey:[(MCPAttribute *)[thePrimKeyAttributes objectAtIndex:i] name]]; - - if (j) { - [theQuery appendString:@" AND "]; - } - if (theValue) { - [theQuery appendFormat:@"%@ = %@", [(MCPAttribute *)[thePrimKeyAttributes objectAtIndex:i] externalName], [theConnection quoteObject:theValue]]; - ++j; - } - } -// Perform the update: - if (j == [thePrimKeyAttributes count]) { - [theConnection queryString:theQuery]; - i = [theConnection affectedRows]; - switch (i) { - case 0 : - theCheckCode = MCPDBReturnNone; - break; - case 1 : - theCheckCode = MCPDBReturnOK; - break; - default : - theCheckCode = MCPDBReturnMultiple; - break; - } - } - else { - NSDictionary *theKeyCheck = [self checkDBId]; - NSInteger theIdCheckCode = [(NSNumber *) [theKeyCheck objectForKey:@"MCPDBReturnCode"] integerValue]; - - if (MCPDBReturnOK == theIdCheckCode) { - theCheckCode = [self updateInDB]; - } - else { - theCheckCode = MCPDBReturnNoKey; - } - } -// Return proper code: - return theCheckCode; -} - - -- (MCPDBReturnCode) deleteInDB -/*" Uses the connection to delete the object from the DB. In this process the autoGenerated attributes are set to null. - If the primary key is not completely set, this method calls checkDBId... method to try to complete it - (if the identityAttributes of the class description is not empty)."*/ -{ - NSArray *theKeyAttributes = [classDescription primaryKeyAttributes]; - NSArray *theAttributes = [classDescription attributes]; - NSUInteger i; -// NSMutableDictionary *theKeyValue = [NSMutableDictionary dictionary]; - NSInteger theCheckCode = MCPDBReturnOK; - MCPConnection *theConnection = [self connection]; - - if (! theConnection) { - return MCPDBReturnNoConnection; - } -// Get the value of the primary key: - for (i=0; [theKeyAttributes count] != i; ++i) { - id theValue = [self valueForKey:[(MCPAttribute*) [theKeyAttributes objectAtIndex:i] name]]; - if ((! theValue) || ([theValue isKindOfClass:[NSNumber class]] && (0 == [theValue integerValue]))) { - theCheckCode = MCPDBReturnIncompleteKey; - break; - } - } -// If incomplete, try to find the rest, and perform again: - if (MCPDBReturnIncompleteKey == theCheckCode) { - if (MCPDBReturnOK == [(NSNumber *)[[self checkDBId] objectForKey:@"MCPDBReturnCode"] integerValue]) { - return [self deleteInDB]; - } - else { - return MCPDBReturnIncompleteKey; - } - } - -// Perform the deletion from the DB: - theCheckCode = [[self class] deleteInDBUsingConnection:theConnection withId:self]; - -// set the auto-generated attributes to proper values: - for (i=0 ; [theAttributes count] != i; ++i) { - MCPAttribute *theAttribute = (MCPAttribute *) [theAttributes objectAtIndex:i]; - if ([theAttribute autoGenerated]) { -// [self setValue:NULL forKey:[theAttribute name]]; - [self setValue:[self defaultValueForKey:[theAttribute name]] forKey:[theAttribute name]]; - } - } - -// Finished... just have to return the proper value: - return theCheckCode; -} - - -+ (MCPDBReturnCode) deleteInDBUsingConnection:(MCPConnection *) iConnection withId:(id) iId -/*" Uses the connection to remove from the DB the entry corresponding to the primary key id given by iId. - If any part of the primary key is missing, nothing is done."*/ -{ - NSMutableString *theQuery = [NSMutableString string]; - MCPClassDescription *theClassDescription = (MCPClassDescription *) [NSClassDescription classDescriptionForClass:[self class]]; - NSArray *theKeyAttributes = [theClassDescription primaryKeyAttributes]; - NSUInteger i; - - if (! [iConnection checkConnection]) { - return MCPDBReturnNoConnection; - } -// Generate the query: - [theQuery appendFormat:@"DELETE FROM %@ WHERE ", [theClassDescription externalName]]; -// Prepare the WHERE STATEMENT: - for (i=0; [theKeyAttributes count] != i; ++i) { - if (i) { - [theQuery appendString:@" AND "]; - } -// [theQuery appendFormat:@"( %@ = %@ )", [(MCPAttribute*)[theKeyAttributes objectAtIndex:i] externalName], [iConnection quoteObject:[iId objectForKey:[(MCPAttribute*)[theKeyAttributes objectAtIndex:i] name]]]]; - [theQuery appendFormat:@"( %@ = %@ )", [(MCPAttribute*)[theKeyAttributes objectAtIndex:i] externalName], [iConnection quoteObject:[iId valueForKey:[(MCPAttribute*)[theKeyAttributes objectAtIndex:i] name]]]]; - } -// Perform the query: - [iConnection queryString:theQuery]; -// Return the proper code: - i = [iConnection affectedRows]; - - if (1 < i) { - return MCPDBReturnMultiple; - } - if (0 == i) { - return MCPDBReturnNone; - } - return MCPDBReturnOK; -} - - -#pragma mark Handling realtions -- (id) getTargetOfRelation:(MCPRelation *) iRelation -/*" This method is using the information from iRelation to fetch the targe of the relation in the DB. - -If iRelation is flagged as a to-one, then the return type is the type of the target object (value might be nil, if the target was not found). -If iRelation is flagged as a to-many, then the return type is NSArray (and might be empty if no target were found). - -In any case this method is first checking that iRelation is starting from the class of self, and that self is connected to the DB. -Also the returned object is ALWAYS autoreleased before being returned. -"*/ -{ - NSMutableString *query; - MCPClassDescription *destinationDesc; - NSArray *joins; - NSArray *keys; - NSArray *ids; - MCPResult *result; - NSUInteger i; - NSDictionary *theRow; - id theRet; - - if (! iRelation) { - NSLog(@"Tried to get the target of a relation... but the relation object is nil"); - } - else { -// NSLog(@"Trying to get the target of the realtion : %@", [iRelation descriptionWithLocale:nil]); - } - if ((! [connection isConnected]) || (! [classDescription isEqual:[iRelation origin]])) { // Error condition. - return nil; - } -// Generating the query: - destinationDesc = [iRelation destination]; - keys = [destinationDesc primaryKeyAttributes]; - joins = [iRelation joins]; - ids = [destinationDesc identityAttributes]; - query = [[NSMutableString alloc] initWithString:@"SELECT "]; - for (i=0; [keys count] != i; ++i) { - if (i) { - [query appendString:@", "]; - } - [query appendString:[(MCPAttribute *)[keys objectAtIndex:i] externalName]]; - } - [query appendFormat:@" FROM %@ WHERE ", [destinationDesc externalName]]; - for (i=0; [joins count] != i; ++i) { - MCPJoin *theJoin = (MCPJoin *)[joins objectAtIndex:i]; - - if (i) { - [query appendString:@" and "]; - } - [query appendFormat:@"(%@ = %@)", [[theJoin destination] externalName], [connection quoteObject:[self valueForKey:[[theJoin origin] name]]]]; - } -// NSLog(@"in -[MCPObject getTargetOfRelation:%@]; query is %@...", [iRelation descriptionWithLocale:nil], query); - [query appendString:[self orderSQLForClassDescription:destinationDesc]]; -// NSLog(@"in -[MCPObject getTargetOfRelation:%@]; query is %@...", [iRelation descriptionWithLocale:nil], query); -/* - [query appendString:@" ORDER BY "]; - for (i=0; [ids count] != i; ++i) { // Generating the order : - if (i) { - [query appendString:@", "]; - } - [query appendString:[(MCPAttribute *)[ids objectAtIndex:i] externalName]]; - } -*/ - result = [connection queryString:query]; - [query release]; - -// Getting the results in proper objects: - if ([iRelation isToMany]) { // To-Many relation - NSMutableArray *theArrayRet = [[NSMutableArray alloc] init]; - - theRet = theArrayRet; - while (theRow = [result fetchRowAsDictionary]) { - MCPObject *theTarget = [[[destinationDesc representedClass] alloc] init]; - - [theTarget setPrimaryKey:theRow andFetchFromDB:connection]; - [theArrayRet insertObject:theTarget atIndex:[theArrayRet count]]; - [theTarget release]; - } - } - else { // To-One relation - theRow = [result fetchRowAsDictionary]; - if (theRow) { - theRet = [[[destinationDesc representedClass] alloc] init]; - [theRet setPrimaryKey:theRow andFetchFromDB:connection]; - } - else { - theRet = nil; - } - } - [theRet autorelease]; - return theRet; -} - -- (id) getTargetOfRelationNamed:(NSString *) iRelationName -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self getTargetOfRelation:theRelation] : nil; -} - -- (MCPDBReturnCode) setTarget:(id) iTarget forRelation:(MCPRelation *) iRelation -/*" This method will modify the DB content so that the corresponding relation is deleted. - If any value corresping to an attribute of self is modified in the DB, then it will update all attributes of self to reflect DB status. - -Obviuosly this method is taking care of only to-one relation. It will hence check that iRelation is a to-one relation starting from self. -Finally, you can use setTarget:nil forRelation:... to 'delete' a previously establlished relation (if the model and DB permit it)."*/ -{ - NSUInteger i; - MCPObject *oldTarget; - - if (! [connection isConnected]) { - return MCPDBReturnNoConnection; - } - if (! [classDescription isEqual:[iRelation origin]]) { - return MCPDBReturnWrongRelationOrigin; - } - if ([iRelation isToMany]) { - return MCPDBReturnWrongRelationCardinality; - } - - oldTarget = [self getTargetOfRelation:iRelation]; - if ((oldTarget) && ([iTarget isEqual:oldTarget])) { // No need to change the relation's target. - return MCPDBReturnOK; - } - for (i=0; [iRelation countOfJoins] != i; ++i) { - MCPJoin *theJoin = [iRelation objectInJoinsAtIndex:i]; - - if (([[theJoin origin] isPartOfKey]) && (![[theJoin destination] isPartOfKey])) { // Will change the destination... - [iTarget setValue:[self valueForKey:[[theJoin origin] name]] forKey:[[theJoin destination] name]]; - [oldTarget setValue:[oldTarget defaultValueForKey:[[theJoin destination] name]] forKey:[[theJoin destination] name]]; - } - else { // Will change the origin - [self setValue:[iTarget valueForKey:[[theJoin destination] name]] forKey:[[theJoin origin] name]]; - } - } - if ([iRelation ownsDestination]) { - [oldTarget deleteInDB]; - } - return MCPDBReturnOK; -} - -- (MCPDBReturnCode) setTarget:(id) iTarget forRelationNamed:(NSString *) iRelationName -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self setTarget:iTarget forRelation:theRelation] : MCPDBReturnNoSuchRelation; -} - -- (NSUInteger) countTargetForRelation:(MCPRelation *) iRelation -{ - NSMutableString *theQuery; - NSUInteger i; - NSArray *theJoinArray; - MCPResult *theResult; - NSDictionary *theRow; - - if ((! [connection isConnected]) || (! [classDescription isEqual:[iRelation origin]])){ - return 0; - } - theJoinArray = [iRelation joins]; - theQuery = [[NSMutableString alloc] initWithFormat:@"SELECT COUNT(1) FROM %@ WHERE ", [[iRelation destination] externalName]]; - for (i=0; [theJoinArray count] != i; ++i) { - MCPJoin *theJoin = (MCPJoin *)[theJoinArray objectAtIndex:i]; - if (i) { - [theQuery appendString:@" AND "]; - } - [theQuery appendFormat:@"( %@ = %@ )", [[theJoin destination] externalName], [connection quoteObject:[self valueForKey:[[theJoin origin] name]]]]; - } - theResult = [connection queryString:theQuery]; - [theQuery release]; - theRow = [theResult fetchRowAsDictionary]; - return [(NSNumber *)[theRow objectForKey:@"COUNT(1)"] unsignedIntegerValue]; -} - -- (NSUInteger) countTargetForRelationNamed:(NSString *) iRelationName -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self countTargetForRelation:theRelation] : 0; -} - - -- (MCPObject *) getTargetOfRelation:(MCPRelation *) iRelation atIndex:(NSUInteger) iIndex -/*" This method will return the specific object which is the iIndex'th object of th relation (after ordering the object using the destination identity). - -This method (like other assuming order in the relation targets) will be doubtfull if the class does NOT have a single identity attribute."*/ -{ - NSMutableString *query; - MCPClassDescription *destinationDesc; - NSArray *joins; - NSArray *keys; - NSArray *ids; - MCPResult *result; - NSUInteger i; - NSDictionary *theRow; - MCPObject *theRet; - - if (! iRelation) { - NSLog(@"Tried to get the target of a relation... but the relation object is nil"); - } - else { -// NSLog(@"Trying to get the target of the realtion : %@", [iRelation descriptionWithLocale:nil]); - } - if ((! [connection isConnected]) || (! [classDescription isEqual:[iRelation origin]])) { // Error condition. - return nil; - } - if (! [iRelation isToMany]) { - NSLog(@"Tried to use the -[MCPObject getTargetOfRelation:atIndex:] on a to-one relation... this does NOT works!!! You should use -[MCPObject getTargetOfRelation:] instead!!!"); - return [self getTargetOfRelation:iRelation]; - } -// Generating the query: - destinationDesc = [iRelation destination]; - keys = [destinationDesc primaryKeyAttributes]; - joins = [iRelation joins]; - ids = [destinationDesc identityAttributes]; - query = [[NSMutableString alloc] initWithString:@"SELECT "]; - for (i=0; [keys count] != i; ++i) { - if (i) { - [query appendString:@", "]; - } - [query appendString:[(MCPAttribute *)[keys objectAtIndex:i] externalName]]; - } - [query appendFormat:@" FROM %@ WHERE ", [destinationDesc externalName]]; - for (i=0; [joins count] != i; ++i) { - MCPJoin *theJoin = (MCPJoin *)[joins objectAtIndex:i]; - - if (i) { - [query appendString:@" and "]; - } - [query appendFormat:@"(%@ = %@)", [[theJoin destination] externalName], [connection quoteObject:[self valueForKey:[[theJoin origin] name]]]]; - } - [query appendString:[self orderSQLForClassDescription:destinationDesc]]; -/* - [query appendString:@" ORDER BY "]; - for (i=0; [ids count] != i; ++i) { // Generating the order : - if (i) { - [query appendString:@", "]; - } - [query appendString:[(MCPAttribute *)[ids objectAtIndex:i] externalName]]; - } -*/ - [query appendFormat:@" LIMIT 1 OFFSET %ld", iIndex]; - result = [connection queryString:query]; - [query release]; - -// Getting the results in proper objects: - theRow = [result fetchRowAsDictionary]; - if (theRow) { - theRet = (MCPObject *)[[[destinationDesc representedClass] alloc] init]; - [theRet setPrimaryKey:theRow andFetchFromDB:connection]; - [theRet autorelease]; - } - else { - theRet = nil; - } - return theRet; -} - -- (MCPObject *) getTargetOfRelationNamed:(NSString *) iRelationName atIndex:(NSUInteger) iIndex -/*"This is the equivalent of the getTargetOfRelation:atIndex:, but giving a relation name instead of the MCPRelation object itself."*/ -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self getTargetOfRelation:theRelation atIndex:iIndex]: nil; -} - -- (MCPDBReturnCode) addTarget:(MCPObject *) iTarget toRelation:(MCPRelation *) iRelation -/*" This method will modify the DB content so that the corresponding relation is added. -If any value corresping to an attribute of self i modified in the DB, then it will update all attributes of self to reflect DB status. - -Obviuosly this method is taking care of only to-many relation. It will hence check that iRelation is a to-many relation starting from self."*/ -{ - NSArray *joins; - NSUInteger i; - NSDictionary *saveReturn; - - if (! [connection isConnected]) { - return MCPDBReturnNoConnection; - } - if (! [classDescription isEqual:[iRelation origin]]) { - return MCPDBReturnWrongRelationOrigin; - } - if (! [iRelation isToMany]) { - return MCPDBReturnWrongRelationCardinality; - } - joins = [iRelation joins]; - for (i=0; [joins count] != i; ++i) { // Will change only values of iTarget, because it is a to-many relation. - MCPJoin *join = (MCPJoin *)[joins objectAtIndex:i]; - - [iTarget setValue:[self valueForKey:[[join origin] name]] forKey:[[join destination] name]]; - } - if (! [[iTarget connection] isConnected]) { - [iTarget setConnection:connection]; - } - saveReturn = [iTarget saveInDB]; - return (MCPDBReturnCode)[(NSNumber *)[saveReturn objectForKey:@"MCPDBReturnCode"] unsignedIntegerValue]; -} - -- (MCPDBReturnCode) addTarget:(MCPObject *) iTarget toRelationNamed:(NSString *) iRelationName -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self addTarget:iTarget toRelation:theRelation] : MCPDBReturnNoSuchRelation; -} - -- (MCPDBReturnCode) removeTarget:(MCPObject *) iTarget toRelation:(MCPRelation *) iRelation -/*" This method will modify the DB content so that the corresponding relation is removed. -If any value corresping to an attribute of self i modified in the DB, then it will update all attributes of self to reflect DB status. - -Obviuosly this method is taking care of only to-many relation. It will hence check that iRelation is a to-many relation starting from self."*/ -{ - NSArray *joins; - NSUInteger i; -// NSDictionary *saveReturn; - BOOL targetIsTarget = YES; - MCPDBReturnCode returnCode; - - if (! [connection isConnected]) { - return MCPDBReturnNoConnection; - } - if (! [classDescription isEqual:[iRelation origin]]) { - return MCPDBReturnWrongRelationOrigin; - } - if (! [iRelation isToMany]) { - return MCPDBReturnWrongRelationCardinality; - } - joins = [iRelation joins]; - for (i=0; [joins count] != i; ++i) { - MCPJoin *join = (MCPJoin *)[joins objectAtIndex:i]; - targetIsTarget = targetIsTarget && [[iTarget valueForKey:[[join destination] name]] isEqual:[self valueForKey:[[join origin] name]]]; - } - if (! targetIsTarget) { - return MCPDBReturnNotTarget; - } - if ([iRelation ownsDestination]) { // just delete the target from the DB. - returnCode = [iTarget deleteInDB]; - } - for (i=0; [joins count] != i; ++i) { // Put all the destination to default... - MCPJoin *join = (MCPJoin *)[joins objectAtIndex:i]; - - [iTarget setValue:[[join destination] defaultValue] forKey:[[join destination] name]]; - } - if (! [iRelation ownsDestination]) { - returnCode = [(NSNumber *)[[iTarget saveInDB] objectForKey:@"MCPDBReturnCode"] unsignedIntegerValue]; - } - return returnCode; -} - -- (MCPDBReturnCode) removeTarget:(MCPObject *) iTarget toRelationNamed:(NSString *) iRelationName -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self removeTarget:iTarget toRelation:theRelation] : MCPDBReturnNoSuchRelation; -} - -- (MCPDBReturnCode) removeTargetToRelation:(MCPRelation *) iRelation atIndex:(NSUInteger) iIndex -/*" This method will use an index t first query the object that it should remove from the relation, then uses the -[MCPObject removeTarget:toRelation:] - method to remove the object from the relation. If the index is out of bound (the returned object is nil), it will return MCPDBReturnNone, to signal - there was no object with this index in the relation."*/ -{ - MCPObject *target; - - if (! [connection isConnected]) { - return MCPDBReturnNoConnection; - } - if (! [classDescription isEqual:[iRelation origin]]) { - return MCPDBReturnWrongRelationOrigin; - } - if (! [iRelation isToMany]) { - return MCPDBReturnWrongRelationCardinality; - } - target = [self getTargetOfRelation:iRelation atIndex:iIndex]; - if (target) { - return [self removeTarget:target toRelation:iRelation]; - } - else { - return MCPDBReturnNone; - } -} - -- (MCPDBReturnCode) removeTargetToRelationNamed:(NSString *) iRelationName atIndex:(NSUInteger) iIndex -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self removeTargetToRelation:theRelation atIndex:iIndex] : MCPDBReturnNoSuchRelation; -} - -- (NSUInteger) indexOfTarget:(MCPObject *) iTarget inRelation:(MCPRelation *) iRelation -/*" Returns the index of the target object within the relation. Return NSNotFound if the objkect is NOT in the relation!!"*/ -{ - NSMutableString *query; - NSArray *joins; - NSArray *keys; - NSArray *ids; - NSUInteger i; - MCPResult *result; - NSDictionary *row; - NSMutableDictionary *targetKey; - BOOL targetIsTarget = YES; - - if ((! [connection isConnected]) || (! [classDescription isEqual:[iRelation origin]]) || (! [iRelation isToMany])) { // Checking the realtion object. - return NSNotFound; - } - query = [[NSMutableString alloc] initWithString:@"SELECT "]; - joins = [iRelation joins]; -// keys = [[iRelation destination] attributeKeys]; - keys = [[iRelation destination] primaryKeyAttributes]; - ids = [[iRelation destination] identityAttributes]; - for (i=0; [keys count] != i; ++i) { - if (i) { - [query appendString:@", "]; - } - [query appendString:[(MCPAttribute *)[keys objectAtIndex:i] externalName]]; - } - [query appendFormat:@"FROM %@ WHERE ", [[iRelation destination] externalName]]; - for (i=0; [joins count] != i; ++i) { - MCPJoin *join = (MCPJoin *)[joins objectAtIndex:i]; - - targetIsTarget = targetIsTarget && [[iTarget valueForKey:[[join destination] name]] isEqual:[self valueForKey:[[join origin] name]]]; - if (i) { - [query appendString:@" AND "]; - } - [query appendFormat:@"( %@ = %@ )", [[join destination] externalName], [connection quoteObject:[self valueForKey:[[join origin] name]]]]; - } - if (! targetIsTarget) { // Checking that iTarget belongs to the relation. - [query release]; - return NSNotFound; - } - [query appendString:[self orderSQLForClassDescription:[iRelation destination]]]; -/* - [query appendString:@" ORDER BY "]; - for (i=0; [ids count] != i; ++i) { - if (i) { - [query appendString:@", "]; - } - [query appendString:[(MCPAttribute *)[ids objectAtIndex:i] externalName]]; - } -*/ - targetKey = [[NSMutableDictionary alloc] init]; - for (i=0; [keys count] != i; ++i) { // Setting the targetKey to the row that should gives the target. - MCPAttribute *attribute = (MCPAttribute *)[keys objectAtIndex:i]; - - [targetKey setObject:[iTarget valueForKey:[attribute name]] forKey:[attribute externalName]]; - } - result = [connection queryString:query]; - [query release]; - i = 0; - while (row = [result fetchRowAsDictionary]) { - if ([targetKey isEqualToDictionary:row]) { // We have found the proper object return i (after cleaning up); - [targetKey release]; - return i; - } - ++i; - } - return NSNotFound; -} - -- (NSUInteger) indexOfTarget:(MCPObject *) iTarget inRelationNamed:(NSString *) iRelationName -/*" The equivalent of -[MCPObject indexOfTarget:inRelation:] but using relation name instead of a MCPRelation -object. Indeed after getting the MCPRelation object corresponding to the name, this method will only return -the result of the corresponding call to -[MCPObject indexOfTarget:inRelation:]."*/ -{ - MCPRelation *theRelation = [classDescription relationWithName:iRelationName]; - return (theRelation) ? [self indexOfTarget:iTarget inRelation:theRelation] : NSNotFound; -} - -#pragma mark Utility methods -- (id) defaultValueForKey:(NSString *) iKey -/*" This method will return the default value (object) for the given key."*/ -{ - MCPAttribute *theAttribute = [classDescription attributeWithName:iKey]; - - if ([theAttribute allowsNull]) { -// return [NSNull null]; - return nil; - } - else { - Class theAttrClass = [theAttribute valueClass]; - id theRet; - - if ([theAttrClass isSubclassOfClass:[NSNumber class]]) { - return [NSNumber numberWithInteger:0]; - } - theRet = [[[theAttrClass alloc] init] autorelease]; - if (nil == theRet) { - NSLog(@"in MCPObject defaultValueForKey:%@ , for object of class %@, (attribute of class %@) the return value will be nil!!!", iKey, [self className], theAttrClass); - } - return theRet; - } -} - - -- (NSDictionary *) primaryKey -/*" Returns a dictionary with the values of the primary key. "*/ -{ - NSMutableDictionary *theRet = [NSMutableDictionary dictionary]; - NSArray *theIdAttr = [classDescription primaryKeyAttributes]; - NSUInteger i; - - for (i=0; [theIdAttr count] != i; ++i) { - NSString *theKey = [(MCPAttribute *)[theIdAttr objectAtIndex:i] name]; - - if ([self valueForKey:theKey]) { - [theRet setObject:[self valueForKey:theKey] forKey:theKey]; - } - else { - [theRet setObject:[NSNull null] forKey:theKey]; - } - } - return [NSDictionary dictionaryWithDictionary:theRet]; -} - -#pragma mark Testing equality (VERY important for relation management) -- (BOOL) isEqual:(id) iObject -{ - NSArray *theIdAttr; - NSUInteger i; - BOOL theRet; - - if (self == iObject) { - return YES; - } - if ([self class] != [iObject class]) { - return NO; - } - theIdAttr = [classDescription identityAttributes]; - for (i = 0; [theIdAttr count] != i; ++i) { - MCPAttribute *theAttr = [theIdAttr objectAtIndex:i]; - - theRet = theRet && [[self valueForKey:[theAttr name]] isEqual:[iObject valueForKey:[theAttr name]]]; - } - return theRet; -} - - -#pragma mark Output -- (NSString *) description -{ - return [self descriptionWithLocale:nil]; -} - -- (NSString *) descriptionWithLocale:(NSDictionary *) locale -{ - NSMutableString *theOutput = [NSMutableString string]; - NSUInteger i; - NSArray *theAttributes = [classDescription attributes]; - BOOL trunc = [MCPConnection truncateLongField]; - - [theOutput appendFormat:@"MCPObject subclass : %@\n", [self className]]; - - for (i = 0; [theAttributes count] != i; ++i) - { - MCPAttribute *theAttribute = (MCPAttribute *) [theAttributes objectAtIndex:i]; - id theValue = [self valueForKey:[theAttribute name]]; - - if (trunc) { - if (([theValue isKindOfClass:[NSString class]]) && (kLengthOfTruncationForLog < [(NSString *)theValue length])) { - theValue = [theValue substringToIndex:kLengthOfTruncationForLog]; - } - else if (([theValue isKindOfClass:[NSData class]]) && (kLengthOfTruncationForLog < [(NSData *)theValue length])) { - theValue = [NSData dataWithBytes:[theValue bytes] length:kLengthOfTruncationForLog]; - } - } - - [theOutput appendFormat:@"\tAttribute %ld : name = %@, value = %@\n", i, [theAttribute name], theValue]; - } - - [theOutput appendString:@"\n"]; - - return theOutput; -} - -#pragma mark Ordering the array for relations -- (NSString *) orderSQLForClassDescription:(MCPClassDescription *) iClassDescription -{ - NSMutableArray *theAttributes = [[NSMutableArray alloc] initWithArray:[iClassDescription identityAttributes]]; - NSMutableString *theReturn = [NSMutableString string]; - NSUInteger i; - - for (i = 0; [[iClassDescription primaryKeyAttributes] count] != i; ++i) { - [theAttributes insertObject:[[iClassDescription primaryKeyAttributes] objectAtIndex:i] atIndex:[theAttributes count]]; - } - for (i = 0; [theAttributes count] != i; ++i) { - if (i) { - [theReturn appendString:@", "]; - } - else { - [theReturn appendString:@" ORDER BY "]; - } - [theReturn appendString:[(MCPAttribute *)[theAttributes objectAtIndex:i] externalName]]; - } - return theReturn; -} - -#pragma mark Anti-crash method... -- (void) setNilValueForKey:(NSString *) iKey -{ - NSLog(@"Try to set %@ to nil .... not possible, will set it to zero instead...", iKey); - [self setValue:[NSNumber numberWithInteger:0] forKey:iKey]; -} - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation+Private.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation+Private.h deleted file mode 100644 index 2d3a7d8d..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation+Private.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// $Id$ -// -// MCPRelation+Private.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 11/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPRelation.h" - -@interface MCPRelation (Private) - -#pragma mark Making some work -- (void) invalidateJoins; // Check that the joins are realistics. - -#pragma mark Setters -- (void) setOrigin:(MCPClassDescription *) iOrigin; -//- (void) setJoins:(NSArray *) iJoins; - -#pragma mark Getters -- (MCPModel *) model; - -#pragma mark Fro the controller layer and the UI -- (void) addNewDefaultJoin; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation.h b/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation.h deleted file mode 100644 index 118734eb..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation.h +++ /dev/null @@ -1,112 +0,0 @@ -// -// $Id$ -// -// MCPRelation.h -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 11/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import <Foundation/Foundation.h> - -@class MCPModel; -@class MCPClassDescription; -@class MCPAttribute; -@class MCPJoin; - -typedef enum { - OnDeleteNullify = 1, - OnDeleteDeny = 2, - OnDeleteCascade = 3, - OnDeleteDefault = 4, - OnDeleteNoAction = 5 -} MCPRelationDeleteRule; - -@interface MCPRelation : NSObject <NSCoding> -{ -@protected - NSString *name; // Name of the relation - MCPRelationDeleteRule deleteRule; // Delete rule : what to do of the destination when origin is deleted - MCPRelation *inverseRelation; // The inverse relation (or nil if no inverse present) - MCPClassDescription *origin; // The class description from which the relation originate - MCPClassDescription *destination; // The class description to which the relation arrives - NSMutableArray *joins; // Joining attributes (array of MCPJoin) - BOOL isToMany; // Is the relation to many (or to one) - BOOL isMandatory; // Is the relation mandatory for the class description (origin) - BOOL ownsDestination; // The origin class description owns the destination class description(ies) -} - -#pragma mark Class methods -+ (void) initialize; - -+ (NSArray *) existingDeleteRules; -- (NSArray *) existingDeleteRules; - -#pragma mark Life cycle -- (id) initWithName:(NSString *) iName from:(MCPClassDescription *) iFrom to:(MCPClassDescription *) iTo; -- (void) invalidateRelation; -- (void) dealloc; - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder; -- (void) encodeWithCoder:(NSCoder *) encoder; - -#pragma mark Managing joins -//- (MCPJoin *) addNewJoin; -- (MCPJoin *) addJoinFrom:(MCPAttribute *) iFrom to:(MCPAttribute *) iTo; -- (void) removeJoinFrom:(MCPAttribute *) iFrom to:(MCPAttribute *) iTo; -//- (void) unjoinAttribute:(MCPAttribute *) iAttribute; - -#pragma mark Setters -- (void) setDestination:(MCPClassDescription *) iDestination; -- (void) setName:(NSString *) iName; -- (void) setDeleteRule:(MCPRelationDeleteRule) iDeleteRule; -- (void) setInverseRelation:(MCPRelation *) iInverseRelation; -- (void) insertObject:(MCPJoin *) iJoin inJoinsAtIndex:(NSUInteger) index; -- (void) removeObjectFromJoinsAtIndex:(NSUInteger) index; -- (void) setIsToMany:(BOOL) iIsToMany; -- (void) setIsMandatory:(BOOL) iIsMandatory; -- (void) setOwnsDestintation:(BOOL) iOwnsDestination; - -#pragma mark Getters -- (NSString *) name; -- (MCPRelationDeleteRule) deleteRule; -- (MCPRelation *) inverseRelation; -- (MCPClassDescription *) origin; -- (MCPClassDescription *) destination; -- (NSArray *) joins; -- (NSUInteger) countOfJoins; -- (MCPJoin *) objectInJoinsAtIndex:(NSUInteger) index; -- (NSUInteger) indexOfJoinIdenticalTo:(id) iJoin; -- (BOOL) isToMany; -- (BOOL) isMandatory; -- (BOOL) ownsDestination; - -#pragma mark Some Usefull methods -- (MCPAttribute *) destinationAttributeForOrigin:(MCPAttribute *) iFrom; -- (MCPAttribute *) originAttributeForDestination:(MCPAttribute *) iTo; - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject; -- (NSString *) descriptionWithLocale:(NSDictionary *) locale; - -@end diff --git a/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation.m b/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation.m deleted file mode 100644 index 6d1e58f4..00000000 --- a/Frameworks/MCPKit/MCPEntrepriseKit/MCPRelation.m +++ /dev/null @@ -1,486 +0,0 @@ -// -// $Id$ -// -// MCPRelation.m -// MCPKit -// -// Created by Serge Cohen (serge.cohen@m4x.org) on 11/08/04. -// Copyright (c) 2004 Serge Cohen. All rights reserved. -// -// Forked by the Sequel Pro team (sequelpro.com), April 2009 -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// More info at <http://mysql-cocoa.sourceforge.net/> -// More info at <http://code.google.com/p/sequel-pro/> - -#import "MCPRelation.h" -#import "MCPRelation+Private.h" - -#import "MCPEntrepriseNotifications.h" - -#import "MCPModel.h" -#import "MCPClassDescription.h" -#import "MCPClassDescription+Private.h" -#import "MCPAttribute.h" - -#import "MCPJoin.h" - -static NSArray *MCPexistingDeleteRules; - -@implementation MCPRelation - -#pragma mark Class methods -+ (void) initialize -{ - if (self = [MCPRelation class]) { - NSMutableArray *theExistingDeleteRules = [[NSMutableArray alloc] init]; - - [self setVersion:010101]; // Ma.Mi.Re -> MaMiRe - - [theExistingDeleteRules addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:OnDeleteNullify], @"tag", @"Nullify", @"name", nil]]; - [theExistingDeleteRules addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:OnDeleteDeny], @"tag", @"Deny", @"name", nil]]; - [theExistingDeleteRules addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:OnDeleteCascade], @"tag", @"Cascade", @"name", nil]]; - [theExistingDeleteRules addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:OnDeleteDefault], @"tag", @"Default", @"name", nil]]; - [theExistingDeleteRules addObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedInteger:OnDeleteNoAction], @"tag", @"No Action", @"name", nil]]; - MCPexistingDeleteRules = [[NSArray alloc] initWithArray:theExistingDeleteRules]; - [theExistingDeleteRules release]; - } - return; -} - -+ (NSArray *) existingDeleteRules -{ - return MCPexistingDeleteRules; -} - -- (NSArray *) existingDeleteRules -{ - return [MCPRelation existingDeleteRules]; -} - - -#pragma mark Life cycle -- (id) initWithName:(NSString *) iName from:(MCPClassDescription *) iFrom to:(MCPClassDescription *) iTo -{ - self = [super init]; - if (self) { - [self setName:iName]; - [self setOrigin:iFrom]; - [self setDestination:iTo]; - joins = [[NSMutableArray alloc] init]; - } - return self; -} - -- (void) invalidateRelation -{ - [self retain]; // To be sure not to be released before the end of the method - [self invalidateJoins]; // Remove each of the joins (so that attributes get notified) -/* - [origin removeObjectFromRelationsAtIndex:[[origin relations] indexOfObjectIdenticalTo:self]]; - origin = nil; - [destination removeObjectFromIncomingsAtIndex:[[destination incomings] indexOfObjectIdenticalTo:self]]; - destination = nil; -*/ - [self setOrigin:nil]; - [self setDestination:nil]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - [self release]; -} - -- (void) dealloc -{ - [joins release]; // Should be empty by now... - [name release]; -// The inverse relation don't have an inverse relation any more... -// [inverseRelation setInverseRelation:nil]; - [self setInverseRelation:nil]; -// Other are weak references. - [super dealloc]; -} - -#pragma mark NSCoding protocol -- (id) initWithCoder:(NSCoder *) decoder -{ - self = [super init]; - if ((self) && ([decoder allowsKeyedCoding])) { - [self setName:[decoder decodeObjectForKey:@"MCPname"]]; - [self setDeleteRule:(MCPRelationDeleteRule)[decoder decodeInt32ForKey:@"MCPdeleteRule"]]; - if ([decoder containsValueForKey:@"MCPinverseRelation"]) { - [self setInverseRelation:[decoder decodeObjectForKey:@"MCPinverseRelation"]]; - } - else { - [self setInverseRelation:nil]; - } - [self setOrigin:[decoder decodeObjectForKey:@"MCPorigin"]]; - [self setDestination:[decoder decodeObjectForKey:@"MCPdestination"]]; -// [self setJoins:[decoder decodeObjectForKey:@"MCPjoins"]]; - joins = [[NSMutableArray alloc] initWithArray:[decoder decodeObjectForKey:@"MCPjoins"]]; - [self setIsToMany:[decoder decodeBoolForKey:@"MCPisToMany"]]; - [self setIsMandatory:[decoder decodeBoolForKey:@"MCPisMandatory"]]; - [self setOwnsDestintation:[decoder decodeBoolForKey:@"MCPownsDestination"]]; - } - - return self; -} - -- (void) encodeWithCoder:(NSCoder *) encoder -{ - if (! [encoder allowsKeyedCoding]) { - NSLog(@"In MCPRelation -encodeWithCoder : Unable to encode to a non-keyed encoder!!, will not perform encoding!!"); - return; - } - [encoder encodeObject:[self name] forKey:@"MCPname"]; - [encoder encodeInt32:(int32_t)[self deleteRule] forKey:@"MCPdeleteRule"]; - if ([self inverseRelation]) { - [encoder encodeObject:[self inverseRelation] forKey:@"MCPinverseRelation"]; - } - [encoder encodeObject:[self origin] forKey:@"MCPorigin"]; - [encoder encodeObject:[self destination] forKey:@"MCPdestination"]; - [encoder encodeObject:[self joins] forKey:@"MCPjoins"]; - [encoder encodeBool:[self isToMany] forKey:@"MCPisToMany"]; - [encoder encodeBool:[self isMandatory] forKey:@"MCPisMandatory"]; - [encoder encodeBool:[self ownsDestination] forKey:@"MCPownsDestination"]; -} - -#pragma mark Making new joins -/* -- (MCPJoin *) addNewJoin // Usefull for the interface, to be able to create a new join by just using a binding. -{ - [self addJoinFrom:[origin objectInAttributesAtIndex:0] to:[destination objectInAttributesAtIndex:0]]; -} -*/ - -- (MCPJoin *) addJoinFrom:(MCPAttribute *) iFrom to:(MCPAttribute *) iTo -{ - MCPJoin *theJoin; - - if ([iFrom classDescription] != [self origin]) { - NSLog(@"Tried to make a join starting from an attribute (%@) that does NOT belong to the origin class description (%@)! Will not perform the link", iFrom, [self origin]); - return nil; - } - if ([iTo classDescription] != [self destination]) { - NSLog(@"Tried to make a join arriving to an attribute (%@) that does NOT belong to the destination class description (%@)! Will not perform the link", iTo, [self destination]); - return nil; - } - theJoin = [[MCPJoin alloc] initForRelation:self from:iFrom to:iTo]; -// theJoin = [[MCPJoin alloc] initFrom:iFrom to:iTo]; -// [joins addObject:theJoin]; - [joins insertObject:theJoin atIndex:[joins count]]; - [theJoin release]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - return theJoin; -} - -- (void) removeJoinFrom:(MCPAttribute *) iFrom to:(MCPAttribute *) iTo -{ - NSDictionary *theJoinDict = [[NSDictionary alloc] initWithObjectsAndKeys:self, @"relation", iFrom, @"origin", iTo, @"destination", nil]; - NSUInteger i = [joins indexOfObject:theJoinDict]; - - if (NSNotFound != i) { - [[self objectInJoinsAtIndex:i] invalidate]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } - [theJoinDict release]; -} - -/* -- (void) unjoinAttribute:(MCPAttribute *) iAttribute -{ - unsigned int i = 0; - -#warning HAVE to rewrite this code!!! - if ([[iAttribute classDescription] isEqual:origin]) { - for (i=0; ([joins count] != i) && ([iAttribute isEqual:[(MCPJoin *)[joins objectAtIndex:i] origin]]); ++i) { - } - } - if ([[iAttribute classDescription] isEqual:destination]) { - for (i=0; ([joins count] != i) && ([iAttribute isEqual:[(MCPJoin *)[joins objectAtIndex:i] destination]]); ++i) { - } - } - if ((0 == i) || ([joins count] == i)) { // No joins found using this attribute. - return; - } - [self removeJoinFrom:[(MCPJoin *)[joins objectAtIndex:i] origin] to:[(MCPJoin *)[joins objectAtIndex:i] destination]]; -} -*/ - -#pragma mark Setters -- (void) setDestination:(MCPClassDescription *) iDestination -{ - if (iDestination != destination) { - [destination removeObjectFromIncomingsAtIndex:[[destination incomings] indexOfObjectIdenticalTo:self]]; - destination = iDestination; - [destination insertObject:self inIncomingsAtIndex:0]; - [self invalidateJoins]; - } -} - - -- (void) setName:(NSString *) iName -{ - if (iName != name) { - [name release]; - name = [iName retain]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[origin model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:origin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} - -- (void) setDeleteRule:(MCPRelationDeleteRule) iDeleteRule -{ - if (iDeleteRule != deleteRule) { // Don't do the notification for nothing!!! - deleteRule = iDeleteRule; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[origin model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:origin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} - -- (void) setInverseRelation:(MCPRelation *) iInverseRelation -{ - if (iInverseRelation != inverseRelation) { - [inverseRelation release]; - inverseRelation = [iInverseRelation retain]; - [inverseRelation setInverseRelation:self]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[origin model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:origin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} - -- (void) insertObject:(MCPJoin *) iJoin inJoinsAtIndex:(NSUInteger) index -{ - [joins insertObject:iJoin atIndex:index]; -} - -- (void) removeObjectFromJoinsAtIndex:(NSUInteger) index -{ - [joins removeObjectAtIndex:index]; -} - -- (void) setIsToMany:(BOOL) iIsToMany -{ - if (iIsToMany != isToMany) { // Don't do the notification for nothing!!! - isToMany = iIsToMany; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[origin model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:origin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} - -- (void) setIsMandatory:(BOOL) iIsMandatory -{ - if (iIsMandatory != isMandatory) { // Don't do the notification for nothing!!! - isMandatory = iIsMandatory; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[origin model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:origin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} - -- (void) setOwnsDestintation:(BOOL) iOwnsDestination -{ - if (iOwnsDestination != ownsDestination) { // Don't do the notification for nothing!!! - ownsDestination = iOwnsDestination; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPModelChangedNotification object:[origin model]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPClassDescriptionChangedNotification object:origin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} - -#pragma mark Getters -- (NSString *) name -{ - return name; -} - -- (MCPRelationDeleteRule) deleteRule -{ - return deleteRule; -} - -- (MCPRelation *) inverseRelation -{ - return inverseRelation; -} - -- (MCPClassDescription *) origin -{ - return origin; -} - -- (MCPClassDescription *) destination -{ - return destination; -} - -- (NSArray *) joins -{ - return [NSArray arrayWithArray:joins]; -} - -- (NSUInteger) countOfJoins -{ - return [joins count]; -} - -- (MCPJoin *) objectInJoinsAtIndex:(NSUInteger) index -{ - return (MCPJoin *)((NSNotFound != index) ? [joins objectAtIndex:index] : nil); -} - -- (NSUInteger) indexOfJoinIdenticalTo:(id) iJoin -{ - return [joins indexOfObjectIdenticalTo:iJoin]; -} - -- (BOOL) isToMany -{ - return isToMany; -} - -- (BOOL) isMandatory -{ - return isMandatory; -} - -- (BOOL) ownsDestination -{ - return ownsDestination; -} - -#pragma mark Some Usefull methods - -- (MCPAttribute *) destinationAttributeForOrigin:(MCPAttribute *) iFrom -{ - NSUInteger i; - - for (i=0; ([joins count] != i) && ([[(MCPJoin *)[joins objectAtIndex:i] origin] isEqual:iFrom]); ++i) { - } - return ([joins count] == i) ? nil : [(MCPJoin *)[joins objectAtIndex:i] destination]; -} - -- (MCPAttribute *) originAttributeForDestination:(MCPAttribute *) iTo -{ - NSUInteger i; - - for (i=0; ([joins count] != i) && ([[(MCPJoin *)[joins objectAtIndex:i] destination] isEqual:iTo]); ++i) { - } - return ([joins count] == i) ? nil : [(MCPJoin *)[joins objectAtIndex:i] origin]; -} - - -#pragma mark Some general methods: -- (BOOL) isEqual:(id) iObject -// Equal to another relation, if they have the same name and same origin and destination class descriptions (they have the same names). -// Equal to a string (NSString), if the name of the relation is equal to the string. -{ - if ([iObject isKindOfClass:[MCPRelation class]]) { - MCPRelation *theRelation = (MCPRelation *) iObject; - - return ([name isEqualToString:[theRelation name]]) && ([[self origin] isEqual:[theRelation origin]]) && ([[self destination] isEqual:[theRelation destination]]); - } - if ([iObject isKindOfClass:[NSString class]]) { - return [name isEqualToString:(NSString *)iObject]; - } - return NO; -} - -- (NSString *) descriptionWithLocale:(NSDictionary *) locale -{ - NSMutableString *theRet = [NSMutableString stringWithFormat:@"MCPRelation named %@, going from %@ to %@. Joins :\n", name, [origin name], [destination name]]; - NSUInteger i; - - for (i = 0; [joins count] != i; ++i) { - MCPJoin *tmpJoin = (MCPJoin *)[joins objectAtIndex:i]; - [theRet appendFormat:@"\t\t%@ == %@\n", [[tmpJoin origin] name], [[tmpJoin destination] name]]; - } - return theRet; -} - - -#pragma mark For debugging the retain counting -- (id) retain -{ - [super retain]; - return self; -} - -- (void) release -{ - [super release]; - return; -} - -@end - -@implementation MCPRelation (Private) - -#pragma mark Making some work -- (void) invalidateJoins -{ - while ([joins count]) { - [[self objectInJoinsAtIndex:0] invalidate]; - } - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; -} - -#pragma mark Setters -- (void) setOrigin:(MCPClassDescription *) iOrigin -{ - if (iOrigin != origin) { - [origin removeObjectFromRelationsAtIndex:[[origin relations] indexOfObjectIdenticalTo:self]]; - origin = iOrigin; - [origin insertObject:self inRelationsAtIndex:[origin countOfRelations]]; - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - [self invalidateJoins]; - } -} - -/* -- (void) setJoins:(NSArray *) iJoins -{ - if (iJoins != joins) { - unsigned int i; - if (joins) { - [self invalidateJoins]; - } - else { - joins = [[NSMutableArray alloc] init]; - } - for (i=0; [iJoins count] != i; ++i) { - [self addJoinFrom:[(MCPJoin *)[iJoins objectAtIndex:i] origin] to:[(MCPJoin *)[iJoins objectAtIndex:i] destination]]; - } - [[NSNotificationCenter defaultCenter] postNotificationName:MCPRelationChangedNotification object:self]; - } -} -*/ - -#pragma mark Getters -- (MCPModel *) model -{ - return [origin model]; -} - -#pragma mark Fro the controller layer and the UI -- (void) addNewDefaultJoin // Usefull for the interface, to be able to create a new join by just using a binding. -{ - [self addJoinFrom:[origin objectInAttributesAtIndex:0] to:[destination objectInAttributesAtIndex:0]]; -} - -@end |