* DBModeler/AdaptorsPanel.m (-init): Add parenthesis around

assignment.   Replace label with window title.
(-runAdaptorsPanel:): Remove unused variable.

* DBModeler/DefaultColumnProvider.m: Add missing braces, remove
unused ivars.
(-cellForColumnNamed:): Autorelease cells.

* DBModeler/EOAdditions.m: New EOAttribute KVC methods -allowNull and
 -setAllowNull:.

* DBModeler/GNUmakefile: Add new to project.

* DBModeler/KVDataSource.m (-createObject:): Return nil after
throwing exception.

* DBModeler/MainModelEditor.m
(-dragImageForRows:event:dragImageOffset:):: Enable drag and
drop for relationships.
(-initWithDocument:): Add parenthesis around assignment. Don't
release the document window on close.
(-ecStuff:): temporarily reload everything in the outline view when
something changes.
(-viewSelectedObject:): Remove NSLog.  Rewrite editor activation.
Fix leaks.

* DBModeler/Modeler.m (-applicationWillFinishLaunching:): Add new menu
items. Don't order our menu in.
(-new:,-open:): Move document initializition to _newDocumentWithModel:.
(-_newDocumentWithModel:,-newFromDatabase:): New methods.
(-validateMenuItem:,-generateSQL:): Ditto.

* DBModeler/ModelerAttributeEditor.m (-initWithParentEditor:):
Remove unused variables.
(-displayGroupDidChangeSelection:): return early if there is no
longer a selection.

* DBModeler/ModelerEntityEditor.m:
(-canSupportCurrentSelection): Remove NSLog.
(-displayGroupDidChangeSelection:): Ditto.
(-dealloc:): New method.
(-initWithParentEditor:): Remove unused variables.  Add parens around
assignment.  Release local variables.

* DBModeler/ModelerTableEmbedibleEditor:
(-addDefaultTableColumnsForTableView:displayGroup:): Release table
 columns.
(-addTableColumnForItem:tableView:): Ditto.

* DBModeler/Inspectors/RelationshipInspector.m:
(-selectedEntity, -selectedDestinationAttribute): New methods.
(-selectedSourceAttribute, -indexOfSourceAttribute:): Ditto.
(-indexOfDestinationAttribute:,joinWithSource:destination:): Ditto.
(-selectedJoin:,updateConnectButton,): Ditto.
(-refresh): Rewrite using new methods.
(-numberOfRowsInTableView:): Add fallback return value.
(-tableView:objectValueForTableColumn:row:): Ditto.
(-tableView:selectionDidChange:): If a source or destination
attribute is now selected, select its counterpart.
(-tableView:shouldSelectRow:): New method to disallow entity
selection if there is a destination entity.
(-tableView:willDisplayCell:forTableColumn:row:): New method,
set the cell text color to disabled text color, if we would disallow
 selection.
(-connectionChanged:): Implement disconnection.

* DBModeler/SQLGenerator.h/m: New files initial implementation.
* DBModeler/Resources/SQLGenerator.gorm: Ditto.
* DBModeler/ConsistencyChecker.h/m: Ditto.
* DBModeler/ConsistencyResults.h/m: Ditto.
* DBModeler/ConsistencyResults.gorm: Ditto.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@21438 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Matt Rice 2005-07-09 02:07:42 +00:00
parent 22a14f5447
commit 91868e3d12
24 changed files with 1459 additions and 181 deletions

View file

@ -1,3 +1,66 @@
2005-07-08 Matt Rice <ratmice@yahoo.com>
* DBModeler/AdaptorsPanel.m (-init): Add parenthesis around assignment.
Replace label with window title.
(-runAdaptorsPanel:): Remove unused variable.
* DBModeler/DefaultColumnProvider.m: Add missing braces, remove unused
ivars.
(-cellForColumnNamed:): Autorelease cells.
* DBModeler/EOAdditions.m: New EOAttribute KVC methods -allowNull and
-setAllowNull:.
* DBModeler/GNUmakefile: Add new to project.
* DBModeler/KVDataSource.m (-createObject:): Return nil after throwing
exception.
* DBModeler/MainModelEditor.m
(-dragImageForRows:event:dragImageOffset:):: Enable drag and drop for
relationships.
(-initWithDocument:): Add parenthesis around assignment. Don't release
the document window on close.
(-ecStuff:): temporarily reload everything in the outline view when
something changes.
(-viewSelectedObject:): Remove NSLog. Rewrite editor activation.
Fix leaks.
* DBModeler/Modeler.m (-applicationWillFinishLaunching:): Add new menu
items. Don't order our menu in.
(-new:,-open:): Move document initializition to _newDocumentWithModel:.
(-_newDocumentWithModel:,-newFromDatabase:): New methods.
(-validateMenuItem:,-generateSQL:): Ditto.
* DBModeler/ModelerAttributeEditor.m (-initWithParentEditor:): Remove
unused variables.
(-displayGroupDidChangeSelection:): return early if there is no longer
a selection.
* DBModeler/ModelerEntityEditor.m:
(-canSupportCurrentSelection): Remove NSLog.
(-displayGroupDidChangeSelection:): Ditto.
(-dealloc:): New method.
(-initWithParentEditor:): Remove unused variables. Add parens around
assignment. Release local variables.
* DBModeler/ModelerTableEmbedibleEditor:
(-addDefaultTableColumnsForTableView:displayGroup:): Release table
columns.
(-addTableColumnForItem:tableView:): Ditto.
* DBModeler/Inspectors/RelationshipInspector.m:
(-selectedEntity, -selectedDestinationAttribute): New methods.
(-selectedSourceAttribute, -indexOfSourceAttribute:): Ditto.
(-indexOfDestinationAttribute:,joinWithSource:destination:): Ditto.
(-selectedJoin:,updateConnectButton,): Ditto.
(-refresh): Rewrite using new methods.
(-numberOfRowsInTableView:): Add fallback return value.
(-tableView:objectValueForTableColumn:row:): Ditto.
(-tableView:selectionDidChange:): If a source or destination attribute
is now selected, select its counterpart.
(-tableView:shouldSelectRow:): New method to disallow entity selection
if there is a destination entity.
(-tableView:willDisplayCell:forTableColumn:row:): New method, set the
cell text color to disabled text color, if we would disallow
selection.
(-connectionChanged:): Implement disconnection.
* DBModeler/SQLGenerator.h/m: New files initial implementation.
* DBModeler/Resources/SQLGenerator.gorm: Ditto.
* DBModeler/ConsistencyChecker.h/m: Ditto.
* DBModeler/ConsistencyResults.h/m: Ditto.
* DBModeler/ConsistencyResults.gorm: Ditto.
2005-07-03 Matt Rice <ratmice@yahoo.com> 2005-07-03 Matt Rice <ratmice@yahoo.com>
* EOAccess/EOAdaptorContext.h/m (-channels:): New method. * EOAccess/EOAdaptorContext.h/m (-channels:): New method.
@ -58,6 +121,7 @@
2005-05-11 Matt Rice <ratmice@yahoo.com> 2005-05-11 Matt Rice <ratmice@yahoo.com>
* GNUmakefile: Compile EOInterface, EOModeler, DBModeler, GDL2Palette * GNUmakefile: Compile EOInterface, EOModeler, DBModeler, GDL2Palette
if gui is installed. if gui is installed.
* EOModeler/EOModelExtensions.h: Update copyright header. * EOModeler/EOModelExtensions.h: Update copyright header.
@ -3893,4 +3957,3 @@
-objectStoreForFetchSpecification:]): bug fix: changed notification -objectStoreForFetchSpecification:]): bug fix: changed notification
object. object.

View file

