mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-25 23:43:17 +02:00
578 lines
15 KiB
ObjectPascal
578 lines
15 KiB
ObjectPascal
unit lr_SQLQuery;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Graphics, LR_Class, LR_DBComponent, sqldb, DB, contnrs;
|
|
|
|
type
|
|
|
|
TQueryParam = class
|
|
ParamType:TFieldType;
|
|
ParamName:string;
|
|
ParamValue:string;
|
|
end;
|
|
|
|
{ TQueryParamList }
|
|
|
|
TQueryParamList = class(TFPObjectList)
|
|
function ParamByName(AParamName:string):TQueryParam;
|
|
function Add(AParamType:TFieldType; const AParamName, AParamValue:string):TQueryParam;
|
|
end;
|
|
|
|
{ TLRSQLQuery }
|
|
|
|
TLRSQLQuery = class(TLRDataSetControl)
|
|
private
|
|
FDatabase: string;
|
|
FParams: TQueryParamList;
|
|
procedure SetDatabase(AValue: string);
|
|
procedure DoMakeParams;
|
|
procedure DoEditParams;
|
|
procedure SQLQueryBeforeOpen(ADataSet: TDataSet);
|
|
protected
|
|
function GetSQL: string;
|
|
procedure SetSQL(AValue:string);
|
|
procedure SetDataSource(AValue: string); override;
|
|
procedure AfterLoad;override;
|
|
public
|
|
constructor Create(AOwnerPage:TfrPage); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure LoadFromXML(XML: TLrXMLConfig; const Path: String); override;
|
|
procedure SaveToXML(XML: TLrXMLConfig; const Path: String); override;
|
|
published
|
|
property SQL:string read GetSQL write SetSQL;
|
|
property Database:string read FDatabase write SetDatabase;
|
|
property Params:TQueryParamList read FParams write FParams;
|
|
end;
|
|
|
|
{ TLRSQLConnection }
|
|
|
|
TLRSQLConnection = class(TfrNonVisualControl)
|
|
private
|
|
FConnected:boolean;
|
|
function GetCharSet: string;
|
|
function GetConnected: Boolean;
|
|
function GetDatabase: string;
|
|
function GetHostName: string;
|
|
function GetLoginPrompt: Boolean;
|
|
function GetPassword: string;
|
|
function GetUserName: string;
|
|
procedure SetCharSet(AValue: string);
|
|
procedure SetConnected(AValue: Boolean);
|
|
procedure SetDatabase(AValue: string);
|
|
procedure SetHostName(AValue: string);
|
|
procedure SetLoginPrompt(AValue: Boolean);
|
|
procedure SetPassword(AValue: string);
|
|
procedure SetUserName(AValue: string);
|
|
protected
|
|
FConnection: TSQLConnection;
|
|
FSQLTransaction:TSQLTransaction;
|
|
procedure SetName(const AValue: string); override;
|
|
procedure AfterLoad;override;
|
|
public
|
|
constructor Create(AOwnerPage:TfrPage); override;
|
|
destructor Destroy; override;
|
|
|
|
procedure LoadFromXML(XML: TLrXMLConfig; const Path: String); override;
|
|
procedure SaveToXML(XML: TLrXMLConfig; const Path: String); override;
|
|
published
|
|
property CharSet: string read GetCharSet write SetCharSet;
|
|
property Connected: Boolean read GetConnected write SetConnected;
|
|
property LoginPrompt: Boolean read GetLoginPrompt write SetLoginPrompt;
|
|
property HostName: string read GetHostName write SetHostName;
|
|
property DatabaseName: string read GetDatabase write SetDatabase;
|
|
property UserName: string read GetUserName write SetUserName;
|
|
property Password: string read GetPassword write SetPassword;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
{$R lrsqldb_img.res}
|
|
|
|
uses LR_Utils, DBPropEdits, PropEdits, Controls, Forms,
|
|
lr_EditSQLDBParamsUnit;
|
|
|
|
var
|
|
lrBMP_SQLQuery:TBitmap = nil;
|
|
|
|
procedure InitLRComp;
|
|
begin
|
|
if not assigned(lrBMP_SQLQuery) then
|
|
begin
|
|
lrBMP_SQLQuery := TbitMap.Create;
|
|
lrBMP_SQLQuery.LoadFromResourceName(HInstance, 'TLRSQLQuery');
|
|
frRegisterObject(TLRSQLQuery, lrBMP_SQLQuery, 'TLRSQLQuery', nil, otlUIControl, nil);
|
|
end;
|
|
end;
|
|
|
|
{ TQueryParamList }
|
|
|
|
function TQueryParamList.ParamByName(AParamName: string): TQueryParam;
|
|
var
|
|
i:integer;
|
|
begin
|
|
Result:=nil;
|
|
AParamName:=UpperCase(AParamName);
|
|
for i:=0 to Count - 1 do
|
|
begin
|
|
if UpperCase(TQueryParam(Items[i]).ParamName) = AParamName then
|
|
begin
|
|
Result:=TQueryParam(Items[i]);
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TQueryParamList.Add(AParamType: TFieldType; const AParamName,
|
|
AParamValue: string): TQueryParam;
|
|
begin
|
|
Result:=TQueryParam.Create;
|
|
inherited Add(Result);
|
|
Result.ParamType:=AParamType;
|
|
Result.ParamName:=AParamName;
|
|
Result.ParamValue:=AParamValue;
|
|
end;
|
|
|
|
{ TLRSQLConnection }
|
|
|
|
function TLRSQLConnection.GetCharSet: string;
|
|
begin
|
|
Result:=FConnection.CharSet;
|
|
end;
|
|
|
|
function TLRSQLConnection.GetConnected: Boolean;
|
|
begin
|
|
Result:=FConnection.Connected;
|
|
end;
|
|
|
|
function TLRSQLConnection.GetDatabase: string;
|
|
begin
|
|
Result:=FConnection.DatabaseName;
|
|
end;
|
|
|
|
function TLRSQLConnection.GetHostName: string;
|
|
begin
|
|
Result:=FConnection.HostName;
|
|
end;
|
|
|
|
function TLRSQLConnection.GetLoginPrompt: Boolean;
|
|
begin
|
|
Result:=FConnection.LoginPrompt;
|
|
end;
|
|
|
|
function TLRSQLConnection.GetPassword: string;
|
|
begin
|
|
Result:=FConnection.Password;
|
|
end;
|
|
|
|
function TLRSQLConnection.GetUserName: string;
|
|
begin
|
|
Result:=FConnection.UserName;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetCharSet(AValue: string);
|
|
begin
|
|
FConnection.CharSet:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetConnected(AValue: Boolean);
|
|
begin
|
|
FConnection.Connected:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetDatabase(AValue: string);
|
|
begin
|
|
FConnection.DatabaseName:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetHostName(AValue: string);
|
|
begin
|
|
FConnection.HostName:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetLoginPrompt(AValue: Boolean);
|
|
begin
|
|
FConnection.LoginPrompt:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetPassword(AValue: string);
|
|
begin
|
|
FConnection.Password:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetUserName(AValue: string);
|
|
begin
|
|
FConnection.UserName:=AValue;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SetName(const AValue: string);
|
|
begin
|
|
inherited SetName(AValue);
|
|
FConnection.Name:=Name;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.AfterLoad;
|
|
begin
|
|
inherited AfterLoad;
|
|
FConnection.Connected:=FConnected;
|
|
end;
|
|
|
|
constructor TLRSQLConnection.Create(AOwnerPage: TfrPage);
|
|
begin
|
|
inherited Create(AOwnerPage);
|
|
FSQLTransaction:=TSQLTransaction.Create(OwnerForm);
|
|
end;
|
|
|
|
destructor TLRSQLConnection.Destroy;
|
|
begin
|
|
if not (Assigned(OwnerPage) and (OwnerPage is TfrPageDialog)) then
|
|
begin
|
|
FreeAndNil(FSQLTransaction);
|
|
FreeAndNil(FConnection);
|
|
end;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TLRSQLConnection.LoadFromXML(XML: TLrXMLConfig; const Path: String);
|
|
begin
|
|
inherited LoadFromXML(XML, Path);
|
|
FConnection.LoginPrompt:=XML.GetValue(Path + 'LoginPrompt/Value'{%H-}, false);
|
|
FConnection.CharSet:=XML.GetValue(Path + 'CharSet/Value'{%H-}, '');
|
|
|
|
FConnection.HostName:=XML.GetValue(Path + 'HostName/Value'{%H-}, '');
|
|
FConnection.DatabaseName:=XML.GetValue(Path + 'Database/Value'{%H-}, '');
|
|
FConnection.UserName:=XML.GetValue(Path + 'User/Value'{%H-}, '');
|
|
FConnection.Password:=XML.GetValue(Path + 'Password/Value'{%H-}, '');
|
|
|
|
FConnected:=XML.GetValue(Path + 'Connected/Value'{%H-}, false);
|
|
end;
|
|
|
|
procedure TLRSQLConnection.SaveToXML(XML: TLrXMLConfig; const Path: String);
|
|
begin
|
|
inherited SaveToXML(XML, Path);
|
|
XML.SetValue(Path + 'LoginPrompt/Value'{%H-}, FConnection.LoginPrompt);
|
|
XML.SetValue(Path + 'CharSet/Value'{%H-}, FConnection.CharSet);
|
|
|
|
XML.SetValue(Path + 'HostName/Value'{%H-}, FConnection.HostName);
|
|
XML.SetValue(Path + 'Database/Value'{%H-}, FConnection.DatabaseName);
|
|
XML.SetValue(Path + 'User/Value'{%H-}, FConnection.UserName);
|
|
XML.SetValue(Path + 'Password/Value'{%H-}, FConnection.Password);
|
|
XML.SetValue(Path + 'Connected/Value'{%H-}, FConnection.Connected);
|
|
end;
|
|
|
|
{ TLRSQLQuery }
|
|
|
|
procedure TLRSQLQuery.SetDatabase(AValue: string);
|
|
var
|
|
D:TComponent;
|
|
begin
|
|
if FDatabase=AValue then Exit;
|
|
FDatabase:=AValue;
|
|
|
|
DataSet.Active:=false;
|
|
D:=frFindComponent(TSQLQuery(DataSet).Owner, FDatabase);
|
|
if Assigned(D) and (D is TSQLConnection)then
|
|
TSQLQuery(DataSet).DataBase:=TSQLConnection(D);
|
|
end;
|
|
|
|
procedure TLRSQLQuery.DoMakeParams;
|
|
var
|
|
Q:TSQLQuery;
|
|
i:integer;
|
|
begin
|
|
Q:=TSQLQuery(DataSet);
|
|
if Q.Params.Count > 0 then
|
|
begin
|
|
//Add new params...
|
|
for i:=0 to Q.Params.Count-1 do
|
|
begin
|
|
if not Assigned(FParams.ParamByName(Q.Params[i].Name)) then
|
|
FParams.Add(ftUnknown, Q.Params[i].Name, '');
|
|
end;
|
|
|
|
//Delete not exists params
|
|
for i:=FParams.Count-1 downto 0 do
|
|
begin
|
|
if not Assigned(Q.Params.FindParam(TQueryParam(FParams[i]).ParamName)) then
|
|
FParams.Delete(i);
|
|
end;
|
|
end
|
|
else
|
|
FParams.Clear;
|
|
end;
|
|
|
|
procedure TLRSQLQuery.DoEditParams;
|
|
var
|
|
lrEditParamsForm: Tlr_EditSQLDBParamsForm;
|
|
begin
|
|
lrEditParamsForm:=Tlr_EditSQLDBParamsForm.Create(Application);
|
|
lrEditParamsForm.LoadParamList(FParams);
|
|
if lrEditParamsForm.ShowModal = mrOk then
|
|
begin
|
|
lrEditParamsForm.SaveParamList(FParams);
|
|
if Assigned(frDesigner) then
|
|
frDesigner.Modified:=true;
|
|
end;
|
|
lrEditParamsForm.Free;
|
|
end;
|
|
|
|
procedure TLRSQLQuery.SQLQueryBeforeOpen(ADataSet: TDataSet);
|
|
var
|
|
i: Integer;
|
|
s: String;
|
|
SaveView: TfrView;
|
|
SavePage: TfrPage;
|
|
SaveBand: TfrBand;
|
|
Q:TSQLQuery;
|
|
P:TQueryParam;
|
|
begin
|
|
Q:=TSQLQuery(DataSet);
|
|
SaveView := CurView;
|
|
SavePage := CurPage;
|
|
SaveBand := CurBand;
|
|
|
|
CurView := Self;
|
|
CurPage := OwnerPage;
|
|
CurBand := nil;
|
|
|
|
for i := 0 to Q.Params.Count - 1 do
|
|
begin
|
|
S:=Q.Params[i].Name;
|
|
P:=FParams.ParamByName(S);
|
|
if Assigned(P) and (P.ParamValue <> '') and (DocMode = dmPrinting) then
|
|
begin
|
|
case P.ParamType of
|
|
ftDate,
|
|
ftDateTime:Q.Params[i].AsDateTime := frParser.Calc(P.ParamValue);
|
|
ftInteger:Q.Params[i].AsInteger := frParser.Calc(P.ParamValue);
|
|
ftFloat:Q.Params[i].AsFloat := frParser.Calc(P.ParamValue);
|
|
ftString:Q.Params[i].AsString := frParser.Calc(P.ParamValue);
|
|
else
|
|
Q.Params[i].Value := frParser.Calc(P.ParamValue);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if Assigned(Q.DataBase) then
|
|
if not Q.DataBase.Connected then Q.DataBase.Connected:=true;
|
|
|
|
CurView := SaveView;
|
|
CurPage := SavePage;
|
|
CurBand := SaveBand;
|
|
end;
|
|
|
|
function TLRSQLQuery.GetSQL: string;
|
|
begin
|
|
Result:=TSQLQuery(DataSet).SQL.Text;
|
|
end;
|
|
|
|
procedure TLRSQLQuery.SetSQL(AValue: string);
|
|
begin
|
|
DataSet.Active:=false;
|
|
TSQLQuery(DataSet).SQL.Text:=AValue;
|
|
DoMakeParams;
|
|
if Assigned(frDesigner) then
|
|
frDesigner.Modified:=true;
|
|
end;
|
|
|
|
procedure TLRSQLQuery.SetDataSource(AValue: string);
|
|
var
|
|
D:TComponent;
|
|
begin
|
|
inherited SetDataSource(AValue);
|
|
D:=frFindComponent(OwnerForm, AValue);
|
|
if Assigned(D) and (D is TDataSource)then
|
|
TSQLQuery(DataSet).DataSource:=TDataSource(D);
|
|
end;
|
|
|
|
procedure TLRSQLQuery.AfterLoad;
|
|
var
|
|
D:TComponent;
|
|
begin
|
|
D:=frFindComponent(OwnerForm, DataSource);
|
|
if Assigned(D) and (D is TDataSource)then
|
|
TSQLQuery(DataSet).DataSource:=TDataSource(D);
|
|
|
|
D:=frFindComponent(DataSet.Owner, FDatabase);
|
|
if Assigned(D) and (D is TSQLConnection)then
|
|
begin
|
|
TSQLQuery(DataSet).DataBase:=TSQLConnection(D);
|
|
DataSet.Active:=FActive;
|
|
end;
|
|
end;
|
|
|
|
constructor TLRSQLQuery.Create(AOwnerPage: TfrPage);
|
|
begin
|
|
inherited Create(AOwnerPage);
|
|
BaseName := 'lrSQLQuery';
|
|
DataSet:=TSQLQuery.Create(OwnerForm);
|
|
DataSet.BeforeOpen:=@SQLQueryBeforeOpen;
|
|
FParams:=TQueryParamList.Create;
|
|
end;
|
|
|
|
destructor TLRSQLQuery.Destroy;
|
|
begin
|
|
FreeAndNil(FParams);
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function StrToFieldType(AStrTypeName:string):TFieldType;
|
|
var
|
|
i:TFieldType;
|
|
begin
|
|
Result:=ftUnknown;
|
|
AStrTypeName:=UpperCase(AStrTypeName);
|
|
for i in TFieldType do
|
|
begin
|
|
if UpperCase(Fieldtypenames[i]) = AStrTypeName then
|
|
begin
|
|
Result:=i;
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TLRSQLQuery.LoadFromXML(XML: TLrXMLConfig; const Path: String);
|
|
var
|
|
C: Integer;
|
|
i: Integer;
|
|
begin
|
|
inherited LoadFromXML(XML, Path);
|
|
TSQLQuery(DataSet).SQL.Text := XML.GetValue(Path+'SQL/Value'{%H-}, '');
|
|
FDatabase:= XML.GetValue(Path+'Database/Value'{%H-}, '');
|
|
|
|
C:=XML.GetValue(Path+'Params/Count/Value', 0);
|
|
for i:=0 to C-1 do
|
|
FParams.Add(
|
|
StrToFieldType(XML.GetValue(Path+'Params/Item'+IntToStr(i)+'/ParamType', '')),
|
|
XML.GetValue(Path+'Params/Item'+IntToStr(i)+'/Name', ''),
|
|
XML.GetValue(Path+'Params/Item'+IntToStr(i)+'/Value', '')
|
|
);
|
|
end;
|
|
|
|
procedure TLRSQLQuery.SaveToXML(XML: TLrXMLConfig; const Path: String);
|
|
var
|
|
i: Integer;
|
|
P: TQueryParam;
|
|
begin
|
|
inherited SaveToXML(XML, Path);
|
|
XML.SetValue(Path+'SQL/Value', TSQLQuery(DataSet).SQL.Text);
|
|
XML.SetValue(Path+'Database/Value', FDatabase);
|
|
|
|
XML.SetValue(Path+'Params/Count/Value', FParams.Count);
|
|
for i:=0 to FParams.Count-1 do
|
|
begin
|
|
P:=TQueryParam(FParams[i]);
|
|
XML.SetValue(Path+'Params/Item'+IntToStr(i)+'/Name', P.ParamName);
|
|
XML.SetValue(Path+'Params/Item'+IntToStr(i)+'/Value', P.ParamValue);
|
|
XML.SetValue(Path+'Params/Item'+IntToStr(i)+'/ParamType', Fieldtypenames[P.ParamType]);
|
|
end;
|
|
end;
|
|
|
|
type
|
|
|
|
{ TLRSQLQueryParamsProperty }
|
|
|
|
TLRSQLQueryParamsProperty = class(TPropertyEditor)
|
|
public
|
|
function GetAttributes: TPropertyAttributes; override;
|
|
function GetValue: ansistring; override;
|
|
procedure Edit; override;
|
|
end;
|
|
|
|
|
|
TLRSQLConnectionProtocolProperty = class(TFieldProperty)
|
|
public
|
|
procedure FillValues(const Values: TStringList); override;
|
|
end;
|
|
|
|
|
|
{ TLRSQLQuerySQLProperty }
|
|
|
|
TLRSQLQuerySQLProperty = class(TStringPropertyEditor)
|
|
public
|
|
function GetAttributes: TPropertyAttributes; override;
|
|
function GetValue: ansistring; override;
|
|
procedure Edit; override;
|
|
end;
|
|
|
|
{ TLRSQLQueryParamsProperty }
|
|
|
|
function TLRSQLQueryParamsProperty.GetAttributes: TPropertyAttributes;
|
|
begin
|
|
Result:=[paDialog, paReadOnly];
|
|
end;
|
|
|
|
function TLRSQLQueryParamsProperty.GetValue: ansistring;
|
|
begin
|
|
Result:='(Params)';
|
|
end;
|
|
|
|
procedure TLRSQLQueryParamsProperty.Edit;
|
|
begin
|
|
if (GetComponent(0) is TLRSQLQuery) then
|
|
TLRSQLQuery(GetComponent(0)).DoEditParams;
|
|
end;
|
|
|
|
{ TLRSQLQuerySQLProperty }
|
|
|
|
function TLRSQLQuerySQLProperty.GetAttributes: TPropertyAttributes;
|
|
begin
|
|
Result:=[paDialog, paReadOnly];
|
|
end;
|
|
|
|
function TLRSQLQuerySQLProperty.GetValue: ansistring;
|
|
begin
|
|
Result:='(SQL)';
|
|
end;
|
|
|
|
procedure TLRSQLQuerySQLProperty.Edit;
|
|
var
|
|
TheDialog : TStringsPropEditorDlg;
|
|
AString : string;
|
|
begin
|
|
AString := GetStrValue;
|
|
TheDialog := TStringsPropEditorDlg.Create(nil);
|
|
try
|
|
TheDialog.Editor := Self;
|
|
TheDialog.Memo.Text := AString;
|
|
TheDialog.MemoChange(nil);
|
|
if (TheDialog.ShowModal = mrOK) then
|
|
begin
|
|
AString := TheDialog.Memo.Text;
|
|
//erase the last lineending if any
|
|
if Copy(AString, length(AString) - length(LineEnding) + 1, length(LineEnding)) = LineEnding then
|
|
Delete(AString, length(AString) - length(LineEnding) + 1, length(LineEnding));
|
|
SetStrValue(AString);
|
|
end;
|
|
finally
|
|
TheDialog.Free;
|
|
end;
|
|
end;
|
|
|
|
{ TLRZConnectionProtocolProperty }
|
|
|
|
procedure TLRSQLConnectionProtocolProperty.FillValues(const Values: TStringList);
|
|
begin
|
|
if (GetComponent(0) is TLRSQLQuery) then
|
|
frGetComponents(nil, TSQLConnection, Values, nil);
|
|
end;
|
|
|
|
initialization
|
|
InitLRComp;
|
|
|
|
RegisterPropertyEditor(TypeInfo(string), TLRSQLQuery, 'Database', TLRSQLConnectionProtocolProperty);
|
|
RegisterPropertyEditor(TypeInfo(string), TLRSQLQuery, 'SQL', TLRSQLQuerySQLProperty);
|
|
|
|
RegisterPropertyEditor(TypeInfo(TQueryParamList), TLRSQLQuery, 'Params', TLRSQLQueryParamsProperty);
|
|
finalization
|
|
if Assigned(lrBMP_SQLQuery) then
|
|
FreeAndNil(lrBMP_SQLQuery);
|
|
end.
|
|
|