TmanagedDataSet and DataSetPool implementation
Every day with delphi, I have a lot of ideas. After writing code, there is no time to organize some things as a document.
Delphi uses the most ADOEXPRESS component, which is Borland encapsulated Microsoft's ADO's stuff, using Tadodataset with the most frequent Tadodataset corresponding to ADO native Recordset, has made some enhancements, but the usage is basically consistent, with more I feel that tadodataset has a place to expand and transform.
Since many tadodataset controls are used in code, create and release objects are very frequent, and there are many basic identical properties to set up every time you are created, quite troublesome. So I think that a recordset can be implemented. Every time you need a recordset, you get an idle and meet (readable or readable) from this pool. After using it, you will be reclaimed by the pool, if you record the set Not enough, automatically generate new record set objects.
The first thing to do is to transform Tadodataset, I wrote a TManageDataSet, inherited from tadodataset, I can know that I have been used or idle (by iSused ()), renovate free (), change the movement of the original release It is set yourself as idle, and clear the status (session) information, and you can return a TDataSource object to your own via Source ().
After you have these foundations, you can build a TDataSetPool class quickly. This class is just a TManageDataSet object that saves the available, returns an idle dataset object via getDataSet (WantType: TManageDataSetType, if there is not idle in the pool, A return. TmanagedDataSetType is an enumeration class, identifies read-only dataset and read and write datasets (read-only data sets can be accelerated by optimizing Cursortype and LockType).
The following code is directly from the source file of the project I made, some chaos, only a reference.
Unit managementDataSet;
Interface
Uses AdoDB, Commondm, Sysutils, DB, DBGRIDS, COMOBJ, CLASS, Contnrs
Type
TmanagedDataSetType = (readonly, editable); // 猅羭 猅羭
TXLSEXPADAPTER = Class
Private
_SXLSCAPTION: STRING;
_SXLSFILENAME: STRING;
_BOVERWRITEEXISTFILE: BOOLEAN;
_asfieldname: tstringlist;
_asxlstitle: tstringlist;
_adattype: TOBJECTLIST;
Function getDataType (const inIindex: integer): TDATYPE;
Function getfieldName (const iniindex: integer): String;
Function getXLstitle (const iniindex: integer): String;
public
Constructor crete ();
DEStructor destroy ();
Property Xlscaption: String Read_sxlscaption Write_Sxlscaption;
Property XLSFileName: String Read _sxlsfilename Write_sxlsFileName
Property OverwriteexistFile: Boolean Read _boverwriteexistfile Write_boverwriteexistFile; Procedure Addfield (Const InsfieldName, InscAption: string; const INTYPE: TDATATYPE = ftunknown;
Procedure GetInfofromDBGrid (const INGRID: TDBGRID);
Property DataType [Const IniINDEX: Integer]: TDATATYPE Read GetDataType;
Property FieldName [Const IniINDEX: Integer]: String ReadFieldName
Property XLstitle [Const IniINDEX: Integer]: String Read getxlstitle;
Function count (): integer;
END;
TmanagedDataSet = Class (tadodataset)
Private
_Source: tdataserce;
_Type: TmanagedDataSetType;
_bused: bolean;
Procedure setDataSettype (const INTYPE: TMANAGEDDATASETTYPE);
Function getDataSource (): TDataSource;
public
Constructor Create (Const Intype: TmanagedDataType = Editable);
DEStructor destroy (); OVERRIDE;
PROCEDURE USE ();
Procedure free (); reintroduce; // 滦 笼 free ぃ穦 ㄒ ㄒ
Property DataSettype: TmanagedDataSetType Read_type Write setDataType;
Property isused: boolean read _bused;
Property Source: TDataSource Read GetDataSource;
Function ExportTOLS (Const INADAPTER: TXLSEXPADAPTER): Boolean
END;
IMPLEMENTATION
Function TXLSEXPADAPTER.COUNT (): Integer;
Begin
Result: = _ASfieldName.count;
END;
Function TXLSEXPADAPTER.GETXLSTITLE (Const IniINDEX: Integer): String;
Begin
IF (inIindex> = 0) and (inIindex <= _ADataType.count-1) THEN
Begin
Result: = _ASXLstitle [inIindex];
END;
END;
Function TXLSEXPADAPTER.GETFIELDNAME (Const IniINDEX: Integer): String;
Begin
IF (inIindex> = 0) and (inIindex <= _ADataType.count-1) THEN
Begin
Result: = _ASfieldName [inIindex];
END;
END;
Function TXLSEXPADAPTER.GETDATATYPE (Const IniINDEX: Integer): TDATYPE; Begin
IF (inIindex> = 0) and (inIindex <= _ADataType.count-1) THEN
Begin
Result: = TDATYPE (_ADATATYPE [IniInDex]);
END;
END;
Procedure TXLSEXPADAPTER.GETINFOFROMDBGRID (Const Inrid: TDBGRID);
VAR
I, J: Integer;
DT: TDATYPE;
Begin
For i: = 0 to ingrid.columns.count-1 do
Begin
If INGRID.COLUMNS [i] .visible the
Begin
DT: = ftunknown;
For j: = 0 to ingrid.fieldcount-1 do
Begin
If INGRID.COLUMNS [i] .fieldname = ingrid.fields [j] .fieldname dam
Begin
DT: = INGRID.FIELDS [J] .DATATYPE
Break;
END;
END;
Self.addfield (Ingrid.columns [i] .fieldName, INGRID.COLUMNS [i] .title.caption, dt);
END;
END;
END;
Procedure txlsexpadapter.addfield (constinfieldname, inscaption: string; constype: tdattype = ftunknown);
VAR
IINDEX: INTEGER;
Begin
IINDEX: = _ASfieldName.indexof (InsfieldName);
IF IIndex = -1 Then
Begin
_ASfieldName.Add (InsfieldName);
_asxlstitle.add (inscaption);
_adatatype.add (Tobject (inteles));
end
Else Begin
_asfieldname [IIndex]: = insfieldname;
_asxlstitle [IIndex]: = inscaption;
_adattype [IIndex]: = TOBJECT (INTYPE);
END;
END;
Constructor txlsexpadapter.create ();
Begin
_asfieldname: = tstringlist.create ();
_asxlstitle: = TSTRINGLIST.CREATE ();
_adattype: = TOBJECTLIST.CREATE ();
END;
Destructor TXLSEXPADAPTER.DESTROPADAPTER.DESTROY ();
Begin
END;
Function TmanagedDataSet.exPostToxls (Const INADAPTER: TXLSEXPADAPTER): Boolean
VAR
Excelobj: olevariant;
i: integer;
Begin
Result: = FALSE;
IF not self.active kil
EXIT;
Try
Excelobj: = CreateoleObject ('Excel.Application');
Excelobj.workbooks.add;
Except
EXIT;
End; if fileexists (inadapter.xlsfilename) and iNadapter.overwriteexistfile kil
Begin
Deletefile (pchar (inadapter.xlsfilename);
end
Else Begin
Excelobj.quit;
EXIT;
END;
For i: = 0 to INADADAPTER.COUNT-1 DO
Begin
END;
END;
Constructor TmanagedDataSet.create (const INTYPE: TManagedDataSettype = Editable);
Begin
Inherited Create (NIL);
Self.Connection: = DMCOMMON.CNN;
Self.cursorlocation: = cluseclient;
Self.prepared: = true;
Self.cachesize: = 1000;
IF intYPE = readonly then
Begin
Self.cursortype: = ctopenforwardonly;
Self.lockType: = LTREADOxLY;
end
Else if Intype = Editable Then
Begin
Self.cursortype: = CTSTATIC;
Self.lockType: = LTOPTIMISTIC;
END;
_type: = intYpe;
_bused: = false;
END;
Destructor TmanagedDataSet.destroy ();
Begin
IF self.active kil
Begin
Self.close;
END;
IF assigned (_Source) then
Begin
Freeandnil (_Source);
END;
Inherited destroy ();
END;
Procedure tmanagedDataSet.Use ();
Begin
IF _bused
Begin
Raise Exception.create ('Cannot Get A Used Managed DataSet!');
END;
_bused: = true;
END;
Procedure tmanagedDataSet.free ();
Begin
IF self.active kil
Begin
Self.close;
END;
Self.commandtext: = '';
Self.parameters.clear; // 睲 睲 计 计
Self.masterfields: = ''; // 睲 睲 珲
Self.DataSource: = NIL;
Self.executeOptions: = []; // 睲 睲 ︽
_bused: = false;
END;
Procedure TmanagedDataSet.SetDataSetType (Const INTYPE: TMANAGEDDATSETTYPE);
Begin
IF intYPE = _type dam
EXIT;
IF intYPE = readonly then
Begin
Self.cursortype: = ctopenforwardonly;
Self.lockType: = LTREADOxLY;
end
Else if Intype = Editable Then
Begin
Self.cursortype: = CTSTATIC; Self.lockType: = LTOPTIMISTIC
END;
END;
Function TmanagedDataSet.getDataSource (): TDataSource;
Begin
IF not assigned (_source) THEN
Begin
_Source: = tdataasource.create (nil);
_Source.autoEdit: = false;
_Source.DataSet: = Self;
END;
Result: = _Source;
END;
End.
Unit datasetpool; // 疠疠栋 globalvar 承 ㄒ ㄒ 祇
Interface
Uses ManagedDataSet, Contnrs, Sysutils, Adodb, DB, Commondm
Type
TDATASETPOOL = Class
Private
_ads: TOBJECTLIST;
Function getCount (): integer;
public
Constructor Creger (Const Ini: INTEGER = 10);
DEStructor destroy (); OVERRIDE;
Property Count: Integer Read GetCount;
Function getDataSet (const Intype: tmanagedDatatettype = editable): tmanagedDataSet;
Function getadocommand (): tadocommand; // degrees tadocommand 睦 パ パ ノ 砫 砫
END;
IMPLEMENTATION
Constructor TDataSetPool.create (Const Ini: Integer = 10);
Begin
_ads: = TOBJECTLISTLISTLISTLIST.CREATE
END;
Destructor TDataSetPool.destroy ();
Begin
Freeandnil (_ADS);
END;
Function TDataSetPool.getCount (): Integer;
Begin
Result: = _ADS.COUNT;
END;
Function TDataSetPool.getDataSet (constiType: tmanageddatatettype = editable): tmanageddata
VAR
i: integer;
Begin
Result: = NIL;
For i: = 0 to _ads.count-1 do
Begin
IF (_ADS [i]). iSused) and (tmanageddata). DataSettype = Intype) THEN
Begin
Result: = TmanagedDataSet (_ADS [i]);
Result.use;
Break;
END;
END;
if Result = nil dam
Begin
_ads.add (tmanagedDataSet.create (intYPE));
Result: = tmanagedDataSet (_ADS [_ADS.COUNT-1]);
Result.use;
END;
END;
Function TDataSetPool.getAdocommand (): tadocommand;
Begin
Result: = tadocommand.create (nil); result.connection: = DMCOMMON.CNN;
END;
End.