mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-02-14 23:51:40 +00:00
get rid of RCSID/RCS_ID as shortly discussed with David and Manuel git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@37928 72102866-910b-0410-8b05-ffd578937521
866 lines
21 KiB
Objective-C
866 lines
21 KiB
Objective-C
/**
|
|
EOSchemaGeneration.m <title>EOSchemaGeneration Class</title>
|
|
|
|
Copyright (C) 2006 Free Software Foundation, Inc.
|
|
|
|
Author: David Ayers <ayers@fsfe.org>
|
|
Date: February 2006
|
|
|
|
$Revision: 23653 $
|
|
$Date: 2006-09-28 17:25:30 +0200 (Don, 28 Sep 2006) $
|
|
|
|
<abstract></abstract>
|
|
|
|
This file is part of the GNUstep Database Library.
|
|
|
|
<license>
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 3 of the License, or (at your option) any later version.
|
|
|
|
This library 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
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with this library; see the file COPYING.LIB.
|
|
If not, write to the Free Software Foundation,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
</license>
|
|
**/
|
|
|
|
#include "config.h"
|
|
|
|
#include <string.h>
|
|
|
|
#ifdef GNUSTEP
|
|
#include <Foundation/NSEnumerator.h>
|
|
#include <Foundation/NSDictionary.h>
|
|
#include <Foundation/NSNotification.h>
|
|
#include <Foundation/NSString.h>
|
|
#else
|
|
#include <Foundation/Foundation.h>
|
|
#endif
|
|
|
|
#ifndef GNUSTEP
|
|
#include <GNUstepBase/GNUstep.h>
|
|
#include <GNUstepBase/GSObjCRuntime.h>
|
|
#include <GNUstepBase/NSDebug+GNUstepBase.h>
|
|
#include <GNUstepBase/NSObject+GNUstepBase.h>
|
|
#endif
|
|
|
|
#include <EOControl/EODebug.h>
|
|
|
|
#include <EOAccess/EOModel.h>
|
|
#include <EOAccess/EOEntity.h>
|
|
#include <EOAccess/EOAttribute.h>
|
|
#include <EOAccess/EORelationship.h>
|
|
#include <EOAccess/EOAdaptor.h>
|
|
#include <EOAccess/EOAdaptorContext.h>
|
|
#include <EOAccess/EOAdaptorChannel.h>
|
|
#include <EOAccess/EOJoin.h>
|
|
#include <EOAccess/EOSchemaGeneration.h>
|
|
|
|
NSString *EOCreateTablesKey = @"EOCreateTablesKey";
|
|
NSString *EODropTablesKey = @"EODropTablesKey";
|
|
NSString *EOCreatePrimaryKeySupportKey = @"EOCreatePrimaryKeySupportKey";
|
|
NSString *EODropPrimaryKeySupportKey = @"EODropPrimaryKeySupportKey";
|
|
NSString *EOPrimaryKeyConstraintsKey = @"EOPrimaryKeyConstraintsKey";
|
|
NSString *EOForeignKeyConstraintsKey = @"EOForeignKeyConstraintsKey";
|
|
NSString *EOCreateDatabaseKey = @"EOCreateDatabaseKey";
|
|
NSString *EODropDatabaseKey = @"EODropDatabaseKey";
|
|
|
|
|
|
@implementation EOSQLExpression (EOSchemaGeneration)
|
|
|
|
+ (NSArray *)_administrativeDatabaseStatementsForSelector:(SEL) sel
|
|
forEntityGroup:(NSArray *)group
|
|
{
|
|
EOEntity *entity;
|
|
EOModel *model;
|
|
NSDictionary *connDict;
|
|
NSDictionary *admDict;
|
|
NSArray *stmts;
|
|
NSString *notifName;
|
|
NSMutableDictionary *notifDict;
|
|
|
|
entity = [group lastObject];
|
|
model = [entity model];
|
|
connDict = [model connectionDictionary];
|
|
|
|
notifDict = (id)[NSMutableDictionary dictionaryWithCapacity: 2];
|
|
[notifDict setObject: model forKey: EOModelKey];
|
|
notifName = EOAdministrativeConnectionDictionaryNeededNotification;
|
|
[[NSNotificationCenter defaultCenter] postNotificationName: notifName
|
|
object: notifDict];
|
|
admDict = [notifDict objectForKey: EOAdministrativeConnectionDictionaryKey];
|
|
/* TODO: ayers
|
|
if (admDict == nil && [admDict count] == 0)
|
|
{
|
|
EOAdaptor *adaptor;
|
|
EOLoginPanel *panel;
|
|
|
|
adaptor = [EOAdaptor adaptorWithModel: model];
|
|
panel = [[adaptor class] sharedLoginPanelInstance];
|
|
admDict = [panel administrativeConnectionDictionaryForAdaptor: adaptor];
|
|
}
|
|
*/
|
|
stmts = [self performSelector: sel
|
|
withObject: connDict
|
|
withObject: admDict];
|
|
|
|
return stmts;
|
|
}
|
|
|
|
+ (NSArray *)_dropDatabaseStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *cumStmts;
|
|
NSArray *stmts;
|
|
NSArray *group;
|
|
unsigned i,n;
|
|
SEL sel;
|
|
|
|
sel = @selector(dropDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:);
|
|
|
|
n = [entityGroups count];
|
|
cumStmts = [NSMutableArray arrayWithCapacity: n];
|
|
|
|
for (i=0; i<n; i++)
|
|
{
|
|
EOSQLExpression *expr;
|
|
unsigned j,m;
|
|
|
|
group = [entityGroups objectAtIndex: i];
|
|
stmts = [self _administrativeDatabaseStatementsForSelector: sel
|
|
forEntityGroup: group];
|
|
for (j=0, m=[stmts count]; j<m; j++)
|
|
{
|
|
NSArray *rawStmts;
|
|
NSString *stmt;
|
|
|
|
rawStmts = [cumStmts valueForKey:@"statement"];
|
|
expr = [stmts objectAtIndex: j];
|
|
stmt = [expr statement];
|
|
|
|
if ([rawStmts containsObject: stmt] == NO)
|
|
{
|
|
[cumStmts addObject: expr];
|
|
}
|
|
}
|
|
}
|
|
|
|
return [NSArray arrayWithArray: cumStmts];
|
|
}
|
|
|
|
+ (NSArray *)_createDatabaseStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *cumStmts;
|
|
NSArray *stmts;
|
|
NSArray *group;
|
|
unsigned i,n;
|
|
SEL sel;
|
|
|
|
sel = @selector(createDatabaseStatementsForConnectionDictionary:administrativeConnectionDictionary:);
|
|
|
|
n = [entityGroups count];
|
|
cumStmts = [NSMutableArray arrayWithCapacity: n];
|
|
|
|
for (i=0; i<n; i++)
|
|
{
|
|
EOSQLExpression *expr;
|
|
unsigned j,m;
|
|
|
|
group = [entityGroups objectAtIndex: i];
|
|
stmts = [self _administrativeDatabaseStatementsForSelector: sel
|
|
forEntityGroup: group];
|
|
|
|
for (j=0, m=[stmts count]; j<m; j++)
|
|
{
|
|
NSArray *rawStmts;
|
|
NSString *stmt;
|
|
|
|
rawStmts = [cumStmts valueForKey:@"statement"];
|
|
expr = [stmts objectAtIndex: j];
|
|
stmt = [expr statement];
|
|
|
|
if ([rawStmts containsObject: stmt] == NO)
|
|
{
|
|
[cumStmts addObject: expr];
|
|
}
|
|
}
|
|
}
|
|
|
|
return [NSArray arrayWithArray: cumStmts];
|
|
}
|
|
|
|
+ (NSArray *)foreignKeyConstraintStatementsForRelationship: (EORelationship *)relationship
|
|
{
|
|
NSMutableArray *array, *sourceColumns, *destColumns;
|
|
EOSQLExpression *sqlExpression;
|
|
EOEntity *entity;
|
|
NSEnumerator *joinEnum;
|
|
EOJoin *join;
|
|
unsigned num;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: 1];
|
|
|
|
if ([[relationship entity] model]
|
|
!= [[relationship destinationEntity] model])
|
|
{
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
if ([relationship isToMany] == YES
|
|
|| ([relationship inverseRelationship] != nil
|
|
&& [[relationship inverseRelationship] isToMany] == NO))
|
|
{
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
entity = [relationship entity];
|
|
sqlExpression = [self sqlExpressionWithEntity: entity];
|
|
|
|
num = [[relationship joins] count];
|
|
|
|
sourceColumns = [NSMutableArray arrayWithCapacity: num];
|
|
destColumns = [NSMutableArray arrayWithCapacity: num];
|
|
|
|
joinEnum = [[relationship joins] objectEnumerator];
|
|
while ((join = [joinEnum nextObject]))
|
|
{
|
|
[sourceColumns addObject: [join sourceAttribute]];
|
|
[destColumns addObject: [join destinationAttribute]];
|
|
}
|
|
|
|
[sqlExpression prepareConstraintStatementForRelationship: relationship
|
|
sourceColumns: sourceColumns
|
|
destinationColumns: destColumns];
|
|
|
|
[array addObject: sqlExpression];
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray *)foreignKeyConstraintStatementsForEntityGroup:(NSArray *)entityGroup
|
|
{
|
|
NSMutableArray *sqlExps;
|
|
EORelationship *rel;
|
|
EOEntity *entity;
|
|
EOEntity *parentEntity;
|
|
unsigned i,j,n,m;
|
|
|
|
|
|
|
|
sqlExps = [NSMutableArray array];
|
|
|
|
for (i=0, n=[entityGroup count]; i<n; i++)
|
|
{
|
|
NSArray *rels;
|
|
|
|
entity = [entityGroup objectAtIndex: i];
|
|
parentEntity = [entity parentEntity];
|
|
rels = [entity relationships];
|
|
|
|
for (j=0, m=[rels count]; parentEntity == nil && j<m; j++)
|
|
{
|
|
NSArray *stmts;
|
|
|
|
rel = [rels objectAtIndex: j];
|
|
stmts =[self foreignKeyConstraintStatementsForRelationship: rel];
|
|
[sqlExps addObjectsFromArray: stmts];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return sqlExps;
|
|
}
|
|
|
|
+ (NSArray *)foreignKeyConstraintStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *array;
|
|
NSEnumerator *groupsEnum;
|
|
NSArray *group;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: [entityGroups count]];
|
|
|
|
groupsEnum = [entityGroups objectEnumerator];
|
|
while ((group = [groupsEnum nextObject]))
|
|
{
|
|
NSArray *stmts;
|
|
|
|
stmts = [self foreignKeyConstraintStatementsForEntityGroup: group];
|
|
[array addObjectsFromArray: stmts];
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
// default implementation verifies that relationship joins on foreign key
|
|
// of destination and calls
|
|
// prepareConstraintStatementForRelationship:sourceColumns:destinationColumns:
|
|
|
|
+ (NSArray *)createTableStatementsForEntityGroup: (NSArray *)entityGroup
|
|
{
|
|
EOSQLExpression *sqlExp;
|
|
NSEnumerator *entityEnum, *attrEnum;
|
|
EOAttribute *attr;
|
|
EOEntity *entity;
|
|
NSString *tableName;
|
|
NSString *stmt;
|
|
|
|
|
|
|
|
if ([[entityGroup objectAtIndex:0] isAbstractEntity])
|
|
return [NSArray array];
|
|
|
|
sqlExp = [self sqlExpressionWithEntity:[entityGroup objectAtIndex: 0]];
|
|
|
|
entityEnum = [entityGroup objectEnumerator];
|
|
while ((entity = [entityEnum nextObject]))
|
|
{
|
|
attrEnum = [[entity attributes] objectEnumerator];
|
|
|
|
while ((attr = [attrEnum nextObject]))
|
|
[sqlExp addCreateClauseForAttribute: attr];
|
|
}
|
|
|
|
entity = [entityGroup objectAtIndex: 0];
|
|
tableName = [entity externalName];
|
|
tableName = [sqlExp sqlStringForSchemaObjectName: tableName];
|
|
|
|
stmt = [NSString stringWithFormat: @"CREATE TABLE %@ (%@)",
|
|
tableName,
|
|
[sqlExp listString]];
|
|
[sqlExp setStatement: stmt];
|
|
|
|
|
|
|
|
return [NSArray arrayWithObject: sqlExp];
|
|
}
|
|
|
|
+ (NSArray *)dropTableStatementsForEntityGroup:(NSArray *)entityGroup
|
|
{
|
|
NSArray *newArray;
|
|
NSString *tableName;
|
|
EOEntity *entity;
|
|
NSString *stmt;
|
|
EOSQLExpression *sqlExp;
|
|
|
|
|
|
|
|
entity = [entityGroup objectAtIndex: 0];
|
|
|
|
if ([entity isAbstractEntity])
|
|
return [NSArray array];
|
|
|
|
sqlExp = [self sqlExpressionWithEntity: entity];
|
|
tableName = [entity externalName];
|
|
tableName = [sqlExp sqlStringForSchemaObjectName: tableName];
|
|
|
|
stmt = [NSString stringWithFormat: @"DROP TABLE %@", tableName];
|
|
[sqlExp setStatement: stmt];
|
|
newArray = [NSArray arrayWithObject: sqlExp];
|
|
|
|
|
|
|
|
return newArray;
|
|
}
|
|
|
|
+ (NSArray *)primaryKeyConstraintStatementsForEntityGroup:(NSArray *)entityGroup
|
|
{
|
|
EOSQLExpression *sqlExp;
|
|
NSMutableString *listString;
|
|
NSEnumerator *attrEnum;
|
|
EOAttribute *attr;
|
|
EOEntity *entity;
|
|
NSString *tableName;
|
|
NSString *stmt;
|
|
BOOL first = YES;
|
|
|
|
|
|
|
|
entity = [entityGroup objectAtIndex: 0];
|
|
listString = [NSMutableString stringWithCapacity: 30];
|
|
|
|
attrEnum = [[entity primaryKeyAttributes] objectEnumerator];
|
|
while ((attr = [attrEnum nextObject]))
|
|
{
|
|
NSString *columnName = [attr columnName];
|
|
|
|
if (!columnName || ![columnName length])
|
|
continue;
|
|
|
|
if (first == NO)
|
|
[listString appendString: @", "];
|
|
|
|
[listString appendString: columnName];
|
|
first = NO;
|
|
}
|
|
|
|
if (first == YES)
|
|
{
|
|
|
|
|
|
return [NSArray array];
|
|
}
|
|
|
|
sqlExp = [self sqlExpressionWithEntity:[entityGroup objectAtIndex: 0]];
|
|
tableName = [entity externalName];
|
|
tableName = [sqlExp sqlStringForSchemaObjectName: tableName];
|
|
|
|
stmt = [NSString stringWithFormat: @"ALTER TABLE %@ ADD PRIMARY KEY (%@)",
|
|
tableName, listString];
|
|
[sqlExp setStatement: stmt];
|
|
|
|
|
|
|
|
return [NSArray arrayWithObject: sqlExp];
|
|
}
|
|
|
|
+ (NSArray *)primaryKeySupportStatementsForEntityGroup: (NSArray *)entityGroup
|
|
{
|
|
NSArray *newArray;
|
|
NSString *seqName;
|
|
EOEntity *entity;
|
|
NSString *pkRootName;
|
|
NSString *stmt;
|
|
EOSQLExpression *sqlExp;
|
|
|
|
|
|
|
|
entity = [entityGroup objectAtIndex: 0];
|
|
|
|
if ([entity isAbstractEntity])
|
|
return [NSArray array];
|
|
|
|
pkRootName = [entity primaryKeyRootName];
|
|
seqName = [NSString stringWithFormat: @"%@_SEQ", pkRootName];
|
|
|
|
sqlExp = [self sqlExpressionWithEntity: nil];
|
|
seqName = [sqlExp sqlStringForSchemaObjectName: seqName];
|
|
|
|
stmt = [NSString stringWithFormat: @"CREATE SEQUENCE %@", seqName];
|
|
[sqlExp setStatement: stmt];
|
|
newArray = [NSArray arrayWithObject: sqlExp];
|
|
|
|
|
|
|
|
return newArray;
|
|
}
|
|
|
|
+ (NSArray *)dropPrimaryKeySupportStatementsForEntityGroup: (NSArray *)entityGroup
|
|
{
|
|
NSArray *newArray;
|
|
NSString *seqName;
|
|
EOEntity *entity;
|
|
NSString *pkRootName;
|
|
NSString *stmt;
|
|
EOSQLExpression *sqlExp;
|
|
|
|
|
|
|
|
entity = [entityGroup objectAtIndex: 0];
|
|
|
|
if ([entity isAbstractEntity])
|
|
return [NSArray array];
|
|
|
|
pkRootName = [entity primaryKeyRootName];
|
|
seqName = [NSString stringWithFormat: @"%@_SEQ", pkRootName];
|
|
|
|
sqlExp = [self sqlExpressionWithEntity: nil];
|
|
seqName = [sqlExp sqlStringForSchemaObjectName: seqName];
|
|
|
|
stmt = [NSString stringWithFormat: @"DROP SEQUENCE %@", seqName];
|
|
[sqlExp setStatement: stmt];
|
|
newArray = [NSArray arrayWithObject: sqlExp];
|
|
|
|
|
|
|
|
return newArray;
|
|
}
|
|
|
|
+ (NSArray *)createTableStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *array;
|
|
NSEnumerator *groupsEnum;
|
|
NSArray *group;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: [entityGroups count]];
|
|
|
|
groupsEnum = [entityGroups objectEnumerator];
|
|
while ((group = [groupsEnum nextObject]))
|
|
{
|
|
[array addObjectsFromArray:
|
|
[self createTableStatementsForEntityGroup: group]];
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray *)dropTableStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *array;
|
|
NSEnumerator *groupsEnum;
|
|
NSArray *group;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: [entityGroups count]];
|
|
|
|
groupsEnum = [entityGroups objectEnumerator];
|
|
while ((group = [groupsEnum nextObject]))
|
|
{
|
|
[array addObjectsFromArray:
|
|
[self dropTableStatementsForEntityGroup: group]];
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray *)primaryKeyConstraintStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *array;
|
|
NSEnumerator *groupsEnum;
|
|
NSArray *group;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: [entityGroups count]];
|
|
|
|
groupsEnum = [entityGroups objectEnumerator];
|
|
while ((group = [groupsEnum nextObject]))
|
|
{
|
|
[array addObjectsFromArray:
|
|
[self primaryKeyConstraintStatementsForEntityGroup: group]];
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray *)primaryKeySupportStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *array;
|
|
NSEnumerator *groupsEnum;
|
|
NSArray *group;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: [entityGroups count]];
|
|
|
|
groupsEnum = [entityGroups objectEnumerator];
|
|
while ((group = [groupsEnum nextObject]))
|
|
{
|
|
[array addObjectsFromArray:
|
|
[self primaryKeySupportStatementsForEntityGroup: group]];
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (NSArray *)dropPrimaryKeySupportStatementsForEntityGroups: (NSArray *)entityGroups
|
|
{
|
|
NSMutableArray *array;
|
|
NSEnumerator *groupsEnum;
|
|
NSArray *group;
|
|
|
|
|
|
|
|
array = [NSMutableArray arrayWithCapacity: [entityGroups count]];
|
|
|
|
groupsEnum = [entityGroups objectEnumerator];
|
|
while ((group = [groupsEnum nextObject]))
|
|
{
|
|
[array addObjectsFromArray:
|
|
[self dropPrimaryKeySupportStatementsForEntityGroup: group]];
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
+ (void)appendExpression: (EOSQLExpression *)expression
|
|
toScript: (NSMutableString *)script
|
|
{
|
|
|
|
|
|
[script appendFormat:@"%@;\n", [expression statement]];
|
|
|
|
|
|
}
|
|
|
|
|
|
+ (NSString *)schemaCreationScriptForEntities: (NSArray *)entities
|
|
options: (NSDictionary *)options
|
|
{
|
|
NSMutableString *script = [NSMutableString stringWithCapacity:50];
|
|
NSEnumerator *arrayEnum;
|
|
EOSQLExpression *sqlExp;
|
|
|
|
|
|
|
|
arrayEnum = [[self schemaCreationStatementsForEntities: entities
|
|
options: options] objectEnumerator];
|
|
|
|
while ((sqlExp = [arrayEnum nextObject]))
|
|
[self appendExpression: sqlExp toScript: script];
|
|
|
|
|
|
|
|
return script;
|
|
}
|
|
|
|
struct _schema
|
|
{
|
|
NSString *key;
|
|
NSString *value;
|
|
SEL selector;
|
|
};
|
|
|
|
+ (NSArray *)schemaCreationStatementsForEntities: (NSArray *)entities
|
|
options: (NSDictionary *)options
|
|
{
|
|
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 5];
|
|
NSMutableArray *groups = [NSMutableArray arrayWithCapacity: 5];
|
|
NSMutableArray *group;
|
|
NSString *externalName;
|
|
EOEntity *entity;
|
|
int i, h, count;
|
|
struct _schema defaults[] = {
|
|
{EODropPrimaryKeySupportKey , @"YES",
|
|
@selector(dropPrimaryKeySupportStatementsForEntityGroups:)},
|
|
{EODropTablesKey , @"YES",
|
|
@selector(dropTableStatementsForEntityGroups:)},
|
|
{EODropDatabaseKey , @"NO",
|
|
@selector(_dropDatabaseStatementsForEntityGroups:)},
|
|
{EOCreateDatabaseKey , @"NO",
|
|
@selector(_createDatabaseStatementsForEntityGroups:)},
|
|
{EOCreateTablesKey , @"YES",
|
|
@selector(createTableStatementsForEntityGroups:)},
|
|
{EOCreatePrimaryKeySupportKey, @"YES",
|
|
@selector(primaryKeySupportStatementsForEntityGroups:)},
|
|
{EOPrimaryKeyConstraintsKey , @"YES",
|
|
@selector(primaryKeyConstraintStatementsForEntityGroups:)},
|
|
{EOForeignKeyConstraintsKey , @"NO",
|
|
@selector(foreignKeyConstraintStatementsForEntityGroups:)},
|
|
{nil, nil},
|
|
}; // Order is important!
|
|
|
|
|
|
|
|
count = [entities count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
entity = [entities objectAtIndex: i];
|
|
externalName = [entity externalName];
|
|
|
|
group = [NSMutableArray arrayWithCapacity: 1];
|
|
[groups addObject: group];
|
|
[group addObject: entity];
|
|
|
|
for (h = i + 1; h < count; h++)
|
|
{
|
|
if ([[[entities objectAtIndex: h] externalName]
|
|
isEqual: externalName])
|
|
[group addObject: [entities objectAtIndex: h]];
|
|
}
|
|
}
|
|
|
|
for (i = 0; defaults[i].key != nil; i++)
|
|
{
|
|
NSString *value;
|
|
|
|
value = [options objectForKey: defaults[i].key];
|
|
|
|
if (!value)
|
|
value = defaults[i].value;
|
|
|
|
if ([value isEqual: @"YES"] == YES)
|
|
{
|
|
NSArray *stmts;
|
|
stmts = [self performSelector: defaults[i].selector
|
|
withObject: groups];
|
|
[array addObjectsFromArray: stmts];
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return array;
|
|
}
|
|
|
|
- (NSString *)columnTypeStringForAttribute:(EOAttribute *)attribute
|
|
{
|
|
NSString *extType = [attribute externalType];
|
|
int precision = [attribute precision];
|
|
|
|
|
|
|
|
if (precision)
|
|
{
|
|
|
|
return [NSString stringWithFormat:@"%@(%d, %d)", extType, precision,
|
|
[attribute scale]];
|
|
}
|
|
else if ([attribute width])
|
|
{
|
|
|
|
return [NSString stringWithFormat: @"%@(%d)",
|
|
extType, [attribute width]];
|
|
}
|
|
else
|
|
{
|
|
|
|
return [NSString stringWithFormat: @"%@", extType];
|
|
}
|
|
}
|
|
|
|
- (NSString *)allowsNullClauseForConstraint: (BOOL)allowsNull
|
|
{
|
|
if (allowsNull == NO)
|
|
return @"NOT NULL";
|
|
|
|
return nil;
|
|
}
|
|
|
|
- (void)addCreateClauseForAttribute: (EOAttribute *)attribute
|
|
{
|
|
NSString *columnType;
|
|
NSString *allowsNull;
|
|
NSString *str;
|
|
|
|
|
|
|
|
columnType = [self columnTypeStringForAttribute: attribute];
|
|
allowsNull = [self allowsNullClauseForConstraint: [attribute allowsNull]];
|
|
|
|
if (allowsNull)
|
|
str = [NSString stringWithFormat: @"%@ %@ %@", [attribute columnName],
|
|
columnType, allowsNull];
|
|
else
|
|
str = [NSString stringWithFormat: @"%@ %@", [attribute columnName],
|
|
columnType];
|
|
|
|
[self appendItem:str toListString: /*_listString*/[self listString]]; // Else no chance to get inited (lazy)
|
|
|
|
|
|
}
|
|
|
|
- (void)prepareConstraintStatementForRelationship: (EORelationship *)relationship
|
|
sourceColumns: (NSArray *)sourceColumns
|
|
destinationColumns: (NSArray *)destinationColumns
|
|
{
|
|
NSMutableString *sourceString, *destinationString;
|
|
NSEnumerator *attrEnum;
|
|
EOAttribute *attr;
|
|
NSString *name, *str, *tableName, *relTableName;
|
|
BOOL first = YES;
|
|
|
|
|
|
|
|
name = [NSString stringWithFormat: @"%@_%@_FK", [_entity externalName],
|
|
[relationship name]];
|
|
|
|
sourceString = [NSMutableString stringWithCapacity: 30];
|
|
|
|
attrEnum = [sourceColumns objectEnumerator];
|
|
while ((attr = [attrEnum nextObject]))
|
|
{
|
|
NSString *columnName = [attr columnName];
|
|
|
|
if (!columnName || ![columnName length])
|
|
continue;
|
|
|
|
if (first == NO)
|
|
[sourceString appendString: @", "];
|
|
|
|
[sourceString appendString: columnName];
|
|
first = NO;
|
|
}
|
|
|
|
first = YES;
|
|
destinationString = [NSMutableString stringWithCapacity: 30];
|
|
|
|
attrEnum = [destinationColumns objectEnumerator];
|
|
while ((attr = [attrEnum nextObject]))
|
|
{
|
|
NSString *columnName = [attr columnName];
|
|
|
|
if (!columnName || ![columnName length])
|
|
continue;
|
|
|
|
if (first == NO)
|
|
[destinationString appendString: @", "];
|
|
|
|
[destinationString appendString: columnName];
|
|
first = NO;
|
|
}
|
|
|
|
tableName = [_entity externalName];
|
|
tableName = [self sqlStringForSchemaObjectName: tableName];
|
|
|
|
relTableName = [[relationship destinationEntity] externalName];
|
|
relTableName = [self sqlStringForSchemaObjectName: relTableName];
|
|
|
|
str = [NSString stringWithFormat: @"ALTER TABLE %@ ADD CONSTRAINT %@ "
|
|
@"FOREIGN KEY (%@) REFERENCES %@ (%@)",
|
|
tableName,
|
|
name,
|
|
sourceString,
|
|
relTableName,
|
|
destinationString];
|
|
|
|
ASSIGN(_statement, str);
|
|
|
|
|
|
}
|
|
|
|
// Assembles an adaptor specific constraint statement for relationship.
|
|
|
|
+ (NSArray *)createDatabaseStatementsForConnectionDictionary: (NSDictionary *)connectionDictionary
|
|
administrativeConnectionDictionary: (NSDictionary *)administrativeConnectionDictionary
|
|
{
|
|
[self subclassResponsibility: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
+ (NSArray *)dropDatabaseStatementsForConnectionDictionary: (NSDictionary *)connectionDictionary
|
|
administrativeConnectionDictionary: (NSDictionary *)administrativeConnectionDictionary
|
|
{
|
|
[self subclassResponsibility: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
+ (EOSQLExpression *)selectStatementForContainerOptions
|
|
{
|
|
[self notImplemented: _cmd];
|
|
return nil;
|
|
}
|
|
|
|
@end
|