@ -44,7 +44,7 @@ static NSArray *_adaptorNames;
- (id) init - (id) init
{ {
if (self = [super init]) if ((self = [super init]))
{ {
_adaptorNames = RETAIN([EOAdaptor availableAdaptorNames]); _adaptorNames = RETAIN([EOAdaptor availableAdaptorNames]);
/* redo all these numbers so buttons and labels are on the right? */ /* redo all these numbers so buttons and labels are on the right? */
@ -53,15 +53,8 @@ static NSArray *_adaptorNames;
styleMask: NSBorderlessWindowMask | NSTitledWindowMask styleMask: NSBorderlessWindowMask | NSTitledWindowMask
backing: NSBackingStoreBuffered backing: NSBackingStoreBuffered
defer: YES]; defer: YES];
[_window setTitle: @"Select adaptor"];
_label = [[NSTextField alloc] initWithFrame: NSMakeRect(5,275,80,20)];
[_label setStringValue: @"New model"];
[_label setEditable: NO];
[_label setSelectable: NO];
[_label setBezeled: NO];
[_label setBordered: NO];
[_label setBackgroundColor: [NSColor windowBackgroundColor]];
brws_adaptors = [[NSBrowser alloc] initWithFrame: NSMakeRect(5,30,190,240)]; brws_adaptors = [[NSBrowser alloc] initWithFrame: NSMakeRect(5,30,190,240)];
[brws_adaptors setDelegate: self]; [brws_adaptors setDelegate: self];
[brws_adaptors addColumn]; [brws_adaptors addColumn];
@ -80,7 +73,6 @@ static NSArray *_adaptorNames;
[btn_cancel setTarget: self]; [btn_cancel setTarget: self];
[btn_cancel setAction: @selector(cancel:)]; [btn_cancel setAction: @selector(cancel:)];
[[_window contentView] addSubview: _label];
[[_window contentView] addSubview: brws_adaptors]; [[_window contentView] addSubview: brws_adaptors];
[[_window contentView] addSubview: btn_ok]; [[_window contentView] addSubview: btn_ok];
[[_window contentView] addSubview: btn_cancel]; [[_window contentView] addSubview: btn_cancel];
@ -96,7 +88,6 @@ static NSArray *_adaptorNames;
- (NSString *) runAdaptorsPanel - (NSString *) runAdaptorsPanel
{ {
NSString *selection; NSString *selection;
BOOL response = NO;
if ([NSApp runModalForWindow:_window] == NSRunAbortedResponse) if ([NSApp runModalForWindow:_window] == NSRunAbortedResponse)
{ {

View file

@ -0,0 +1,31 @@
/**
ConsistencyChecker.h
Author: Matt Rice <ratmice@yahoo.com>
Date: Jul 2005
This file is part of DBModeler.
<license>
DBModeler 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.
DBModeler 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 DBModeler; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
</license>
**/
#include <Foundation/NSObject.h>
@class NSNotification;
@interface ConsistencyChecker : NSObject
@end

View file

@ -0,0 +1,408 @@
/**
ConsistencyChecker.m
Author: Matt Rice <ratmice@yahoo.com>
Date: Jul 2005
This file is part of DBModeler.
<license>
DBModeler 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.
DBModeler 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 DBModeler; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
</license>
**/
#include <Foundation/NSNotification.h>
#include "ConsistencyChecker.h"
#include <EOModeler/EOModelerApp.h>
#include <EOModeler/EOModelerDocument.h>
#include <EOModeler/EOModelExtensions.h>
#include <EOAccess/EOAttribute.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOModel.h>
#include <EOAccess/EORelationship.h>
#define MY_PRETTY NSMutableAttributedString \
mutableAttributedStringWithBoldSubstitutionsWithFormat
static NSMutableArray *successText;
@implementation ConsistencyChecker
+(void) initialize
{
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(beginConsistencyCheck:)
name:EOMCheckConsistencyBeginNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(endConsistencyCheck:)
name:EOMCheckConsistencyEndNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(modelConsistencyCheck:)
name:EOMCheckConsistencyForModelNotification
object:nil];
successText = [[NSMutableArray alloc] initWithCapacity:8];
}
+ (void) beginConsistencyCheck:(NSNotification *)notif
{
}
+ (void) endConsistencyCheck:(NSNotification *)notif
{
int i,c;
for (i = 0, c = [successText count]; i < c; i++)
{
[[EOMApp activeDocument] appendConsistencyCheckSuccessText:[successText objectAtIndex:i]];
}
[successText removeAllObjects];
}
/* helper functions */
static void pass(BOOL flag, NSAttributedString *as)
{
if (flag)
{
[successText addObject:as];
}
else
[[EOMApp activeDocument] appendConsistencyCheckErrorText: as];
}
static BOOL isInvalid(NSString *str)
{
return (str == nil) || ([str length] == 0) ? YES : NO;
}
+ (void) attributeDetailsCheckForModel:(EOModel *)model
{
NSArray *ents = [model entities];
int i, c;
BOOL flag = YES;
for (i = 0, c = [ents count]; i < c; i++)
{
EOEntity *entity = [ents objectAtIndex:i];
NSArray *arr = [entity attributes];
int j,d;
for (j = 0, d = [arr count]; j < d; j++)
{
EOAttribute *attrib = [arr objectAtIndex:j];
NSString *className = [attrib valueClassName];
if ([[attrib className] isEqualToString:@"NSNumber"])
{
if (isInvalid([attrib externalType]))
{
pass(NO,[MY_PRETTY: @"Fail: %@ of type 'NSNumber has no external type\n",[(EOAttribute *)attrib name]]);
flag = NO;
}
}
/* TODO check whether NSCalendarDate/NSData require valueFactory...*/
if ((!isInvalid(className))
&& (![className isEqual:@"NSString"]
&& ![className isEqual:@"NSNumber"]
&& ![className isEqual:@"NSDecimalNumber"]
&& ![className isEqual:@"NSDate"]
&& ![className isEqual:@"NSData"])
&& (isInvalid([attrib valueFactoryMethodName])))
{
pass(NO,[MY_PRETTY: @"Fail: attribute '%@' of type '%@' requires a value factory method name\n",[(EOAttribute *)attrib name], className]);
flag = NO;
}
}
/* relationship primary key propagation */
arr = [entity relationships];
for (j = 0, d = [arr count]; j < d; j++)
{
EORelationship *rel = [arr objectAtIndex:j];
if ([rel propagatesPrimaryKey] == YES)
{
NSArray *attribs = [rel sourceAttributes];
NSArray *pkAttribs = [[rel entity] primaryKeyAttributes];
int k, e;
id pkey;
BOOL ok = YES;
for (k = 0, e = [pkAttribs count]; ok == YES && k < e; i++)
{
pkey = [pkAttribs objectAtIndex:k];
ok = [attribs containsObject:pkey];
}
if (ok == NO)
{
pass(NO,[MY_PRETTY: @"Fail: relationship '%@' propagates primary key but its source attributes does not contain the source entity's primary key attributes\n",[(EORelationship *)rel name]]);
flag = NO;
}
ok = YES;
attribs = [rel destinationAttributes];
pkAttribs = [[rel destinationEntity] primaryKeyAttributes];
for (k = 0, e = [pkAttribs count]; ok == YES && k < e; i++)
{
pkey = [pkAttribs objectAtIndex:k];
ok = [attribs containsObject:pkey];
}
if (ok == NO)
{
pass(NO, [MY_PRETTY: @"Fail: relationship '%@' propagates primary key but its destination attributes does not contain the destination entity's primary key attributes\n",[(EORelationship *)rel name]]);
flag = NO;
}
}
}
}
if (flag == YES)
pass(YES, [MY_PRETTY: @"Success: attribute detail check\n"]);
}
+ (void) entityStoredProcedureCheckForModel:(EOModel *)model
{
/* TODO */
}
+ (void) storedProcedureCheckForModel:(EOModel *)model
{
/* TODO */
}
+ (void) inheritanceCheckForModel:(EOModel *)model
{
BOOL flag = YES;
NSArray *ents = [model entities];
int i,c;
for (i = 0, c = [ents count]; i < c; i++)
{
EOEntity *ent = [ents objectAtIndex:i];
NSArray *subEnts = [ent subEntities];
int j, d;
for (j = 0, d = [subEnts count]; j < d; j++)
{
EOEntity *subEnt = [subEnts objectAtIndex:j];
NSArray *arr = [ent attributes];
NSArray *subArr = [subEnt attributes];
int k, e;
for (k = 0, e = [arr count]; k < e; k++)
{
EOAttribute *attrib = [arr objectAtIndex:k];
if (![subArr containsObject:[(EOAttribute *)attrib name]])
{
pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' missing parent's '%@' attribute",[(EOEntity *)subEnt name], [(EOAttribute *)attrib name]]);
flag = NO;
}
}
arr = [ent relationships];
for (k = 0, e = [arr count]; k < e; k++)
{
EORelationship *rel = [arr objectAtIndex:k];
EORelationship *subRel = [subEnt relationshipNamed:[(EORelationship *)rel name]];
if (!subRel || ![[rel definition] isEqual:[subRel definition]])
{
pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' missing relationship '%@' or definitions do not match", [(EOEntity *)subEnt name], [(EORelationship *)rel name]]);
flag = NO;
}
}
arr = [ent primaryKeyAttributes];
subArr = [subEnt primaryKeyAttributes];
if (![arr isEqual:subArr])
{
pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' and parent entities primary keys do not match", [(EOEntity *)subEnt name]]);
flag = NO;
}
if ([[subEnt externalName] isEqual:[ent externalName]]
&& (![subEnt restrictingQualifier] || ![ent restrictingQualifier]))
{
pass(NO, [MY_PRETTY: @"FAIL: sub entity '%@' and parent entity in same table must contain a restricting qualifier", [(EOEntity *)subEnt name]]);
flag = NO;
}
}
}
if (flag == YES)
{
pass(YES, [MY_PRETTY: @"Success: inheritance check"]);
}
}
+ (void) relationshipCheckForModel:(EOModel *)model
{
/* TODO */
NSArray *ents = [model entities];
int i, c;
BOOL flag = YES;
for (i = 0, c = [ents count]; i < c; i++)
{
EOEntity *ent = [ents objectAtIndex:i];
NSArray *arr = [ent relationships];
int j, d;
for (j = 0, d = [arr count]; j < d; j++)
{
id rel = [arr objectAtIndex:j];
if (![[rel joins] count])
{
pass(NO,[MY_PRETTY: @"Fail: relationship '%@' does not contain a join\n", [(EORelationship *)rel name]]);
flag = NO;
}
if ([rel isToMany] == NO)
{
NSArray *pkAttribs = [[rel destinationEntity] primaryKeyAttributes];
NSArray *attribs = [rel destinationAttributes];
if (![pkAttribs isEqual:attribs])
{
pass(NO, [MY_PRETTY: @"Fail: destination attributes of relationship '%@' are not the destination entity primary keys\n",[(EORelationship *)rel name]]);
flag = NO;
}
}
if ([rel propagatesPrimaryKey])
{
NSArray *pkAttribs = [[rel entity] primaryKeyAttributes];
NSArray *attribs = [rel sourceAttributes];
int k,e;
BOOL ok = YES;
for (k = 0, e = [pkAttribs count]; ok == YES && k < e; k++)
{
ok = [attribs containsObject: [pkAttribs objectAtIndex:k]];
}
if (ok == NO)
{
pass(NO, [MY_PRETTY: @"Fail: relationship '%@' propagates primary keys but does not contain source entities primary key attributes\n", [(EORelationship *)rel name]]);
flag = NO;
}
pkAttribs = [[rel destinationEntity] primaryKeyAttributes];
attribs = [rel destinationAttributes];
for (k = 0, e = [pkAttribs count]; ok == YES && k < e; k++)
{
ok = [attribs containsObject: [pkAttribs objectAtIndex:k]];
}
if (ok == NO)
{
pass(NO, [MY_PRETTY: @"Fail: relationship '%@' propagates primary keys but does not contain destination entities primary key attributes\n", [(EORelationship *)rel name]]);
flag = NO;
}
if ([[rel inverseRelationship] propagatesPrimaryKey])
{
pass(NO,[MY_PRETTY: @"Fail: both relationship '%@' and inverse relationship '%@' should not propagate primary keys\n", [(EORelationship *)rel name], [(EORelationship *)[rel inverseRelationship] name]]);
flag = NO;
}
}
}
}
if (flag == YES)
pass(YES, [MY_PRETTY: @"Success: relationship check\n"]);
}
+ (void) primaryKeyCheckForModel:(EOModel *)model
{
NSArray *ents = [model entities];
int i,c;
BOOL flag = YES;
for (i = 0, c = [ents count]; i < c; i++)
{
EOEntity *entity = [ents objectAtIndex:i];
NSArray *arr = [entity primaryKeyAttributes];
if (![arr count])
{
pass(NO,[MY_PRETTY: @"Fail: Entity '%@' does not have a primary key.\n", [(EOEntity *)entity name]]);
flag = NO;
}
}
if (flag == YES)
pass(YES, [MY_PRETTY:@"Success: primary key check\n"]);
}
+ (void) externalNameCheckForModel:(EOModel *)model
{
NSArray *ents = [model entities];
NSArray *arr;
int i,c,j,d;
BOOL flag = YES;
for (i = 0,c = [ents count]; i < c; i++)
{
EOEntity *entity = [ents objectAtIndex:i];
NSString *extName = [entity externalName];
if (isInvalid(extName))
{
pass(NO,[MY_PRETTY: @"Fail: Entity '%@' does not have an external name\n",
[(EOEntity *)entity name]]);
flag = NO;
}
arr = [entity attributes];
for (j = 0, d = [arr count]; j<d; j++)
{
EOAttribute *attrib = [arr objectAtIndex:j];
extName = [attrib columnName];
if (isInvalid(extName))
{
pass(NO,[MY_PRETTY: @"Fail: Attribute '%@' does not have an external name\n",
[(EOAttribute *)attrib name]]);
flag = NO;
}
extName = [attrib valueClassName];
if (isInvalid(extName))
{
pass(NO,[MY_PRETTY: @"Fail: Attribute '%@' does not have a value class name\n", [(EOAttribute *)attrib name]]);
flag = NO;
}
}
}
if (flag == YES)
pass(YES, [MY_PRETTY: @"Success: external name check\n"]);
}
+ (void) modelConsistencyCheck:(NSNotification *)notif
{
EOModel *model = [[notif userInfo] objectForKey:EOMConsistencyModelObjectKey];
/* TODO user defaults */
[self attributeDetailsCheckForModel:model];
[self primaryKeyCheckForModel:model];
[self externalNameCheckForModel:model];
[self relationshipCheckForModel:model];
[self inheritanceCheckForModel:model];
}
@end

View file

@ -0,0 +1,45 @@
/**
ConsistencyResults.h
Author: Matt Rice <ratmice@yahoo.com>
Date: Jul 2005
This file is part of DBModeler.
<license>
DBModeler 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.
DBModeler 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 DBModeler; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
</license>
**/
#include <Foundation/NSObject.h>
#include <AppKit/NSNibDeclarations.h>
@class NSPanel;
@class NSButton;
@class NSTextView;
@interface ConsistencyResults : NSObject
{
IBOutlet NSPanel *_panel;
IBOutlet NSButton *okButton;
IBOutlet NSButton *cancelButton;
IBOutlet NSTextView *results;
BOOL successful;
}
+ (id) sharedConsistencyPanel;
- (int) showConsistencyCheckResults:(id)sender cancelButton:(BOOL)useCancel
showOnSuccess:(BOOL)flag;
@end

View file

@ -0,0 +1,98 @@
/**
ConsistencyResults.m
Author: Matt Rice <ratmice@yahoo.com>
Date: Jul 2005
This file is part of DBModeler.
<license>
DBModeler 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.
DBModeler 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 DBModeler; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
</license>
**/
#include <ConsistencyResults.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSButton.h>
#include <AppKit/NSNibLoading.h>
#include <AppKit/NSPanel.h>
#include <AppKit/NSTextView.h>
#include <AppKit/NSTextStorage.h>
static ConsistencyResults *_sharedResults;
@implementation ConsistencyResults
+ (id) sharedConsistencyPanel;
{
if (!_sharedResults)
_sharedResults = [[self allocWithZone:NSDefaultMallocZone()] init];
return _sharedResults;
}
- (id) init
{
self = [super init];
[NSBundle loadNibNamed:@"ConsistencyResults" owner:self];
successful = YES;
return self;
}
- (int) showConsistencyCheckResults:(id)sender cancelButton:(BOOL)useCancel
showOnSuccess:(BOOL)flag
{
int foo = NSRunStoppedResponse;
[cancelButton setEnabled:useCancel];
if (!flag && successful)
{
}
else
{
foo = [NSApp runModalForWindow:_panel];
}
/* reset this.. */
successful = YES;
return foo;
}
- (void) appendConsistencyCheckErrorText:(NSAttributedString *)errorText
{
successful = NO;
[[results textStorage] appendAttributedString:errorText];
}
- (void) appendConsistencyCheckSuccessText:(NSAttributedString *)successText
{
[[results textStorage] appendAttributedString:successText];
}
- (void) cancel:(id)sender
{
[NSApp abortModal];
[_panel orderOut:self];
[results setString:@""];
}
- (void) ok:(id)sender
{
[NSApp stopModal];
[_panel orderOut:self];
[results setString:@""];
}
@end

View file

@ -48,37 +48,37 @@ static NSMutableDictionary *_aspectsAndKeys;
/* object key default */ /* object key default */
static id attribute_columns[][3] = { static id attribute_columns[][3] = {
@"allowsNull", @"Allows null", nil, {@"allowNull", @"Allows null", uhuh},
@"isClassProperty", @"Class property", uhuh, {@"isClassProperty", @"Class property", uhuh},
@"columnName", @"Column name", uhuh, {@"columnName", @"Column name", uhuh},
@"definition", @"Definition", nil, {@"definition", @"Definition", nil},
@"externalType", @"External Type", uhuh, {@"externalType", @"External Type", uhuh},
@"isUsedForLocking", @"Locking", uhuh, {@"isUsedForLocking", @"Locking", uhuh},
@"name", @"Name", uhuh, {@"name", @"Name", uhuh},
@"precision", @"Precision", nil, {@"precision", @"Precision", nil},
@"isPrimaryKey", @"Primary key", uhuh, {@"isPrimaryKey", @"Primary key", uhuh},
@"readFormat", @"Read format", nil, {@"readFormat", @"Read format", nil},
@"scale", @"Scale", nil, {@"scale", @"Scale", nil},
@"valueClassName", @"Value class name", uhuh, {@"valueClassName", @"Value class name", uhuh},
@"valueType", @"Value type", nil, {@"valueType", @"Value type", nil},
@"width", @"Width", uhuh, {@"width", @"Width", uhuh},
@"writeFormat", @"Write format", nil {@"writeFormat", @"Write format", nil}
}; };
static id relationship_columns[][3]= { static id relationship_columns[][3]= {
@"isClassProperty", @"Class Property", uhuh, {@"isClassProperty", @"Class property", uhuh},
@"definition", @"Definition", nil, {@"definition", @"Definition", nil},
@"name", @"Name", uhuh, {@"name", @"Name", uhuh},
@"destinationEntity.name", @"Destination Entity", uhuh {@"destinationEntity.name", @"Destination Entity", uhuh}
}; };
static id entity_columns[][3] = { static id entity_columns[][3] = {
@"name", @"Name", uhuh, {@"name", @"Name", uhuh},
@"className", @"Class name", uhuh, {@"className", @"Class name", uhuh},
@"externalName", @"External name", uhuh, {@"externalName", @"External name", uhuh},
@"externalQuery", @"External query", nil, {@"externalQuery", @"External query", nil},
@"parentEntity.name", @"Parent", nil {@"parentEntity.name", @"Parent", nil}
}; };
@ -101,7 +101,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
{ {
id *objects; id *objects;
id *keys; id *keys;
int i,c; int i;
size_t size; size_t size;
NSDictionary *tmp; NSDictionary *tmp;
size = (count * sizeof(id)); size = (count * sizeof(id));
@ -156,6 +156,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
- (NSCell *)cellForColumnNamed:(NSString *)name - (NSCell *)cellForColumnNamed:(NSString *)name
{ {
/* TODO need a switch button for "Locking" and "Allows null" */ /* TODO need a switch button for "Locking" and "Allows null" */
if ([name isEqual:@"Primary key"]) if ([name isEqual:@"Primary key"])
{ {
@ -168,7 +169,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
[cell setAlternateImage:[NSImage imageNamed:@"Key_On"]]; [cell setAlternateImage:[NSImage imageNamed:@"Key_On"]];
[cell setControlSize: NSSmallControlSize]; [cell setControlSize: NSSmallControlSize];
[cell setEditable:YES]; [cell setEditable:YES];
return cell; return AUTORELEASE(cell);
} }
else if ([name isEqual:@"Class property"]) else if ([name isEqual:@"Class property"])
{ {
@ -181,7 +182,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
[cell setAlternateImage:[NSImage imageNamed:@"ClassProperty_On"]]; [cell setAlternateImage:[NSImage imageNamed:@"ClassProperty_On"]];
[cell setControlSize: NSSmallControlSize]; [cell setControlSize: NSSmallControlSize];
[cell setEditable:YES]; [cell setEditable:YES];
return cell; return AUTORELEASE(cell);
} }
else if ([name isEqual:@"Locking"]) else if ([name isEqual:@"Locking"])
{ {
@ -194,7 +195,19 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
[cell setAlternateImage:[NSImage imageNamed:@"ClassProperty_On"]]; [cell setAlternateImage:[NSImage imageNamed:@"ClassProperty_On"]];
[cell setControlSize: NSSmallControlSize]; [cell setControlSize: NSSmallControlSize];
[cell setEditable:YES]; [cell setEditable:YES];
return cell; return AUTORELEASE(cell);
}
else if ([name isEqual:@"Allows null"])
{
NSButtonCell *cell = [[NSButtonCell alloc] initImageCell:nil];
[cell setButtonType:NSSwitchButton];
[cell setImagePosition:NSImageOnly];
[cell setBordered:NO];
[cell setBezeled:NO];
[cell setControlSize: NSSmallControlSize];
[cell setEditable:YES];
return AUTORELEASE(cell);
} }
else else
{ {
@ -202,7 +215,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
[cell setEnabled:YES]; [cell setEnabled:YES];
[cell setEditable:YES]; [cell setEditable:YES];
[cell setScrollable: YES]; [cell setScrollable: YES];
return cell; return AUTORELEASE(cell);
} }
} }

View file

@ -108,6 +108,17 @@ static inline void setIsClassProperty(id self, NSNumber *flag)
{ {
/* FIXME */ /* FIXME */
} }
- (NSNumber *)allowNull
{
return [NSNumber numberWithBool:[self allowsNull]];
}
- (void) setAllowNull:(NSNumber *)flag
{
[self setAllowsNull:[flag boolValue]];
}
@end @end
@ -121,4 +132,6 @@ static inline void setIsClassProperty(id self, NSNumber *flag)
{ {
return setIsClassProperty(self, flag); return setIsClassProperty(self, flag);
} }
@end @end

View file

@ -23,7 +23,9 @@ ADDITIONAL_NATIVE_LIBS += EOInterface gnustep-db2modeler
$(APP_NAME)_RESOURCE_FILES = \ $(APP_NAME)_RESOURCE_FILES = \
Resources/Key_On.tiff \ Resources/Key_On.tiff \
Resources/ClassProperty_On.tiff \ Resources/ClassProperty_On.tiff \
Resources/ModelDrag.tiff Resources/ModelDrag.tiff \
Resources/SQLGenerator.gorm \
Resources/ConsistencyResults.gorm
$(APP_NAME)_OBJC_FILES = \ $(APP_NAME)_OBJC_FILES = \
main.m \ main.m \
@ -35,6 +37,9 @@ $(APP_NAME)_OBJC_FILES = \
KVDataSource.m \ KVDataSource.m \
ModelerAttributeEditor.m \ ModelerAttributeEditor.m \
EOAdditions.m \ EOAdditions.m \
ModelerTableEmbedibleEditor.m ModelerTableEmbedibleEditor.m \
SQLGenerator.m \
ConsistencyResults.m \
ConsistencyChecker.m
include $(GNUSTEP_MAKEFILES)/application.make include $(GNUSTEP_MAKEFILES)/application.make

View file

@ -11,35 +11,150 @@
#include <Foundation/NSArray.h> #include <Foundation/NSArray.h>
@implementation RelationshipInspector @implementation RelationshipInspector
- (EOEntity *)selectedEntity
{
int row = [destEntity_tableView selectedRow];
if (row == -1)
return nil;
return [[[[EOMApp activeDocument] model] entities] objectAtIndex:row];
}
- (EOAttribute *)selectedDestinationAttribute
{
int row = [destAttrib_tableView selectedRow];
if (row == -1)
return nil;
return [[[self selectedEntity] attributes]
objectAtIndex:[destAttrib_tableView selectedRow]];
}
- (EOAttribute *)selectedSourceAttribute
{
int row = [srcAttrib_tableView selectedRow];
if (row == -1)
return nil;
return [[[[self selectedObject] entity] attributes] objectAtIndex:[srcAttrib_tableView selectedRow]];
}
- (int) indexOfSourceAttribute:(EOAttribute *)srcAttrib
{
id tmp;
int row;
if (srcAttrib == nil) return NSNotFound;
tmp = [self selectedObject];
if (tmp == nil) return NSNotFound;
tmp = [tmp entity];
if (tmp == nil) return NSNotFound;
tmp = [(EOEntity *)tmp attributes];
if (tmp == nil) return NSNotFound;
row = [tmp indexOfObject:srcAttrib];
return row;
}
- (int) indexOfDestinationAttribute:(EOAttribute *)destAttrib
{
id tmp;
int row;
if (destAttrib == nil) return NSNotFound;
tmp = [self selectedObject];
if (tmp == nil) return NSNotFound;
tmp = [tmp destinationEntity];
if (tmp == nil) return NSNotFound;
tmp = [(EOEntity *)tmp attributes];
if (tmp == nil) return NSNotFound;
row = [tmp indexOfObject:destAttrib];
return row;
}
- (EOJoin *) joinWithSource:(EOAttribute *)srcAttrib destination:(EOAttribute *)destAttrib
{
NSArray *joins;
int i,c;
if (!srcAttrib && !destAttrib)
return nil;
joins = [[self selectedObject] joins];
c = [joins count];
for (i = 0; i < c; i++)
{
BOOL flag;
id join = [joins objectAtIndex:i];
/* if both arguments are non-nil, both must be equal,
* if one argument is nil the non-nil argument must be equal */
flag = ((srcAttrib
&& destAttrib
&& [srcAttrib isEqual:[join sourceAttribute]]
&& [destAttrib isEqual:[join destinationAttribute]])
|| (srcAttrib
&& (destAttrib == nil)
&& [srcAttrib isEqual:[join sourceAttribute]])
|| (destAttrib
&& (srcAttrib == nil)
&& [destAttrib isEqual:[join destinationAttribute]]));
if (flag)
{
return join;
}
}
return nil;
}
- (EOJoin *) selectedJoin
{
return [self joinWithSource:[self selectedSourceAttribute]
destination:[self selectedDestinationAttribute]];
}
- (void) awakeFromNib - (void) awakeFromNib
{ {
[destEntity_tableView setAllowsEmptySelection:NO]; [destEntity_tableView setAllowsEmptySelection:NO];
[srcAttrib_tableView setAllowsEmptySelection:NO]; [srcAttrib_tableView setAllowsEmptySelection:NO];
[destAttrib_tableView setAllowsEmptySelection:NO]; [destAttrib_tableView setAllowsEmptySelection:NO];
} }
- (float) displayOrder - (float) displayOrder
{ {
return 0; return 0;
} }
- (BOOL) canInspectObject:(id)anObject - (BOOL) canInspectObject:(id)anObject
{ {
return [anObject isKindOfClass:[EORelationship class]]; return [anObject isKindOfClass:[EORelationship class]];
} }
- (void) updateConnectButton
{
[connect_button setState: ([self selectedJoin] != nil) ? NSOnState : NSOffState];
}
- (void) refresh - (void) refresh
{ {
EOModel *activeModel = [[EOMApp activeDocument] model]; EOModel *activeModel = [[EOMApp activeDocument] model];
EOEntity *destEntity; EOEntity *destEntity;
EOAttribute *srcAttrib, *destAttrib; EOAttribute *srcAttrib, *destAttrib;
NSArray *srcAttribs; NSArray *joins;
NSArray *destAttribs;
unsigned int row; unsigned int row;
[name_textField setStringValue:[(EORelationship *)[self selectedObject] name]]; [name_textField setStringValue:[(EORelationship *)[self selectedObject] name]];
/* it is important that the destEntity has a selected row before the destAttrib tableview /* it is important that the destEntity has a selected row before the destAttrib tableview
* reloads data */ * reloads data */
[destEntity_tableView reloadData]; [destEntity_tableView reloadData];
@ -51,45 +166,29 @@
row = 0; row = 0;
} }
else if ([destEntity_tableView numberOfRows]) else if ([destEntity_tableView numberOfRows])
row = 0; row = 0;
[destEntity_tableView selectRow:row byExtendingSelection:NO]; [destEntity_tableView selectRow:row byExtendingSelection:NO];
srcAttribs = [[self selectedObject] sourceAttributes]; joins = [[self selectedObject] joins];
if (srcAttribs && [srcAttribs count])
srcAttrib = [srcAttribs objectAtIndex:0]; if ([joins count])
{
EOJoin *join = [joins objectAtIndex:0];
srcAttrib = [join sourceAttribute];
destAttrib = [join destinationAttribute];
row = [self indexOfSourceAttribute:srcAttrib];
[srcAttrib_tableView selectRow:row byExtendingSelection:NO];
row = [self indexOfDestinationAttribute:srcAttrib];
[destAttrib_tableView selectRow:row byExtendingSelection:NO];
}
else else
srcAttrib = nil; {
[srcAttrib_tableView selectRow:0 byExtendingSelection:NO];
[destAttrib_tableView selectRow:0 byExtendingSelection:NO];
}
[srcAttrib_tableView reloadData]; [self updateConnectButton];
if (srcAttrib)
{
// FIXME!!!! when there is no srcAttrib we segfault when calling isEqual: so we use indexOfObjectIdenticalTo:
row = [[[[self selectedObject] entity] attributes] indexOfObject:srcAttrib];
if (row == NSNotFound)
row = 0;
}
else if ([srcAttrib_tableView numberOfRows])
row = 0;
[srcAttrib_tableView selectRow:row byExtendingSelection:NO];
destAttribs = [[self selectedObject] destinationAttributes];
if (destAttribs && [destAttribs count])
destAttrib = [destAttribs objectAtIndex:0];
else
destAttrib = nil;
[destAttrib_tableView reloadData];
if (destAttrib)
{
// FIXME!!!! when there is no destAttrib we segfault when calling isEqual: so we use indexOfObjectIdenticalTo:
row = [[[[self selectedObject] destinationEntity] attributes] indexOfObject:destAttrib];
if (row == NSNotFound)
row = 0;
}
else if ([destAttrib_tableView numberOfRows])
row = 0;
[destAttrib_tableView selectRow:row byExtendingSelection:NO];
[connect_button setState: ([[self selectedObject] destinationEntity] == nil) ? NSOffState : NSOnState];
[joinCardinality_matrix selectCellWithTag:[[self selectedObject] isToMany]]; [joinCardinality_matrix selectCellWithTag:[[self selectedObject] isToMany]];
[joinSemantic_popup selectItemAtIndex: [joinSemantic_popup indexOfItemWithTag: [[self selectedObject] joinSemantic]]]; [joinSemantic_popup selectItemAtIndex: [joinSemantic_popup indexOfItemWithTag: [[self selectedObject] joinSemantic]]];
@ -110,6 +209,7 @@
return [[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] count]; return [[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] count];
} }
return 0;
} }
- (id) tableView:(NSTableView *)tv - (id) tableView:(NSTableView *)tv
@ -133,6 +233,8 @@ row:(int)rowIndex
return [(EOAttribute *)[[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] return [(EOAttribute *)[[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]]
attributes] objectAtIndex:rowIndex] name]; attributes] objectAtIndex:rowIndex] name];
} }
return nil;
} }
- (void) tableViewSelectionDidChange:(NSNotification *)notif - (void) tableViewSelectionDidChange:(NSNotification *)notif
@ -143,24 +245,76 @@ row:(int)rowIndex
{ {
[destAttrib_tableView reloadData]; [destAttrib_tableView reloadData];
} }
else if (tv == destAttrib_tableView)
{
EOJoin *join = [self joinWithSource:nil destination:[self selectedDestinationAttribute]];
int row = [self indexOfSourceAttribute:[join sourceAttribute]];
if (row != NSNotFound)
[srcAttrib_tableView selectRow:row byExtendingSelection:NO];
[self updateConnectButton];
}
else if (tv == srcAttrib_tableView)
{
EOJoin *join = [self joinWithSource:[self selectedSourceAttribute] destination:nil];
int row = [self indexOfDestinationAttribute:[join destinationAttribute]];
if (row != NSNotFound)
[destAttrib_tableView selectRow:row byExtendingSelection:NO];
[self updateConnectButton];
}
} }
- (BOOL) tableView:(NSTableView *)tv shouldSelectRow:(int)rowIndex
{
if (tv == destEntity_tableView)
{
return [[self selectedObject] destinationEntity] == nil;
}
else
{
return YES;
}
}
- (void) tableView:(NSTableView *)tv willDisplayCell:(NSCell *)cell forTableColumn:(id)tc
row:(int)row
{
if (tv == destEntity_tableView)
{
NSColor *enabledText = [NSColor controlTextColor];
NSColor *disabledText = [NSColor disabledControlTextColor];
BOOL flag = ([[self selectedObject] destinationEntity] == nil);
[(NSTextFieldCell *)cell setTextColor:(flag == YES) ? enabledText : disabledText];
}
}
- (void) connectionChanged:(id)sender - (void) connectionChanged:(id)sender
{ {
EOEntity *destEntity;
EOAttribute *srcAttrib; EOAttribute *srcAttrib;
EOAttribute *destAttrib; EOAttribute *destAttrib;
EOModel *model; EOJoin *join;
EOJoin *newJoin; EOEntity *destEnt = [[self selectedObject] destinationEntity];
destAttrib = [self selectedDestinationAttribute];
srcAttrib = [self selectedSourceAttribute];
if ([sender state] == NSOnState)
{
join = [[EOJoin alloc] initWithSourceAttribute:srcAttrib destinationAttribute:destAttrib];
[[self selectedObject] addJoin:join];
[join release];
}
else
{
join = [self joinWithSource:srcAttrib destination:destAttrib];
[[self selectedObject] removeJoin:join];
}
model = [[EOMApp activeDocument] model]; if (destEnt != [[self selectedObject] destinationEntity])
[destEntity_tableView reloadData];
destEntity = [[model entities] objectAtIndex:[destEntity_tableView selectedRow]];
destAttrib = [[destEntity attributes] objectAtIndex:[destAttrib_tableView selectedRow]];
srcAttrib = [[[[self selectedObject] entity] attributes] objectAtIndex:[srcAttrib_tableView selectedRow]];
newJoin = [[EOJoin alloc] initWithSourceAttribute:srcAttrib destinationAttribute:destAttrib];
[[self selectedObject] addJoin:newJoin];
[newJoin release];
} }
- (void) nameChanged:(id)sender - (void) nameChanged:(id)sender
@ -182,5 +336,6 @@ row:(int)rowIndex
/* the tag in the nib for to-one must be 0 to-many 1 */ /* the tag in the nib for to-one must be 0 to-many 1 */
[[self selectedObject] setToMany: [[sender selectedCell] tag]]; [[self selectedObject] setToMany: [[sender selectedCell] tag]];
} }
@end @end

