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: <jcm...@us...> - 2006-07-30 15:08:52
|
Revision: 692 Author: jcmoraisjr Date: 2006-07-30 08:08:43 -0700 (Sun, 30 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=692&view=rev Log Message: ----------- - Fixed [1473942] Boolean attributes cause error Modified Paths: -------------- branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBO.pas branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas Modified: branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBO.pas =================================================================== --- branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBO.pas 2006-07-30 14:25:35 UTC (rev 691) +++ branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBO.pas 2006-07-30 15:08:43 UTC (rev 692) @@ -1122,7 +1122,7 @@ function TInstantZeosDBOMySQLBroker.UseBooleanFields: Boolean; begin - Result := True; + Result := False; end; {$ENDIF} Modified: branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas =================================================================== --- branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas 2006-07-30 14:25:35 UTC (rev 691) +++ branches/2.0/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas 2006-07-30 15:08:43 UTC (rev 692) @@ -24,6 +24,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Joao Morais * * ***** END LICENSE BLOCK ***** *) @@ -219,13 +220,12 @@ stString, stUnicodeString: DataType := dtString; stBoolean: DataType := dtBoolean; - stShort: + stShort, stByte: begin DataType := dtBoolean; Include(AlternateDataTypes, dtInteger); end; - stByte, - stInteger, + stInteger, stLong: DataType := dtInteger; stFloat, stDouble: |
From: <jcm...@us...> - 2006-07-30 14:25:44
|
Revision: 691 Author: jcmoraisjr Date: 2006-07-30 07:25:35 -0700 (Sun, 30 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=691&view=rev Log Message: ----------- - Fixed [1473942] Boolean attributes cause error Modified Paths: -------------- trunk/Source/Brokers/ZeosDBO/InstantZeosDBO.pas trunk/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas Modified: trunk/Source/Brokers/ZeosDBO/InstantZeosDBO.pas =================================================================== --- trunk/Source/Brokers/ZeosDBO/InstantZeosDBO.pas 2006-07-22 22:43:16 UTC (rev 690) +++ trunk/Source/Brokers/ZeosDBO/InstantZeosDBO.pas 2006-07-30 14:25:35 UTC (rev 691) @@ -1122,7 +1122,7 @@ function TInstantZeosDBOMySQLBroker.UseBooleanFields: Boolean; begin - Result := True; + Result := False; end; {$ENDIF} Modified: trunk/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas =================================================================== --- trunk/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas 2006-07-22 22:43:16 UTC (rev 690) +++ trunk/Source/Brokers/ZeosDBO/InstantZeosDBOCatalog.pas 2006-07-30 14:25:35 UTC (rev 691) @@ -24,6 +24,7 @@ * the Initial Developer. All Rights Reserved. * * Contributor(s): + * Joao Morais * * ***** END LICENSE BLOCK ***** *) @@ -219,13 +220,12 @@ stString, stUnicodeString: DataType := dtString; stBoolean: DataType := dtBoolean; - stShort: + stShort, stByte: begin DataType := dtBoolean; Include(AlternateDataTypes, dtInteger); end; - stByte, - stInteger, + stInteger, stLong: DataType := dtInteger; stFloat, stDouble: |
From: <sr...@us...> - 2006-07-22 22:43:25
|
Revision: 690 Author: srmitch Date: 2006-07-22 15:43:16 -0700 (Sat, 22 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=690&view=rev Log Message: ----------- - Added implementation of class methods that were left out of 687 update in InstantPersistence.pas. Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-07-22 22:06:11 UTC (rev 689) +++ trunk/Source/Core/InstantPersistence.pas 2006-07-22 22:43:16 UTC (rev 690) @@ -15951,6 +15951,463 @@ end; end; +constructor TInstantNavigationalLinkResolver.Create(AResolver: + TInstantNavigationalResolver; const ATableName: string); +begin + inherited Create(AResolver); + FTableName := ATableName; +end; + +destructor TInstantNavigationalLinkResolver.Destroy; +begin + FreeDataSet; + inherited; +end; + +procedure TInstantNavigationalLinkResolver.Append; +begin + DataSet.Append; +end; + +procedure TInstantNavigationalLinkResolver.Cancel; +begin + DataSet.Cancel; +end; + +procedure TInstantNavigationalLinkResolver.Close; +begin + DataSet.Close; +end; + +procedure TInstantNavigationalLinkResolver.Delete; +begin + DataSet.Delete; +end; + +procedure TInstantNavigationalLinkResolver.Edit; +begin + DataSet.Edit; +end; + +function TInstantNavigationalLinkResolver.Eof: Boolean; +begin + Result := DataSet.Eof; +end; + +function TInstantNavigationalLinkResolver.FieldByName(const FieldName: string): + TField; +begin + Result := DataSet.FieldByName(FieldName); +end; + +procedure TInstantNavigationalLinkResolver.First; +begin + Dataset.First; +end; + +procedure TInstantNavigationalLinkResolver.FreeDataSet; +begin + if FFreeDataSet then + FreeAndNil(FDataSet); +end; + +function TInstantNavigationalLinkResolver.GetBroker: TInstantNavigationalBroker; +begin + Result := Resolver.Broker; +end; + +function TInstantNavigationalLinkResolver.GetDataSet: TDataSet; +begin + if not Assigned(FDataSet) then + begin + Broker.Connector.DoGetDataSet(TableName, FDataSet); + if not Assigned(FDataSet) then + begin + FDataSet := CreateDataSet; + FFreeDataSet := True; + end; + Broker.Connector.DoInitDataSet(TableName, FDataSet); + end; + Result := FDataSet; +end; + +function TInstantNavigationalLinkResolver.GetResolver: + TInstantNavigationalResolver; +begin + Result := inherited Resolver as TInstantNavigationalResolver; +end; + +procedure TInstantNavigationalLinkResolver.InternalStoreAttributeObjects( + Attribute: TInstantContainer); +var + I: Integer; + Obj: TInstantObject; + WasOpen: Boolean; +begin + WasOpen := Dataset.Active; + + if not WasOpen then + Open; + try + for I := 0 to Pred(Attribute.Count) do + begin + Obj := Attribute.Items[I]; + if Obj.InUpdate then // prevent recursion + Continue; + Obj.CheckId; + Append; + try + FieldByName(InstantIdFieldName).AsString := Obj.GenerateId; + FieldByName(InstantParentClassFieldName).AsString := + Attribute.Owner.ClassName; + FieldByName(InstantParentIdFieldName).AsString := Attribute.Owner.Id; + FieldByName(InstantChildClassFieldName).AsString := Obj.ClassName; + FieldByName(InstantChildIdFieldName).AsString := Obj.Id; + FieldByName(InstantSequenceNoFieldName).AsInteger := Succ(I); + Post; + except + Cancel; + end; + Obj.ObjectStore.StoreObject(Obj, caIgnore); + end; + finally + if not WasOpen then + Close; + end; +end; + +procedure TInstantNavigationalLinkResolver.InternalClearAttributeLinkRecords; +var + WasOpen: Boolean; +begin + WasOpen := Dataset.Active; + + if not WasOpen then + Open; + try + SetDatasetParentRange(Resolver.ObjectClassname, Resolver.ObjectId); + First; + while not Eof do + Delete; + finally + if not WasOpen then + Close; + end; +end; + +procedure TInstantNavigationalLinkResolver.InternalDisposeDeletedAttributeObjects( + Attribute: TInstantContainer); +var +// I: Integer; + Obj: TInstantObject; + AttributeMetadata: TInstantAttributeMetadata; + ObjDisposed: Boolean; + WasOpen: Boolean; +begin + WasOpen := Dataset.Active; + + if not WasOpen then + Open; + try + SetDatasetParentRange(Attribute.Owner.ClassName, Attribute.Owner.Id); + First; + AttributeMetadata := Attribute.Metadata; + while not Eof do + begin + ObjDisposed := False; + Obj := AttributeMetadata.ObjectClass.Retrieve( + FieldByName(InstantChildIdFieldName).AsString, + False, False, Attribute.Connector); + try + if Assigned(Obj) and + (Attribute.IndexOf(Obj) = -1) then + begin + Obj.ObjectStore.DisposeObject(Obj, caIgnore); + Delete; + ObjDisposed := True; + end; + finally + Obj.Free; + end; + if not ObjDisposed then + Next; + end; + finally + if not WasOpen then + Close; + end; +end; + +procedure TInstantNavigationalLinkResolver.InternalReadAttributeObjects( + Attribute: TInstantContainer; const AObjectId: string); +var + WasOpen: Boolean; +begin + WasOpen := Dataset.Active; + + if not WasOpen then + Open; + try + // Attribute.Owner.Id can be '', so do not use here. + SetDatasetParentRange(Attribute.Owner.Classname, AObjectId); + First; + while not Eof do + begin + Attribute.AddReference( + FieldByName(InstantChildClassFieldName).AsString, + FieldByName(InstantChildIdFieldName).AsString); + Next; + end; + finally + if not WasOpen then + Close; + end; +end; + +procedure TInstantNavigationalLinkResolver.Next; +begin + DataSet.Next; +end; + +procedure TInstantNavigationalLinkResolver.Open; +begin + DataSet.Open; +end; + +procedure TInstantNavigationalLinkResolver.Post; +begin + DataSet.Post; +end; + +procedure TInstantNavigationalLinkResolver.SetDataSet(Value: TDataset); +begin + if Value <> FDataSet then + begin + FreeDataSet; + FDataSet := Value; + end; +end; + +constructor TInstantLinkResolver.Create(AResolver: TInstantCustomResolver); +begin + inherited Create; + FResolver := AResolver; +end; + +procedure TInstantLinkResolver.StoreAttributeObjects(Attribute: + TInstantContainer); +begin + InternalStoreAttributeObjects(Attribute); +end; + +procedure TInstantLinkResolver.ClearAttributeLinkRecords; +begin + InternalClearAttributeLinkRecords; +end; + +procedure TInstantLinkResolver.DisposeDeletedAttributeObjects(Attribute: + TInstantContainer); +begin + InternalDisposeDeletedAttributeObjects(Attribute); +end; + +function TInstantLinkResolver.GetBroker: TInstantCustomRelationalBroker; +begin + Result := Resolver.Broker; +end; + +function TInstantLinkResolver.GetResolver: TInstantCustomResolver; +begin + Result := FResolver; +end; + +procedure TInstantLinkResolver.InternalStoreAttributeObjects(Attribute: + TInstantContainer); +begin +end; + +procedure TInstantLinkResolver.InternalClearAttributeLinkRecords; +begin +end; + +procedure TInstantLinkResolver.InternalDisposeDeletedAttributeObjects( + Attribute: TInstantContainer); +begin +end; + +procedure TInstantLinkResolver.InternalReadAttributeObjects(Attribute: + TInstantContainer; const AObjectId: string); +begin +end; + +procedure TInstantLinkResolver.ReadAttributeObjects(Attribute: + TInstantContainer; const AObjectId: string); +begin + InternalReadAttributeObjects(Attribute, AObjectId); +end; + +constructor TInstantSQLLinkResolver.Create(AResolver: TInstantSQLResolver; + const ATableName: string; AObject: TInstantObject); +begin + inherited Create(AResolver); + FTableName := ATableName; + FAttributeOwner := AObject; +end; + +function TInstantSQLLinkResolver.GetBroker: TInstantSQLBroker; +begin + Result := Resolver.Broker; +end; + +function TInstantSQLLinkResolver.GetResolver: TInstantSQLResolver; +begin + Result := FResolver as TInstantSQLResolver; +end; + +procedure TInstantSQLLinkResolver.InternalStoreAttributeObjects(Attribute: + TInstantContainer); +var + Params: TParams; + Statement: string; + Obj: TInstantObject; + I: Integer; +begin + // Store all objects and links + for I := 0 to Pred(Attribute.Count) do + begin + // Store object + Obj := Attribute.Items[I]; + Obj.CheckId; + Obj.ObjectStore.StoreObject(Obj, caIgnore); + + // Insert link + Params := TParams.Create; + try + Statement := Format(Resolver.InsertExternalSQL, + [TableName]); + Resolver.AddIdParam(Params, InstantIdFieldName, AttributeOwner.GenerateId); + Resolver.AddStringParam(Params, InstantParentClassFieldName, + AttributeOwner.ClassName); + Resolver.AddIdParam(Params, InstantParentIdFieldName, + AttributeOwner.Id); + Resolver.AddStringParam(Params, InstantChildClassFieldName, + Obj.ClassName); + Resolver.AddIdParam(Params, InstantChildIdFieldName, + Obj.Id); + Resolver.AddIntegerParam(Params, InstantSequenceNoFieldName, Succ(I)); + Broker.Execute(Statement, Params); + finally + Params.Free; + end; + end; +end; + +procedure TInstantSQLLinkResolver.InternalClearAttributeLinkRecords; +var + Params: TParams; + Statement: string; +begin + Params := TParams.Create; + try + Statement := Format(Resolver.DeleteExternalSQL, + [TableName, + InstantParentClassFieldName, + InstantParentIdFieldName]); + Resolver.AddStringParam(Params, InstantParentClassFieldName, + AttributeOwner.ClassName); + Resolver.AddIdParam(Params, InstantParentIdFieldName, + AttributeOwner.Id); + Broker.Execute(Statement, Params); + finally + Params.Free; + end; +end; + +procedure TInstantSQLLinkResolver.InternalDisposeDeletedAttributeObjects( + Attribute: TInstantContainer); +var + Statement: string; + Params: TParams; + Dataset: TDataset; + Obj: TInstantObject; +begin + // Delete all objects + Params := TParams.Create; + try + Statement := Format(Resolver.SelectExternalSQL, [TableName]); + Resolver.AddIdParam(Params, InstantParentIdFieldName, AttributeOwner.Id); + Resolver.AddStringParam(Params, InstantParentClassFieldName, + AttributeOwner.ClassName); + Resolver.AddStringParam(Params, InstantChildClassFieldName, + Attribute.Metadata.ObjectClassName); + DataSet := Broker.AcquireDataSet(Statement, Params); + try + DataSet.Open; + try + while not DataSet.Eof do + begin + Obj := Attribute.Metadata.ObjectClass.Retrieve( + DataSet.FieldByName(InstantChildIdFieldName).AsString, + False, False, Attribute.Connector); + try + if Assigned(Obj) and + (Attribute.IndexOf(Obj) = -1) then + Obj.ObjectStore.DisposeObject(Obj, + caIgnore); + finally + Obj.Free; + end; + DataSet.Next; + end; + finally + DataSet.Close; + end; + finally + Broker.ReleaseDataSet(DataSet); + end; + finally + Params.Free; + end; +end; + +procedure TInstantSQLLinkResolver.InternalReadAttributeObjects(Attribute: + TInstantContainer; const AObjectId: string); +var + Statement: string; + Params: TParams; + Dataset: TDataset; +begin + Params := TParams.Create; + try + Statement := Format(Resolver.SelectExternalSQL, [TableName]); + Resolver.AddIdParam(Params, InstantParentIdFieldName, AObjectId); + Resolver.AddStringParam(Params, InstantParentClassFieldName, + AttributeOwner.ClassName); + Resolver.AddStringParam(Params, InstantChildClassFieldName, + Attribute.Metadata.ObjectClassName); + DataSet := Broker.AcquireDataSet(Statement, Params); + try + DataSet.Open; + try + while not DataSet.Eof do + begin + Attribute.AddReference( + DataSet.FieldByName(InstantChildClassFieldName).AsString, + DataSet.FieldByName(InstantChildIdFieldName).AsString); + DataSet.Next; + end; + finally + DataSet.Close; + end; + finally + Broker.ReleaseDataSet(DataSet); + end; + finally + Params.Free; + end; +end; + + initialization RegisterClasses([TInstantClassMetadatas, TInstantClassMetadata, TInstantAttributeMetadatas, TInstantAttributeMetadata, |
From: <sr...@us...> - 2006-07-22 22:06:21
|
Revision: 689 Author: srmitch Date: 2006-07-22 15:06:11 -0700 (Sat, 22 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=689&view=rev Log Message: ----------- - Remove TInstantNavigationalResolver.ClearEnum implementation from InstantPersistence.pas that was incorrectly added in previous update (687). Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-07-22 05:32:46 UTC (rev 688) +++ trunk/Source/Core/InstantPersistence.pas 2006-07-22 22:06:11 UTC (rev 689) @@ -12312,10 +12312,6 @@ inherited; end; -procedure TInstantNavigationalResolver.ClearEnum(Attribute: TInstantEnum); -begin -end; - procedure TInstantNavigationalResolver.Edit; begin DataSet.Edit; |
From: <sr...@us...> - 2006-07-22 05:32:55
|
Revision: 688 Author: srmitch Date: 2006-07-21 22:32:46 -0700 (Fri, 21 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=688&view=rev Log Message: ----------- - Update to throw a more useful EInstantAccessError rather than an AV when trying to access the members of an object that has been disposed before being fetched by an InstantQuery. Related to [bug# 1516101 ] "Problem disposing an TInstantObject with multiple queries". Modified Paths: -------------- trunk/Source/Core/InstantConsts.pas trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantConsts.pas =================================================================== --- trunk/Source/Core/InstantConsts.pas 2006-07-20 00:56:59 UTC (rev 687) +++ trunk/Source/Core/InstantConsts.pas 2006-07-22 05:32:46 UTC (rev 688) @@ -148,6 +148,7 @@ SObjectClassUndefined = 'ObjectClass undefined'; SObjectError = 'Error for object of class %s: "%s"'; SObjectIsOwned = 'Object %s(''%s'') is owned.'; + SObjectNotAvailable = 'Object is not available!'; SOwnershipRecursion = 'Ownership Recursion for object %s(''%s'')'; SPersistentObjectNotAllowed = 'Persistent object %s(''%s'') not allowed.'; SProtocolNotSupported = 'Protocol ''%s'' not supported'; Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-07-20 00:56:59 UTC (rev 687) +++ trunk/Source/Core/InstantPersistence.pas 2006-07-22 05:32:46 UTC (rev 688) @@ -10658,6 +10658,10 @@ function TInstantQuery.GetObjects(Index: Integer): TObject; begin Result := InternalGetObjects(Index); + if not Assigned(Result) then + raise EInstantAccessError.CreateFmt(SErrorRetrievingObject, + [ObjectClassName, 'Query.Object[' + IntToStr(Index) + ']', + SObjectNotAvailable]); end; function TInstantQuery.GetParams: TParams; |
From: <sr...@us...> - 2006-07-20 00:57:18
|
Revision: 687 Author: srmitch Date: 2006-07-19 17:56:59 -0700 (Wed, 19 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=687&view=rev Log Message: ----------- - Changes to enable the navigational brokers to use external storage of attributes. Refactored the code for handling the external linking tables into TInstantLinkResolver and descendant classes to allow for this. - Updated BDE broker to use new external storage of attributes feature. Still need to add index for parent class and id fields in the linking table for this to work. - Updated unit tests to include new InstantContainer AddReference method (see TestInstantParts.pas and TestInstantReferences.pas). Modified Paths: -------------- trunk/Source/Brokers/BDE/InstantBDE.pas trunk/Source/Core/InstantConsts.pas trunk/Source/Core/InstantPersistence.pas trunk/Source/Tests/TestInstantParts.pas trunk/Source/Tests/TestInstantReferences.pas trunk/Source/Tests/TestModel.pas Modified: trunk/Source/Brokers/BDE/InstantBDE.pas =================================================================== --- trunk/Source/Brokers/BDE/InstantBDE.pas 2006-07-18 07:46:13 UTC (rev 686) +++ trunk/Source/Brokers/BDE/InstantBDE.pas 2006-07-20 00:56:59 UTC (rev 687) @@ -112,11 +112,13 @@ function GetDataSet: TTable; protected function CreateDataSet: TDataSet; override; - function FormatTableName(const ATableName: string): string; virtual; + function CreateNavigationalLinkResolver(const ATableName: string): + TInstantNavigationalLinkResolver; override; function Locate(const AClassName, AObjectId: string): Boolean; override; function TranslateError(AObject: TInstantObject; E: Exception): Exception; override; public + function FormatTableName(const ATableName: string): string; virtual; property Broker: TInstantBDEBroker read GetBroker; property DataSet: TTable read GetDataSet; end; @@ -213,6 +215,24 @@ property IndexMetadata: TInstantIndexMetadata read GetIndexMetadata; end; +type + TInstantBDELinkResolver = class(TInstantNavigationalLinkResolver) + private + function GetBroker: TInstantBDEBroker; + function GetDataSet: TTable; + function GetResolver: TInstantBDEResolver; + protected + function CreateDataSet: TDataSet; override; + procedure SetDatasetParentRange(const AParentClass, AParentId: string); + override; + public + constructor Create(AResolver: TInstantNavigationalResolver; const ATableName: + string); + property Broker: TInstantBDEBroker read GetBroker; + property DataSet: TTable read GetDataSet; + property Resolver: TInstantBDEResolver read GetResolver; + end; + procedure Register; implementation @@ -504,13 +524,18 @@ end; end; -function TInstantBDEResolver.FormatTableName( - const ATableName: string): string; +function TInstantBDEResolver.CreateNavigationalLinkResolver(const ATableName: + string): TInstantNavigationalLinkResolver; begin + Result := TInstantBDELinkResolver.Create(Self, ATableName); +end; + +function TInstantBDEResolver.FormatTableName(const ATableName: string): string; +begin if Broker.Connector.DriverType = dtOracle then Result := UpperCase(ATableName) else - Result := TableName; + Result := ATableName; end; function TInstantBDEResolver.GetBroker: TInstantBDEBroker; @@ -523,14 +548,14 @@ Result := inherited DataSet as TTable; end; -function TInstantBDEResolver.Locate(const AClassName, - AObjectId: string): Boolean; +function TInstantBDEResolver.Locate(const AClassName, AObjectId: string): + Boolean; begin Result := DataSet.FindKey([AClassName, AObjectId]); end; function TInstantBDEResolver.TranslateError( - AObject: TInstantObject; E: Exception): Exception; + AObject: TInstantObject; E: Exception): Exception; var Error: TDBError; begin @@ -863,7 +888,51 @@ end; end; +constructor TInstantBDELinkResolver.Create(AResolver: + TInstantNavigationalResolver; const ATableName: string); +begin + inherited Create(AResolver, ATableName); +end; +function TInstantBDELinkResolver.CreateDataSet: TDataSet; +begin + Result:= TTable.Create(nil); + with TTable(Result) do + try + DatabaseName := Broker.Connector.Connection.DatabaseName; + TableName := Resolver.FormatTableName(Self.TableName); + IndexFieldNames := InstantParentClassFieldName + ';' + + InstantParentIdFieldName; + CacheBlobs := False; + UpdateMode := upWhereKeyOnly; + except + Result.Free; + raise; + end; +end; + +function TInstantBDELinkResolver.GetBroker: TInstantBDEBroker; +begin + Result := inherited Broker as TInstantBDEBroker; +end; + +function TInstantBDELinkResolver.GetDataSet: TTable; +begin + Result := inherited DataSet as TTable; +end; + +function TInstantBDELinkResolver.GetResolver: TInstantBDEResolver; +begin + Result := inherited Resolver as TInstantBDEResolver; +end; + +procedure TInstantBDELinkResolver.SetDatasetParentRange(const + AParentClass, AParentId: string); +begin + Dataset.SetRange([AParentClass, AParentId], [AParentClass, AParentId]); +end; + + initialization RegisterClass(TInstantBDEConnectionDef); TInstantBDEConnector.RegisterClass; Modified: trunk/Source/Core/InstantConsts.pas =================================================================== --- trunk/Source/Core/InstantConsts.pas 2006-07-18 07:46:13 UTC (rev 686) +++ trunk/Source/Core/InstantConsts.pas 2006-07-20 00:56:59 UTC (rev 687) @@ -182,6 +182,7 @@ SUnknownAttributeClass = 'Unknown attribute class for attribute %s(''%s'')'; SUnspecifiedCommand = 'Command is not specified'; SUnsupportedColumnSkipped = 'Skipped column %s.%s. Unsupported type %s.'; + SUnsupportedAttributeOperation = 'Unsupported operation (%s) for attribute %s(''%s''). Reason: %s.'; SUnsupportedDataType = 'Unsupported datatype: %s'; SUnsupportedGraphicClass = 'Unsupported graphic class'; SUnsupportedGraphicStream = 'Unsupported graphic stream format'; Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-07-18 07:46:13 UTC (rev 686) +++ trunk/Source/Core/InstantPersistence.pas 2006-07-20 00:56:59 UTC (rev 687) @@ -999,7 +999,7 @@ end; TInstantSortCompare = function(Holder, Obj1, Obj2: TInstantObject): Integer of object; - TInstantContentChangeType = (ctAdd, ctRemove, ctReplace, ctClear); + TInstantContentChangeType = (ctAdd, ctAddRef, ctRemove, ctReplace, ctClear); TInstantContainer = class(TInstantComplex) private @@ -1017,6 +1017,8 @@ function GetInstances(Index: Integer): TInstantObject; virtual; function GetIsDefault: Boolean; override; 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; function InternalGetItems(Index: Integer): TInstantObject; virtual; abstract; @@ -1030,6 +1032,7 @@ property Instances[Index: Integer]: TInstantObject read GetInstances; public function Add(AObject: TInstantObject): Integer; + function AddReference(const AObjectClassName, AObjectId: string): Integer; function AttachObject(AObject: TInstantObject): Boolean; override; procedure Clear; procedure Delete(Index: Integer); @@ -1072,6 +1075,8 @@ function GetIsChanged: Boolean; override; function GetInstances(Index: Integer): TInstantObject; override; function InternalAdd(AObject: TInstantObject): Integer; override; + function InternalAddReference(const AObjectClassName, AObjectId: string): + Integer; override; procedure InternalClear; override; procedure InternalDelete(Index: Integer); override; function InternalGetItems(Index: Integer): TInstantObject; override; @@ -1108,6 +1113,8 @@ function GetCount: Integer; override; function GetInstances(Index: Integer): TInstantObject; override; function InternalAdd(AObject: TInstantObject): Integer; override; + function InternalAddReference(const AObjectClassName, AObjectId: string): + Integer; override; procedure InternalClear; override; procedure InternalDelete(Index: Integer); override; function InternalGetItems(Index: Integer): TInstantObject; override; @@ -1362,6 +1369,7 @@ property ObjectClass: TInstantObjectClass read GetObjectClass; property ObjectCount: Integer read GetObjectCount; property Id: string read GetId write SetId; + property InUpdate: Boolean read FInUpdate write FInUpdate; property Objects[Index: Integer]: TInstantObject read GetObjects write SetObjects; property Owner: TInstantObject read FOwner; property OwnerAttribute: TInstantComplex read FOwnerAttribute; @@ -1980,6 +1988,9 @@ end; TInstantCustomResolver = class; + TInstantLinkResolver = class; + TInstantNavigationalLinkResolver = class; + TInstantSQLLinkResolver = class; TInstantBrokerOperation = procedure(AObject: TInstantObject; const AObjectId: string; Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction = caFail; Info: PInstantOperationInfo = nil) of object; @@ -2150,6 +2161,7 @@ private FDataSet: TDataSet; FFreeDataSet: Boolean; + FNavigationalLinkResolvers: TObjectList; FTableName: string; function CheckConflict(AObject: TInstantObject; const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; @@ -2159,6 +2171,9 @@ procedure FreeDataSet; function GetBroker: TInstantNavigationalBroker; function GetDataSet: TDataSet; + function GetNavigationalLinkResolvers: TObjectList; + function GetObjectClassName: string; + function GetObjectId: string; procedure PerformOperation(AObject: TInstantObject; Map: TInstantAttributeMap; Operation: TInstantNavigationalResolverOperation); procedure ReadAttribute(AObject: TInstantObject; @@ -2185,17 +2200,24 @@ procedure ClearString(Attribute: TInstantString); virtual; procedure Close; virtual; function CreateDataSet: TDataSet; virtual; abstract; + function CreateNavigationalLinkResolver(const ATableName: string): + TInstantNavigationalLinkResolver; virtual; abstract; function CreateLocateVarArray(const AObjectClassName, AObjectId: string): Variant; procedure Delete; virtual; procedure Edit; virtual; + function GetLinkDatasetResolver(const ATableName: string): + TInstantNavigationalLinkResolver; function FieldHasObjects(Field: TField): Boolean; virtual; + function FindLinkDatasetResolver(const ATableName: string): + TInstantNavigationalLinkResolver; procedure InternalDisposeMap(AObject: TInstantObject; Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); override; procedure InternalRetrieveMap(AObject: TInstantObject; const AObjectId: string; Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); override; procedure InternalStoreMap(AObject: TInstantObject; Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); override; - function Locate(const AObjectClassName, AObjectId: string): Boolean; virtual; abstract; + function Locate(const AObjectClassName, AObjectId: string): Boolean; virtual; + abstract; procedure Open; virtual; procedure Post; virtual; procedure ReadBlob(Attribute: TInstantBlob); virtual; @@ -2226,11 +2248,15 @@ procedure WriteReferences(Attribute: TInstantReferences); virtual; procedure WriteString(Attribute: TInstantString); virtual; property DataSet: TDataset read GetDataSet write SetDataSet; + property NavigationalLinkResolvers: TObjectList read + GetNavigationalLinkResolvers; public constructor Create(ABroker: TInstantNavigationalBroker; const ATableName: string); destructor Destroy; override; property Broker: TInstantNavigationalBroker read GetBroker; + property ObjectClassName: string read GetObjectClassName; + property ObjectId: string read GetObjectId; property TableName: string read FTableName; end; @@ -2636,6 +2662,7 @@ procedure Exchange(Index1, Index2: Integer); function IndexOf(Item: TInstantObject; NeedInstance: Boolean = False): Integer; function IndexOfInstance(Item: TInstantObject): Integer; + function IndexOfReference(AObjectReference: TInstantObjectReference): Integer; procedure Insert(Index: Integer; Item: TInstantObject); procedure Move(CurIndex, NewIndex: Integer); function Remove(Item: TInstantObject): Integer; @@ -2646,6 +2673,103 @@ property RefItems[Index: Integer]: TInstantObjectReference read GetRefItems; end; + // TInstantLinkResolver class defines common interface for handling + // access to container attributes with external storage + TInstantLinkResolver = class(TInstantStreamable) + private + FResolver: TInstantCustomResolver; + function GetBroker: TInstantCustomRelationalBroker; + function GetResolver: TInstantCustomResolver; + protected + procedure InternalStoreAttributeObjects(Attribute: TInstantContainer); virtual; + procedure InternalClearAttributeLinkRecords; virtual; + procedure InternalDisposeDeletedAttributeObjects(Attribute: TInstantContainer); + virtual; + procedure InternalReadAttributeObjects(Attribute: TInstantContainer; const + AObjectId: string); virtual; + public + constructor Create(AResolver: TInstantCustomResolver); + procedure StoreAttributeObjects(Attribute: TInstantContainer); + procedure ClearAttributeLinkRecords; + procedure DisposeDeletedAttributeObjects(Attribute: TInstantContainer); + procedure ReadAttributeObjects(Attribute: TInstantContainer; const AObjectId: + string); + property Broker: TInstantCustomRelationalBroker read GetBroker; + property Resolver: TInstantCustomResolver read GetResolver; + end; + + // TInstantNavigationalLinkResolver is an abstract class that + // defines the interface for handling access to container attributes + // with external storage for navigational brokers. + // Each navigational broker needs to provide a concrete class descendent. + // See the BDE broker as an example. + TInstantNavigationalLinkResolver = class(TInstantLinkResolver) + private + FDataSet: TDataSet; + FFreeDataSet: Boolean; + FTableName: string; + function FieldByName(const FieldName: string): TField; + procedure FreeDataSet; + function GetBroker: TInstantNavigationalBroker; + function GetDataSet: TDataSet; + function GetResolver: TInstantNavigationalResolver; + procedure SetDataSet(Value: TDataset); + protected + procedure Append; virtual; + procedure Cancel; virtual; + procedure Close; virtual; + function CreateDataSet: TDataSet; virtual; abstract; + procedure Delete; virtual; + procedure Edit; virtual; + function Eof: Boolean; virtual; + procedure First; virtual; + procedure InternalStoreAttributeObjects(Attribute: TInstantContainer); override; + procedure InternalClearAttributeLinkRecords; override; + procedure InternalDisposeDeletedAttributeObjects(Attribute: TInstantContainer); + override; + procedure InternalReadAttributeObjects(Attribute: TInstantContainer; const + AObjectId: string); override; + procedure Next; virtual; + procedure Open; virtual; + procedure Post; virtual; + procedure SetDatasetParentRange(const AParentClass, AParentId: string); + virtual; abstract; + property DataSet: TDataset read GetDataSet write SetDataSet; + public + constructor Create(AResolver: TInstantNavigationalResolver; const ATableName: + string); + destructor Destroy; override; + property Broker: TInstantNavigationalBroker read GetBroker; + property Resolver: TInstantNavigationalResolver read GetResolver; + property TableName: string read FTableName; + end; + + // TInstantSQLLinkResolver class defines interface for handling + // access to container attributes with external storage for + // SQL brokers. Due to the generic nature of SQL this class is used + // directly and no descendant classes are needed for SQL brokers. + TInstantSQLLinkResolver = class(TInstantLinkResolver) + private + FAttributeOwner: TInstantObject; + FTableName: string; + function GetBroker: TInstantSQLBroker; + function GetResolver: TInstantSQLResolver; + property TableName: string read FTableName; + protected + procedure InternalStoreAttributeObjects(Attribute: TInstantContainer); override; + procedure InternalClearAttributeLinkRecords; override; + procedure InternalDisposeDeletedAttributeObjects(Attribute: TInstantContainer); + override; + procedure InternalReadAttributeObjects(Attribute: TInstantContainer; const + AObjectId: string); override; + public + constructor Create(AResolver: TInstantSQLResolver; const ATableName: string; + AObject: TInstantObject); + property AttributeOwner: TInstantObject read FAttributeOwner; + property Broker: TInstantSQLBroker read GetBroker; + property Resolver: TInstantSQLResolver read GetResolver; + end; + procedure AssignInstantStreamFormat(Strings: TStrings); function InstantAttributeTypeToDataType(AttributeType: TInstantAttributeType; BlobStreamFormat: TInstantStreamFormat = sfBinary): TInstantDataType; @@ -6560,6 +6684,21 @@ AfterContentChange(ctAdd, Result, AObject); end; +function TInstantContainer.AddReference(const AObjectClassName, AObjectId: + string): Integer; +begin + if Assigned(Metadata) and (Metadata.StorageKind = skEmbedded) then + raise EInstantError.CreateFmt(SUnsupportedAttributeOperation, + ['AddReference', ClassName, Name, 'StorageKind = skEmbedded']); + if RequiredClassName <> AObjectClassName then + raise EInstantValidationError.CreateFmt(SInvalidObjectClass, + [AObjectClassName, ClassName, Name, RequiredClass.ClassName]); + + BeforeContentChange(ctAddRef, -1, nil); + Result := InternalAddReference(AObjectClassName, AObjectId); + AfterContentChange(ctAddRef, Result, nil); +end; + procedure TInstantContainer.AfterContentChange( ChangeType: TInstantContentChangeType; Index: Integer; AObject: TInstantObject); @@ -6993,6 +7132,25 @@ end; end; +function TInstantParts.InternalAddReference(const AObjectClassName, AObjectId: + string): Integer; +var + Ref: TInstantObjectReference; +begin + Result := -1; + + if Metadata.StorageKind = skExternal then + begin + Ref := CreateObjectReference(nil); + try + Ref.ReferenceObject(AObjectClassName, AObjectId); + Result := ObjectReferenceList.Add(Ref); + except + Ref.Free; + end; + end; +end; + procedure TInstantParts.InternalClear; var I: Integer; @@ -7296,6 +7454,25 @@ Result := ObjectReferenceList.Add(AObject); end; +function TInstantReferences.InternalAddReference(const AObjectClassName, + AObjectId: string): Integer; +var + Ref: TInstantObjectReference; +begin + Result := -1; + + if Metadata.StorageKind = skExternal then + begin + Ref := ObjectReferenceList.Add; + try + Ref.ReferenceObject(AObjectClassName, AObjectId); + Result := ObjectReferenceList.IndexOfReference(Ref); + except + Ref.Free; + end; + end; +end; + procedure TInstantReferences.InternalClear; begin ObjectReferenceList.Clear; @@ -8388,7 +8565,7 @@ if Result then Exit; end; - end; + end; end; var @@ -10161,7 +10338,7 @@ if not (Assigned(AObject) and AObject.Metadata.IsStored) then Exit; CheckBroker(Broker); - AObject.FInUpdate := True; + AObject.InUpdate := True; try try if Broker.StoreObject(AObject, ConflictAction) then @@ -10186,7 +10363,7 @@ [AObject.ClassName, AObject.Id, E.Message], E); end; finally - AObject.FInUpdate := False; + AObject.InUpdate := False; end; end; @@ -11739,7 +11916,7 @@ // Remove references from the BusyList for objects destroyed // when the query was closed. RemoveRefsOfDeletedObjectsFromList; - + Open; // Refresh objects in the BusyList that were not destroyed @@ -12059,10 +12236,23 @@ procedure TInstantNavigationalResolver.ClearPart(Attribute: TInstantPart); begin + if Attribute.Metadata.StorageKind = skExternal then + Attribute.Value.ObjectStore.DisposeObject(Attribute.Value, caIgnore); end; procedure TInstantNavigationalResolver.ClearParts(Attribute: TInstantParts); +var + I: Integer; + LinkDatasetResolver: TInstantNavigationalLinkResolver; begin + if Attribute.Metadata.StorageKind = skExternal then + begin + for I := 0 to Pred(Attribute.Count) do + Attribute.Items[I].ObjectStore.DisposeObject(Attribute.Items[I], caIgnore); + LinkDatasetResolver := + GetLinkDatasetResolver(Attribute.Metadata.ExternalStorageName); + LinkDatasetResolver.ClearAttributeLinkRecords; + end; end; procedure TInstantNavigationalResolver.ClearReference( @@ -12072,7 +12262,15 @@ procedure TInstantNavigationalResolver.ClearReferences( Attribute: TInstantReferences); +var + LinkDatasetResolver: TInstantNavigationalLinkResolver; begin + if Attribute.Metadata.StorageKind = skExternal then + begin + LinkDatasetResolver := + GetLinkDatasetResolver(Attribute.Metadata.ExternalStorageName); + LinkDatasetResolver.ClearAttributeLinkRecords; + end; end; procedure TInstantNavigationalResolver.ClearString(Attribute: TInstantString); @@ -12105,15 +12303,31 @@ destructor TInstantNavigationalResolver.Destroy; begin + FreeAndNil(FNavigationalLinkResolvers); FreeDataSet; inherited; end; +procedure TInstantNavigationalResolver.ClearEnum(Attribute: TInstantEnum); +begin +end; + procedure TInstantNavigationalResolver.Edit; begin DataSet.Edit; end; +function TInstantNavigationalResolver.GetLinkDatasetResolver(const ATableName: + string): TInstantNavigationalLinkResolver; +begin + Result := FindLinkDatasetResolver(ATableName); + if not Assigned(Result) then + begin + Result := CreateNavigationalLinkResolver(ATableName); + NavigationalLinkResolvers.Add(Result); + end; +end; + function TInstantNavigationalResolver.FieldByName( const FieldName: string): TField; begin @@ -12125,6 +12339,20 @@ Result := Length(Field.AsString) > 1; end; +function TInstantNavigationalResolver.FindLinkDatasetResolver(const ATableName: + string): TInstantNavigationalLinkResolver; +var + I: Integer; +begin + for I := 0 to Pred(NavigationalLinkResolvers.Count) do + begin + Result := NavigationalLinkResolvers[I] as TInstantNavigationalLinkResolver; + if SameText(ATableName, Result.TableName) then + Exit; + end; + Result := nil; +end; + procedure TInstantNavigationalResolver.FreeDataSet; begin if FFreeDataSet then @@ -12151,6 +12379,23 @@ Result := FDataSet; end; +function TInstantNavigationalResolver.GetNavigationalLinkResolvers: TObjectList; +begin + if not Assigned(FNavigationalLinkResolvers) then + FNavigationalLinkResolvers := TObjectList.Create; + Result := FNavigationalLinkResolvers; +end; + +function TInstantNavigationalResolver.GetObjectClassName: string; +begin + Result := FieldByName(InstantClassFieldName).AsString; +end; + +function TInstantNavigationalResolver.GetObjectId: string; +begin + Result := FieldByName(InstantIdFieldName).AsString; +end; + procedure TInstantNavigationalResolver.InternalDisposeMap( AObject: TInstantObject; Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); @@ -12388,17 +12633,38 @@ var Field: TField; Stream: TInstantStringStream; + PartClassName: string; + ObjID: string; begin with Attribute do begin - Field := FieldByName(Metadata.FieldName); - if not FieldHasObjects(Field) then - Exit; - Stream := TInstantStringStream.Create(Field.AsString); - try - LoadObjectFromStream(Stream); - finally - Stream.Free; + if Metadata.StorageKind = skExternal then + begin + // Must clear Value first to avoid leak for Refresh operation + // as OldValue = NewValue. + Value := nil; + PartClassName := FieldByName(Metadata.FieldName + + InstantClassFieldName).AsString; + ObjID := FieldByName(Metadata.FieldName + InstantIdFieldName).AsString; + // PartClassName and ObjID will be empty if the attribute was + // added to a class with existing instances in the database. + if (PartClassName = '') and (ObjID = '') then + Attribute.Reset + else + Value := InstantFindClass(PartClassName).Retrieve( + ObjID, False, False, Connector); + end + else + begin + Field := FieldByName(Metadata.FieldName); + if not FieldHasObjects(Field) then + Exit; + Stream := TInstantStringStream.Create(Field.AsString); + try + LoadObjectFromStream(Stream); + finally + Stream.Free; + end; end; end; end; @@ -12407,17 +12673,28 @@ var Field: TField; Stream: TInstantStringStream; + LinkDatasetResolver: TInstantNavigationalLinkResolver; begin with Attribute do begin - Field := FieldByName(Metadata.FieldName); - if not FieldHasObjects(Field) then - Exit; - Stream := TInstantStringStream.Create(Field.AsString); - try - LoadObjectsFromStream(Stream); - finally - Stream.Free; + if Metadata.StorageKind = skExternal then + begin + Clear; + LinkDatasetResolver := + GetLinkDatasetResolver(Metadata.ExternalStorageName); + LinkDatasetResolver.ReadAttributeObjects(Attribute, ObjectId); + end + else + begin + Field := FieldByName(Metadata.FieldName); + if not FieldHasObjects(Field) then + Exit; + Stream := TInstantStringStream.Create(Field.AsString); + try + LoadObjectsFromStream(Stream); + finally + Stream.Free; + end; end; end; end; @@ -12440,17 +12717,28 @@ var Field: TField; Stream: TInstantStringStream; + LinkDatasetResolver: TInstantNavigationalLinkResolver; begin with Attribute do begin - Field := FieldByName(Metadata.FieldName); - if not FieldHasObjects(Field) then - Exit; - Stream := TInstantStringStream.Create(Field.AsString); - try - LoadReferencesFromStream(Stream); - finally - Stream.Free; + if Metadata.StorageKind = skExternal then + begin + Clear; + LinkDatasetResolver := + GetLinkDatasetResolver(Metadata.ExternalStorageName); + LinkDatasetResolver.ReadAttributeObjects(Attribute, ObjectId); + end + else + begin + Field := FieldByName(Metadata.FieldName); + if not FieldHasObjects(Field) then + Exit; + Stream := TInstantStringStream.Create(Field.AsString); + try + LoadReferencesFromStream(Stream); + finally + Stream.Free; + end; end; end; end; @@ -12502,6 +12790,8 @@ with AttributeMetadata do begin Attribute := AObject.AttributeByName(Name); + if not Attribute.IsChanged then + Exit; case AttributeType of atInteger: WriteInteger(Attribute as TInstantInteger); @@ -12586,13 +12876,25 @@ begin with Attribute do begin - Field := FieldByName(Metadata.FieldName); - Stream := TInstantStringStream.Create(''); - try - SaveObjectToStream(Stream); - Field.AsString := Stream.DataString; - finally - Stream.Free; + if Metadata.StorageKind = skExternal then + begin + Value.CheckId; + FieldByName(Metadata.FieldName + InstantClassFieldName).AsString := + Value.ClassName; + FieldByName(Metadata.FieldName + InstantIdFieldName).AsString := + Value.Id; + Value.ObjectStore.StoreObject(Value, caIgnore); + end + else + begin + Field := FieldByName(Metadata.FieldName); + Stream := TInstantStringStream.Create(''); + try + SaveObjectToStream(Stream); + Field.AsString := Stream.DataString; + finally + Stream.Free; + end; end; end; end; @@ -12601,16 +12903,33 @@ var Field: TField; Stream: TInstantStringStream; + LinkDatasetResolver: TInstantNavigationalLinkResolver; begin with Attribute do begin - Field := FieldByName(Metadata.FieldName); - Stream := TInstantStringStream.Create(''); - try - Attribute.SaveObjectsToStream(Stream); - Field.AsString := Stream.DataString; - finally - Stream.Free; + if Metadata.StorageKind = skExternal then + begin + LinkDatasetResolver := + GetLinkDatasetResolver(Metadata.ExternalStorageName); + LinkDatasetResolver.Open; + try + LinkDatasetResolver.DisposeDeletedAttributeObjects(Attribute); + LinkDatasetResolver.ClearAttributeLinkRecords; + LinkDatasetResolver.StoreAttributeObjects(Attribute); + finally + LinkDatasetResolver.Close; + end; + end + else + begin + Field := FieldByName(Metadata.FieldName); + Stream := TInstantStringStream.Create(''); + try + SaveObjectsToStream(Stream); + Field.AsString := Stream.DataString; + finally + Stream.Free; + end; end; end; end; @@ -12631,16 +12950,32 @@ var Field: TField; Stream: TInstantStringStream; + LinkDatasetResolver: TInstantNavigationalLinkResolver; begin with Attribute do begin - Field := FieldByName(Metadata.FieldName); - Stream := TInstantStringStream.Create(''); - try - SaveReferencesToStream(Stream); - Field.AsString := Stream.DataString; - finally - Stream.Free; + if Metadata.StorageKind = skExternal then + begin + LinkDatasetResolver := + GetLinkDatasetResolver(Metadata.ExternalStorageName); + LinkDatasetResolver.Open; + try + LinkDatasetResolver.ClearAttributeLinkRecords; + LinkDatasetResolver.StoreAttributeObjects(Attribute); + finally + LinkDatasetResolver.Close; + end; + end + else + begin + Field := FieldByName(Metadata.FieldName); + Stream := TInstantStringStream.Create(''); + try + SaveReferencesToStream(Stream); + Field.AsString := Stream.DataString; + finally + Stream.Free; + end; end; end; end; @@ -12793,7 +13128,7 @@ I: Integer; begin for I := 0 to Pred(ObjectRowCount) do - if (ObjectRows[I]^.Instance is TInstantObject) then + if ObjectFetched(I) and (ObjectRows[I]^.Instance is TInstantObject) then List.Add(TInstantObject(ObjectRows[I]^.Instance)); end; @@ -13967,143 +14302,83 @@ for i := 0 to Pred(Map.Count) do begin AttributeMetadata := Map[i]; - if Map[i].AttributeType = atPart then + if (AttributeMetadata.AttributeType = atPart) and + (AttributeMetadata.StorageKind = skExternal) then begin - if Map[i].StorageKind = skExternal then - begin - // Dispose object - SelectParams := TParams.Create; + // Dispose object + SelectParams := TParams.Create; + try + SelectStatement := Format(SelectExternalPartSQL, + [AttributeMetadata.FieldName + InstantClassFieldName, + AttributeMetadata.FieldName + InstantIdFieldName, + AttributeMetadata.ClassMetadata.TableName]); + AddStringParam(SelectParams, InstantClassFieldName, AObject.ClassName); + AddIdParam(SelectParams, InstantIdFieldName, AObject.Id); + DataSet := Broker.AcquireDataSet(SelectStatement, SelectParams); try - SelectStatement := Format(SelectExternalPartSQL, - [AttributeMetadata.FieldName + InstantClassFieldName, - AttributeMetadata.FieldName + InstantIdFieldName, - AttributeMetadata.ClassMetadata.TableName]); - AddStringParam(SelectParams, InstantClassFieldName, AObject.ClassName); - AddIdParam(SelectParams, InstantIdFieldName, AObject.Id); - DataSet := Broker.AcquireDataSet(SelectStatement, SelectParams); + DataSet.Open; try - DataSet.Open; - try - if not DataSet.IsEmpty then - begin - PartObject := AttributeMetadata.ObjectClass.Retrieve( - DataSet.Fields[1].AsString, False, False, AObject.Connector); - try - if Assigned(PartObject) then - PartObject.ObjectStore.DisposeObject(PartObject, caIgnore); - finally - PartObject.Free; - end; + if not DataSet.IsEmpty then + begin + PartObject := AttributeMetadata.ObjectClass.Retrieve( + DataSet.Fields[1].AsString, False, False, AObject.Connector); + try + if Assigned(PartObject) then + PartObject.ObjectStore.DisposeObject(PartObject, caIgnore); + finally + PartObject.Free; end; - finally - DataSet.Close; end; finally - Broker.ReleaseDataSet(DataSet); + DataSet.Close; end; finally - SelectParams.Free; + Broker.ReleaseDataSet(DataSet); end; - + finally + SelectParams.Free; end; end; end; end; - procedure DeleteExternalPartsMap; + procedure DeleteAllExternalLinks(Index: Integer); var - i: Integer; - PartObject: TInstantObject; - SelectParams, DeleteParams: TParams; - SelectStatement, DeleteStatement: string; - AttributeMetadata: TInstantAttributeMetadata; - DataSet: TDataSet; + LinkResolver: TInstantSQLLinkResolver; begin - for i := 0 to Pred(Map.Count) do - begin - AttributeMetadata := Map[i]; - if Map[i].AttributeType = atParts then - begin - if Map[i].StorageKind = skExternal then - begin - // dispose all objects - SelectParams := TParams.Create; - try - SelectStatement := Format(SelectExternalSQL, [AttributeMetadata.ExternalStorageName]); - AddIdParam(SelectParams, InstantParentIdFieldName, AObject.Id); - AddStringParam(SelectParams, InstantParentClassFieldName, AObject.ClassName); - AddStringParam(SelectParams, InstantChildClassFieldName, AttributeMetadata.ObjectClassName); - DataSet := Broker.AcquireDataSet(SelectStatement, SelectParams); - try - DataSet.Open; - try - while not DataSet.Eof do - begin - PartObject := AttributeMetadata.ObjectClass.Retrieve( - DataSet.Fields[1].AsString, False, False, AObject.Connector); - try - if Assigned(PartObject) then - PartObject.ObjectStore.DisposeObject(PartObject, caIgnore); - finally - PartObject.Free; - end; - DataSet.Next; - end; - finally - DataSet.Close; - end; - finally - Broker.ReleaseDataSet(DataSet); - end; - finally - SelectParams.Free; - end; - - // Delete all links - DeleteParams := TParams.Create; - try - DeleteStatement := Format(DeleteExternalSQL, - [AttributeMetadata.ExternalStorageName, - InstantParentClassFieldName, - InstantParentIdFieldName]); - AddStringParam(DeleteParams, InstantParentClassFieldName, AObject.ClassName); - AddIdParam(DeleteParams, InstantParentIdFieldName, AObject.Id); - Broker.Execute(DeleteStatement, DeleteParams); - finally - DeleteParams.Free; - end; - end; - end; + LinkResolver := TInstantSQLLinkResolver.Create(Self, + Map[Index].ExternalStorageName, AObject); + try + LinkResolver.ClearAttributeLinkRecords; + finally + LinkResolver.Free; end; end; - procedure DeleteExternalReferencesMap; + procedure DeleteExternalContainerMaps; var i: Integer; - DeleteParams: TParams; - DeleteStatement: string; + j: Integer; AttributeMetadata: TInstantAttributeMetadata; + Attribute: TInstantContainer; begin for i := 0 to Pred(Map.Count) do begin AttributeMetadata := Map[i]; - if AttributeMetadata.AttributeType = atReferences then + if (AttributeMetadata.AttributeType in [atParts, atReferences]) and + (AttributeMetadata.StorageKind = skExternal) then begin - if AttributeMetadata.StorageKind = skExternal then + if AttributeMetadata.AttributeType = atParts then begin - // Delete all links - DeleteParams := TParams.Create; - try - DeleteStatement := Format(DeleteExternalSQL, - [AttributeMetadata.ExternalStorageName, - InstantParentClassFieldName]); - AddStringParam(DeleteParams, InstantParentClassFieldName, AObject.ClassName); - AddIdParam(DeleteParams, InstantParentIdFieldName, AObject.Id); - Broker.Execute(DeleteStatement, DeleteParams); - finally - DeleteParams.Free; - end; + // Dispose all contained objects + Attribute := TInstantContainer(AObject.AttributeByName( + AttributeMetadata.Name)); + for j := 0 to Pred(Attribute.Count) do + Attribute.Items[j].ObjectStore.DisposeObject( + Attribute.Items[j], caIgnore); end; + + DeleteAllExternalLinks(i); end; end; end; @@ -14112,8 +14387,7 @@ if not Assigned(Info) then Info := @AInfo; DeleteExternalPartMap; - DeleteExternalPartsMap; - DeleteExternalReferencesMap; + DeleteExternalContainerMaps; Params := TParams.Create; try AddBaseParams(Params, AObject.ClassName, AObject.PersistentId); @@ -14277,173 +14551,38 @@ end; end; - procedure UpdateExternalPartsMap; + procedure UpdateExternalContainerMaps; var - i, ii: Integer; - PartObject: TInstantObject; - PartsAttribute: TInstantParts; + I: Integer; AttributeMetadata: TInstantAttributeMetadata; - SelectParams, DeleteParams, InsertParams: TParams; - SelectStatement, DeleteStatement, InsertStatement: string; - DataSet: TDataSet; + LinkResolver: TInstantSQLLinkResolver; + Attribute: TInstantContainer; begin - for i := 0 to Pred(Map.Count) do + for I := 0 to Pred(Map.Count) do begin - AttributeMetadata := Map[i]; - if AttributeMetadata.AttributeType = atParts then + AttributeMetadata := Map[I]; + if AttributeMetadata.AttributeType in [atParts, atReferences] then begin - PartsAttribute := TInstantParts(AObject.AttributeByName(AttributeMetadata.Name)); - if PartsAttribute.IsChanged then + Attribute := TInstantContainer(AObject.AttributeByName( + AttributeMetadata.Name)); + if Attribute.IsChanged and + (AttributeMetadata.StorageKind = skExternal) then begin - if Map[i].StorageKind = skExternal then - begin - // Make sure that all the items are in memory because they will be - // accessed later, after the database records have been deleted. - for ii := 0 to Pred(PartsAttribute.Count) do - PartsAttribute.Items[ii]; - // Delete all objects - SelectParams := TParams.Create; - try - SelectStatement := Format(SelectExternalSQL, [AttributeMetadata.ExternalStorageName]); - AddIdParam(SelectParams, InstantParentIdFieldName, AObject.Id); - AddStringParam(SelectParams, InstantParentClassFieldName, AObject.ClassName); - AddStringParam(SelectParams, InstantChildClassFieldName, AttributeMetadata.ObjectClassName); - DataSet := Broker.AcquireDataSet(SelectStatement, SelectParams); - try - DataSet.Open; - try - while not DataSet.Eof do - begin - PartObject := AttributeMetadata.ObjectClass.Retrieve( - DataSet.Fields[1].AsString, False, False, AObject.Connector); - try - if Assigned(PartObject) and - (PartsAttribute.IndexOf(PartObject) = -1) then - PartObject.ObjectStore.DisposeObject(PartObject, caIgnore); - finally - PartObject.Free; - end; - DataSet.Next; - end; - finally - DataSet.Close; - end; - finally - Broker.ReleaseDataSet(DataSet); - end; - finally - SelectParams.Free; - end; - - // Delete all links - DeleteParams := TParams.Create; - try - DeleteStatement := Format(DeleteExternalSQL, - [AttributeMetadata.ExternalStorageName, - InstantParentClassFieldName]); - AddStringParam(DeleteParams, InstantParentClassFieldName, AObject.ClassName); - AddIdParam(DeleteParams, InstantParentIdFieldName, AObject.Id); - Broker.Execute(DeleteStatement, DeleteParams); - finally - DeleteParams.Free; - end; - - // Store all objects and links - for ii := 0 to Pred(PartsAttribute.Count) do - begin - // Store object - PartObject := PartsAttribute.Items[ii]; - PartObject.CheckId; - PartObject.ObjectStore.StoreObject(PartObject, caIgnore); - - // Insert link - InsertParams := TParams.Create; - try - InsertStatement := Format(InsertExternalSQL, - [AttributeMetadata.ExternalStorageName]); - AddIdParam(InsertParams, InstantIdFieldName, AObject.GenerateId); - AddStringParam(InsertParams, InstantParentClassFieldName, AObject.ClassName); - AddIdParam(InsertParams, InstantParentIdFieldName, AObject.Id); - AddStringParam(InsertParams, InstantChildClassFieldName, - PartsAttribute.Items[ii].ClassName); - AddIdParam(InsertParams, InstantChildIdFieldName, - PartsAttribute.Items[ii].Id); - AddIntegerParam(InsertParams, InstantSequenceNoFieldName, Succ(ii)); - Broker.Execute(InsertStatement, InsertParams); - finally - InsertParams.Free; - end; - end; + LinkResolver := TInstantSQLLinkResolver.Create(Self, + AttributeMetadata.ExternalStorageName, AObject); + try + if AttributeMetadata.AttributeType = atParts then + LinkResolver.DisposeDeletedAttributeObjects(Attribute); + LinkResolver.ClearAttributeLinkRecords; + LinkResolver.StoreAttributeObjects(Attribute); + finally + LinkResolver.Free; end; end; end; end; end; - procedure UpdateExternalReferencesMap; - var - i, ii: integer; - AttributeMetadata: TInstantAttributeMetadata; - ReferenceObject: TInstantObject; - ReferencesAttribute: TInstantReferences; - DeleteParams, InsertParams: TParams; - DeleteStatement, InsertStatement: string; - begin - for i := 0 to Pred(Map.Count) do - begin - AttributeMetadata := Map[i]; - if AttributeMetadata.AttributeType = atReferences then - begin - ReferencesAttribute := TInstantReferences(AObject.AttributeByName(AttributeMetadata.Name)); - if ReferencesAttribute.IsChanged then - begin - if AttributeMetadata.StorageKind = skExternal then - begin - // Delete all links - DeleteParams := TParams.Create; - try - DeleteStatement := Format(DeleteExternalSQL, - [AttributeMetadata.ExternalStorageName, - InstantParentClassFieldName, - InstantParentIdFieldName]); - AddStringParam(DeleteParams, InstantParentClassFieldName, AObject.ClassName); - AddIdParam(DeleteParams, InstantParentIdFieldName, AObject.Id); - Broker.Execute(DeleteStatement, DeleteParams); - finally - DeleteParams.Free; - end; - // Store all links - for ii := 0 to Pred(ReferencesAttribute.Count) do - begin - ReferenceObject := ReferencesAttribute.Items[ii]; - if ReferenceObject.FInUpdate then // prevent recursion - Continue; - ReferenceObject.CheckId; - ReferenceObject.ObjectStore.StoreObject(ReferenceObject, caIgnore); - - InsertParams := TParams.Create; - try - InsertStatement := Format(InsertExternalSQL, - [AttributeMetadata.ExternalStorageName]); - AddIdParam(InsertParams, InstantIdFieldName, AObject.GenerateId); - AddStringParam(InsertParams, InstantParentClassFieldName, AObject.ClassName); - AddIdParam(InsertParams, InstantParentIdFieldName, AObject.Id); - AddStringParam(InsertParams, InstantChildClassFieldName, - ReferencesAttribute.Items[ii].ClassName); - AddIdParam(InsertParams, InstantChildIdFieldName, - ReferencesAttribute.Items[ii].Id); - AddIntegerParam(InsertParams, InstantSequenceNoFieldName, Succ(ii)); - Broker.Execute(InsertStatement, InsertParams); - finally - InsertParams.Free; - end; - end; - end; - end; - end; - end; - end; - begin if not Assigned(Info) then Info := @AInfo; @@ -14470,8 +14609,7 @@ if Map.IsRootMap then Broker.SetObjectUpdateCount(AObject, NewUpdateCount); - UpdateExternalPartsMap; - UpdateExternalReferencesMap; + UpdateExternalContainerMaps; finally Params.Free; end; @@ -14565,49 +14703,22 @@ procedure ReadPartsAttribute; var - //PartObject: TInstantObject; - Statement: string; - Params: TParams; Stream: TInstantStringStream; - RefObject:TInstantObjectReference; + LinkResolver: TInstantSQLLinkResolver; begin if AttributeMetadata.StorageKind = skExternal then begin with (Attribute as TInstantParts) do begin Clear; - Params := TParams.Create; + LinkResolver := TInstantSQLLinkResolver.Create(Self, + AttributeMetadata.ExternalStorageName, AObject); try - Statement := Format(SelectExternalSQL, [AttributeMetadata.ExternalStorageName]); - AddIdParam(Params, InstantParentIdFieldName, AObjectId); - AddStringParam(Params, InstantParentClassFieldName, AObject.ClassName); - AddStringParam(Params, InstantChildClassFieldName, AttributeMetadata.ObjectClassName); - DataSet := Broker.AcquireDataSet(Statement, Params); - try - DataSet.Open; - try - while not DataSet.Eof do - begin - RefObject := TInstantObjectReference.Create(nil, True); - RefObject.ReferenceObject(DataSet.Fields[0].AsString, DataSet.Fields[1].AsString); - (Attribute as TInstantParts).ObjectReferenceList.Add(RefObject); - {PartObject := AttributeMetadata.ObjectClass.Retrieve(Fields[1].AsString, False, False, AObject.Connector); - if Assigned(PartObject) then - Add(PartObject) - else - PartObject.Free;} - DataSet.Next; - end; - finally - DataSet.Close; - end; - finally - Broker.ReleaseDataSet(DataSet); - end; + LinkResolver.ReadAttributeObjects(TInstantParts(Attribute), + AObjectId); finally - Params.Free; + LinkResolver.Free; end; - //Changed; end; end else @@ -14633,41 +14744,21 @@ procedure ReadReferencesAttribute; var - RefObject:TInstantObjectReference; Stream: TInstantStringStream; - Statement: string; - Params: TParams; + LinkResolver: TInstantSQLLinkResolver; begin if AttributeMetadata.StorageKind = skExternal then begin with (Attribute as TInstantReferences) do begin Clear; - Params := TParams.Create; + LinkResolver := TInstantSQLLinkResolver.Create(Self, + AttributeMetadata.ExternalStorageName, AObject); try - Statement:=Format(SelectExternalSQL, [AttributeMetadata.ExternalStorageName]); - AddIdParam(Params, InstantParentIdFieldName, AObjectId); - AddStringParam(Params, InstantParentClassFieldName, AObject.ClassName); - AddStringParam(Params, InstantChildClassFieldName, AttributeMetadata.ObjectClassName); - DataSet := Broker.AcquireDataSet(Statement, Params); - try - DataSet.Open; - try - while not DataSet.Eof do - begin - RefObject := - (Attribute as TInstantReferences).ObjectReferenceList.Add; - RefObject.ReferenceObject(Metadata.ObjectClass, DataSet.Fields[1].AsString); - DataSet.Next; - end; - finally - DataSet.Close; - end; - finally - Broker.ReleaseDataSet(DataSet); - end; + LinkResolver.ReadAttributeObjects(TInstantReferences(Attribute), + AObjectId); finally - Params.Free; + LinkResolver.Free; end; end; end @@ -15810,6 +15901,12 @@ Result := IndexOf(Item, True); end; +function TInstantObjectReferenceList.IndexOfReference(AObjectReference: + TInstantObjectReference): Integer; +begin + Result := FList.IndexOf(AObjectReference); +end; + procedure TInstantObjectReferenceList.Insert(Index: Integer; Item: TInstantObject); var Ref: TInstantObjectReference; Modified: trunk/Source/Tests/TestInstantParts.pas =================================================================== --- trunk/Source/Tests/TestInstantParts.pas 2006-07-18 07:46:13 UTC (rev 686) +++ trunk/Source/Tests/TestInstantParts.pas 2006-07-20 00:56:59 UTC (rev 687) @@ -48,6 +48,7 @@ procedure TearDown; override; published procedure TestAdd; + procedure TestAddReference; procedure TestAssign; procedure TestAttachObject; procedure TestClear; @@ -77,6 +78,7 @@ procedure TearDown; override; published procedure TestAdd; + procedure TestAddReference; procedure TestAssign; procedure TestAttachObject; procedure TestClear; @@ -109,7 +111,7 @@ implementation -uses SysUtils, Classes, testregistry; +uses SysUtils, Classes, testregistry, InstantClasses; procedure TestTInstantExtParts.SetUp; var @@ -125,17 +127,17 @@ FOwner := TContact.Create(FConn); FInstantParts := FOwner._ExternalPhones; for i := 0 to 2 do - FOwner.AddExternalPart(TExternalPhones.Create(FConn)); + FOwner.AddExternalPart(TExternalPhone.Create(FConn)); AssertEquals('Setup FInstantParts.Count', 3, FInstantParts.Count); end; function TestTInstantExtParts.PartsExternalCompare(Holder, Obj1, Obj2: TInstantObject): Integer; var - vObj1, vObj2: TExternalPhones; + vObj1, vObj2: TExternalPhone; begin - vObj1 := Obj1 as TExternalPhones; - vObj2 := Obj2 as TExternalPhones; + vObj1 := Obj1 as TExternalPhone; + vObj2 := Obj2 as TExternalPhone; Result := AnsiCompareText(vObj1.Name, vObj2.Name); end; @@ -151,14 +153,29 @@ procedure TestTInstantExtParts.TestAdd; var vReturnValue: Integer; - vExternalPart: TExternalPhones; + vExternalPart: TExternalPhone; begin - vExternalPart := TExternalPhones.Create(FConn); + FInstantParts.Unchanged; + AssertFalse(FInstantParts.IsChanged); + vExternalPart := TExternalPhone.Create(FConn); vReturnValue := FInstantParts.Add(vExternalPart); AssertTrue(vReturnValue <> -1); + AssertTrue(FInstantParts.IsChanged); AssertEquals(4, FInstantParts.Count); end; +procedure TestTInstantExtParts.TestAddReference; +var + vReturnValue: Integer; +begin + FInstantParts.Unchanged; + AssertFalse(FInstantParts.IsChanged); + vReturnValue := FInstantParts.AddReference('TExternalPhone', 'NewPhoneId'); + AssertTrue(vReturnValue <> -1); + AssertTrue(FInstantParts.IsChanged); + AssertEquals(4, FInstantParts.Count); +end; + procedure TestTInstantExtParts.TestAssign; var vSource: TInstantParts; @@ -185,9 +202,9 @@ procedure TestTInstantExtParts.TestAttachObject; var vReturnValue: Boolean; - vExternalPart: TExternalPhones; + vExternalPart: TExternalPhone; begin - vExternalPart := TExternalPhones.Create(FConn); + vExternalPart := TExternalPhone.Create(FConn); vReturnValue := FInstantParts.AttachObject(vExternalPart); AssertTrue(vReturnValue); AssertEquals(4, FInstantParts.Count); @@ -224,13 +241,13 @@ procedure TestTInstantExtParts.TestExchange; begin - TExternalPhones(FInstantParts.Items[0]).Name := 'Part0'; - TExternalPhones(FInstantParts.Items[1]).Name := 'Part1'; - TExternalPhones(FInstantParts.Items[2]).Name := 'Part2'; + TExternalPhone(FInstantParts.Items[0]).Name := 'Part0'; + TExternalPhone(FInstantParts.Items[1]).Name := 'Part1'; + TExternalPhone(FInstantParts.Items[2]).Name := 'Part2'; FInstantParts.Exchange(0, 2); - AssertEquals('Part2', TExternalPhones(FInstantParts.Items[0]).Name); - AssertEquals('Part1', TExternalPhones(FInstantParts.Items[1]).Name); - AssertEquals('Part0', TExternalPhones(FInstantParts.Items[2]).Name); + AssertEquals('Part2', TExternalPhone(FInstantParts.Items[0]).Name); + AssertEquals('Part1', TExternalPhone(FInstantParts.Items[1]).Name); + AssertEquals('Part0', TExternalPhone(FInstantParts.Items[2]).Name); end; procedure TestTInstantExtParts.TestHasItem; @@ -250,7 +267,7 @@ vReturnValue: Integer; vObject: TInstantObject; begin - vObject := TExternalPhones.Create(FConn); + vObject := TExternalPhone.Create(FConn); FInstantParts.Insert(1, vObject); vReturnValue := FInstantParts.IndexOf(vObject); AssertEquals(1, vReturnValue); @@ -261,7 +278,7 @@ vReturnValue: Integer; vInstance: Pointer; begin - vInstance := TExternalPhones.Create(FConn); + vInstance := TExternalPhone.Create(FConn); FInstantParts.Insert(1, vInstance); vReturnValue := FInstantParts.IndexOfInstance(vInstance); AssertEquals(1, vReturnValue); @@ -269,19 +286,19 @@ procedure TestTInstantExtParts.TestMove; var - vExternalPart: TExternalPhones; + vExternalPart: TExternalPhone; begin - TExternalPhones(FInstantParts.Items[0]).Name := 'Part0'; - TExternalPhones(FInstantParts.Items[1]).Name := 'Part1'; - TExternalPhones(FInstantParts.Items[2]).Name := 'Part2'; - vExternalPart := TExternalPhones.Create(FConn); + TExternalPhone(FInstantParts.Items[0]).Name := 'Part0'; + TExternalPhone(FInstantParts.Items[1]).Name := 'Part1'; + TExternalPhone(FInstantParts.Items[2]).Name := 'Part2'; + vExternalPart := TExternalPhone.Create(FConn); FInstantParts.Add(vExternalPart); - TExternalPhones(FInstantParts.Items[3]).Name := 'Part3'; + TExternalPhone(FInstantParts.Items[3]).Name := 'Part3'; FInstantParts.Move(0, 2); - AssertEquals('Part1', TExternalPhones(FInstantParts.Items[0]).Name); - AssertEquals('Part2', TExternalPhones(FInstantParts.Items[1]).Name); - AssertEquals('Part0', TExternalPhones(FInstantParts.Items[2]).Name); - AssertEquals('Part3', TExternalPhones(FInstantParts.Items[3]).Name); + AssertEquals('Part1', TExternalPhone(FInstantParts.Items[0]).Name); + AssertEquals('Part2', TExternalPhone(FInstantParts.Items[1]).Name); + AssertEquals('Part0', TExternalPhone(FInstantParts.Items[2]).Name); + AssertEquals('Part3', TExternalPhone(FInstantParts.Items[3]).Name); end; procedure TestTInstantExtParts.TestRemove; @@ -321,20 +338,20 @@ procedure TestTInstantExtParts.TestSort; var - vExternalPart: TExternalPhones; + vExternalPart: TExternalPhone; begin - TExternalPhones(FInstantParts.Items[0]).Name := '2 Part'; - TExternalPhones(FInstantParts.Items[1]).Name := '0 Part'; - TExternalPhones(FInstantParts.Items[2]).Name := '1 Part'; - vExternalPart := TExternalPhones.Create(FConn); + TExternalPhone(FInstantParts.Items[0]).Name := '2 Part'; + TExternalPhone(FInstantParts.Items[1]).Name := '0 Part'; + TExternalPhone(FInstantParts.Items[2]).Name := '1 Part'; + vExternalPart := TExternalPhone.Create(FConn); FOwner.AddExternalPart(vExternalPart); - TExternalPhones(FInstantParts.Items[3]).Name := '0 Part'; + TExternalPhone(FInstantParts.Items[3]).Name := '0 Part'; FInstantParts.Sort(PartsExternalCompare); - AssertEquals('0 Part', TExternalPhones(FInstantParts.Items[0]).Name); - AssertEquals('0 Part', TExternalPhones(FInstantParts.Items[1]).Name); - AssertEquals('1 Part', TExternalPhones(FInstantParts.Items[2]).Name); - AssertEquals('2 Part', TExternalPhones(FInstantParts.Items[3]).Name); + AssertEquals('0 Part', TExternalPhone(FInstantParts.Items[0]).Name); + AssertEquals('0 Part', TExternalPhone(FInstantParts.Items[1]).Name); + AssertEquals('1 Part', TExternalPhone(FInstantParts.Items[2]).Name); + AssertEquals('2 Part', TExternalPhone(FInstantParts.Items[3]).Name); end; procedure TestTInstantExtParts.TestUnchanged; @@ -345,7 +362,7 @@ FInstantParts.Unchanged; AssertFalse(FInstantParts.IsChanged); - TExternalPhones(FInstantParts.Items[1]).Name := 'Part2'; + TExternalPhone(FInstantParts.Items[1]).Name := 'Part2'; AssertTrue(FInstantParts.IsChanged); end; @@ -399,6 +416,18 @@ AssertEquals(4, FInstantParts.Count); end; +procedure TestTinstantEmbParts.TestAddReference; +begin + try + FInstantParts.AddReference('TPhone', 'NewPhoneId'); + Fail('Should never get here!!'); + except + on E: EInstantError do ; // do nothing as this is expected + else + raise; + end; +end; + procedure TestTinstantEmbParts.TestAssign; var vSource: TInstantParts; @@ -577,7 +606,7 @@ FInstantParts.Unchanged; AssertFalse(FInstantParts.IsChanged); - TExternalPhones(FInstantParts.Items[1]).Name := 'Part2'; + TExternalPhone(FInstantParts.Items[1]).Name := 'Part2'; AssertTrue(FInstantParts.IsChanged); end; @@ -626,11 +655,11 @@ procedure TestTInstantParts_Leak.TestAddExternalObject; var vReturnValue: Integer; - vPart: TExternalPhones; + vPart: TExternalPhone; begin FInstantParts := FOwner._ExternalPhones; - vPart := TExternalPhones.Create(FConn); + vPart := TExternalPhone.Create(FConn); AssertEquals(1, vPart.RefCount); vReturnValue := FInstantParts.Add(vPart); Modified: trunk/Source/Tests/TestInstantReferences.pas =================================================================== --- trunk/Source/Tests/TestInstantReferences.pas 2006-07-18 07:46:13 UTC (rev 686) +++ trunk/Source/Tests/TestInstantReferences.pas 2006-07-20 00:56:59 UTC (rev 687) @@ -47,6 +47,7 @@ procedure TearDown; override; published procedure TestAdd; + procedure TestAddReference; procedure TestAssign; procedure TestAttachObject; procedure TestClear; @@ -77,6 +78,7 @@ procedure TearDown; override; published procedure TestAdd; + procedure TestAddReference; procedure TestAssign; procedure TestAttachObject; procedure TestClear; @@ -98,7 +100,7 @@ implementation -uses SysUtils, Classes, testregistry; +uses SysUtils, Classes, testregistry, InstantClasses; function TestTInstantEmbReferences.RefsEmbeddedCompare(Holder, ... [truncated message content] |
From: <sr...@us...> - 2006-07-18 07:46:29
|
Revision: 686 Author: srmitch Date: 2006-07-18 00:46:13 -0700 (Tue, 18 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=686&view=rev Log Message: ----------- Create a branch for IO Version 2.0 release development. Added Paths: ----------- branches/2.0/ Copied: branches/2.0 (from rev 685, trunk) |
From: <sr...@us...> - 2006-07-06 06:00:34
|
Revision: 685 Author: srmitch Date: 2006-07-05 23:00:08 -0700 (Wed, 05 Jul 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=685&view=rev Log Message: ----------- - Added a 'Performance Hint' note to the 'External Storage of Attributes" topic. The note relates to indices for external attribute linking tables. - Added a compressed CHM help file option. - Further clean-up of typos and spelling mistakes, etc. Modified Paths: -------------- trunk/Help/IOHelp.cnt trunk/Help/IOHelp.hlp trunk/Help/IOHelp.hsc trunk/Help/IOHelp.rtf Added Paths: ----------- trunk/Help/IOHelp.chm Added: trunk/Help/IOHelp.chm =================================================================== (Binary files differ) Property changes on: trunk/Help/IOHelp.chm ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Modified: trunk/Help/IOHelp.cnt =================================================================== --- trunk/Help/IOHelp.cnt 2006-06-07 15:39:31 UTC (rev 684) +++ trunk/Help/IOHelp.cnt 2006-07-06 06:00:08 UTC (rev 685) @@ -100,7 +100,7 @@ 2 Functions 3 InstantCharSetToStr=327SI7S>MAIN 3 InstantCheckConnection=327SI7X>MAIN -3 InstantCheckConnector=327SI7X>MAIN +3 InstantCheckConnector=327SI8Y>MAIN 3 InstantClassNameToName=327SI8R>MAIN 3 InstantCompareObjects=327SI8U>MAIN 3 InstantCompareText=327SI8X>MAIN Modified: trunk/Help/IOHelp.hlp =================================================================== (Binary files differ) Modified: trunk/Help/IOHelp.hsc =================================================================== --- trunk/Help/IOHelp.hsc 2006-06-07 15:39:31 UTC (rev 684) +++ trunk/Help/IOHelp.hsc 2006-07-06 06:00:08 UTC (rev 685) @@ -181,11 +181,11 @@ \par \pard\sb25\sa25\fs18 This user guide contains \f1 practical\f0 guidelines for building InstantObjects\lang1033\f1 \lang1040\f0 based applications. The intention is to give an overview o\f1 f\f0 the classes, components and tools that make up the InstantObjects framework. Although the guide is very detailed, it has not been the intention to cover all aspects of the framework. If more information is needed, \lang1033\f1 please\lang1040\f0 refer to the Symbol Reference. \par Th\lang1033\f1 is\lang1040\f0 guide \lang1033\f1 contains\lang1040\f0 three parts \lang1033\f1 that\lang1040\f0 constitute almost any InstantObjects based development process. \par \f2\fs10 -\par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\keep\fi-200\li295\sb25\sa25\tx280\lang1033\f1\fs18 \lang1040\strike\f0 Creating the Business Model\strike0\{linkID=70>main\} -\par \lang1033\f1{\pntext\f3\'B7\tab} \lang1040\strike\f0 Creating the User Interface\strike0\{linkID=280>main\} -\par \lang1033\f1{\pntext\f3\'B7\tab} \lang1040\strike\f0 Programming with Persistent Objects\strike0\{linkID=340>main\} +\par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\keep\fi-200\li295\sb25\sa25\tx280\lang1033\f1\fs18 \cf2\lang1040\strike\f0 Creating the Business Model\cf3\strike0\{linkID=70>main\}\cf1 +\par \lang1033\f1{\pntext\f3\'B7\tab} \cf2\lang1040\strike\f0 Creating the User Interface\cf3\strike0\{linkID=280>main\}\cf1 +\par \lang1033\f1{\pntext\f3\'B7\tab} \cf2\lang1040\strike\f0 Programming with Persistent Objects\cf3\strike0\{linkID=340>main\}\cf1 \par \pard\sb25\sa25\f2\fs10 -\par \pard\keep\li95\sb25\sa25\lang1033\f1\fs18 There is also a section on \lang1040\strike Learning the Primer Demo\cf3\strike0\{linkID=460>main\}\cf1\lang1033 .\lang1040\f0 +\par \pard\keep\li95\sb25\sa25\lang1033\f1\fs18 There is also a section on \cf2\lang1040\strike Learning the Primer Demo\cf3\strike0\{linkID=460>main\}\cf1\lang1033 .\lang1040\f0 \par \pard\sb25\sa25 \par } 60 @@ -202,13 +202,13 @@ FALSE 10 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} -{\colortbl ;\red0\green0\blue0;\red128\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\sb25\lang1040\b\f0\fs24 Us\lang1033\f1 er Guide\lang1040\f0 \cf1\b0\fs16 -\par \strike Using InstantObjects\strike0\fs18\{linkID=50>main\}\cf2\{keepn\}\cf1\fs16 -\par \pard\keep\li95\sb25\sa25\strike\fs18 Creating the Business Model\strike0\{linkID=70>main\} -\par \strike Creating the User Interface\strike0\{linkID=280>main\} -\par \strike Programming with Persistent Objects\strike0\{linkID=340>main\} -\par \strike\f1 Learning the Primer Demo\cf2\strike0\{linkID=460>main\}\cf1\strike\f0 +\par \cf2\strike Using InstantObjects\cf3\strike0\fs18\{linkID=50>main\}\{keepn\}\cf1\fs16 +\par \pard\keep\li95\sb25\sa25\cf2\strike\fs18 Creating the Business Model\cf3\strike0\{linkID=70>main\}\cf1 +\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\cf1 +\par \cf2\strike Programming with Persistent Objects\cf3\strike0\{linkID=340>main\}\cf1 +\par \cf2\strike\f1 Learning the Primer Demo\cf3\strike0\{linkID=460>main\}\cf1\strike\f0 \par \strike0 \par } 70 @@ -225,36 +225,36 @@ FALSE 33 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil Arial;}} -{\colortbl ;\red0\green0\blue0;\red128\green0\blue0;\red0\green128\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Creating the Business Model\cf1\b0\fs16 -\par \pard\sb25\tx1435\strike Group Topics\strike0\{linkID=80>nav\}\tab\strike Using InstantObjects\strike0\{linkID=50>main\}\cf0\b\fs24 \cf1\b0\fs16\{keepn\} +\par \pard\sb25\tx1435\cf2\strike Group Topics\cf3\strike0\{linkID=80>nav\}\cf1\tab\cf2\strike Using InstantObjects\cf3\strike0\{linkID=50>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\tx1435\fs18 Object Oriented applications are based on models. This section covers the definition of the InstantObjects business\lang1033\f1 \lang1040\f0 model, which is \lang1033\f1 \lang1040\f0 the initial step in the creation of an InstantObjects based application. The InstantObjects Model Explorer is the central tool in this process. \par \lang1033\f1 T\lang1040\f0 he InstantObjects business\lang1033\f1 \lang1040\f0 model\lang1033\f1 consists of a collection of user designed classes, many of which are related through inheritance or association. Most if not all of the data controlled by these classes is required to be persisted or stored in such a way that the relationships among this data are retained. In addition to the simple class attribute types, which provide persistence for the \lang1040\f0 Object Pascal equivalent simple type\lang1033\f1 s (eg string or integer)\lang1040\f0 \lang1033\f1 , the InstantObjects framework provides several class attribute types to facilitate the persistence of instances of related classes. These attribute types are known as relational or complex attributes. \par \pard\sb25\sa25\f2\fs10 -\par \cf2\fs18\{target=RelationalAttributeTypes\}\cf0\b\fs22 Re\lang1040 lational \lang1033 Attribute T\lang1040 ypes\cf1\b0\f0\fs18 +\par \cf3\fs18\{target=RelationalAttributeTypes\}\cf0\b\fs22 Re\lang1040 lational \lang1033 Attribute T\lang1040 ypes\cf1\b0\f0\fs18 \par The relational types are\lang1033\f1 :\lang1040\f0 Reference, Part, References and Parts.\lang1033\f1 It is important to understand the nature of the relationship that each of these attribute types provides so that the desired behaviour is reflected within the \lang1040\f0 business\lang1033\f1 \lang1040\f0 model\lang1033\f1 . \par \f2\fs10 \par \lang1040\b\f1\fs18 Container attributes \b0 is the collective name for the subset of relational types consisting of Parts and References type attributes.\lang1033\b \par \b0\f2\fs10 \par \lang1040\b\f0\fs18 Reference\b0 \par Reference is the simplest object relation supported by InstantObjects. A reference defines a unidirectional relation from one object to another. The object referred to lives outside the referring object and knows nothing about the relation itself. -\par See \strike TInstantReference\strike0\{linkID=9510>main\} for more information. +\par See \cf2\strike TInstantReference\cf3\strike0\{linkID=9510>main\}\cf1 for more information. \par \f2\fs10 \par \b\f0\fs18 Part\f1 \par \b0\f0 Objects in Part relations are tied together more closely. A Part relation is bi-directional, meaning the object at each end of the relation knows about the object at the other end. The object referred to in a Part relation is considered to be a part of the owning object and as such can only be reached via the owning object. In addition, an object referred to in a part relation is disposed along with its owner. -\par See \strike TInstantPart\strike0\{linkID=9240>main\} for more information. +\par See \cf2\strike TInstantPart\cf3\strike0\{linkID=9240>main\}\cf1 for more information. \par \f2\fs10 \par \b\f0\fs18 References\b0 \par Like its singular counterpart, Reference, the References relation is unidirectional. But instead of just referring to a single object, a References relation can refer to any number of objects and thereby defining a one-to-many relation to objects outside of the referring object. -\par See \strike TInstantReferences\strike0\{linkID=9770>main\} for more information. +\par See \cf2\strike TInstantReferences\cf3\strike0\{linkID=9770>main\}\cf1 for more information. \par \f2\fs10 \par \b\f0\fs18 Parts\f1 \par \b0\f0 Parts is the one-to-many counterpart of the equivalent one-to-one relation type, Part. A Parts relation can refer to any number of objects that are all considered to be part of the referring object. -\par See \strike TInstantParts\strike0\{linkID=9380>main\} for more information. +\par See \cf2\strike TInstantParts\cf3\strike0\{linkID=9380>main\}\cf1 for more information. \par Parts and References are known as container attributes. When defining an attribute of one of these types, a corresponding array property and optional methods to access the container attribute \lang1033\f1 are\lang1040\f0 added to the class. For any of the relational types, the class of the related object(s) must be specified as the Object Class of the attribute. \par \f2\fs10 \par \f1\fs18 Notes: -\par \pard\sb25\sa25\tx200 For \i "External Storage support"\i0 of the Part, Parts and References attribute, refer to \cf3\strike External Storage of Attributes\cf2\strike0\{linkID=220\}\cf1 . +\par \pard\sb25\sa25\tx200 For \i "External Storage support"\i0 of the Part, Parts and References attribute, refer to \cf2\strike External Storage of Attributes\cf3\strike0\{linkID=220\}\cf1 . \par \pard\sb25\sa25\tx1435\f0 \par } 80 @@ -273,13 +273,13 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\sb25\lang1040\b\f0\fs24 Creating the Business Model \cf1\b0\fs16 -\par \strike Creating the Business Model\strike0\{LinkID=70>main\}\{keepn\} -\par \pard\keep\li95\sb25\sa25\strike\fs18 The \lang1033\f1 InstantObjects \lang1040\f0 Model Explorer\strike0\{linkID=90>main\} +\par \cf2\strike Creating the Business Model\cf3\strike0\{LinkID=70>main\}\{keepn\}\cf1 +\par \pard\keep\li95\sb25\sa25\cf2\strike\fs18 The \lang1033\f1 InstantObjects \lang1040\f0 Model Explorer\cf3\strike0\{linkID=90>main\} \par \cf2\lang1033\strike\f1 Declaring Model Units\cf3\strike0\{linkID=110>main\}\cf1\lang1040\f0 -\par \strike Defining Classes\strike0\{linkID=120>main\} -\par \strike Adding Business Rules\strike0\{linkID=240>main\} -\par \strike Building/Evolving the Business Model\strike0\{linkID=270>main\} -\par +\par \cf2\strike Defining Classes\cf3\strike0\{linkID=120>main\}\cf1 +\par \cf2\strike Adding Business Rules\cf3\strike0\{linkID=240>main\} +\par \cf2\strike Building/Evolving the Business Model\cf3\strike0\{linkID=270>main\} +\par \cf1 \par } 90 327SA3S @@ -295,29 +295,29 @@ FALSE 27 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil Arial;}{\f3\fnil\fcharset0 Arial;}{\f4\fnil\fcharset2 Symbol;}} -{\colortbl ;\red0\green0\blue0;\red128\green0\blue0;\red0\green128\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 The InstantObjects Model Explorer \cf1\b0\fs16 -\par \strike Creating the Business Model\strike0\{LinkID=70>main\}\{keepn\} +\par \cf2\strike Creating the Business Model\cf3\strike0\{LinkID=70>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\fs18 The first step in building an application with InstantObjects is to define the classes and relations that make up the business model. The business model\lang1033\f1 for the application\lang1040\f0 is created\lang1033\f1 and managed\lang1040\f0 in the \lang1033\f1 InstantObjects \lang1040\f0 Model Explorer, which can be opened via the View\lang1033\f1 \lang1040\f0 menu in the Delphi IDE.\lang1033\f1 T\lang1040\f0 he \lang1033\f1 InstantObjects \lang1040\f0 Model Explorer\lang1033\f1 window is non-modal and can be docked, if desired, in the Delphi IDE. This allows the \lang1040\f0 Explorer\lang1033\f1 window to remain open while working in other areas of the IDE. \par \lang1040\f2\fs10 -\par \cf0\b\fs22 Th\lang1033\f3 e \lang1040\f2 InstantObjects Model Explorer \lang1033\f3 (\lang1040\f2 with \f3 "\f2 Inheritance\f3 "\f2 view of classes\lang1033\f3 )\cf2\lang1040\b0\f0\fs18 +\par \cf0\b\fs22 Th\lang1033\f3 e \lang1040\f2 InstantObjects Model Explorer \lang1033\f3 (\lang1040\f2 with \f3 "\f2 Inheritance\f3 "\f2 view of classes\lang1033\f3 )\cf3\lang1040\b0\f0\fs18 \par \{bmc ModelExplorerInheritance.gif\} \par \cf1\f2\fs10 \par \lang1033\f1\fs18 T\lang1040\f0 he \lang1033\f1 InstantObjects \lang1040\f0 Model Explorer\lang1033\f1 window has two main areas of interest. \par \f2\fs10 \par \pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\f1\fs18 The toolbar that holds the action speed buttons. \f3 The speed buttons display mouse-over, pop-up hints. These speed buttons provide access to the configuration aspects for model code units, persistence broker connections and type of class view presented in the tree view pane;\cf0\lang1040\b\f2\fs22 \par \pard\sb25\sa25\cf1\b0\fs10 -\par \pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\lang1033\f1\fs18 The tree view pane that displays the model's classes.\cf0\b\f3\fs22 \cf1\b0\fs18 The tree view pane has a mouse right button click, \cf3\strike pop-up menu\cf2\strike0\{linkID=100>main\}\cf1 that is used to access the procedures for managing the model.\cf0\lang1040\b\f2\fs22 +\par \pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\lang1033\f1\fs18 The tree view pane that displays the model's classes.\cf0\b\f3\fs22 \cf1\b0\fs18 The tree view pane has a mouse right button click, \cf2\strike pop-up menu\cf3\strike0\{linkID=100>main\}\cf1 that is used to access the procedures for managing the model.\cf0\lang1040\b\f2\fs22 \par \pard\sb25\sa25\cf1\b0\fs10 \par \cf0\lang1033\b\fs22 Class Views -\par \cf1\b0\fs18 A\f3 useful feature of the \f1 InstantObjects \lang1040\f0 Model Explorer\lang1033\f1 when creating or managing the class model is the ability to toggle \f3 the tree view pane \f1 between inheritance and relational type views. This is done using the 'View [Type]' speed button on the toolbar. The button has a context sensitive glyph, \cf2\{bmc ModelExplorerViewRelationsButton.gif\} \cf0 or\cf1 \cf2\{bmc ModelExplorerViewInheritanceButton.gif\}\cf0 ,\cf1 and pop-up hint. +\par \cf1\b0\fs18 A\f3 useful feature of the \f1 InstantObjects \lang1040\f0 Model Explorer\lang1033\f1 when creating or managing the class model is the ability to toggle \f3 the tree view pane \f1 between inheritance and relational type views. This is done using the 'View [Type]' speed button on the toolbar. The button has a context sensitive glyph, \cf3\{bmc ModelExplorerViewRelationsButton.gif\} \cf0 or\cf1 \cf3\{bmc ModelExplorerViewInheritanceButton.gif\}\cf0 ,\cf1 and pop-up hint. \par \f2\fs10 \par \pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\f3\fs18 Inheritance View - The tree view is based on the class inheritance structure; \par \pard\sb25\sa25\f2\fs10 \par \pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\f3\fs18 Relations View - The tree view is based on the relationships between the classes. \par \pard\sb25\sa25\f2\fs10 \par \f1\fs18 The Relations view for the above example Inheritance view is shown below.\cf0\lang1040\b\f2\fs22 -\par The InstantObjects Model Explorer \lang1033\f3 (\lang1040\f2 with \f3 "Relations"\f2 view of classes\lang1033\f3 )\cf2\lang1040\b0\f0\fs18 +\par The InstantObjects Model Explorer \lang1033\f3 (\lang1040\f2 with \f3 "Relations"\f2 view of classes\lang1033\f3 )\cf3\lang1040\b0\f0\fs18 \par \{bmc ModelExplorerRelations.gif\}\cf1 \par \par } @@ -356,14 +356,14 @@ FALSE 11 {\rtf1\ansi\ansicpg1252\deff0\deflang3081{\fonttbl{\f0\fnil Arial;}{\f1\fswiss Arial;}{\f2\fswiss\fcharset0 Arial;}{\f3\fnil\fcharset0 Arial;}} -{\colortbl ;\red0\green0\blue0;\red128\green0\blue0;\red0\green128\blue0;} +{\colortbl ;\red0\green128\blue0;\red128\green0\blue0;\red0\green0\blue0;} \viewkind4\uc1\pard\b\f0\fs24 Declaring Model Units -\par \cf1\lang1040\b0\strike\f1\fs16 Creating the Business Model\strike0\{LinkID=70>main\}\{keepn\} +\par \cf1\lang1040\b0\strike\f1\fs16 Creating the Business Model\cf2\strike0\{LinkID=70>main\}\{keepn\}\cf3 \par \pard\sb25\sa25\lang1033\f2\fs18 It is good practice to keep an application's business classes encapsulated and separated from other classes such as the user interface classes. The convention when using InstantObjects is to create separate code units within the application's IDE project solely for the purpose of containing the \lang1040\f1 business \lang1033\f2 classes that constitute an InstantObjects model. \lang1040\f1 Th\lang1033\f2 is\lang1040\f1 model can be placed in one or more \lang1033\f2 code \lang1040\f1 units in the project. These units are referred to as model units. \par \f0\fs10 -\par \lang1033\f2\fs18 The InstantObjects Model Explorer needs to know which of the application project's units are intended to be model units. This is done using\lang1040\f1 the \cf2\{bmc ModelExplorerSelectUnitsButton.gif\}\cf1 Select Units button on the toolbar of the InstantObjects Model Explorer. \lang1033\f2 T\lang1040\f1 he Select Units button\lang1033\f2 \lang1040\f1 will open a dialog showing all the units of the current project. The left side of the dialog shows the model units and the right side shows the other units included in the project. Use the buttons between the two lists to move one or more units from one side to the other. \lang1033\f2 Select the OK or Cancel button to close the dialog and save or cancel, respectively, any changes. \lang1040\f1 When \lang1033\f2 the \lang1040\f1 model unit(s)\lang1033\f2 has been declared \lang1040\f1 the business model\lang1033\f2 can be created or maintained using the \f3 tree view pane's right button click, \cf3\strike pop-up menu\cf2\strike0\{linkID=100>main\}\cf1 \lang1040\f1 . +\par \lang1033\f2\fs18 The InstantObjects Model Explorer needs to know which of the application project's units are intended to be model units. This is done using\lang1040\f1 the \cf2\{bmc ModelExplorerSelectUnitsButton.gif\}\cf3 Select Units button on the toolbar of the InstantObjects Model Explorer. \lang1033\f2 T\lang1040\f1 he Select Units button\lang1033\f2 \lang1040\f1 will open a dialog showing all the units of the current project. The left side of the dialog shows the model units and the right side shows the other units included in the project. Use the buttons between the two lists to move one or more units from one side to the other. \lang1033\f2 Select the OK or Cancel button to close the dialog and save or cancel, respectively, any changes. \lang1040\f1 When \lang1033\f2 the \lang1040\f1 model unit(s)\lang1033\f2 has been declared \lang1040\f1 the business model\lang1033\f2 can be created or maintained using the \f3 tree view pane's right button click, \cf1\strike pop-up menu\cf2\strike0\{linkID=100>main\}\cf3 \lang1040\f1 . \par \f0\fs10 -\par \cf2\f1\fs18\{bmc ModelUnitSelector.gif\}\cf1 +\par \cf2\f1\fs18\{bmc ModelUnitSelector.gif\}\cf3 \par \pard\lang3081\f0 \par } 120 @@ -382,7 +382,7 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil Arial;}{\f3\fnil\fcharset2 Symbol;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Defining Classes \cf1\b0\fs16 -\par \strike Creating the Business Model\strike0\{LinkID=70>main\}\{keepn\} +\par \cf2\strike Creating the Business Model\cf3\strike0\{LinkID=70>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\fs18 Classes can be added\lang1033\f1 , deleted\lang1040\f0 and edited\lang1033\f1 as follows (note that keyboard short cuts are also available): \par \lang1040\f0\fs10 \par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\fs18 Add a new class to the model by right-clicking in the empty area of the \lang1033\f1 tree view pane in InstantObjects \lang1040\f0 Model Explorer\lang1033\f1 . This will launch the \cf2\strike pop-up menu\cf3\strike0\{linkID=100>main\}\cf1\lang1040\f0 . Select New Class from the menu\lang1033\f1 to\lang1040\f0 bring up the Class Editor with an empty class definition\lang1033\f1 ;\lang1040\f0 @@ -439,7 +439,7 @@ \par \cf2\f2\fs18\{bmc ClassEditor\lang1033\f3 Class\lang1040\f2 .gif\} \par \cf1\f1\fs10 \par \lang1033\f3\fs18 The \b class name \b0 can be any valid Object Pascal class identifier.\lang1040\f2 -\par The default \b base class \b0 of any business class is \strike TInstantObject\strike0\{linkID=7380>main\}, the class from which persistence capabilities are inherited. When classes are present in your model, you can choose any of these as the immediate base class instead. +\par The default \b base class \b0 of any business class is \cf3\strike TInstantObject\cf2\strike0\{linkID=7380>main\}\cf1 , the class from which persistence capabilities are inherited. When classes are present in your model, you can choose any of these as the immediate base class instead. \par The \lang1033\f3 model \lang1040\b\f2 unit \b0 in which \lang1033\f3 a\lang1040\f2 new class \lang1033\f3 will\lang1040\f2 be placed can be selected from the list of available model units.\lang1033\f3 This entry is read only when editing an existing class.\lang1040\f2 \par The class\lang1033\f3 \b persistence\lang1040\f2 \b0 can be defined as either \lang1033\i\f3 stored\lang1040\f2 \i0 or \i embedded\i0 . Instances of \lang1033\i\f3 stored\lang1040\f2 \i0 classes can be \lang1033\f3 independently \lang1040\f2 stored in and retrieved from \lang1033\f3 the database\lang1040\f2 . \lang1033\f3 An i\lang1040\f2 nstance of \lang1033\f3 an \lang1040\i\f2 embedded \i0 class can exist in the database only as \lang1033\f3 an attribute\lang1040\f2 of \lang1033\f3 its owner, which is \lang1040\f2 another \i embedded \i0 or \lang1033\i\f3 stored\lang1040\f2 \lang1033\i0\f3 class instance. In practice this means that the attribute values of an \lang1040\i\f2 embedded \i0 class \lang1033\f3 are stored in the database in a BLOB type field.\lang1040\f2 \lang1033\f3 Therefore, i\lang1040\f2 f you want instances of a class to be \lang1033\f3 independently \lang1040\f2 retrievable or available by query, define the class\lang1033\f3 persistence as\lang1040\f2 \lang1033\i\f3 stored\lang1040\i0\f2 . \par \f3 S\i tored \i0 persistence is also required for those classes used by Reference attributes or other \cf3\strike attributes with \i external \i0 storage\cf2\strike0\{linkID=220>main\}\cf1 . A class, used only for objects that are owned by other objects, should be defined with \i embedded \i0 persistence if the owning objects use \i embedded \i0 storage for the attribute. If, however, the owning objects use \i external \i0 storage kind for the attribute, define the owned class with \i stored \i0 persistence.\f2 @@ -513,7 +513,7 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil\fcharset0 Arial;}{\f3\fnil Arial;}{\f4\fnil\fcharset2 Symbol;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Attribute Editor \cf1\b0\fs16 -\par \strike Creating the Business Model\strike0\{LinkID=70>main\}\tab\lang1033\f1\tab\lang1040\ul\f0 See Also\ulnone\{linkID=180\}\{keepn\} +\par \cf2\strike Creating the Business Model\cf3\strike0\{LinkID=70>main\}\cf1\tab\lang1033\f1\tab\cf2\lang1040\ul\f0 See Also\cf3\ulnone\{linkID=180\}\{keepn\}\cf1 \par \lang1033\f2\fs18 The Attribute Editor is used to manage an attribute's properties. It contains the tabbed pages as follows: \par \f3\fs10 \par \pard{\pntext\f4\'B7\tab}{\*\pn\pnlvlblt\pnf4\pnindent0{\pntxtb\'B7}}\fi-200\li200\tx200\cf2\strike\f2\fs18 Definition Page\cf3\strike0\{linkID=190>main\}\cf1 - This is where the attribute's properties are defined;\lang3081\f3 @@ -537,10 +537,10 @@ FALSE 7 {\rtf1\ansi\ansicpg1252\deff0\deflang3081{\fonttbl{\f0\fswiss Arial;}{\f1\fnil Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\sb55\sa25\lang1040\b\f0\fs24 See Also \par \pard\sb25\sa25\cf1\b0\f1\fs10 -\par \pard\li60\sb25\sa25\strike\fs18 External Storage of Attributes\strike0\{linkID=220>main\} +\par \pard\li60\sb25\sa25\cf2\strike\fs18 External Storage of Attributes\cf3\strike0\{linkID=220>main\}\cf1 \par \pard\lang3081 \par } 190 @@ -633,11 +633,11 @@ FALSE -32 +33 {\rtf1\ansi\ansicpg1252\deff0\deflang1040{\fonttbl{\f0\fswiss\fcharset0 Arial;}{\f1\fswiss Arial;}{\f2\fnil Arial;}{\f3\fnil\fcharset2 Symbol;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\b\f0\fs24 External Storage of Attributes\cf1\b0\f1\fs16 -\par \pard\sb25\sa25\cf2\lang1033\strike\f0 Example\cf3\strike0\{linkID=230>example\}\cf1\tab\tab\lang1040\strike\f1 Creating the Business Model\strike0\{LinkID=70>main\}\{keepn\} \f0\fs18 +\par \pard\sb25\sa25\cf2\lang1033\strike\f0 Example\cf3\strike0\{linkID=230>example\}\cf1\tab\tab\cf2\lang1040\strike\f1 Creating the Business Model\cf3\strike0\{LinkID=70>main\}\{keepn\} \cf1\f0\fs18 \par \lang1033 The E\lang1040\f1 xternal \lang1033\f0 S\lang1040\f1 torage\lang1033\f0 option\lang1040\f1 \lang1033\f0 for \cf2\strike relational attributes\cf3\strike0\{linkTarget=RelationalAttributeTypes>main\}\cf1\lang1040\f1 \lang1033\f0 was introduced to resolve several shortcomings and issues in earlier versions of InstantObjects. These include the following: \par \f2\fs10 \par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\f0\fs18 the \lang1040\f1 inability to fully query the database from a SQL-enabled (non-IO) interface; @@ -663,6 +663,7 @@ \par \pard\sb25\sa25\lang1033\f0\fs18 IMPORTANT\lang1040\f1 NOTE\lang1033\f0 S: \par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\b\i External Storage and Class Persistence\b0\i0 - A cl\lang1040\f1 ass must \lang1033\f0 have its Persistence property set to\lang1040\f1 \i stored\i0 \lang1033\f0 if it is referred\lang1040\f1 \lang1033\f0 to by attributes that use\lang1040\f1 \i external \i0 storage. \lang1033\f0 A c\lang1040\f1 lass\lang1033\f0 defined with\lang1040\f1 \i embedded\i0 \lang1033\f0 Persistence may only be used by\lang1040\f1 \i embedded\i0 (the \lang1033\f0 InstantObjects \lang1040\f1 historical arrangement) part and parts attributes\lang1033\f0 ;\lang1040\f1 \par \cf3\lang1033\i\f0{\pntext\f3\'B7\tab}\{target=ExternalStorageandPersistenceBrokers\}\cf1\b External Storage and Persistence Brokers\b0\i0 - Currently (V2), the InstantObjects library requires the use of persistence brokers derived from TInstantSQLBroker to support \i external \i0 storage of attributes\lang1040\f1 .\lang1033\f0 Brokers that are derived from TInstantNavigationalBroker, including the BDE and some ADO brokers, DO NOT SUPPORT \i external \i0 storage of attributes and MUST NOT BE USED if the class model makes use of this feature.\lang1040\f1 +\par \lang1033\b\i\f0{\pntext\f3\'B7\tab}Performance Hint\b0\i0 - Currently (V2.0), the InstantObjects (IO) library does not create parent class indices for the linking tables in the database. A significant improvement in performance, therefore, can often be achieved by manually adding these indices (fields 'ParentClass' and 'ParentId', non-unique) to the linking tables for your external \cf2\strike container attributes\cf3\strike0\{linkTarget=RelationalAttributeTypes>main\}\cf1 . Remember that these manually added indices will be removed by each IO database build and probably after an evolve, so they will need to monitored and re-added as necessary. The need to add these indices manually will be eliminated after the introduction of Referential Integrity (RI) options to IO. This is expected to happen in the near future and will enhance both the integrity of data in and performance of the database for brokers that can implement RI. \lang1040\f1 \par \pard\sb25\sa25\f2\fs10 \par \pard\cf0\fs20 \par } @@ -715,10 +716,10 @@ FALSE 7 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Adding Business Rules \cf1\b0\fs16 -\par \strike Example 1\strike0\{linkID=250>example\}\tab\strike Example 2\strike0\{linkID=260>example\}\f1\tab\strike\f0 Creating the Business Model\strike0\{LinkID=70>main\}\{keepn\} -\par \pard\sb25\sa25\fs18 Validation rules and other business related behavior is added to your business classes by adding the required code plus additional methods and properties to the class. Validation rules and side effects of changing the value of an attribute are often added to the setter method of the corresponding property. Complete validation of business objects before they are stored to the database can be added by overriding the BeforeStore method of the class. New objects can be initialized by overriding the Initialize method. For a complete list of the virtual methods of \strike TInstantObject\strike0\{linkID=7380>main\}, please refer to the InstantObjects Reference Guide. +\par \cf2\strike Example 1\cf3\strike0\{linkID=250>example\}\cf1\tab\cf2\strike Example 2\cf3\strike0\{linkID=260>example\}\cf1\f1\tab\cf2\strike\f0 Creating the Business Model\cf3\strike0\{LinkID=70>main\}\{keepn\}\cf1 +\par \pard\sb25\sa25\fs18 Validation rules and other business related behavior is added to your business classes by adding the required code plus additional methods and properties to the class. Validation rules and side effects of changing the value of an attribute are often added to the setter method of the corresponding property. Complete validation of business objects before they are stored to the database can be added by overriding the BeforeStore method of the class. New objects can be initialized by overriding the Initialize method. For a complete list of the virtual methods of \cf2\strike TInstantObject\cf3\strike0\{linkID=7380>main\}\cf1 , please refer to the InstantObjects Reference Guide. \par \par } 250 @@ -735,9 +736,9 @@ FALSE 33 {\rtf1\ansi\ansicpg1252\deff0\deflang1040{\fonttbl{\f0\fnil Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fswiss Arial;}{\f3\fnil\fcharset0 Arial;}{\f4\fnil\fcharset0 Courier New;}} -{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} -\viewkind4\uc1\pard\b\f0\fs26 Example 1\b0\fs20 -\par \cf1\strike\f1\fs16 Adding Business Rules\strike0\f2\{LinkID=240>main\}\{keepn\} \cf0\f0\fs20 +{\colortbl ;\red0\green128\blue0;\red128\green0\blue0;\red0\green0\blue0;} +\viewkind4\uc1\pard\b\f0\fs24 Example 1\b0\fs20 +\par \cf1\strike\f1\fs16 Adding Business Rules\cf2\strike0\f2\{LinkID=240>main\}\{keepn\}\cf3 \cf0\f0\fs20 \par \f3 In InstantObjects you usually apply single-attribute business rules in the attribute's property setter method: \par \par \b\f4 procedure\b0 TAddress.SetPostalCode(\b const \b0 Value: \b string\b0 ); @@ -753,7 +754,7 @@ \par GetDefaultCityByPostalCode(Value); \par \b end\b0 ; \par \f0 -\par \f3 If you need to apply business rules that involve more than one attribute, instead, you often use the BeforeStore virtual method(see \cf2\strike Example 2\cf3\strike0\{linkID=260\}\cf0 ). +\par \f3 If you need to apply business rules that involve more than one attribute, instead, you often use the BeforeStore virtual method(see \cf1\strike Example 2\cf2\strike0\{linkID=260\}\cf0 ). \par \par When you code side effects, be aware that the property setters might be called more often than expected, for example when reading an object from an XML file or when you use the data-aware presentation layer. Here is an example: \par @@ -764,7 +765,7 @@ \par MaxShipDate := 0; \par \b end\b0 ; \par \f3 -\par The intent of this code is to reset MaxShipDate whenever MinShipDate changes, so that a user, in a hypothetical data-entry scenario, will have to re-enter a value for MaxShipDate. But things might not work always as expected. For example, SetMinShipDate might be called after SetMaxShipDate when streaming in an object from a XML file. The lesson here is: use the property setters and the BeforeStore method only to appy real business rules (like "MaxShipDate must be equal to or greater than MinShipDate"), and code data-entry rules (like "whenever a value for MinShipDate is entered, MaxShipDate should be reset") at the data-entry level (that is, not in the model classes). +\par The intent of this code is to reset MaxShipDate whenever MinShipDate changes, so that a user, in a hypothetical data-entry scenario, will have to re-enter a value for MaxShipDate. But things might not work always as expected. For example, SetMinShipDate might be called after SetMaxShipDate when streaming in an object from a XML file. The lesson here is: use the property setters and the BeforeStore method only to apply real business rules (like "MaxShipDate must be equal to or greater than MinShipDate"), and code data-entry rules (like "whenever a value for MinShipDate is entered, MaxShipDate should be reset") at the data-entry level (that is, not in the model classes). \par \par } 260 @@ -781,9 +782,9 @@ FALSE 30 {\rtf1\ansi\ansicpg1252\deff0\deflang1040{\fonttbl{\f0\fnil Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fswiss Arial;}{\f3\fnil\fcharset0 Arial;}{\f4\fnil\fcharset0 Courier New;}} -{\colortbl ;\red0\green0\blue0;} -\viewkind4\uc1\pard\b\f0\fs26 Example 2\b0\fs20 -\par \cf1\strike\f1\fs16 Adding Business Rules\strike0\f2\{LinkID=240>main\}\{keepn\} +{\colortbl ;\red0\green128\blue0;\red128\green0\blue0;\red0\green0\blue0;} +\viewkind4\uc1\pard\b\f0\fs24 Example 2\b0\fs20 +\par \cf1\strike\f1\fs16 Adding Business Rules\cf2\strike0\f2\{LinkID=240>main\}\{keepn\}\cf3 \par \cf0\f3\fs20 Business rules that involve more than one attribute are usually applied in BeforeStore, which gets called whenever the Store method is called to write an object (back) to the storage. Example: \par \par \b\f4 procedure \b0 TShipment.BeforeStore; @@ -826,10 +827,10 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil Arial;}{\f3\fnil\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\cf1\lang1040\b\f0\fs24 Building/Evolving the Business Model \b0\fs16 -\par \cf2\strike Creating the Business Model\cf3\strike0\{linkID=70>main\}\cf1\{keepn\} +\par \cf2\strike Creating the Business Model\cf3\strike0\{linkID=70>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\fs18 The final step in the modeling phase is to make the model physical in terms of storage for the objects. The required tables and indices have to be created from the business model. InstantObjects allows \lang1033\f1 the\lang1040\f0 use\lang1033\f1 of\lang1040\f0 various types of databases as storage for \lang1033\f1 the business class \lang1040\f0 objects\lang1033\f1 by\lang1040 using different brokers. \par \f2\fs10 -\par \f0\fs18 The Connection Manager \lang1033\f1 manages the\lang1040\f0 \f1 definition, \f0 creat\lang1033\f1 ion\lang1040\f0 \f1 and evolution of \lang1033 the\lang1040\f0 database. \lang1033\f1 It\lang1040\f0 \lang1033\f1 can be launched using the \cf3\{bmc ModelExplorerBuildDatabaseButton.gif\}\cf1 Build Database speed button\lang1040\f0 on the toolbar of the\lang1033\f1 \cf2\strike InstantObjects\lang1040\f0 Model Explorer\cf3\strike0\{linkID=90>main\}\f1 +\par \f0\fs18 The Connection Manager \lang1033\f1 manages the\lang1040\f0 \f1 definition, \f0 creat\lang1033\f1 ion\lang1040\f0 \f1 and evolution of \lang1033 the\lang1040\f0 database. \lang1033\f1 It\lang1040\f0 \lang1033\f1 can be launched using the \cf3\{bmc ModelExplorerBuildDatabaseButton.gif\} \cf1 Build Database speed button\lang1040\f0 on the toolbar of the\lang1033\f1 \cf2\strike InstantObjects\lang1040\f0 Model Explorer\cf3\strike0\{linkID=90>main\}\f1 \par \cf1\f2\fs10 \par \cf3\f1\fs18\{bmc ConnectionManager.gif\} \par \cf1\f2\fs10 @@ -868,9 +869,9 @@ FALSE 7 {\rtf1\ansi\deff0{\fonttbl{\f0\fswiss Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Creating the User Interface\cf1\b0\fs16 -\par \pard\sb25\tx1435\strike Group Topics\strike0\{linkID=290>nav\}\tab\strike Using InstantObjects\strike0\{linkID=50>main\}\cf0\b\fs24 \cf1\b0\fs16\{keepn\} +\par \pard\sb25\tx1435\cf2\strike Group Topics\cf3\strike0\{linkID=290>nav\}\cf1\tab\cf2\strike Using InstantObjects\cf3\strike0\{linkID=50>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\tx1435\fs18 The next phase in the development process is to create a user interface through which the business objects may interact with the user. This section explains the components that are involved in the creation of the user interface. \par \par } @@ -887,14 +888,14 @@ FALSE 11 -{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil\fcharset0 Arial;}} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\sb25\lang1040\b\f0\fs24 Creating the User Interface \cf1\b0\fs16 -\par \strike Creating the User Interface\strike0\{link\lang1033\f1 ID\lang1040\f0 =\lang1033\f1 280\lang1040\f0 >main\}\{keepn\} -\par \pard\keep\li95\sb25\sa25\strike\fs18 Persistence by RAD\strike0\{linkID=300>main\} -\par \strike The Connector\strike0\{linkID=310>main\} -\par \strike The Exposer\strike0\{linkID=320>main\} -\par \strike The Selector\strike0\{linkID=330>main\} +\par \cf2\strike Creating the User Interface\cf3\strike0\{link\lang1033\f1 ID\lang1040\f0 =\lang1033\f1 280\lang1040\f0 >main\}\{keepn\}\cf1 +\par \pard\keep\li95\sb25\sa25\cf2\strike\fs18 Persistence by RAD\cf3\strike0\{linkID=300>main\}\cf1 +\par \cf2\strike The Connector\cf3\strike0\{linkID=\f2 310\f0 >main\}\cf1 +\par \cf2\strike The Exposer\cf3\strike0\{linkID=\f2 320\f0 >main\}\cf1 +\par \cf2\strike The Selector\cf3\strike0\{linkID=330>main\}\cf1 \par \par \par } @@ -914,7 +915,7 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Persistence by RAD \cf1\b0\fs16 -\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\cf1\{keepn\} +\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\fs18 When InstantObjects has been installed in your Delphi environment, a set of components is available on the InstantObjects tab of the Delphi component palette. \par \cf3\{bmc InstantObjectsPalette.gif\}\cf1 \par Applications can be built with InstantObjects using the same RAD approach used when building traditional database applications in Delphi. InstantObjects allows you to use standard VCL data-aware controls with your persistent business objects. The InstantObjects components are used to connect to the database and to make business objects available in the user interface of the application\f1 .\f0 @@ -936,13 +937,13 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 The Connector \cf1\b0\fs16 -\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\cf1\{keepn\} +\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\fs18 In order for your application to use the database \lang1033\f1 for\lang1040\f0 object storage, you must use a connector component. The connector acts as a gateway between your application and the database\f1 (by means of an internal component called the broker) and \f0 manag\lang1033\f1 es\lang1040\f0 all the objects that are stored to and retrieved from the database. A connector component for each type of data access layer that \lang1033\f1 has been installed from\lang1040\f0 InstantObjects is available on the component palette. A connector is attached to a database by assigning a connection component to its Connection \f1 (or equivalent) \f0 property. Each connector component supports its own connection type\f1 . For example:\f0 \par \f2\fs10 \par \pard\sb25\sa25\tx1980\tx4800\b\f0\fs18 Access type\tab Connector type\tab\f1 Type of \f0 Connection\b0 -\par ADO\tab\cf2\strike TInstantADOConnector\cf1\strike0\{linkID=1900>main\}\tab TADOConnection -\par BDE\tab\cf2\strike TInstantBDEConnector\cf1\strike0\{linkID=2560>main\}\tab TDatabase -\par IBX\tab\cf2\strike TInstantIBXConnector\cf1\strike0\{linkID=6950>main\}\tab TIBDatabase +\par ADO\tab\cf2\strike TInstantADOConnector\cf3\strike0\{linkID=1900>main\}\cf1\tab TADOConnection +\par BDE\tab\cf2\strike TInstantBDEConnector\cf3\strike0\{linkID=2560>main\}\cf1\tab TDatabase +\par IBX\tab\cf2\strike TInstantIBXConnector\cf3\strike0\{linkID=6950>main\}\cf1\tab TIBDatabase \par \f1 D\f0 BX\tab\cf0 TInstant\f1 D\f0 BXConnector\cf1\tab TSQLConnection \par \f1 XML\tab\cf0\f0 TInstantX\f1 ML\f0 Connector\cf1\tab TXMLFilesAccessor \par \pard\f2\fs10 @@ -969,14 +970,14 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\cf1\lang1040\b\f0\fs24 The Exposer \b0\fs16 -\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\cf1\{keepn\} -\par \pard\sb25\sa25\strike\fs18 TInstantExposer\strike0\{linkID=6440>main\} is a dataset component that maps objects to the user interface of your application. +\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\{keepn\}\cf1 +\par \pard\sb25\sa25\cf2\strike\fs18 TInstantExposer\cf3\strike0\{linkID=6440>main\}\cf1 is a dataset component that maps objects to the user interface of your application. \par Attributes defined in the business model are accessed through properties. Properties that are published can be accessed by data-aware controls via this component. In addition, the content of container attributes can be accessed too. The exposer component maps the published properties of objects to fields in a dataset. The objects being exposed are represented as rows in the dataset. -\par To expose an object, it must be assigned to the \strike Subject\strike0\{linkID=5150>main\} property of a \strike TInstantExposer\strike0\{linkID=6440>main\}. To expose multiple objects contained within another object, assign the main object to the Subject property and enter content mode by changing the \strike Mode\strike0\{linkID=5020>main\} property from amObject to amContent. If the exposed class has no default container, specify the desired container in the property \strike ContainerName\strike0\{linkID=6550>main\}. Specify the class of the exposed\lang1033\f1 , contained\lang1040\f0 object(s) in the property \strike ObjectClassName\strike0\{linkID=6620>main\}. -\par By default, an exposer will make all simple properties of each exposed object as well as any related object available through fields in the dataset. Every field will have a \f1 F\f0 ield\f1 N\f0 ame matching the property it represents. For related objects, the fieldname will be the complete path to the property using regular dot notation. The property \strike FieldOptions\strike0\{linkID=4930>main\} and the event \strike OnIncludeField\strike0\{linkID=5560>main\} allow you to limit or extend the number fields to include. +\par To expose an object, it must be assigned to the \cf2\strike Subject\cf3\strike0\{linkID=5150>main\}\cf1 property of a \cf2\strike TInstantExposer\cf3\strike0\{linkID=6440>main\}\cf1 . To expose multiple objects contained within another object, assign the main object to the Subject property and enter content mode by changing the \cf2\strike Mode\cf3\strike0\{linkID=5020>main\}\cf1 property from amObject to amContent. If the exposed class has no default container, specify the desired container in the property \cf2\strike ContainerName\cf3\strike0\{linkID=6550>main\}\cf1 . Specify the class of the exposed\lang1033\f1 , contained\lang1040\f0 object(s) in the property \cf2\strike ObjectClassName\cf3\strike0\{linkID=6620>main\}\cf1 . +\par By default, an exposer will make all simple properties of each exposed object as well as any related object available through fields in the dataset. Every field will have a \f1 F\f0 ield\f1 N\f0 ame matching the property it represents. For related objects, the fieldname will be the complete path to the property using regular dot notation. The property \cf2\strike FieldOptions\cf3\strike0\{linkID=4930>main\}\cf1 and the event \cf2\strike OnIncludeField\cf3\strike0\{linkID=5560>main\}\cf1 allow you to limit or extend the number fields to include. \par Container attributes of exposed objects are automatically recognized by the exposer and \lang1033\f1 are \lang1040\f0 represented as nested datasets within the exposer. -\par Exposers can be linked together in master/detail relation\f1 ships\f0 . To link one exposer to another, assign the master exposer to the DataSet property of a TDataSource and assign the TDataSource to the \strike MasterSource\strike0\{linkID=6570>main\} property of the detail exposer. The Subject of the detail exposer will be set to the current object of the master exposer\lang1033\f1 and updated\lang1040\f0 whenever this changes. If you want the detail exposer to expose an object that is related to the current object of the master exposer instead, simply specify the desired property path in \strike MasterProperty\strike0\{linkID=6560>main\}. -\par \strike TInstantExposer\strike0\{linkID=6440>main\} is not limited to exposing \strike TInstantObject\strike0\{linkID=7380>main\} descendants. Any object with published propertied can be exposed. The content of standard VCL containers like TList, TObjectList and TCollection can be exposed in content mode. +\par Exposers can be linked together in master/detail relation\f1 ships\f0 . To link one exposer to another, assign the master exposer to the DataSet property of a TDataSource and assign the TDataSource to the \cf2\strike MasterSource\cf3\strike0\{linkID=6570>main\}\cf1 property of the detail exposer. The Subject of the detail exposer will be set to the current object of the master exposer\lang1033\f1 and updated\lang1040\f0 whenever this changes. If you want the detail exposer to expose an object that is related to the current object of the master exposer instead, simply specify the desired property path in \cf2\strike MasterProperty\cf3\strike0\{linkID=6560>main\}\cf1 . +\par \cf2\strike TInstantExposer\cf3\strike0\{linkID=6440>main\}\cf1 is not limited to exposing \cf2\strike TInstantObject\cf3\strike0\{linkID=7380>main\}\cf1 descendants. Any object with published propertied can be exposed. The content of standard VCL containers like TList, TObjectList and TCollection can be exposed in content mode. \par \par } 330 @@ -995,8 +996,8 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fmodern Courier New;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 The Selector \cf1\b0\fs16 -\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\cf1\{keepn\} -\par \pard\sb25\sa25\fs18 The \strike TInstantSelector\strike0\{linkID=10190>main\} is a dataset component \lang1033\f1 that \lang1040\f0 allows you to select objects from the database and optionally expose them in the user interface. +\par \cf2\strike Creating the User Interface\cf3\strike0\{linkID=280>main\}\{keepn\}\cf1 +\par \pard\sb25\sa25\fs18 The \cf2\strike TInstantSelector\cf3\strike0\{linkID=10190>main\}\cf1 is a dataset component \lang1033\f1 that \lang1040\f0 allows you to select objects from the database and optionally expose them in the user interface. \par To select objects from the database, a command must be specified \lang1033\f1 in\lang1040\f0 the Command property. The syntax of this command\f1 (called an IQL command, from Instant Query Language) \f0 is somewhat similar to an SQL SELECT-statement\f1 , \f0 but instead of tables and columns, you specify classes and attributes: \par \pard\keep\f2 \par SELECT [DISTINCT] *|<Attribute> @@ -1046,10 +1047,10 @@ FALSE 7 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Programming with Persistent Objects\cf1\b0\fs16 -\par \pard\sb25\tx1435\strike Group Topics\strike0\{linkID=350>nav\}\tab\strike Using InstantObjects\strike0\{linkID=50>main\}\f1 \cf0\b\f0\fs24 \cf1\b0\fs16\{keepn\} -\par \pard\sb25\sa25\tx1435\fs18 The driving force in InstantObjects based applications \lang1033\f1 is\lang1040\f0 the persistent classes \lang1033\f1 that\lang1040\f0 contain the business logic. These business classes all descend from the fundamental \strike TInstantObject\strike0\{linkID=7380>main\} class. This section covers aspects of working directly with the business classes of \lang1033\f1 an\lang1040\f0 application. +\par \pard\sb25\tx1435\cf2\strike Group Topics\cf3\strike0\{linkID=350>nav\}\cf1\tab\cf2\strike Using InstantObjects\cf3\strike0\{linkID=50>main\}\{keepn\}\cf1 +\par \pard\sb25\sa25\tx1435\fs18 The driving force in InstantObjects based applications \lang1033\f1 is\lang1040\f0 the persistent classes \lang1033\f1 that\lang1040\f0 contain the business logic. These business classes all descend from the fundamental \cf2\strike TInstantObject\cf3\strike0\{linkID=7380>main\}\cf1 class. This section covers aspects of working directly with the business classes of \lang1033\f1 an\lang1040\f0 application. \par \par } 350 @@ -1068,11 +1069,11 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\sb25\lang1040\b\f0\fs24 Programming with Persistent Objects \cf1\b0\fs16 -\par \cf2\strike Programming with Persistent Objects\cf3\strike0\{linkID=340>main\}\cf1\{keepn\} -\par \pard\keep\li95\sb25\sa25\strike\fs18 Creating New Objects\strike0\{linkID=360>main\} -\par \strike Retrieving Existing Objects\strike0\{linkID=380>main\} -\par \strike Associating Objects\strike0\{linkID=420>main\} -\par \strike\f1 Using t\f0 he \f1 InstantQuery\strike0\f0\{linkID=440>main\} +\par \cf2\strike Programming with Persistent Objects\cf3\strike0\{linkID=340>main\}\{keepn\}\cf1 +\par \pard\keep\li95\sb25\sa25\cf2\strike\fs18 Creating New Objects\cf3\strike0\{linkID=360>main\}\cf1 +\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\cf1 +\par \cf2\strike Associating Objects\cf3\strike0\{linkID=420>main\}\cf1 +\par \cf2\strike\f1 Using t\f0 he \f1 InstantQuery\cf3\strike0\f0\{linkID=440>main\}\cf1 \par \par } 360 @@ -1089,9 +1090,9 @@ FALSE 10 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\cf1\lang1040\b\f0\fs24 Creating New Objects\b0\fs16 -\par \pard\sb25\tx1435\strike Example 1\strike0\{linkID=370>example\}\tab\strike Programming with Persistent Objects\strike0\{linkID=340>main\}\{keepn\} +\par \pard\sb25\tx1435\cf2\strike Example 1\cf3\strike0\{linkID=370>example\}\cf1\tab\cf2\strike Programming with Persistent Objects\cf3\strike0\{linkID=340>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\tx1435\fs18 Business objects are created just like any other object. The Create constructor of the class creates a new instance of the class. \par The constructor can be called with an optional Connector parameter. This connector specifies the database in which to make the object persistent. If no connector is specified, the default connector will be used. \par To make an object persistent, call its Store method. Only instances of classes declared \lang1033\f1 with\lang1040\f0 \lang1033\f1 a \lang1040\f0 persisten\lang1033\f1 ce property of \i stored\lang1040\f0 \i0 in the business model can be \lang1033\f1 S\lang1040\f0 tored. @@ -1114,7 +1115,7 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Courier New;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Example 1 \cf1\b0\fs16 -\par \cf2\strike Creating New Objects\cf3\strike0\{linkID=360>main\}\cf1\{keepn\} +\par \cf2\strike Creating New Objects\cf3\strike0\{linkID=360>main\}\{keepn\}\cf1 \par \pard\keep\f1\fs18 \par \b var\b0 \par Person: TPerson @@ -1144,13 +1145,13 @@ FALSE 10 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fnil Arial;}{\f3\fnil\fcharset2 Symbol;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Retrieving Existing Objects\cf1\b0\fs16 -\par \pard\sb25\tx1435\tx2875\strike Example 1\strike0\{linkID=390>example\}\tab\strike Example 2\strike0\{linkID=400>example\}\tab\strike Example \lang1033\f1 3\lang1040\strike0\f0\{linkID=410>example\}\lang1033\f1\tab\tab\lang1040\strike\f0 Programming with Persistent Objects\strike0\{linkID=340>main\}\{keepn\} +\par \pard\sb25\tx1435\tx2875\cf2\strike Example 1\cf3\strike0\{linkID=390>example\}\cf1\tab\cf2\strike Example 2\cf3\strike0\{linkID=400>example\}\cf1\tab\cf2\strike Example \lang1033\f1 3\cf3\lang1040\strike0\f0\{linkID=410>example\}\cf1\lang1033\f1\tab\tab\cf2\lang1040\strike\f0 Programming with Persistent Objects\cf3\strike0\{linkID=340>main\}\{keepn\}\cf1 \par \pard\sb25\sa25\tx1435\tx2875\fs18 Objects that have been stored to the database can be retrieved into memory \lang1033\f1 by using any of the following techniques: -\par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\tx2875 If the Id of the object is known \lang1040\f0 the Retrieve constructor\lang1033\f1 can be used\lang1040\f0 . An optional connector through which the object shall be retrieved can be specified. If no connector is specified, the default connector is used. If the object already exists in memory, the existing object is returned. If the object is not found, the constructor returns nil.\lang1033\f1 See \strike example 1\lang1040\strike0\f0\fs16\{linkID=390>example\}\lang1033\f1\fs18 .\lang1040\f0 +\par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\tx2875 If the Id of the object is known \lang1040\f0 the Retrieve constructor\lang1033\f1 can be used\lang1040\f0 . An optional connector through which the object shall be retrieved can be specified. If no connector is specified, the default connector is used. If the object already exists in memory, the existing object is returned. If the object is not found, the constructor returns nil.\lang1033\f1 See \cf2\strike example 1\cf3\lang1040\strike0\f0\fs16\{linkID=390>example\}\cf1\lang1033\f1\fs18 .\lang1040\f0 \par \pard\sb25\sa25\f2\fs10 -\par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\tx2875\f0\fs18 If the Id of the object is not known or multiple objects meeting a certain criteria \lang1033\f1 need to\lang1040\f0 be retrieved, a \lang1033\strike\f1 S\lang1040\f0 elector\strike0\fs16\{linkID=330>main\}\fs18 \lang1033\f1 or an \lang1040\strike InstantQuery\strike0\f0\fs16\{linkID=440>main\}\lang1033\f1 \lang1040\f0\fs18 can be used\lang1033\f1 . See \strike example 2\lang1040\strike0\f0\fs16\{linkID=400>example\}\lang1033\f1\fs18 and \strike example 3\lang1040\strike0\f0\fs16\{linkID=410>example\}\lang1033\f1\fs18 .\lang1040\f0 +\par \pard{\pntext\f3\'B7\tab}{\*\pn\pnlvlblt\pnf3\pnindent0{\pntxtb\'B7}}\fi-200\li200\sb25\sa25\tx200\tx2875\f0\fs18 If the Id of the object is not known or multiple objects meeting a certain criteria \lang1033\f1 need to\lang1040\f0 be retrieved, a \cf2\lang1033\strike\f1 S\lang1040\f0 elector\cf3\strike0\fs16\{linkID=330>main\}\cf1\fs18 \lang1033\f1 or an \cf2\lang1040\strike InstantQuery\cf3\strike0\f0\fs16\{linkID=440>main\}\cf1\lang1033\f1 \lang1040\f0\fs18 can be used\lang1033\f1 . See \cf2\strike example 2\cf3\lang1040\strike0\f0\fs16\{linkID=400>example\}\cf1\lang1033\f1\fs18 and \cf2\strike example 3\cf3\lang1040\strike0\f0\fs16\{linkID=410>example\}\cf1\lang1033\f1\fs18 .\lang1040\f0 \par \pard\sb25\sa25\tx200\tx2875\f2\fs10 \par } 390 @@ -1169,7 +1170,7 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Courier New;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Example 1 \cf1\b0\fs16 -\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\cf1\{keepn\} +\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\{keepn\}\cf1 \par \pard\keep\f1\fs18 \par \b var\b0 \par Person: TPerson; @@ -1199,7 +1200,7 @@ {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fmodern Courier New;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Example 2 \cf1\b0\fs16 -\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\cf1\{keepn\} +\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\{keepn\}\cf1 \par \pard\keep\f1\fs18 \par \b var\b0 \par I: Integer; @@ -1238,7 +1239,7 @@ {\rtf1\ansi\ansicpg1252\deff0\deflang3081{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fmodern Courier New;}{\f3\fnil\fcharset0 Courier New;}{\f4\fmodern\fcharset0 Courier New;}{\f5\fnil Arial;}} {\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Example \lang1033\f1 3\lang1040\f0 \cf1\b0\fs16 -\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\cf1\{keepn\} +\par \cf2\strike Retrieving Existing Objects\cf3\strike0\{linkID=380>main\}\{keepn\}\cf1 \par \pard\keep\f2\fs18 \par \b var\b0 \par I: Integer; @@ -1274,9 +1275,9 @@ FALSE 9 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 Associating Obj... [truncated message content] |
From: <na...@us...> - 2006-06-08 02:58:11
|
Revision: 683 Author: nandod Date: 2006-06-07 08:34:26 -0700 (Wed, 07 Jun 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=683&view=rev Log Message: ----------- * docs and res files updated for 2.0 RC 1. Modified Paths: -------------- trunk/Docs/Changes.txt trunk/Docs/Install.txt trunk/Readme1st.txt trunk/ReleaseTools/InstantVersion.res trunk/Source/Brokers/ADO/D2005/DclIOADO.res trunk/Source/Brokers/ADO/D2005/IOADO.res trunk/Source/Brokers/ADO/D2006/DclIOADO.res trunk/Source/Brokers/ADO/D2006/IOADO.res trunk/Source/Brokers/ADO/D5/DclIOADO_D5.res trunk/Source/Brokers/ADO/D5/IOADO_D5.res trunk/Source/Brokers/ADO/D6/DclIOADO.res trunk/Source/Brokers/ADO/D6/IOADO.res trunk/Source/Brokers/ADO/D7/DclIOADO.res trunk/Source/Brokers/ADO/D7/IOADO.res trunk/Source/Brokers/ADS/D5/DclIOADS_D5.res trunk/Source/Brokers/ADS/D5/ioads_D5.res trunk/Source/Brokers/BDE/D2005/DclIOBDE.res trunk/Source/Brokers/BDE/D2005/IOBDE.res trunk/Source/Brokers/BDE/D2006/DclIOBDE.res trunk/Source/Brokers/BDE/D2006/IOBDE.res trunk/Source/Brokers/BDE/D5/DclIOBDE_D5.res trunk/Source/Brokers/BDE/D5/Iobde_D5.res trunk/Source/Brokers/BDE/D6/DclIOBDE.res trunk/Source/Brokers/BDE/D6/IOBDE.res trunk/Source/Brokers/BDE/D7/DclIOBDE.res trunk/Source/Brokers/BDE/D7/IOBDE.res trunk/Source/Brokers/DBISAM/D6/DclDBISAM.res trunk/Source/Brokers/DBISAM/D6/IODBISAM.res trunk/Source/Brokers/DBISAM/D7/DclDBISAM.res trunk/Source/Brokers/DBISAM/D7/IODBISAM.res trunk/Source/Brokers/DBX/D2005/DclIODBX.res trunk/Source/Brokers/DBX/D2005/IODBX.res trunk/Source/Brokers/DBX/D2006/DclIODBX.res trunk/Source/Brokers/DBX/D2006/IODBX.res trunk/Source/Brokers/DBX/D6/DclIODBX.res trunk/Source/Brokers/DBX/D6/IODBX.res trunk/Source/Brokers/DBX/D7/DclIODBX.res trunk/Source/Brokers/DBX/D7/IODBX.res trunk/Source/Brokers/DBX/K3/DclIODBX.res trunk/Source/Brokers/DBX/K3/IODBX.res trunk/Source/Brokers/FlashFiler/D5/DclIOff_D5.res trunk/Source/Brokers/FlashFiler/D5/ioff_D5.res trunk/Source/Brokers/IBX/D2005/DclIOIBX.res trunk/Source/Brokers/IBX/D2005/IOIBX.res trunk/Source/Brokers/IBX/D2006/DclIOIBX.res trunk/Source/Brokers/IBX/D2006/IOIBX.res trunk/Source/Brokers/IBX/D5/DclIOIBX_D5.res trunk/Source/Brokers/IBX/D5/Ioibx_D5.res trunk/Source/Brokers/IBX/D6/DclIOIBX.res trunk/Source/Brokers/IBX/D6/IOIBX.res trunk/Source/Brokers/IBX/D7/DclIOIBX.res trunk/Source/Brokers/IBX/D7/IOIBX.res trunk/Source/Brokers/NexusDb/D2005/DclIONexusDB.res trunk/Source/Brokers/NexusDb/D2005/IONexusDB.res trunk/Source/Brokers/NexusDb/D2006/DclIONexusDB.res trunk/Source/Brokers/NexusDb/D2006/IONexusDB.res trunk/Source/Brokers/NexusDb/D5/DclIONexusDB_D5.res trunk/Source/Brokers/NexusDb/D5/IONexusDB_D5.res trunk/Source/Brokers/NexusDb/D6/DclIONexusDB.res trunk/Source/Brokers/NexusDb/D6/IONexusDB.res trunk/Source/Brokers/NexusDb/D7/DclIONexusDB.res trunk/Source/Brokers/NexusDb/D7/IONexusDB.res trunk/Source/Brokers/UIB/D2005/DclIOUIB.res trunk/Source/Brokers/UIB/D2005/IOUIB.res trunk/Source/Brokers/UIB/D2006/DclIOUIB.res trunk/Source/Brokers/UIB/D2006/IOUIB.res trunk/Source/Brokers/UIB/D5/DclIOUIB_D5.res trunk/Source/Brokers/UIB/D5/IOUIB_D5.res trunk/Source/Brokers/UIB/D6/DclIOUIB.res trunk/Source/Brokers/UIB/D6/IOUIB.res trunk/Source/Brokers/UIB/D7/DclIOUIB.res trunk/Source/Brokers/UIB/D7/IOUIB.res trunk/Source/Brokers/XML/D2005/DclIOXML.res trunk/Source/Brokers/XML/D2005/IOXML.res trunk/Source/Brokers/XML/D2006/DclIOXML.res trunk/Source/Brokers/XML/D2006/IOXML.res trunk/Source/Brokers/XML/D5/DclIOXML_D5.res trunk/Source/Brokers/XML/D5/Ioxml_D5.res trunk/Source/Brokers/XML/D6/DclIOXML.res trunk/Source/Brokers/XML/D6/IOXML.res trunk/Source/Brokers/XML/D7/DclIOXML.res trunk/Source/Brokers/XML/D7/IOXML.res trunk/Source/Brokers/XML/k3/DclIOXML.res trunk/Source/Brokers/XML/k3/IOXML.res trunk/Source/Brokers/ZeosDBO/D2005/DclIOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D2005/IOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D2006/DclIOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D2006/IOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D5/DclIOZeosDBO_D5.res trunk/Source/Brokers/ZeosDBO/D5/IOZeosDBO_D5.res trunk/Source/Brokers/ZeosDBO/D6/DclIOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D6/IOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D7/DclIOZeosDBO.res trunk/Source/Brokers/ZeosDBO/D7/IOZeosDBO.res trunk/Source/Catalogs/IBFb/D2005/IOIBFbCatalog.res trunk/Source/Catalogs/IBFb/D2006/IOIBFbCatalog.res trunk/Source/Catalogs/IBFb/D5/IOIBFbCatalog_D5.res trunk/Source/Catalogs/IBFb/D6/IOIBFbCatalog.res trunk/Source/Catalogs/IBFb/D7/IOIBFbCatalog.res trunk/Source/Catalogs/IBFb/K3/IOIBFbCatalog.res trunk/Source/Catalogs/MSSql/D2005/IOMSSqlCatalog.res trunk/Source/Catalogs/MSSql/D2006/IOMSSqlCatalog.res trunk/Source/Catalogs/MSSql/D5/IOMSSqlCatalog_D5.res trunk/Source/Catalogs/MSSql/D6/IOMSSqlCatalog.res trunk/Source/Catalogs/MSSql/D7/IOMSSqlCatalog.res trunk/Source/Catalogs/MSSql/K3/IOMSSqlCatalog.res trunk/Source/Core/D2005/IOCore.res trunk/Source/Core/D2006/IOCore.res trunk/Source/Core/D5/IOCore_D5.res trunk/Source/Core/D6/IOCore.res trunk/Source/Core/D7/IOCore.res trunk/Source/Core/K3/IOCore.res trunk/Source/Design/D2005/DclIOCore.res trunk/Source/Design/D2006/DclIOCore.res trunk/Source/Design/D5/DclIOCore_D5.res trunk/Source/Design/D6/DclIOCore.res trunk/Source/Design/D7/DclIOCore.res trunk/Source/Design/K3/DclIOCore.res Modified: trunk/Docs/Changes.txt =================================================================== --- trunk/Docs/Changes.txt 2006-05-31 06:45:28 UTC (rev 682) +++ trunk/Docs/Changes.txt 2006-06-07 15:34:26 UTC (rev 683) @@ -1,7 +1,7 @@ VERSION HISTORY --------------- -Version 2.0 RC 1 (1.9.1.4) (2006-05-31) +Version 2.0 RC 1 (1.9.2.1) (2006-05-07) - Help file has been improved. Modified: trunk/Docs/Install.txt =================================================================== --- trunk/Docs/Install.txt 2006-05-31 06:45:28 UTC (rev 682) +++ trunk/Docs/Install.txt 2006-06-07 15:34:26 UTC (rev 683) @@ -1,10 +1,8 @@ ------------------------------------------------------------------ - InstantObjects 2.0 Beta 1 (1.9.1.1) for Delphi, Kylix, FPC + InstantObjects 2.0 for Delphi, Kylix, FPC - Mozilla Public License 1.1 Edition - November 2005 release - + Mozilla Public License 1.1 Based on Seleqt InstantObjects. Portions created by Seleqt are Copyright (c) 2001-2003 Seleqt. Other portions and changes are Copyright (c) the authors. Modified: trunk/Readme1st.txt =================================================================== --- trunk/Readme1st.txt 2006-05-31 06:45:28 UTC (rev 682) +++ trunk/Readme1st.txt 2006-06-07 15:34:26 UTC (rev 683) @@ -1,10 +1,8 @@ ------------------------------------------------------------------ - InstantObjects 2.0 Beta 2 (1.9.2.1) for Delphi, Kylix, FPC + InstantObjects 2.0 for Delphi, Kylix, FPC Mozilla Public License 1.1 Edition - January 2006 release - Based on Seleqt InstantObjects. Portions created by Seleqt are Copyright (c) 2001-2003 Seleqt. Other portions and changes are Copyright (c) the authors. Modified: trunk/ReleaseTools/InstantVersion.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D2005/DclIOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D2005/IOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D2006/DclIOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D2006/IOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D5/DclIOADO_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D5/IOADO_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D6/DclIOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D6/IOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D7/DclIOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADO/D7/IOADO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADS/D5/DclIOADS_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ADS/D5/ioads_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D2005/DclIOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D2005/IOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D2006/DclIOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D2006/IOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D5/DclIOBDE_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D5/Iobde_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D6/DclIOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D6/IOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D7/DclIOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/BDE/D7/IOBDE.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBISAM/D6/DclDBISAM.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBISAM/D6/IODBISAM.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBISAM/D7/DclDBISAM.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBISAM/D7/IODBISAM.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D2005/DclIODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D2005/IODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D2006/DclIODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D2006/IODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D6/DclIODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D6/IODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D7/DclIODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/D7/IODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/K3/DclIODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/DBX/K3/IODBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/FlashFiler/D5/DclIOff_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/FlashFiler/D5/ioff_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D2005/DclIOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D2005/IOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D2006/DclIOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D2006/IOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D5/DclIOIBX_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D5/Ioibx_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D6/DclIOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D6/IOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D7/DclIOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/IBX/D7/IOIBX.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D2005/DclIONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D2005/IONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D2006/DclIONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D2006/IONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D5/DclIONexusDB_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D5/IONexusDB_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D6/DclIONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D6/IONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D7/DclIONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/NexusDb/D7/IONexusDB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D2005/DclIOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D2005/IOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D2006/DclIOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D2006/IOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D5/DclIOUIB_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D5/IOUIB_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D6/DclIOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D6/IOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D7/DclIOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/UIB/D7/IOUIB.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D2005/DclIOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D2005/IOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D2006/DclIOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D2006/IOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D5/DclIOXML_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D5/Ioxml_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D6/DclIOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D6/IOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D7/DclIOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/D7/IOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/k3/DclIOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/XML/k3/IOXML.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D2005/DclIOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D2005/IOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D2006/DclIOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D2006/IOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D5/DclIOZeosDBO_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D5/IOZeosDBO_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D6/DclIOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D6/IOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D7/DclIOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Brokers/ZeosDBO/D7/IOZeosDBO.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/IBFb/D2005/IOIBFbCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/IBFb/D2006/IOIBFbCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/IBFb/D5/IOIBFbCatalog_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/IBFb/D6/IOIBFbCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/IBFb/D7/IOIBFbCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/IBFb/K3/IOIBFbCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/MSSql/D2005/IOMSSqlCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/MSSql/D2006/IOMSSqlCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/MSSql/D5/IOMSSqlCatalog_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/MSSql/D6/IOMSSqlCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/MSSql/D7/IOMSSqlCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Catalogs/MSSql/K3/IOMSSqlCatalog.res =================================================================== (Binary files differ) Modified: trunk/Source/Core/D2005/IOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Core/D2006/IOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Core/D5/IOCore_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Core/D6/IOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Core/D7/IOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Core/K3/IOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Design/D2005/DclIOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Design/D2006/DclIOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Design/D5/DclIOCore_D5.res =================================================================== (Binary files differ) Modified: trunk/Source/Design/D6/DclIOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Design/D7/DclIOCore.res =================================================================== (Binary files differ) Modified: trunk/Source/Design/K3/DclIOCore.res =================================================================== (Binary files differ) |
From: <na...@us...> - 2006-06-08 02:43:54
|
Revision: 684 Author: nandod Date: 2006-06-07 08:39:31 -0700 (Wed, 07 Jun 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=684&view=rev Log Message: ----------- * 2.0 RC1 tag. Added Paths: ----------- tags/IO2_RC1/ Copied: tags/IO2_RC1 (from rev 683, trunk) |
From: <sr...@us...> - 2006-05-30 06:52:52
|
Revision: 681 Author: srmitch Date: 2006-05-29 23:52:37 -0700 (Mon, 29 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=681&view=rev Log Message: ----------- Two fixes and a doc update: 1. Fix for # 1496971 Bug In Model Explorer Setting Index and Required properties. Applied to TInstantAttributeEditorForm.SaveData in InstantAttributeEditor.pas. 2. Fix for AV in Model Explorer when setting Method access properties for container attributes. Applied to TInstantCodeAttributeTailor.DeleteMethods in InstantCode.pas. 3. Updated Changes.txt file for the bug fix above. Modified Paths: -------------- trunk/Docs/Changes.txt trunk/Source/Core/InstantCode.pas trunk/Source/Design/InstantAttributeEditor.pas Modified: trunk/Docs/Changes.txt =================================================================== --- trunk/Docs/Changes.txt 2006-05-29 03:23:15 UTC (rev 680) +++ trunk/Docs/Changes.txt 2006-05-30 06:52:37 UTC (rev 681) @@ -5,6 +5,9 @@ - Help file has been improved. +- Bug fix for # 1496971 Bug In Model Explorer Setting Index and + Required properties. + - Bug fix for # 1475841. "TInstantContainer.Sort error if empty". - Bug fix for # 1475982. Rebuilding a Firebird database creates Modified: trunk/Source/Core/InstantCode.pas =================================================================== --- trunk/Source/Core/InstantCode.pas 2006-05-29 03:23:15 UTC (rev 680) +++ trunk/Source/Core/InstantCode.pas 2006-05-30 06:52:37 UTC (rev 681) @@ -3440,11 +3440,17 @@ procedure TInstantCodeAttributeTailor.DeleteMethods; begin DeleteItem(FAddMethod); + FAddMethod := nil; DeleteItem(FClearMethod); + FClearMethod := nil; DeleteItem(FDeleteMethod); + FDeleteMethod := nil; DeleteItem(FIndexOfMethod); + FIndexOfMethod := nil; DeleteItem(FInsertMethod); + FInsertMethod := nil; DeleteItem(FRemoveMethod); + FRemoveMethod := nil; end; destructor TInstantCodeAttributeTailor.Destroy; Modified: trunk/Source/Design/InstantAttributeEditor.pas =================================================================== --- trunk/Source/Design/InstantAttributeEditor.pas 2006-05-29 03:23:15 UTC (rev 680) +++ trunk/Source/Design/InstantAttributeEditor.pas 2006-05-30 06:52:37 UTC (rev 681) @@ -429,38 +429,58 @@ // SubjectExposer.PostChanges does not overwrite our changes. procedure TInstantAttributeEditorForm.SaveData; - procedure SaveOptions; + function SetChangedField(const AFieldName: String; ACheckBoxChecked: Boolean): + Boolean; begin - SubjectExposer.FieldByName('IsIndexed').AsBoolean := - OptionIndexedCheckBox.Checked; - SubjectExposer.FieldByName('IsRequired').AsBoolean := - OptionRequiredCheckBox.Checked; - SubjectExposer.FieldByName('ReadOnly').AsBoolean := - OptionReadOnlyCheckBox.Checked; - SubjectExposer.FieldByName('IsDefault').AsBoolean := - OptionDefaultCheckBox.Checked; + Result := False; + if SubjectExposer.FieldByName(AFieldName).AsBoolean <> + ACheckBoxChecked then + begin + SubjectExposer.FieldByName(AFieldName).AsBoolean := + ACheckBoxChecked; + Result := True; + end; end; - procedure SaveMethods; + function SaveOptions: Boolean; begin - SubjectExposer.FieldByName('IncludeAddMethod').AsBoolean := - MethodAddCheckBox.Checked; - SubjectExposer.FieldByName('IncludeRemoveMethod').AsBoolean := - MethodRemoveCheckBox.Checked; - SubjectExposer.FieldByName('IncludeInsertMethod').AsBoolean := - MethodInsertCheckBox.Checked; - SubjectExposer.FieldByName('IncludeDeleteMethod').AsBoolean := - MethodDeleteCheckBox.Checked; - SubjectExposer.FieldByName('IncludeIndexOfMethod').AsBoolean := - MethodIndexOfCheckBox.Checked; - SubjectExposer.FieldByName('IncludeClearMethod').AsBoolean := - MethodClearCheckBox.Checked; + Result := False; + if SetChangedField('IsIndexed', OptionIndexedCheckBox.Checked) then + Result := True; + if SetChangedField('IsRequired', OptionRequiredCheckBox.Checked) then + Result := True; + if SetChangedField('ReadOnly', OptionReadOnlyCheckBox.Checked) then + Result := True; + if SetChangedField('IsDefault', OptionDefaultCheckBox.Checked) then + Result := True; end; + function SaveMethods: Boolean; + begin + Result := False; + if SetChangedField('IncludeAddMethod', MethodAddCheckBox.Checked) then + Result := True; + if SetChangedField('IncludeRemoveMethod', MethodRemoveCheckBox.Checked) then + Result := True; + if SetChangedField('IncludeInsertMethod', MethodInsertCheckBox.Checked) then + Result := True; + if SetChangedField('IncludeDeleteMethod', MethodDeleteCheckBox.Checked) then + Result := True; + if SetChangedField('IncludeIndexOfMethod', MethodIndexOfCheckBox.Checked) then + Result := True; + if SetChangedField('IncludeClearMethod', MethodClearCheckBox.Checked) then + Result := True; + end; + +var + OptionsChanged: Boolean; + MethodsChanged: Boolean; begin inherited; - SaveOptions; - SaveMethods; + OptionsChanged := SaveOptions; + MethodsChanged := SaveMethods; + if OptionsChanged or MethodsChanged then + SubjectExposer.Edit; end; procedure TInstantAttributeEditorForm.SetLimited(Value: Boolean); |
From: <sr...@us...> - 2006-05-29 03:23:22
|
Revision: 680 Author: srmitch Date: 2006-05-28 20:23:15 -0700 (Sun, 28 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=680&view=rev Log Message: ----------- Update of Changes.txt for V2.0 RC1. Modified Paths: -------------- trunk/Docs/Changes.txt Modified: trunk/Docs/Changes.txt =================================================================== --- trunk/Docs/Changes.txt 2006-05-29 00:17:20 UTC (rev 679) +++ trunk/Docs/Changes.txt 2006-05-29 03:23:15 UTC (rev 680) @@ -1,7 +1,46 @@ VERSION HISTORY --------------- +Version 2.0 RC 1 (1.9.1.4) (2006-05-31) +- Help file has been improved. + +- Bug fix for # 1475841. "TInstantContainer.Sort error if empty". + +- Bug fix for # 1475982. Rebuilding a Firebird database creates + disabled PKs. + +- Changed the visibility of the + TInstantReferences.ObjectReferenceList property from private to + protected. + +- Bug fix for # 1479652. "Problem with PrimeCross demo and + InstantReference.Reset". + +- Changed TInstantSQLBroker.AcquireDataSet method to virtual. + +- Added a protected, virtual method UndoRecordBuffer to + TInstantCustomExposer to enable customization of its Undo + method. + +- Bug fix for # 1466586. Minor Error in Attribute Editor. + Force the main definition tabsheet to be active before trying + to focus the attribute Name or Size edit controls. + +- Fix for bug # 1467511. When adding a new attribute in + ModelMaker, in the attribute editor there aren't field types + other than "part" and "parts" available. + +- Updated unit tests. Added TestInstantObjectReference.pas unit + to the Tests folder. This new unit contains tests for the + TInstantObjectReference class. + +- InstantPart and InstantReference tests updated. + +- Bug Fix for # 1464661. TInstantReference.Assign causes AV. Check + for nil needed before trying to clone a TInstantReference + attribute object. + Version 2.0 Beta 3 (1.9.1.3) (2006-03-31) - The IDE menu item "Build Database..." has been changed |
From: <sr...@us...> - 2006-05-29 00:17:55
|
Revision: 679 Author: srmitch Date: 2006-05-28 17:17:20 -0700 (Sun, 28 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=679&view=rev Log Message: ----------- Update of Help files and its sources as follows: 1. Modified TInstantCustomExposer.IsChanged topic. 2. Added TInstantCustomExposer.IsSubjectChanged topic. 3. Updated TInstantCustomExposer links to reflect changes. Modified Paths: -------------- trunk/Help/IOHelp.hlp trunk/Help/IOHelp.hpj trunk/Help/IOHelp.hsc trunk/Help/IOHelp.rtf Modified: trunk/Help/IOHelp.hlp =================================================================== (Binary files differ) Modified: trunk/Help/IOHelp.hpj =================================================================== --- trunk/Help/IOHelp.hpj 2006-05-27 05:35:41 UTC (rev 678) +++ trunk/Help/IOHelp.hpj 2006-05-29 00:17:20 UTC (rev 679) @@ -484,7 +484,10 @@ ID_422 4930 ID_471 4940 ID_423 4950 -ID_424 4960 +ID_424 4955 +Scribble4957 4957 +Scribble4960 4960 +Scribble4965 4965 ID_425 4970 ID_472 4980 ID_415 4990 Modified: trunk/Help/IOHelp.hsc =================================================================== --- trunk/Help/IOHelp.hsc 2006-05-27 05:35:41 UTC (rev 678) +++ trunk/Help/IOHelp.hsc 2006-05-29 00:17:20 UTC (rev 679) @@ -37,7 +37,7 @@ Next FALSE -1262 +1265 10 ID_0 InstantObjects Welcome @@ -10688,8 +10688,8 @@ FALSE -24 -{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss Arial;}} +25 +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;} \viewkind4\uc1\pard\sb25\tx355\lang1040\b\f0\fs24 TInstantCustomExposer Properties \cf1\b0\fs16 \par \strike TInstantCustomExposer\strike0\{linkID=4790>main\}\tab\ul Legend\ulnone\{link=ID_434\}\{keepn\} @@ -10699,7 +10699,8 @@ \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike CurrentObject\strike0\{linkID=4920>main\} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike FieldOptions\strike0\{linkID=4930>main\} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike HasSubject\strike0\{linkID=4950>main\} -\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0\{linkID=4960>main\} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0\{linkID=49\lang1033\f1 55\lang1040\f0 >main\} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike Is\lang1033\f1 Subject\lang1040\f0 Changed\strike0\{linkID=49\lang1033\f1 60\lang1040\f0 >main\} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike Limited\strike0\{linkID=4970>main\} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike Mode\strike0\{linkID=4990>main\} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike ObjectClass\strike0\{linkID=5000>main\} @@ -10858,8 +10859,8 @@ FALSE -59 -{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss Arial;}} +60 +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} {\colortbl ;\red0\green0\blue0;} \viewkind4\uc1\pard\sb25\tx355\lang1040\b\f0\fs24 TInstantCustomExposer Members \cf1\b0\fs16 \par \strike TInstantCustomExposer\strike0\{linkID=4790>main\}\tab\ul Legend\ulnone\{link=ID_470\}\{keepn\} @@ -10869,7 +10870,8 @@ \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike CurrentObject\strike0\{linkID=4920>main\} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike FieldOptions\strike0\{linkID=4930>main\} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike HasSubject\strike0\{linkID=4950>main\} -\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0\{linkID=4960>main\} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0\{linkID=49\lang1033\f1 55\lang1040\f0 >main\} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike Is\lang1033\f1 Subject\lang1040\f0 Changed\strike0\{linkID=49\lang1033\f1 60\lang1040\f0 >main\} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike Limited\strike0\{linkID=4970>main\} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike Mode\strike0\{linkID=4990>main\} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike ObjectClass\strike0\{linkID=5000>main\} @@ -11074,29 +11076,92 @@ \par \pard\sb25\sa25\b0 Use HasSubject to determine if the exposer has a subject. \par \par } -4960 +4955 ID_424 TInstantCustomExposer.IsChanged IsChanged;IsChanged,TInstantCustomExposer;TInstantCustomExposer,IsChanged; -Imported -main +Modified + IsChanged;IsChanged_Property;TInstantCustomExposer_IsChanged FALSE 10 {\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fmodern Courier New;}} -{\colortbl ;\red0\green0\blue0;} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} \viewkind4\uc1\pard\lang1040\b\f0\fs24 TInstantCustomExposer.IsChanged \cf1\b0\fs16 -\par \strike TInstantCustomExposer\strike0\{link\lang1033\f1 ID\lang1040\f0 =\lang1033\f1 4790\lang1040\f0 >main\}\{keepn\} -\par \pard\sb25\sa85\fs18 Specifies if changes have been made to the exposed subject. +\par \cf2\strike TInstantCustomExposer\cf3\strike0\{linkID=4790>main\}\cf1\tab\ul See Also\ulnone\{linkID=49\lang1033\f1 57\lang1040\f0\}\{keepn\} +\par \pard\sb25\sa85\fs18 Specifies if changes have been made to the expose\lang1033\f1 r's\lang1040\f0 \lang1033\f1 dataset fields or records\lang1040\f0 . \par \pard\sb25\sa25\b\f2 property\b0 IsChanged: Boolean; \par \pard\sb55\sa25\b\f0 Description -\par \pard\sb25\sa25\b0 If objects have been added or removed or any changes have been made to the subject or any object within the subject, IsChanged is True. Otherwise IsChanged is False. +\par \pard\sb25\sa25\b0 If \lang1033\f1 dataset records\lang1040\f0 have been added or removed or any changes have been made to \lang1033\f1 their fields\lang1040\f0 , IsChanged is True. Otherwise IsChanged is False. \par \par } +4957 +Scribble4957 + + + + + +Imported + + + +FALSE +7 +{\rtf1\ansi\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} +{\colortbl ;\red0\green0\blue0;} +\viewkind4\uc1\pard\sb55\sa25\lang1040\b\f0\fs24 See Also +\par \pard\li95\sb25\sa25\cf1\b0\fs18 +\par \strike TInstantCustomExposer.\lang1033\f1 IsSubjectChanged\lang1040\strike0\f0\{linkID=\lang1033\f1 496\lang1040\f0 0>main\} +\par \strike +\par } +4960 +Scribble4960 +TInstantCustomExposer.IsSubjectChanged +IsSubjectChanged;IsSubjectChanged,TInstantCustomExposer;TInstantCustomExposer,IsSubjectChanged; + + + +Added +main + +IsSubjectChanged;IsSubjectChanged_Property;TInstantCustomExposer_IsSubjectChanged +FALSE +10 +{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}{\f2\fmodern Courier New;}} +{\colortbl ;\red0\green0\blue0;\red0\green128\blue0;\red128\green0\blue0;} +\viewkind4\uc1\pard\lang1040\b\f0\fs24 TInstantCustomExposer.IsSubjectChanged \cf1\b0\fs16 +\par \cf2\strike TInstantCustomExposer\cf3\strike0\{linkID=4790>main\}\cf1\tab\ul See Also\ulnone\{linkID=49\lang1033\f1 65\lang1040\f0\}\{keepn\} +\par \pard\sb25\sa85\fs18 Specifies if changes have been made to the exposed subject. +\par \pard\sb25\sa25\b\f2 property\b0 IsSubjectChanged: Boolean; +\par \pard\sb55\sa25\b\f0 Description +\par \pard\sb25\sa25\b0 If objects have been added or removed or any changes have been made to the subject or any object within the subject, IsSubjectChanged is True. Otherwise IsSubjectChanged is False. +\par +\par } +4965 +Scribble4965 + + + + + +Imported + + + +FALSE +7 +{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss Arial;}{\f1\fswiss\fcharset0 Arial;}} +{\colortbl ;\red0\green0\blue0;} +\viewkind4\uc1\pard\sb55\sa25\lang1040\b\f0\fs24 See Also +\par \pard\li95\sb25\sa25\cf1\b0\fs18 +\par \strike TInstantCustomExposer.\lang1033\f1 IsChanged\lang1040\strike0\f0\{linkID=\lang1033\f1 4955\lang1040\f0 >main\} +\par \strike +\par } 4970 ID_425 TInstantCustomExposer.Limited Modified: trunk/Help/IOHelp.rtf =================================================================== --- trunk/Help/IOHelp.rtf 2006-05-27 05:35:41 UTC (rev 678) +++ trunk/Help/IOHelp.rtf 2006-05-29 00:17:20 UTC (rev 679) @@ -7419,6 +7419,7 @@ \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike FieldOptions\strike0{\v ID_422>main} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike HasSubject\strike0{\v ID_423>main} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0{\v ID_424>main} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike Is\lang1033\f1 Subject\lang1040\f0 Changed\strike0{\v Scribble4960>main} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike Limited\strike0{\v ID_425>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike Mode\strike0{\v ID_415>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike ObjectClass\strike0{\v ID_426>main} @@ -7535,6 +7536,7 @@ \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike FieldOptions\strike0{\v ID_422>main} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike HasSubject\strike0{\v ID_423>main} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0{\v ID_424>main} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike Is\lang1033\f1 Subject\lang1040\f0 Changed\strike0{\v Scribble4960>main} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike Limited\strike0{\v ID_425>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike Mode\strike0{\v ID_415>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike ObjectClass\strike0{\v ID_426>main} @@ -7701,23 +7703,62 @@ {\pard\plain\f0\fs20 {\up #}{\footnote {\up #} ID_424} -{\up >}{\footnote {\up >} main} {\up $}{\footnote {\up $} TInstantCustomExposer.IsChanged} {\up K}{\footnote {\up K} IsChanged;IsChanged,TInstantCustomExposer;TInstantCustomExposer,IsChanged;} {\up A}{\footnote {\up A} IsChanged;IsChanged_Property;TInstantCustomExposer_IsChanged} } \viewkind4\uc1\pard\keepn\lang1040\b\f0\fs24 TInstantCustomExposer.IsChanged \cf1\b0\fs16 -\par \strike TInstantCustomExposer\strike0\{link\lang1033\f1 ID\lang1040\f0 =\lang1033\f1 4790\lang1040\f0 >main\} -\par \pard\sb25\sa85\fs18 Specifies if changes have been made to the exposed subject. +\par \cf2\strike TInstantCustomExposer\cf3\strike0{\v ID_407>main}\cf1\tab\ul See Also\ulnone{\v Scribble4957} +\par \pard\sb25\sa85\fs18 Specifies if changes have been made to the expose\lang1033\f1 r's\lang1040\f0 \lang1033\f1 dataset fields or records\lang1040\f0 . \par \pard\sb25\sa25\b\f7 property\b0 IsChanged: Boolean; \par \pard\sb55\sa25\b\f0 Description -\par \pard\sb25\sa25\b0 If objects have been added or removed or any changes have been made to the subject or any object within the subject, IsChanged is True. Otherwise IsChanged is False. +\par \pard\sb25\sa25\b0 If \lang1033\f1 dataset records\lang1040\f0 have been added or removed or any changes have been made to \lang1033\f1 their fields\lang1040\f0 , IsChanged is True. Otherwise IsChanged is False. \par \par \pard\plain\f0 {\page} {\pard\plain\f0\fs20 +{\up #}{\footnote {\up #} Scribble4957} +} +\viewkind4\uc1\pard\sb55\sa25\lang1040\b\f0\fs24 See Also +\par \pard\li95\sb25\sa25\cf1\b0\fs18 +\par \strike TInstantCustomExposer.\lang1033\f1 IsSubjectChanged\lang1040\strike0\f0{\v Scribble4960>main} +\par \strike +\par \pard\plain\f0 + +{\page} + +{\pard\plain\f0\fs20 +{\up #}{\footnote {\up #} Scribble4960} +{\up >}{\footnote {\up >} main} +{\up $}{\footnote {\up $} TInstantCustomExposer.IsSubjectChanged} +{\up K}{\footnote {\up K} IsSubjectChanged;IsSubjectChanged,TInstantCustomExposer;TInstantCustomExposer,IsSubjectChanged;} +{\up A}{\footnote {\up A} IsSubjectChanged;IsSubjectChanged_Property;TInstantCustomExposer_IsSubjectChanged} +} +\viewkind4\uc1\pard\keepn\lang1040\b\f0\fs24 TInstantCustomExposer.IsSubjectChanged \cf1\b0\fs16 +\par \cf2\strike TInstantCustomExposer\cf3\strike0{\v ID_407>main}\cf1\tab\ul See Also\ulnone{\v Scribble4965} +\par \pard\sb25\sa85\fs18 Specifies if changes have been made to the exposed subject. +\par \pard\sb25\sa25\b\f7 property\b0 IsSubjectChanged: Boolean; +\par \pard\sb55\sa25\b\f0 Description +\par \pard\sb25\sa25\b0 If objects have been added or removed or any changes have been made to the subject or any object within the subject, IsSubjectChanged is True. Otherwise IsSubjectChanged is False. +\par +\par \pard\plain\f0 + +{\page} + +{\pard\plain\f0\fs20 +{\up #}{\footnote {\up #} Scribble4965} +} +\viewkind4\uc1\pard\sb55\sa25\lang1040\b\f0\fs24 See Also +\par \pard\li95\sb25\sa25\cf1\b0\fs18 +\par \strike TInstantCustomExposer.\lang1033\f1 IsChanged\lang1040\strike0\f0{\v ID_424>main} +\par \strike +\par \pard\plain\f0 + +{\page} + +{\pard\plain\f0\fs20 {\up #}{\footnote {\up #} ID_425} {\up >}{\footnote {\up >} main} {\up $}{\footnote {\up $} TInstantCustomExposer.Limited} @@ -10167,7 +10208,7 @@ \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike CurrentObject\strike0{\v ID_421>main} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike FieldOptions\strike0{\v ID_422>main} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike HasSubject\strike0{\v ID_423>main} -\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0{\v ID_424>main} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0{\v Scribble4960>main} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike Limited\strike0{\v ID_425>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike Mode\strike0{\v ID_415>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike ObjectClass\strike0{\v ID_426>main} @@ -16394,7 +16435,7 @@ \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike CurrentObject\strike0{\v ID_421>main} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike FieldOptions\strike0{\v ID_422>main} \par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike HasSubject\strike0{\v ID_423>main} -\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0{\v ID_424>main} +\par \{bmct bm0.BMP\}\{bmct bm1.BMP\} \strike IsChanged\strike0{\v Scribble4960>main} \par \{bmct bm0.BMP\}\{bmct bm4.BMP\} \strike Limited\strike0{\v ID_425>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike Mode\strike0{\v ID_415>main} \par \{bmct bm0.BMP\}\{bmct bm5.BMP\} \strike ObjectClass\strike0{\v ID_426>main} |
From: <sr...@us...> - 2006-05-27 05:36:12
|
Revision: 678 Author: srmitch Date: 2006-05-26 22:35:41 -0700 (Fri, 26 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=678&view=rev Log Message: ----------- Update of Help files and its sources: Part 2. Added Paths: ----------- trunk/Help/AttributeEditorPresentation.gif trunk/Help/ClassEditorAttributesPop-upMenu.gif trunk/Help/ClassEditorClass.gif trunk/Help/ModelExplorerBuildDatabaseButton.gif trunk/Help/ModelExplorerPop-upMenu.gif trunk/Help/ModelExplorerSelectUnitsButton.gif trunk/Help/ModelExplorerViewInheritanceButton.gif trunk/Help/ModelExplorerViewRelationsButton.gif Removed Paths: ------------- trunk/Help/ClassEditor.gif Added: trunk/Help/AttributeEditorPresentation.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/AttributeEditorPresentation.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Deleted: trunk/Help/ClassEditor.gif =================================================================== (Binary files differ) Added: trunk/Help/ClassEditorAttributesPop-upMenu.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ClassEditorAttributesPop-upMenu.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Help/ClassEditorClass.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ClassEditorClass.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Help/ModelExplorerBuildDatabaseButton.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ModelExplorerBuildDatabaseButton.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Help/ModelExplorerPop-upMenu.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ModelExplorerPop-upMenu.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Help/ModelExplorerSelectUnitsButton.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ModelExplorerSelectUnitsButton.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Help/ModelExplorerViewInheritanceButton.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ModelExplorerViewInheritanceButton.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/Help/ModelExplorerViewRelationsButton.gif =================================================================== (Binary files differ) Property changes on: trunk/Help/ModelExplorerViewRelationsButton.gif ___________________________________________________________________ Name: svn:mime-type + application/octet-stream |
From: <na...@us...> - 2006-05-18 18:18:48
|
Revision: 676 Author: nandod Date: 2006-05-18 11:18:40 -0700 (Thu, 18 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=676&view=rev Log Message: ----------- * added a virtual method to enable customization. Modified Paths: -------------- trunk/Source/Core/InstantPresentation.pas Modified: trunk/Source/Core/InstantPresentation.pas =================================================================== --- trunk/Source/Core/InstantPresentation.pas 2006-05-16 15:52:33 UTC (rev 675) +++ trunk/Source/Core/InstantPresentation.pas 2006-05-18 18:18:40 UTC (rev 676) @@ -461,6 +461,7 @@ procedure SetFiltered(Value: Boolean); override; procedure SetRecNo(Value: Integer); override; procedure Undo; virtual; + procedure UndoRecordBuffer(RecordBuffer: TInstantRecordBuffer); virtual; procedure UpdateCalcFields; procedure WriteProperty(Field: TField; Instance: TObject; Value: Variant); virtual; function BreakThorough( const FieldName : string ) : boolean; virtual; @@ -4197,11 +4198,16 @@ end; if Assigned(FRecordBuffer) then begin - FRecordBuffer.UndoChanges; + UndoRecordBuffer(FRecordBuffer); FreeAndNil(FRecordBuffer); end; end; +procedure TInstantCustomExposer.UndoRecordBuffer(RecordBuffer: TInstantRecordBuffer); +begin + RecordBuffer.UndoChanges; +end; + procedure TInstantCustomExposer.UpdateBookmark(var BM: TInstantBookmark); begin if (RecordCount = 0) or (BM.Instance = FRemovedObject) then |
From: <na...@us...> - 2006-05-16 15:52:40
|
Revision: 675 Author: nandod Date: 2006-05-16 08:52:33 -0700 (Tue, 16 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=675&view=rev Log Message: ----------- * made TInstantSQLBroker.AcquireDataSet virtual. Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-05-11 07:41:33 UTC (rev 674) +++ trunk/Source/Core/InstantPersistence.pas 2006-05-16 15:52:33 UTC (rev 675) @@ -2379,7 +2379,7 @@ function CreateDataSet(const AStatement: string; AParams: TParams = nil): TDataSet; virtual; abstract; public destructor Destroy; override; - function AcquireDataSet(const AStatement: string; AParams: TParams = nil): TDataSet; + function AcquireDataSet(const AStatement: string; AParams: TParams = nil): TDataSet; virtual; procedure ReleaseDataSet(const ADataSet: TDataSet); virtual; function DataTypeToColumnType(DataType: TInstantDataType; Size: Integer): string; virtual; abstract; |
From: <sr...@us...> - 2006-05-11 07:41:46
|
Revision: 674 Author: srmitch Date: 2006-05-11 00:41:33 -0700 (Thu, 11 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=674&view=rev Log Message: ----------- Updated unit tests. Added TestInstantObjectReference.pas unit to the Tests folder. This new unit contains tests for the TInstantObjectReference class. Modified Paths: -------------- trunk/Source/Tests/TestIO.dpr Added Paths: ----------- trunk/Source/Tests/TestInstantObjectReference.pas Modified: trunk/Source/Tests/TestIO.dpr =================================================================== --- trunk/Source/Tests/TestIO.dpr 2006-05-02 23:43:48 UTC (rev 673) +++ trunk/Source/Tests/TestIO.dpr 2006-05-11 07:41:33 UTC (rev 674) @@ -50,7 +50,8 @@ TestInstantObjectStore in 'TestInstantObjectStore.pas', TestInstantParts in 'TestInstantParts.pas', TestInstantReferences in 'TestInstantReferences.pas', - TestInstantCircularReferences in 'TestInstantCircularReferences.pas'; + TestInstantCircularReferences in 'TestInstantCircularReferences.pas', + TestInstantObjectReference in 'TestInstantObjectReference.pas'; {$R *.res} {$R *.mdr} {TestModel} Added: trunk/Source/Tests/TestInstantObjectReference.pas =================================================================== --- trunk/Source/Tests/TestInstantObjectReference.pas (rev 0) +++ trunk/Source/Tests/TestInstantObjectReference.pas 2006-05-11 07:41:33 UTC (rev 674) @@ -0,0 +1,387 @@ +(* + * InstantObjects Test Suite + * TestInstantObjectReference + *) + +(* ***** 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/TestInstantObjectReference + * + * 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 TestInstantObjectReference; + +interface + +uses fpcunit, InstantMock, InstantPersistence, TestModel; + +type + // Test methods for class TInstantObjectReference + TestTInstantObjectReference = class(TTestCase) + private + FConn: TInstantMockConnector; + FInstantObjectReference: TInstantObjectReference; + FInstantParts: TInstantParts; + FInstantReferences: TInstantReferences; + FInstantObject: TCompany; + public + procedure SetUp; override; + procedure TearDown; override; + published + procedure TestAssign; + procedure TestAssignInstance_DestroyInstance; + procedure TestDereference; + procedure TestEquals; + procedure TestEquals_Object; + procedure TestHasInstance; + procedure TestHasReference; + procedure TestIsBroken; + procedure TestReferenceObject; + procedure TestReferenceObject_ClassType; + procedure TestReset; + procedure TestWrite_ReadAsObject; + end; + +implementation + +uses Classes, SysUtils, TypInfo, InstantClasses, testregistry; + +procedure TestTInstantObjectReference.SetUp; +begin + FConn := TInstantMockConnector.Create(nil); + FConn.BrokerClass := TInstantMockBroker; + + if InstantModel.ClassMetadatas.Count > 0 then + InstantModel.ClassMetadatas.Clear; + InstantModel.LoadFromResFile(ChangeFileExt(ParamStr(0), '.mdr')); + + FInstantObject := TCompany.Create(FConn); + FInstantReferences := FInstantObject._Employees; + FInstantParts := FInstantObject._ExternalPhones; + FInstantObjectReference := TInstantObjectReference.Create; +end; + +procedure TestTInstantObjectReference.TearDown; +begin + FreeAndNil(FInstantObjectReference); + FreeAndNil(FInstantObject); + InstantModel.ClassMetadatas.Clear; + FreeAndNil(FConn); +end; + +procedure TestTInstantObjectReference.TestAssign; +var + Source: TPersistent; +begin + Source := TInstantObjectReference.Create(FInstantObject); + try + AssertEquals('ClassName', FInstantObject.ClassName, + TInstantObjectReference(Source).ObjectClassName); + AssertEquals('Id', FInstantObject.Id, + TInstantObjectReference(Source).ObjectId); + AssertSame('Instance', FInstantObject, + TInstantObjectReference(Source).Instance); + + FInstantObjectReference.Assign(Source); + AssertEquals('ClassName 2', FInstantObject.ClassName, + FInstantObjectReference.ObjectClassName); + AssertEquals('Id 2', FInstantObject.Id, FInstantObjectReference.ObjectId); + AssertSame('Instance 2', FInstantObject, FInstantObjectReference.Instance); + finally + Source.Free; + end; +end; + +procedure TestTInstantObjectReference.TestAssignInstance_DestroyInstance; +var + RefCnt: Integer; +begin + AssertNotNull(FInstantObject); + RefCnt := FInstantObject.RefCount; + AssertFalse('OwnsInstance', FInstantObjectReference.OwnsInstance); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + + FInstantObjectReference.AssignInstance(FInstantObject); + AssertTrue('HasInstance 2', FInstantObjectReference.HasInstance); + AssertEquals('RefCount', RefCnt, FInstantObject.RefCount); + + FInstantObjectReference.DestroyInstance; + AssertEquals('RefCount 2', RefCnt, FInstantObject.RefCount); + AssertFalse('HasInstance 3', FInstantObjectReference.HasInstance); + + FInstantObjectReference.OwnsInstance := True; + FInstantObjectReference.AssignInstance(FInstantObject); + AssertTrue('HasInstance 4', FInstantObjectReference.HasInstance); + AssertEquals('RefCount 3', Succ(RefCnt), FInstantObject.RefCount); + + FInstantObjectReference.DestroyInstance; + AssertEquals('RefCount 4', RefCnt, FInstantObject.RefCount); + AssertFalse('HasInstance 5', FInstantObjectReference.HasInstance); +end; + +procedure TestTInstantObjectReference.TestDereference; +var + vObj: TInstantObject; + RefCnt: Integer; +begin + FInstantObject.Id := 'TestId'; + FInstantObject.Name := 'TestCo'; + FInstantObject.Store; + RefCnt := FInstantObject.RefCount; + + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + AssertEquals('RefCount', RefCnt, FInstantObject.RefCount); + + // with ownership + vObj := FInstantObjectReference.Dereference(FConn, True, + False); + AssertEquals('FInstantObject.Id <> vObj.Id', FInstantObject.Id, vObj.Id); + AssertSame('FInstantObject <> vObj', FInstantObject, vObj); + AssertEquals('RefCount 2', Succ(RefCnt), FInstantObject.RefCount); + FInstantObjectReference.DestroyInstance; + AssertEquals('RefCount 3', RefCnt, FInstantObject.RefCount); + + // without ownership + vObj := FInstantObjectReference.Dereference(FConn, False, + False); + AssertEquals('FInstantObject.Id <> vObj.Id', FInstantObject.Id, vObj.Id); + AssertSame('FInstantObject <> vObj', FInstantObject, vObj); + AssertEquals('RefCount 4', RefCnt, FInstantObject.RefCount); +end; + +procedure TestTInstantObjectReference.TestEquals; +var + ReturnValue: Boolean; +begin + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + + ReturnValue := FInstantObjectReference.Equals( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('ReturnValue', ReturnValue); + + FInstantObject.Id := 'TestId'; + ReturnValue := FInstantObjectReference.Equals( + FInstantObject.ClassName, FInstantObject.Id); + AssertFalse('ReturnValue 2', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestEquals_Object; +var + ReturnValue: Boolean; +begin + // FInstantObject is not persistent + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + + ReturnValue := FInstantObjectReference.Equals(FInstantObject); + AssertFalse('ReturnValue', ReturnValue); + + FInstantObject.Id := 'TestId'; + FInstantObject.Name := 'TestCo'; + FInstantObject.Store; + + // FInstantObject is persistent + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + + ReturnValue := FInstantObjectReference.Equals(FInstantObject); + AssertTrue('ReturnValue 2', ReturnValue); + + FInstantObject.Id := 'TestId_changed'; + FInstantObject.Store; + + ReturnValue := FInstantObjectReference.Equals(FInstantObject); + AssertFalse('ReturnValue 3', ReturnValue); + + FreeAndNil(FInstantObject); + + ReturnValue := FInstantObjectReference.Equals(FInstantObject); + AssertFalse('ReturnValue 4', ReturnValue); + + FInstantObjectReference.Reset; + + ReturnValue := FInstantObjectReference.Equals(FInstantObject); + AssertTrue('ReturnValue 5', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestHasInstance; +var + ReturnValue: Boolean; +begin + ReturnValue := FInstantObjectReference.HasInstance; + AssertFalse('ReturnValue', ReturnValue); + + FInstantObjectReference.AssignInstance(FInstantObject); + ReturnValue := FInstantObjectReference.HasInstance; + AssertTrue('ReturnValue 2', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestHasReference; +var + ReturnValue: Boolean; +begin + ReturnValue := FInstantObjectReference.HasReference; + AssertFalse('ReturnValue', ReturnValue); + + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + ReturnValue := FInstantObjectReference.HasReference; + AssertTrue('ReturnValue 2', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestIsBroken; +var + ReturnValue: Boolean; +begin + FInstantObjectReference.Dereference(FConn, False, + False); + ReturnValue := FInstantObjectReference.IsBroken; + AssertTrue('ReturnValue', ReturnValue); + + FInstantObjectReference.AssignInstance(FInstantObject); + ReturnValue := FInstantObjectReference.IsBroken; + AssertFalse('ReturnValue 2', ReturnValue); + + FInstantObjectReference.Reset; + ReturnValue := FInstantObjectReference.IsBroken; + AssertFalse('ReturnValue 3', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestWrite_ReadAsObject; +var + vStream: TStream; + vReader: TInstantReader; + vWriter: TInstantWriter; +begin + FInstantObject.Id := 'TestId'; + FInstantObjectReference.AssignInstance(FInstantObject); + AssertTrue('HasInstance', FInstantObjectReference.HasInstance); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + + vStream := TMemoryStream.Create; + try + AssertEquals(0, vStream.Size); + vWriter := TInstantWriter.Create(vStream); + try + FInstantObjectReference.WriteAsObject(vWriter); + finally + vWriter.Free; + end; + AssertTrue('vStream.Size', vStream.Size > 0); + + FInstantObjectReference.Reset; + AssertFalse('HasInstance 2', FInstantObjectReference.HasInstance); + AssertFalse('HasReference 2', FInstantObjectReference.HasReference); + + vStream.Position := 0; + vReader := TInstantReader.Create(vStream); + try + FInstantObjectReference.ReadAsObject(vReader); + AssertFalse('HasInstance 3', FInstantObjectReference.HasInstance); + AssertTrue('HasReference 3', FInstantObjectReference.HasReference); + AssertEquals('ObjectClassName', 'TCompany', + FInstantObjectReference.ObjectClassName); + AssertEquals('ObjectId', 'TestId', FInstantObjectReference.ObjectId); + finally + vReader.Free; + end; + finally + vStream.Free; + end; +end; + +procedure TestTInstantObjectReference.TestReferenceObject; +var + RefCnt: Integer; + ReturnValue: Boolean; +begin + FInstantObject.Id := 'TestId'; + RefCnt := FInstantObject.RefCount; + + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + AssertEquals('RefCount', RefCnt, FInstantObject.RefCount); + + ReturnValue := FInstantObjectReference.Equals( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('ReturnValue', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestReferenceObject_ClassType; +var + RefCnt: Integer; + ReturnValue: Boolean; +begin + FInstantObject.Id := 'TestId'; + RefCnt := FInstantObject.RefCount; + + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassType, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + AssertEquals('RefCount', RefCnt, FInstantObject.RefCount); + + ReturnValue := FInstantObjectReference.Equals( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('ReturnValue', ReturnValue); +end; + +procedure TestTInstantObjectReference.TestReset; +begin + FInstantObject.Id := 'TestId'; + FInstantObjectReference.AssignInstance(FInstantObject); + AssertTrue('HasInstance', FInstantObjectReference.HasInstance); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + + FInstantObjectReference.Reset; + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + AssertFalse('HasReference', FInstantObjectReference.HasReference); + + FInstantObjectReference.ReferenceObject( + FInstantObject.ClassName, FInstantObject.Id); + AssertTrue('HasReference', FInstantObjectReference.HasReference); + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + + FInstantObjectReference.Reset; + AssertFalse('HasInstance', FInstantObjectReference.HasInstance); + AssertFalse('HasReference', FInstantObjectReference.HasReference); +end; + +initialization + // Register any test cases with the test runner +{$IFNDEF CURR_TESTS} + RegisterTests([TestTInstantObjectReference]); +{$ENDIF} + +end. |
From: <sr...@us...> - 2006-05-02 23:44:02
|
Revision: 673 Author: srmitch Date: 2006-05-02 16:43:48 -0700 (Tue, 02 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=673&view=rev Log Message: ----------- Fix for bug #1479652 in SF BT "Problem with PrimeCross demo and InstantReference.Reset". Unit tests were also updated. Bug Symptom(s): An InstantPart or InstantReference attribute Reset does not cause the change to the object to be stored. Bug Cause: InstantPart and InstantReference attributes do not signal a change after a Reset. Fix affects: <<InstantPersistence.pas>> procedure TInstantPart.Reset; procedure TInstantReference.Reset; <<TestInstantPart.pas>> <<TestInstantReference.pas>> Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas trunk/Source/Tests/TestInstantPart.pas trunk/Source/Tests/TestInstantReference.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-05-02 19:09:06 UTC (rev 672) +++ trunk/Source/Core/InstantPersistence.pas 2006-05-02 23:43:48 UTC (rev 673) @@ -6229,7 +6229,11 @@ procedure TInstantPart.Reset; begin - DestroyObject; + if not IsDefault then + begin + DestroyObject; + Changed; + end; end; procedure TInstantPart.SetOwnerContext(AObject: TInstantObject); @@ -6470,7 +6474,11 @@ procedure TInstantReference.Reset; begin - DestroyObjectReference; + if not IsDefault then + begin + DestroyObjectReference; + Changed; + end; end; function TInstantReference.RetrieveObject: TInstantObject; Modified: trunk/Source/Tests/TestInstantPart.pas =================================================================== --- trunk/Source/Tests/TestInstantPart.pas 2006-05-02 19:09:06 UTC (rev 672) +++ trunk/Source/Tests/TestInstantPart.pas 2006-05-02 23:43:48 UTC (rev 673) @@ -174,12 +174,16 @@ var vPart: TAddress; begin - AssertFalse(FInstantPart.IsChanged); + AssertFalse('Initial IsChanged', FInstantPart.IsChanged); vPart := TAddress.Create(FConn); + FInstantPart.Value := vPart; + AssertTrue('IsChanged False after Value assignment', FInstantPart.IsChanged); + + FInstantPart.Unchanged; + AssertFalse(FInstantPart.IsChanged); vPart.Changed; - FInstantPart.Value := vPart; - AssertTrue(FInstantPart.IsChanged); + AssertTrue('IsChanged False after part changed', FInstantPart.IsChanged); end; procedure TestTInstantEmbPart.TestIsDefault; @@ -245,6 +249,11 @@ vFirstObj: TInstantObject; vSecondObj: TInstantObject; begin + AssertTrue(FInstantPart.IsDefault); + AssertFalse(FInstantPart.IsChanged); + FInstantPart.Reset; + AssertFalse('IsChanged True after initial Reset', FInstantPart.IsChanged); + AssertFalse('HasValue 1', FInstantPart.HasValue); AssertNotNull('AssertNotNull', FInstantPart.Value); AssertTrue('HasValue 2', FInstantPart.HasValue); @@ -255,9 +264,15 @@ FInstantPart.Value := vSecondObj; AssertEquals('Value.Id', 'PartId', FInstantPart.Value.Id); AssertNotSame('AssertNotSame', vFirstObj, FInstantPart.Value); + AssertTrue('IsChanged False after second Value assignment', + FInstantPart.IsChanged); + FInstantPart.Unchanged; + AssertFalse(FInstantPart.IsChanged); + FInstantPart.Reset; AssertFalse('HasValue 3', FInstantPart.HasValue); + AssertTrue('IsChanged False after Reset', FInstantPart.IsChanged); end; procedure TestTInstantExtPart.SetUp; Modified: trunk/Source/Tests/TestInstantReference.pas =================================================================== --- trunk/Source/Tests/TestInstantReference.pas 2006-05-02 19:09:06 UTC (rev 672) +++ trunk/Source/Tests/TestInstantReference.pas 2006-05-02 23:43:48 UTC (rev 673) @@ -50,6 +50,7 @@ procedure TestAttach_DetachObject; procedure TestDestroyObject_HasReference_HasValue; procedure TestHasValue; + procedure TestIsChanged; procedure TestLoadObjectFromStream; procedure TestObjectClass_ObjectClassName_ObjectId; procedure TestReferenceObject_Class; @@ -73,6 +74,7 @@ FOwner := TContact.Create(FConn); FInstantReference := FOwner._Category; + FInstantReference.UnChanged; end; procedure TestTInstantReference.TearDown; @@ -171,6 +173,28 @@ AssertFalse(FInstantReference.HasValue); end; +procedure TestTInstantReference.TestIsChanged; +var + vObject: TCategory; +begin + AssertFalse('Initial IsChanged', FInstantReference.IsChanged); + + vObject := TCategory.Create(FConn); + try + AssertNotNull('Create object is nil', vObject); + FInstantReference.Value := vObject; + AssertTrue('IsChanged False after Value assignment', FInstantReference.IsChanged); + + FInstantReference.Unchanged; + AssertFalse(FInstantReference.IsChanged); + vObject.Changed; + AssertFalse('IsChanged True after referenced object changed', + FInstantReference.IsChanged); + finally + vObject.Free; + end; +end; + procedure TestTInstantReference.TestLoadObjectFromStream; var vObject: TCategory; @@ -270,6 +294,12 @@ begin AssertTrue('Initial HasRef', FInstantReference.HasReference); AssertFalse('Initial HasVal', FInstantReference.HasValue); + AssertFalse('Initial IsChanged', FInstantReference.IsChanged); + AssertFalse('Initial IsDefault', FInstantReference.IsDefault); + FInstantReference.Reset; + AssertTrue('IsDefault after Reset', FInstantReference.IsDefault); + AssertTrue('IsChanged True after initial Reset', + FInstantReference.IsChanged); vObj := TCategory.Create(FConn); try @@ -277,10 +307,13 @@ AssertTrue(FInstantReference.HasReference); AssertTrue(FInstantReference.HasValue); AssertSame(vObj, FInstantReference.Value); + AssertTrue('IsChanged 2 is False!', FInstantReference.IsChanged); + FInstantReference.UnChanged; FInstantReference.Reset; AssertFalse('Final HasRef', FInstantReference.HasReference); AssertFalse('Final HasVal', FInstantReference.HasValue); + AssertTrue('Final IsChanged', FInstantReference.IsChanged); finally vObj.Free; end; |
From: <jcm...@us...> - 2006-05-02 19:09:29
|
Revision: 672 Author: jcmoraisjr Date: 2006-05-02 12:09:06 -0700 (Tue, 02 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=672&view=rev Log Message: ----------- Changed the visibility of the TInstantReferences.ObjectReferenceList property (private -> protected) Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-05-01 21:24:47 UTC (rev 671) +++ trunk/Source/Core/InstantPersistence.pas 2006-05-02 19:09:06 UTC (rev 672) @@ -1100,8 +1100,6 @@ FConnector: TInstantConnector; FObjectReferenceList: TInstantObjectReferenceList; function GetObjectReferenceList: TInstantObjectReferenceList; - property ObjectReferenceList: TInstantObjectReferenceList read - GetObjectReferenceList; function GetRefItems(Index: Integer): TInstantObjectReference; protected class function AttributeType: TInstantAttributeType; override; @@ -1123,6 +1121,8 @@ procedure SetAllowOwned(Value: Boolean); virtual; procedure ValidateObject(AObject: TInstantObject); override; procedure WriteObject(Writer: TInstantWriter); override; + property ObjectReferenceList: TInstantObjectReferenceList read + GetObjectReferenceList; public destructor Destroy; override; procedure Assign(Source: TPersistent); override; |
From: <na...@us...> - 2006-05-01 21:24:58
|
Revision: 671 Author: nandod Date: 2006-05-01 14:24:47 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=671&view=rev Log Message: ----------- * fixed compile error in EvolveTest. Modified Paths: -------------- trunk/Demos/EvolveTest/FMainEvolveTest.pas Modified: trunk/Demos/EvolveTest/FMainEvolveTest.pas =================================================================== --- trunk/Demos/EvolveTest/FMainEvolveTest.pas 2006-05-01 14:28:18 UTC (rev 670) +++ trunk/Demos/EvolveTest/FMainEvolveTest.pas 2006-05-01 21:24:47 UTC (rev 671) @@ -102,7 +102,7 @@ InstantUIB, InstantDBX, InstantADO, - InstantConnectionManagerForm; + InstantConnectionManagerFormUnit; var BusySaveCursor: TCursor; |
From: <na...@us...> - 2006-05-01 14:28:30
|
Revision: 670 Author: nandod Date: 2006-05-01 07:28:18 -0700 (Mon, 01 May 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=670&view=rev Log Message: ----------- * [ 1475982 ] - the real fix. Modified Paths: -------------- trunk/Source/Core/InstantDBBuild.pas Modified: trunk/Source/Core/InstantDBBuild.pas =================================================================== --- trunk/Source/Core/InstantDBBuild.pas 2006-04-25 08:12:33 UTC (rev 669) +++ trunk/Source/Core/InstantDBBuild.pas 2006-05-01 14:28:18 UTC (rev 670) @@ -742,16 +742,7 @@ DoBeforeCommandExecute(CurrentCommand); try if CurrentCommand.Enabled then - begin - Connector.StartTransaction; - try - CurrentCommand.Execute; - Connector.CommitTransaction; - except - Connector.RollbackTransaction; - raise; - end; - end; + CurrentCommand.Execute; except on E: Exception do begin |
From: <na...@us...> - 2006-04-25 08:12:42
|
Revision: 669 Author: nandod Date: 2006-04-25 01:12:33 -0700 (Tue, 25 Apr 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=669&view=rev Log Message: ----------- * [ 1475982 ] Rebuilding a Firebird database creates disabled PKs * some small refactorings and reformatting Modified Paths: -------------- trunk/Source/Core/InstantDBBuild.pas trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantDBBuild.pas =================================================================== --- trunk/Source/Core/InstantDBBuild.pas 2006-04-24 23:01:01 UTC (rev 668) +++ trunk/Source/Core/InstantDBBuild.pas 2006-04-25 08:12:33 UTC (rev 669) @@ -198,7 +198,6 @@ procedure DoCommandExecuteError(const ACommand: TInstantDBBuildCommand; const Error: Exception; var RaiseError: Boolean); procedure DoExecute; - procedure DoExecuteInTransaction; function GetCount: Integer; function GetItem(const Index: Integer): TInstantDBBuildCommand; procedure SetSourceScheme(const Value: TInstantScheme); @@ -270,6 +269,9 @@ // beginning of the overridden version, just returns '', or raises an // exception if Index is not in the allowed range. function GetSQLStatement(const Index: Integer): string; virtual; + // Executes the Nth statement. Handles transactions internally. + procedure ExecuteSQLStatement(const Index: Integer); + // Executes all statements. procedure InternalExecute; override; public property Connector: TInstantRelationalConnector read GetConnector; @@ -362,15 +364,25 @@ property NewIndexMetadata: TInstantIndexMetadata read GetNewIndexMetadata; end; + // Alters a field using a sequence of 6 instructions: + // 1. adds a temporary new field of the new type. + // 2. copies the values from the old field to the new field. + // 3. drops the old field. + // 4. adds a field with the old name and the new type. + // 5. copies back the values from the new temp field to the field with + // the old name. + // 6. drops the temp field. + // This class should be used for those database that don't support the + // SQL ALTER TABLE ALTER COLUMN statement. TInstantDBBuildAlterFieldGenericSQLCommand = class( - TInstantDBBuildAlterFieldSQLCommand) + TInstantDBBuildAlterFieldSQLCommand) private - FTmpFieldMD: TInstantFieldMetadata; + FTempFieldMetadata: TInstantFieldMetadata; protected function GetDescription: string; override; function GetSQLStatement(const Index: Integer): string; override; function GetSQLStatementCount: Integer; override; - procedure InternalExecute; override; + function InternalExecuteHandleError(const E: Exception): Boolean; override; public destructor Destroy; override; end; @@ -720,17 +732,26 @@ procedure TInstantDBBuildCommandSequence.DoExecute; var - i: Integer; + I: Integer; CurrentCommand: TInstantDBBuildCommand; RaiseError: Boolean; begin - for i := 0 to FCommands.Count - 1 do + for I := 0 to FCommands.Count - 1 do begin - CurrentCommand := FCommands[i] as TInstantDBBuildCommand; + CurrentCommand := FCommands[I] as TInstantDBBuildCommand; DoBeforeCommandExecute(CurrentCommand); try if CurrentCommand.Enabled then - CurrentCommand.Execute; + begin + Connector.StartTransaction; + try + CurrentCommand.Execute; + Connector.CommitTransaction; + except + Connector.RollbackTransaction; + raise; + end; + end; except on E: Exception do begin @@ -744,37 +765,19 @@ end; end; -procedure TInstantDBBuildCommandSequence.DoExecuteInTransaction; -begin - Connector.StartTransaction; - try - DoExecute; - Connector.CommitTransaction; - except - Connector.RollbackTransaction; - raise; - end; -end; - procedure TInstantDBBuildCommandSequence.Execute; var - ConnState: Boolean; + LWasConnected: Boolean; begin - ConnState := Connector.Connected; - if not ConnState then + LWasConnected := Connector.Connected; + if not LWasConnected then Connector.Connect; - DoBeforeExecute; - try - if Connector.DDLTransactionSupported then - DoExecuteInTransaction - else - DoExecute; - + DoExecute; DoAfterExecute; finally - if not ConnState then + if not LWasConnected then Connector.Disconnect; end; end; @@ -857,6 +860,21 @@ { TInstantDBBuildSQLCommand } +procedure TInstantDBBuildSQLCommand.ExecuteSQLStatement(const Index: Integer); +begin + if Connector.DDLTransactionSupported then + Connector.StartTransaction; + try + Broker.Execute(GetSQLStatement(Index)); + if Connector.DDLTransactionSupported then + Connector.CommitTransaction; + except + if Connector.DDLTransactionSupported then + Connector.RollbackTransaction; + raise; + end; +end; + function TInstantDBBuildSQLCommand.GetBroker: TInstantSQLBroker; begin Result := Connector.Broker as TInstantSQLBroker; @@ -896,10 +914,10 @@ procedure TInstantDBBuildSQLCommand.InternalExecute; var - iStatement: Integer; + IStatement: Integer; begin - for iStatement := 0 to Pred(GetSQLStatementCount) do - Broker.Execute(GetSQLStatement(iStatement)); + for IStatement := 0 to Pred(GetSQLStatementCount) do + ExecuteSQLStatement(IStatement); end; { TInstantDBBuildAddTableSQLCommand } @@ -1036,20 +1054,20 @@ destructor TInstantDBBuildAlterFieldGenericSQLCommand.Destroy; begin - FTmpFieldMD.Free; + FTempFieldMetadata.Free; inherited; end; function TInstantDBBuildAlterFieldGenericSQLCommand.GetDescription: string; begin Result := Format('ALTER TABLE %s evolve column %s - multi-statement SQL.', - [NewFieldMetadata.TableMetadata.Name, NewFieldMetadata.Name]); + [NewFieldMetadata.TableMetadata.Name, NewFieldMetadata.Name]); end; -function TInstantDBBuildAlterFieldGenericSQLCommand.GetSQLStatement(const - Index: Integer): string; +function TInstantDBBuildAlterFieldGenericSQLCommand.GetSQLStatement( + const Index: Integer): string; - function CreateTmpFieldMetadata(FieldMetadata: TInstantFieldMetadata): + function CreateTempFieldMetadata(FieldMetadata: TInstantFieldMetadata): TInstantFieldMetadata; begin Result := TInstantFieldMetadata.Create(FieldMetadata.Collection); @@ -1059,43 +1077,30 @@ begin Result := inherited GetSQLStatement(Index); - - FTmpFieldMD := CreateTmpFieldMetadata(NewFieldMetadata); - + FTempFieldMetadata := CreateTempFieldMetadata(NewFieldMetadata); with Broker.Generator do case Index of - 0 : Result := GenerateAddFieldSQL(FTmpFieldMD); - - 1 : Result := GenerateUpdateFieldCopySQL(OldFieldMetadata, FTmpFieldMD); - - 2 : Result := GenerateDropFieldSQL(OldFieldMetadata); - - 3 : Result := GenerateAddFieldSQL(NewFieldMetadata); - - 4 : Result := GenerateUpdateFieldCopySQL(FTmpFieldMD, NewFieldMetadata); - - 5 : Result := GenerateDropFieldSQL(FTmpFieldMD); + 0: Result := GenerateAddFieldSQL(FTempFieldMetadata); + 1: Result := GenerateUpdateFieldCopySQL(OldFieldMetadata, FTempFieldMetadata); + 2: Result := GenerateDropFieldSQL(OldFieldMetadata); + 3: Result := GenerateAddFieldSQL(NewFieldMetadata); + 4: Result := GenerateUpdateFieldCopySQL(FTempFieldMetadata, NewFieldMetadata); + 5: Result := GenerateDropFieldSQL(FTempFieldMetadata); end; end; -function TInstantDBBuildAlterFieldGenericSQLCommand.GetSQLStatementCount: - Integer; +function TInstantDBBuildAlterFieldGenericSQLCommand.GetSQLStatementCount: Integer; begin Result := 6; end; -procedure TInstantDBBuildAlterFieldGenericSQLCommand.InternalExecute; -var - iStatement: Integer; +function TInstantDBBuildAlterFieldGenericSQLCommand.InternalExecuteHandleError( + const E: Exception): Boolean; begin - try - for iStatement := 0 to Pred(GetSQLStatementCount) do - Broker.Execute(GetSQLStatement(iStatement)); - except - if Assigned(FTmpFieldMD) then - Broker.Execute(Broker.Generator.GenerateDropFieldSQL(FTmpFieldMD)); - raise; - end; + // Try not to leave the temp field around. + if Assigned(FTempFieldMetadata) then + Broker.Execute(Broker.Generator.GenerateDropFieldSQL(FTempFieldMetadata)); + Result := False; end; end. Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-04-24 23:01:01 UTC (rev 668) +++ trunk/Source/Core/InstantPersistence.pas 2006-04-25 08:12:33 UTC (rev 669) @@ -1695,6 +1695,11 @@ procedure InternalExecute; virtual; abstract; // Computes and returns the step's description. function GetDescription: string; virtual; + // Called if an exception occurs in InternalExecute. It should do + // whatever is needed to handle the error and return True if the exception + // needs to be trapped, otherwise it's re-raised. The default implementation + // just returns False. + function InternalExecuteHandleError(const E: Exception): Boolean; virtual; public constructor Create(const ACommandType: TInstantDBBuildCommandType; const AConnector: TInstantConnector = nil); @@ -15469,7 +15474,13 @@ procedure TInstantDBBuildCommand.Execute; begin - InternalExecute; + try + InternalExecute; + except + on E: Exception do + if not InternalExecuteHandleError(E) then + raise; + end; end; function TInstantDBBuildCommand.GetConnector: TInstantConnector; @@ -15490,6 +15501,12 @@ Result := Result + ']'; end; +function TInstantDBBuildCommand.InternalExecuteHandleError( + const E: Exception): Boolean; +begin + Result := False; +end; + { TInstantBrokerCatalog } constructor TInstantBrokerCatalog.Create(const AScheme: TInstantScheme; @@ -15643,8 +15660,7 @@ procedure TInstantUnsupportedDBBuildCommand.InternalExecute; begin - raise EInstantDBBuildError.CreateFmt(SCannotBuildDB, - [Description]); + raise EInstantDBBuildError.CreateFmt(SCannotBuildDB, [Description]); end; { TInstantCatalog } |
From: <fas...@us...> - 2006-04-24 23:01:11
|
Revision: 668 Author: fastbike2 Date: 2006-04-24 16:01:01 -0700 (Mon, 24 Apr 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=668&view=rev Log Message: ----------- Bug fix for #1475841 "TInstantContainer.Sort error if empty" Modified Paths: -------------- trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2006-04-24 11:25:52 UTC (rev 667) +++ trunk/Source/Core/InstantPersistence.pas 2006-04-24 23:01:01 UTC (rev 668) @@ -6817,7 +6817,8 @@ procedure TInstantContainer.Sort(Compare: TInstantSortCompare); begin - QuickSort(0, Pred(Count), Compare); + if Count > 1 then + QuickSort(0, Pred(Count), Compare); end; procedure TInstantContainer.ValidateObject(AObject: TInstantObject); |
From: <na...@us...> - 2006-04-24 11:26:29
|
Revision: 667 Author: nandod Date: 2006-04-24 04:25:52 -0700 (Mon, 24 Apr 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=667&view=rev Log Message: ----------- * [ 1475435 ] Dot character not supported in Id with XML broker. * removed some D2006 hints. * partially reformatted according to IO's coding conventions. Modified Paths: -------------- trunk/Source/Brokers/XML/InstantXML.pas Modified: trunk/Source/Brokers/XML/InstantXML.pas =================================================================== --- trunk/Source/Brokers/XML/InstantXML.pas 2006-04-11 01:05:38 UTC (rev 666) +++ trunk/Source/Brokers/XML/InstantXML.pas 2006-04-24 11:25:52 UTC (rev 667) @@ -35,8 +35,8 @@ {$ENDIF} {$IFDEF D6+} - {$WARN SYMBOL_PLATFORM OFF} - {$WARN UNIT_PLATFORM OFF} +{$WARN SYMBOL_PLATFORM OFF} +{$WARN UNIT_PLATFORM OFF} {$ENDIF} interface @@ -48,11 +48,12 @@ XML_UTF8_HEADER = '<?xml version="1.0" encoding="UTF-8"?>'; XML_ISO_HEADER = '<?xml version="1.0" encoding="ISO-8859-1"?>'; XML_EXT = 'xml'; - DOT_XML_EXT = '.'+XML_EXT; - XML_WILDCARD = '*'+DOT_XML_EXT; + DOT_XML_EXT = '.' + XML_EXT; + XML_WILDCARD = '*' + DOT_XML_EXT; {$IFNDEF LINUX} - {$IFDEF D5}PathDelim = '\';{$ENDIF} +{$IFDEF D5}PathDelim = '\'; {$ENDIF} +{$ENDIF} type TXMLFileFormat = (xffUtf8, xffUtf8BOT, xffIso); @@ -60,38 +61,52 @@ { TXMLFilesAccessor } TXMLFilesAccessor = class(TCustomConnection) private - FConnected : boolean; - FRootFolder : string; + FConnected: boolean; + FRootFolder: string; FUseVersioning: Boolean; FXMLFileFormat: TXMLFileFormat; - procedure MkStorageDir(const StorageName : string); + procedure MkStorageDir(const StorageName: string); function GetRootFolder: string; procedure SetRootFolder(const Value: string); - function SaveToFileXML_UTF8(AObject: TInstantObject; const FileName: string) : boolean; - function LoadFromFileXML_UTF8(AObject: TInstantObject; const FileName: string) : boolean; - function PlainObjectFileName(const StorageName, ClassName, Id: string): string; - function NewObjectFileName(const StorageName, ClassName, Id: string): string; - function DeleteObjectFileName(const StorageName, ClassName, Id: string): string; + function SaveToFileXML_UTF8(AObject: TInstantObject; const FileName: + string): boolean; + function LoadFromFileXML_UTF8(AObject: TInstantObject; const FileName: + string): boolean; + function PlainObjectFileName(const StorageName, ClassName, Id: string): + string; + function NewObjectFileName(const StorageName, ClassName, Id: string): + string; + function DeleteObjectFileName(const StorageName, ClassName, Id: string): + string; function VersionFromFilename(const longfilename: string): Integer; protected procedure DoConnect; override; procedure DoDisconnect; override; function GetConnected: Boolean; override; public - constructor Create (AOwner: TComponent); override; - function LastObjectFileName(const StorageName, ClassName, Id: string) : string; - function ReadInstantObject(AObject : TInstantObject; const StorageName, AObjectId: string; - out Version : integer): boolean; - function WriteInstantObject(AObject : TInstantObject; const StorageName: string; - out Version : integer): boolean; - function DeleteInstantObject(AObject : TInstantObject; const StorageName: string) : boolean; - function Locate(const StorageName, AObjectClassName, AObjectId: string): Boolean; - function CheckConflict (AObject : TInstantObject; const StorageName, AObjectId: string): Boolean; - procedure LoadFileList (FFileListAccessor: TStringList; const StorageName: string); + constructor Create(AOwner: TComponent); override; + function LastObjectFileName(const StorageName, ClassName, Id: string): + string; + function ReadInstantObject(AObject: TInstantObject; const StorageName, + AObjectId: string; + out Version: integer): boolean; + function WriteInstantObject(AObject: TInstantObject; const StorageName: + string; + out Version: integer): boolean; + function DeleteInstantObject(AObject: TInstantObject; const StorageName: + string): boolean; + function Locate(const StorageName, AObjectClassName, AObjectId: string): + Boolean; + function CheckConflict(AObject: TInstantObject; const StorageName, + AObjectId: string): Boolean; + procedure LoadFileList(FFileListAccessor: TStringList; const StorageName: + string); published - property RootFolder : string read GetRootFolder write SetRootFolder; - property UseVersioning: Boolean read FUseVersioning write FUseVersioning default False; - property XMLFileFormat: TXMLFileFormat read FXMLFileFormat write FXMLFileFormat default xffUtf8; + property RootFolder: string read GetRootFolder write SetRootFolder; + property UseVersioning: Boolean read FUseVersioning write FUseVersioning + default False; + property XMLFileFormat: TXMLFileFormat read FXMLFileFormat write + FXMLFileFormat default xffUtf8; end; TInstantXMLConnectionDef = class(TInstantConnectionBasedConnectionDef) @@ -106,9 +121,11 @@ class function ConnectionTypeName: string; override; class function ConnectorClass: TInstantConnectorClass; override; published - property RootFolder : string read FRootFolder write FRootFolder; - property UseVersioning: Boolean read FUseVersioning write FUseVersioning default False; - property XMLFileFormat: TXMLFileFormat read FXMLFileFormat write FXMLFileFormat default xffUtf8; + property RootFolder: string read FRootFolder write FRootFolder; + property UseVersioning: Boolean read FUseVersioning write FUseVersioning + default False; + property XMLFileFormat: TXMLFileFormat read FXMLFileFormat write + FXMLFileFormat default xffUtf8; end; TInstantXMLConnector = class(TInstantConnectionBasedConnector) @@ -128,7 +145,8 @@ class function ConnectionDefClass: TInstantConnectionDefClass; override; constructor Create(AOwner: TComponent); override; published - property Connection: TXMLFilesAccessor read GetConnection write SetConnection; + property Connection: TXMLFilesAccessor read GetConnection write + SetConnection; property UseTransactions default False; property LoginPrompt default False; end; @@ -145,16 +163,18 @@ function GetConnector: TInstantXMLConnector; protected function CreateCatalog(const AScheme: TInstantScheme): TInstantCatalog; - override; + override; function CreateResolver(const StorageName: string): TInstantXMLResolver; - function EnsureResolver(Map: TInstantAttributeMap): TInstantCustomResolver; override; + function EnsureResolver(Map: TInstantAttributeMap): TInstantCustomResolver; + override; function FindResolver(const StorageName: string): TInstantXMLResolver; property ResolverCount: Integer read GetResolverCount; property Resolvers[Index: Integer]: TInstantXMLResolver read GetResolvers; public destructor Destroy; override; - function CreateDBBuildCommand(const CommandType: TInstantDBBuildCommandType): - TInstantDBBuildCommand; override; + function CreateDBBuildCommand(const CommandType: + TInstantDBBuildCommandType): + TInstantDBBuildCommand; override; property Connector: TInstantXMLConnector read GetConnector; end; @@ -165,18 +185,27 @@ function CheckConflict(AObject: TInstantObject; const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; protected - procedure InternalDisposeMap(AObject: TInstantObject; Map: TInstantAttributeMap; - ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); override; - procedure InternalRetrieveMap(AObject: TInstantObject; const AObjectId: string; - Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); override; - procedure InternalStoreMap(AObject: TInstantObject; Map: TInstantAttributeMap; - ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); override; - procedure ResetAttributes(AObject: TInstantObject; Map: TInstantAttributeMap); - function Locate(AObject : TObject; const AObjectId: string): Boolean; virtual; - function ReadInstantObject(AObject : TInstantObject; const AObjectId: string; - out Version : integer): boolean; - function WriteInstantObject(AObject : TInstantObject; const AObjectId: string; - out Version : integer): boolean; + procedure InternalDisposeMap(AObject: TInstantObject; Map: + TInstantAttributeMap; + ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); + override; + procedure InternalRetrieveMap(AObject: TInstantObject; const AObjectId: + string; + Map: TInstantAttributeMap; ConflictAction: TInstantConflictAction; Info: + PInstantOperationInfo); override; + procedure InternalStoreMap(AObject: TInstantObject; Map: + TInstantAttributeMap; + ConflictAction: TInstantConflictAction; Info: PInstantOperationInfo); + override; + procedure ResetAttributes(AObject: TInstantObject; Map: + TInstantAttributeMap); + function Locate(AObject: TObject; const AObjectId: string): Boolean; + virtual; + function ReadInstantObject(AObject: TInstantObject; const AObjectId: string; + out Version: integer): boolean; + function WriteInstantObject(AObject: TInstantObject; const AObjectId: + string; + out Version: integer): boolean; public constructor Create(ABroker: TInstantCustomRelationalBroker; const AStorageName: string); @@ -186,7 +215,8 @@ TInstantXMLTranslator = class(TInstantRelationalTranslator) protected - function TranslateClassRef(ClassRef: TInstantIQLClassRef; Writer: TInstantIQLWriter): Boolean; override; + function TranslateClassRef(ClassRef: TInstantIQLClassRef; Writer: + TInstantIQLWriter): Boolean; override; end; TInstantXMLQuery = class(TInstantCustomRelationalQuery) @@ -198,7 +228,7 @@ function GetObjectReferenceCount: Integer; function GetObjectReferenceList: TObjectList; function GetObjectReferences(Index: Integer): TInstantObjectReference; - procedure InitObjectReferences(FileListAccessor : TStringList); + procedure InitObjectReferences(FileListAccessor: TStringList); function GetParamsObject: TParams; function GetConnector: TInstantXMLConnector; protected @@ -221,10 +251,11 @@ procedure SetStatement(const Value: string); override; property ObjectReferenceCount: Integer read GetObjectReferenceCount; property ObjectReferenceList: TObjectList read GetObjectReferenceList; - property ObjectReferences[Index: Integer]: TInstantObjectReference read GetObjectReferences; + property ObjectReferences[Index: Integer]: TInstantObjectReference read + GetObjectReferences; property ParamsObject: TParams read GetParamsObject; public - StorageName : string; + StorageName: string; destructor Destroy; override; property Connector: TInstantXMLConnector read GetConnector; end; @@ -274,44 +305,45 @@ SysUtils, InstantConsts, InstantClasses, TypInfo, InstantXMLCatalog, InstantXMLConnectionDefEdit, {$IFDEF MSWINDOWS} - {$IFDEF D5} - FileCtrl, - {$ENDIF} - Controls; +{$IFDEF D5} + FileCtrl, {$ENDIF} + Windows, Controls; +{$ENDIF} {$IFDEF LINUX} - QControls; +QControls; {$ENDIF} resourcestring SCannotCreateDirectory = 'Cannot create directory %s'; SCommandIndexOutOfBounds = 'Command index out of bounds.'; -function GetFileClassName(const FileName : string) : string; forward; -function GetFileId(const FileName : string) : string; forward; -function GetFileVersion(const FileName : string) : Integer; forward; +function GetFileClassName(const FileName: string): string; forward; +function GetFileId(const FileName: string): string; forward; +function GetFileVersion(const FileName: string): Integer; forward; {$IFDEF D5} -function IncludeTrailingPathDelimiter(const S : string) : string; + +function IncludeTrailingPathDelimiter(const S: string): string; begin Result := IncludeTrailingBackSlash(S); end; {$ENDIF} -procedure GlobalLoadFileList(const Path: string; FileList : TStringList); +procedure GlobalLoadFileList(const Path: string; FileList: TStringList); var - SearchRec : TSearchRec; - R : Integer; - PathWithWildCards : string; + SearchRec: TSearchRec; + R: Integer; + PathWithWildCards: string; begin FileList.Clear; - PathWithWildCards := IncludeTrailingPathDelimiter(Path)+XML_WILDCARD; + PathWithWildCards := IncludeTrailingPathDelimiter(Path) + XML_WILDCARD; //Find the first file - R := SysUtils.FindFirst( PathWithWildCards, faAnyFile, SearchRec ); + R := SysUtils.FindFirst(PathWithWildCards, faAnyFile, SearchRec); try while R = 0 do // file found! begin - FileList.Append( SearchRec.Name ); // Add file to list + FileList.Append(SearchRec.Name); // Add file to list R := SysUtils.FindNext(SearchRec); // Find next file end; finally @@ -322,13 +354,15 @@ // fill filelist with unique names of files, using the last version // number or skipping the deleted files (version = 0) // code badly needs to be optimized - marcoc -procedure GlobalLoadFileListLastVersion(const Path: string; FileList : TStringList); + +procedure GlobalLoadFileListLastVersion(const Path: string; FileList: + TStringList); var - i, currentVersion, activeVersionPos, newVersion : Integer; - currentid, shortFileName : string; + i, currentVersion, activeVersionPos, newVersion: Integer; + currentid, shortFileName: string; begin // first load all of them - GlobalLoadFileList (Path, FileList); + GlobalLoadFileList(Path, FileList); // now remove version duplicates and deleted documents FileList.Sorted := True; @@ -337,8 +371,8 @@ activeVersionPos := -1; for i := FileList.Count - 1 downto 0 do begin - shortFileName := extractFilename (filelist[i]); - if currentid = GetFileId (shortFileName) then + shortFileName := extractFilename(filelist[i]); + if currentid = GetFileId(shortFileName) then begin newVersion := GetFileVersion(shortFileName); // if the file is marked as deleted @@ -350,14 +384,13 @@ if activeVersionPos <> -1 then fileList.Delete(activeVersionPos); end - // if it is already marked as deleted, skip it + // if it is already marked as deleted, skip it else if currentVersion = 0 then begin fileList.Delete(i); end - // if the file is "newer" - else - if currentVersion < newVersion then + // if the file is "newer" + else if currentVersion < newVersion then begin // delete the other version, as this is newer CurrentVersion := GetFileVersion(shortFileName); @@ -371,7 +404,7 @@ end else // we have moved to a new objectid, reset all begin - currentid := GetFileId (shortFileName); + currentid := GetFileId(shortFileName); currentVersion := GetFileVersion(shortFileName); activeVersionPos := i; // if the first file of this instance is marked as deleted... @@ -381,29 +414,54 @@ end; end; -function GetFileClassName(const FileName : string) : string; +function RightPos(const ASubString, AString: string): Integer; +var + I: Integer; + SubStringLength: Integer; begin - Result := Copy(FileName,1,pos('.',FileName)-1); + Result := 0; + SubStringLength := Length(ASubString); + for I := Length(AString) - Length(ASubString) + 1 downto 1 do + begin + if Copy(AString, I, SubStringLength) = ASubString then + begin + Result := I; + Break; + end; + end; end; -function GetFileId(const FileName : string) : string; +function GetFileClassName(const FileName: string): string; begin - //File Name: ClassName.Id.UpdateCount.xml - Result := Copy(FileName,pos('.',FileName)+1,MaxInt); //Extract ClassName - Result := Copy(Result,1,pos('.',Result)-1); //Extract UpdateCount + // File Name: ClassName.Id.UpdateCount.xml + Result := Copy(FileName, 1, Pos('.', FileName) - 1); end; -function GetFileVersion(const FileName : string) : Integer; +function GetFileId(const FileName: string): string; var - s: string; + P: Integer; begin - //File Name: ClassName.Id.UpdateCount.xml - s := Copy(FileName,pos('.',FileName)+1,MaxInt); //Extract ClassName - s := Copy(s,pos('.',s)+1,MaxInt); //Extract Id - s := Copy(s,1,pos('.',s)-1); //Extract UpdateCount - Result := StrToIntDef (s, 0); + // File Name: ClassName.Id.UpdateCount.xml + // Drop ClassName and extension. + P := Pos('.', FileName); + Result := Copy(FileName, P + 1, RightPos('.', FileName) - P - 1); + // Drop UpdateCount. + Delete(Result, RightPos('.', Result), MaxInt); end; +function GetFileVersion(const FileName: string): Integer; +var + S: string; + P: Integer; +begin + // File Name: ClassName.Id.UpdateCount.xml + // Drop ClassName and extension. + P := Pos('.', FileName); + S := Copy(FileName, P + 1, RightPos('.', FileName) - P - 1); + // Drop Id. + Delete(S, 1, RightPos('.', S)); + Result := StrToIntDef(S, 0); +end; { TInstantXMLConnectionDef } @@ -445,7 +503,8 @@ const AObjectId: string; ConflictAction: TInstantConflictAction): Boolean; begin - Result := Broker.Connector.Connection.CheckConflict(AObject, FStorageName, AObjectId); + Result := Broker.Connector.Connection.CheckConflict(AObject, FStorageName, + AObjectId); if Result and (ConflictAction = caFail) then raise EInstantConflict.CreateFmt(SUpdateConflict, @@ -481,7 +540,7 @@ begin // Delete object file try - Broker.Connector.Connection.DeleteInstantObject (AObject, FStorageName); + Broker.Connector.Connection.DeleteInstantObject(AObject, FStorageName); Info.Success := True; Info.Conflict := not Info.Success; except @@ -489,7 +548,7 @@ raise; on E: Exception do begin -// TransError := TranslateError(AObject, E); + // TransError := TranslateError(AObject, E); TransError := nil; if Assigned(TransError) then raise TransError @@ -497,7 +556,8 @@ raise; end; end; - end else if Map.IsRootMap and (ConflictAction = caFail) then + end + else if Map.IsRootMap and (ConflictAction = caFail) then raise EInstantConflict.CreateFmt(SDisposeConflict, [AObject.ClassName, AObject.PersistentId]) end; @@ -524,7 +584,8 @@ begin Broker.SetObjectUpdateCount(AObject, Version); end; - end else + end + else ResetAttributes(AObject, Map); end; @@ -557,7 +618,7 @@ try if (ConflictAction = caIgnore) or not Info.Conflict then begin - Info.Success := WriteInstantObject(AObject,NewId,Version); + Info.Success := WriteInstantObject(AObject, NewId, Version); Info.Conflict := not Info.Success; if Map.IsRootMap then Broker.SetObjectUpdateCount(AObject, version); @@ -569,8 +630,9 @@ begin if E is EAbort then raise - else begin -// TransError := TranslateError(AObject, E); + else + begin + // TransError := TranslateError(AObject, E); TransError := nil; if Assigned(TransError) then raise TransError @@ -581,16 +643,19 @@ end; end; -function TInstantXMLResolver.Locate(AObject : TObject; const AObjectId: string): Boolean; +function TInstantXMLResolver.Locate(AObject: TObject; const AObjectId: string): + Boolean; begin Result := Broker.Connector.Connection.Locate( FStorageName, AObject.ClassName, AObjectId); end; -function TInstantXMLResolver.ReadInstantObject(AObject : TInstantObject; const AObjectId: string; - out Version : integer): boolean; +function TInstantXMLResolver.ReadInstantObject(AObject: TInstantObject; const + AObjectId: string; + out Version: integer): boolean; begin - Result := Broker.Connector.Connection.ReadInstantObject(AObject, FStorageName, AObjectId, Version); + Result := Broker.Connector.Connection.ReadInstantObject(AObject, FStorageName, + AObjectId, Version); end; procedure TInstantXMLResolver.ResetAttributes(AObject: TInstantObject; @@ -599,10 +664,12 @@ end; -function TInstantXMLResolver.WriteInstantObject(AObject: TInstantObject; const AObjectId: string; - out Version : integer): boolean; +function TInstantXMLResolver.WriteInstantObject(AObject: TInstantObject; const + AObjectId: string; + out Version: integer): boolean; begin - Result := Broker.Connector.Connection.WriteInstantObject(AObject, FStorageName, Version); + Result := Broker.Connector.Connection.WriteInstantObject(AObject, + FStorageName, Version); end; { TInstantXMLConnector } @@ -613,7 +680,8 @@ raise EPropertyError.Create(SUnassignedConnection); end; -class function TInstantXMLConnector.ConnectionDefClass: TInstantConnectionDefClass; +class function TInstantXMLConnector.ConnectionDefClass: + TInstantConnectionDefClass; begin Result := TInstantXMLConnectionDef; end; @@ -642,21 +710,22 @@ procedure TInstantXMLConnector.InternalBuildDatabase(Scheme: TInstantScheme); var - i : integer; - StorageName : string; + i: integer; + StorageName: string; begin CheckConnection; //build RootFolder if not exists if not DirectoryExists(Connection.RootFolder) and not ForceDirectories(Connection.RootFolder) then - raise EInOutError.CreateFmt(SCannotCreateDirectory, [Connection.RootFolder]); + raise EInOutError.CreateFmt(SCannotCreateDirectory, + [Connection.RootFolder]); //build SubFolder for each "storage name" - for i := 0 to Scheme.TableMetadataCount -1 do + for i := 0 to Scheme.TableMetadataCount - 1 do begin StorageName := Scheme.TableMetadatas[i].Name; - if not DirectoryExists(Connection.RootFolder+StorageName) then - MkDir(Connection.RootFolder+StorageName); + if not DirectoryExists(Connection.RootFolder + StorageName) then + MkDir(Connection.RootFolder + StorageName); end; end; @@ -701,13 +770,13 @@ end; function TInstantXMLBroker.CreateCatalog(const AScheme: TInstantScheme): - TInstantCatalog; + TInstantCatalog; begin Result := TInstantXMLCatalog.Create(AScheme, Self); end; function TInstantXMLBroker.CreateDBBuildCommand(const CommandType: - TInstantDBBuildCommandType): TInstantDBBuildCommand; + TInstantDBBuildCommandType): TInstantDBBuildCommand; begin if CommandType = ctAddTable then Result := TInstantDBBuildXMLAddTableCommand.Create(CommandType, Connector) @@ -752,7 +821,7 @@ function TInstantXMLBroker.GetResolverCount: Integer; begin - Result := ResolverList.Count; + Result := ResolverList.Count; end; function TInstantXMLBroker.GetResolverList: TObjectList; @@ -827,11 +896,12 @@ Result := FStatement; end; -procedure TInstantXMLQuery.InitObjectReferences(FileListAccessor : TStringList); +procedure TInstantXMLQuery.InitObjectReferences(FileListAccessor: TStringList); var - i : integer; + i: integer; - function CreateObjectReference(const FileName : string): TInstantObjectReference; + function CreateObjectReference(const FileName: string): + TInstantObjectReference; var ClassName, ObjectId: string; begin @@ -847,7 +917,7 @@ end; begin - for i := 0 to FileListAccessor.Count -1 do + for i := 0 to FileListAccessor.Count - 1 do begin ObjectReferenceList.Add(CreateObjectReference(FileListAccessor.Strings[i])); end; @@ -907,13 +977,13 @@ procedure TInstantXMLQuery.InternalOpen; var - FFileListAccessor : TStringList; + FFileListAccessor: TStringList; begin inherited; FFileListAccessor := TStringList.Create; try Connector.Connection.Open; - Connector.Connection.LoadFileList (FFileListAccessor, StorageName); + Connector.Connection.LoadFileList(FFileListAccessor, StorageName); InitObjectReferences(FFileListAccessor); finally FFileListAccessor.Free; @@ -975,7 +1045,8 @@ FStatement := Value; end; -class function TInstantXMLQuery.TranslatorClass: TInstantRelationalTranslatorClass; +class function TInstantXMLQuery.TranslatorClass: + TInstantRelationalTranslatorClass; begin Result := TInstantXMLTranslator; end; @@ -996,20 +1067,20 @@ end; function TXMLFilesAccessor.SaveToFileXML_UTF8(AObject: TInstantObject; - const FileName: string) : boolean; + const FileName: string): boolean; var strstream: TStringStream; fileStream: TFileStream; - DataStr : string; + DataStr: string; begin strstream := TStringStream.Create(''); try InstantWriteObject(strStream, sfXML, AObject); {$IFNDEF VER130} if FXMLFileFormat in [xffUtf8, xffUtf8Bot] then - DataStr := AnsiToUtf8(XML_UTF8_HEADER+strStream.DataString) + DataStr := AnsiToUtf8(XML_UTF8_HEADER + strStream.DataString) else - DataStr := XML_ISO_HEADER+strStream.DataString; + DataStr := XML_ISO_HEADER + strStream.DataString; {$ELSE} DataStr := strStream.DataString; {$ENDIF} @@ -1018,7 +1089,7 @@ end; fileStream := TFileStream.Create(FileName, fmCreate); try - Result := fileStream.Write (DataStr[1], Length (DataStr)) <> 0; + Result := fileStream.Write(DataStr[1], Length(DataStr)) <> 0; finally fileStream.Free; end; @@ -1036,7 +1107,7 @@ end; function TXMLFilesAccessor.LoadFromFileXML_UTF8(AObject: TInstantObject; - const FileName: string) : boolean; + const FileName: string): boolean; var fileStream: TFileStream; strUtf8: string; @@ -1046,20 +1117,20 @@ try // if FXMLFileFormat = xffUtf8Bot then // check/skip BOT - SetLength(strUtf8,fileStream.Size); - Result := fileStream.Read(strUtf8[1],fileStream.Size) <> 0; + SetLength(strUtf8, fileStream.Size); + Result := fileStream.Read(strUtf8[1], fileStream.Size) <> 0; // skip XML HEADER (until the parser is "dumb") - strUtf8 := RemoveXmlDeclaration (strUtf8); + strUtf8 := RemoveXmlDeclaration(strUtf8); finally fileStream.Free; end; {$IFNDEF VER130} if FXMLFileFormat in [xffUtf8, xffUtf8Bot] then - strUtf8 := Utf8ToAnsi (strUtf8); + strUtf8 := Utf8ToAnsi(strUtf8); {$ENDIF} - strstream := TStringStream.Create (strUtf8); + strstream := TStringStream.Create(strUtf8); try InstantReadObject(strstream, sfXML, AObject); finally @@ -1067,8 +1138,9 @@ end; end; -function TXMLFilesAccessor.ReadInstantObject(AObject : TInstantObject; const StorageName, AObjectId: string; - out Version : integer): boolean; +function TXMLFilesAccessor.ReadInstantObject(AObject: TInstantObject; const + StorageName, AObjectId: string; + out Version: integer): boolean; var filename: string; begin @@ -1080,17 +1152,18 @@ Version := VersionFromFilename(filename); end; -function TXMLFilesAccessor.WriteInstantObject(AObject : TInstantObject; const StorageName: string; - out Version : integer): boolean; +function TXMLFilesAccessor.WriteInstantObject(AObject: TInstantObject; const + StorageName: string; + out Version: integer): boolean; var filename: string; begin MkStorageDir(StorageName); if FUseVersioning then - filename := NewObjectFileName(StorageName,AObject.ClassName,AObject.Id) + filename := NewObjectFileName(StorageName, AObject.ClassName, AObject.Id) else - filename := PlainObjectFileName(StorageName,AObject.ClassName,AObject.Id); - Result := SavetoFileXML_UTF8(AObject,filename); + filename := PlainObjectFileName(StorageName, AObject.ClassName, AObject.Id); + Result := SavetoFileXML_UTF8(AObject, filename); Version := VersionFromFilename(filename); end; @@ -1114,8 +1187,8 @@ procedure TXMLFilesAccessor.MkStorageDir(const StorageName: string); begin - if not DirectoryExists(RootFolder+StorageName) then - MkDir(RootFolder+StorageName); + if not DirectoryExists(RootFolder + StorageName) then + MkDir(RootFolder + StorageName); end; function TXMLFilesAccessor.LastObjectFileName(const StorageName, ClassName, @@ -1125,34 +1198,36 @@ lastnum, nCurrent: Integer; begin if FindFirst( - RootFolder+StorageName+PathDelim+ClassName+'.'+Id+'.*'+DOT_XML_EXT, + RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.*' + + DOT_XML_EXT, faAnyFile, SR) = 0 then try - Result := RootFolder+StorageName+PathDelim+sr.Name; - lastnum := VersionFromFileName (sr.Name); + Result := RootFolder + StorageName + PathDelim + sr.Name; + lastnum := VersionFromFileName(sr.Name); while FindNext(sr) = 0 do begin nCurrent := VersionFromFilename(sr.Name); // version "zero" means the file has been deleted if (nCurrent = 0) then begin - Result := RootFolder+StorageName+PathDelim+sr.Name; + Result := RootFolder + StorageName + PathDelim + sr.Name; Break; end; if nCurrent > lastnum then begin lastnum := nCurrent; - Result := RootFolder+StorageName+PathDelim+sr.Name; + Result := RootFolder + StorageName + PathDelim + sr.Name; end; end; finally - FindClose (sr); + SysUtils.FindClose(sr); end else Result := ''; // not found, new object/file end; -function TXMLFilesAccessor.VersionFromFilename(const longfilename: string): Integer; +function TXMLFilesAccessor.VersionFromFilename(const longfilename: string): + Integer; begin Result := GetFileVersion(ExtractFileName(longfilename)); end; @@ -1169,7 +1244,7 @@ filename := LastObjectFileName(storagename, ClassName, Id); if filename <> '' then begin - nVersion := VersionFromFilename (filename); + nVersion := VersionFromFilename(filename); inc(nVersion); end else @@ -1180,22 +1255,24 @@ filename := PlainObjectFileName(StorageName, ClassName, Id); nVersion := 1; // no version always 1 end; - Result := RootFolder+StorageName+PathDelim+ClassName+'.'+Id+'.'+IntToStr(nVersion)+DOT_XML_EXT; + Result := RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.' + + IntToStr(nVersion) + DOT_XML_EXT; end; function TXMLFilesAccessor.DeleteInstantObject(AObject: TInstantObject; - const StorageName: string) : boolean; + const StorageName: string): boolean; begin if UseVersioning then begin // save the document once more with 0 in the version name Result := SavetoFileXML_UTF8(AObject, - DeleteObjectFileName(StorageName,AObject.ClassName,AObject.Id)); + DeleteObjectFileName(StorageName, AObject.ClassName, AObject.Id)); end else begin // delete file from disk - Result := DeleteFile(PlainObjectFileName(StorageName,AObject.ClassName,AObject.Id)); + Result := SysUtils.DeleteFile(PlainObjectFileName(StorageName, + AObject.ClassName, AObject.Id)); end; end; @@ -1203,8 +1280,8 @@ ClassName, Id: string): string; begin // mark deleted file as version 0 - Result := RootFolder+StorageName+PathDelim+ClassName+'.'+Id+'.'+ - IntToStr (0)+DOT_XML_EXT; + Result := RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.' + + IntToStr(0) + DOT_XML_EXT; end; constructor TXMLFilesAccessor.Create(AOwner: TComponent); @@ -1221,7 +1298,8 @@ begin // ignore versioning //FileName: ClassName.Id.UpdateCount.xml - Result := RootFolder+StorageName+PathDelim+ClassName+'.'+Id+'.1'+DOT_XML_EXT; + Result := RootFolder + StorageName + PathDelim + ClassName + '.' + Id + '.1' + + DOT_XML_EXT; end; function TXMLFilesAccessor.CheckConflict(AObject: TInstantObject; @@ -1240,7 +1318,8 @@ Result := False; // don't care about updatecount and versioning end; -procedure TXMLFilesAccessor.LoadFileList(FFileListAccessor: TStringList; const StorageName: string); +procedure TXMLFilesAccessor.LoadFileList(FFileListAccessor: TStringList; const + StorageName: string); //var // xmldom: TGeoXslProcess; - to be finished by marcoc //strXPath, - to be finished by marcoc @@ -1248,9 +1327,9 @@ // posOpenSquare, posCloseSquare: Integer; begin if FUseVersioning then - GlobalLoadFileListLastVersion (RootFolder + StorageName, FFileListAccessor) + GlobalLoadFileListLastVersion(RootFolder + StorageName, FFileListAccessor) else - GlobalLoadFileList (RootFolder + StorageName, FFileListAccessor); + GlobalLoadFileList(RootFolder + StorageName, FFileListAccessor); // tentative XPATH support by marcoc {posOpenSquare := Pos ('[', Statement); - to be finished by marcoc @@ -1328,14 +1407,14 @@ end; function TInstantDBBuildXMLAddTableCommand.GetTableMetadata: - TInstantTableMetadata; + TInstantTableMetadata; begin Result := NewMetadata as TInstantTableMetadata; end; procedure TInstantDBBuildXMLAddTableCommand.InternalExecute; var - vDatabaseName: String; + vDatabaseName: string; begin Connector.CheckConnection; vDatabaseName := Connector.DatabaseName; @@ -1351,16 +1430,16 @@ end; function TInstantDBBuildXMLDropTableCommand.GetTableMetadata: - TInstantTableMetadata; + TInstantTableMetadata; begin Result := OldMetadata as TInstantTableMetadata; end; procedure TInstantDBBuildXMLDropTableCommand.InternalExecute; var - vTableName: String; + vTableName: string; sr: TSearchRec; - vDatabaseName: String; + vDatabaseName: string; begin Connector.CheckConnection; vDatabaseName := Connector.DatabaseName; @@ -1372,20 +1451,20 @@ if FindFirst(vTableName + '\*.*', faAnyFile, sr) = 0 then begin repeat - DeleteFile(vTableName + '\' + sr.Name); + SysUtils.DeleteFile(vTableName + '\' + sr.Name); until FindNext(sr) <> 0; - FindClose(sr); + SysUtils.FindClose(sr); end; RemoveDir(vTableName); end; end; - initialization - RegisterClass(TInstantXMLConnectionDef); + Classes.RegisterClass(TInstantXMLConnectionDef); TInstantXMLConnector.RegisterClass; finalization TInstantXMLConnector.UnregisterClass; end. + |
From: <sr...@us...> - 2006-04-11 01:05:46
|
Revision: 666 Author: srmitch Date: 2006-04-10 18:05:38 -0700 (Mon, 10 Apr 2006) ViewCVS: http://svn.sourceforge.net/instantobjects?rev=666&view=rev Log Message: ----------- Fix for bug #1467511 in SF BT. Bug Symptom(s): Currently, when adding a new attribute in ModelMaker, in the attribute editor there aren't field types other than "part" and "parts" available. Bug Cause: The current code in InstantAttributeEditor does not check to see if the attribute is a Complex type before restricting the types loaded. Fix affects: <<InstantAttributeEditor.pas>> procedure TInstantAttributeEditorForm.LoadTypes. Modified Paths: -------------- trunk/Source/Design/InstantAttributeEditor.pas Modified: trunk/Source/Design/InstantAttributeEditor.pas =================================================================== --- trunk/Source/Design/InstantAttributeEditor.pas 2006-04-10 18:55:03 UTC (rev 665) +++ trunk/Source/Design/InstantAttributeEditor.pas 2006-04-11 01:05:38 UTC (rev 666) @@ -282,6 +282,20 @@ end; procedure TInstantAttributeEditorForm.LoadTypes; + + procedure RestrictForComplexAttr; + var + I: Integer; + begin + for I := Pred(TypeEdit.Items.Count) downto 0 do + if not ((TypeEdit.Items[I] = 'Part') or + (TypeEdit.Items[I] = 'Parts') or + (IsClassPersistent(ObjectClassEdit.Text) and + ((TypeEdit.Items[I] = 'Reference') or + (TypeEdit.Items[I] = 'References')))) then + TypeEdit.Items.Delete(I); + end; + var I: Integer; begin @@ -292,14 +306,8 @@ I := TypeEdit.Items.IndexOf('Unknown'); if I <> -1 then TypeEdit.Items.Delete(I); - if not Assigned(FModel) then - for I := Pred(TypeEdit.Items.Count) downto 0 do - if not ((TypeEdit.Items[I] = 'Part') or - (TypeEdit.Items[I] = 'Parts') or - (IsClassPersistent(ObjectClassEdit.Text) and - ((TypeEdit.Items[I] = 'Reference') or - (TypeEdit.Items[I] = 'References')))) then - TypeEdit.Items.Delete(I); + if not Assigned(FModel) and Subject.IsComplex then + RestrictForComplexAttr; finally TypeEdit.Items.EndUpdate; end; |