ユニットBDECLIENTDATASET;
インタフェース
窓、sysutils、バリアント、クラス、db、dbcommon、midasを使用します。
sqltimst、dbclient、dblocal、プロバイダー、dbtables;
タイプ
{tbdequery}
tbdequery = class(tquery)
プライベート
fkeyfields:string;
保護されています
関数psgetDefaultOrder:tindexdef;オーバーライド;
終わり;
{tbdeclientdataset}
tbdeclientdataset = class(tcustomcacheddataset)
プライベート
fcommandText:string;
fcurrentCommand:文字列;
fdataset:tbdequery;
fdatabase:tdatabase;
FlocalParams:TPARAMS;
fstreamedactive:boolean;
手順CheckMasterSourceActive(MasterSource:TDataSource);
手順setDetailSactive(value:boolean);
関数getConnection:tdatabase;
関数getDataset:tdataset;
関数getMasterSource:tdatasource;
関数GetMasterFields:String;
手順SetConnection(値:tdatabase);
手順SetDataSource(Value:TDataSource);
手順SetLocalParams;
手順SetMasterFields(const値:文字列);
手順SetParamSfromsQl(const Value:String);
手順SetSQL(const値:文字列);
保護されています
関数getCommandText:string;オーバーライド;
ロードされた手順。オーバーライド;
手順通知(acomponent:tcomponent;操作:トッテレーション);オーバーライド;
手順Setactive(value:boolean);オーバーライド;
手順SetCommandText(value:string);オーバーライド;
公共
Constructor Create(aowner:tcomponent);オーバーライド;
デストラクタは破壊します。オーバーライド;
手順CloneCursor(出典:TCustomClientDataset;リセット:Boolean;
Keepsettings:boolean = false);オーバーライド;
手順getFieldNames(リスト:TStrings);オーバーライド;
関数getquotechar:string;
プロパティデータセット:tdataset read getdataset;
公開
アクティブなプロパティ;
Property CommandText:String read getCommandText Write SetCommandText;
プロパティdbconnection:tdatabase read getConnection write setConnection;
Property Masterfields read getmasterfields write setmasterfields;
Property MasterSource:tdatasource read getmastersource write setdatasource;
終わり;
手順登録。
実装
MidConst、Bdeconstを使用します。
タイプ
{tbdecdsparams}
tbdecdsparams = class(tparams)
プライベート
ffieldName:tstrings;
保護されています
手順parseSelect(sql:string);
公共
Constructor Create(所有者:TPERSISTENT);
デストラクタは破壊します。オーバーライド;
終わり;
Constructor tbdecdsparams.create(所有者:tpersistent);
始める
継承;
ffieldName:= tstringlist.create;
終わり;
Destructor tbdecdsparams.destroy;
始める
Freeandnil(ffieldName);
継承;
終わり;
手順tbdecdsparams.parselect(sql:string);
const
sselect = 'select';
var
fherefound:boolean;
開始:PCHAR;
fname、value:string;
sqltoken、cursection、lasttoken:tsqltoken;
パラメーション:整数;
始める
pos( '' + sselect + ''、lowercase(string(pchar(sql)+8)))> 1の場合、終了します。 //サブクエリを解析できません
start:= pchar(parsesql(pchar(sql)、true));
Cursection:= Stunknown;
LastToken:= Stunknown;
fherefound:= false;
パラメーション:= 0;
繰り返す
繰り返す
sqltoken:= nextsqltoken(start、fname、cursection);
[sthwhere]でsqltokenの場合
始める
fwherefound:= true;
LastToken:= sthwhere;
[sttablename]でsqltokenの場合はelseを終了します
始める
{所有者の資格のあるテーブル名をチェック}
開始^ = '。'それから
NextSqlToken(start、fname、cursection);
ENSEを終了します
if(sqltoken = stvalue)および(lasttoken = sthwhere)then
sqltoken:= stfieldname;
sqlSectionsでsqltokenの場合、Cursection:= sqltoken;
[StfieldName、Stend]でsqltokenまで;
fherefoundと([stfieldname] in [stfieldname] in sqltoken)の場合
繰り返す
sqltoken:= nextsqltoken(start、value、cursection);
sqlSectionsでsqltokenの場合、Cursection:= sqltoken;
[Stend、Stvalue、Stisnull、Stisnotnull、StfieldName]でsqltoken;
value = '?'の場合それから
始める
ffieldname.add(fname);
inc(params);
終わり;
まで(params = count)または(sqltoken in [stend]);
終わり;
{tbdequery}
function tbdequery.psgetDefaultOrder:tindexdef;
始める
fkeyfields = ''の場合
結果:=継承されたpsgetDefaultOrder
それ以外
begin //詳細テーブルデフォルトの順序
結果:= tindexdef.create(nil);
result.options:= [ixunique]; //キーフィールドはユニークです
result.name:= stringReplace(fkeyfields、 ';'、 '_'、[rfreplaceall]);
result.fields:= fkeyfields;
終わり;
終わり;
{tbdeclientdataset}
Constructor tbdeclientdataset.create(aowner:tcomponent);
始める
継承されたcreate(aowner);
fdataset:= tbdequery.create(nil);
fdataset.name:= self.name + 'dataset1';
provider.dataset:= fdataset;
sqldbtype:= typebde;
flocalparams:= tparams.create;
終わり;
Destructor tbdeclientdataset.destroy;
始める
Freeandnil(flocalparams);
fdataset.close;
Freeandnil(fdataset);
継承された破壊;
終わり;
手順tbdeclientdataset.getFieldNames(リスト:TStrings);
var
オープン:boolean;
始める
オープン:=(active = false);
試す
開いた場合
開ける;
継承getFieldNames(リスト);
ついに
開いた場合は閉じます。
終わり;
終わり;
関数tbdeclientdataset.getCommandText:string;
始める
結果:= fcommandText;
終わり;
関数tbdeclientdataset.getDataset:tdataset;
始める
結果:= fdataset as tdataset;
終わり;
手順tbdeclientdataset.checkmastersourceactive(MasterSource:tdatasource);
始める
割り当て(MasterSource)と割り当てられた場合(MasterSource.Dataset)
そうでない場合は、MasterSource.Dataset.Activeではありません
DatabaseError(SmasterNotopen);
終わり;
手順tbdeclientdataset.setparamsfromsql(const value:string);
var
データセット:tquery;
TableName、Tempquery、Q:String;
リスト:tbdecdsparams;
I:整数;
フィールド:Tfield;
始める
TableName:= getTableNameFromsQl(value);
TableName <> ''の場合
始める
Tempquery:= value;
リスト:= tbdecdsparams.create(self);
試す
list.parseselect(tempquery);
list.AssignValues(params);
for i:= 0 to list.count -1 do
list [i] .paramtype:= ptinput;
データセット:= tquery.create(nil);
試す
dataset.databasename:= fdataset.databasename;
Q:= GetQuotechar;
dataset.sql.add( 'select * from' + q + tablename + q + 'where 0 = 1'); {ローカライズしないで}
試す
dataset.open;
for i:= 0 to list.count -1 do
始める
list.ffieldname.count> iの場合
始める
試す
フィールド:= dataset.fieldbyname(list.ffieldname [i]);
を除外する
フィールド:= nil;
終わり;
ENSEを終了します
フィールド:= nil;
割り当てられた場合(フィールド)
始める
field.datatype <> ftstringの場合
list [i] .datatype:= field.datatype
それ以外の場合は、tstringfield(field).fixedChar thenの場合
list [i] .datatype:= ftfixedChar
それ以外
list [i] .datatype:= ftstring;
終わり;
終わり;
を除外する
//すべての例外を無視します
終わり;
ついに
dataset.free;
終わり;
ついに
list.count> 0の場合
params.assign(list);
list.free;
終わり;
終わり;
終わり;
手順tbdeclientdataset.setsql(const value:string);
始める
割り当てられている場合(provider.dataset)
始める
tquery(provider.dataset).sql.clear;
value <> ''の場合
tquery(provider.dataset).sql.add(value);
継承されたsetCommandText(value);
ENSEを終了します
DatabaseError(snodataprovider);
終わり;
手順tbdeclientdataset.loaded;
始める
継承されたロード;
fstreamedactiveの場合
始める
Setactive(true);
fstreamedactive:= false;
終わり;
終わり;
関数tbdeclientdataset.getmasterfields:string;
始める
結果:=継承されたマスターフィールド。
終わり;
手順tbdeclientdataset.setmasterfields(const値:文字列);
始める
継承されたマスターフィールド:=値;
value <> ''の場合
indexfieldNames:= value;
fdataset.fkeyfields:= '';
終わり;
手順tbdeclientdataset.setcommandtext(value:string);
始める
継承されたsetCommandText(value);
fcommandText:= value;
そうでない場合(componentStateでのcsloading)次に
始める
fdataset.fkeyfields:= '';
indexfieldNames:= '';
マスターフィールド:= '';
indexName:= '';
indexdefs.clear;
params.clear;
if(csdesingin in componentState)および(value <> '')then
setParamsfromsql(value);
終わり;
終わり;
関数tbdeclientdataset.getConnection:tdatabase;
始める
結果:= fdatabase;
終わり;
手順tbdeclientdataset.setConnection(value:tdatabase);
始める
value = fdatabaseの場合、終了します。
CheckInactive;
割り当てられている場合(値)
始める
そうでない場合(componentStateでのcsloading)and(value.databasename = '')
DatabaseError(Sdatabasenamemissing);
fdataset.databasename:= value.databasename;
ENSEを終了します
fdataset.databasename:= '';
fdatabase:= value;
終わり;
関数tbdeclientdataset.getquotechar:string;
始める
結果:= '';
割り当てられている場合(fdataset)
結果:= fdataset.psgetquotechar;
終わり;
手順tbdeclientdataset.clonecursor(出典:tcustomclientdataset; reset:boolean;
Keepsettings:boolean = false);
始める
そうでない場合(ソースはtbdeclientdatasetです)
DatabaseError(sinvalidclone);
provider.dataset:= tbdeclientdataset(source).provider.dataset;
dbconnection:= tbdeclientdataset(source).dbconnection;
commandText:= tbdeclientdataset(source).commandtext;
継承されたクローネコール(ソース、リセット、キープセッティング);
終わり;
手順tbdeclientdataset.notification(acomponent:tcomponent;操作:トッテレーション);
始める
継承通知(acomponent、操作);
操作= opremoveの場合
acomponent = fdatabaseの場合
始める
fdatabase:= nil;
setactive(false);
終わり;
終わり;
手順tbdeclientdataset.setlocalparams;
手順CreateParamsFromasterFields(Create:Boolean);
var
I:整数;
リスト:tstrings;
始める
リスト:= tstringlist.create;
試す
作成する場合
flocalparams.clear;
fdataset.fkeyfields:= Masterfields;
list.commatext:= Masterfields;
for i:= 0 to list.count -1 do
始める
作成する場合
flocalparams.createparam(ftunknown、mastersource.dataset.fieldbyname(list [i])。フィールド名、
ptinput);
flocalparams [i] .Assignfield(mastersource.dataset.fieldbyname(list [i]));
終わり;
ついに
list.free;
終わり;
終わり;
始める
if(masterfields <> '')および割り当て(MasterSource)および割り当て(MasterSource.Dataset)
始める
createparamsfrommasterfields(true);
fcurrentCommand:= addparamsqlfordetail(flocalparams、commandText、true、getQuoteChar);
終わり;
終わり;
手順tbdeclientdataset.setdatasource(value:tdatasource);
始める
継承されたMasterSource:= value;
割り当てられている場合(値)
始める
packetRecords = -1の場合、packetRecords:= 0;
ENSEを終了します
始める
PacketRecords = 0の場合、PacketRecords:= -1;
終わり;
終わり;
関数tbdeclientdataset.getmastersource:tdatasource;
始める
結果:=継承されたMasterSource;
終わり;
手順tbdeclientdataset.setdetailsactive(value:boolean);
var
detaillist:tlist;
I:整数;
始める
detaillist:= tlist.create;
試す
getdetaildatasets(detaillist);
i:= 0 to detaillist.count -1 do
tdataset(detaillist [i])がtbdeclientdatasetである場合
tbdeclientdataset(tdataset(detaillist [i]))。active:= value;
ついに
detaillist.free;
終わり;
終わり;
手順tbdeclientdataset.setactive(value:boolean);
始める
価値の場合
始める
ComponentStateでのcsloadingの場合
始める
fstreamedactive:= true;
出口;
終わり;
Masterfields <> ''の場合
始める
そうでない場合(componentStateでのcsloading)次に
CheckMasterSourceActive(MasterSource);
setlocalparams;
setSql(fcurrentCommand);
パラメーション:= flocalparams;
FetchParams;
ENSEを終了します
始める
setSql(fcommandText);
params.count> 0の場合
始める
fdataset.params:= params;
FetchParams;
終わり;
終わり;
終わり;
値と(fdataset.objectView <> objectView)の場合
fdataset.objectView:= objectView;
継承されたsetactive(value);
setDetailsactive(value);
終わり;
手順登録。
始める
RegisterComponents( 'bde'、[tbdeclientdataset]);
終わり;
終わり。
//以上经dblocalb.pas
//然后安装此控件即可