View file

@ -86,6 +86,7 @@ return self;
[[NSException exceptionWithName:NSInternalInconsistencyException [[NSException exceptionWithName:NSInternalInconsistencyException
reason: [NSString stringWithFormat:@"%@ not supported by %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])] reason: [NSString stringWithFormat:@"%@ not supported by %@", NSStringFromSelector(_cmd), NSStringFromClass([self class])]
userInfo:nil] raise]; userInfo:nil] raise];
return nil;
} }
- (void) insertObject:(id)object - (void) insertObject:(id)object
{ {

View file

@ -23,6 +23,7 @@
</license> </license>
**/ **/
#include <Foundation/NSRunLoop.h>
#include "MainModelEditor.h" #include "MainModelEditor.h"
#include "ModelerEntityEditor.h" #include "ModelerEntityEditor.h"
@ -39,6 +40,7 @@
#include <EOControl/EOObserver.h> #include <EOControl/EOObserver.h>
#include <EOControl/EOEditingContext.h> #include <EOControl/EOEditingContext.h>
#include <AppKit/NSPanel.h>
#include <AppKit/NSImage.h> #include <AppKit/NSImage.h>
#include <AppKit/NSOutlineView.h> #include <AppKit/NSOutlineView.h>
#include <AppKit/NSPasteboard.h> #include <AppKit/NSPasteboard.h>
@ -47,7 +49,7 @@
#include <AppKit/NSTableColumn.h> #include <AppKit/NSTableColumn.h>
#include <Foundation/NSNotification.h> #include <Foundation/NSNotification.h>
//#define DEBUG_STUFF 1 #define DEBUG_STUFF 0
@interface ModelerOutlineView : NSOutlineView @interface ModelerOutlineView : NSOutlineView
@end @end
@ -60,7 +62,8 @@
id foo = [self itemAtRow:[[dragRows objectAtIndex:0] intValue]]; id foo = [self itemAtRow:[[dragRows objectAtIndex:0] intValue]];
NSImage *img = nil; NSImage *img = nil;
if ([foo isKindOfClass: [EOEntity class]]) if ([foo isKindOfClass: [EOEntity class]]
|| [foo isKindOfClass:[EORelationship class]])
{ {
img = [NSImage imageNamed:@"ModelDrag"]; img = [NSImage imageNamed:@"ModelDrag"];
[img setScalesWhenResized:NO]; [img setScalesWhenResized:NO];
@ -71,7 +74,7 @@
@implementation MainModelEditor @implementation MainModelEditor
- (id) initWithDocument:(EOModelerDocument *)document - (id) initWithDocument:(EOModelerDocument *)document
{ {
if (self = [super initWithDocument:document]) if ((self = [super initWithDocument:document]))
{ {
NSTableColumn *_col; NSTableColumn *_col;
NSSplitView *vSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,400,400)]; NSSplitView *vSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,400,400)];
@ -99,6 +102,7 @@
styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask | NSResizableWindowMask styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask | NSResizableWindowMask
backing:NSBackingStoreBuffered backing:NSBackingStoreBuffered
defer:YES]; defer:YES];
[_window setReleasedWhenClosed:NO];
[sv setHasHorizontalScroller:YES]; [sv setHasHorizontalScroller:YES];
[sv setHasVerticalScroller:YES]; [sv setHasVerticalScroller:YES];
@ -146,21 +150,7 @@
{ {
if ([[notif object] isKindOfClass:[EOEditingContext class]]) if ([[notif object] isKindOfClass:[EOEditingContext class]])
{ {
int i,c; [_iconPath reloadData];
NSArray *objects = [[notif userInfo] objectForKey:EOUpdatedKey];
for (i = 0, c = [objects count]; i < c; i++)
[_iconPath reloadItem:[objects objectAtIndex:i] reloadChildren:YES];
#if 0
objects = [[notif userInfo] objectForKey:EOInsertedKey];
for (i = 0, c = [objects count]; i < c; i++)
[_iconPath reloadItem:[objects objectAtIndex:i] reloadChildren:YES];
objects = [[notif userInfo] objectForKey:EODeletedKey];
for (i = 0, c = [objects count]; i < c; i++)
[_iconPath reloadItem:[objects objectAtIndex:i] reloadChildren:YES];
#endif
} }
} }
@ -214,10 +204,7 @@
{ {
id selection; id selection;
if ([[self selectionWithinViewedObject] count] == 0) if ([[self selectionWithinViewedObject] count] == 0)
{ return;
NSLog(@"view count == 0, obj:");
return;
}
selection = [[self selectionWithinViewedObject] objectAtIndex:0]; selection = [[self selectionWithinViewedObject] objectAtIndex:0];
#if DEBUG_STUFF == 1 #if DEBUG_STUFF == 1
@ -235,39 +222,35 @@
current selection */ current selection */
for (i = 0, c = [friends count]; i < c; i++) for (i = 0, c = [friends count]; i < c; i++)
{ {
id friend = [friends objectAtIndex:i];
for (j = 0,editorsCount = [_editors count]; j < editorsCount; j++) for (j = 0,editorsCount = [_editors count]; j < editorsCount; j++)
{ {
if ([_editors isKindOfClass: friend]) id friendEditor = [_editors objectAtIndex:j];
id friendClass = [friends objectAtIndex:i];
if ([friendEditor isKindOfClass: friendClass])
{ {
id friendEditor = [_editors objectAtIndex:j]; if ([friendEditor canSupportCurrentSelection])
if ([friend canSupportCurrentSelection])
{ {
[self activateEmbeddedEditor:friend]; [self activateEmbeddedEditor:friendEditor];
[super viewSelectedObject]; [super viewSelectedObject];
return; return;
} }
} }
} }
} }
/* instantiate friends to see if we can support the current selection */ /* instantiate friends to see if we can support the current selection */
for (i = 0,c = [friends count]; i < c; i++) for (i = 0,c = [friends count]; i < c; i++)
{ {
id friendClass = [friends objectAtIndex:i]; id friendClass = [friends objectAtIndex:i];
id friend = [[friendClass alloc] initWithParentEditor:self]; id friend = [[friendClass alloc] initWithParentEditor:self];
if ([friend canSupportCurrentSelection])
{ {
if ([friend canSupportCurrentSelection]) [self activateEmbeddedEditor:friend];
{ RELEASE(friend);
[self activateEmbeddedEditor:friend]; [super viewSelectedObject];
[super viewSelectedObject]; return;
return;
}
else
{
[friend release];
}
} }
RELEASE(friend);
} }
/* look for any old editor this isn't very nice... /* look for any old editor this isn't very nice...
* because it only works with registered editors, and we can only * because it only works with registered editors, and we can only
@ -304,7 +287,7 @@
else if ([item isKindOfClass:[EORelationship class]]) else if ([item isKindOfClass:[EORelationship class]])
ret = 0; ret = 0;
#if DEBUG_STUFF == 1 #if DEBUG_STUFF == 1
NSLog(@"isItemExpandable %i", ret); NSLog(@"%@\n\t %@ %i", NSStringFromSelector(_cmd), [item class], ret);
#endif #endif
return ret; return ret;
} }
@ -324,7 +307,7 @@
ret = 0; ret = 0;
#if DEBUG_STUFF == 1 #if DEBUG_STUFF == 1
NSLog(@"num children %i %@", ret, [item class]); NSLog(@"%@\n\t %i %@", NSStringFromSelector(_cmd), ret, [item class]);
#endif #endif
return ret; return ret;
@ -345,7 +328,7 @@
else if ([item isKindOfClass: [EORelationship class]]) else if ([item isKindOfClass: [EORelationship class]])
ret = nil; ret = nil;
#if DEBUG_STUFF == 1 #if DEBUG_STUFF == 1
NSLog(@"child %@ atIndex: %i ofItem %@", [ret class], index, [item class]); NSLog(@"%@\n\tchild %@ atIndex: %i ofItem %@", NSStringFromSelector(_cmd), [ret class], index, [item class]);
#endif #endif
return ret; return ret;
} }

View file

@ -23,10 +23,13 @@
</license> </license>
**/ **/
#include "Modeler.h"
#include "AdaptorsPanel.h" #include "AdaptorsPanel.h"
#include "ConsistencyChecker.h"
#include "ConsistencyResults.h"
#include "MainModelEditor.h" #include "MainModelEditor.h"
#include "Modeler.h"
#include "ModelerEntityEditor.h" #include "ModelerEntityEditor.h"
#include "SQLGenerator.h"
#include <EOModeler/EOModelerApp.h> #include <EOModeler/EOModelerApp.h>
#include <EOModeler/EOModelerEditor.h> #include <EOModeler/EOModelerEditor.h>
@ -34,12 +37,14 @@
#include <EOModeler/EOMInspectorController.h> #include <EOModeler/EOMInspectorController.h>
#include <EOAccess/EOModel.h> #include <EOAccess/EOModel.h>
#include <EOAccess/EOModelGroup.h> #include <EOAccess/EOModelGroup.h>
#include <EOAccess/EOAdaptorChannel.h>
#include <EOAccess/EOAdaptorContext.h>
#include <EOAccess/EOAdaptor.h>
#include <AppKit/NSOpenPanel.h> #include <AppKit/NSOpenPanel.h>
#include <Foundation/NSObject.h> #include <Foundation/NSObject.h>
/* TODO validate menu items.. */
@interface NSMenu (im_lazy) @interface NSMenu (im_lazy)
-(id <NSMenuItem>) addItemWithTitle: (NSString *)s; -(id <NSMenuItem>) addItemWithTitle: (NSString *)s;
-(id <NSMenuItem>) addItemWithTitle: (NSString *)s action: (SEL)sel; -(id <NSMenuItem>) addItemWithTitle: (NSString *)s action: (SEL)sel;
@ -63,6 +68,7 @@
@implementation Modeler @implementation Modeler
-(void)bundleDidLoad:(NSNotification *)not -(void)bundleDidLoad:(NSNotification *)not
{ {
/* a place to put breakpoints? */ /* a place to put breakpoints? */
@ -98,10 +104,12 @@
/* useful method for setting breakpoints after an adaptor is loaded */ /* useful method for setting breakpoints after an adaptor is loaded */
mainMenu = [[NSMenu alloc] init]; mainMenu = [[NSMenu alloc] init];
[mainMenu setAutoenablesItems:YES];
subMenu = [[NSMenu alloc] init]; subMenu = [[NSMenu alloc] init];
[subMenu setAutoenablesItems:YES];
[subMenu addItemWithTitle: _(@"Info..") [subMenu addItemWithTitle: _(@"Info...")
action: @selector(:orderFrontStandardInfoPanel:)]; action: @selector(orderFrontStandardInfoPanel:)];
[subMenu addItemWithTitle: _(@"Preferences...") [subMenu addItemWithTitle: _(@"Preferences...")
action: @selector(openPrefs:)]; action: @selector(openPrefs:)];
@ -109,14 +117,34 @@
[mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle: _(@"Info")]]; [mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle: _(@"Info")]];
[subMenu release]; [subMenu release];
subMenu = [[NSMenu alloc] init]; subMenu = [[NSMenu alloc] init];
subMenu = [[NSMenu alloc] init];
[subMenu setAutoenablesItems:YES];
[subMenu addItemWithTitle: _(@"Copy")
action: @selector(copy:)
keyEquivalent:@"c"];
[subMenu addItemWithTitle: _(@"Cut")
action: @selector(cut:)
keyEquivalent:@"x"];
[subMenu addItemWithTitle: _(@"Paste")
action: @selector(paste:)
keyEquivalent:@"v"];
[mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle: _(@"Edit")]];
[subMenu release];
subMenu = [[NSMenu alloc] init];
[subMenu addItemWithTitle: _(@"New...") [subMenu addItemWithTitle: _(@"New...")
action: @selector(new:) action: @selector(new:)
keyEquivalent: @"n"]; keyEquivalent: @"n"];
[subMenu addItemWithTitle: _(@"New from databse...")
action: @selector(newFromDatabase:)
keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Open") [subMenu addItemWithTitle: _(@"Open")
action: @selector(open:) action: @selector(open:)
keyEquivalent: @""]; keyEquivalent: @"o"];
[subMenu addItemWithTitle: _(@"Save") [subMenu addItemWithTitle: _(@"Save")
action: @selector(save:) action: @selector(save:)
@ -138,10 +166,11 @@
action: @selector(switchAdaptor:) action: @selector(switchAdaptor:)
keyEquivalent: @""]; keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Check consistency") [ConsistencyChecker class];
[[subMenu addItemWithTitle: _(@"Check consistency")
action: @selector(checkConsistency:) action: @selector(checkConsistency:)
keyEquivalent: @""]; keyEquivalent: @""] setRepresentedObject:[ConsistencyResults sharedConsistencyPanel]];
[mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle:_(@"Model")]]; [mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle:_(@"Model")]];
[subMenu release]; [subMenu release];
@ -150,10 +179,16 @@
[subMenu addItemWithTitle:_(@"Inspector") [subMenu addItemWithTitle:_(@"Inspector")
action: @selector(showInspector:) action: @selector(showInspector:)
keyEquivalent: @"i"]; keyEquivalent: @"i"];
[subMenu addItemWithTitle: _(@"Generate SQL")
action: @selector(generateSQL:)
keyEquivalent: @""];
[mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Tools")]]; [mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Tools")]];
[subMenu release]; [subMenu release];
subMenu = [[NSMenu alloc] init]; subMenu = [[NSMenu alloc] init];
[subMenu setAutoenablesItems:YES];
[subMenu addItemWithTitle: _(@"Add entity") [subMenu addItemWithTitle: _(@"Add entity")
action: @selector(addEntity:) action: @selector(addEntity:)
keyEquivalent: @"e"]; keyEquivalent: @"e"];
@ -165,6 +200,9 @@
[subMenu addItemWithTitle: _(@"Add relationship") [subMenu addItemWithTitle: _(@"Add relationship")
action: @selector(addRelationship:) action: @selector(addRelationship:)
keyEquivalent: @"r"]; keyEquivalent: @"r"];
[subMenu addItemWithTitle: _(@"delete")
action: @selector(delete:)
keyEquivalent: @""];
[mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Property")]]; [mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Property")]];
[subMenu release]; [subMenu release];
@ -178,33 +216,66 @@
keyEquivalent: @"q"]; keyEquivalent: @"q"];
[NSApp setMainMenu: mainMenu]; [NSApp setMainMenu: mainMenu];
/* make this a bundle? */ /* make this a default? */
[EOModelerDocument setDefaultEditorClass: NSClassFromString(@"MainModelEditor")]; [EOModelerDocument setDefaultEditorClass: NSClassFromString(@"MainModelEditor")];
[[mainMenu window] makeKeyAndOrderFront:self]; }
- (void) _newDocumentWithModel:(EOModel *)newModel
{
EOModelerDocument *newModelerDoc;
EOModelerCompoundEditor *editor;
newModelerDoc = [[EOModelerDocument alloc] initWithModel: newModel];
RELEASE(newModel);
editor = (EOModelerCompoundEditor*)[newModelerDoc addDefaultEditor];
[EOMApp setCurrentEditor: editor];
[EOMApp addDocument: newModelerDoc];
RELEASE(newModelerDoc);
[newModelerDoc activate];
} }
- (void)new:(id)sender - (void)new:(id)sender
{ {
/* this entire function -really- seems to belong somewhere else */
EOModelerCompoundEditor *editor;
EOModelerDocument *newModelerDoc;
EOModel *newModel = [[EOModel alloc] init]; EOModel *newModel = [[EOModel alloc] init];
EOAdaptor *newAdaptor;
NSString *modelName; NSString *modelName;
unsigned int nDocs; unsigned int nDocs;
//[newModel setCreateMutableObjects:YES];
nDocs = [[EOMApp documents] count]; nDocs = [[EOMApp documents] count];
modelName=[NSString stringWithFormat:@"Model_%u",++nDocs]; modelName=[NSString stringWithFormat:@"Model_%u",++nDocs];
[newModel setName:modelName]; [newModel setName:modelName];
[[EOModelGroup defaultGroup] addModel:newModel]; [self _newDocumentWithModel:newModel];
}
newModelerDoc = [[EOModelerDocument alloc] initWithModel: newModel];
editor = (EOModelerCompoundEditor*)[newModelerDoc addDefaultEditor]; - (void) newFromDatabase:(id)sender
[EOMApp setCurrentEditor: editor]; {
[EOMApp addDocument: newModelerDoc]; NSString *adaptorName;
[newModelerDoc activate]; EOAdaptor *adaptor;
EOAdaptorChannel *channel;
EOAdaptorContext *ctxt;
EOModel *newModel;
AdaptorsPanel *adaptorsPanel = [[AdaptorsPanel alloc] init];
adaptorName = [adaptorsPanel runAdaptorsPanel];
RELEASE(adaptorsPanel);
adaptor = [EOAdaptor adaptorWithName:adaptorName];
[adaptor setConnectionDictionary:[adaptor runLoginPanel]];
ctxt = [adaptor createAdaptorContext];
channel = [ctxt createAdaptorChannel];
[channel openChannel];
newModel = [channel describeModelWithTableNames:[channel describeTableNames]];
[newModel setConnectionDictionary:[adaptor connectionDictionary]];
[newModel setName: [[adaptor connectionDictionary] objectForKey:@"databaseName"]];
[channel closeChannel];
[self _newDocumentWithModel:newModel];
}
- (BOOL) validateMenuItem:(NSMenuItem *)menuItem
{
if ([[menuItem title] isEqualToString:@"Set Adaptor Info"])
{
return ([EOMApp activeDocument] != nil);
}
return YES;
} }
- (void) setAdaptor:(id)sender - (void) setAdaptor:(id)sender
@ -229,6 +300,7 @@
- (void) open:(id)sender - (void) open:(id)sender
{ {
NSOpenPanel *panel = [NSOpenPanel openPanel]; NSOpenPanel *panel = [NSOpenPanel openPanel];
if ([panel runModalForTypes:[NSArray arrayWithObject:@"eomodeld"]] == NSOKButton) if ([panel runModalForTypes:[NSArray arrayWithObject:@"eomodeld"]] == NSOKButton)
{ {
NSArray *modelPaths = [panel filenames]; NSArray *modelPaths = [panel filenames];
@ -238,13 +310,17 @@
{ {
NSString *modelPath = [modelPaths objectAtIndex:i]; NSString *modelPath = [modelPaths objectAtIndex:i];
EOModel *model = [[EOModel alloc] initWithContentsOfFile:modelPath]; EOModel *model = [[EOModel alloc] initWithContentsOfFile:modelPath];
EOModelerDocument *newDoc = [[EOModelerDocument alloc] initWithModel:model];
EOModelerEditor *editor = (EOModelerCompoundEditor*)[newDoc addDefaultEditor]; [self _newDocumentWithModel:model];
[EOMApp setCurrentEditor: editor]; RELEASE(model);
[EOMApp addDocument: newDoc];
[newDoc activate];
} }
} }
} }
- (void) generateSQL:(id)sender
{
[[SQLGenerator sharedGenerator] openSQLGenerator:self];
}
@end @end

