* 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>
* EOAccess/EOAdaptorContext.h/m (-channels:): New method.
@ -58,6 +121,7 @@
2005-05-11 Matt Rice <ratmice@yahoo.com>
* GNUmakefile: Compile EOInterface, EOModeler, DBModeler, GDL2Palette
if gui is installed.
* EOModeler/EOModelExtensions.h: Update copyright header.
@ -3893,4 +3957,3 @@
-objectStoreForFetchSpecification:]): bug fix: changed notification
object.

View file

@ -44,7 +44,7 @@ static NSArray *_adaptorNames;
- (id) init
{
if (self = [super init])
if ((self = [super init]))
{
_adaptorNames = RETAIN([EOAdaptor availableAdaptorNames]);
/* redo all these numbers so buttons and labels are on the right? */
@ -53,15 +53,8 @@ static NSArray *_adaptorNames;
styleMask: NSBorderlessWindowMask | NSTitledWindowMask
backing: NSBackingStoreBuffered
defer: YES];
_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]];
[_window setTitle: @"Select adaptor"];
brws_adaptors = [[NSBrowser alloc] initWithFrame: NSMakeRect(5,30,190,240)];
[brws_adaptors setDelegate: self];
[brws_adaptors addColumn];
@ -80,7 +73,6 @@ static NSArray *_adaptorNames;
[btn_cancel setTarget: self];
[btn_cancel setAction: @selector(cancel:)];
[[_window contentView] addSubview: _label];
[[_window contentView] addSubview: brws_adaptors];
[[_window contentView] addSubview: btn_ok];
[[_window contentView] addSubview: btn_cancel];
@ -96,7 +88,6 @@ static NSArray *_adaptorNames;
- (NSString *) runAdaptorsPanel
{
NSString *selection;
BOOL response = NO;
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 */
static id attribute_columns[][3] = {
@"allowsNull", @"Allows null", nil,
@"isClassProperty", @"Class property", uhuh,
@"columnName", @"Column name", uhuh,
@"definition", @"Definition", nil,
@"externalType", @"External Type", uhuh,
@"isUsedForLocking", @"Locking", uhuh,
@"name", @"Name", uhuh,
@"precision", @"Precision", nil,
@"isPrimaryKey", @"Primary key", uhuh,
@"readFormat", @"Read format", nil,
@"scale", @"Scale", nil,
@"valueClassName", @"Value class name", uhuh,
@"valueType", @"Value type", nil,
@"width", @"Width", uhuh,
@"writeFormat", @"Write format", nil
{@"allowNull", @"Allows null", uhuh},
{@"isClassProperty", @"Class property", uhuh},
{@"columnName", @"Column name", uhuh},
{@"definition", @"Definition", nil},
{@"externalType", @"External Type", uhuh},
{@"isUsedForLocking", @"Locking", uhuh},
{@"name", @"Name", uhuh},
{@"precision", @"Precision", nil},
{@"isPrimaryKey", @"Primary key", uhuh},
{@"readFormat", @"Read format", nil},
{@"scale", @"Scale", nil},
{@"valueClassName", @"Value class name", uhuh},
{@"valueType", @"Value type", nil},
{@"width", @"Width", uhuh},
{@"writeFormat", @"Write format", nil}
};
static id relationship_columns[][3]= {
@"isClassProperty", @"Class Property", uhuh,
@"definition", @"Definition", nil,
@"name", @"Name", uhuh,
@"destinationEntity.name", @"Destination Entity", uhuh
{@"isClassProperty", @"Class property", uhuh},
{@"definition", @"Definition", nil},
{@"name", @"Name", uhuh},
{@"destinationEntity.name", @"Destination Entity", uhuh}
};
static id entity_columns[][3] = {
@"name", @"Name", uhuh,
@"className", @"Class name", uhuh,
@"externalName", @"External name", uhuh,
@"externalQuery", @"External query", nil,
@"parentEntity.name", @"Parent", nil
{@"name", @"Name", uhuh},
{@"className", @"Class name", uhuh},
{@"externalName", @"External name", uhuh},
{@"externalQuery", @"External query", nil},
{@"parentEntity.name", @"Parent", nil}
};
@ -101,7 +101,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
{
id *objects;
id *keys;
int i,c;
int i;
size_t size;
NSDictionary *tmp;
size = (count * sizeof(id));
@ -156,6 +156,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
- (NSCell *)cellForColumnNamed:(NSString *)name
{
/* TODO need a switch button for "Locking" and "Allows null" */
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 setControlSize: NSSmallControlSize];
[cell setEditable:YES];
return cell;
return AUTORELEASE(cell);
}
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 setControlSize: NSSmallControlSize];
[cell setEditable:YES];
return cell;
return AUTORELEASE(cell);
}
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 setControlSize: NSSmallControlSize];
[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
{
@ -202,7 +215,7 @@ void registerColumnsForClass(id columns[][3], int count, Class aClass,NSMutableA
[cell setEnabled:YES];
[cell setEditable:YES];
[cell setScrollable: YES];
return cell;
return AUTORELEASE(cell);
}
}

View file

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

View file

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

View file

@ -11,35 +11,150 @@
#include <Foundation/NSArray.h>
@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
{
[destEntity_tableView setAllowsEmptySelection:NO];
[srcAttrib_tableView setAllowsEmptySelection:NO];
[destAttrib_tableView setAllowsEmptySelection:NO];
}
- (float) displayOrder
{
return 0;
}
- (BOOL) canInspectObject:(id)anObject
{
return [anObject isKindOfClass:[EORelationship class]];
}
- (void) updateConnectButton
{
[connect_button setState: ([self selectedJoin] != nil) ? NSOnState : NSOffState];
}
- (void) refresh
{
EOModel *activeModel = [[EOMApp activeDocument] model];
EOEntity *destEntity;
EOAttribute *srcAttrib, *destAttrib;
NSArray *srcAttribs;
NSArray *destAttribs;
NSArray *joins;
unsigned int row;
[name_textField setStringValue:[(EORelationship *)[self selectedObject] name]];
/* it is important that the destEntity has a selected row before the destAttrib tableview
* reloads data */
[destEntity_tableView reloadData];
@ -51,45 +166,29 @@
row = 0;
}
else if ([destEntity_tableView numberOfRows])
row = 0;
row = 0;
[destEntity_tableView selectRow:row byExtendingSelection:NO];
srcAttribs = [[self selectedObject] sourceAttributes];
if (srcAttribs && [srcAttribs count])
srcAttrib = [srcAttribs objectAtIndex:0];
joins = [[self selectedObject] joins];
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
srcAttrib = nil;
{
[srcAttrib_tableView selectRow:0 byExtendingSelection:NO];
[destAttrib_tableView selectRow:0 byExtendingSelection:NO];
}
[srcAttrib_tableView reloadData];
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];
[self updateConnectButton];
[joinCardinality_matrix selectCellWithTag:[[self selectedObject] isToMany]];
[joinSemantic_popup selectItemAtIndex: [joinSemantic_popup indexOfItemWithTag: [[self selectedObject] joinSemantic]]];
@ -110,6 +209,7 @@
return [[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] count];
}
return 0;
}
- (id) tableView:(NSTableView *)tv
@ -133,6 +233,8 @@ row:(int)rowIndex
return [(EOAttribute *)[[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]]
attributes] objectAtIndex:rowIndex] name];
}
return nil;
}
- (void) tableViewSelectionDidChange:(NSNotification *)notif
@ -143,24 +245,76 @@ row:(int)rowIndex
{
[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
{
EOEntity *destEntity;
EOAttribute *srcAttrib;
EOAttribute *destAttrib;
EOModel *model;
EOJoin *newJoin;
EOJoin *join;
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];
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];
if (destEnt != [[self selectedObject] destinationEntity])
[destEntity_tableView reloadData];
}
- (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 */
[[self selectedObject] setToMany: [[sender selectedCell] tag]];
}
@end

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -87,6 +87,7 @@
/* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */
[tv addTableColumn:tc];
RELEASE(tc);
[provider initColumn:tc class:aClass name:columnName
displayGroup:dg document:[self document]];
@ -111,7 +112,7 @@
/* THIS *MUST* be before initColumn:class:name:displayGroup:document calls */
[tv addTableColumn:tc];
RELEASE(tc);
/* 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 */
[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