lazarus/fpc自带的bufDataSet和MemDataSet缺少类似TClientDataSet的Delta功能,这个单元从TDataSet扩展了Delta,可以直接生成增删改的SQL,适用于所有TDataSet。
2024-10-25 高勇高老板增强了GetActionSQL功能:
function GetActionSQL(const ATableName : String; const AKeyFields: String = ''): String; overload; function GetActionSQL(const DataBaseType:string;aTablename: string; AKeyFields: string; aAutoIncFieldname: string = ''; aNotE
2024-08-17
增加blob类型转base64,不过服务器需将base64转为blob保存。
2024-07-04
合并ccc(QQ1650680975)增加的delphi 12.0版(unidac)
2024-06-09:
修正可能QFDataSetMonitor1.Active:=true放在表打开前设置时数据监控可能会失效的Bug;
2024-06-07:
将TDataSetChangesMonitor封装为控件,安装DatasetMonitorPack.lpk就可以
使用方法:
procedure TForm1.FormCreate(Sender: TObject); begin BufDataset2.FieldDefs.Clear; BufDataset2.FieldDefs.Add('vstr1', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftString')), 30); BufDataset2.FieldDefs.Add('vint1', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftinteger'))); BufDataset2.FieldDefs.Add('vint2', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftinteger'))); BufDataset2.CreateDataset; memo1.Lines.Clear; BufDataset2.Open; dcm2:=TQFDataSetMonitor.Create(self); dcm2.DataSet:=BufDataset2; //监控BufDataset2的数据变化 dcm2.ActivateMonitoring; {$ifdef linux} SQLiteLibraryName:=ExtractFilePath(Application.ExeName)+'libsqlite3.so'; {$else} SQLiteLibraryName:=utf8tocp936(ExtractFilePath(Application.ExeName)+'sqlite3.dll'); {$endif} ZConnection1.Disconnect; ZConnection1.Protocol:='sqlite'; ZConnection1.LibraryLocation:=utf8tocp936(ExtractFilePath(Application.ExeName)+{$ifdef linux}'libsqlite3.so'{$else}'sqlite3.dll'{$endif}); ZConnection1.Properties.Clear; ZConnection1.Properties.Add('encrypted=yes'); ZConnection1.Properties.Add('cipher=sqlcipher'); ZConnection1.Properties.Add('sqlcipher=legacy'); ZConnection1.Properties.Add('legacy=1'); ZConnection1.Properties.Add('controls_cp=CP_UTF8'); ZConnection1.Properties.Add('AutoEncodeStrings=True'); ZConnection1.Database:='demo.db3'; ZConnection1.Password:='123asd'; ZConnection1.Connect; ZQuery1.Close; ZQuery1.SQL.Text:='select * from hardware'; ZQuery1.Open; QFDataSetMonitor1.Active:=true;//激活监控功能 end;
2024-06-06:
第1版采用helper class方式,发现受限太多,不适合多DataSet使用,今天改标准的class方法,使用方法也相应有调整。
使用方法:
1、在unit的uses添加DataSetDelta
2、ActivateMonitoring(true)//true--启动Delta功能 false--停止Delta
3、GetActionSQL(const ATableName: String; const AKeyFields: String = '');//根据Delta生成SQL
注意:
使用GetActionSQL后会清空Delta的记录。
BufDataset使用Delta的方法:
dcm1:TDataSetChangesMonitor;
dcm2:TDataSetChangesMonitor;
dcm1:=TDataSetChangesMonitor.Create(self);
dcm2:=TDataSetChangesMonitor.Create(self);
dcm1.DataSet:=BufDataset1; //监控BufDataset1的数据变化
dcm2.DataSet:=BufDataset2; //监控BufDataset2的数据变化
dcm1.ActivateMonitoring(true);
dcm2.ActivateMonitoring;
sql:=dcm1.GetActionSQL('test');//读取Delta生成的SQL
sql:=dcm2.GetActionSQL('demo');
继续开源:
https://github.com/szlbz/DataSetDelta.git
{*******************************************************} { } { 为lazarus TDataSet增加类似TClientDataSet的Delta功能 } { 适用于所有TDataSet } { } { } { Copyright(c) 2024-2024 } { 秋风(QQ315795176)原创出品 } { } { All rights reserved } { 保留所有权利 } { } {*******************************************************} unit DataSetDelta; {$mode objfpc}{$H+} interface uses Classes, SysUtils, BufDataset, DB, TypInfo, Variants; type TDataStateValue = (dsvOriginal, dsvDeleted, dsvInserted, dsvUpdated); TDataStateValues=set of TDataStateValue; TDataSetChangesMonitor =class(TComponent) private FDataState:TDataStateValue; Foldvalue:array of Variant; FBeforeEdit: TDataSetNotifyEvent; FBeforeDelete: TDataSetNotifyEvent; FBeforeInsert: TDataSetNotifyEvent; FAfterPost: TDataSetNotifyEvent; FNewDataSet:TBufDataSet; FOldDataSet:TBufDataSet; FDataSet:TDataSet; procedure CreateMonitorDataSet; procedure SetDataSet(AValue: TDataSet); procedure BeforeInserts(DataSet: TDataSet); procedure BeforeEdits(DataSet: TDataSet); procedure BeforeDeletes(DataSet:TDataSet); procedure AfterPosts(DataSet: TDataSet); function GetChangedCount:int64; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GetActionSQL(const ATableName : String; const AKeyFields: String = ''): String; procedure ActivateMonitoring(AValue:Boolean =true); property ChangedCount:int64 read GetChangedCount; property DataSet:TDataSet read FDataSet write SetDataSet; end; implementation
unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, BufDataset, DB, Forms, Controls, Graphics, Dialogs, DBGrids, StdCtrls, Memds,TypInfo,Variants,DataSetDelta,lazutf8; type { TForm1 } TForm1 = class(TForm) BufDataset1: TBufDataset; BufDataset2: TBufDataset; Button2: TButton; Button3: TButton; DataSource1: TDataSource; DataSource2: TDataSource; DBGrid1: TDBGrid; DBGrid2: TDBGrid; Memo1: TMemo; procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormCreate(Sender: TObject); private public dcm1:TDataSetChangesMonitor; dcm2:TDataSetChangesMonitor; end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button2Click(Sender: TObject); var sql:string; begin if BufDataset1.State in [dsEdit, dsInsert] then BufDataset1.Post; sql:=dcm1.GetActionSQL('test'); if sql<>'' then memo1.Lines.Add(sql); end; procedure TForm1.Button3Click(Sender: TObject); var sql:string; begin if BufDataset2.State in [dsEdit, dsInsert] then BufDataset2.Post; sql:=dcm2.GetActionSQL('demo'); if sql<>'' then memo1.Lines.Add(sql); end; procedure TForm1.FormCreate(Sender: TObject); begin BufDataset1.FieldDefs.Clear; BufDataset1.FieldDefs.Add('test1', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftString')), 30); BufDataset1.FieldDefs.Add('test2', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftinteger'))); BufDataset1.CreateDataset; BufDataset2.FieldDefs.Clear; BufDataset2.FieldDefs.Add('test11', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftString')), 30); BufDataset2.FieldDefs.Add('test12', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftinteger'))); BufDataset2.FieldDefs.Add('test13', TFieldType(GetEnumValue(TypeInfo(TFieldType), 'ftinteger'))); BufDataset2.CreateDataset; memo1.Lines.Clear; BufDataset2.Open; BufDataset1.Open; dcm1:=TDataSetChangesMonitor.Create(self); dcm2:=TDataSetChangesMonitor.Create(self); dcm1.DataSet:=BufDataset1; //监控BufDataset1的数据变化 dcm2.DataSet:=BufDataset2; //监控BufDataset2的数据变化 dcm1.ActivateMonitoring(true); dcm2.ActivateMonitoring; end; end.