View file

@ -56,10 +56,8 @@
{ {
NSScrollView *scrollView; NSScrollView *scrollView;
KVDataSource *wds1, *wds2; KVDataSource *wds1, *wds2;
int i,c;
NSPopUpButton *cornerView; NSPopUpButton *cornerView;
NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""]; NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""];
NSArray *columnNames;
self = [super initWithParentEditor:parentEditor]; self = [super initWithParentEditor:parentEditor];
[DefaultColumnProvider class]; [DefaultColumnProvider class];
@ -175,7 +173,8 @@
return NO; return NO;
selection = [selection objectAtIndex:0]; selection = [selection objectAtIndex:0];
flag = ([selection isKindOfClass:[EOEntity class]] flag = ([selection isKindOfClass:[EOEntity class]]
|| [selection isKindOfClass:[EORelationship class]]); || [selection isKindOfClass:[EOAttribute class]]
|| [selection isKindOfClass:[EORelationship class]]);
return flag; return flag;
} }
@ -232,10 +231,14 @@
- (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup - (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup
{ {
NSArray *currentSelection = [_parentEditor selectionWithinViewedObject]; NSArray *currentSelection = [_parentEditor selectionWithinViewedObject];
id theSelection; id theSelection;
int c = [currentSelection count]; int c = [currentSelection count];
if (c && c == 1 )
if (!c)
return;
else
theSelection = [currentSelection objectAtIndex:0]; theSelection = [currentSelection objectAtIndex:0];
if ([theSelection isKindOfClass:[EOEntity class]]) if ([theSelection isKindOfClass:[EOEntity class]])

View file

@ -67,7 +67,6 @@
} }
selection = [selection objectAtIndex:0]; selection = [selection objectAtIndex:0];
flag = [selection isKindOfClass:[EOModel class]]; flag = [selection isKindOfClass:[EOModel class]];
//NSLog(@"%@ %@ %i", [self class], NSStringFromSelector(_cmd), flag);
return flag; return flag;
} }
@ -76,17 +75,21 @@
return [NSArray arrayWithObjects: [ModelerAttributeEditor class], nil]; return [NSArray arrayWithObjects: [ModelerAttributeEditor class], nil];
} }
- (void) dealloc
{
[EOObserverCenter removeObserver:self forObject:[[self document] model]];
RELEASE(_splitView);
[dg setDataSource:nil];
RELEASE(dg);
[super dealloc];
}
- (id) initWithParentEditor: (EOModelerCompoundEditor *)parentEditor - (id) initWithParentEditor: (EOModelerCompoundEditor *)parentEditor
{ {
if (self = [super initWithParentEditor:parentEditor]) if ((self = [super initWithParentEditor:parentEditor]))
{ {
id columnProvider;
NSTableColumn *tc;
EOClassDescription *classDescription = nil; EOClassDescription *classDescription = nil;
KVDataSource *wds; KVDataSource *wds;
NSArray *columnNames;
int i;
Class editorClass = [EOEntity class];
NSScrollView *scrollView; NSScrollView *scrollView;
NSPopUpButton *cornerView; NSPopUpButton *cornerView;
NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""]; NSMenuItem *mi = [[NSMenuItem alloc] initWithTitle:@"+" action:(SEL)nil keyEquivalent:@""];
@ -101,7 +104,9 @@
_bottomTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; _bottomTable = [[NSTableView alloc] initWithFrame:NSMakeRect(0,0,10,10)];
[_topTable setAutoresizesAllColumnsToFit:YES]; [_topTable setAutoresizesAllColumnsToFit:YES];
[scrollView setDocumentView:_topTable]; [scrollView setDocumentView:_topTable];
RELEASE(_topTable);
[_splitView addSubview:scrollView]; [_splitView addSubview:scrollView];
RELEASE(scrollView);
scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,10,10)]; scrollView = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,10,10)];
[scrollView setHasHorizontalScroller:YES]; [scrollView setHasHorizontalScroller:YES];
@ -109,7 +114,10 @@
[scrollView setBorderType: NSBezelBorder]; [scrollView setBorderType: NSBezelBorder];
[_bottomTable setAutoresizesAllColumnsToFit:YES]; [_bottomTable setAutoresizesAllColumnsToFit:YES];
[scrollView setDocumentView:_bottomTable]; [scrollView setDocumentView:_bottomTable];
RELEASE(_bottomTable);
[_splitView addSubview:scrollView]; [_splitView addSubview:scrollView];
RELEASE(scrollView);
[DefaultColumnProvider class]; // calls +initialize [DefaultColumnProvider class]; // calls +initialize
@ -125,6 +133,7 @@
[[cornerView cell] setShowsFirstResponder:NO]; [[cornerView cell] setShowsFirstResponder:NO];
[[cornerView cell] setShowsStateBy:NSContentsCellMask]; [[cornerView cell] setShowsStateBy:NSContentsCellMask];
[[cornerView cell] setMenuItem:mi]; [[cornerView cell] setMenuItem:mi];
RELEASE(mi);
[[cornerView cell] setImagePosition:NSNoImage]; [[cornerView cell] setImagePosition:NSNoImage];
[_topTable setCornerView:cornerView]; [_topTable setCornerView:cornerView];
@ -141,6 +150,7 @@
dg = [[EODisplayGroup alloc] init]; dg = [[EODisplayGroup alloc] init];
[EOObserverCenter addObserver:self forObject:[[self document] model]]; [EOObserverCenter addObserver:self forObject:[[self document] model]];
[dg setDataSource: wds]; [dg setDataSource: wds];
RELEASE(wds);
[dg setFetchesOnLoad:YES]; [dg setFetchesOnLoad:YES];
[dg setDelegate: self]; [dg setDelegate: self];
@ -156,6 +166,7 @@
} }
return self; return self;
} }
- (NSArray *)defaultColumnNamesForClass:(Class)aClass - (NSArray *)defaultColumnNamesForClass:(Class)aClass
{ {
NSArray *colNames = [super defaultColumnNamesForClass:aClass]; NSArray *colNames = [super defaultColumnNamesForClass:aClass];
@ -194,7 +205,6 @@
@implementation ModelerEntityEditor (DisplayGroupDelegate) @implementation ModelerEntityEditor (DisplayGroupDelegate)
- (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup - (void) displayGroupDidChangeSelection:(EODisplayGroup *)displayGroup
{ {
//NSLog(@"didChangeSelection %@ %@",dg,[dg selectedObjects]);
[self setSelectionWithinViewedObject: [displayGroup selectedObjects]]; [self setSelectionWithinViewedObject: [displayGroup selectedObjects]];
} }

View file

@ -87,6 +87,7 @@
/* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */ /* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */
[tv addTableColumn:tc]; [tv addTableColumn:tc];
RELEASE(tc);
[provider initColumn:tc class:aClass name:columnName [provider initColumn:tc class:aClass name:columnName
displayGroup:dg document:[self document]]; displayGroup:dg document:[self document]];
@ -111,7 +112,7 @@
/* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */ /* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */
[tv addTableColumn:tc]; [tv addTableColumn:tc];
RELEASE(tc);
/* this requires that the table at least have 1 table column in it... /* this requires that the table at least have 1 table column in it...
* so we have to have another method to setup the default table columns */ * so we have to have another method to setup the default table columns */
[provider initColumn:tc [provider initColumn:tc

View file

@ -0,0 +1,25 @@
{
"## Comment" = "Do NOT change this file, Gorm maintains it";
ConsistencyResults = {
Actions = (
"showConsistencyCheckResults:",
"ok:",
"cancel:"
);
Outlets = (
_panel,
cancelButton,
results,
okButton
);
Super = NSObject;
};
FirstResponder = {
Actions = (
"newAction1:",
"newAction:",
"showConsistencyCheckResults:"
);
Super = NSObject;
};
}

Binary file not shown.

View file

@ -0,0 +1,35 @@
{
"## Comment" = "Do NOT change this file, Gorm maintains it";
FirstResponder = {
Actions = (
"executeSQL:",
"switchChanged:",
"openSesame:",
"saveAs:",
"showTables:"
);
Super = NSObject;
};
SQLGenerator = {
Actions = (
"openSesame:",
"executeSQL:",
"switchChanged:",
"saveAs:",
"showTables:"
);
Outlets = (
dropDatabaseSwitch,
createDatabaseSwitch,
dropTablesSwitch,
createTablesSwitch,
dropPKSwitch,
createPKSwitch,
createPKConstraintsSwitch,
createFKConstraintsSwitch,
_sqlOutput,
_window
);
Super = NSObject;
};
}

Binary file not shown.

Binary file not shown.

56
DBModeler/SQLGenerator.h Normal file
View file

@ -0,0 +1,56 @@
/**
SQLGenerator.h
Author: Matt Rice <ratmice@yahoo.com>
Date: Jul 2005
This file is part of DBModeler.
<license>
DBModeler 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.
DBModeler 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 DBModeler; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
</license>
**/
#include <Foundation/NSObject.h>
#include <AppKit/NSNibDeclarations.h>
@class NSWindow;
@class NSButton;
@class NSTextView;
@interface SQLGenerator : NSObject
{
IBOutlet NSWindow *_window;
IBOutlet NSButton *dropDatabaseSwitch;
IBOutlet NSButton *createDatabaseSwitch;
IBOutlet NSButton *dropTablesSwitch;
IBOutlet NSButton *createTablesSwitch;
IBOutlet NSButton *dropPKSwitch;
IBOutlet NSButton *createPKSwitch;
IBOutlet NSButton *createPKConstraintsSwitch;
IBOutlet NSButton *createFKConstraintsSwitch;
IBOutlet NSTextView *_sqlOutput;
}
+(SQLGenerator *) sharedGenerator;
- (void) openSQLGenerator:(id)sender;
- (void) generate;
- (IBAction) switchChanged:(id)sender;
- (IBAction) executeSQL:(id)sender;
- (IBAction) saveAs:(id)sender;
- (IBAction) showTables:(id)sender;
@end

266
DBModeler/SQLGenerator.m Normal file
View file

@ -0,0 +1,266 @@
/**
SQLGenerator.m
Author: Matt Rice <ratmice@yahoo.com>
Date: Jul 2005
This file is part of DBModeler.
<license>
DBModeler 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.
DBModeler 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 DBModeler; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
</license>
**/
#include "SQLGenerator.h"
#include <Foundation/NSException.h>
#include <Foundation/NSDictionary.h>
#include <AppKit/NSNibLoading.h>
#include <AppKit/NSButton.h>
#include <AppKit/NSTextView.h>
#include <AppKit/NSSavePanel.h>
#include <AppKit/NSWindow.h>
#include <EOAccess/EOAdaptor.h>
#include <EOAccess/EOAdaptorChannel.h>
#include <EOAccess/EOAdaptorContext.h>
#include <EOAccess/EOSchemaGeneration.h>
#include <EOAccess/EOSQLExpression.h>
#include <EOAccess/EOModel.h>
#include <EOModeler/EOModelerApp.h>
#include <EOModeler/EOModelerDocument.h>
static SQLGenerator *sharedGenerator;
static BOOL loadedNib;
static BOOL goodToGo;
static NSMutableArray *adminSwitchButtons;
static NSMutableArray *otherSwitchButtons;
NSMutableDictionary *opts;
static NSString *_adminScript;
static NSString *_otherScript;
@implementation SQLGenerator : NSObject
+ (SQLGenerator *) sharedGenerator;
{
if (!sharedGenerator)
sharedGenerator = [[self allocWithZone:NSDefaultMallocZone()] init];
return sharedGenerator;
}
- (id) init
{
if (sharedGenerator)
{
[[NSException exceptionWithName:NSInternalInconsistencyException
reason: @"singleton initialized multiple times"
userInfo:nil] raise];
return nil;
}
self = [super init];
adminSwitchButtons = [[NSMutableArray alloc] initWithCapacity:3];
otherSwitchButtons = [[NSMutableArray alloc] initWithCapacity:7];
opts = [[NSMutableDictionary alloc] initWithCapacity:8];
loadedNib = [NSBundle loadNibNamed:@"SQLGenerator" owner:self];
return self;
}
- (void) awakeFromNib
{
[[dropDatabaseSwitch cell] setRepresentedObject: EODropDatabaseKey];
[[createDatabaseSwitch cell] setRepresentedObject: EOCreateDatabaseKey];
[[dropTablesSwitch cell] setRepresentedObject: EODropTablesKey];
[[createTablesSwitch cell] setRepresentedObject:EOCreateTablesKey];
[[dropPKSwitch cell] setRepresentedObject:EODropPrimaryKeySupportKey];
[[createPKSwitch cell] setRepresentedObject:EOCreatePrimaryKeySupportKey];
[[createPKConstraintsSwitch cell] setRepresentedObject:EOPrimaryKeyConstraintsKey];
[[createFKConstraintsSwitch cell] setRepresentedObject:EOForeignKeyConstraintsKey];
[adminSwitchButtons addObject:dropDatabaseSwitch];
[adminSwitchButtons addObject:createDatabaseSwitch];
[otherSwitchButtons addObject:dropTablesSwitch];
[otherSwitchButtons addObject:createTablesSwitch];
[otherSwitchButtons addObject:dropPKSwitch];
[otherSwitchButtons addObject:createPKSwitch];
[otherSwitchButtons addObject:createPKConstraintsSwitch];
[otherSwitchButtons addObject:createFKConstraintsSwitch];
goodToGo = YES;
}
- (void) openSQLGenerator:(id)sender;
{
while (loadedNib && !goodToGo)
{
/* wait.. */
}
[_window makeKeyAndOrderFront:self];
}
- (IBAction) executeSQL:(id)sender
{
EOAdaptor *adaptor = [[EOMApp activeDocument] adaptor];
EOAdaptorContext *context;
EOAdaptorChannel *channel;
Class exprClass = [[[EOMApp activeDocument] adaptor] expressionClass];
EOSQLExpression *expr;
NSDictionary *connDict = RETAIN([adaptor connectionDictionary]);
if ([[_sqlOutput string] length] == 0)
return;
if ([adaptor hasOpenChannels])
{
NSArray *contexts = [adaptor contexts];
int i,c;
for (i = 0, c = [contexts count]; i < c; i++)
{
EOAdaptorContext *ctxt = [contexts objectAtIndex:i];
if ([ctxt hasOpenChannels])
{
int j, d;
NSArray *channels = [ctxt channels];
for (j = 0, d = [channels count]; j < d; j++)
{
EOAdaptorChannel *channel = [channels objectAtIndex:j];
if ([channel isOpen])
[channel closeChannel];
}
}
}
}
context = [adaptor createAdaptorContext];
channel = [context createAdaptorChannel];
if (_adminScript && [_adminScript length]
&& [[connDict objectForKey:@"adaptorName"] isEqual:@"Postgres95EOAdaptor"])
{
NSMutableDictionary *tmp = RETAIN([NSMutableDictionary dictionaryWithDictionary:connDict]);
[tmp setObject:@"template1" forKey:@"databaseName"];
[adaptor setConnectionDictionary:tmp];
}
if (_adminScript && [_adminScript length])
{
NS_DURING
[channel openChannel];
NS_HANDLER
NSLog(@"admin exception%@ %@ %@", [localException name], [localException reason], [localException userInfo]);
NS_ENDHANDLER
expr = [exprClass expressionForString:_adminScript];
NS_DURING
[channel evaluateExpression:expr];
NS_HANDLER
NSLog(@"admin exception%@ %@ %@", [localException name], [localException reason], [localException userInfo]);
NS_ENDHANDLER
if ([channel isOpen])
[channel closeChannel];
}
if (_otherScript && [_otherScript length])
{
[adaptor setConnectionDictionary:connDict];
NS_DURING
[channel openChannel];
NS_HANDLER
NSLog(@"exception %@ %@ %@", [localException name], [localException reason], [localException userInfo]);
NS_ENDHANDLER
expr = [exprClass expressionForString:_otherScript];
NS_DURING
[channel evaluateExpression:expr];
NS_HANDLER
NSLog(@"exception %@ %@ %@", [localException name], [localException reason], [localException userInfo]);
NS_ENDHANDLER
if ([channel isOpen])
[channel closeChannel];
}
RELEASE(connDict);
}
- (IBAction) showTables:(id)sender
{
}
- (IBAction) saveAs:(id)sender
{
id savePanel = [NSSavePanel savePanel];
NSString *path;
int result = [savePanel runModal];
if (result == NSOKButton)
{
path = [savePanel filename];
}
[[_sqlOutput string] writeToFile:path atomically:YES];
}
- (IBAction) switchChanged:(id)sender
{
RELEASE(_adminScript);
RELEASE(_otherScript);
[self generate];
}
- (void) generate
{
Class expr = [[[EOMApp activeDocument] adaptor] expressionClass];
NSArray *arr;
int i, c;
NSButton *btn;
for (i = 0, c = [adminSwitchButtons count]; i < c; i++)
{
btn = [adminSwitchButtons objectAtIndex:i];
[opts setObject:([[btn objectValue] boolValue]) ? @"YES" : @"NO"
forKey: [[btn cell] representedObject]];
}
for (i = 0, c = [otherSwitchButtons count]; i < c; i++)
{
btn = [otherSwitchButtons objectAtIndex:i];
[opts setObject:@"NO" forKey:[[btn cell] representedObject]];
}
arr = [[[EOMApp activeDocument] model] entities];
_adminScript = RETAIN([expr schemaCreationScriptForEntities:arr
options:opts]);
for (i = 0, c = [adminSwitchButtons count]; i < c; i++)
{
btn = [adminSwitchButtons objectAtIndex:i];
[opts setObject:@"NO" forKey:[[btn cell] representedObject]];
}
for (i = 0, c = [otherSwitchButtons count]; i < c; i++)
{
btn = [otherSwitchButtons objectAtIndex:i];
[opts setObject:([[btn objectValue] boolValue]) ? @"YES" : @"NO"
forKey: [[btn cell] representedObject]];
}
arr = [[[EOMApp activeDocument] model] entities];
_otherScript = RETAIN([expr schemaCreationScriptForEntities:arr
options:opts]);
[_sqlOutput setString:[_adminScript stringByAppendingString:_otherScript]];
}
@end