mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 14:19:31 +02:00
* Fixed Master/Detail relation in SQLDB and fixed memory leak
git-svn-id: trunk@25055 -
This commit is contained in:
parent
2cdb4adf39
commit
087b6b4a39
@ -355,6 +355,7 @@ end;
|
||||
|
||||
procedure TIBConnection.DoInternalDisconnect;
|
||||
begin
|
||||
Inherited;
|
||||
FDialect := INVALID_DATA;
|
||||
if not Connected then
|
||||
begin
|
||||
|
@ -41,10 +41,12 @@ type
|
||||
WhereStopPos : integer;
|
||||
end;
|
||||
|
||||
|
||||
type
|
||||
TSQLConnection = class;
|
||||
TSQLTransaction = class;
|
||||
TCustomSQLQuery = class;
|
||||
TCustomSQLStatement = Class;
|
||||
TSQLQuery = class;
|
||||
TSQLScript = class;
|
||||
|
||||
@ -106,7 +108,7 @@ type
|
||||
FHostName : string;
|
||||
FCharSet : string;
|
||||
FRole : String;
|
||||
|
||||
FStatements : TFPList;
|
||||
function GetPort: cardinal;
|
||||
function GetStatementInfo(const ASQL: string; Full: Boolean; ASchema : TSchemaType): TSQLStatementInfo;
|
||||
procedure SetPort(const AValue: cardinal);
|
||||
@ -126,6 +128,8 @@ type
|
||||
Function AllocateCursorHandle : TSQLCursor; virtual; abstract;
|
||||
Procedure DeAllocateCursorHandle(var cursor : TSQLCursor); virtual; abstract;
|
||||
Function AllocateTransactionHandle : TSQLHandle; virtual; abstract;
|
||||
Procedure RegisterStatement(S : TCustomSQLStatement);
|
||||
Procedure UnRegisterStatement(S : TCustomSQLStatement);
|
||||
|
||||
procedure PrepareStatement(cursor: TSQLCursor;ATransaction : TSQLTransaction;buf : string; AParams : TParams); virtual; abstract;
|
||||
procedure Execute(cursor: TSQLCursor;atransaction:tSQLtransaction; AParams : TParams); virtual; abstract;
|
||||
@ -145,6 +149,7 @@ type
|
||||
function GetSchemaInfoSQL(SchemaType : TSchemaType; SchemaObjectName, SchemaPattern : string) : string; virtual;
|
||||
procedure LoadBlobIntoBuffer(FieldDef: TFieldDef;ABlobBuf: PBufBlobField; cursor: TSQLCursor; ATransaction : TSQLTransaction); virtual; abstract;
|
||||
function RowsAffected(cursor: TSQLCursor): TRowsCount; virtual;
|
||||
Property Statements : TFPList Read FStatements;
|
||||
property Port: cardinal read GetPort write SetPort;
|
||||
public
|
||||
property Handle: Pointer read GetHandle;
|
||||
@ -224,17 +229,19 @@ type
|
||||
FOrigSQL : String;
|
||||
FServerSQL : String;
|
||||
FTransaction: TSQLTransaction;
|
||||
FDatasource : TDatasource;
|
||||
FParseSQL: Boolean;
|
||||
FDataLink : TDataLink;
|
||||
procedure SetDatabase(AValue: TSQLConnection);
|
||||
procedure SetParams(AValue: TParams);
|
||||
procedure SetSQL(AValue: TStrings);
|
||||
procedure SetTransaction(AValue: TSQLTransaction);
|
||||
Function GetPrepared : Boolean;
|
||||
Protected
|
||||
Function CreateDataLink : TDataLink; virtual;
|
||||
procedure OnChangeSQL(Sender : TObject); virtual;
|
||||
function GetDataSource: TDatasource; Virtual;
|
||||
procedure SetDataSource(AValue: TDatasource); virtual;
|
||||
Procedure CopyParamsFromMaster(CopyBound : Boolean); virtual;
|
||||
procedure AllocateCursor;
|
||||
procedure DeAllocateCursor;
|
||||
Function GetSchemaType : TSchemaType; virtual;
|
||||
@ -285,7 +292,6 @@ type
|
||||
private
|
||||
// FCheckParams: Boolean;
|
||||
// FCursor : TSQLCursor;
|
||||
FParams: TParams;
|
||||
FSchemaType: TSchemaType;
|
||||
// FSQL: TStringlist;
|
||||
FUpdateable : boolean;
|
||||
@ -673,13 +679,18 @@ end;
|
||||
|
||||
procedure TCustomSQLStatement.SetDataSource(AValue: TDatasource);
|
||||
|
||||
|
||||
begin
|
||||
if FDatasource=AValue then Exit;
|
||||
If Assigned(FDatasource) then
|
||||
FDatasource.RemoveFreeNotification(Self);
|
||||
FDatasource:=AValue;
|
||||
If Assigned(FDatasource) then
|
||||
FDatasource.FreeNotification(Self);
|
||||
if GetDatasource=AValue then Exit;
|
||||
if (FDataLink=Nil) then
|
||||
FDataLink:=CreateDataLink;
|
||||
FDataLink.DataSource:=AValue;
|
||||
end;
|
||||
|
||||
procedure TCustomSQLStatement.CopyParamsFromMaster(CopyBound : Boolean);
|
||||
begin
|
||||
if Assigned(DataSource) and Assigned(DataSource.Dataset) then
|
||||
FParams.CopyParamValuesFromDataset(DataSource.Dataset,CopyBound);
|
||||
end;
|
||||
|
||||
procedure TCustomSQLStatement.SetParams(AValue: TParams);
|
||||
@ -711,8 +722,8 @@ end;
|
||||
|
||||
procedure TCustomSQLStatement.DoExecute;
|
||||
begin
|
||||
If (FParams.Count>0) and Assigned(FDatasource) then
|
||||
; // FMasterLink.CopyParamsFromMaster(False);
|
||||
If (FParams.Count>0) and Assigned(Datasource) then
|
||||
CopyParamsFromMaster(False);
|
||||
If LogEvent(detExecute) then
|
||||
Log(detExecute,FServerSQL);
|
||||
Database.Execute(FCursor,Transaction, FParams);
|
||||
@ -723,6 +734,11 @@ begin
|
||||
Result := Assigned(FCursor) and FCursor.FPrepared;
|
||||
end;
|
||||
|
||||
function TCustomSQLStatement.CreateDataLink: TDataLink;
|
||||
begin
|
||||
Result:=TDataLink.Create;
|
||||
end;
|
||||
|
||||
function TCustomSQLStatement.CreateParams: TParams;
|
||||
begin
|
||||
Result:=TParams.Create(Nil);
|
||||
@ -756,7 +772,10 @@ begin
|
||||
If (AComponent=FTransaction) then
|
||||
FTransaction:=Nil
|
||||
else if (AComponent=FDatabase) then
|
||||
begin
|
||||
UnPrepare;
|
||||
FDatabase:=Nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TCustomSQLStatement.Create(AOwner: TComponent);
|
||||
@ -774,6 +793,8 @@ begin
|
||||
UnPrepare;
|
||||
Transaction:=Nil;
|
||||
Database:=Nil;
|
||||
DataSource:=Nil;
|
||||
FreeAndNil(FDataLink);
|
||||
FreeAndNil(Fparams);
|
||||
FreeAndNil(FSQL);
|
||||
inherited Destroy;
|
||||
@ -812,13 +833,20 @@ procedure TCustomSQLStatement.AllocateCursor;
|
||||
|
||||
begin
|
||||
if not assigned(FCursor) then
|
||||
begin
|
||||
// Do this as late as possible.
|
||||
FCursor:=Database.AllocateCursorHandle;
|
||||
FDatabase.RegisterStatement(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSQLStatement.DeAllocateCursor;
|
||||
begin
|
||||
if Assigned(FCursor) and Assigned(Database) then
|
||||
begin
|
||||
DataBase.DeAllocateCursorHandle(FCursor);
|
||||
Database.UnRegisterStatement(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomSQLStatement.DoPrepare;
|
||||
@ -861,7 +889,7 @@ begin
|
||||
DoPrepare;
|
||||
except
|
||||
if assigned(FCursor) then
|
||||
DataBase.DeAllocateCursorHandle(FCursor);
|
||||
DeAllocateCursor;
|
||||
Raise;
|
||||
end;
|
||||
end;
|
||||
@ -887,7 +915,10 @@ end;
|
||||
|
||||
function TCustomSQLStatement.GetDataSource: TDatasource;
|
||||
begin
|
||||
Result:=FDatasource;
|
||||
if Assigned(FDataLink) then
|
||||
Result:=FDataLink.Datasource
|
||||
else
|
||||
Result:=Nil;
|
||||
end;
|
||||
|
||||
procedure TCustomSQLStatement.Unprepare;
|
||||
@ -950,11 +981,19 @@ begin
|
||||
end;
|
||||
|
||||
procedure TSQLConnection.DoInternalDisconnect;
|
||||
|
||||
Var
|
||||
I : integer;
|
||||
|
||||
begin
|
||||
For I:=0 to FStatements.Count-1 do
|
||||
TCustomSQLStatement(FStatements[i]).Unprepare;
|
||||
end;
|
||||
|
||||
destructor TSQLConnection.Destroy;
|
||||
begin
|
||||
Connected:=False; // needed because we want to de-allocate statements
|
||||
FreeAndNil(FStatements);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -974,13 +1013,14 @@ begin
|
||||
Transaction.EndTransaction;
|
||||
end;
|
||||
|
||||
Procedure TSQLConnection.ExecuteDirect(SQL: String);
|
||||
procedure TSQLConnection.ExecuteDirect(SQL: String);
|
||||
|
||||
begin
|
||||
ExecuteDirect(SQL,FTransaction);
|
||||
end;
|
||||
|
||||
Procedure TSQLConnection.ExecuteDirect(SQL: String; ATransaction : TSQLTransaction);
|
||||
procedure TSQLConnection.ExecuteDirect(SQL: String;
|
||||
ATransaction: TSQLTransaction);
|
||||
|
||||
var Cursor : TSQLCursor;
|
||||
|
||||
@ -1059,6 +1099,7 @@ begin
|
||||
inherited Create(AOwner);
|
||||
FSQLFormatSettings:=DefaultSQLFormatSettings;
|
||||
FFieldNameQuoteChars:=DoubleQuotes;
|
||||
FStatements:=TFPList.Create;
|
||||
end;
|
||||
|
||||
procedure TSQLConnection.GetTableNames(List: TStrings; SystemTables: Boolean);
|
||||
@ -1162,6 +1203,17 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSQLConnection.RegisterStatement(S: TCustomSQLStatement);
|
||||
begin
|
||||
if FStatements.IndexOf(S)=-1 then
|
||||
FStatements.Add(S);
|
||||
end;
|
||||
|
||||
procedure TSQLConnection.UnRegisterStatement(S: TCustomSQLStatement);
|
||||
begin
|
||||
FStatements.Remove(S);
|
||||
end;
|
||||
|
||||
procedure TSQLConnection.FreeFldBuffers(cursor: TSQLCursor);
|
||||
begin
|
||||
// empty
|
||||
@ -1631,7 +1683,8 @@ begin
|
||||
end;
|
||||
*)
|
||||
|
||||
Function TSQLConnection.GetStatementInfo(const ASQL : string; Full : Boolean; ASchema : TSchemaType) : TSQLStatementInfo;
|
||||
function TSQLConnection.GetStatementInfo(const ASQL: string; Full: Boolean;
|
||||
ASchema: TSchemaType): TSQLStatementInfo;
|
||||
|
||||
|
||||
type TParsePart = (ppStart,ppWith,ppSelect,ppTableName,ppFrom,ppWhere,ppGroup,ppOrder,ppBogus);
|
||||
@ -1903,39 +1956,20 @@ Type
|
||||
|
||||
TQuerySQLStatement = Class(TCustomSQLStatement)
|
||||
protected
|
||||
FMasterLink: TMasterParamsDataLink;
|
||||
FQuery : TCustomSQLQuery;
|
||||
function GetDataSource: TDatasource; override;
|
||||
procedure SetDataSource(AValue: TDatasource); override;
|
||||
Function CreateDataLink : TDataLink; override;
|
||||
Function GetSchemaType : TSchemaType; override;
|
||||
Function GetSchemaObjectName : String; override;
|
||||
Function GetSchemaPattern: String; override;
|
||||
procedure GetStatementInfo(Var ASQL: String; Full: Boolean; ASchema: TSchemaType; out Info: TSQLStatementInfo); override;
|
||||
procedure OnChangeSQL(Sender : TObject); override;
|
||||
Public
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
{ TQuerySQLStatement }
|
||||
|
||||
function TQuerySQLStatement.GetDataSource: TDatasource;
|
||||
function TQuerySQLStatement.CreateDataLink: TDataLink;
|
||||
begin
|
||||
Result:=inherited GetDataSource;
|
||||
|
||||
end;
|
||||
|
||||
procedure TQuerySQLStatement.SetDataSource(AValue: TDatasource);
|
||||
begin
|
||||
inherited SetDataSource(AValue);
|
||||
If Assigned(AValue) then
|
||||
begin
|
||||
AValue.FreeNotification(Self);
|
||||
If (FMasterLink=Nil) then
|
||||
FMasterLink:=TMasterParamsDataLink.Create(FQuery);
|
||||
FMasterLink.Datasource:=AValue;
|
||||
end
|
||||
else
|
||||
FreeAndNil(FMasterLink);
|
||||
Result:=TMasterParamsDataLink.Create(FQuery);
|
||||
end;
|
||||
|
||||
function TQuerySQLStatement.GetSchemaType: TSchemaType;
|
||||
@ -1981,17 +2015,11 @@ procedure TQuerySQLStatement.OnChangeSQL(Sender: TObject);
|
||||
begin
|
||||
UnPrepare;
|
||||
inherited OnChangeSQL(Sender);
|
||||
If CheckParams and Assigned(FMasterLink) then
|
||||
FMasterLink.RefreshParamNames;
|
||||
If CheckParams and Assigned(FDataLink) then
|
||||
(FDataLink as TMasterParamsDataLink).RefreshParamNames;
|
||||
FQuery.ServerIndexDefs.Updated:=false;
|
||||
end;
|
||||
|
||||
destructor TQuerySQLStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FMasterLink);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
constructor TCustomSQLQuery.Create(AOwner : TComponent);
|
||||
|
||||
Var
|
||||
@ -1999,7 +2027,6 @@ Var
|
||||
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FParams := TParams.create(self);
|
||||
F:=TQuerySQLStatement.Create(Self);
|
||||
F.FQuery:=Self;
|
||||
FStatement:=F;
|
||||
@ -2034,7 +2061,6 @@ begin
|
||||
if Active then Close;
|
||||
UnPrepare;
|
||||
FreeAndNil(Fstatement);
|
||||
FreeAndNil(FParams);
|
||||
// FreeAndNil(FSQL);
|
||||
FreeAndNil(FInsertSQL);
|
||||
FreeAndNil(FDeleteSQL);
|
||||
|
@ -5,6 +5,9 @@ if [ $? != 0 ]; then
|
||||
echo "Compilation failed";
|
||||
exit
|
||||
fi
|
||||
echo "Generating test list"
|
||||
./dbtestframework --list 2>/dev/null | sed /TestSuites/d | tr -d '[:blank:]' > test-list.txt
|
||||
exit
|
||||
for f in `cat test-list.txt`
|
||||
do
|
||||
echo -n "Doing test $f"
|
||||
|
Loading…
Reference in New Issue
Block a user