You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(13) |
Sep
(25) |
Oct
(10) |
Nov
(19) |
Dec
(20) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
|
Feb
(206) |
Mar
(43) |
Apr
(25) |
May
(20) |
Jun
(69) |
Jul
(121) |
Aug
(95) |
Sep
(122) |
Oct
(213) |
Nov
(46) |
Dec
(39) |
2006 |
Jan
(28) |
Feb
(57) |
Mar
(21) |
Apr
(7) |
May
(11) |
Jun
(2) |
Jul
(8) |
Aug
(13) |
Sep
(2) |
Oct
(2) |
Nov
(20) |
Dec
(16) |
2007 |
Jan
(9) |
Feb
(15) |
Mar
|
Apr
(4) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
(1) |
Sep
(9) |
Oct
|
Nov
(1) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
(8) |
Apr
(1) |
May
|
Jun
|
Jul
(11) |
Aug
(57) |
Sep
(2) |
Oct
(6) |
Nov
|
Dec
(7) |
2010 |
Jan
(11) |
Feb
(1) |
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
(1) |
Aug
(2) |
Sep
(27) |
Oct
(3) |
Nov
(7) |
Dec
(1) |
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(10) |
Oct
|
Nov
|
Dec
|
2012 |
Jan
(8) |
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
|
Oct
(3) |
Nov
(1) |
Dec
(1) |
2013 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(3) |
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(4) |
Dec
|
2015 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
(1) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(3) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
(4) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(3) |
Oct
|
Nov
(4) |
Dec
|
2022 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
From: <sr...@us...> - 2006-12-18 02:19:23
|
Revision: 743 http://svn.sourceforge.net/instantobjects/revision/?rev=743&view=rev Author: srmitch Date: 2006-12-17 18:19:20 -0800 (Sun, 17 Dec 2006) Log Message: ----------- - Added the changes for IME behaviour: Class B has a base class A and subclasses C, D, etc. making a three tier class hierarchy. If Class B is deleted classes C, D, etc. will become subclasses of class A. Previously they would become subclasses of TInstantObject. - Added the changes for IME behaviour: New class B in model unit X has a base class A in model unit Y. When adding new class B, unit Y will be automatically added to the Interface uses clause of unit X. - Changes to InstantCode unit so that whenever a unit is added to the uses clause of an interface section, that unit is removed from the implementation section uses clause if present. Whenever a unit is added to the implementation section uses clause, check the interface section uses clause and if the unit is there then don't add anything. Modified Paths: -------------- trunk/Source/Core/InstantCode.pas Modified: trunk/Source/Core/InstantCode.pas =================================================================== --- trunk/Source/Core/InstantCode.pas 2006-12-12 02:14:37 UTC (rev 742) +++ trunk/Source/Core/InstantCode.pas 2006-12-18 02:19:20 UTC (rev 743) @@ -875,6 +875,7 @@ procedure SetStorageName(const Value: string); procedure SetUnitName(const Value: string); procedure RemoveDivision(Division: TInstantCodeDivision); + procedure SetSubClass(Index: Integer; const Value: TInstantCodeClass); protected function AddDivision(Visibility: TInstantCodeVisibility): TInstantCodeDivision; procedure InsertDivision(Division: TInstantCodeDivision); @@ -889,7 +890,7 @@ procedure SetName(const Value: string); override; procedure VisibilityFilter(Sender: TInstantCodeObject; var Include: Boolean; Arg: Pointer); - procedure AddUses(const AUnitNames: array of string; Scope: + procedure AddUses(AUnitNames: array of string; Scope: TInstantCodeScope; var Source: string; ChangeInfo: TInstantCodeClassChangeInfo); property SubClassList: TList read GetSubClassList; @@ -949,7 +950,8 @@ property Properties[Index: Integer]: TInstantCodeProperty read GetProperties; property PropertyCount: Integer read GetPropertyCount; property SubClassCount: Integer read GetSubClassCount; - property SubClasses[Index: Integer]: TInstantCodeClass read GetSubClass; + property SubClasses[Index: Integer]: TInstantCodeClass read GetSubClass write + SetSubClass; published property BaseClassName: string read GetBaseClassName write SetBaseClassName; property Persistence: TInstantPersistence read GetPersistence write SetPersistence; @@ -1393,6 +1395,7 @@ FModule: TInstantCodeModule; FProject: TInstantCodeProject; FReader: TInstantCodeReader; + procedure CheckBaseClassAddUsers(AClass: TInstantCodeClass); procedure CreateModule; procedure CreateReader; procedure DestroyReader; @@ -1417,6 +1420,7 @@ function AddProc(Template: TInstantCodeProc): TInstantCodeProc; function AddProperty(AClass: TInstantCodeClass; Template: TInstantCodeProperty): TInstantCodeProperty; procedure AddUses(const AUnitNames: array of string; Scope: TInstantCodeScope = scInterface); + procedure AdjustForUnitNamesInInterface(var AUnitNames: array of string); procedure ChangeAttribute(AClass: TInstantCodeClass; Name: string; Template: TInstantCodeAttribute); procedure ChangeClass(ChangeInfo: TInstantCodeClassChangeInfo; NewClass: TInstantCodeClass); @@ -1447,6 +1451,8 @@ procedure MoveCursor(Count: Integer); function NextChar: Char; function ReadToken: string; + procedure RemoveUses(const AUnitNames: array of string; Scope: + TInstantCodeScope = scInterface); procedure ReplaceObjectText(AObject: TInstantCodeObject); procedure ReplaceText(Len: Integer; const Str: string); procedure Skip(Str: string); @@ -4823,18 +4829,25 @@ Result := TInstantCodeProperty(AddMember(TInstantCodeProperty, Visibility)); end; -procedure TInstantCodeClass.AddUses(const AUnitNames: array of string; +procedure TInstantCodeClass.AddUses(AUnitNames: array of string; Scope: TInstantCodeScope; var Source: string; ChangeInfo: TInstantCodeClassChangeInfo); var Modifier: TInstantCodeModifier; begin + if Length(AUnitNames) = 0 then + Exit; + if Assigned(ChangeInfo.Modifier) then Modifier := ChangeInfo.Modifier else Modifier := TInstantCodeModifier.Create(Source, Self.Project); try + if Scope = scImplementation then + Modifier.AdjustForUnitNamesInInterface(AUnitNames); Modifier.AddUses(AUnitNames, Scope); + if Scope = scInterface then + Modifier.RemoveUses(AUnitNames, scImplementation); finally if not Assigned(ChangeInfo.Modifier) then Modifier.Free; @@ -4913,7 +4926,12 @@ end; destructor TInstantCodeClass.Destroy; +var + I: Integer; begin + if SubClassCount > 0 then + for I := Pred(SubClassCount) to 0 do + SubClasses[I].BaseClass := BaseClass; RemoveFromBase; while SubClassCount > 0 do SubClasses[0].BaseClass := nil; @@ -5384,6 +5402,12 @@ MetadataInfo.StorageName := Value; end; +procedure TInstantCodeClass.SetSubClass(Index: Integer; const Value: + TInstantCodeClass); +begin + SubClassList[Index] := Value; +end; + procedure TInstantCodeClass.SetUnitName(const Value: string); var NewModule: TInstantCodeModule; @@ -7368,6 +7392,7 @@ AddImplementation; UpdateClassRegistration(nil, AClass); UpdateClassForward(nil, AClass); + CheckBaseClassAddUsers(AClass); end; function TInstantCodeModifier.AddField(AClass: TInstantCodeClass; @@ -7517,57 +7542,70 @@ end; procedure TInstantCodeModifier.AddUses(const AUnitNames: array of string; Scope: TInstantCodeScope); -var - Section: TInstantCodeSection; - UsesClause: TInstantCodeUsesClause; - iNames: Integer; - sStr: string; -begin - { check for an empty array } - if Length(AUnitNames) = 0 then - Exit; - with Module do - if Scope = scInterface then - Section := InterfaceSection else - Section := ImplementationSection; - with Section do + procedure AddUsesClause(ASection: TInstantCodeSection; + AUsesClause: TInstantCodeUsesClause); + var + sStr: string; + iNames: Integer; begin sStr := ''; - UsesClause := FindUsesClause; - if Assigned(UsesClause) then + for iNames := Low(AUnitNames) to High(AUnitNames) do begin - { check an existing uses clause and add missing units } - for iNames := Low(AUnitNames) to High(AUnitNames) do - { build the required string first } - if (AUnitNames[iNames] <> '') and - not Assigned(UsesClause.Find(AUnitNames[iNames])) then + if AUnitNames[iNames] <> '' then + if sStr = '' then + sStr := ' ' + AUnitNames[iNames] + else sStr := sStr + ', ' + AUnitNames[iNames]; - if sStr <> '' then - begin - InsertMode := imBefore; - CursorPos := UsesClause.EndPos; - MoveCursor(-1); - InsertText(sStr, True); - end; - end - else + end; + + if sStr <> '' then begin - { uses clause was not found, add all units } InsertMode := imAfter; - CursorPos := StartPos; + CursorPos := ASection.StartPos; SkipLine; - for iNames := Low(AUnitNames) to High(AUnitNames) do - begin - if AUnitNames[iNames] <> '' then - if sStr = '' then - sStr := ' ' + AUnitNames[iNames] - else - sStr := sStr + ', ' + AUnitNames[iNames]; - end; - InsertText(CRLF + 'uses' + CRLF + sStr + ';' + CRLF) + InsertText(CRLF + 'uses' + CRLF + sStr + ';' + CRLF); end; end; + + procedure UpdateUsesClause(ASection: TInstantCodeSection; + AUsesClause: TInstantCodeUsesClause); + var + sStr: string; + iNames: Integer; + begin + sStr := ''; + for iNames := Low(AUnitNames) to High(AUnitNames) do + if (AUnitNames[iNames] <> '') and + not Assigned(AUsesClause.Find(AUnitNames[iNames])) then + sStr := sStr + ', ' + AUnitNames[iNames]; + + if sStr <> '' then + begin + InsertMode := imBefore; + CursorPos := AUsesClause.EndPos; + MoveCursor(-1); + InsertText(sStr, True); + end; + end; + +var + Section: TInstantCodeSection; + UsesClause: TInstantCodeUsesClause; +begin + if Length(AUnitNames) = 0 then + Exit; + + if Scope = scInterface then + Section := Module.InterfaceSection + else + Section := Module.ImplementationSection; + + UsesClause := Section.FindUsesClause; + if Assigned(UsesClause) then + UpdateUsesClause(Section, UsesClause) + else + AddUsesClause(Section, UsesClause); end; procedure TInstantCodeModifier.ChangeAttribute(AClass: TInstantCodeClass; @@ -7649,6 +7687,7 @@ ChangeClassMetadata(OldClass, NewClass); UpdateClassRegistration(OldClass, NewClass); UpdateClassForward(OldClass, NewClass); + CheckBaseClassAddUsers(NewClass); end; procedure TInstantCodeModifier.ChangeClassBase(AClass: TInstantCodeClass; @@ -7974,6 +8013,19 @@ end; end; + procedure UpdateSubclassesBaseClass(AClass: TInstantCodeClass); + var + I: Integer; + begin + for I := 0 to Pred(AClass.SubClassCount) do + begin + if AClass.BaseClassName <> '' then + ChangeClassBase(AClass.SubClasses[I], AClass.BaseClassName) + else + ChangeClassBase(AClass.SubClasses[I], 'TInstantObject'); + end; + end; + var OldClass: TInstantCodeClass; begin @@ -7982,6 +8034,7 @@ OldClass := Module.FindClass(AClass.Name); if not Assigned(OldClass) then Exit; + UpdateSubclassesBaseClass(OldClass); UpdateClassRegistration(OldClass, nil); UpdateClassForward(OldClass, nil); DeleteImplementation(OldClass); @@ -8088,6 +8141,159 @@ inherited; end; +procedure TInstantCodeModifier.AdjustForUnitNamesInInterface(var AUnitNames: + array of string); +var + Section: TInstantCodeSection; + UsesClause: TInstantCodeUsesClause; + iNames: Integer; +begin + if Length(AUnitNames) = 0 then + Exit; + + Section := Module.InterfaceSection; + UsesClause := Section.FindUsesClause; + if Assigned(UsesClause) then + begin + { check the uses clause and remove names of found units from array } + for iNames := Low(AUnitNames) to High(AUnitNames) do + if (AUnitNames[iNames] <> '') and + Assigned(UsesClause.Find(AUnitNames[iNames])) then + AUnitNames[iNames] := ''; + end; +end; + +procedure TInstantCodeModifier.RemoveUses(const AUnitNames: array of string; + Scope: TInstantCodeScope = scInterface); + + function EraseTrailingUsesItem(const AUsesItem: TInstantCodeUses; + const AUsesClause: TInstantCodeUsesClause): Boolean; + var + SavePos: TInstantCodePos; + Ch: Char; + Pos: TInstantCodePos; + begin + Result := False; + if not Assigned(AUsesItem) or not Assigned(AUsesClause) then + Exit; + + with FReader do + begin + SavePos := Position; + Position := AUsesItem.StartPos; + Pos := Position; + Ch := BackChar; + while (Position.Offset > AUsesClause.StartPos.Offset) and + not IsText(Ch) do + begin + if (Ch = ',') then + begin + Pos := Position; + Break; + end; + Ch := BackChar; + end; + Result := not (Pos.Offset = AUsesItem.StartPos.Offset); + if Result then + DeleteTo(AUsesItem.EndPos) + else + Position := SavePos; + end; + end; + + function EraseFirstUsesItem(const AUsesItem: TInstantCodeUses; + const AUsesClause: TInstantCodeUsesClause): Boolean; + var + SavePos: TInstantCodePos; + Ch: Char; + Pos: TInstantCodePos; + begin + Result := False; + if not Assigned(AUsesItem) or not Assigned(AUsesClause) then + Exit; + + with FReader do + begin + SavePos := Position; + Position := AUsesItem.EndPos; + Pos := Position; + Ch := ReadChar; + while (Position.Offset <= AUsesClause.EndPos.Offset) and + not IsText(Ch) do + begin + if (Ch = ',') then + begin + SkipSpace; + Pos := Position; + Break; + end; + Ch := ReadChar; + end; + Result := not (Pos.Offset = AUsesItem.EndPos.Offset); + if Result then + DeleteFrom(AUsesItem.StartPos) + else + Position := SavePos; + end; + end; + + procedure EraseUsesItem(const AUsesItem: TInstantCodeUses; + AUsesClause: TInstantCodeUsesClause); + begin + if not EraseTrailingUsesItem(AUsesItem, AUsesClause) then + EraseFirstUsesItem(AUsesItem, AUsesClause); + end; + + procedure EraseUsesClause(AUsesClause: TInstantCodeUsesClause); + begin + EraseObject(AUsesClause); + CloseGap; + CloseGap; + end; + +var + Section: TInstantCodeSection; + UsesClause: TInstantCodeUsesClause; + iNames: Integer; + UsesItem: TInstantCodeUses; +begin + if Length(AUnitNames) = 0 then + Exit; + + if Scope = scInterface then + Section := Module.InterfaceSection + else + Section := Module.ImplementationSection; + + UsesClause := Section.FindUsesClause; + if not Assigned(UsesClause) then + Exit; + + for iNames := Low(AUnitNames) to High(AUnitNames) do + if (AUnitNames[iNames] <> '') then + begin + UsesItem := UsesClause.Find(AUnitNames[iNames]); + if Assigned(UsesItem) then + begin + if UsesClause.ObjectCount > 1 then + EraseUsesItem(UsesItem, UsesClause) + else + begin + EraseUsesClause(UsesClause); + Break; + end; + end; + end; +end; + +procedure TInstantCodeModifier.CheckBaseClassAddUsers(AClass: + TInstantCodeClass); +begin + if Assigned(AClass.BaseClass) and + (AClass.Module.Name <> AClass.BaseClass.Module.Name) then + AddUses([AClass.BaseClass.Module.Name]); +end; + procedure TInstantCodeModifier.DestroyReader; begin FreeAndNil(FReader); |
From: <sr...@us...> - 2006-12-12 02:14:39
|
Revision: 742 http://svn.sourceforge.net/instantobjects/revision/?rev=742&view=rev Author: srmitch Date: 2006-12-11 18:14:37 -0800 (Mon, 11 Dec 2006) Log Message: ----------- - Updated NexusDb broker for new InstantDate and InstantTime support. - Added InstantTypes to Implementation uses clause in InstantNexusDBEmbeddedConnectionDefEdit.pas. Modified Paths: -------------- trunk/Source/Brokers/NexusDb/InstantNexusDB.pas trunk/Source/Brokers/NexusDb/InstantNexusDBCatalog.pas trunk/Source/Brokers/NexusDb/InstantNexusDBEmbeddedConnectionDefEdit.pas Modified: trunk/Source/Brokers/NexusDb/InstantNexusDB.pas =================================================================== --- trunk/Source/Brokers/NexusDb/InstantNexusDB.pas 2006-12-11 16:45:35 UTC (rev 741) +++ trunk/Source/Brokers/NexusDb/InstantNexusDB.pas 2006-12-12 02:14:37 UTC (rev 742) @@ -793,7 +793,9 @@ 'VARCHAR', 'TEXT', 'DATETIME', - 'BLOB'); + 'BLOB', + 'DATE', + 'TIME'); begin Result := Types[DataType]; if (DataType = dtString) and (Size > 0) then @@ -824,7 +826,7 @@ Result := TInstantNexusDBSQLGenerator; end; -{ TInstantNexusDBSQLTranslator } +{ TInstantNexusDBTranslator } function TInstantNexusDBTranslator.GetDelimiters: string; begin Modified: trunk/Source/Brokers/NexusDb/InstantNexusDBCatalog.pas =================================================================== --- trunk/Source/Brokers/NexusDb/InstantNexusDBCatalog.pas 2006-12-11 16:45:35 UTC (rev 741) +++ trunk/Source/Brokers/NexusDb/InstantNexusDBCatalog.pas 2006-12-12 02:14:37 UTC (rev 742) @@ -239,10 +239,12 @@ DataType := dtCurrency else if SameText(ColumnType, 'Boolean') then DataType := dtBoolean - else if SameText(ColumnType, 'DateTime') - or SameText(ColumnType, 'Date') - or SameText(ColumnType, 'Time')then + else if SameText(ColumnType, 'DateTime') then DataType := dtDateTime + else if SameText(ColumnType, 'DATE') then + DataType := dtDate + else if SameText(ColumnType, 'TIME')then + DataType := dtTime else if SameText(ColumnType, 'BLOB') then DataType := dtBlob else if SameText(ColumnType, 'BLOB Memo') then @@ -264,10 +266,12 @@ DataType := dtCurrency else if SameText(ColumnType, 'nxtBoolean') then DataType := dtBoolean - else if SameText(ColumnType, 'nxtDateTime') - or SameText(ColumnType, 'nxtDate') - or SameText(ColumnType, 'nxtTime')then + else if SameText(ColumnType, 'nxtDateTime') then DataType := dtDateTime + else if SameText(ColumnType, 'nxtDate') then + DataType := dtDate + else if SameText(ColumnType, 'nxtTime')then + DataType := dtTime else if SameText(ColumnType, 'nxtBlob') then DataType := dtBlob else if SameText(ColumnType, 'nxtBlobMemo') then Modified: trunk/Source/Brokers/NexusDb/InstantNexusDBEmbeddedConnectionDefEdit.pas =================================================================== --- trunk/Source/Brokers/NexusDb/InstantNexusDBEmbeddedConnectionDefEdit.pas 2006-12-11 16:45:35 UTC (rev 741) +++ trunk/Source/Brokers/NexusDb/InstantNexusDBEmbeddedConnectionDefEdit.pas 2006-12-12 02:14:37 UTC (rev 742) @@ -106,6 +106,7 @@ InstantClasses, InstantPersistence, InstantConsts, + InstantTypes, InstantNexusDBConsts; { TInstantNexusDBEmbeddedConnectionDefEditForm } |
From: <bvs...@us...> - 2006-12-11 16:45:38
|
Revision: 741 http://svn.sourceforge.net/instantobjects/revision/?rev=741&view=rev Author: bvsimmons Date: 2006-12-11 08:45:35 -0800 (Mon, 11 Dec 2006) Log Message: ----------- Support for InstantDate and InstantTime for UIB Broker Modified Paths: -------------- trunk/Source/Brokers/UIB/InstantUIB.pas Modified: trunk/Source/Brokers/UIB/InstantUIB.pas =================================================================== --- trunk/Source/Brokers/UIB/InstantUIB.pas 2006-12-11 04:12:04 UTC (rev 740) +++ trunk/Source/Brokers/UIB/InstantUIB.pas 2006-12-11 16:45:35 UTC (rev 741) @@ -454,7 +454,9 @@ 'VARCHAR', 'BLOB SUB_TYPE 1', 'TIMESTAMP', - 'BLOB'); + 'BLOB', + 'DATE', + 'TIME'); function TInstantUIBBroker.DataTypeToColumnType( DataType: TInstantDataType; Size: Integer): string; |
From: <sr...@us...> - 2006-12-11 04:12:07
|
Revision: 740 http://svn.sourceforge.net/instantobjects/revision/?rev=740&view=rev Author: srmitch Date: 2006-12-10 20:12:04 -0800 (Sun, 10 Dec 2006) Log Message: ----------- - Added remainder of fix for SF BT 1612909 - "AV from IO Model Explorer with second model unit". First part of fix already committed to InstantCode.pas in previous SVN update. Modified Paths: -------------- trunk/Source/Design/InstantModelExplorer.pas Modified: trunk/Source/Design/InstantModelExplorer.pas =================================================================== --- trunk/Source/Design/InstantModelExplorer.pas 2006-12-11 01:06:06 UTC (rev 739) +++ trunk/Source/Design/InstantModelExplorer.pas 2006-12-11 04:12:04 UTC (rev 740) @@ -513,7 +513,14 @@ if Assigned(BaseClass) then NewClass.Persistence := BaseClass.Persistence; if EditClass(NewClass, True) then - UpdateModel + begin + if NewClass.Module.Name <> Module.Name then + begin + Module.RemoveType(NewClass); + NewClass.Module.InsertType(NewClass); + end; + UpdateModel; + end else NewClass.Free end; |
From: <bvs...@us...> - 2006-12-11 01:06:05
|
Revision: 739 http://svn.sourceforge.net/instantobjects/revision/?rev=739&view=rev Author: bvsimmons Date: 2006-12-10 17:06:06 -0800 (Sun, 10 Dec 2006) Log Message: ----------- Updated InstantPersistence.pas to support InstantDate and InstantTime data types. Found a missing change. Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-12-11 00:35:04 UTC (rev 738) +++ trunk/Source/Core/InstantPersistence.pas 2006-12-11 01:06:06 UTC (rev 739) @@ -388,7 +388,6 @@ FValue: TDateTime; function DefaultValue: TDateTime; protected - class function AttributeType: TInstantAttributeType; override; function GetAsDateTime: TDateTime; override; function GetAsString: string; override; function GetAsVariant: Variant; override; |
From: <bvs...@us...> - 2006-12-11 00:35:04
|
Revision: 738 http://svn.sourceforge.net/instantobjects/revision/?rev=738&view=rev Author: bvsimmons Date: 2006-12-10 16:35:04 -0800 (Sun, 10 Dec 2006) Log Message: ----------- Updated InterBase/Firebird Catalog to support InstantDate and InstantTime data types and not step on changes made by David Moorehouse Modified Paths: -------------- trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas Modified: trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas =================================================================== --- trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas 2006-12-11 00:17:56 UTC (rev 737) +++ trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas 2006-12-11 00:35:04 UTC (rev 738) @@ -242,8 +242,12 @@ DataType := dtInteger; 10, 27: //FLOAT, DOUBLE DataType := dtFloat; - 12,13,35: // DATE, TIME, TIMESTAMP - will need refactoring to support proposed TDate and TTime types + 35: // TIMESTAMP DataType := dtDateTime; + 12: // DATE + DataType := dtDate; + 13: // TIME + DataType := dtTime; 14, 37: // TEXT, VARYING DataType := dtString; 16: // INT64 |
From: <bvs...@us...> - 2006-12-11 00:17:58
|
Revision: 737 http://svn.sourceforge.net/instantobjects/revision/?rev=737&view=rev Author: bvsimmons Date: 2006-12-10 16:17:56 -0800 (Sun, 10 Dec 2006) Log Message: ----------- Support for InstantDate and InstantTime Modified Paths: -------------- trunk/Demos/PrimerCross/DemoData.pas trunk/Demos/PrimerCross/Model/Model.pas trunk/Demos/PrimerCross/ModelExternal/Model.pas trunk/Demos/PrimerCross/PersonEdit.dfm trunk/Demos/PrimerCross/PersonEdit.pas trunk/Demos/PrimerCross/Primer.mdr trunk/Demos/PrimerCross/PrimerExternal.mdr trunk/Source/Brokers/ADO/InstantADO.pas trunk/Source/Brokers/BDE/InstantBDE.pas trunk/Source/Brokers/BDE/InstantBDECatalog.pas trunk/Source/Brokers/DBX/InstantDBX.pas trunk/Source/Brokers/IBX/InstantIBX.pas trunk/Source/Catalogs/MSSql/InstantMSSqlCatalog.pas trunk/Source/Core/InstantBrokers.pas trunk/Source/Core/InstantCode.pas trunk/Source/Core/InstantMetadata.pas trunk/Source/Core/InstantPersistence.pas trunk/Source/Core/InstantPresentation.pas trunk/Source/Core/InstantTypes.pas trunk/Tests/TestIO.dpr trunk/Tests/TestIO.mdr trunk/Tests/TestInstantDateTime.pas trunk/Tests/TestModel.pas Added Paths: ----------- trunk/Docs/InstantDate-InstantTime Release Notes.txt trunk/Tests/TestInstantDate.pas trunk/Tests/TestInstantTime.pas Modified: trunk/Demos/PrimerCross/DemoData.pas =================================================================== --- trunk/Demos/PrimerCross/DemoData.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Demos/PrimerCross/DemoData.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -184,6 +184,7 @@ Gender := TGender(Random(2)); Result.Name := RandomFullName(Gender); Result.BirthDate := Date - (20 * 365 + Random(365 * 50)); // 20 - 70 years old + Result.BirthTime := Random; Result.Address := CreateRandomAddress; // Result.Salary := 922337203685470; Result.Salary := 500 + Random(5000); Modified: trunk/Demos/PrimerCross/Model/Model.pas =================================================================== --- trunk/Demos/PrimerCross/Model/Model.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Demos/PrimerCross/Model/Model.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -8,7 +8,7 @@ interface uses - InstantPersistence; + InstantPersistence, InstantTypes; type TAddress = class; @@ -21,6 +21,7 @@ TPerson = class; TPhone = class; + TAddress = class(TInstantObject) {IOMETADATA City: String(30) index; Country: Reference(TCountry); @@ -164,25 +165,29 @@ TPerson = class(TContact) {IOMETADATA stored; - BirthDate: DateTime; Emails: Parts(TEmail); Employer: Reference(TCompany); Picture: Graphic; - Salary: Currency; } - _BirthDate: TInstantDateTime; + Salary: Currency; + BirthDate: Date; + BirthTime: Time; } + _BirthDate: TInstantDate; + _BirthTime: TInstantTime; _Emails: TInstantParts; _Employer: TInstantReference; _Picture: TInstantGraphic; _Salary: TInstantCurrency; private - function GetBirthDate: TDateTime; + function GetBirthDate: TDate; + function GetBirthTime: TTime; function GetEmailCount: Integer; function GetEmails(Index: Integer): TEmail; function GetEmployer: TCompany; function GetMainEmailAddress: string; function GetPicture: string; function GetSalary: Currency; - procedure SetBirthDate(Value: TDateTime); + procedure SetBirthDate(Value: TDate); + procedure SetBirthTime(Value: TTime); procedure SetEmails(Index: Integer; Value: TEmail); procedure SetMainEmailAddress(const Value: string); procedure SetPicture(const Value: string); @@ -200,7 +205,8 @@ property EmailCount: Integer read GetEmailCount; property Emails[Index: Integer]: TEmail read GetEmails write SetEmails; published - property BirthDate: TDateTime read GetBirthDate write SetBirthDate; + property BirthDate: TDate read GetBirthDate write SetBirthDate; + property BirthTime: TTime read GetBirthTime write SetBirthTime; property Employer: TCompany read GetEmployer; property MainEmailAddress: string read GetMainEmailAddress write SetMainEmailAddress; property Picture: string read GetPicture write SetPicture; @@ -390,11 +396,16 @@ end; end; -function TPerson.GetBirthDate: TDateTime; +function TPerson.GetBirthDate: TDate; begin Result := _BirthDate.Value; end; +function TPerson.GetBirthTime: TTime; +begin + Result := _BirthTime.Value; +end; + function TPerson.GetEmailCount: Integer; begin Result := _Emails.Count @@ -443,11 +454,16 @@ Result := _Emails.Remove(Email); end; -procedure TPerson.SetBirthDate(Value: TDateTime); +procedure TPerson.SetBirthDate(Value: TDate); begin _BirthDate.Value := Value; end; +procedure TPerson.SetBirthTime(Value: TTime); +begin + _BirthTime.Value := Value; +end; + procedure TPerson.SetEmails(Index: Integer; Value: TEmail); begin _Emails[Index] := Value; Modified: trunk/Demos/PrimerCross/ModelExternal/Model.pas =================================================================== --- trunk/Demos/PrimerCross/ModelExternal/Model.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Demos/PrimerCross/ModelExternal/Model.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -8,7 +8,7 @@ interface uses - InstantPersistence; + InstantPersistence, InstantTypes; type TAddress = class; @@ -167,25 +167,29 @@ TPerson = class(TContact) {IOMETADATA stored; - BirthDate: DateTime; Emails: Parts(TEmail) external 'Person_Emails'; Employer: Reference(TCompany); Picture: Graphic; - Salary: Currency; } - _BirthDate: TInstantDateTime; + Salary: Currency; + BirthDate: Date; + BirthTime: Time; } + _BirthDate: TInstantDate; + _BirthTime: TInstantTime; _Emails: TInstantParts; _Employer: TInstantReference; _Picture: TInstantGraphic; _Salary: TInstantCurrency; private - function GetBirthDate: TDateTime; + function GetBirthDate: TDate; + function GetBirthTime: TTime; function GetEmailCount: Integer; function GetEmails(Index: Integer): TEmail; function GetEmployer: TCompany; function GetMainEmailAddress: string; function GetPicture: string; function GetSalary: Currency; - procedure SetBirthDate(Value: TDateTime); + procedure SetBirthDate(Value: TDate); + procedure SetBirthTime(Value: TTime); procedure SetEmails(Index: Integer; Value: TEmail); procedure SetMainEmailAddress(const Value: string); procedure SetPicture(const Value: string); @@ -203,7 +207,8 @@ property EmailCount: Integer read GetEmailCount; property Emails[Index: Integer]: TEmail read GetEmails write SetEmails; published - property BirthDate: TDateTime read GetBirthDate write SetBirthDate; + property BirthDate: TDate read GetBirthDate write SetBirthDate; + property BirthTime: TTime read GetBirthTime write SetBirthTime; property Employer: TCompany read GetEmployer; property MainEmailAddress: string read GetMainEmailAddress write SetMainEmailAddress; property Picture: string read GetPicture write SetPicture; @@ -393,11 +398,16 @@ end; end; -function TPerson.GetBirthDate: TDateTime; +function TPerson.GetBirthDate: TDate; begin Result := _BirthDate.Value; end; +function TPerson.GetBirthTime: TTime; +begin + Result := _BirthTime.Value; +end; + function TPerson.GetEmailCount: Integer; begin Result := _Emails.Count; @@ -446,11 +456,16 @@ Result := _Emails.Remove(Email); end; -procedure TPerson.SetBirthDate(Value: TDateTime); +procedure TPerson.SetBirthDate(Value: TDate); begin _BirthDate.Value := Value; end; +procedure TPerson.SetBirthTime(Value: TTime); +begin + _BirthTime.Value := Value; +end; + procedure TPerson.SetEmails(Index: Integer; Value: TEmail); begin _Emails[Index] := Value; Modified: trunk/Demos/PrimerCross/PersonEdit.dfm =================================================================== --- trunk/Demos/PrimerCross/PersonEdit.dfm 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Demos/PrimerCross/PersonEdit.dfm 2006-12-11 00:17:56 UTC (rev 737) @@ -59,7 +59,15 @@ Height = 13 Caption = 'Sa&lary' end - object PicturePanel: TPanel [13] + object Label1: TLabel [13] + Left = 136 + Top = 264 + Width = 44 + Height = 13 + Caption = 'BirthTime' + FocusControl = BirthTimeEdit + end + object PicturePanel: TPanel [14] Left = 332 Top = 203 Width = 76 @@ -95,7 +103,7 @@ Visible = True end> end - object BirthDateEdit: TDBEdit [20] + object BirthDateEdit: TDBEdit [21] Left = 136 Top = 200 Width = 73 @@ -104,7 +112,7 @@ DataSource = SubjectSource TabOrder = 7 end - object EmployerEdit: TDBEdit [21] + object EmployerEdit: TDBEdit [22] Left = 8 Top = 240 Width = 129 @@ -114,7 +122,7 @@ ReadOnly = True TabOrder = 8 end - object EmailsGrid: TDBGrid [22] + object EmailsGrid: TDBGrid [23] Left = 240 Top = 120 Width = 169 @@ -135,7 +143,7 @@ Visible = True end> end - object EmployerToolBar: TToolBar [23] + object EmployerToolBar: TToolBar [24] Left = 140 Top = 237 Width = 69 @@ -175,7 +183,7 @@ OnClick = EmployerClearButtonClick end end - object PictureButton: TButton [24] + object PictureButton: TButton [25] Left = 240 Top = 246 Width = 81 @@ -187,7 +195,7 @@ object SalaryEdit: TDBEdit Left = 8 Top = 280 - Width = 153 + Width = 121 Height = 21 DataField = 'Salary' DataSource = SubjectSource @@ -202,6 +210,15 @@ TabOrder = 15 OnClick = ClearButtonClick end + object BirthTimeEdit: TDBEdit + Left = 136 + Top = 280 + Width = 81 + Height = 21 + DataField = 'BirthTime' + DataSource = SubjectSource + TabOrder = 16 + end end end end Modified: trunk/Demos/PrimerCross/PersonEdit.pas =================================================================== --- trunk/Demos/PrimerCross/PersonEdit.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Demos/PrimerCross/PersonEdit.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -41,6 +41,8 @@ PicturePanel: TPanel; PictureImage: TImage; ClearButton: TButton; + Label1: TLabel; + BirthTimeEdit: TDBEdit; procedure EmployerClearButtonClick(Sender: TObject); procedure EmployerEditButtonClick(Sender: TObject); procedure EmployerLookupButtonClick(Sender: TObject); Modified: trunk/Demos/PrimerCross/Primer.mdr =================================================================== (Binary files differ) Modified: trunk/Demos/PrimerCross/PrimerExternal.mdr =================================================================== (Binary files differ) Added: trunk/Docs/InstantDate-InstantTime Release Notes.txt =================================================================== --- trunk/Docs/InstantDate-InstantTime Release Notes.txt (rev 0) +++ trunk/Docs/InstantDate-InstantTime Release Notes.txt 2006-12-11 00:17:56 UTC (rev 737) @@ -0,0 +1,122 @@ +---------- InstantDate InstantTime Release Notes ----------------- +Summary of Changes for Support of InstantDate and InstantTime Data types. + +Requirements +--------------------------------- +1. Must completely rebuild IO. +2. Must add InstantTypes to Interface Uses class of the model unit(s). if you want to use the new datatypes. + +InstantType.pas defines: +TDate = class(TDateTime); +TTime = class(TDateTime); +The Model Explorer has been modified to automatically or (auto-magically) add the Interface uses clause of your model file(s) with InstantType and the Implementation uses clause with InstantMetadata when you edit your model. + +Files affected : +Core Files modified: +--------------------------------- +InstantBrokers.pas +InstantClasses.pas +InstantCode.pas +InstantMetadata.pas +InstantPersistence.pas +InstantPresentation.pas +InstantTypes.pas + + +Tests Files Modified (* new files) +--------------------------------- +* TestInstantDate.pas +TestInstantDateTime.pas +* TestInstantTime.pas +TestIO.dpr +TestIO.mdr +TestModel.pas + +Document files (Docs Directory) +-------------------------------- +* InstantDateInstantTime_Releasenotes.txt (this document) + +Demos - PrimerCross (Birthtime attribute added to TPerson and random Birthtimes are generated) +--------------------------------- +DemoData.pas +PersonEdit.dfm +PersonEdit.pas +Primer.mdr +PrimerExternal.mdr +Model/model.pas +ModelExternal/model.pas + +Brokers (Note: I only modified the files for the standard set of Brokers which are build in RunTimePackages.bpg). +--------------------------------- +InstantADO.pas +InstantBDE.pas +InstantDBX.pas +InstantIBX.pas + +Note: The following brokers will also need to be modified. +InstantADS.pas +InstantDBISAM.pas +InstantFlashFiler.pas +InstantNexusDB.pas +InstantUIB.pas +InstantZeosDBO.pas + +Catalogs +--------------------------------- +InstantBDECatalog.pas +InstantIBFbCatalog.pas +InstantMSSqlCatalog.pas + +Note: (AFIK InstantXML.pas does not need to be modified) + +Note: +All brokers and catalogs must be modified to account for the two new data types. All standard brokers have been modified to map SQL datatypes for Date and Time. The default is to use DATETIME/TIMESTAMP for Date and Time Datatypes in SQL Brokers. The update has made this modification to all of the standard brokers and catalogs, but you should double check to be sure. If you have your own customized broker/catalog or you are using one of the brokers which is not part of the standard build, you will have to make similar changes as shown in the below mapping between SQL Datatypes and InstantDatatypes: + +function TInstantBDECatalog.ColumnTypeToDataType(const ColumnType: TFieldType; + out DataType: TInstantDataType): Boolean; +begin + Result := True; + case ColumnType of + ftString: DataType := dtString; + ftSmallint, + ftInteger: DataType := dtInteger; + ftBoolean: DataType := dtBoolean; + ftFloat: DataType := dtFloat; + ftCurrency: DataType := dtCurrency; + ftDate: DataType := dtDate; // <- Map Date Fields + ftTime: DataType := dtTime; // <-- Map Time Fields + ftDateTime: DataType := dtDateTime; + ftAutoInc: DataType := dtInteger; + ftBlob, + ftGraphic: DataType := dtBlob; + ftMemo: DataType := dtMemo; + else + Result := False; + end; +end; + +function TInstantADOMSSQLBroker.DataTypeToColumnType( + DataType: TInstantDataType; Size: Integer): string; +const + Types: array[TInstantDataType] of string = ( + 'INTEGER', + 'FLOAT', + 'MONEY', + 'BIT', + 'VARCHAR', + 'TEXT', + 'DATETIME', + 'IMAGE', + 'DATETIME', // <- Map Date Fields + 'DATETIME'); // <- Map Time Fields +begin + Result := Types[DataType]; + if (DataType = dtString) and (Size > 0) then + Result := Result + InstantEmbrace(IntToStr(Size), '()'); +end; + +I haved removed the following that were contained in my uploads to the repository ng. + +1. ACR - Accuracer +2. DBX - Support for ASA-SqlAnyWhere (and it's Catalog 'InstantASACatalog.pas') +3. SDAC - Corelab SQL Server Data Access Components Property changes on: trunk/Docs/InstantDate-InstantTime Release Notes.txt ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/Source/Brokers/ADO/InstantADO.pas =================================================================== --- trunk/Source/Brokers/ADO/InstantADO.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Brokers/ADO/InstantADO.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -107,9 +107,12 @@ function GetDataSet: TCustomADODataSet; protected function CreateDataSet: TDataSet; override; + function CreateNavigationalLinkResolver(const ATableName: string): + TInstantNavigationalLinkResolver; override; function Find(const AClassName, AObjectId: string): Boolean; function Locate(const AClassName, AObjectId: string): Boolean; override; public + function FormatTableName(const ATableName: string): string; virtual; property Broker: TInstantADOBroker read GetBroker; property DataSet: TCustomADODataSet read GetDataSet; end; @@ -148,6 +151,23 @@ property Connector: TInstantADOConnector read GetConnector; end; + TInstantADOLinkResolver = class(TInstantNavigationalLinkResolver) + private + function GetBroker: TInstantADOBroker; + function GetDataSet: TADODataSet; + function GetResolver: TInstantADOResolver; + protected + function CreateDataSet: TDataSet; override; + procedure SetDatasetParentRange(const AParentClass, AParentId: string); + override; + public + constructor Create(AResolver: TInstantNavigationalResolver; const ATableName: + string); + property Broker: TInstantADOBroker read GetBroker; + property DataSet: TADODataSet read GetDataSet; + property Resolver: TInstantADOResolver read GetResolver; + end; + { MS Jet } TInstantADOMSJetBroker = class(TInstantADOBroker) @@ -331,7 +351,9 @@ (adVarChar, adVarWChar, adVarChar, adVarChar, adVarChar, adVarChar), // dtString (adLongVarChar, adLongVarWChar, adLongVarChar, adVarBinary, adLongVarChar, adLongVarChar), // dtMemo (adDate, adDate, adDBTimeStamp, adDBTimeStamp, adDate, adDate), // dtDateTime - (adLongVarBinary, adLongVarBinary, adLongVarBinary, adVarBinary, adLongVarBinary, adLongVarBinary) // dtBlob + (adLongVarBinary, adLongVarBinary, adLongVarBinary, adVarBinary, adLongVarBinary, adLongVarBinary), // dtBlob + (adDate, adDate, adDBTimeStamp, adDBTimeStamp, adDate, adDate), // dtDate + (adDate, adDate, adDBTimeStamp, adDBTimeStamp, adDate, adDate) // dtTime ); var Column: _Column; @@ -447,7 +469,9 @@ 'VARCHAR', 'MEMO', 'DATETIME', - 'BLOB' + 'BLOB', + 'DATE', + 'TIME' ); begin Result := Types[DataType]; @@ -467,6 +491,8 @@ Result := 'TEXT'; dtBlob: Result := 'IMAGE'; + dtDate, dtDateTime: + Result := 'DATETIME'; end; ptOracle: case DataType of @@ -474,7 +500,7 @@ Result := 'CHAR(1)'; dtCurrency: Result := 'DECIMAL(14,4)'; - dtDateTime: + dtDateTime, dtDate, dtTime: Result := 'DATE'; dtBlob: Result := 'BLOB'; @@ -485,7 +511,7 @@ case DataType of dtCurrency: Result := 'DECIMAL(14,4)'; - dtDateTime: + dtDateTime, dtDate, dtTime: Result := 'TIMESTAMP'; dtBlob: Result := 'BLOB (1000 K)'; @@ -795,6 +821,12 @@ end; end; +function TInstantADOResolver.CreateNavigationalLinkResolver( + const ATableName: string): TInstantNavigationalLinkResolver; +begin + Result := TInstantADOLinkResolver.Create(Self, ATableName); +end; + function TInstantADOResolver.Find(const AClassName, AObjectId: string): Boolean; var @@ -837,6 +869,12 @@ end; end; +function TInstantADOResolver.FormatTableName( + const ATableName: string): string; +begin + Result := TableName; +end; + function TInstantADOResolver.GetBroker: TInstantADOBroker; begin Result := inherited Broker as TInstantADOBroker; @@ -1144,7 +1182,9 @@ 'VARCHAR', 'TEXT', 'DATETIME', - 'IMAGE'); + 'IMAGE', + 'DATETIME', + 'DATETIME'); begin Result := Types[DataType]; if (DataType = dtString) and (Size > 0) then @@ -1176,6 +1216,50 @@ { TInstantADOMSSQLQuery } +{ TInstantADOLinkResolver } + +constructor TInstantADOLinkResolver.Create( + AResolver: TInstantNavigationalResolver; const ATableName: string); +begin + inherited Create(AResolver, ATableName); +end; + +function TInstantADOLinkResolver.CreateDataSet: TDataSet; +begin + Result:= TADOTable.Create(nil); + with TADOTable(Result) do + try + Connection := Broker.Connector.Connection; + TableName := Self.TableName; + IndexFieldNames := InstantParentClassFieldName + ';' + + InstantParentIdFieldName; + except + Result.Free; + raise; + end; +end; + +function TInstantADOLinkResolver.GetBroker: TInstantADOBroker; +begin + Result := inherited Broker as TInstantADOBroker; +end; + +function TInstantADOLinkResolver.GetDataSet: TADODataSet; +begin + Result := inherited DataSet as TADODataSet; +end; + +function TInstantADOLinkResolver.GetResolver: TInstantADOResolver; +begin + Result := inherited Resolver as TInstantADOResolver; +end; + +procedure TInstantADOLinkResolver.SetDatasetParentRange(const AParentClass, + AParentId: string); +begin +// Dataset.SetRange([AParentClass, AParentId], [AParentClass, AParentId]); +end; + initialization RegisterClass(TInstantADOConnectionDef); TInstantADOConnector.RegisterClass; Modified: trunk/Source/Brokers/BDE/InstantBDE.pas =================================================================== --- trunk/Source/Brokers/BDE/InstantBDE.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Brokers/BDE/InstantBDE.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -405,7 +405,7 @@ procedure CreateTable(TableMetadata: TInstantTableMetadata); const FieldTypes: array[TInstantDataType] of TFieldType = - (ftInteger, ftFloat, ftBCD, ftBoolean, ftString, ftMemo, ftDateTime, ftBlob); + (ftInteger, ftFloat, ftBCD, ftBoolean, ftString, ftMemo, ftDateTime, ftBlob, ftDate, ftTime); var I: Integer; Table: TTable; @@ -758,7 +758,7 @@ procedure TInstantDBBuildBDEAddTableCommand.InternalExecute; const FieldTypes: array[TInstantDataType] of TFieldType = - (ftInteger, ftFloat, ftCurrency, ftBoolean, ftString, ftMemo, ftDateTime, ftBlob); + (ftInteger, ftFloat, ftCurrency, ftBoolean, ftString, ftMemo, ftDateTime, ftBlob, ftDate, ftTime); var I: Integer; Table: TTable; Modified: trunk/Source/Brokers/BDE/InstantBDECatalog.pas =================================================================== --- trunk/Source/Brokers/BDE/InstantBDECatalog.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Brokers/BDE/InstantBDECatalog.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -171,8 +171,8 @@ ftBoolean: DataType := dtBoolean; ftFloat: DataType := dtFloat; ftCurrency: DataType := dtCurrency; - ftDate, - ftTime, + ftDate: DataType := dtDate; + ftTime: DataType := dtTime; ftDateTime: DataType := dtDateTime; ftAutoInc: DataType := dtInteger; ftBlob, Modified: trunk/Source/Brokers/DBX/InstantDBX.pas =================================================================== --- trunk/Source/Brokers/DBX/InstantDBX.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Brokers/DBX/InstantDBX.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -160,6 +160,14 @@ { MS SQL Server } + TInstantDBXMSSQLSQLGenerator = class(TInstantSQLGenerator) + protected + function InternalGenerateAlterFieldSQL(OldMetadata, NewMetadata: TInstantFieldMetadata): string; override; + function InternalGenerateDropFieldSQL(Metadata: TInstantFieldMetadata): string; override; + function InternalGenerateDropIndexSQL(Metadata: TInstantIndexMetadata): string; override; + function EmbraceIndex(const IndexName: string): string; virtual; + end; + TInstantDBXMSSQLBroker = class(TInstantDBXBroker) protected function CreateCatalog(const AScheme: TInstantScheme): TInstantCatalog; override; @@ -169,6 +177,8 @@ function GetDBMSName: string; override; function GetSQLQuote: Char; override; function InternalCreateQuery: TInstantQuery; override; + public + class function GeneratorClass: TInstantSQLGeneratorClass; override; end; TInstantDBXMSSQLResolver = class(TInstantSQLResolver) @@ -522,7 +532,9 @@ 'VARCHAR', 'BLOB SUB_TYPE 1', 'TIMESTAMP', - 'BLOB'); + 'BLOB', + 'TIMESTAMP', + 'TIMESTAMP'); begin Result := Types[DataType]; end; @@ -564,7 +576,9 @@ 'VARCHAR', 'TEXT', 'DATETIME', - 'IMAGE'); + 'IMAGE', + 'DATETIME', + 'DATETIME'); begin Result := Types[DataType]; end; @@ -581,6 +595,11 @@ Result := TInstantDBXMSSQLResolver.Create(Self, Map); end; +class function TInstantDBXMSSQLBroker.GeneratorClass: TInstantSQLGeneratorClass; +begin + Result := TInstantDBXMSSQLSQLGenerator; +end; + function TInstantDBXMSSQLBroker.GetDBMSName: string; begin Result := 'MS SQL Server'; @@ -596,6 +615,39 @@ Result := TInstantDBXMSSQLQuery.Create(Connector); end; +{ TInstantDBXMSSQLSQLGenerator } + +function TInstantDBXMSSQLSQLGenerator.EmbraceIndex( + const IndexName: string): string; +begin + Result := InstantEmbrace(IndexName, Delimiters); +end; + +function TInstantDBXMSSQLSQLGenerator.InternalGenerateAlterFieldSQL( + OldMetadata, NewMetadata: TInstantFieldMetadata): string; +begin + Result := Format('ALTER TABLE %s ALTER COLUMN %s %s', + [EmbraceTable(OldMetadata.TableMetadata.Name), + EmbraceField(OldMetadata.Name), + Broker.DataTypeToColumnType(NewMetadata.DataType, NewMetadata.Size)]); +end; + +function TInstantDBXMSSQLSQLGenerator.InternalGenerateDropFieldSQL( + Metadata: TInstantFieldMetadata): string; +begin + Result := Format('ALTER TABLE %s DROP COLUMN %s', + [EmbraceTable(Metadata.TableMetadata.Name), + EmbraceField(Metadata.Name)]); +end; + +function TInstantDBXMSSQLSQLGenerator.InternalGenerateDropIndexSQL( + Metadata: TInstantIndexMetadata): string; +begin + Result := Format('DROP INDEX %s.%s', + [EmbraceTable(Metadata.TableMetadata.Name), + EmbraceIndex(Metadata.Name)]); +end; + { TInstantDBXOracleBroker } procedure TInstantDBXOracleBroker.AssignParam(SourceParam, TargetParam: TParam); @@ -621,7 +673,9 @@ 'VARCHAR', 'CLOB', 'DATE', - 'BLOB'); + 'BLOB', + 'DATE', + 'DATE'); begin Result := Types[DataType]; end; @@ -649,7 +703,9 @@ 'VARCHAR', 'CLOB (1000 K)', 'TIMESTAMP', - 'BLOB (1000 K)'); + 'BLOB (1000 K)', + 'TIMESTAMP', + 'TIMESTAMP'); begin Result := Types[DataType]; end; @@ -690,7 +746,9 @@ 'VARCHAR', 'TEXT', 'DATETIME', - 'BLOB'); + 'BLOB', + 'DATE', + 'TIME'); begin Result := Types[DataType]; end; Modified: trunk/Source/Brokers/IBX/InstantIBX.pas =================================================================== --- trunk/Source/Brokers/IBX/InstantIBX.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Brokers/IBX/InstantIBX.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -426,7 +426,9 @@ 'VARCHAR', 'BLOB SUB_TYPE 1', 'TIMESTAMP', - 'BLOB'); + 'BLOB', + 'DATE', + 'TIME'); begin Result := Types[DataType]; if (DataType = dtString) and (Size > 0) then Modified: trunk/Source/Catalogs/MSSql/InstantMSSqlCatalog.pas =================================================================== --- trunk/Source/Catalogs/MSSql/InstantMSSqlCatalog.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Catalogs/MSSql/InstantMSSqlCatalog.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -167,6 +167,8 @@ FieldMetadata := TableMetadata.FieldMetadatas.Add; FieldMetadata.Name := Fields.FieldByName('COLUMN_NAME').AsString; FieldMetadata.DataType := FieldDataType; + if FieldDataType = dtDateTime then + FieldMetadata.AlternateDataTypes := [dtDate, dtTime]; FieldMetadata.Options := []; if Fields.FieldByName('COLUMN_NULLABLE').AsInteger <> 1 then FieldMetadata.Options := FieldMetadata.Options + [foRequired]; @@ -387,6 +389,8 @@ ExternalPartAttributeClass varchar 17 0 129 167 32 32 NULL 1 ExternalPartAttributeId varchar 18 0 129 167 32 32 NULL 1 EmbeddedReferencesAtttribute image 19 0 128 34 16 NULL NULL 1 +DateAttr datetime 8 0 135 61 16 23 3 1 +TimeAttr datetime 8 0 135 61 16 23 3 1 *) end. Modified: trunk/Source/Core/InstantBrokers.pas =================================================================== --- trunk/Source/Core/InstantBrokers.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Core/InstantBrokers.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -316,6 +316,8 @@ procedure ClearBlob(Attribute: TInstantBlob); virtual; procedure ClearBoolean(Attribute: TInstantBoolean); virtual; procedure ClearDateTime(Attribute: TInstantDateTime); virtual; + procedure ClearDate(Attribute: TInstantDate); virtual; + procedure ClearTime(Attribute: TInstantTime); virtual; procedure ClearInteger(Attribute: TInstantInteger); virtual; procedure ClearFloat(Attribute: TInstantFloat); virtual; procedure ClearCurrency(Attribute: TInstantCurrency); virtual; @@ -356,6 +358,8 @@ procedure ReadBlob(Attribute: TInstantBlob); virtual; procedure ReadBoolean(Attribute: TInstantBoolean); virtual; procedure ReadDateTime(Attribute: TInstantDateTime); virtual; + procedure ReadDate(Attribute: TInstantDate); virtual; + procedure ReadTime(Attribute: TInstantTime); virtual; procedure ReadInteger(Attribute: TInstantInteger); virtual; procedure ReadFloat(Attribute: TInstantFloat); virtual; procedure ReadCurrency(Attribute: TInstantCurrency); virtual; @@ -373,6 +377,8 @@ procedure WriteBlob(Attribute: TInstantBlob); virtual; procedure WriteBoolean(Attribute: TInstantBoolean); virtual; procedure WriteDateTime(Attribute: TInstantDateTime); virtual; + procedure WriteDate(Attribute: TInstantDate); virtual; + procedure WriteTime(Attribute: TInstantTime); virtual; procedure WriteFloat(Attribute: TInstantFloat); virtual; procedure WriteCurrency(Attribute: TInstantCurrency); virtual; procedure WriteInteger(Attribute: TInstantInteger); virtual; @@ -464,6 +470,10 @@ Boolean; virtual; function ReadDateTimeField(DataSet: TDataSet; const FieldName: string): TDateTime; virtual; + function ReadDateField(DataSet: TDataSet; const FieldName: string): + TDateTime; virtual; + function ReadTimeField(DataSet: TDataSet; const FieldName: string): + TDateTime; virtual; function ReadFloatField(DataSet: TDataSet; const FieldName: string): Double; virtual; function ReadCurrencyField(DataSet: TDataSet; const FieldName: string): @@ -969,6 +979,7 @@ {$IFDEF D6+} Variants, {$ENDIF} + DateUtils, TypInfo, InstantUtils, InstantRtti; const @@ -1719,6 +1730,10 @@ ClearString(Attribute as TInstantString); atDateTime: ClearDateTime(Attribute as TInstantDateTime); + atDate: + ClearDate(Attribute as TInstantDate); + atTime: + ClearTime(Attribute as TInstantTime); atBlob: ClearBlob(Attribute as TInstantBlob); atGraphic: @@ -1753,6 +1768,14 @@ begin end; +procedure TInstantNavigationalResolver.ClearDate(Attribute: TInstantDate); +begin +end; + +procedure TInstantNavigationalResolver.ClearTime(Attribute: TInstantTime); +begin +end; + procedure TInstantNavigationalResolver.ClearFloat(Attribute: TInstantFloat); begin end; @@ -2083,6 +2106,10 @@ ReadString(Attribute as TInstantString); atDateTime: ReadDateTime(Attribute as TInstantDateTime); + atDate: + ReadDate(Attribute as TInstantDate); + atTime: + ReadTime(Attribute as TInstantTime); atBlob: ReadBlob(Attribute as TInstantBlob); atGraphic: @@ -2126,6 +2153,20 @@ Value := FieldByName(Metadata.FieldName).AsDateTime; end; +procedure TInstantNavigationalResolver.ReadDate( + Attribute: TInstantDate); +begin + with Attribute do + Value := DateOf(FieldByName(Metadata.FieldName).AsDateTime); +end; + +procedure TInstantNavigationalResolver.ReadTime( + Attribute: TInstantTime); +begin + with Attribute do + Value := TimeOf(FieldByName(Metadata.FieldName).AsDateTime); +end; + procedure TInstantNavigationalResolver.ReadFloat(Attribute: TInstantFloat); begin with Attribute do @@ -2320,6 +2361,10 @@ WriteString(Attribute as TInstantString); atDateTime: WriteDateTime(Attribute as TInstantDateTime); + atDate: + WriteDate(Attribute as TInstantDate); + atTime: + WriteTime(Attribute as TInstantTime); atBlob: WriteBlob(Attribute as TInstantBlob); atGraphic: @@ -2367,6 +2412,20 @@ FieldByName(Metadata.FieldName).AsDateTime := Value; end; +procedure TInstantNavigationalResolver.WriteDate( + Attribute: TInstantDate); +begin + with Attribute do + FieldByName(Metadata.FieldName).AsDateTime := Value; +end; + +procedure TInstantNavigationalResolver.WriteTime( + Attribute: TInstantTime); +begin + with Attribute do + FieldByName(Metadata.FieldName).AsDateTime := Value; +end; + procedure TInstantNavigationalResolver.WriteFloat(Attribute: TInstantFloat); begin with Attribute do @@ -2553,6 +2612,18 @@ (Attribute as TInstantDateTime).Value; end; + procedure AddDateAttributeParam; + begin + AddParam(Params, FieldName, ftDate).AsDateTime := + (Attribute as TInstantDate).Value; + end; + + procedure AddTimeAttributeParam; + begin + AddParam(Params, FieldName, ftTime).AsDateTime := + (Attribute as TInstantTime).Value; + end; + procedure AddFloatAttributeParam; begin AddParam(Params, FieldName, ftFloat).AsFloat := @@ -2664,6 +2735,10 @@ AddBooleanAttributeParam; atDateTime: AddDateTimeAttributeParam; + atDate: + AddDateAttributeParam; + atTime: + AddTimeAttributeParam; atFloat: AddFloatAttributeParam; atCurrency: @@ -3236,6 +3311,18 @@ ReadDateTimeField(DataSet, AFieldName); end; + procedure ReadDateAttribute; + begin + (Attribute as TInstantDate).Value := + ReadDateField(DataSet, AFieldName); + end; + + procedure ReadTimeAttribute; + begin + (Attribute as TInstantTime).Value := + ReadTimeField(DataSet, AFieldName); + end; + procedure ReadFloatAttribute; begin (Attribute as TInstantFloat).Value := ReadFloatField(DataSet, AFieldName); @@ -3398,6 +3485,10 @@ ReadStringAttribute; atDateTime: ReadDateTimeAttribute; + atDate: + ReadDateAttribute; + atTime: + ReadTimeAttribute; atBlob, atGraphic: ReadBlobAttribute; atMemo: @@ -3448,6 +3539,18 @@ Result := DataSet.FieldByName(FieldName).AsDateTime; end; +function TInstantSQLResolver.ReadDateField(DataSet: TDataSet; + const FieldName: string): TDateTime; +begin + Result := DateOf(DataSet.FieldByName(FieldName).AsDateTime); +end; + +function TInstantSQLResolver.ReadTimeField(DataSet: TDataSet; + const FieldName: string): TDateTime; +begin + Result := TimeOf(DataSet.FieldByName(FieldName).AsDateTime); +end; + function TInstantSQLResolver.ReadFloatField(DataSet: TDataSet; const FieldName: string): Double; begin Modified: trunk/Source/Core/InstantCode.pas =================================================================== --- trunk/Source/Core/InstantCode.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Core/InstantCode.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -889,6 +889,9 @@ procedure SetName(const Value: string); override; procedure VisibilityFilter(Sender: TInstantCodeObject; var Include: Boolean; Arg: Pointer); + procedure AddUses(const AUnitNames: array of string; Scope: + TInstantCodeScope; var Source: string; ChangeInfo: + TInstantCodeClassChangeInfo); property SubClassList: TList read GetSubClassList; public constructor Create(AOwner: TInstantCodeObject); override; @@ -1241,15 +1244,15 @@ procedure SetModuleTypeName(const Value: string); protected function GetModule: TInstantCodeModule; override; - procedure InsertType(AType: TInstantCodeType); procedure InternalRead(Reader: TInstantCodeReader); override; procedure InternalWrite(Writer: TInstantCodeWriter); override; - procedure RemoveType(AType: TInstantCodeType); public constructor Create(AOwner: TInstantCodeObject); override; destructor Destroy; override; function FindClass(const Name: string): TInstantCodeClass; function FindType(const Name: string): TInstantCodeType; + procedure InsertType(AType: TInstantCodeType); + procedure RemoveType(AType: TInstantCodeType); procedure LoadFromFile(const FileName: string; Scope: TInstantCodeScope); procedure LoadFromStream(Stream: TStream; Scope: TInstantCodeScope); procedure LoadFromString(const Str: string; Scope: TInstantCodeScope); @@ -1413,7 +1416,7 @@ function AddMethod(AClass: TInstantCodeClass; Template: TInstantCodeMethod): TInstantCodeMethod; function AddProc(Template: TInstantCodeProc): TInstantCodeProc; function AddProperty(AClass: TInstantCodeClass; Template: TInstantCodeProperty): TInstantCodeProperty; - procedure AddUses(const AUnitName: string; Scope: TInstantCodeScope); + procedure AddUses(const AUnitNames: array of string; Scope: TInstantCodeScope = scInterface); procedure ChangeAttribute(AClass: TInstantCodeClass; Name: string; Template: TInstantCodeAttribute); procedure ChangeClass(ChangeInfo: TInstantCodeClassChangeInfo; NewClass: TInstantCodeClass); @@ -1570,6 +1573,10 @@ Result := 'string'; atDateTime: Result := 'TDateTime'; + atDate: + Result := 'TDate'; + atTime: + Result := 'TTime'; else Result := ''; end; @@ -1592,8 +1599,9 @@ '', // atPart '', // atReference '', // atParts, - '' // atReferences - ); + '', // atReferences + 'TDate', + 'TTime'); begin for Result := Low(Result) to High(Result) do if SameText(PropType, TypeNames[Result]) then @@ -1615,6 +1623,8 @@ AddObject('String', TStringTypeProcessor.Create); AddObject('Memo', TStringTypeProcessor.Create); AddObject('DateTime', TDateTimeTypeProcessor.Create); + AddObject('Date', TDateTimeTypeProcessor.Create); + AddObject('Time', TDateTimeTypeProcessor.Create); AddObject('Part', TPartTypeProcessor.Create); AddObject('Reference', TObjectTypeProcessor.Create); AddObject('Parts', TContainerTypeProcessor.Create); @@ -4813,6 +4823,24 @@ Result := TInstantCodeProperty(AddMember(TInstantCodeProperty, Visibility)); end; +procedure TInstantCodeClass.AddUses(const AUnitNames: array of string; + Scope: TInstantCodeScope; var Source: string; + ChangeInfo: TInstantCodeClassChangeInfo); +var + Modifier: TInstantCodeModifier; +begin + if Assigned(ChangeInfo.Modifier) then + Modifier := ChangeInfo.Modifier + else + Modifier := TInstantCodeModifier.Create(Source, Self.Project); + try + Modifier.AddUses(AUnitNames, Scope); + finally + if not Assigned(ChangeInfo.Modifier) then + Modifier.Free; + end; +end; + procedure TInstantCodeClass.ApplyToSource(var Source: string; ChangeInfo: TInstantCodeClassChangeInfo); var @@ -4825,7 +4853,6 @@ Modifier := TInstantCodeModifier.Create(Source, Self.Project); try with Modifier do - begin case ChangeInfo.ChangeType of ctNew: AddClass(Self); @@ -4834,12 +4861,13 @@ ctDelete: DeleteClass(Self); end; - AddUses('InstantPersistence', scInterface); - end; finally if not Assigned(ChangeInfo.Modifier) then Modifier.Free; end; + AddUses(['InstantPersistence', 'InstantTypes'], + scInterface, Source, ChangeInfo); + AddUses(['InstantMetadata'], scImplementation, Source, ChangeInfo); end; procedure TInstantCodeClass.AssignAttributes(List: TList); @@ -7488,33 +7516,56 @@ Result.Setter := AddMethod(AClass, Template.Setter); end; -procedure TInstantCodeModifier.AddUses(const AUnitName: string; - Scope: TInstantCodeScope); +procedure TInstantCodeModifier.AddUses(const AUnitNames: array of string; Scope: TInstantCodeScope); var Section: TInstantCodeSection; UsesClause: TInstantCodeUsesClause; + iNames: Integer; + sStr: string; begin + { check for an empty array } + if Length(AUnitNames) = 0 then + Exit; + with Module do if Scope = scInterface then Section := InterfaceSection else Section := ImplementationSection; with Section do begin + sStr := ''; UsesClause := FindUsesClause; if Assigned(UsesClause) then begin - if Assigned(UsesClause.Find(AUnitName)) then - Exit; - InsertMode := imBefore; - CursorPos := UsesClause.EndPos; - MoveCursor(-1); - InsertText(', ' + AUnitName, True); - end else + { check an existing uses clause and add missing units } + for iNames := Low(AUnitNames) to High(AUnitNames) do + { build the required string first } + if (AUnitNames[iNames] <> '') and + not Assigned(UsesClause.Find(AUnitNames[iNames])) then + sStr := sStr + ', ' + AUnitNames[iNames]; + if sStr <> '' then + begin + InsertMode := imBefore; + CursorPos := UsesClause.EndPos; + MoveCursor(-1); + InsertText(sStr, True); + end; + end + else begin + { uses clause was not found, add all units } InsertMode := imAfter; CursorPos := StartPos; SkipLine; - InsertText(CRLF + 'uses' + CRLF + ' ' + AUnitName + ';' + CRLF); + for iNames := Low(AUnitNames) to High(AUnitNames) do + begin + if AUnitNames[iNames] <> '' then + if sStr = '' then + sStr := ' ' + AUnitNames[iNames] + else + sStr := sStr + ', ' + AUnitNames[iNames]; + end; + InsertText(CRLF + 'uses' + CRLF + sStr + ';' + CRLF) end; end; end; Modified: trunk/Source/Core/InstantMetadata.pas =================================================================== --- trunk/Source/Core/InstantMetadata.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Core/InstantMetadata.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -538,9 +538,9 @@ const AttributeClasses: array[TInstantAttributeType] of TInstantAttributeClass = ( nil, TInstantInteger, TInstantFloat, TInstantCurrency, TInstantBoolean, - TInstantString, TInstantDateTime, TInstantBlob, TInstantMemo, + TInstantString, TInstantDateTime, TInstantBlob, TInstantMemo, TInstantGraphic, TInstantPart, TInstantReference, TInstantParts, - TInstantReferences); + TInstantReferences, TInstantDate, TInstantTime); { TInstantMetadata } Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Core/InstantPersistence.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -169,6 +169,8 @@ function GetAsBoolean: Boolean; virtual; function GetAsCurrency: Currency; virtual; function GetAsDateTime: TDateTime; virtual; + function GetAsDate: TDateTime; virtual; + function GetAsTime: TDateTime; virtual; function GetAsFloat: Double; virtual; function GetAsInteger: Integer; virtual; function GetAsObject: TInstantObject; virtual; @@ -184,6 +186,8 @@ procedure SetAsBoolean(AValue: Boolean); virtual; procedure SetAsCurrency(AValue: Currency); virtual; procedure SetAsDateTime(AValue: TDateTime); virtual; + procedure SetAsDate(AValue: TDateTime); virtual; + procedure SetAsTime(AValue: TDateTime); virtual; procedure SetAsFloat(AValue: Double); virtual; procedure SetAsInteger(AValue: Integer); virtual; procedure SetAsObject(AValue: TInstantObject); virtual; @@ -203,6 +207,8 @@ property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; property AsCurrency: Currency read GetAsCurrency write SetAsCurrency; property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime; + property AsDate: TDateTime read GetAsDate write SetAsDate; + property AsTime: TDateTime read GetAsTime write SetAsTime; property AsFloat: Double read GetAsFloat write SetAsFloat; property AsInteger: Integer read GetAsInteger write SetAsInteger; property AsObject: TInstantObject read GetAsObject write SetAsObject; @@ -377,7 +383,7 @@ property Value: string read GetValue write SetValue; end; - TInstantDateTime = class(TInstantSimple) + TInstantCustomDateTime = class(TInstantSimple) private FValue: TDateTime; function DefaultValue: TDateTime; @@ -403,6 +409,32 @@ property Value: TDateTime read GetValue write SetValue; end; + TInstantDateTime = class(TInstantCustomDateTime) + protected + class function AttributeType: TInstantAttributeType; override; + function GetAsDate: TDateTime; override; + function GetAsTime: TDateTime; override; + procedure SetAsDate(AValue: TDateTime); override; + procedure SetAsTime(AValue: TDateTime); override; + end; + + TInstantDate = class(TInstantCustomDateTime) + protected + class function AttributeType: TInstantAttributeType; override; + function GetAsDate: TDateTime; override; + procedure SetValue(AValue: TDateTime); override; + procedure SetAsDate(AValue: TDateTime); override; + end; + + TInstantTime = class(TInstantCustomDateTime) + protected + class function AttributeType: TInstantAttributeType; override; + function GetAsString: string; override; + function GetAsTime: TDateTime; override; + procedure SetValue(AValue: TDateTime); override; + procedure SetAsTime(AValue: TDateTime); override; + end; + TInstantBlob = class(TInstantSimple) private FStream: TMemoryStream; @@ -1542,7 +1574,7 @@ const InstantDataTypeStrings: array[TInstantDataType] of string = - ('Integer', 'Float', 'Currency', 'Boolean', 'String', 'Memo', 'DateTime', 'Blob'); + ('Integer', 'Float', 'Currency', 'Boolean', 'String', 'Memo', 'DateTime', 'Blob', 'Date', 'Time'); procedure AssignInstantDataTypeStrings(Strings: TStrings); @@ -1569,6 +1601,7 @@ {$ELSE} Mask, {$ENDIF} + DateUtils, InstantUtils, {InstantRtti, }InstantDesignHook, InstantCode; var @@ -1643,7 +1676,9 @@ dtBlob, //atPart dtString, //atReference dtBlob, //atParts - dtBlob); //atReferences + dtBlob, //atReferences + dtDate, //atDate + dtTime); //atTime DataTypesXML: array[TInstantAttributeType] of TInstantDataType = ( dtString, //atUnknown @@ -1659,7 +1694,9 @@ dtMemo, //atPart dtString, //atReference dtMemo, //atParts - dtMemo); //atReferences + dtMemo, //atReferences + dtDate, //atDate + dtTime); //atTime begin if BlobStreamFormat = sfBinary then Result := DataTypesBinary[AttributeType] @@ -1677,6 +1714,8 @@ dtString: Result := ftString; dtMemo: Result := ftMemo; dtDateTime: Result := ftDateTime; + dtDate: Result := ftDate; + dtTime: Result := ftTime; dtBlob: Result := ftBlob; else raise EInstantError.CreateFmt(SUnsupportedDataType, @@ -2292,6 +2331,16 @@ raise AccessError('DateTime'); end; +function TInstantAttribute.GetAsDate: TDateTime; +begin + raise AccessError('Date'); +end; + +function TInstantAttribute.GetAsTime: TDateTime; +begin + raise AccessError('Time'); +end; + function TInstantAttribute.GetAsFloat: Double; begin raise AccessError('Float'); @@ -2417,6 +2466,16 @@ raise AccessError('DateTime'); end; +procedure TInstantAttribute.SetAsDate(AValue: TDateTime); +begin + raise AccessError('Date'); +end; + +procedure TInstantAttribute.SetAsTime(AValue: TDateTime); +begin + raise AccessError('Time'); +end; + procedure TInstantAttribute.SetAsFloat(AValue: Double); begin raise AccessError('Float'); @@ -3194,20 +3253,15 @@ { TInstantDateTime } -procedure TInstantDateTime.Assign(Source: TPersistent); +procedure TInstantCustomDateTime.Assign(Source: TPersistent); begin inherited; - if Source is TInstantDateTime then - Value := TInstantDateTime(Source).Value + if Source is TInstantCustomDateTime then + Value := TInstantCustomDateTime(Source).Value end; -class function TInstantDateTime.AttributeType: TInstantAttributeType; +function TInstantCustomDateTime.DefaultValue: TDateTime; begin - Result := atDateTime; -end; - -function TInstantDateTime.DefaultValue: TDateTime; -begin if Assigned(Metadata) and (Metadata.DefaultValue <> '') then if SameText(Metadata.DefaultValue, InstantNowString) then Result := Now @@ -3226,22 +3280,22 @@ Result := 0; end; -function TInstantDateTime.GetAsDateTime: TDateTime; +function TInstantCustomDateTime.GetAsDateTime: TDateTime; begin Result := Value; end; -function TInstantDateTime.GetAsString: string; +function TInstantCustomDateTime.GetAsString: string; begin Result := DateTimeToStr(Value); end; -function TInstantDateTime.GetAsVariant: Variant; +function TInstantCustomDateTime.GetAsVariant: Variant; begin Result := Value; end; -function TInstantDateTime.GetDisplayText: string; +function TInstantCustomDateTime.GetDisplayText: string; begin if AsDateTime = 0 then Result := '' @@ -3253,28 +3307,28 @@ end end; -function TInstantDateTime.GetIsDefault: Boolean; +function TInstantCustomDateTime.GetIsDefault: Boolean; begin Result := Value = DefaultValue; end; -function TInstantDateTime.GetValue: TDateTime; +function TInstantCustomDateTime.GetValue: TDateTime; begin Result := FValue; end; -procedure TInstantDateTime.Initialize; +procedure TInstantCustomDateTime.Initialize; begin FValue := DefaultValue; end; -procedure TInstantDateTime.ReadObject(Reader: TInstantReader); +procedure TInstantCustomDateTime.ReadObject(Reader: TInstantReader); begin ReadName(Reader); Value := Reader.ReadDate; end; -procedure TInstantDateTime.Reset; +procedure TInstantCustomDateTime.Reset; begin if Assigned(Metadata) then Initialize @@ -3283,12 +3337,12 @@ Changed; end; -procedure TInstantDateTime.SetAsDateTime(AValue: TDateTime); +procedure TInstantCustomDateTime.SetAsDateTime(AValue: TDateTime); begin Value := AValue; end; -procedure TInstantDateTime.SetAsString(const AValue: string); +procedure TInstantCustomDateTime.SetAsString(const AValue: string); begin try Value := StrToDateTime(AValue) @@ -3298,7 +3352,7 @@ end; end; -procedure TInstantDateTime.SetAsVariant(AValue: Variant); +procedure TInstantCustomDateTime.SetAsVariant(AValue: Variant); begin try Value := AValue; @@ -3308,7 +3362,7 @@ end; end; -procedure TInstantDateTime.SetValue(AValue: TDateTime); +procedure TInstantCustomDateTime.SetValue(AValue: TDateTime); begin if AValue <> FValue then begin @@ -3317,12 +3371,39 @@ end; end; -procedure TInstantDateTime.WriteObject(Writer: TInstantWriter); +procedure TInstantCustomDateTime.WriteObject(Writer: TInstantWriter); begin WriteName(Writer); Writer.WriteDate(Value); end; +{ TInstantDateTime } + +class function TInstantDateTime.AttributeType: TInstantAttributeType; +begin + Result := atDateTime; +end; + +function TInstantDateTime.GetAsDate: TDateTime; +begin + Result := DateOf(Value); +end; + +function TInstantDateTime.GetAsTime: TDateTime; +begin + Result := TimeOf(Value); +end; + +procedure TInstantDateTime.SetAsDate(AValue: TDateTime); +begin + Value := DateOf(AValue); +end; + +procedure TInstantDateTime.SetAsTime(AValue: TDateTime); +begin + Value := TimeOf(AValue); +end; + { TInstantBlob } procedure TInstantBlob.Assign(Source: TPersistent); @@ -5407,7 +5488,7 @@ Writer.WriteBoolean(SameText(Processor.ReadData, InstantTrueString)); atString, atMemo: Writer.WriteString(Processor.ReadData); - atDateTime: + atDateTime, atDate, atTime: Writer.WriteDate(InstantStrToDateTime(Processor.ReadData)); atBlob, atGraphic: begin @@ -8820,7 +8901,63 @@ inherited Items[Index] := Value; end; +{ TInstantDate } +class function TInstantDate.AttributeType: TInstantAttributeType; +begin + Result := atDate; +end; + +function TInstantDate.GetAsDate: TDateTime; +begin + Result := Value; +end; + +procedure TInstantDate.SetAsDate(AValue: TDateTime); +begin + Value := DateOf(AValue); +end; + +procedure TInstantDate.SetValue(AValue: TDateTime); +begin + if AValue <> FValue then + begin + FValue := DateOf(AValue); + Changed; + end; +end; + +{ TInstantTime } + +class function TInstantTime.AttributeType: TInstantAttributeType; +begin + Result := atTime; +end; + +function TInstantTime.GetAsTime: TDateTime; +begin + Result := Value; +end; + +function TInstantTime.GetAsString: string; +begin + Result := TimeToStr(Value); +end; + +procedure TInstantTime.SetAsTime(AValue: TDateTime); +begin + Value := TimeOf(AValue); +end; + +procedure TInstantTime.SetValue(AValue: TDateTime); +begin + if AValue <> FValue then + begin + FValue := TimeOf(AValue); + Changed; + end; +end; + initialization RegisterClasses([TInstantClassMetadatas, TInstantClassMetadata, TInstantAttributeMetadatas, TInstantAttributeMetadata, Modified: trunk/Source/Core/InstantPresentation.pas =================================================================== --- trunk/Source/Core/InstantPresentation.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Core/InstantPresentation.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -769,7 +769,8 @@ const FieldTypes: array[TInstantAttributeType] of TFieldType = ( ftUnknown, ftInteger, ftFloat, ftBCD, ftBoolean, ftString, ftDateTime, - ftBlob, ftMemo, ftBlob, ftInteger, ftInteger, ftDataSet, ftDataSet); + ftBlob, ftMemo, ftBlob, ftInteger, ftInteger, ftDataSet, ftDataSet, + ftDate, ftTime); begin Result := FieldTypes[AttributeType]; end; @@ -2162,6 +2163,7 @@ ATypeInfo : PTypeInfo; begin ATypeInfo := PropInfo.PropType^; + if GetTypeData(PropInfo^.PropType^).FloatType = ftCurr then Result := DB.ftBcd else @@ -2172,7 +2174,7 @@ Result := DB.ftDate else if ATypeInfo = TypeInfo(TTime) then Result := DB.ftTime -*) +*) else Result := DB.ftFloat; end; @@ -2225,7 +2227,12 @@ tkInteger: FieldType := ftInteger; tkFloat: - FieldType := FloatFieldType; + if PropInfo^.PropType^^.Name = 'TTime' then + FieldType := DB.ftTime + else if PropInfo^.PropType^^.Name = 'TDate' then + FieldType := DB.ftDate + else + FieldType := FloatFieldType; tkClass: FieldType := ftInteger; tkSet: Modified: trunk/Source/Core/InstantTypes.pas =================================================================== --- trunk/Source/Core/InstantTypes.pas 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Source/Core/InstantTypes.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -44,7 +44,7 @@ TInstantStorageKind = (skEmbedded, skExternal); TInstantAttributeType = (atUnknown, atInteger, atFloat, atCurrency, atBoolean, atString, atDateTime, atBlob, atMemo, atGraphic, - atPart, atReference, atParts, atReferences); + atPart, atReference, atParts, atReferences, atDate, atTime); TInstantAttributeCategory = (acUnknown, acSimple, acElement, acContainer); TInstantGraphicFileFormat = (gffUnknown, gffBmp, gffTiff, gffJpeg, gffPng, @@ -53,7 +53,7 @@ TInstantPersistence = (peEmbedded, peStored); TInstantDataType = (dtInteger, dtFloat, dtCurrency, dtBoolean, dtString, - dtMemo, dtDateTime, dtBlob); + dtMemo, dtDateTime, dtBlob, dtDate, dtTime); TInstantDataTypes = set of TInstantDataType; TInstantFieldOption = (foRequired, foIndexed); TInstantFieldOptions = set of TInstantFieldOption; @@ -81,6 +81,9 @@ TInstantWarningEvent = procedure (const Sender: TObject; const AWarningText: string) of object; + TTime = type TDateTime; + TDate = type TDateTime; + implementation end. Modified: trunk/Tests/TestIO.dpr =================================================================== --- trunk/Tests/TestIO.dpr 2006-12-10 05:19:12 UTC (rev 736) +++ trunk/Tests/TestIO.dpr 2006-12-11 00:17:56 UTC (rev 737) @@ -38,6 +38,8 @@ TestInstantInteger in 'TestInstantInteger.pas', TestInstantString in 'TestInstantString.pas', TestInstantDateTime in 'TestInstantDateTime.pas', + TestInstantDate in 'TestInstantDate.pas', + TestInstantTime in 'TestInstantTime.pas', TestInstantBoolean in 'TestInstantBoolean.pas', TestInstantFloat in 'TestInstantFloat.pas', TestInstantCurrency in 'TestInstantCurrency.pas', Modified: trunk/Tests/TestIO.mdr =================================================================== (Binary files differ) Added: trunk/Tests/TestInstantDate.pas =================================================================== --- trunk/Tests/TestInstantDate.pas (rev 0) +++ trunk/Tests/TestInstantDate.pas 2006-12-11 00:17:56 UTC (rev 737) @@ -0,0 +1,323 @@ +(* + * InstantObjects Test Suite + * TestInstantDate + *) + +(* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is: InstantObjects Test Suite/TestInstantDate + * + * The Initial Developer of the Original Code is: Steven Mitchell + * + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * + * ***** END LICENSE BLOCK ***** *) + +unit TestInstantDate; + +interface + +uses fpcunit, InstantPersistence, InstantMock, TestModel; + +type + + // Test methods for class TInstantDate + TestTInstantDate = class(TTestCase) + private + FConn: TInstantMockConnector; + FInstantDate: TInstantDate; + FOwner: TPerson; + public + procedure SetUp; override; + procedure TearDown; override; + published + procedure TestAsBoolean; + procedure TestAsCurrency; + procedure TestAsDate; + procedure TestAsDateTime; + procedure TestAsTime; + procedure TestAsFloat; + procedure TestAsInteger; + procedure TestAsObject; + procedure TestAssign; + procedure TestAsString; + procedure TestAsVariant; + procedure TestDisplayText; + procedure TestIsDefault; + procedure TestReset; + procedure TestValue; + end; + +implementation + +uses SysUtils, testregistry, InstantClasses; + +procedure TestTInstantDate.SetUp; +begin + FConn := TInstantMockConnector.Create(nil); + FConn.BrokerClass := TInstantMockBroker; + + if InstantModel.ClassMetadatas.Count > 0 then + InstantModel.ClassMetadatas.Clear; + InstantModel.LoadFromResFile(ChangeFileExt(ParamStr(0), '.mdr')); + + FOwner := TPerson.Create(FConn); + FInstantDate := FOwner._EmploymentDate; + FInstantDate.Value := 100; +end; + +procedure TestTInstantDate.TearDown; +begin + FInstantDate := nil; + FreeAndNil(FOwner); + InstantModel.ClassMetadatas.Clear; + ... [truncated message content] |
From: <fas...@us...> - 2006-12-10 05:19:13
|
Revision: 736 http://svn.sourceforge.net/instantobjects/revision/?rev=736&view=rev Author: fastbike2 Date: 2006-12-09 21:19:12 -0800 (Sat, 09 Dec 2006) Log Message: ----------- Refactored InstantAttributeEditor form to remove exceptions from flow control Parallel changes made to Model Maker object foundry plugin expert. Modified Paths: -------------- trunk/Source/Design/InstantAttributeEditor.pas trunk/Source/ObjectFoundry/OFExpert.pas Modified: trunk/Source/Design/InstantAttributeEditor.pas =================================================================== --- trunk/Source/Design/InstantAttributeEditor.pas 2006-12-08 09:41:29 UTC (rev 735) +++ trunk/Source/Design/InstantAttributeEditor.pas 2006-12-10 05:19:12 UTC (rev 736) @@ -61,12 +61,14 @@ private FAttribute: TInstantCodeAttribute; FInterface: IInterface; + FErrorMsg: string; protected property Attribute: TInstantCodeAttribute read FAttribute; property MMInterface: IInterface read FInterface; + property ErrorMsg: string read FErrorMsg write FErrorMsg; public constructor Create(AnAttribute: TInstantCodeAttribute; const AInterface: IInterface); - procedure Validate; virtual; + function Validate: Boolean; virtual; end; TInstantAttributeEditorForm = class(TInstantEditForm) @@ -412,13 +414,13 @@ if OKButton.CanFocus then OKButton.SetFocus; - try - FValidator.Validate; - except + if not FValidator.Validate then + begin ModalResult := mrNone; PageControl.ActivePage := DefinitionSheet; NameEdit.SetFocus; - raise; + MessageDlg(FValidator.ErrorMsg, mtError, [mbOK], 0); + Abort; end; if (Subject.AttributeType = atString) and (Subject.Metadata.Size = 0) then @@ -427,7 +429,7 @@ ModalResult := mrNone; PageControl.ActivePage := DefinitionSheet; SizeEdit.SetFocus; - Abort; + Exit; end; if ObjectClassEdit.Enabled then @@ -782,7 +784,7 @@ FInterface := AInterface; end; -procedure TInstantAttributeValidator.Validate; +function TInstantAttributeValidator.Validate: Boolean; var TempAttribute: TInstantCodeAttribute; CodeClass: TInstantCodeClass; @@ -797,45 +799,85 @@ for J := 0 to Pred(CurrentClass.SubClassCount) do begin for K := 0 to Pred(CurrentClass.SubClasses[J].PropertyCount) do + begin + if not Result then + Break; if SameText(CurrentClass.SubClasses[J].Properties[K].Name, FAttribute.Name) then - raise Exception.CreateFmt('Attribute "%s" exists in descendant class "%s"', + begin + ErrorMsg := Format('Attribute "%s" exists in descendant class "%s"', [FAttribute.Name, CurrentClass.SubClasses[J].Name]); + Result := False; + end; + end; for K := 0 to Pred(CurrentClass.SubClasses[J].MethodCount) do + begin + if not Result then + Break; if SameText(CurrentClass.SubClasses[J].Methods[K].Name, FAttribute.Name) then - raise Exception.CreateFmt('Attribute "%s" exists as a method in descendant class "%s"', + begin + ErrorMsg := Format('Attribute "%s" exists as a method in descendant class "%s"', [FAttribute.Name, CurrentClass.SubClasses[J].Name]); + Result := False; + end; + end; CheckChildClass(CurrentClass.SubClasses[J]); end; end; begin + Result := True; + ErrorMsg := ''; + if not Assigned(FAttribute) and not Assigned(FAttribute.Owner) and not Assigned(FAttribute.Owner.Owner) then - raise Exception.Create('Cannot validate attribute'); - + begin + ErrorMsg := 'Cannot validate attribute'; + Result := False; + Exit; + end; // check that the same attribute name is not used in an ancestor class CodeClass := FAttribute.Owner.Owner.BaseClass; - while (CodeClass <> nil) do + while (Result) and (CodeClass <> nil) do begin for I := 0 to Pred(CodeClass.PropertyCount) do + begin + if not Result then + Break; if SameText(CodeClass.Properties[I].Name, FAttribute.Name) then - raise Exception.CreateFmt('Attribute "%s" exists in ancestor class "%s"', - [FAttribute.Name, CodeClass.Name]); + begin + ErrorMsg := Format('Attribute "%s" exists in ancestor class "%s"', + [FAttribute.Name, CodeClass.Name]); + Result := False; + end; + end; for I := 0 to Pred(CodeClass.MethodCount) do + begin + if not Result then + Break; if SameText(CodeClass.Methods[I].Name, FAttribute.Name) then - raise Exception.CreateFmt('Attribute "%s" exists as a method in ancestor class "%s"', + begin + ErrorMsg := Format('Attribute "%s" exists as a method in ancestor class "%s"', [FAttribute.Name, CodeClass.Name]); + Result := False; + end; + end; CodeClass := CodeClass.BaseClass; end; // check that the same attribute name is not used in any child class - CheckChildClass(FAttribute.Owner.Owner); + if Result then + CheckChildClass(FAttribute.Owner.Owner); - if Assigned(FAttribute.Owner) then + if Result and Assigned(FAttribute.Owner) then for I := 0 to Pred(FAttribute.Owner.AttributeCount) do begin + if not Result then + Break; TempAttribute := FAttribute.Owner.Attributes[I]; if (TempAttribute <> FAttribute) and SameText(TempAttribute.Name, FAttribute.Name) then - raise Exception.Create('Attribute Name already used'); + begin + ErrorMsg := 'Attribute Name already used'; + Result := False; + end; end; end; Modified: trunk/Source/ObjectFoundry/OFExpert.pas =================================================================== --- trunk/Source/ObjectFoundry/OFExpert.pas 2006-12-08 09:41:29 UTC (rev 735) +++ trunk/Source/ObjectFoundry/OFExpert.pas 2006-12-10 05:19:12 UTC (rev 736) @@ -103,7 +103,7 @@ type TMMAttributeValidator = class(TInstantAttributeValidator) public - procedure Validate; override; + function Validate: Boolean; override; end; @@ -604,7 +604,7 @@ { TMMAttributeValidator } -procedure TMMAttributeValidator.Validate; +function TMMAttributeValidator.Validate: Boolean; var MMProperty: IMMProperty; CodeClass: IMMClassifier; @@ -618,14 +618,22 @@ Exit; for J := 0 to Pred(CurrentClass.DescendantCount) do begin + if not Result then + Break; if CurrentClass.Descendants[J].FindMember(Attribute.Name, I) then - raise Exception.CreateFmt('Attribute "%s" exists in descendant class "%s"', + begin + ErrorMsg := Format('Attribute "%s" exists in descendant class "%s"', [Attribute.Name, CurrentClass.Descendants[J].Name]); + Result := False; + end; CheckChildClass(CurrentClass.Descendants[J]); end; end; begin + Result := True; + ErrorMsg := ''; + if MMInterface = nil then Exit; MMProperty := MMInterface as IMMProperty; @@ -638,19 +646,26 @@ // check that the new attribute name is not used in parent class // except by itself if CodeClass.FindMember(Attribute.Name, I) and - (CodeClass.Members[I] <> MMProperty) then - raise Exception.Create('Attribute Name already used'); + (CodeClass.Members[I] <> MMProperty) then + begin + ErrorMsg := 'Attribute Name already used'; + Result := False; + end; // check that the new attribute name is not used in any child class - CheckChildClass(CodeClass); + if Result then + CheckChildClass(CodeClass); // check that the new attribute name is not used in an ancestor class CodeClass := CodeClass.Ancestor; - while (CodeClass <> nil) do + while Result and (CodeClass <> nil) do begin if CodeClass.FindMember(Attribute.Name, I) then - raise Exception.CreateFmt('Attribute "%s" exists in ancestor class "%s"', + begin + ErrorMsg := Format('Attribute "%s" exists in ancestor class "%s"', [Attribute.Name, CodeClass.Name]); + Result := False; + end; CodeClass := CodeClass.Ancestor; end; end; |
From: <na...@us...> - 2006-12-08 09:41:29
|
Revision: 735 http://svn.sourceforge.net/instantobjects/revision/?rev=735&view=rev Author: nandod Date: 2006-12-08 01:41:29 -0800 (Fri, 08 Dec 2006) Log Message: ----------- * fixed incomplete implementation of IdDataType and IdSize in the ADO broker. Modified Paths: -------------- trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.dfm trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.pas Modified: trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.dfm =================================================================== --- trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.dfm 2006-12-08 09:40:42 UTC (rev 734) +++ trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.dfm 2006-12-08 09:41:29 UTC (rev 735) @@ -4,7 +4,7 @@ BorderStyle = bsDialog Caption = 'ADO Connection' ClientHeight = 242 - ClientWidth = 362 + ClientWidth = 446 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -19,7 +19,7 @@ object BottomBevel: TBevel Left = 0 Top = 205 - Width = 362 + Width = 446 Height = 2 Align = alBottom Shape = bsBottomLine @@ -27,7 +27,7 @@ object ClientPanel: TPanel Left = 0 Top = 0 - Width = 362 + Width = 446 Height = 205 Align = alClient BevelOuter = bvNone @@ -40,6 +40,22 @@ Caption = 'Blob &format' FocusControl = StreamFormatComboBox end + object Label1: TLabel + Left = 134 + Top = 152 + Width = 62 + Height = 13 + Caption = 'Id Data Type' + FocusControl = IdDataTypeComboBox + end + object Label2: TLabel + Left = 259 + Top = 152 + Width = 32 + Height = 13 + Caption = 'Id Size' + FocusControl = IdDataTypeComboBox + end object DataLinkRadioButton: TRadioButton Left = 16 Top = 16 @@ -97,7 +113,7 @@ object StreamFormatComboBox: TComboBox Left = 32 Top = 168 - Width = 145 + Width = 97 Height = 21 Style = csDropDownList ItemHeight = 13 @@ -112,17 +128,33 @@ Caption = '&Login Prompt' TabOrder = 6 end + object IdDataTypeComboBox: TComboBox + Left = 134 + Top = 168 + Width = 120 + Height = 21 + Style = csDropDownList + ItemHeight = 13 + TabOrder = 8 + end + object IdSizeEdit: TEdit + Left = 259 + Top = 168 + Width = 42 + Height = 21 + TabOrder = 9 + end end object BottomPanel: TPanel Left = 0 Top = 207 - Width = 362 + Width = 446 Height = 35 Align = alBottom BevelOuter = bvNone TabOrder = 1 object OkButton: TButton - Left = 204 + Left = 288 Top = 6 Width = 75 Height = 25 @@ -133,7 +165,7 @@ TabOrder = 0 end object CancelButton: TButton - Left = 284 + Left = 368 Top = 6 Width = 75 Height = 25 Modified: trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.pas =================================================================== --- trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.pas 2006-12-08 09:40:42 UTC (rev 734) +++ trunk/Source/Brokers/ADO/InstantADOConnectionDefEdit.pas 2006-12-08 09:41:29 UTC (rev 735) @@ -24,8 +24,8 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Carlo Barazzetta: blob streaming in XML format (Part, Parts, References) - * Carlo Barazzetta: Currency and LoginPrompt support + * Carlo Barazzetta, Nando Dessena + * * ***** END LICENSE BLOCK ***** *) unit InstantADOConnectionDefEdit; @@ -52,6 +52,10 @@ StreamFormatLabel: TLabel; StreamFormatComboBox: TComboBox; LoginPromptCheckBox: TCheckBox; + Label1: TLabel; + IdDataTypeComboBox: TComboBox; + Label2: TLabel; + IdSizeEdit: TEdit; procedure ConnectionStringButtonClick(Sender: TObject); procedure DataLinkButtonClick(Sender: TObject); procedure DataChanged(Sender: TObject); @@ -67,10 +71,10 @@ implementation -{$R *.DFM} +{$R *.dfm} uses - ADODB, InstantPersistence, InstantClasses; + ADODB, InstantPersistence, InstantClasses, InstantTypes, InstantConsts; { TInstantADOConnDefEditForm } @@ -94,7 +98,10 @@ procedure TInstantADOConnectionDefEditForm.FormCreate(Sender: TObject); begin - AssignInstantStreamFormat(StreamFormatComboBox.Items); //CB + AssignInstantStreamFormat(StreamFormatComboBox.Items); + AssignInstantDataTypeStrings(IdDataTypeComboBox.Items); + IdDataTypeComboBox.ItemIndex := Ord(dtString); + IdSizeEdit.Text := IntToStr(InstantDefaultFieldSize); UpdateControls; end; @@ -121,9 +128,10 @@ DataLinkRadioButton.Checked := True; DataLinkEdit.Text := LinkFileName; end; - //CB StreamFormatComboBox.ItemIndex := Ord(BlobStreamFormat); LoginPromptCheckBox.Checked := LoginPrompt; + IdDataTypeComboBox.ItemIndex := Ord(IdDataType); + IdSizeEdit.Text := IntToStr(IdSize); end; end; @@ -136,9 +144,10 @@ ConnectionString := 'FILE NAME=' + DataLinkEdit.Text else ConnectionString := ConnectionStringEdit.Text; - //CB BlobStreamFormat := TInstantStreamFormat(StreamFormatComboBox.ItemIndex); LoginPrompt := LoginPromptCheckBox.Checked; + IdDataType := TInstantDataType(IdDataTypeComboBox.ItemIndex); + IdSize := StrToInt(IdSizeEdit.Text); end; end; |
From: <na...@us...> - 2006-12-08 09:40:44
|
Revision: 734 http://svn.sourceforge.net/instantobjects/revision/?rev=734&view=rev Author: nandod Date: 2006-12-08 01:40:42 -0800 (Fri, 08 Dec 2006) Log Message: ----------- * fixed incomplete implementation of IdDataType and IdSize in the BDE broker. Modified Paths: -------------- trunk/Source/Brokers/BDE/InstantBDEConnectionDefEdit.pas Modified: trunk/Source/Brokers/BDE/InstantBDEConnectionDefEdit.pas =================================================================== --- trunk/Source/Brokers/BDE/InstantBDEConnectionDefEdit.pas 2006-12-08 04:31:04 UTC (rev 733) +++ trunk/Source/Brokers/BDE/InstantBDEConnectionDefEdit.pas 2006-12-08 09:40:42 UTC (rev 734) @@ -181,9 +181,11 @@ with DriverComboBox do ItemIndex := Items.IndexOf(DriverName); end; - //CB StreamFormatComboBox.ItemIndex := Ord(BlobStreamFormat); LoginPromptCheckBox.Checked := LoginPrompt; + IdDataTypeComboBox.ItemIndex := Ord(IdDataType); + IdSizeEdit.Text := IntToStr(IdSize); + UpdateControls; ParametersEdit.Text := Parameters; end; |
From: <sr...@us...> - 2006-12-08 04:31:12
|
Revision: 733 http://svn.sourceforge.net/instantobjects/revision/?rev=733&view=rev Author: srmitch Date: 2006-12-07 20:31:04 -0800 (Thu, 07 Dec 2006) Log Message: ----------- - Reversal of previous commit, which was done in error. Modified Paths: -------------- trunk/Tests/TestIO.dpr trunk/Tests/TestInstantDateTime.pas trunk/Tests/TestModel.pas Modified: trunk/Tests/TestIO.dpr =================================================================== --- trunk/Tests/TestIO.dpr 2006-12-08 04:18:27 UTC (rev 732) +++ trunk/Tests/TestIO.dpr 2006-12-08 04:31:04 UTC (rev 733) @@ -38,8 +38,6 @@ TestInstantInteger in 'TestInstantInteger.pas', TestInstantString in 'TestInstantString.pas', TestInstantDateTime in 'TestInstantDateTime.pas', - TestInstantDate in 'TestInstantDate.pas', - TestInstantTime in 'TestInstantTime.pas', TestInstantBoolean in 'TestInstantBoolean.pas', TestInstantFloat in 'TestInstantFloat.pas', TestInstantCurrency in 'TestInstantCurrency.pas', Modified: trunk/Tests/TestInstantDateTime.pas =================================================================== --- trunk/Tests/TestInstantDateTime.pas 2006-12-08 04:18:27 UTC (rev 732) +++ trunk/Tests/TestInstantDateTime.pas 2006-12-08 04:31:04 UTC (rev 733) @@ -49,8 +49,6 @@ procedure TestAsBoolean; procedure TestAsCurrency; procedure TestAsDateTime; - procedure TestAsDate; - procedure TestAsTime; procedure TestAsFloat; procedure TestAsInteger; procedure TestAsObject; @@ -136,20 +134,6 @@ AssertEquals(12.45, FInstantDateTime.AsDateTime); end; -procedure TestTInstantDateTime.TestAsDate; -begin - FInstantDateTime.AsDate := 120.00; - AssertEquals(120.00, FInstantDateTime.Value); - AssertEquals(120.00, FInstantDateTime.AsDate); -end; - -procedure TestTInstantDateTime.TestAsTime; -begin - FInstantDateTime.AsTime := 0.45; - AssertEquals(0.45, FInstantDateTime.Value); - AssertEquals(0.45, FInstantDateTime.AsTime); -end; - procedure TestTInstantDateTime.TestAsFloat; begin try Modified: trunk/Tests/TestModel.pas =================================================================== --- trunk/Tests/TestModel.pas 2006-12-08 04:18:27 UTC (rev 732) +++ trunk/Tests/TestModel.pas 2006-12-08 04:31:04 UTC (rev 733) @@ -237,37 +237,29 @@ Picture: Blob; Salary: Currency; Employed: Boolean; - AL_hours: Float; - EmploymentDate: Date; - BirthTime: Time; } + AL_hours: Float; } _AL_hours: TInstantFloat; _BirthDate: TInstantDateTime; - _BirthTime: TInstantTime; _Emails: TInstantParts; _Employed: TInstantBoolean; _Employer: TInstantReference; - _EmploymentDate: TInstantDate; _Picture: TInstantGraphic; _Salary: TInstantCurrency; private function GetAL_hours: Double; function GetBirthDate: TDateTime; - function GetBirthTime: TDateTime; function GetEmailCount: Integer; function GetEmails(Index: Integer): TEmail; function GetEmployed: Boolean; function GetEmployer: TCompany; - function GetEmploymentDate: TDateTime; function GetMainEmailAddress: string; function GetPicture: string; function GetSalary: Currency; procedure SetAL_hours(Value: Double); procedure SetBirthDate(Value: TDateTime); - procedure SetBirthTime(Value: TDateTime); procedure SetEmails(Index: Integer; Value: TEmail); procedure SetEmployed(Value: Boolean); procedure SetEmployer(const Value: TCompany); - procedure SetEmploymentDate(Value: TDateTime); procedure SetMainEmailAddress(const Value: string); procedure SetPicture(const Value: string); procedure SetSalary(Value: Currency); @@ -286,10 +278,8 @@ published property AL_hours: Double read GetAL_hours write SetAL_hours; property BirthDate: TDateTime read GetBirthDate write SetBirthDate; - property BirthTime: TDateTime read GetBirthTime write SetBirthTime; property Employed: Boolean read GetEmployed write SetEmployed; property Employer: TCompany read GetEmployer write SetEmployer; - property EmploymentDate: TDateTime read GetEmploymentDate write SetEmploymentDate; property MainEmailAddress: string read GetMainEmailAddress write SetMainEmailAddress; property Picture: string read GetPicture write SetPicture; property Salary: Currency read GetSalary write SetSalary; @@ -715,11 +705,6 @@ Result := _BirthDate.Value; end; -function TPerson.GetBirthTime: TDateTime; -begin - Result := _BirthTime.Value; -end; - function TPerson.GetEmailCount: Integer; begin Result := _Emails.Count @@ -740,11 +725,6 @@ Result := _Employer.Value as TCompany; end; -function TPerson.GetEmploymentDate: TDateTime; -begin - Result := _EmploymentDate.Value; -end; - function TPerson.GetMainEmailAddress: string; begin if EmailCount > 0 then @@ -788,11 +768,6 @@ _BirthDate.Value := Value; end; -procedure TPerson.SetBirthTime(Value: TDateTime); -begin - _BirthTime.Value := Value; -end; - procedure TPerson.SetEmails(Index: Integer; Value: TEmail); begin _Emails[Index] := Value; @@ -808,11 +783,6 @@ _Employer.Value := Value; end; -procedure TPerson.SetEmploymentDate(Value: TDateTime); -begin - _EmploymentDate.Value := Value; -end; - procedure TPerson.SetMainEmailAddress(const Value: string); var Email: TEmail; |
From: <sr...@us...> - 2006-12-08 04:18:29
|
Revision: 732 http://svn.sourceforge.net/instantobjects/revision/?rev=732&view=rev Author: srmitch Date: 2006-12-07 20:18:27 -0800 (Thu, 07 Dec 2006) Log Message: ----------- - Missed in previous commit. Modified Paths: -------------- trunk/Tests/TestIO.dpr trunk/Tests/TestInstantDateTime.pas trunk/Tests/TestModel.pas Modified: trunk/Tests/TestIO.dpr =================================================================== --- trunk/Tests/TestIO.dpr 2006-12-03 20:20:14 UTC (rev 731) +++ trunk/Tests/TestIO.dpr 2006-12-08 04:18:27 UTC (rev 732) @@ -38,6 +38,8 @@ TestInstantInteger in 'TestInstantInteger.pas', TestInstantString in 'TestInstantString.pas', TestInstantDateTime in 'TestInstantDateTime.pas', + TestInstantDate in 'TestInstantDate.pas', + TestInstantTime in 'TestInstantTime.pas', TestInstantBoolean in 'TestInstantBoolean.pas', TestInstantFloat in 'TestInstantFloat.pas', TestInstantCurrency in 'TestInstantCurrency.pas', Modified: trunk/Tests/TestInstantDateTime.pas =================================================================== --- trunk/Tests/TestInstantDateTime.pas 2006-12-03 20:20:14 UTC (rev 731) +++ trunk/Tests/TestInstantDateTime.pas 2006-12-08 04:18:27 UTC (rev 732) @@ -49,6 +49,8 @@ procedure TestAsBoolean; procedure TestAsCurrency; procedure TestAsDateTime; + procedure TestAsDate; + procedure TestAsTime; procedure TestAsFloat; procedure TestAsInteger; procedure TestAsObject; @@ -134,6 +136,20 @@ AssertEquals(12.45, FInstantDateTime.AsDateTime); end; +procedure TestTInstantDateTime.TestAsDate; +begin + FInstantDateTime.AsDate := 120.00; + AssertEquals(120.00, FInstantDateTime.Value); + AssertEquals(120.00, FInstantDateTime.AsDate); +end; + +procedure TestTInstantDateTime.TestAsTime; +begin + FInstantDateTime.AsTime := 0.45; + AssertEquals(0.45, FInstantDateTime.Value); + AssertEquals(0.45, FInstantDateTime.AsTime); +end; + procedure TestTInstantDateTime.TestAsFloat; begin try Modified: trunk/Tests/TestModel.pas =================================================================== --- trunk/Tests/TestModel.pas 2006-12-03 20:20:14 UTC (rev 731) +++ trunk/Tests/TestModel.pas 2006-12-08 04:18:27 UTC (rev 732) @@ -237,29 +237,37 @@ Picture: Blob; Salary: Currency; Employed: Boolean; - AL_hours: Float; } + AL_hours: Float; + EmploymentDate: Date; + BirthTime: Time; } _AL_hours: TInstantFloat; _BirthDate: TInstantDateTime; + _BirthTime: TInstantTime; _Emails: TInstantParts; _Employed: TInstantBoolean; _Employer: TInstantReference; + _EmploymentDate: TInstantDate; _Picture: TInstantGraphic; _Salary: TInstantCurrency; private function GetAL_hours: Double; function GetBirthDate: TDateTime; + function GetBirthTime: TDateTime; function GetEmailCount: Integer; function GetEmails(Index: Integer): TEmail; function GetEmployed: Boolean; function GetEmployer: TCompany; + function GetEmploymentDate: TDateTime; function GetMainEmailAddress: string; function GetPicture: string; function GetSalary: Currency; procedure SetAL_hours(Value: Double); procedure SetBirthDate(Value: TDateTime); + procedure SetBirthTime(Value: TDateTime); procedure SetEmails(Index: Integer; Value: TEmail); procedure SetEmployed(Value: Boolean); procedure SetEmployer(const Value: TCompany); + procedure SetEmploymentDate(Value: TDateTime); procedure SetMainEmailAddress(const Value: string); procedure SetPicture(const Value: string); procedure SetSalary(Value: Currency); @@ -278,8 +286,10 @@ published property AL_hours: Double read GetAL_hours write SetAL_hours; property BirthDate: TDateTime read GetBirthDate write SetBirthDate; + property BirthTime: TDateTime read GetBirthTime write SetBirthTime; property Employed: Boolean read GetEmployed write SetEmployed; property Employer: TCompany read GetEmployer write SetEmployer; + property EmploymentDate: TDateTime read GetEmploymentDate write SetEmploymentDate; property MainEmailAddress: string read GetMainEmailAddress write SetMainEmailAddress; property Picture: string read GetPicture write SetPicture; property Salary: Currency read GetSalary write SetSalary; @@ -705,6 +715,11 @@ Result := _BirthDate.Value; end; +function TPerson.GetBirthTime: TDateTime; +begin + Result := _BirthTime.Value; +end; + function TPerson.GetEmailCount: Integer; begin Result := _Emails.Count @@ -725,6 +740,11 @@ Result := _Employer.Value as TCompany; end; +function TPerson.GetEmploymentDate: TDateTime; +begin + Result := _EmploymentDate.Value; +end; + function TPerson.GetMainEmailAddress: string; begin if EmailCount > 0 then @@ -768,6 +788,11 @@ _BirthDate.Value := Value; end; +procedure TPerson.SetBirthTime(Value: TDateTime); +begin + _BirthTime.Value := Value; +end; + procedure TPerson.SetEmails(Index: Integer; Value: TEmail); begin _Emails[Index] := Value; @@ -783,6 +808,11 @@ _Employer.Value := Value; end; +procedure TPerson.SetEmploymentDate(Value: TDateTime); +begin + _EmploymentDate.Value := Value; +end; + procedure TPerson.SetMainEmailAddress(const Value: string); var Email: TEmail; |
From: <fas...@us...> - 2006-12-03 20:20:24
|
Revision: 731 http://svn.sourceforge.net/instantobjects/revision/?rev=731&view=rev Author: fastbike2 Date: 2006-12-03 12:20:14 -0800 (Sun, 03 Dec 2006) Log Message: ----------- Added InstantMetadata and InstantTypes to implementation uses clause. Required due to earlier refactoring of InstantPersistence.pas Modified Paths: -------------- trunk/Demos/ConsoleApp/Model.pas Modified: trunk/Demos/ConsoleApp/Model.pas =================================================================== --- trunk/Demos/ConsoleApp/Model.pas 2006-11-29 17:19:47 UTC (rev 730) +++ trunk/Demos/ConsoleApp/Model.pas 2006-12-03 20:20:14 UTC (rev 731) @@ -21,6 +21,9 @@ implementation +uses + InstantMetadata, InstantTypes; + procedure CreateInstantModel; var InstantClassMetadata : TInstantClassMetadata; |
From: <the...@us...> - 2006-11-29 17:19:52
|
Revision: 730 http://svn.sourceforge.net/instantobjects/revision/?rev=730&view=rev Author: the_kique Date: 2006-11-29 09:19:47 -0800 (Wed, 29 Nov 2006) Log Message: ----------- Added icon support to AssignToPicture [1603283], compatibility to Assign method in TPicture class [1603285] Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas trunk/Source/Core/InstantTypes.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-11-29 10:53:06 UTC (rev 729) +++ trunk/Source/Core/InstantPersistence.pas 2006-11-29 17:19:47 UTC (rev 730) @@ -422,6 +422,7 @@ procedure SetAsVariant(AValue: Variant); override; function Write(const Buffer; Position, Count: Integer): Integer; virtual; procedure WriteObject(Writer: TInstantWriter); override; + procedure AssignTo(Dest: TPersistent); override; public destructor Destroy; override; procedure Assign(Source: TPersistent); override; @@ -1956,6 +1957,9 @@ // gif format else if (P[0] = #$47) and (P[1] = #$49) and (P[2] = #$46) then Result := gffGif + // Ico format + else if (P[0] = #00) and (P[1] = #00) and (P[2] = #01) and (P[3] = #00) then + Result := gffIco // bitmap format with TGraphicHeader header else if (P[0] = #01) and (P[1] = #00) and (P[2] = #00) and (P[3] = #01) and (PLongint(@p[4])^ = StreamLength - SizeOfGraphicHeader) then @@ -3543,6 +3547,14 @@ Dest.Graphic := nil; end; +procedure TInstantBlob.AssignTo(Dest: TPersistent); +begin + if Dest is TPicture then + AssignToPicture(TPicture(Dest)) + else + inherited; +end; + { TInstantMemo } class function TInstantMemo.AttributeType: TInstantAttributeType; @@ -8815,12 +8827,14 @@ TInstantObjectReference, TInstantConnectionDefs, TInstantConnectionDef]); ClassList := TList.Create; {$IFDEF MSWINDOWS} + GraphicClassList[gffIco] := Graphics.TIcon; GraphicClassList[gffBmp] := Graphics.TBitmap; {$IFNDEF FPC} GraphicClassList[gffEmf] := Graphics.TMetaFile; {$ENDIF} {$ENDIF} {$IFDEF LINUX} + GraphicClassList[gffIco] := QGraphics.TIcon; GraphicClassList[gffBmp] := QGraphics.TBitmap; GraphicClassList[gffPng] := QGraphics.TBitmap; GraphicClassList[gffJpeg]:= QGraphics.TBitmap; Modified: trunk/Source/Core/InstantTypes.pas =================================================================== --- trunk/Source/Core/InstantTypes.pas 2006-11-29 10:53:06 UTC (rev 729) +++ trunk/Source/Core/InstantTypes.pas 2006-11-29 17:19:47 UTC (rev 730) @@ -48,7 +48,7 @@ TInstantAttributeCategory = (acUnknown, acSimple, acElement, acContainer); TInstantGraphicFileFormat = (gffUnknown, gffBmp, gffTiff, gffJpeg, gffPng, - gffDcx, gffPcx, gffEmf, gffGif); + gffDcx, gffPcx, gffEmf, gffGif, gffIco); TInstantPersistence = (peEmbedded, peStored); |
From: <na...@us...> - 2006-11-29 10:53:05
|
Revision: 729 http://svn.sourceforge.net/instantobjects/revision/?rev=729&view=rev Author: nandod Date: 2006-11-29 02:53:06 -0800 (Wed, 29 Nov 2006) Log Message: ----------- * fixed [ 1605157 ] BlobStreamFormat not honored when building a database Modified Paths: -------------- trunk/Source/Core/InstantBrokers.pas Modified: trunk/Source/Core/InstantBrokers.pas =================================================================== --- trunk/Source/Core/InstantBrokers.pas 2006-11-29 10:42:28 UTC (rev 728) +++ trunk/Source/Core/InstantBrokers.pas 2006-11-29 10:53:06 UTC (rev 729) @@ -1448,9 +1448,15 @@ Model: TInstantModel): TInstantScheme; begin Result := TInstantScheme.Create; - Result.IdDataType := IdDataType; - Result.IdSize := IdSize; - Result.Catalog := TInstantModelCatalog.Create(Result, Model); + try + Result.IdDataType := IdDataType; + Result.IdSize := IdSize; + Result.BlobStreamFormat := BlobStreamFormat; + Result.Catalog := TInstantModelCatalog.Create(Result, Model); + except + FreeAndNil(Result); + raise; + end; end; constructor TInstantConnectionBasedConnector.Create(AOwner: TComponent); |
From: <fas...@us...> - 2006-11-29 10:42:30
|
Revision: 728 http://svn.sourceforge.net/instantobjects/revision/?rev=728&view=rev Author: fastbike2 Date: 2006-11-29 02:42:28 -0800 (Wed, 29 Nov 2006) Log Message: ----------- Changes to ensure backward compatibility of Object Foundry addin expert with MM 6.20 Modified Paths: -------------- trunk/Source/ObjectFoundry/OFClasses.pas trunk/Source/ObjectFoundry/OFExpert.pas trunk/Source/ObjectFoundry/OFUtils.pas Modified: trunk/Source/ObjectFoundry/OFClasses.pas =================================================================== --- trunk/Source/ObjectFoundry/OFClasses.pas 2006-11-29 05:41:29 UTC (rev 727) +++ trunk/Source/ObjectFoundry/OFClasses.pas 2006-11-29 10:42:28 UTC (rev 728) @@ -24,7 +24,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Steven Mitchell + * Steven Mitchell, David Moorhouse * * ***** END LICENSE BLOCK ***** *) @@ -82,6 +82,11 @@ procedure Refresh; end; +{$IFNDEF MM7+} // i.e. redefine for MM 6.20 +type + IMMClassifier = IMMClassBase; +{$ENDIF} + implementation uses @@ -495,11 +500,15 @@ FieldTypeName: string; begin Name := Prop.Name; +{$IFDEF MM7+} {$IFDEF MM9} Visibility := MMVisibilityToInstantCodeVisibility(Prop.Visibility); {$ELSE} Visibility := TInstantCodeVisibility(Prop.V9Visibility); {$ENDIF} +{$ELSE} + Visibility := TInstantCodeVisibility(Prop.Visibility); +{$ENDIF} if Attribute.IsIOAttribute then begin { If the type of attribute field is Integer (which is considered Modified: trunk/Source/ObjectFoundry/OFExpert.pas =================================================================== --- trunk/Source/ObjectFoundry/OFExpert.pas 2006-11-29 05:41:29 UTC (rev 727) +++ trunk/Source/ObjectFoundry/OFExpert.pas 2006-11-29 10:42:28 UTC (rev 728) @@ -159,7 +159,11 @@ AClass := CodeModel.Classes[I]; if IsInstantObjectClass(AClass) and (not PersistentOnly or + {$IFDEF MM7+} (PersistentOnly and (AClass.Persistency = cpPersistent))) then + {$ELSE} + (PersistentOnly and ((AClass as IMMV9ClassBase).Persistency = cpPersistent))) then + {$ENDIF} Items.Add(AClass.Name); end; end; { if } @@ -179,7 +183,11 @@ begin lClass := CodeModel.Classes[I]; if IsInstantObjectClass(lClass) and SameText(AClassName, lClass.Name) then + {$IFDEF MM7+} IsPersistent := lClass.Persistency = cpPersistent; + {$ELSE} + IsPersistent := (lClass as IMMV9ClassBase).Persistency = cpPersistent; + {$ENDIF} end; end; { if } end; Modified: trunk/Source/ObjectFoundry/OFUtils.pas =================================================================== --- trunk/Source/ObjectFoundry/OFUtils.pas 2006-11-29 05:41:29 UTC (rev 727) +++ trunk/Source/ObjectFoundry/OFUtils.pas 2006-11-29 10:42:28 UTC (rev 728) @@ -24,7 +24,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Steven Mitchell + * Steven Mitchell, David Moorhouse * * ***** END LICENSE BLOCK ***** *) @@ -146,9 +146,14 @@ function MMVisibilityToInstantCodeVisibility(const Value: TVisibility): TInstantCodeVisibility; const + {$IFDEF MM7+} Map: array[TVisibility] of TInstantCodeVisibility = (viDefault, viPrivate, viPrivate, viProtected, viProtected, viPublic, viPublished, viPublished); + {$ELSE} + Map: array[TVisibility] of TInstantCodeVisibility = + (viDefault, viPrivate, viProtected, viPublic, viPublished, viPublished); + {$ENDIF} begin Result := Map[Value]; end; |
From: <sr...@us...> - 2006-11-29 05:41:31
|
Revision: 727 http://svn.sourceforge.net/instantobjects/revision/?rev=727&view=rev Author: srmitch Date: 2006-11-28 21:41:29 -0800 (Tue, 28 Nov 2006) Log Message: ----------- Fix for XML query fail in refresh: - Added TInstantXMLQuery.InternalGetInstantObjectRefs. - Deleted TInstantXMLQuery.InternalRefreshObjects. Modified Paths: -------------- trunk/Source/Brokers/XML/InstantXML.pas Modified: trunk/Source/Brokers/XML/InstantXML.pas =================================================================== --- trunk/Source/Brokers/XML/InstantXML.pas 2006-11-29 04:44:52 UTC (rev 726) +++ trunk/Source/Brokers/XML/InstantXML.pas 2006-11-29 05:41:29 UTC (rev 727) @@ -227,12 +227,13 @@ function GetStatement: string; override; function InternalAddObject(AObject: TObject): Integer; override; procedure InternalClose; override; + procedure InternalGetInstantObjectRefs(List: TInstantObjectReferenceList); + override; function InternalGetObjectCount: Integer; override; function InternalGetObjects(Index: Integer): TObject; override; function InternalIndexOfObject(AObject: TObject): Integer; override; procedure InternalInsertObject(Index: Integer; AObject: TObject); override; procedure InternalOpen; override; - procedure InternalRefreshObjects; override; procedure InternalReleaseObject(AObject: TObject); override; function InternalRemoveObject(AObject: TObject): Integer; override; procedure SetParams(Value: TParams); override; @@ -877,6 +878,16 @@ inherited; end; +procedure TInstantXMLQuery.InternalGetInstantObjectRefs(List: + TInstantObjectReferenceList); +var + I: Integer; +begin + for I := 0 to Pred(ObjectReferenceCount) do + if ObjectFetched(I) and (Objects[I] is TInstantObject) then + List.Add(TInstantObject(Objects[I])); +end; + function TInstantXMLQuery.InternalGetObjectCount: Integer; begin Result := ObjectReferenceCount; @@ -925,28 +936,6 @@ end; end; -procedure TInstantXMLQuery.InternalRefreshObjects; -var - I: Integer; - BusyObjects: TObjectList; -begin - BusyObjects := TObjectList.Create; - try - for I := 0 to Pred(ObjectReferenceCount) do - begin - with ObjectReferences[I] do - if HasInstance and (Instance.RefCount > 1) then - BusyObjects.Add(Instance); - end; - Close; - Open; - for I := 0 to Pred(BusyObjects.Count) do - TInstantObject(BusyObjects[I]).Refresh; - finally - BusyObjects.Free; - end; -end; - procedure TInstantXMLQuery.InternalReleaseObject(AObject: TObject); var Index: Integer; |
From: <fas...@us...> - 2006-11-29 04:45:51
|
Revision: 726 http://svn.sourceforge.net/instantobjects/revision/?rev=726&view=rev Author: fastbike2 Date: 2006-11-28 20:44:52 -0800 (Tue, 28 Nov 2006) Log Message: ----------- Updated documentation to include Fb2.0 column types Modified Paths: -------------- trunk/Docs/InterBase_DataTypes.html Modified: trunk/Docs/InterBase_DataTypes.html =================================================================== (Binary files differ) |
From: <sr...@us...> - 2006-11-29 03:55:09
|
Revision: 725 http://svn.sourceforge.net/instantobjects/revision/?rev=725&view=rev Author: srmitch Date: 2006-11-28 19:55:06 -0800 (Tue, 28 Nov 2006) Log Message: ----------- - Update for Object Foundry to support MM9. - Updated and renamed 'OF_readme.txt' to 'ObjectFoundry_readme.txt' and moved it into the main Docs folder. - Introduced an 'ObjectFoundry.inc' file to simplify future MM version support. Modified Paths: -------------- trunk/Source/Design/InstantAttributeEditor.pas trunk/Source/ObjectFoundry/OFClassRegWizard.pas trunk/Source/ObjectFoundry/OFClasses.pas trunk/Source/ObjectFoundry/OFCritic.pas trunk/Source/ObjectFoundry/OFDefs.pas trunk/Source/ObjectFoundry/OFExpert.pas trunk/Source/ObjectFoundry/OFNotify.pas trunk/Source/ObjectFoundry/OFOptions.pas trunk/Source/ObjectFoundry/OFReg.pas trunk/Source/ObjectFoundry/OFUtils.pas Added Paths: ----------- trunk/Docs/ObjectFoundry_readme.txt trunk/Source/ObjectFoundry/ObjectFoundry.inc Removed Paths: ------------- trunk/Source/ObjectFoundry/OF_readme.txt Added: trunk/Docs/ObjectFoundry_readme.txt =================================================================== --- trunk/Docs/ObjectFoundry_readme.txt (rev 0) +++ trunk/Docs/ObjectFoundry_readme.txt 2006-11-29 03:55:06 UTC (rev 725) @@ -0,0 +1,72 @@ +ObjectFoundry (for IO V2.x) Readme +by Carlo Wolter/Steven Mitchell - 21 Mar 2005 +Revised by Steven Mitchell: 29 Nov 2006 + +Introduction +------------ +This file contains instructions and information for the +Object Foundry (OF) integration between IO version 2 and +ModelMaker(c)[http://www.modelmakertools.com]. + +ModelMaker (MM) is an UML designer integrated with Delphi. +It can be used also for InstantObject design, provided +you place the + OFExpt.dll +expert file in the + $(ProgramFiles)\ModelMakerTools\ModelMaker\x.x\Experts +directory. MM detects and loads it during startup and +"ObjectFoundry enabled" is included on the MM startup splash +screen. It is also listed in the "Plug in expert manager" +dialog launched from the Tools/Expert Manager menu option +in MM. + +Currently MM versions 6 to 9 are supported with OF. + +Compiling +--------- +This DLL can be compiled using the project in this directory. + +Please take note that the project needs to know where the +MM Expert files are. Therefore make sure the subdir + $(ProgramFiles)\ModelMakerTools\ModelMaker\x.x\Experts +is in the project options search path + (ie Project/Options/Directories-Conditionals/SearchPath). +This is required because in the MM experts directory there is +a single file that is needed: + MMToolsApi.PAS +Also ensure that the appropriate compiler defines are entered +in the project options Conditional defines (see table below). +(ie Project/Options/Directories-Conditionals/Conditional defines) + + MM Version Define + ---------- ------ + 6.x [none] + 7.x or 8.x MM7+ + 9.x MM9 + +Note: The MMToolsApi.PAS file is protected by copyright of +ModelMakerTools and cannot be put into CVS. Every legitimate +owner of a MM licence, though, should have no problems in +finding it. + +Notes on Usage +-------------- +To operate correctly, this version of OF expects and +generates the IO Metadata identifier tag in the class +metadata info as follows: +"{IOMETADATA " (without quotes but including trailing space). + +Conversion of IO MM projects that did not have the IO +Metadata identifier tag: +Make sure that the model is up to date then save and close +Modelmaker. Backup the MM project file. Backup any previous +'OFExpt.dll' file and copy the new 'OFExpt.dll' file to the +{$Modelmaker}\Experts folder as indicated above. Re-open +Modelmaker. Re-generating the Delphi code from ModelMaker +should update the model code units to include the new class +metadata identifier tag. + +Feedback +-------- +Please report any problems to the IO news support group at +"news.instantobjects.org/instantobjects.org.support". Property changes on: trunk/Docs/ObjectFoundry_readme.txt ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/Source/Design/InstantAttributeEditor.pas =================================================================== --- trunk/Source/Design/InstantAttributeEditor.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/Design/InstantAttributeEditor.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -132,6 +132,7 @@ private FBaseClassStorageName: string; FLimited: Boolean; + FMMUninitializedNewAttribute: Boolean; FModel: TInstantCodeModel; FOnIsClassPersistent: TInstantBooleanEvent; FOnLoadClasses: TInstantStringsEvent; @@ -219,10 +220,14 @@ ObjectClassEdit.Items.Add(FModel.Classes[I].Name); end else if Assigned(ObjectClassEdit.Field) and - (ObjectClassEdit.Field.AsString <> '') then + (ObjectClassEdit.Field.AsString <> '') and + not FMMUninitializedNewAttribute then ObjectClassEdit.Items.Add(ObjectClassEdit.Field.AsString) else if Assigned(FOnLoadClasses) then + begin OnLoadClasses(Self, ObjectClassEdit.Items, NeedOnlyPersistentClasses); + FMMUninitializedNewAttribute := True; + end; if Assigned(ObjectClassEdit.Field) then ObjectClassEdit.ItemIndex := @@ -392,6 +397,8 @@ begin SubjectExposer.AssignFieldValue(ObjectClassEdit.Field, ObjectClassEdit.Text); UpdateControls; + if StorageKindEdit.Items.Count = 0 then + LoadStorageKind; end; procedure TInstantAttributeEditorForm.ObjectClassEditEnter( Modified: trunk/Source/ObjectFoundry/OFClassRegWizard.pas =================================================================== --- trunk/Source/ObjectFoundry/OFClassRegWizard.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFClassRegWizard.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,11 +30,13 @@ unit OFClassRegWizard; +{$I ObjectFoundry.inc} + interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, - StdCtrls, CheckLst, MMToolsAPI, ComCtrls; + StdCtrls, CheckLst, MMToolsAPI, OFDefs, ComCtrls; type TClassRegWizardForm = class(TForm) @@ -206,7 +208,26 @@ Result := False; end; +{$IFDEF MM9} var + UnitManager: IMMModuleManager; + AUnit: IMMModule; + I: Integer; +begin + UnitList.Clear; + UnitManager := MMToolServices.ModuleManager; + if Assigned(UnitManager) then + begin + for I := 0 to Pred(UnitManager.ModuleCount) do + begin + AUnit := UnitManager.Modules[I]; + if UnitHasPersistentClass(AUnit) then + UnitList.Add(AUnit); + end; + end; +end; +{$ELSE} +var UnitManager: IMMUnitManager; AUnit: IMMUnit; I: Integer; @@ -223,6 +244,7 @@ end; end; end; +{$ENDIF} procedure TClassRegWizardForm.OkButtonClick(Sender: TObject); begin @@ -244,7 +266,11 @@ AUnit := Units[I]; with Items.Add do begin + {$IFDEF MM9} + Caption := ExtractFileName(AUnit.RelModuleName); + {$ELSE} Caption := ExtractFileName(AUnit.RelUnitName); + {$ENDIF} Data := Pointer(AUnit); Checked := True; end; Modified: trunk/Source/ObjectFoundry/OFClasses.pas =================================================================== --- trunk/Source/ObjectFoundry/OFClasses.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFClasses.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,13 +30,7 @@ unit OFClasses; -{ 18 Sep 2004 - Steven Mitchell - Modified for use in MM7.25 - - Use V9Visibility property inplace of Visibility - property in MMToolsAPI V10 IMMMember interface. - 30 Sep 2004 - Steven Mitchell - Added tags for part(s) external storage params -} +{$I ObjectFoundry.inc} interface @@ -113,10 +107,17 @@ finally EndOld; end; + {$IFDEF MM9} + if Prop.Classifier.FindMember(OldCountPropName, Index) then + begin + Member := Prop.Classifier.Members[Index]; + Result := MemberAsProperty(Member); + {$ELSE} if Prop.ClassBase.FindMember(OldCountPropName, Index) then begin Member := Prop.ClassBase.Members[Index]; Result := MemberAsProperty(Member); + {$ENDIF} end else Result := nil; end; @@ -130,15 +131,23 @@ Result := FindCountProp; if not Assigned(Result) then begin + {$IFDEF MM9} + Result := Prop.Classifier.AddProperty; + {$ELSE} Result := Prop.ClassBase.AddProperty; + {$ENDIF} Attribute.LinkMember(Result.Id); end; Result.Name := CountPropName; -{$IFDEF MM7+} // SRM begin - 16 Mar 2005 +{$IFDEF MM7+} + {$IFDEF MM9} + Result.Visibility := InstantCodeVisibilityToMMVisibility(Visibility); + {$ELSE} Result.V9Visibility := TV9Visibility(Visibility); + {$ENDIF} {$ELSE} Result.Visibility := TVisibility(Visibility); -{$ENDIF} // SRM end - 16 Mar 2005 +{$ENDIF} Result.SetAccessSpec(rwMethod, rwNone); Getter := MemberAsMethod(Result.ReadMember); if Assigned(Getter) then @@ -208,7 +217,11 @@ begin BeginOld; try + {$IFDEF MM9} + Result := Prop.Classifier.FindMethod(GetMethodName(MT)); + {$ELSE} Result := Prop.ClassBase.FindMethod(GetMethodName(MT)); + {$ENDIF} finally EndOld; end; @@ -235,7 +248,11 @@ begin Result := FindMethod(MT); if not Assigned(Result) then + {$IFDEF MM9} + Result := Prop.Classifier.AddMethod; + {$ELSE} Result := Prop.ClassBase.AddMethod; + {$ENDIF} Attribute.LinkMember(Result.Id); Result.Name := CodeMethod.Name; Result.Parameters := CodeMethod.Proc.Parameters.AsString; @@ -245,11 +262,15 @@ Result.MethodKind := MMEngineDefs.mkFunction; Result.DataName := CodeMethod.Proc.ResultTypeName; end; -{$IFDEF MM7+} // SRM begin - 16 Mar 2005 +{$IFDEF MM7+} + {$IFDEF MM9} + Result.Visibility := InstantCodeVisibilityToMMVisibility(Visibility); + {$ELSE} Result.V9Visibility := TV9Visibility(Visibility); + {$ENDIF} {$ELSE} Result.Visibility := TVisibility(Visibility); -{$ENDIF} // SRM end - 16 Mar 2005 +{$ENDIF} NewBody := CodeMethod.Proc.Body.AsString; if Result.SectionCount = 0 then Result.AddSection(NewBody) @@ -297,11 +318,15 @@ begin Prop.Name := Name; Prop.DataName := PropTypeName; -{$IFDEF MM7+} // SRM begin - 16 Mar 2005 +{$IFDEF MM7+} + {$IFDEF MM9} + Prop.Visibility := InstantCodeVisibilityToMMVisibility(Visibility); + {$ELSE} Prop.V9Visibility := TV9Visibility(Visibility); + {$ENDIF} {$ELSE} Prop.Visibility := TVisibility(Visibility); -{$ENDIF} // SRM end - 16 Mar 2005 +{$ENDIF} TaggedStrings['StorageName'] := StorageName; // External part(s) options TaggedStrings['ExternalStorageName'] := ExternalStorageName; @@ -418,7 +443,11 @@ function TMMCodeAttribute.HasMethod(const Name: string): Boolean; begin + {$IFDEF MM9} + Result := Assigned(Prop.Classifier.FindMethod(Name)); + {$ELSE} Result := Assigned(Prop.ClassBase.FindMethod(Name)); + {$ENDIF} end; function TMMCodeAttribute.IsOld: Boolean; @@ -439,13 +468,23 @@ for MT := Low(MT) to High(MT) do if MT in MethodTypes then begin + {$IFDEF MM9} + Method := Prop.Classifier.FindMethod(GetMethodName(MT)); + {$ELSE} Method := Prop.ClassBase.FindMethod(GetMethodName(MT)); + {$ENDIF} if Assigned(Method) then Attribute.LinkMember(Method.Id); end; + {$IFDEF MM9} + if Prop.Classifier.FindMember(CountPropName, Index) then + begin + Member := Prop.Classifier.Members[Index]; + {$ELSE} if Prop.ClassBase.FindMember(CountPropName, Index) then begin Member := Prop.ClassBase.Members[Index]; + {$ENDIF} CountProp := MemberAsProperty(Member); Attribute.LinkMember(CountProp.Id); end; @@ -456,7 +495,11 @@ FieldTypeName: string; begin Name := Prop.Name; - Visibility := TInstantCodeVisibility(Prop.V9Visibility); // SRM - 18 Sep 2004 + {$IFDEF MM9} + Visibility := MMVisibilityToInstantCodeVisibility(Prop.Visibility); + {$ELSE} + Visibility := TInstantCodeVisibility(Prop.V9Visibility); + {$ENDIF} if Attribute.IsIOAttribute then begin { If the type of attribute field is Integer (which is considered Modified: trunk/Source/ObjectFoundry/OFCritic.pas =================================================================== --- trunk/Source/ObjectFoundry/OFCritic.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFCritic.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,6 +30,8 @@ unit OFCritic; +{$I ObjectFoundry.inc} + interface uses Windows, SysUtils, Classes, MMEngineDefs, MMToolsApi, MMCriticsBase; Modified: trunk/Source/ObjectFoundry/OFDefs.pas =================================================================== --- trunk/Source/ObjectFoundry/OFDefs.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFDefs.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,21 +30,30 @@ unit OFDefs; +{$I ObjectFoundry.inc} + interface - -{$IFDEF MM7+} uses - MMToolsAPI, MMDiagramAPI; + MMToolsAPI + {$IFDEF MM7+} + , MMDiagramAPI + {$ENDIF} + ; type +{$IFDEF MM7+} + {$IFDEF MM9} + IMMUnit = IMMModule; + IMMUnitManager = IMMModuleManager; + IMMV9ClassBase = IMMClassifier; + IMMV9CodeModel = IMMCodeModel; + IMMClassBase = IMMClassifier; + {$ELSE} IMMV9ClassBase = IMMClassBase; IMMV9CodeModel = IMMCodeModel; + {$ENDIF} {$ELSE} -uses - MMToolsAPI; - -type TMMActionData = record Caption: WideString; // ModelMaker provides a defaults name based on to the menu item name ImageIndex: Integer; // Default = -1; Only used for toolbuttons, ignored for menu items @@ -58,7 +67,6 @@ end; {$ENDIF} -type IOFReference = IMMReference; IOFEntityReference = IMMEntityReference; Modified: trunk/Source/ObjectFoundry/OFExpert.pas =================================================================== --- trunk/Source/ObjectFoundry/OFExpert.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFExpert.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,6 +30,8 @@ unit OFExpert; +{$I ObjectFoundry.inc} + interface uses @@ -207,7 +209,11 @@ begin if Assigned(P) and P.Valid then begin + {$IFDEF MM9} + lClass := P.Classifier; + {$ELSE} lClass := P.ClassBase; + {$ENDIF} Attribute := TMMCodeAttribute.Create(P); AttributeValidator := TMMAttributeValidator.Create(Attribute, P); try @@ -615,21 +621,30 @@ if MMInterface = nil then Exit; MMProperty := MMInterface as IMMProperty; + {$IFDEF MM9} + CodeClass := MMProperty.Classifier; + {$ELSE} + CodeClass := MMProperty.ClassBase; + {$ENDIF} - if MMProperty.ClassBase.FindMember(Attribute.Name, I) then - raise Exception.Create('Attribute Name already used'); + // check that the new attribute name is not used in parent class + // except by itself + if CodeClass.FindMember(Attribute.Name, I) and + (CodeClass.Members[I] <> MMProperty) then + raise Exception.Create('Attribute Name already used'); - // check that the same attribute name is not used in an ancestor class - CodeClass := MMProperty.ClassBase; + // check that the new attribute name is not used in any child class + CheckChildClass(CodeClass); + + // check that the new attribute name is not used in an ancestor class + CodeClass := CodeClass.Ancestor; while (CodeClass <> nil) do begin if CodeClass.FindMember(Attribute.Name, I) then raise Exception.CreateFmt('Attribute "%s" exists in ancestor class "%s"', [Attribute.Name, CodeClass.Name]); - CodeClass := CodeClass.Ancestor; + CodeClass := CodeClass.Ancestor; end; - // check that the same attribute name is not used in any child class - CheckChildClass(MMProperty.ClassBase); end; end. Modified: trunk/Source/ObjectFoundry/OFNotify.pas =================================================================== --- trunk/Source/ObjectFoundry/OFNotify.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFNotify.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,6 +30,8 @@ unit OFNotify; +{$I ObjectFoundry.inc} + interface uses SysUtils, Classes, MMEngineDefs, MMToolsApi; Modified: trunk/Source/ObjectFoundry/OFOptions.pas =================================================================== --- trunk/Source/ObjectFoundry/OFOptions.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFOptions.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,6 +30,8 @@ unit OFOptions; +{$I ObjectFoundry.inc} + interface uses Modified: trunk/Source/ObjectFoundry/OFReg.pas =================================================================== --- trunk/Source/ObjectFoundry/OFReg.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFReg.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,6 +30,8 @@ unit OFReg; +{$I ObjectFoundry.inc} + interface uses Modified: trunk/Source/ObjectFoundry/OFUtils.pas =================================================================== --- trunk/Source/ObjectFoundry/OFUtils.pas 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OFUtils.pas 2006-11-29 03:55:06 UTC (rev 725) @@ -30,10 +30,12 @@ unit OFUtils; +{$I ObjectFoundry.inc} + interface uses - MMToolsAPI, MMIOAPI, OFDefs; + MMToolsAPI, MMIOAPI, MMEngineDefs, OFDefs, InstantCode; function ClassAsV9ClassBase(AClass: IMMClassBase): IMMV9ClassBase; function CodeModelAsV9CodeModel(ACodeModel: IMMCodeModel): IMMV9CodeModel; @@ -47,6 +49,12 @@ function MemberAsAttributeProperty(Member: IMMMember): IMMProperty; function SameCode(const Code1, Code2: string): Boolean; +function MMVisibilityToInstantCodeVisibility(const Value: TVisibility): + TInstantCodeVisibility; + +function InstantCodeVisibilityToMMVisibility(const Value: + TInstantCodeVisibility): TVisibility; + implementation uses @@ -135,4 +143,23 @@ Result := SameText(Trim(Code1), Trim(Code2)); end; +function MMVisibilityToInstantCodeVisibility(const Value: TVisibility): + TInstantCodeVisibility; +const + Map: array[TVisibility] of TInstantCodeVisibility = + (viDefault, viPrivate, viPrivate, viProtected, viProtected, + viPublic, viPublished, viPublished); +begin + Result := Map[Value]; +end; + +function InstantCodeVisibilityToMMVisibility(const Value: + TInstantCodeVisibility): TVisibility; +const + Map: array[TInstantCodeVisibility] of TVisibility = + (scDefault, scPrivate, scProtected, scPublic, scPublished); +begin + Result := Map[Value]; +end; + end. Deleted: trunk/Source/ObjectFoundry/OF_readme.txt =================================================================== --- trunk/Source/ObjectFoundry/OF_readme.txt 2006-11-29 03:30:29 UTC (rev 724) +++ trunk/Source/ObjectFoundry/OF_readme.txt 2006-11-29 03:55:06 UTC (rev 725) @@ -1,64 +0,0 @@ -ObjectFoundry (for IO V2) Readme -by Carlo Wolter/Steven Mitchell - 21 Mar 2005 - -Introduction ------------- -This file contains instructions and information for the -Object Foundry (OF) integration between IO version 2 and -ModelMaker(c). - -ModelMaker (MM) is an UML designer integrated with Delphi. -It can be used also for InstantObject design, provided -you place the - OFExpt.dll -expert file in the - $(ProgramFiles)\ModelMakerTools\ModelMaker\x.x\Experts -directory. MM detects and loads it during startup and -"ObjectFoundry enabled" is included on the MM startup splash -screen. It is also listed in the "Plug in expert manager" -dialog launched from the Tools/Expert Manager menu option -in MM. - -Compiling ---------- -This DLL can be compiled using the project in this directory. - -Please take note that the project needs to know where the -MM Expert files are. Therefore make sure the subdir - $(ProgramFiles)\ModelMakerTools\ModelMaker\x.x\Experts -is in the project options search path - (ie Project/Options/Directories-Conditionals/SearchPath). -This is required because in the MM experts directory there is -a single file that is needed: - MMToolsApi.PAS -Also ensure that 'MM7+' is defined in the project options -Conditional defines - (ie Project/Options/Directories-Conditionals/Conditional defines) -when using version 7 or higher of MM. - -Note: The MMToolsApi.PAS file is protected by copyright of -ModelMakerTools and cannot be put into CVS. Every legitimate -owner of a MM licence, though, should have no problems in -finding it. - -Notes on Usage --------------- -To operate correctly, this version of OF expects and -generates the IO Metadata identifier tag in the class -metadata info as follows: -"{IOMETADATA " (without quotes but including trailing space). - -Conversion of IO MM projects that did not have the IO -Metadata identifier tag: -Make sure that the model is up to date then save and close -Modelmaker. Backup the MM project file. Backup any previous -'OFExpt.dll' file and copy the new 'OFExpt.dll' file to the -{$Modelmaker}\Experts folder as indicated above. Re-open -Modelmaker. Re-generating the Delphi code from ModelMaker -should update the model code units to include the new class -metadata identifier tag. - -Feedback --------- -Please report any problems to the IO news groups at -"news.instantobjects.org". Added: trunk/Source/ObjectFoundry/ObjectFoundry.inc =================================================================== --- trunk/Source/ObjectFoundry/ObjectFoundry.inc (rev 0) +++ trunk/Source/ObjectFoundry/ObjectFoundry.inc 2006-11-29 03:55:06 UTC (rev 725) @@ -0,0 +1,3 @@ +{$IFDEF MM9} + {$DEFINE MM7+} +{$ENDIF} Property changes on: trunk/Source/ObjectFoundry/ObjectFoundry.inc ___________________________________________________________________ Name: svn:eol-style + native |
From: <fas...@us...> - 2006-11-29 03:32:02
|
Revision: 724 http://svn.sourceforge.net/instantobjects/revision/?rev=724&view=rev Author: fastbike2 Date: 2006-11-28 19:30:29 -0800 (Tue, 28 Nov 2006) Log Message: ----------- Fix [ 1603022] Evolve DB chokes on IBX Currency Type Refactor IB/FB catalog to: - display more info for unknown field types - match column types on RDB$FIELDS which is always complete (rather than RDB$TYPES which lacks some entries on some servers) - comments at end of file detailing SQL scripts that can be run to extract "Test" meta data - fieldscale checked for currency to ensure data accuracy is not lost Modified Paths: -------------- trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas Modified: trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas =================================================================== --- trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas 2006-11-28 10:51:28 UTC (rev 723) +++ trunk/Source/Catalogs/IBFb/InstantIBFbCatalog.pas 2006-11-29 03:30:29 UTC (rev 724) @@ -24,7 +24,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Steven Mitchell + * Steven Mitchell, David Moorhouse * * ***** END LICENSE BLOCK ***** *) @@ -51,12 +51,12 @@ procedure AddIndexMetadatas(TableMetadata: TInstantTableMetadata); procedure AddTableMetadatas(TableMetadatas: TInstantTableMetadatas); // Returns True if the TInstantDataType value that matches the supplied - // combination of ColumnType, BlobSubType and FieldScale is found. If + // combination of ColumnType, ColumnSubType and FieldScale is found. If // more than one datatypes apply, alternate data types are returned in // AlternateDataTypes, otherwise AlternateDataTypes is [] on exit. - function ColumnTypeToDataType(const ColumnType: string; - const BlobSubType, FieldScale: Integer; out DataType: TInstantDataType; - out AlternateDataTypes: TInstantDataTypes): Boolean; + function ColumnTypeToDataType(const ColumnType: Integer; + const ColumnSubType, FieldScale: Integer; out DataType: TInstantDataType; + out AlternateDataTypes: TInstantDataTypes): Boolean; function GetSelectFieldsSQL(const ATableName: string): string; function GetSelectIndexesSQL(const ATableName: string): string; function GetSelectIndexFieldsSQL(const AIndexName: string): string; @@ -70,7 +70,7 @@ uses SysUtils, Classes, DB, InstantConsts; - + { TInstantIBFbCatalog } procedure TInstantIBFbCatalog.AddIndexMetadatas( @@ -141,6 +141,7 @@ FieldMetadata: TInstantFieldMetadata; AlternateDataTypes: TInstantDataTypes; FieldMetaDataType: TInstantDataType; + FieldTypeName: string; begin Fields := Broker.AcquireDataSet(GetSelectFieldsSQL(TableMetadata.Name)); try @@ -151,7 +152,7 @@ FieldMetadata := TableMetadata.FieldMetadatas.Add; FieldMetadata.Name := Trim(Fields.FieldByName('RDB$FIELD_NAME').AsString); if ColumnTypeToDataType( - Trim(Fields.FieldByName('RDB$TYPE_NAME').AsString), + Fields.FieldByName('RDB$FIELD_TYPE').AsInteger, Fields.FieldByName('RDB$FIELD_SUB_TYPE').AsInteger, Fields.FieldByName('RDB$FIELD_SCALE').AsInteger, FieldMetaDataType, @@ -170,9 +171,15 @@ FieldMetadata.Size := Fields.FieldByName('RDB$FIELD_LENGTH').AsInteger; end else - DoWarning(Format(SUnsupportedColumnSkipped, - [TableMetadata.Name, FieldMetadata.Name, - Trim(Fields.FieldByName('RDB$TYPE_NAME').AsString)])); + begin + FieldTypeName := Trim (Fields.FieldByName('RDB$TYPE_NAME').AsString); + if FieldTypeName = '' then + FieldTypeName := Format('[FieldType=%s FieldSubType=%s]', + [Fields.FieldByName('RDB$FIELD_TYPE').AsString, + Fields.FieldByName('RDB$FIELD_SUB_TYPE').AsString]); + DoWarning(Format(SUnsupportedColumnSkipped, + [TableMetadata.Name, FieldMetadata.Name, FieldTypeName])); + end; Fields.Next; end; finally @@ -211,38 +218,47 @@ end; end; -function TInstantIBFbCatalog.ColumnTypeToDataType(const ColumnType: string; - const BlobSubType, FieldScale: Integer; out DataType: TInstantDataType; - out AlternateDataTypes: TInstantDataTypes): Boolean; +function TInstantIBFbCatalog.ColumnTypeToDataType(const ColumnType: Integer; + const ColumnSubType, FieldScale: Integer; out DataType: TInstantDataType; + out AlternateDataTypes: TInstantDataTypes): Boolean; begin +{RDB$FIELDS.RDB$FIELD_TYPE values +\x95 BLOB - 261 \x95 BLOB_ID - 45 \x95 BOOLEAN - 17 \x95 CHAR - 14 \x95 CSTRING - 40 +\x95 D_FLOAT - 11 \x95 DOUBLE - 27 \x95 FLOAT - 10 \x95 INT64 - 16 \x95 INTEGER - 8 +\x95 QUAD - 9 \x95 SMALLINT - 7 \x95 DATE - 12 (dialect 3 DATE) \x95 TIME - 13 +\x95 TIMESTAMP - 35 \x95 VARCHAR - 37 +These values are always present in table metadata, +RDB$TYPES.RDB$TYPE_NAME is not always defined for all types } + AlternateDataTypes := []; Result := True; - { TODO : How to use FieldScale? } - if SameText(ColumnType, 'TEXT') or SameText(ColumnType, 'VARYING') then - DataType := dtString - else if SameText(ColumnType, 'SHORT') then - begin - DataType := dtBoolean; - Include(AlternateDataTypes, dtInteger); - end - else if SameText(ColumnType, 'LONG') then - DataType := dtInteger - else if SameText(ColumnType, 'FLOAT') or SameText(ColumnType, 'DOUBLE') then - DataType := dtFloat - else if SameText(ColumnType, 'TIMESTAMP') or SameText(ColumnType, 'DATE') - or SameText(ColumnType, 'TIME')then - DataType := dtDateTime - else if SameText(ColumnType, 'BLOB') then - begin - if BlobSubType = 1 then - DataType := dtMemo + case ColumnType of + 7: // SHORT/SMALLINT + begin + DataType := dtBoolean; + Include(AlternateDataTypes, dtInteger); + end; + 8: // INTEGER + DataType := dtInteger; + 10, 27: //FLOAT, DOUBLE + DataType := dtFloat; + 12,13,35: // DATE, TIME, TIMESTAMP - will need refactoring to support proposed TDate and TTime types + DataType := dtDateTime; + 14, 37: // TEXT, VARYING + DataType := dtString; + 16: // INT64 + if (ColumnSubType = 2) and (FieldScale >= -4) then + DataType := dtCurrency + else + Result := False; + 261: // BLOB + if ColumnSubType = 1 then + DataType := dtMemo + else + DataType := dtBlob; else - DataType := dtBlob; - end - else if SameText(ColumnType, 'INT64') then - DataType := dtCurrency - else - Result := False; + Result := False; + end; end; function TInstantIBFbCatalog.GetSelectFieldsSQL( @@ -251,7 +267,8 @@ Result := 'select ' + ' RF.RDB$FIELD_NAME, RF.RDB$NULL_FLAG, ' + - ' T.RDB$TYPE_NAME, F.RDB$FIELD_SUB_TYPE, F.RDB$FIELD_LENGTH, ' + + ' T.RDB$TYPE_NAME, ' + + ' F.RDB$FIELD_TYPE, F.RDB$FIELD_SUB_TYPE, F.RDB$FIELD_LENGTH, ' + ' F.RDB$FIELD_SCALE, F.RDB$CHARACTER_LENGTH ' + 'from ' + ' RDB$RELATION_FIELDS RF ' + @@ -259,7 +276,7 @@ ' RDB$FIELDS F ' + 'on ' + ' RF.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME ' + - 'join ' + + 'left join ' + //Fix [ 1603022] ' RDB$TYPES T ' + 'on ' + ' F.RDB$FIELD_TYPE = T.RDB$TYPE ' + @@ -319,4 +336,62 @@ AddTableMetadatas(ATableMetadatas); end; + +{ A. test table definition + +CREATE TABLE "Test" +( + "Class" VARCHAR(32) NOT NULL, + "Id" VARCHAR(32) NOT NULL, + "UpdateCount" INTEGER, + "StringAttr" VARCHAR(256), + "BlobAttr" BLOB, + "BooleanAttr" SMALLINT, + "CurrencyAttr" DECIMAL(14,4), + "DateTimeAttr" TIMESTAMP, + "FloatAttr" DOUBLE PRECISION, + "GraphicAttr" BLOB, + "IntegerAttr" INTEGER, + "MemoAttr" BLOB SUB_TYPE 1, + "ReferenceAttributeClass" VARCHAR(32), + "ReferenceAttributeId" VARCHAR(32), + "EmbeddedPartsAtttribute" BLOB, + "EmbeddedPartAttribute" BLOB, + "ExternalPartAttributeClass" VARCHAR(32), + "ExternalPartAttributeId" VARCHAR(32), + "EmbeddedReferencesAtttribute" BLOB, + "DateAttr" DATE, + "TimeAttr" TIME, + PRIMARY KEY ("Class", "Id") +); + +B. Result of "GetSelectFieldsSQL" method - run against IB 7.1 Win32 server + +RDB$FIELD_NAME RDB$NULL_FLAG RDB$TYPE_NAME RDB$FIELD_TYPE RDB$FIELD_SUB_TYPE RDB$FIELD_LENGTH RDB$FIELD_SCALE RDB$CHARACTER_LENGTH +=============================== ============= =============================== ============== ================== ================ =============== ==================== +Class 1 VARYING 37 32 0 32 +Id 1 VARYING 37 32 0 32 +UpdateCount LONG 8 4 0 +StringAttr VARYING 37 256 0 256 +BlobAttr BLOB 261 0 8 0 +BooleanAttr SHORT 7 2 0 +CurrencyAttr 16 2 8 -4 +DateTimeAttr TIMESTAMP 35 8 0 +FloatAttr DOUBLE 27 8 0 +GraphicAttr BLOB 261 0 8 0 +IntegerAttr LONG 8 4 0 +MemoAttr BLOB 261 1 8 0 +ReferenceAttributeClass VARYING 37 32 0 32 +ReferenceAttributeId VARYING 37 32 0 32 +EmbeddedPartsAtttribute BLOB 261 0 8 0 +EmbeddedPartAttribute BLOB 261 0 8 0 +ExternalPartAttributeClass VARYING 37 32 0 32 +ExternalPartAttributeId VARYING 37 32 0 32 +EmbeddedReferencesAtttribute BLOB 261 0 8 0 +DateAttr DATE 12 4 0 +TimeAttr TIME 13 4 0 + +} + + end. |
From: <fas...@us...> - 2006-11-28 10:51:42
|
Revision: 723 http://svn.sourceforge.net/instantobjects/revision/?rev=723&view=rev Author: fastbike2 Date: 2006-11-28 02:51:28 -0800 (Tue, 28 Nov 2006) Log Message: ----------- Fix for [ 1467622 ] Duplicate Attribute Names Modified Paths: -------------- trunk/Source/Design/InstantAttributeEditor.pas trunk/Source/ObjectFoundry/OFExpert.pas Modified: trunk/Source/Design/InstantAttributeEditor.pas =================================================================== --- trunk/Source/Design/InstantAttributeEditor.pas 2006-11-28 07:20:59 UTC (rev 722) +++ trunk/Source/Design/InstantAttributeEditor.pas 2006-11-28 10:51:28 UTC (rev 723) @@ -57,6 +57,18 @@ TInstantBooleanEvent = procedure (Sender: TObject; const AClassName: String; var IsPersistent: Boolean) of object; + TInstantAttributeValidator = class + private + FAttribute: TInstantCodeAttribute; + FInterface: IInterface; + protected + property Attribute: TInstantCodeAttribute read FAttribute; + property MMInterface: IInterface read FInterface; + public + constructor Create(AnAttribute: TInstantCodeAttribute; const AInterface: IInterface); + procedure Validate; virtual; + end; + TInstantAttributeEditorForm = class(TInstantEditForm) AccessSheet: TTabSheet; DefinitionSheet: TTabSheet; @@ -123,10 +135,12 @@ FModel: TInstantCodeModel; FOnIsClassPersistent: TInstantBooleanEvent; FOnLoadClasses: TInstantStringsEvent; + FValidator: TInstantAttributeValidator; function GetSubject: TInstantCodeAttribute; procedure SetSubject(const Value: TInstantCodeAttribute); procedure SetLimited(Value: Boolean); procedure SetModel(const Value: TInstantCodeModel); + procedure SetValidator(const Value: TInstantAttributeValidator); protected procedure LoadClasses; procedure LoadData; override; @@ -151,6 +165,7 @@ property OnLoadClasses: TInstantStringsEvent read FOnLoadClasses write FOnLoadClasses; property Subject: TInstantCodeAttribute read GetSubject write SetSubject; + property Validator: TInstantAttributeValidator read FValidator write SetValidator; end; implementation @@ -172,6 +187,7 @@ begin PageControl.ActivePage := DefinitionSheet; ActiveControl := NameEdit; + FValidator := TInstantAttributeValidator.Create(Subject, nil); end; function TInstantAttributeEditorForm.GetSubject: TInstantCodeAttribute; @@ -385,25 +401,19 @@ end; procedure TInstantAttributeEditorForm.OkButtonClick(Sender: TObject); -var - Attribute: TInstantCodeAttribute; - I: Integer; begin if OKButton.CanFocus then OKButton.SetFocus; - if Assigned(Subject.Owner) then - for I := 0 to Pred(Subject.Owner.AttributeCount) do - begin - Attribute := Subject.Owner.Attributes[I]; - if (Attribute <> Subject) and SameText(Attribute.Name, Subject.Name) then - begin - ModalResult := mrNone; - PageControl.ActivePage := DefinitionSheet; - NameEdit.SetFocus; - raise Exception.Create('Attribute Name already used'); - end; - end; + try + FValidator.Validate; + except + ModalResult := mrNone; + PageControl.ActivePage := DefinitionSheet; + NameEdit.SetFocus; + raise; + end; + if (Subject.AttributeType = atString) and (Subject.Metadata.Size = 0) then if not Confirm(SConfirmZeroSizeStringAttribute) then begin @@ -502,10 +512,11 @@ end; end; -procedure TInstantAttributeEditorForm.SetSubject( - const Value: TInstantCodeAttribute); +procedure TInstantAttributeEditorForm.SetSubject(const Value: TInstantCodeAttribute); begin inherited Subject := Value; + if FValidator <> nil then + FValidator.FAttribute := Value; end; procedure TInstantAttributeEditorForm.SubjectChanged; @@ -740,10 +751,87 @@ procedure TInstantAttributeEditorForm.StorageNameEditChange(Sender: TObject); begin inherited; - if Assigned(StorageNameEdit.DataSource) then + if Assigned(StorageNameEdit.DataSource) then SubjectExposer.AssignFieldValue(StorageNameEdit.Field, StorageNameEdit.Text); UpdateControls; end; +procedure TInstantAttributeEditorForm.SetValidator(const Value: TInstantAttributeValidator); +begin + if FValidator <> Value then begin + if FValidator <> nil then + FreeAndNil(FValidator); + FValidator := Value; + end; +end; + +{ TInstantAttributeValidator } + +constructor TInstantAttributeValidator.Create( + AnAttribute: TInstantCodeAttribute; const AInterface: IInterface); +begin + inherited Create; + FAttribute := AnAttribute; + FInterface := AInterface; +end; + +procedure TInstantAttributeValidator.Validate; +var + TempAttribute: TInstantCodeAttribute; + CodeClass: TInstantCodeClass; + I: Integer; + + procedure CheckChildClass(CurrentClass: TInstantCodeClass); + var + J,K: Integer; + begin + if CurrentClass = nil then + Exit; + for J := 0 to Pred(CurrentClass.SubClassCount) do + begin + for K := 0 to Pred(CurrentClass.SubClasses[J].PropertyCount) do + if SameText(CurrentClass.SubClasses[J].Properties[K].Name, FAttribute.Name) then + raise Exception.CreateFmt('Attribute "%s" exists in descendant class "%s"', + [FAttribute.Name, CurrentClass.SubClasses[J].Name]); + for K := 0 to Pred(CurrentClass.SubClasses[J].MethodCount) do + if SameText(CurrentClass.SubClasses[J].Methods[K].Name, FAttribute.Name) then + raise Exception.CreateFmt('Attribute "%s" exists as a method in descendant class "%s"', + [FAttribute.Name, CurrentClass.SubClasses[J].Name]); + CheckChildClass(CurrentClass.SubClasses[J]); + end; + end; + +begin + if not Assigned(FAttribute) and not Assigned(FAttribute.Owner) + and not Assigned(FAttribute.Owner.Owner) then + raise Exception.Create('Cannot validate attribute'); + + // check that the same attribute name is not used in an ancestor class + CodeClass := FAttribute.Owner.Owner.BaseClass; + while (CodeClass <> nil) do + begin + for I := 0 to Pred(CodeClass.PropertyCount) do + if SameText(CodeClass.Properties[I].Name, FAttribute.Name) then + raise Exception.CreateFmt('Attribute "%s" exists in ancestor class "%s"', + [FAttribute.Name, CodeClass.Name]); + for I := 0 to Pred(CodeClass.MethodCount) do + if SameText(CodeClass.Methods[I].Name, FAttribute.Name) then + raise Exception.CreateFmt('Attribute "%s" exists as a method in ancestor class "%s"', + [FAttribute.Name, CodeClass.Name]); + CodeClass := CodeClass.BaseClass; + end; + // check that the same attribute name is not used in any child class + CheckChildClass(FAttribute.Owner.Owner); + + if Assigned(FAttribute.Owner) then + for I := 0 to Pred(FAttribute.Owner.AttributeCount) do + begin + TempAttribute := FAttribute.Owner.Attributes[I]; + if (TempAttribute <> FAttribute) and SameText(TempAttribute.Name, FAttribute.Name) then + raise Exception.Create('Attribute Name already used'); + end; +end; + + end. Modified: trunk/Source/ObjectFoundry/OFExpert.pas =================================================================== --- trunk/Source/ObjectFoundry/OFExpert.pas 2006-11-28 07:20:59 UTC (rev 722) +++ trunk/Source/ObjectFoundry/OFExpert.pas 2006-11-28 10:51:28 UTC (rev 723) @@ -24,7 +24,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Steven Mitchell + * Steven Mitchell, David Moorhouse * * ***** END LICENSE BLOCK ***** *) @@ -35,7 +35,7 @@ uses Classes, {$IFDEF VER130} - Windows, // Need in D5 for definition of THandle + Windows, // Need in D5 for definition of THandle {$ENDIF} MMIOAPI, OFOptions, SysUtils, MMToolsAPI, OFDefs; @@ -98,6 +98,13 @@ const SObjectFoundry = 'ObjectFoundry'; +type + TMMAttributeValidator = class(TInstantAttributeValidator) + public + procedure Validate; override; + end; + + // Function externalised from AttributeEditorLoadClasses function. function TObjectFoundryExpert.IsInstantObjectClass(AClass: IMMClassBase): Boolean; @@ -184,6 +191,7 @@ var Attribute: TMMCodeAttribute; lClass: IMMClassifier; + AttributeValidator: TMMAttributeValidator; function GetBaseClassStorageName: String; begin @@ -201,6 +209,7 @@ begin lClass := P.ClassBase; Attribute := TMMCodeAttribute.Create(P); + AttributeValidator := TMMAttributeValidator.Create(Attribute, P); try with TInstantAttributeEditorForm.Create(nil) do try @@ -208,6 +217,7 @@ OnLoadClasses := AttributeEditorLoadClasses; OnIsClassPersistent := ClassIsPersistent; Subject := Attribute; + Validator := AttributeValidator; Result := ShowModal = mrOK; if Result then Attribute.ApplyChanges; @@ -215,6 +225,7 @@ Free; end; finally + AttributeValidator.Free; Attribute.Free; end; end else @@ -577,4 +588,48 @@ end; end; +{ TMMAttributeValidator } + +procedure TMMAttributeValidator.Validate; +var + MMProperty: IMMProperty; + CodeClass: IMMClassifier; + I: Integer; + + procedure CheckChildClass(CurrentClass: IMMClassifier); + var + J: Integer; + begin + if CurrentClass = nil then + Exit; + for J := 0 to Pred(CurrentClass.DescendantCount) do + begin + if CurrentClass.Descendants[J].FindMember(Attribute.Name, I) then + raise Exception.CreateFmt('Attribute "%s" exists in descendant class "%s"', + [Attribute.Name, CurrentClass.Descendants[J].Name]); + CheckChildClass(CurrentClass.Descendants[J]); + end; + end; + +begin + if MMInterface = nil then + Exit; + MMProperty := MMInterface as IMMProperty; + + if MMProperty.ClassBase.FindMember(Attribute.Name, I) then + raise Exception.Create('Attribute Name already used'); + + // check that the same attribute name is not used in an ancestor class + CodeClass := MMProperty.ClassBase; + while (CodeClass <> nil) do + begin + if CodeClass.FindMember(Attribute.Name, I) then + raise Exception.CreateFmt('Attribute "%s" exists in ancestor class "%s"', + [Attribute.Name, CodeClass.Name]); + CodeClass := CodeClass.Ancestor; + end; + // check that the same attribute name is not used in any child class + CheckChildClass(MMProperty.ClassBase); +end; + end. |
From: <na...@us...> - 2006-11-28 07:20:59
|
Revision: 722 http://svn.sourceforge.net/instantobjects/revision/?rev=722&view=rev Author: nandod Date: 2006-11-27 23:20:59 -0800 (Mon, 27 Nov 2006) Log Message: ----------- * changed doc format to html (supports diffing and is editable with just about any editor). Added Paths: ----------- trunk/Docs/InterBase_DataTypes.html Removed Paths: ------------- trunk/Docs/Interbase DataTypes.doc Copied: trunk/Docs/InterBase_DataTypes.html (from rev 721, trunk/Docs/Interbase DataTypes.doc) =================================================================== (Binary files differ) Deleted: trunk/Docs/Interbase DataTypes.doc =================================================================== (Binary files differ) |
From: <fas...@us...> - 2006-11-28 01:35:16
|
Revision: 721 http://svn.sourceforge.net/instantobjects/revision/?rev=721&view=rev Author: fastbike2 Date: 2006-11-27 17:34:47 -0800 (Mon, 27 Nov 2006) Log Message: ----------- Explanatory document for IO to Interbase data type mappings Added Paths: ----------- trunk/Docs/Interbase DataTypes.doc Added: trunk/Docs/Interbase DataTypes.doc =================================================================== (Binary files differ) Property changes on: trunk/Docs/Interbase DataTypes.doc ___________________________________________________________________ Name: svn:mime-type + application/octet-stream |
From: <sr...@us...> - 2006-11-27 08:09:32
|
Revision: 720 http://svn.sourceforge.net/instantobjects/revision/?rev=720&view=rev Author: srmitch Date: 2006-11-27 00:09:29 -0800 (Mon, 27 Nov 2006) Log Message: ----------- 1. Add an 'EnsureContainerObjects' property to the TInstantObject class. This property, when set to true, will cause all persistent objects referenced in container attributes of instances of this class to be retrieved and instantiated in one process for each container attribute. Container attributes, however, that have their 'EnsureContainerObjects' property (see below) set to true are ignored. The new property will be added to the class metadata so that it can be available at design-time and is persistent; 2. Add a 'Ensure Container Attribute Objects' check box option to the 'Class' page of the Class Editor in the InstantObjects Model Explorer. Add the supporting metadata processing; 3. Add an 'EnsureContainerObjects' property to the TInstantAttribute class. This property, when set to true, will cause all persistent objects referenced in a container attribute to be retrieved and instantiated in one process during the its creation. The new property will be added to the attribute metadata so that it can be available at design-time and is persistent; 4. Add an 'Ensure Container Objects' check box option to the 'Access' page of the Attribute Editor in the InstantObjects Model Explorer. Add the supporting metadata processing; 5. Add an 'EnsureObjects' property to TInstantCustomExposer and publish it in TInstantSelector. Add an 'EnsureObjects' property to TInstantQuery to support the new 'EnsureObjects' property in TInstantSelector; 6. Add several methods to the TInstantBroker and derived/supporting classes to provide the necessary processing for the retrieval and instantiation of multiple persistent objects and/or their container attribute objects. The TInstantBroker public methods are as follows: - procedure TInstantBroker.RetrieveAllObjects(AObjectsClass: TInstantObjectClass; AObjectIdList: TStrings); [Used to instantiate all the objects of AObjectsClass in the persistent store. RetrieveAllObjects passes back the retrieved objects in AObjectIdList, which must be created before calling.] - procedure TInstantBroker.RetrieveMixedObjects(AObjRefList: TInstantObjectReferenceList); [Used to instantiate the objects referenced in AObjRefList from the persistent store. RetrieveMixedObjects passes back the retrieved objects in AObjRefList, which must be created and initialised before calling.] - procedure TInstantBroker.RetrieveObjects(AObjectsClass: TInstantObjectClass; AObjectIdList: TStrings); [Used to instantiate the objects of AObjectsClass referenced by their Id in AObjectIdList from the persistent store. RetrieveObjects passes back the retrieved objects in AObjectIdList, which must be created and initialised before calling.] Modified Paths: -------------- branches/EnsureObjectsDev/Demos/PrimerCross/MainData.dfm branches/EnsureObjectsDev/Demos/PrimerCross/ModelExternal/Model.pas branches/EnsureObjectsDev/Source/Core/InstantBrokers.pas branches/EnsureObjectsDev/Source/Core/InstantCode.pas branches/EnsureObjectsDev/Source/Core/InstantMetadata.pas branches/EnsureObjectsDev/Source/Core/InstantPersistence.pas branches/EnsureObjectsDev/Source/Core/InstantPresentation.pas branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.dfm branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.pas branches/EnsureObjectsDev/Source/Design/InstantClassEditor.dfm branches/EnsureObjectsDev/Source/Design/InstantClassEditor.pas branches/EnsureObjectsDev/Tests/TestInstantAttribute.pas branches/EnsureObjectsDev/Tests/TestInstantAttributeMetadata.pas branches/EnsureObjectsDev/Tests/TestInstantClassMetadata.pas branches/EnsureObjectsDev/Tests/TestInstantObject.pas branches/EnsureObjectsDev/Tests/TestMinimalModel.pas Added Paths: ----------- branches/EnsureObjectsDev/Docs/[RFC]_IO-002_EnsureObjects_Performance_Enhancement_Option.txt Modified: branches/EnsureObjectsDev/Demos/PrimerCross/MainData.dfm =================================================================== --- branches/EnsureObjectsDev/Demos/PrimerCross/MainData.dfm 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Demos/PrimerCross/MainData.dfm 2006-11-27 08:09:29 UTC (rev 720) @@ -8,6 +8,7 @@ FieldOptions = [foObjects, foThorough] Sorted = True OnCompare = CountrySelectorCompare + EnsureObjects = True Command.Strings = ( 'SELECT * FROM TCountry') Left = 40 @@ -22,6 +23,7 @@ FieldOptions = [foObjects, foThorough] Sorted = True OnCompare = CategorySelectorCompare + EnsureObjects = True Command.Strings = ( 'SELECT * FROM TCategory') Left = 136 Modified: branches/EnsureObjectsDev/Demos/PrimerCross/ModelExternal/Model.pas =================================================================== --- branches/EnsureObjectsDev/Demos/PrimerCross/ModelExternal/Model.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Demos/PrimerCross/ModelExternal/Model.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -166,7 +166,7 @@ end; TPerson = class(TContact) - {IOMETADATA stored; + {IOMETADATA stored ensureobjects; BirthDate: DateTime; Emails: Parts(TEmail) external 'Person_Emails'; Employer: Reference(TCompany); @@ -211,7 +211,7 @@ end; TCompany = class(TContact) - {IOMETADATA stored; + {IOMETADATA stored ensureobjects; Employees: References(TPerson) external 'Company_Employees'; } _Employees: TInstantReferences; private Added: branches/EnsureObjectsDev/Docs/[RFC]_IO-002_EnsureObjects_Performance_Enhancement_Option.txt =================================================================== --- branches/EnsureObjectsDev/Docs/[RFC]_IO-002_EnsureObjects_Performance_Enhancement_Option.txt (rev 0) +++ branches/EnsureObjectsDev/Docs/[RFC]_IO-002_EnsureObjects_Performance_Enhancement_Option.txt 2006-11-27 08:09:29 UTC (rev 720) @@ -0,0 +1,42 @@ +RFC: IO-002 +Title: EnsureObjects Performance Enhancement Option +Author: Steven Mitchell +First Draft: 27 Nov 2006 +Current Revision: 0, 27 Nov 2006 + += Goal = + +Currently all object retrievals from the persistence store (eg database) in the IO framework is done individually for each persistent object and each of its container attribute objects. Employing such a 'lazy load' philosophy has both advantages and disadvantages. One of the disadvantages can be the numerous round trips to the persistence store to load a list of objects. This can cause noticeable delays and network traffic when connecting to remote persistence stores. Options in the IO framework to allow the retrieval and instantiation of multiple persistent objects would be helpful to reduce these problems. + += Proposal = + +To provide run-time and design-time options within the IO framework to allow the retrieval and instantiation of multiple persistent objects and/or their container attribute objects as follows: + +1. Add an 'EnsureContainerObjects' property to the TInstantObject class. This property, when set to true, will cause all persistent objects referenced in container attributes of instances of this class to be retrieved and instantiated in one process for each container attribute. Container attributes, however, that have their 'EnsureContainerObjects' property (see below) set to true are ignored. The new property will be added to the class metadata so that it can be available at design-time and is persistent; + +2. Add a 'Ensure Container Attribute Objects' check box option to the 'Class' page of the Class Editor in the InstantObjects Model Explorer. Add the supporting metadata processing; + +3. Add an 'EnsureContainerObjects' property to the TInstantAttribute class. This property, when set to true, will cause all persistent objects referenced in a container attribute to be retrieved and instantiated in one process during the its creation. The new property will be added to the attribute metadata so that it can be available at design-time and is persistent; + +4. Add an 'Ensure Container Objects' check box option to the 'Access' page of the Attribute Editor in the InstantObjects Model Explorer. Add the supporting metadata processing; + +5. Add an 'EnsureObjects' property to TInstantCustomExposer and publish it in TInstantSelector. Add an 'EnsureObjects' property to TInstantQuery to support the new 'EnsureObjects' property in TInstantSelector; + +6. Add several methods to the TInstantBroker and derived/supporting classes to provide the necessary processing for the retrieval and instantiation of multiple persistent objects and/or their container attribute objects. The TInstantBroker public methods are as follows: + +- procedure TInstantBroker.RetrieveAllObjects(AObjectsClass: TInstantObjectClass; AObjectIdList: TStrings); +[Used to instantiate all the objects of AObjectsClass in the persistent store. RetrieveAllObjects passes back the retrieved objects in AObjectIdList, which must be created before calling.] + +- procedure TInstantBroker.RetrieveMixedObjects(AObjRefList: TInstantObjectReferenceList); +[Used to instantiate the objects referenced in AObjRefList from the persistent store. RetrieveMixedObjects passes back the retrieved objects in AObjRefList, which must be created and initialised before calling.] + +- procedure TInstantBroker.RetrieveObjects(AObjectsClass: TInstantObjectClass; AObjectIdList: TStrings); +[Used to instantiate the objects of AObjectsClass referenced by their Id in AObjectIdList from the persistent store. RetrieveObjects passes back the retrieved objects in AObjectIdList, which must be created and initialised before calling.] + += Use = + +NOTE: Initially only implemented when using SQL based brokers. Use with other brokers will raise exceptions. + +At design-time use InstantObjects Model Explorer to 'ensure the attributes' of the class or its individual container attributes as desired. + +At run-time use the broker methods passing in an appropriately created list. Use a TInstantQuery (TInstantSQLQuery only implemented initially) and set its 'EnsureObjects' property to true before opening it. Property changes on: branches/EnsureObjectsDev/Docs/[RFC]_IO-002_EnsureObjects_Performance_Enhancement_Option.txt ___________________________________________________________________ Name: svn:eol-style + native Modified: branches/EnsureObjectsDev/Source/Core/InstantBrokers.pas =================================================================== --- branches/EnsureObjectsDev/Source/Core/InstantBrokers.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Core/InstantBrokers.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -120,9 +120,15 @@ function GetSQLWildcard: string; virtual; function InternalDisposeObject(AObject: TInstantObject; ConflictAction: TInstantConflictAction): Boolean; override; + procedure InternalRetrieveAllObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); override; + procedure InternalRetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); override; function InternalRetrieveObject(AObject: TInstantObject; const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; override; + procedure InternalRetrieveObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); override; function InternalStoreObject(AObject: TInstantObject; ConflictAction: TInstantConflictAction): Boolean; override; public @@ -153,6 +159,12 @@ override; function FindResolver(const TableName: string): TInstantNavigationalResolver; + procedure InternalRetrieveAllObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); override; + procedure InternalRetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); override; + procedure InternalRetrieveObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); override; property ResolverCount: Integer read GetResolverCount; property Resolvers[Index: Integer]: TInstantNavigationalResolver read GetResolvers; @@ -182,10 +194,18 @@ virtual; function CreateDataSet(const AStatement: string; AParams: TParams = nil): TDataSet; virtual; abstract; + procedure InternalRetrieveAllObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); override; + procedure InternalRetrieveObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); override; + procedure InternalRetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); override; public destructor Destroy; override; function AcquireDataSet(const AStatement: string; AParams: TParams = nil): TDataSet; virtual; + procedure CreateObjectsFromDataset(AObjectsClass: TInstantObjectClass; + ADataSet: TDataSet; AObjectIdList: TStrings); procedure ReleaseDataSet(const ADataSet: TDataSet); virtual; function DataTypeToColumnType(DataType: TInstantDataType; Size: Integer): string; virtual; abstract; @@ -668,6 +688,7 @@ function BuildFieldList(Map: TInstantAttributeMap; Additional: array of string): string; overload; function BuildFieldList(const S: string): string; overload; + function BuildTableQualifiedFieldList(const S, ATableName: string): string; function BuildParam(const AName: string): string; virtual; function BuildParamList(Map: TInstantAttributeMap; Additional: array of string): string; @@ -705,6 +726,9 @@ string; virtual; function InternalGenerateSelectExternalPartSQL(Map: TInstantAttributeMap): string; virtual; + function InternalGenerateSelectMultipleQualifiedSQL(Maps: + TInstantAttributeMaps; const StatementInParameters: string = ''): string; + virtual; function InternalGenerateSelectTablesSQL: string; virtual; function InternalGenerateUpdateConcurrentSQL(Map: TInstantAttributeMap): string; virtual; @@ -732,6 +756,8 @@ function GenerateSelectSQL(Map: TInstantAttributeMap): string; function GenerateSelectExternalSQL(Map: TInstantAttributeMap): string; function GenerateSelectExternalPartSQL(Map: TInstantAttributeMap): string; + function GenerateSelectMultipleQualifiedSQL(Maps: TInstantAttributeMaps; const + StatementInParameters: string = ''): string; function GenerateSelectTablesSQL: string; function GenerateUpdateConcurrentSQL(Map: TInstantAttributeMap): string; function GenerateUpdateFieldCopySQL(OldMetadata, NewMetadata: @@ -1088,6 +1114,20 @@ ConflictAction); end; +procedure TInstantCustomRelationalBroker.InternalRetrieveAllObjects( + AObjectsClass: TInstantObjectClass; AObjectIdList: TStrings); +begin + raise EInstantError.CreateFmt( + SMissingImplementation, ['InternalRetrieveAllObjects', ClassName]); +end; + +procedure TInstantCustomRelationalBroker.InternalRetrieveMixedObjects( + AObjRefList: TInstantObjectReferenceList); +begin + raise EInstantError.CreateFmt( + SMissingImplementation, ['InternalRetrieveMixedObjects', ClassName]); +end; + function TInstantCustomRelationalBroker.InternalRetrieveObject( AObject: TInstantObject; const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; @@ -1096,6 +1136,13 @@ ConflictAction); end; +procedure TInstantCustomRelationalBroker.InternalRetrieveObjects(AObjectsClass: + TInstantObjectClass; AObjectIdList: TStrings); +begin + raise EInstantError.CreateFmt( + SMissingImplementation, ['InternalRetrieveObjects', ClassName]); +end; + function TInstantCustomRelationalBroker.InternalStoreObject( AObject: TInstantObject; ConflictAction: TInstantConflictAction): Boolean; begin @@ -1266,6 +1313,27 @@ Result := ResolverList[Index] as TInstantNavigationalResolver; end; +procedure TInstantNavigationalBroker.InternalRetrieveAllObjects(AObjectsClass: + TInstantObjectClass; AObjectIdList: TStrings); +begin + raise EInstantError.CreateFmt( + SMissingImplementation, ['InternalRetrieveAllObjects', ClassName]); +end; + +procedure TInstantNavigationalBroker.InternalRetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); +begin + raise EInstantError.CreateFmt( + SMissingImplementation, ['InternalRetrieveMixedObjects', ClassName]); +end; + +procedure TInstantNavigationalBroker.InternalRetrieveObjects(AObjectsClass: + TInstantObjectClass; AObjectIdList: TStrings); +begin + raise EInstantError.CreateFmt( + SMissingImplementation, ['InternalRetrieveObjects', ClassName]); +end; + destructor TInstantSQLBroker.Destroy; begin FGenerator.Free; @@ -1310,6 +1378,92 @@ raise EInstantError.CreateFmt(SMissingImplementation, ['AssignDataSetParams', ClassName]); end; +procedure TInstantSQLBroker.CreateObjectsFromDataset(AObjectsClass: + TInstantObjectClass; ADataSet: TDataSet; AObjectIdList: TStrings); + + procedure UpdateListWithObject(AObject: TInstantObject; + const AObjectId: string); + var + Idx: Integer; + begin + Idx := AObjectIdList.IndexOf(AObjectId); + if Idx = -1 then + begin + Idx := AObjectIdList.Add(AObjectId); + AObjectIdList.Objects[Idx] := AObject; + end + else + AObjectIdList.Objects[Idx] := AObject; + end; + + procedure ResolveAttributesFromDataset(AObject: TInstantObject; + const AObjectId: string); + var + I: Integer; + Map: TInstantAttributeMap; + begin + with AObject.Metadata do + begin + for I := 0 to Pred(StorageMaps.Count) do + begin + Map := StorageMaps[I]; + if Map.IsRootMap then + SetObjectUpdateCount(AObject, + ADataSet.FieldByName(InstantUpdateCountFieldName).AsInteger); + TInstantSQLResolver(EnsureResolver(Map)).ReadAttributes( + AObject, AObjectId, Map, ADataset); + end; + end; + end; + +var + Obj: TInstantObject; + ObjStore: TInstantObjectStore; + DsId: string; + DsWasActive: Boolean; + Instance: TInstantObject; +begin + if not Assigned(AObjectIdList) or not Assigned(ADataSet) then + Exit; + + DsWasActive := ADataset.Active; + if not DsWasActive then + ADataset.Open; + try + ObjStore := Connector.EnsureObjectStore(AObjectsClass); + ADataset.First; + while not ADataset.Eof do + begin + DsId := ADataset.FindField(InstantIdFieldName).AsString; + Obj := AObjectsClass.Create(Connector); + Instance := ObjStore.Find(DsId); + if Assigned(Instance) then + begin + Obj.FreeInstance; + Obj := Instance; + Obj.AddRef; + end + else + begin + Obj.DisableChanges; + try + ResolveAttributesFromDataset(Obj, DsId); + finally + Obj.EnableChanges; + end; + ObjStore.EnsureObject(DsId, Obj); + end; + + UpdateListWithObject(Obj, DsId); + + ADataset.Next; + end; + finally + if not DsWasActive then + ADataset.Close; + end; +end; + function TInstantSQLBroker.EnsureResolver( AMap: TInstantAttributeMap): TInstantCustomResolver; begin @@ -1396,6 +1550,38 @@ end; end; +procedure TInstantSQLBroker.InternalRetrieveAllObjects(AObjectsClass: + TInstantObjectClass; AObjectIdList: TStrings); +var + Params: TParams; + Statement: string; + Resolver: TInstantSQLResolver; + ObjDataset: TDataset; + Maps: TInstantAttributeMaps; +begin + if not AObjectsClass.Metadata.IsStored or not Assigned(AObjectIdList) then + Exit; + + Maps := AObjectsClass.Metadata.StorageMaps; + Statement := Generator.GenerateSelectMultipleQualifiedSQL(Maps); + Resolver := TInstantSQLResolver(EnsureResolver(Maps.RootMap)); + + Params := TParams.Create; + try + Resolver.AddParam(Params, InstantClassFieldName, ftString).AsString := + AObjectsClass.ClassName; + + ObjDataset := AcquireDataSet(Statement, Params); + try + CreateObjectsFromDataset(AObjectsClass, ObjDataset, AObjectIdList); + finally + ReleaseDataSet(ObjDataset); + end; + finally + Params.Free; + end; +end; + procedure TInstantSQLBroker.ReleaseDataSet(const ADataSet: TDataSet); begin if FStatementCacheCapacity <> 0 then @@ -1404,6 +1590,123 @@ ADataSet.Free; end; +procedure TInstantSQLBroker.InternalRetrieveObjects(AObjectsClass: + TInstantObjectClass; AObjectIdList: TStrings); +var + I: Integer; + Params: TParams; + ObjDataset: TDataset; + Resolver: TInstantSQLResolver; + Statement, StatementInParameters: String; + +begin + if not AObjectsClass.Metadata.IsStored or (AObjectIdList.Count = 0) then + Exit; + + StatementInParameters := ''; + for I:=0 to Pred(AObjectIdList.Count) do + begin + StatementInParameters := StatementInParameters + ':' + + InstantIdFieldName + IntToStr(I); + if I < Pred(AObjectIdList.Count) then + StatementInParameters := StatementInParameters + ', '; + end; + + Statement := Generator.GenerateSelectMultipleQualifiedSQL( + AObjectsClass.Metadata.StorageMaps, StatementInParameters); + + Resolver := TInstantSQLResolver( + EnsureResolver(AObjectsClass.Metadata.StorageMaps.RootMap)); + + Params := TParams.Create; + try + Resolver.AddParam(Params, InstantClassFieldName, ftString).AsString := + AObjectsClass.ClassName; + for I := 0 to Pred(AObjectIdList.Count) do + begin + Resolver.AddIdParam(Params, InstantIdFieldName + IntToStr(I), + AObjectIdList[I]); + end; + + ObjDataset := AcquireDataSet(Statement, Params); + try + CreateObjectsFromDataset(AObjectsClass, ObjDataset, AObjectIdList); + finally + ReleaseDataSet(ObjDataset); + end; + finally + Params.Free; + end; +end; + +procedure TInstantSQLBroker.InternalRetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); + + function IsReferencedClassPersistent(AObjRef: TInstantObjectReference): + Boolean; + begin + Result := AObjRef.ObjectClass.Metadata.IsStored; + end; + +var + I: Integer; + ClassNameList: TStringList; + J: Integer; + Idx: Integer; + ObjIdList: TStringList; + K: Integer; + ObjClassName: string; + Ref: TInstantObjectReference; +begin + if not Assigned(AObjRefList) or (AObjRefList.Count = 0) then + Exit; + + ClassNameList := TStringList.Create; + try + for I := 0 to Pred(AObjRefList.Count) do + begin + Ref := AObjRefList.RefItems[I]; + ObjClassName := Ref.ObjectClassName; + Idx := ClassNameList.IndexOf(ObjClassName); + if (Idx = -1) and IsReferencedClassPersistent(Ref) then + ClassNameList.Add(ObjClassName); + end; + + for I := 0 to Pred(ClassNameList.Count) do + begin + ObjIdList := TStringList.Create; + try + for J := 0 to Pred(AObjRefList.Count) do + if AObjRefList.RefItems[J].ObjectClassName = ClassNameList[I] then + begin + Idx := ObjIdList.IndexOf(AObjRefList.RefItems[J].ObjectId); + if Idx = -1 then + ObjIdList.Add(AObjRefList.RefItems[J].ObjectId); + end; + + RetrieveObjects(InstantFindClass(ClassNameList[I]), ObjIdList); + + for J := 0 to Pred(ObjIdList.Count) do + for K := 0 to Pred(AObjRefList.Count) do + if AObjRefList.RefItems[K].Equals( + TInstantObject(ObjIdList.Objects[J])) then + begin + if not AObjRefList.RefItems[K].HasInstance then + AObjRefList[K] := TInstantObject(ObjIdList.Objects[J]); + if AObjRefList.RefItems[K].OwnsInstance then + ObjIdList.Objects[J].Free; + Break; + end; + + finally + ObjIdList.Free; + end; + end; + finally + ClassNameList.Free; + end; +end; + { TInstantRelationalConnector } procedure TInstantRelationalConnector.DoGetDataSet(const CommandText: string; @@ -4178,6 +4481,29 @@ Result := BuildList(Map, Additional, EmbraceField); end; +function TInstantSQLGenerator.BuildTableQualifiedFieldList(const S, ATableName: + string): string; +var + I: Integer; + List: TStringList; +begin + List := TStringList.Create; + try + InstantStrToList(S, List, [' ', ',']); + Result := ''; + for I := 0 to Pred(List.Count) do + begin + if Trim(List[I]) <> '' then + Result := Result + InstantEmbrace(ATableName, Broker.SQLDelimiters) + + '.' + List[I] + ' , '; + end; + if Length(Result) > 0 then + Delete(Result, Length(Result) - 2, 3); + finally + List.Free; + end; +end; + function TInstantSQLGenerator.BuildList(Map: TInstantAttributeMap; Additional: array of string; StringFunc: TInstantStringFunc; const Delimiter: string): string; @@ -4365,6 +4691,13 @@ Result := InternalGenerateSelectSQL(Map); end; +function TInstantSQLGenerator.GenerateSelectMultipleQualifiedSQL(Maps: + TInstantAttributeMaps; const StatementInParameters: string = ''): string; +begin + Result := InternalGenerateSelectMultipleQualifiedSQL(Maps, + StatementInParameters); +end; + function TInstantSQLGenerator.GenerateSelectTablesSQL: string; begin Result := InternalGenerateSelectTablesSQL; @@ -4587,6 +4920,65 @@ [FieldStr, EmbraceTable(Map.Name), WhereStr]); end; +function TInstantSQLGenerator.InternalGenerateSelectMultipleQualifiedSQL(Maps: + TInstantAttributeMaps; const StatementInParameters: string = ''): string; +var + FieldStr: string; + TableStr: String; + Map: TInstantAttributeMap; + WhereStr: string; + WhereStrA: string; + WhereStrB: string; + RootClassFldName: string; + RootIdFldName: string; + I: Integer; + + function BuildTableQualifiedFieldStr(AMap: TInstantAttributeMap): string; + begin + if AMap.IsRootMap then + Result := BuildFieldList(AMap, [InstantClassFieldName, + InstantIdFieldName, InstantUpdateCountFieldName]) + else + Result := BuildFieldList(AMap, []); + Result := BuildTableQualifiedFieldList(Result, AMap.Name); + end; + +begin + Map := Maps.RootMap; + RootClassFldName := EmbraceTable(Map.Name) + '.' + + EmbraceField(InstantClassFieldName); + RootIdFldName := EmbraceTable(Map.Name) + '.' + + EmbraceField(InstantIdFieldName); + WhereStrA := RootClassFldName + '=:' + InstantClassFieldName; + if StatementInParameters <> '' then + WhereStrB := RootIdFldName + ' IN (' + StatementInParameters + ')'; + FieldStr := BuildTableQualifiedFieldStr(Map); + TableStr := EmbraceTable(Map.Name); + + for I := 0 to Pred(Maps.Count) do + begin + Map := Maps[I]; + if not Map.IsRootMap then + begin + FieldStr := FieldStr + ', ' + BuildTableQualifiedFieldStr(Map); + TableStr := TableStr + ', ' + EmbraceTable(Map.Name); + WhereStrA := WhereStrA + ' AND ' + EmbraceTable(Map.Name) + '.' + + EmbraceField(InstantClassFieldName) + '=' + RootClassFldName; + if StatementInParameters <> '' then + WhereStrB := WhereStrB + ' AND ' + EmbraceTable(Map.Name) + '.' + + EmbraceField(InstantIdFieldName) + '=' + RootIdFldName; + end; + end; + + if StatementInParameters <> '' then + WhereStrB := ' AND ' + WhereStrB; + + WhereStr := WhereStrA + WhereStrB; + + Result := Format('SELECT %s FROM %s WHERE %s', + [FieldStr, TableStr, WhereStr]); +end; + function TInstantSQLGenerator.InternalGenerateSelectTablesSQL: string; begin raise EInstantError.CreateFmt(SUnsupportedOperation, @@ -5826,6 +6218,9 @@ if (MaxCount > 0) and (ObjectReferenceList.Count = MaxCount) then break; DataSet.Next; end; + + if EnsureObjects and (ObjectReferenceList.Count > 0) then + Connector.Broker.RetrieveMixedObjects(ObjectReferenceList); finally DataSet.EnableControls; end; Modified: branches/EnsureObjectsDev/Source/Core/InstantCode.pas =================================================================== --- branches/EnsureObjectsDev/Source/Core/InstantCode.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Core/InstantCode.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -625,6 +625,8 @@ procedure SetStorageKind(const Value: TInstantStorageKind); function GetCanHaveStorageName: boolean; function GetCanBeExternal: boolean; + function GetEnsureContainerObjects: Boolean; + procedure SetEnsureContainerObjects(const Value: Boolean); protected function GetIsDefault: Boolean; virtual; function GetMethodName(MethodType: TInstantCodeContainerMethodType): string; @@ -677,6 +679,8 @@ property AttributeTypeName: string read GetAttributeTypeName write SetAttributeTypeName; property AttributeTypeText: string read GetAttributeTypeText; + property EnsureContainerObjects: Boolean read GetEnsureContainerObjects write + SetEnsureContainerObjects; property ExternalStorageName: string read GetExternalStorageName write SetExternalStorageName; property IncludeAddMethod: Boolean read GetIncludeAddMethod @@ -759,11 +763,13 @@ function GetAttributeCount: Integer; function GetAttributes(Index: Integer): TInstantCodeAttribute; function GetClassStatement: string; + function GetEnsureContainerObjects: Boolean; function GetIsStored: Boolean; function GetMetadata: TInstantClassMetadata; function GetOwner: TInstantCodeClass; reintroduce; function GetPersistence: TInstantPersistence; function GetStorageName: string; + procedure SetEnsureContainerObjects(const Value: Boolean); procedure SetPersistence(Value: TInstantPersistence); procedure SetStorageName(const Value: string); protected @@ -797,6 +803,8 @@ property Metadata: TInstantClassMetadata read GetMetadata; property Owner: TInstantCodeClass read GetOwner; published + property EnsureContainerObjects: Boolean read GetEnsureContainerObjects write + SetEnsureContainerObjects; property Persistence: TInstantPersistence read GetPersistence write SetPersistence; property StorageName: string read GetStorageName write SetStorageName; end; @@ -851,6 +859,7 @@ function GetBaseClassName: string; function GetDivisionCount: Integer; function GetDivisions(Index: Integer): TInstantCodeDivision; + function GetEnsureContainerObjects: Boolean; function GetFieldCount: Integer; function GetFields(Index: Integer): TInstantCodeField; function GetImplementationComment: string; @@ -875,6 +884,7 @@ procedure SetStorageName(const Value: string); procedure SetUnitName(const Value: string); procedure RemoveDivision(Division: TInstantCodeDivision); + procedure SetEnsureContainerObjects(const Value: Boolean); protected function AddDivision(Visibility: TInstantCodeVisibility): TInstantCodeDivision; procedure InsertDivision(Division: TInstantCodeDivision); @@ -949,6 +959,8 @@ property SubClasses[Index: Integer]: TInstantCodeClass read GetSubClass; published property BaseClassName: string read GetBaseClassName write SetBaseClassName; + property EnsureContainerObjects: Boolean read GetEnsureContainerObjects write + SetEnsureContainerObjects; property Persistence: TInstantPersistence read GetPersistence write SetPersistence; property StorageName: string read GetStorageName write SetStorageName; property UnitName: string read GetUnitName write SetUnitName; @@ -1548,6 +1560,7 @@ MetaKeyEmbedded = 'embedded'; MetaKeyValid = 'valid'; MetaKeyWidth = 'width'; + MetaKeyEnsureObjects = 'ensureobjects'; ModuleTypeNames: array[TInstantCodeModuleType] of string = ('program', 'unit', 'library'); @@ -1794,6 +1807,8 @@ Token := ReadToken; if SameText(Token, MetaKeyStored) then FMetadata.StorageName := ReadStringValue; + if SameText(Token, MetaKeyEnsureObjects) then + FMetadata.EnsureContainerObjects := True; if SameText(Token, MetaKeyDefault) then FMetadata.IsDefault := True; if SameText(Token, MetaKeyExternal) then @@ -3623,6 +3638,7 @@ Self.IsIndexed := IsIndexed; Self.IsRequired := IsRequired; Self.ReadOnly := ReadOnly; + Self.EnsureContainerObjects := EnsureContainerObjects; Self.SingularName := SingularName; Self.Visibility := Visibility; Self.Metadata.Assign(Metadata); @@ -4041,6 +4057,8 @@ Writer.Write(' ' + MetaKeyRequired); if IsDefault then Writer.Write(' ' + MetaKeyDefault); + if EnsureContainerObjects then + Writer.Write(' ' + MetaKeyEnsureObjects); Writer.Write(';'); end; @@ -4211,6 +4229,16 @@ Result := AttributeType in [atPart, atParts, atReferences]; end; +function TInstantCodeAttribute.GetEnsureContainerObjects: Boolean; +begin + Result := Metadata.EnsureContainerObjects; +end; + +procedure TInstantCodeAttribute.SetEnsureContainerObjects(const Value: Boolean); +begin + Metadata.EnsureContainerObjects := Value; +end; + { TInstantCodeClassLink } function TInstantCodeClassLink.FindInstance: TInstantCodeObject; @@ -4320,6 +4348,7 @@ begin Self.Persistence := Persistence; Self.StorageName := StorageName; + Self.EnsureContainerObjects := EnsureContainerObjects; Self.AssignAttributes(FAttributes); end; end; @@ -4404,18 +4433,35 @@ function TInstantCodeMetadataInfo.GetClassStatement: string; begin + if (AttributeCount = 0) and (Persistence = peEmbedded) then + begin + Result := MetaKeyEmbedded + ';'; + Exit + end; + + Result := ''; if Persistence = peStored then begin Result := MetaKeyStored; if Metadata.StorageName <> '' then Result := Result + ' ''' + StorageName + ''''; + end; + + if EnsureContainerObjects then + if Result <> '' then + Result := Result + ' ' + MetaKeyEnsureObjects + else + Result := MetaKeyEnsureObjects; + + if Result <> '' then Result := Result + ';'; - end else if AttributeCount = 0 then - Result := MetaKeyEmbedded + ';' - else - Result := ''; end; +function TInstantCodeMetadataInfo.GetEnsureContainerObjects: Boolean; +begin + Result := Metadata.EnsureContainerObjects; +end; + function TInstantCodeMetadataInfo.GetIsEmpty: Boolean; begin Result := False; @@ -4532,6 +4578,11 @@ begin Persistence := peStored; StorageName := Reader.ReadStringValue; + Reader.ReadEndOfStatement(False); + end else if SameText(Token, MetaKeyEnsureObjects) then + begin + EnsureContainerObjects := True; + StorageName := Reader.ReadStringValue; Reader.ReadEndOfStatement(True); end else if Token = '}' then Break @@ -4600,6 +4651,12 @@ FAttributes.Remove(Attribute); end; +procedure TInstantCodeMetadataInfo.SetEnsureContainerObjects(const Value: + Boolean); +begin + Metadata.EnsureContainerObjects := Value; +end; + procedure TInstantCodeMetadataInfo.SetName(const Value: string); begin Metadata.Name := Value; @@ -5065,6 +5122,11 @@ Result := FDivisions[Index]; end; +function TInstantCodeClass.GetEnsureContainerObjects: Boolean; +begin + Result := MetadataInfo.EnsureContainerObjects; +end; + function TInstantCodeClass.GetFieldCount: Integer; begin Result := FFields.Count; @@ -5336,6 +5398,11 @@ FBaseClassLink.Name := Value; end; +procedure TInstantCodeClass.SetEnsureContainerObjects(const Value: Boolean); +begin + MetadataInfo.EnsureContainerObjects := Value; +end; + procedure TInstantCodeClass.SetName(const Value: string); var I: Integer; Modified: branches/EnsureObjectsDev/Source/Core/InstantMetadata.pas =================================================================== --- branches/EnsureObjectsDev/Source/Core/InstantMetadata.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Core/InstantMetadata.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -76,6 +76,7 @@ private FAttributeMetadatas: TInstantAttributeMetadatas; FDefaultContainerName: string; + FEnsureContainerObjects: Boolean; FMemberMap: TInstantAttributeMap; FParent: TInstantClassMetadata; FParentName: string; @@ -126,6 +127,8 @@ published property DefaultContainerName: string read FDefaultContainerName write FDefaultContainerName; + property EnsureContainerObjects: Boolean read FEnsureContainerObjects write + FEnsureContainerObjects; property ParentName: string read GetParentName write SetParentName; property Persistence: TInstantPersistence read FPersistence write FPersistence; @@ -436,6 +439,7 @@ FDefaultValue: string; FDisplayWidth: Integer; FEditMask: string; + FEnsureContainerObjects: Boolean; FIsIndexed: Boolean; FIsRequired: Boolean; FObjectClassName: string; @@ -500,6 +504,8 @@ property DisplayWidth: Integer read FDisplayWidth write FDisplayWidth default 0; property EditMask: string read FEditMask write FEditMask; + property EnsureContainerObjects: Boolean read FEnsureContainerObjects write + FEnsureContainerObjects; property ExternalStorageName: string read FExternalStorageName write FExternalStorageName; property StorageKind: TInstantStorageKind read FStorageKind @@ -584,6 +590,7 @@ Self.FDefaultContainerName := FDefaultContainerName; Self.FStorageName := FStorageName; Self.FPersistence := FPersistence; + Self.FEnsureContainerObjects := FEnsureContainerObjects; end; end; @@ -1648,6 +1655,7 @@ Self.FEditMask := FEditMask; Self.FIsIndexed := FIsIndexed; Self.FIsRequired := FIsRequired; + Self.FEnsureContainerObjects := FEnsureContainerObjects; Self.FObjectClassName := FObjectClassName; Self.FSize := FSize; Self.FStorageName := FStorageName; Modified: branches/EnsureObjectsDev/Source/Core/InstantPersistence.pas =================================================================== --- branches/EnsureObjectsDev/Source/Core/InstantPersistence.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Core/InstantPersistence.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -156,6 +156,7 @@ private FIsChanged: Boolean; function GetIsIndexed: Boolean; + function GetEnsureContainerObjects: Boolean; function GetIsRequired: Boolean; function GetMetadata: TInstantAttributeMetadata; function GetName: string; @@ -212,6 +213,7 @@ property IsChanged: Boolean read GetIsChanged write SetIsChanged; property IsDefault: Boolean read GetIsDefault; property IsIndexed: Boolean read GetIsIndexed; + property EnsureContainerObjects: Boolean read GetEnsureContainerObjects; property IsMandatory: Boolean read GetIsMandatory; property IsRequired: Boolean read GetIsRequired; property Name: string read GetName; @@ -566,8 +568,10 @@ private function GetItems(Index: Integer): TInstantObject; function GetChangeCount: Integer; + function GetObjectReferences(Index: Integer): TInstantObjectReference; procedure SetItems(Index: Integer; AValue: TInstantObject); procedure QuickSort(L, R: Integer; Compare: TInstantSortCompare); + procedure SetObjectReferences(Index: Integer; AValue: TInstantObjectReference); protected procedure AfterContentChange(ChangeType: TInstantContentChangeType; Index: Integer; AObject: TInstantObject); @@ -577,27 +581,37 @@ function GetCount: Integer; virtual; abstract; function GetInstances(Index: Integer): TInstantObject; virtual; function GetIsDefault: Boolean; override; + procedure InternalSetObjectReferences(Index: Integer; AValue: + TInstantObjectReference); virtual; abstract; function InternalAdd(AObject: TInstantObject): Integer; virtual; abstract; function InternalAddReference(const AObjectClassName, AObjectId: string): Integer; virtual; abstract; procedure InternalClear; virtual; abstract; procedure InternalDelete(Index: Integer); virtual; abstract; + procedure InternalEnsureObjects; virtual; function InternalGetItems(Index: Integer): TInstantObject; virtual; abstract; function InternalIndexOf(AObject: TInstantObject): Integer; virtual; abstract; function InternalIndexOfInstance(Instance: Pointer): Integer; virtual; abstract; procedure InternalExchange(Index1, Index2: Integer); virtual; abstract; + function InternalGetObjectReferences(Index: Integer): TInstantObjectReference; + virtual; abstract; procedure InternalInsert(Index: Integer; AObject: TInstantObject); virtual; abstract; procedure InternalMove(CurIndex, NewIndex: Integer); virtual; abstract; procedure InternalSetItems(Index: Integer; AValue: TInstantObject); virtual; abstract; procedure ValidateObject(AObject: TInstantObject); override; property Instances[Index: Integer]: TInstantObject read GetInstances; + property ObjectReferences[Index: Integer]: TInstantObjectReference read + GetObjectReferences write SetObjectReferences; public + constructor Create(AOwner: TInstantAbstractObject = nil; AMetadata: + TInstantCollectionItem = nil); override; function Add(AObject: TInstantObject): Integer; function AddReference(const AObjectClassName, AObjectId: string): Integer; function AttachObject(AObject: TInstantObject): Boolean; override; procedure Clear; procedure Delete(Index: Integer); function DetachObject(AObject: TInstantObject): Boolean; override; + procedure EnsureObjects; procedure Exchange(Index1, Index2: Integer); function HasItem(Index: Integer): Boolean; function IndexOf(AObject: TInstantObject): Integer; @@ -625,10 +639,7 @@ property ObjectList: TObjectList read GetObjectList; function CreateObjectReference(AObject: TInstantObject): TInstantObjectReference; function GetObjectReferenceList: TObjectList; - function GetObjectReferences(Index: Integer): TInstantObjectReference; - procedure SetObjectReferences(Index: Integer; Value: TInstantObjectReference); property ObjectReferenceList: TObjectList read GetObjectReferenceList; - property ObjectReferences[Index: Integer]: TInstantObjectReference read GetObjectReferences write SetObjectReferences; protected class function AttributeType: TInstantAttributeType; override; function GetAllowOwned: Boolean; override; @@ -640,13 +651,18 @@ Integer; override; procedure InternalClear; override; procedure InternalDelete(Index: Integer); override; + procedure InternalEnsureObjects; override; function InternalGetItems(Index: Integer): TInstantObject; override; function InternalIndexOf(AObject: TInstantObject): Integer; override; function InternalIndexOfInstance(Instance: Pointer): Integer; override; procedure InternalExchange(Index1, Index2: Integer); override; + function InternalGetObjectReferences(Index: Integer): TInstantObjectReference; + override; procedure InternalInsert(Index: Integer; AObject: TInstantObject); override; procedure InternalMove(CurIndex, NewIndex: Integer); override; procedure InternalSetItems(Index: Integer; AValue: TInstantObject); override; + procedure InternalSetObjectReferences(Index: Integer; AValue: + TInstantObjectReference); override; procedure ReadObject(Reader: TInstantReader); override; procedure SetAllowOwned(Value: Boolean); virtual; procedure ValidateObject(AObject: TInstantObject); override; @@ -682,9 +698,13 @@ function InternalIndexOf(AObject: TInstantObject): Integer; override; function InternalIndexOfInstance(Instance: Pointer): Integer; override; procedure InternalExchange(Index1, Index2: Integer); override; + function InternalGetObjectReferences(Index: Integer): TInstantObjectReference; + override; procedure InternalInsert(Index: Integer; AObject: TInstantObject); override; procedure InternalMove(CurIndex, NewIndex: Integer); override; procedure InternalSetItems(Index: Integer; AValue: TInstantObject); override; + procedure InternalSetObjectReferences(Index: Integer; AValue: + TInstantObjectReference); override; procedure ReadObject(Reader: TInstantReader); override; procedure SetAllowOwned(Value: Boolean); virtual; procedure ValidateObject(AObject: TInstantObject); override; @@ -788,6 +808,7 @@ procedure Init; procedure Finit; function GetConnector: TInstantConnector; + function GetEnsureContainerObjects: Boolean; procedure PerformUpdate(Operation: TInstantUpdateOperation; OperationType: TInstantOperationType; ConflictAction: TInstantConflictAction); procedure ReadAttributes(Reader: TInstantReader); @@ -829,6 +850,7 @@ procedure Destruct; virtual; procedure DisposeOwnedObject(AObject: TInstantObject; ConflictAction: TInstantConflictAction); + procedure EnsureContainerAttributeObjects; virtual; procedure Finalize; virtual; function GenerateId: string; virtual; function GetCaption: string; virtual; @@ -845,6 +867,7 @@ procedure RestoreState; virtual; procedure SaveState; virtual; procedure SetConnector(AConnector: TInstantConnector); virtual; + procedure SetEnsureContainerObjects(const Value: Boolean); virtual; procedure SetId(const Value: string); virtual; function VerifyOperation(OperationType: TInstantOperationType): TInstantVerificationResult; virtual; procedure WriteObject(Writer: TInstantWriter); override; @@ -903,6 +926,8 @@ property Caption: string read GetCaption; property ClassId: string read GetClassId; property Connector: TInstantConnector read GetConnector; + property EnsureContainerObjects: Boolean read GetEnsureContainerObjects write + SetEnsureContainerObjects; property HasDefaultContainer: Boolean read GetHasDefaultContainer; property IsChanged: Boolean read GetIsChanged write SetIsChanged; property IsDefault: Boolean read GetIsDefault; @@ -1023,6 +1048,7 @@ procedure AbandonObjects; procedure DisposeObject(AObject: TInstantObject; ConflictAction: TInstantConflictAction); + procedure EnsureObject(const AObjectId: string; AObject: TInstantObject); function Find(const AObjectId: string): TInstantObject; procedure ObjectDestroyed(AObject: TInstantObject); procedure RefreshObject(AObject: TInstantObject); @@ -1098,6 +1124,7 @@ private FCommand: string; FConnector: TInstantConnector; + FEnsureObjects: Boolean; FMaxCount: Integer; function GetConnector: TInstantConnector; function GetObjectCount: Integer; @@ -1140,6 +1167,7 @@ property Active: Boolean read GetActive write SetActive; property Command: string read FCommand write SetCommand; property Connector: TInstantConnector read GetConnector; + property EnsureObjects: Boolean read FEnsureObjects write FEnsureObjects; property MaxCount: Integer read FMaxCount write FMaxCount; property ObjectClass: TClass read GetObjectClass; property ObjectClassName: string read GetObjectClassName; @@ -1293,6 +1321,7 @@ property Items[Index: Integer]: TInstantObject read GetItems write SetItems; default; property RefItems[Index: Integer]: TInstantObjectReference read GetRefItems; + property RefOwnsInstance: Boolean read FRefOwnsInstance; end; TInstantBroker = class(TInstantStreamable) @@ -1316,6 +1345,12 @@ function InternalRetrieveObject(AObject: TInstantObject; const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; virtual; abstract; + procedure InternalRetrieveObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); virtual; abstract; + procedure InternalRetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); virtual; abstract; + procedure InternalRetrieveAllObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); virtual; abstract; function InternalStoreObject(AObject: TInstantObject; ConflictAction: TInstantConflictAction): Boolean; virtual; abstract; public @@ -1349,6 +1384,11 @@ function IsCatalogSupported: Boolean; function RetrieveObject(AObject: TInstantObject; const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; + procedure RetrieveObjects(AObjectsClass: TInstantObjectClass; AObjectIdList: + TStrings); + procedure RetrieveMixedObjects(AObjRefList: TInstantObjectReferenceList); + procedure RetrieveAllObjects(AObjectsClass: TInstantObjectClass; AObjectIdList: + TStrings); procedure SetObjectUpdateCount(AObject: TInstantObject; Value: Integer); function StoreObject(AObject: TInstantObject; ConflictAction: TInstantConflictAction): Boolean; @@ -2352,6 +2392,11 @@ Result := Assigned(Metadata) and Metadata.IsIndexed; end; +function TInstantAttribute.GetEnsureContainerObjects: Boolean; +begin + Result := Assigned(Metadata) and Metadata.EnsureContainerObjects; +end; + function TInstantAttribute.GetIsMandatory: Boolean; begin Result := IsRequired or IsIndexed; @@ -4124,6 +4169,14 @@ ObjectReference.WriteAsObject(Writer); end; +constructor TInstantContainer.Create(AOwner: TInstantAbstractObject = nil; + AMetadata: TInstantCollectionItem = nil); +begin + inherited Create(AOwner, AMetadata); + if EnsureContainerObjects then + EnsureObjects; +end; + { TInstantContainer } function TInstantContainer.Add(AObject: TInstantObject): Integer; @@ -4206,6 +4259,56 @@ Result := Remove(AObject) <> -1; end; +procedure TInstantContainer.EnsureObjects; +begin + InternalEnsureObjects; +end; + +procedure TInstantContainer.InternalEnsureObjects; +var + I: Integer; + Ref: TInstantObjectReference; + ObjRefList: TInstantObjectReferenceList; + J: Integer; +begin + if (Metadata.StorageKind <> skExternal) and + (Metadata.AttributeType = atParts) then + Exit; + + ObjRefList := TInstantObjectReferenceList.Create(False); + try + for I := 0 to Pred(Count) do + begin + if not HasItem(I) then + begin + Ref := ObjRefList.Add; + Ref.ReferenceObject(ObjectReferences[I].ObjectClassName, + ObjectReferences[I].ObjectId); + end; + end; + + if ObjRefList.Count > 0 then + begin + Connector.Broker.RetrieveMixedObjects(ObjRefList); + + for I := 0 to Pred(ObjRefList.Count) do + begin + for J := 0 to Pred(Count) do + begin + if ObjectReferences[J].Equals(ObjRefList[I]) then + begin + if not ObjectReferences[J].HasInstance then + Items[J] := ObjRefList[I]; + Break; + end; + end; + end; + end; + finally + ObjRefList.Free; + end; +end; + procedure TInstantContainer.Exchange(Index1, Index2: Integer); begin CheckRange(Index1); @@ -4245,6 +4348,13 @@ Result := InternalGetItems(Index); end; +function TInstantContainer.GetObjectReferences(Index: Integer): + TInstantObjectReference; +begin + CheckRange(Index); + Result := InternalGetObjectReferences(Index); +end; + function TInstantContainer.HasItem(Index: Integer): Boolean; begin Result := Assigned(Instances[Index]); @@ -4417,6 +4527,12 @@ end; end; +procedure TInstantContainer.SetObjectReferences(Index: Integer; AValue: + TInstantObjectReference); +begin + InternalSetObjectReferences(Index, AValue); +end; + procedure TInstantContainer.Sort(Compare: TInstantSortCompare); begin if Count > 1 then @@ -4504,6 +4620,12 @@ Result := False; end; +procedure TInstantParts.InternalEnsureObjects; +begin + if Metadata.StorageKind = skExternal then + inherited; +end; + function TInstantParts.GetAllowOwned: Boolean; begin Result := FAllowOwned; @@ -4553,12 +4675,6 @@ Result := FObjectReferenceList; end; -function TInstantParts.GetObjectReferences( - Index: Integer): TInstantObjectReference; -begin - Result := TInstantObjectReference(ObjectReferenceList[Index]); -end; - function TInstantParts.InternalAdd(AObject: TInstantObject): Integer; var Ref: TInstantObjectReference; @@ -4664,6 +4780,15 @@ end; end; +function TInstantParts.InternalGetObjectReferences(Index: Integer): + TInstantObjectReference; +begin + if Metadata.StorageKind = skEmbedded then + Result := nil + else + Result := TInstantObjectReference(ObjectReferenceList[Index]); +end; + function TInstantParts.InternalIndexOf(AObject: TInstantObject): Integer; var Ref: TInstantObjectReference; @@ -4744,6 +4869,15 @@ ObjectReferences[Index].Instance := AValue; end; +procedure TInstantParts.InternalSetObjectReferences(Index: Integer; AValue: + TInstantObjectReference); +begin + if (Metadata.StorageKind = skExternal) + and not TInstantObjectReference(ObjectReferenceList[Index]).Equals( + AValue.ObjectClassName, AValue.ObjectId) then + TInstantObjectReference(ObjectReferenceList[Index]).Assign(AValue); +end; + procedure TInstantParts.ReadObject(Reader: TInstantReader); var Obj: TPersistent; @@ -4769,12 +4903,6 @@ FAllowOwned := Value; end; -procedure TInstantParts.SetObjectReferences(Index: Integer; - Value: TInstantObjectReference); -begin - ObjectReferenceList[Index] := Value; -end; - procedure TInstantParts.SetOwnerContext(AObject: TInstantObject); begin if Assigned(AObject) then @@ -4883,7 +5011,7 @@ function TInstantReferences.GetInstances(Index: Integer): TInstantObject; begin - Result := ObjectReferenceList[Index]; + Result := RefItems[Index].Instance; end; function TInstantReferences.GetObjectReferenceList: TInstantObjectReferenceList; @@ -4943,6 +5071,12 @@ Result := ObjectReferenceList[Index]; end; +function TInstantReferences.InternalGetObjectReferences(Index: Integer): + TInstantObjectReference; +begin + Result := RefItems[Index]; +end; + function TInstantReferences.InternalIndexOf( AObject: TInstantObject): Integer; begin @@ -4972,6 +5106,13 @@ ObjectReferenceList[Index] := AValue; end; +procedure TInstantReferences.InternalSetObjectReferences(Index: Integer; + AValue: TInstantObjectReference); +begin + if not RefItems[Index].Equals(AValue.ObjectClassName, AValue.ObjectId) then + RefItems[Index].Assign(AValue); +end; + procedure TInstantReferences.LoadObjectsFromStream(AStream: TStream); var I: Integer; @@ -6226,6 +6367,8 @@ AfterCreateAttributes; DisableChanges; try + if EnsureContainerObjects then + EnsureContainerAttributeObjects; try Initialize; except @@ -6552,6 +6695,30 @@ end; end; end; + +procedure TInstantObject.EnsureContainerAttributeObjects; +var + I: Integer; + AttrMetadata: TInstantAttributeMetadata; + Attr: TInstantContainer; + J: Integer; +begin + CodeSite.EnterMethod(Self, 'TInstantObject.EnsureContainerAttributeObjects'); + for I := 0 to Pred(Metadata.MemberMap.Count) do + begin + AttrMetadata := Metadata.MemberMap[I]; + if (AttrMetadata.AttributeType in [atParts, atReferences]) and + (not AttrMetadata.EnsureContainerObjects) then + begin + Attr := TInstantContainer(AttributeByName(AttrMetadata.Name)); + Attr.EnsureObjects; + for J := 0 to Pred(TInstantContainer(Attr).Count) do + Attr[J].EnsureContainerAttributeObjects; + end; + end; + CodeSite.ExitMethod(Self, 'TInstantObject.EnsureContainerAttributeObjects'); +end; + {$O+} function TInstantObject.GetConnector: TInstantConnector; @@ -6559,6 +6726,11 @@ Result := inherited GetConnector as TInstantConnector; end; +function TInstantObject.GetEnsureContainerObjects: Boolean; +begin + Result := Metadata.EnsureContainerObjects; +end; + procedure TInstantObject.SaveState; begin if State.PersistentId = '' then @@ -6584,6 +6756,16 @@ FObjectStore := nil; end; +procedure TInstantObject.SetEnsureContainerObjects(const Value: Boolean); +begin + if EnsureContainerObjects <> Value then + begin + Metadata.EnsureContainerObjects := Value; + if EnsureContainerObjects then + EnsureContainerAttributeObjects; + end; +end; + procedure TInstantObject.SetId(const Value: string); begin if Value <> FId then @@ -7225,6 +7407,13 @@ end; end; +procedure TInstantObjectStore.EnsureObject(const AObjectId: string; AObject: + TInstantObject); +begin + AObject.SetPersistentId(AObjectId); + AddToCache(AObject); +end; + function TInstantObjectStore.Find(const AObjectId: string): TInstantObject; begin Result := FCache.Find(AObjectId); @@ -8335,6 +8524,24 @@ Result := InternalRetrieveObject(AObject, AObjectId, ConflictAction); end; +procedure TInstantBroker.RetrieveObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); +begin + InternalRetrieveObjects(AObjectsClass, AObjectIdList); +end; + +procedure TInstantBroker.RetrieveMixedObjects(AObjRefList: + TInstantObjectReferenceList); +begin + InternalRetrieveMixedObjects(AObjRefList); +end; + +procedure TInstantBroker.RetrieveAllObjects(AObjectsClass: TInstantObjectClass; + AObjectIdList: TStrings); +begin + InternalRetrieveAllObjects(AObjectsClass, AObjectIdList); +end; + procedure TInstantBroker.SetObjectUpdateCount(AObject: TInstantObject; Value: Integer); begin Modified: branches/EnsureObjectsDev/Source/Core/InstantPresentation.pas =================================================================== --- branches/EnsureObjectsDev/Source/Core/InstantPresentation.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Core/InstantPresentation.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -307,6 +307,7 @@ FSorted: Boolean; FAfterPostField: TInstantFieldEvent; FBeforePostField: TInstantFieldEvent; + FEnsureObjects: Boolean; FOnCompare: TInstantCompareObjectsEvent; FOnCreateObject: TInstantCreateObjectEvent; FOnFieldError: TInstantFieldErrorEvent; @@ -474,6 +475,8 @@ property ContentBuffer: TInstantContentBuffer read GetContentBuffer; property CurrentBuffer: PChar read GetCurrentBuffer; property DesignClass: TInstantCodeClass read GetDesignClass; + property EnsureObjects: Boolean read FEnsureObjects write FEnsureObjects + default False; property HasCurrentBuffer: Boolean read GetHasCurrentBuffer; property InContent: Boolean read GetInContent; property Mode: TInstantAccessMode read GetMode write SetMode default amObject; @@ -698,6 +701,7 @@ property AfterOpen; property BeforeClose; property BeforeOpen; + property EnsureObjects default False; end; TInstantBlobStream = class(TStream) @@ -4671,6 +4675,7 @@ DestroyQuery; end; Query.Params := Params; + Query.EnsureObjects := EnsureObjects; Query.Open; inherited; end; Modified: branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.dfm =================================================================== --- branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.dfm 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.dfm 2006-11-27 08:09:29 UTC (rev 720) @@ -303,6 +303,22 @@ TabOrder = 1 end end + object OtherOptionsGroupBox: TGroupBox + Left = 8 + Top = 183 + Width = 209 + Height = 63 + Caption = 'Other Options' + TabOrder = 4 + object OtherOptionEnsureContainerObjectsCheckBox: TCheckBox + Left = 8 + Top = 15 + Width = 190 + Height = 17 + Caption = 'E&nsure Container Objects' + TabOrder = 0 + end + end end object PresentationSheet: TTabSheet Caption = 'Presentation' Modified: branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.pas =================================================================== --- branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.pas 2006-11-27 02:47:53 UTC (rev 719) +++ branches/EnsureObjectsDev/Source/Design/InstantAttributeEditor.pas 2006-11-27 08:09:29 UTC (rev 720) @@ -101,6 +101,8 @@ StorageKindEdit: TDBComboBox; StorageKindLabel: TLabel; AutoExternalStorageNameCheckBox: TCheckBox; + OtherOptionsGroupBox: TGroupBox; + OtherOptionEnsureContainerObjectsCheckBox: TCheckBox; procedure NameEditKeyPress(Sender: TObject; var Key: Char); procedure FormCreate(Sender: TObject); procedure NameEditChange(Sender: TObject); @@ -224,6 +226,8 @@ OptionRequired... [truncated message content] |
From: <sr...@us...> - 2006-11-27 02:47:57
|
Revision: 719 http://svn.sourceforge.net/instantobjects/revision/?rev=719&view=rev Author: srmitch Date: 2006-11-26 18:47:53 -0800 (Sun, 26 Nov 2006) Log Message: ----------- made a copy Added Paths: ----------- branches/EnsureObjectsDev/ Copied: branches/EnsureObjectsDev (from rev 718, trunk) |