From: <na...@us...> - 2010-11-13 09:57:20
|
Revision: 935 http://instantobjects.svn.sourceforge.net/instantobjects/revision/?rev=935&view=rev Author: nandod Date: 2010-11-13 09:57:14 +0000 (Sat, 13 Nov 2010) Log Message: ----------- * Burst mode fixes. Bad interactions with the statement cache fixed. Modified Paths: -------------- trunk/Source/Core/InstantBrokers.pas trunk/Source/Core/InstantClasses.pas trunk/Source/Core/InstantPersistence.pas Modified: trunk/Source/Core/InstantBrokers.pas =================================================================== --- trunk/Source/Core/InstantBrokers.pas 2010-11-13 09:56:04 UTC (rev 934) +++ trunk/Source/Core/InstantBrokers.pas 2010-11-13 09:57:14 UTC (rev 935) @@ -1,4 +1,4 @@ -(* + (* * InstantObjects * Broker and Connector Classes *) @@ -624,11 +624,14 @@ // An item in the statement cache. TInstantStatement = class private - FStatementImplementation: TComponent; + FStatementDataSet: TDataSet; + FDataSetRefCount: Integer; public - constructor Create(const AStatementImplementation: TComponent); + constructor Create(const AStatementDataSet: TDataSet); destructor Destroy; override; - property StatementImplementation: TComponent read FStatementImplementation; + property StatementDataSet: TDataSet read FStatementDataSet; + function AddDataSetRef: Integer; + function ReleaseDataSetRef: Integer; end; // Caches objects that implement command statements in releational brokers. @@ -650,10 +653,11 @@ property Capacity: Integer read FCapacity write SetCapacity; destructor Destroy; override; function GetStatement(const StatementText: string): TInstantStatement; + function IndexOfStatementDataSet(const StatementDataSet: TDataSet): Integer; + function GetStatementByIndex(const AIndex: Integer): TInstantStatement; function AddStatement(const StatementText: string; - const StatementImplementation: TComponent): Integer; + const StatementDataSet: TDataSet): Integer; function RemoveStatement(const StatementText: string): Boolean; - function HasStatementImplementation(const StatementImplementation: TComponent): Boolean; end; // A TInstantCatalog that gathers its info from an existing database (through @@ -1006,6 +1010,9 @@ FDataSet: TDataSet; FRecNo: Integer; FIdField: TField; + protected + procedure Notification(AComponent: TComponent; Operation: TOperation); + override; public constructor CreateAndInit(const ADataSet: TDataSet); property DataSet: TDataSet read FDataSet; @@ -1044,6 +1051,8 @@ procedure SetParams(Value: TParams); override; function ObjectFetched(Index: Integer): Boolean; override; procedure SetStatement(const Value: string); override; + procedure Notification(AComponent: TComponent; Operation: TOperation); + override; property ObjectReferenceCount: Integer read GetObjectReferenceCount; property ObjectReferenceList: TInstantObjectReferenceList read GetObjectReferenceList; @@ -1454,8 +1463,25 @@ CachedStatement := StatementCache.GetStatement(AStatement); if Assigned(CachedStatement) then begin - Result := TDataSet(CachedStatement.StatementImplementation); - AssignDataSetParams(Result, AParams); + Result := TDataSet(CachedStatement.StatementDataSet); + // The dataset might be already open to serve a burst mode retrieval, + // in which case we can reuse it unless it's parametric. + if Result.Active then + begin + if AParams.Count = 0 then + Result.First + else + begin + Result.Close; + AssignDataSetParams(Result, AParams); + Result.Open; + end; + end + else + begin + AssignDataSetParams(Result, AParams); + Result.Open; + end; end; end; if not Assigned(Result) then @@ -1565,11 +1591,22 @@ end; procedure TInstantSQLBroker.ReleaseDataSet(const ADataSet: TDataSet); +var + I: Integer; + LStatement: TInstantStatement; begin - if Assigned(FStatementCache) and FStatementCache.HasStatementImplementation(ADataSet) then - ADataSet.Close - else - ADataSet.Free; + if Assigned(FStatementCache) then + begin + I := FStatementCache.IndexOfStatementDataSet(ADataSet); + if I >= 0 then + begin + LStatement := FStatementCache.GetStatementByIndex(I); + if LStatement.ReleaseDataSetRef <= 0 then + ADataSet.Close; + Exit; + end; + end; + ADataSet.Free; end; { TInstantRelationalConnector } @@ -4378,18 +4415,31 @@ { TInstantStatement } -constructor TInstantStatement.Create(const AStatementImplementation: TComponent); +function TInstantStatement.AddDataSetRef: Integer; begin + Inc(FDataSetRefCount); + Result := FDataSetRefCount; +end; + +constructor TInstantStatement.Create(const AStatementDataSet: TDataSet); +begin inherited Create; - FStatementImplementation := AStatementImplementation; + FStatementDataSet := AStatementDataSet; + FDataSetRefCount := 1; end; destructor TInstantStatement.Destroy; begin - FStatementImplementation.Free; + FStatementDataSet.Free; inherited; end; +function TInstantStatement.ReleaseDataSetRef: Integer; +begin + Dec(FDataSetRefCount); + Result := FDataSetRefCount; +end; + { TInstantStatementCache } constructor TInstantStatementCache.Create(AOwner: TComponent); @@ -4409,16 +4459,16 @@ end; function TInstantStatementCache.AddStatement(const StatementText: string; - const StatementImplementation: TComponent): Integer; + const StatementDataSet: TDataSet): Integer; var StatementObject: TInstantStatement; begin - if Assigned(StatementImplementation) then + if Assigned(StatementDataSet) then begin Shrink; - StatementObject := TInstantStatement.Create(StatementImplementation); + StatementObject := TInstantStatement.Create(StatementDataSet); Result := FStatements.AddObject(StatementText, StatementObject); - StatementImplementation.FreeNotification(Self); + StatementDataSet.FreeNotification(Self); end else Result := -1; @@ -4448,22 +4498,31 @@ begin Index := FStatements.IndexOf(StatementText); if Index >= 0 then - Result := TInstantStatement(FStatements.Objects[Index]) + begin + Result := TInstantStatement(FStatements.Objects[Index]); + Result.AddDataSetRef; + end else Result := nil; end; -function TInstantStatementCache.HasStatementImplementation( - const StatementImplementation: TComponent): Boolean; +function TInstantStatementCache.GetStatementByIndex( + const AIndex: Integer): TInstantStatement; +begin + Result := TinstantStatement(FStatements.Objects[AIndex]); +end; + +function TInstantStatementCache.IndexOfStatementDataSet( + const StatementDataSet: TDataSet): Integer; var I: Integer; begin - Result := False; + Result := -1; for I := 0 to FStatements.Count - 1 do begin - if TinstantStatement(FStatements.Objects[I]).StatementImplementation = StatementImplementation then + if TinstantStatement(FStatements.Objects[I]).StatementDataSet = StatementDataSet then begin - Result := True; + Result := I; Break; end; end; @@ -4476,7 +4535,7 @@ inherited; if Operation = opRemove then for I := FStatements.Count - 1 downto 0 do - if TInstantStatement(FStatements.Objects[I]).StatementImplementation = AComponent then + if TInstantStatement(FStatements.Objects[I]).StatementDataSet = AComponent then DeleteStatement(I); end; @@ -6055,6 +6114,7 @@ FDataSet := AcquireDataSet(Statement, ParamsObject); if Assigned(FDataSet) then try + FDataSet.FreeNotification(Self); if not FDataSet.Active then FDataSet.Open; InitObjectReferences; @@ -6078,6 +6138,14 @@ Result := ObjectReferenceList.Remove(AObject as TInstantObject); end; +procedure TInstantSQLQuery.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited; + if (Operation = opRemove) and (AComponent = FDataSet) then + FDataSet := nil; +end; + function TInstantSQLQuery.ObjectFetched(Index: Integer): Boolean; begin Result := ObjectReferenceList.RefItems[Index].HasInstance; @@ -6772,7 +6840,8 @@ constructor TInstantDataSetObjectData.CreateAndInit(const ADataSet: TDataSet); begin Assert(Assigned(ADataSet)); - Create; + Create(nil); + ADataSet.FreeNotification(Self); FDataSet := ADataSet; FRecNo := ADataSet.RecNo; FIdField := ADataSet.FieldByName(InstantIdFieldName); @@ -6780,8 +6849,21 @@ function TInstantDataSetObjectData.Locate(const AObjectId: string): Boolean; begin - FDataSet.RecNo := FRecNo; - Result := FIdField.AsString = AObjectId; + if not Assigned(FDataSet) or not FDataSet.Active then + Result := False + else + begin + FDataSet.RecNo := FRecNo; + Result := FIdField.AsString = AObjectId; + end; end; +procedure TInstantDataSetObjectData.Notification(AComponent: TComponent; + Operation: TOperation); +begin + inherited; + if (Operation = opRemove) and (AComponent = FDataSet) then + FDataSet := nil; +end; + end. Modified: trunk/Source/Core/InstantClasses.pas =================================================================== --- trunk/Source/Core/InstantClasses.pas 2010-11-13 09:56:04 UTC (rev 934) +++ trunk/Source/Core/InstantClasses.pas 2010-11-13 09:57:14 UTC (rev 935) @@ -399,7 +399,7 @@ TInstantAbstractObjectClass = class of TInstantAbstractObject; - TInstantAbstractObjectData = class(TInstantStreamable); + TInstantAbstractObjectData = class(TComponent); TInstantAbstractObject = class(TInstantStreamable) private Modified: trunk/Source/Core/InstantPersistence.pas =================================================================== --- trunk/Source/Core/InstantPersistence.pas 2010-11-13 09:56:04 UTC (rev 934) +++ trunk/Source/Core/InstantPersistence.pas 2010-11-13 09:57:14 UTC (rev 935) @@ -1144,7 +1144,7 @@ procedure InternalExecute; override; end; - TInstantQuery = class(TPersistent) + TInstantQuery = class(TComponent) private FCommand: string; FConnector: TInstantConnector; @@ -7704,7 +7704,7 @@ constructor TInstantQuery.Create(AConnector: TInstantConnector); begin - inherited Create; + inherited Create(nil); FConnector := AConnector; end; |