toolsunit.pas 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. unit ToolsUnit;
  2. {$IFDEF FPC}
  3. {$mode objfpc}{$H+}
  4. {$ENDIF}
  5. interface
  6. uses
  7. Classes, SysUtils, DB;
  8. Const MaxDataSet = 35;
  9. type
  10. { TDBConnector }
  11. TDBConnectorClass = class of TDBConnector;
  12. TDBConnector = class(TPersistent)
  13. private
  14. FChangedDatasets : array[0..MaxDataSet] of boolean;
  15. FUsedDatasets : TFPList;
  16. FChangedFieldDataset : boolean;
  17. protected
  18. // These methods should be implemented by any descendents
  19. // They are called eacht time a test need a TDataset descendent
  20. Function InternalGetNDataset(n : integer) : TDataset; virtual; abstract;
  21. Function InternalGetFieldDataset : TDataSet; virtual; abstract;
  22. // These methods should be implemented by any descendents
  23. // They are called only once in the constructor. They can be used
  24. // to create the tables on disk, or on a DB-Server
  25. procedure CreateNDatasets; virtual; abstract;
  26. procedure CreateFieldDataset; virtual; abstract;
  27. // These methods are called after each test in which a dataset is used
  28. // by calling GetXXXDataset with Achange=true
  29. // They should reset all data to their right/initial values.
  30. procedure ResetNDatasets; virtual;
  31. procedure ResetFieldDataset; virtual;
  32. // These methods are called only once in the destructor.
  33. // They should clean up all mess, like tables on disk or on a DB-server
  34. procedure DropNDatasets; virtual; abstract;
  35. procedure DropFieldDataset; virtual; abstract;
  36. public
  37. constructor create; virtual;
  38. destructor destroy; override;
  39. procedure DataEvent(dataset :TDataset);
  40. Function GetNDataset(n : integer) : TDataset; overload;
  41. Function GetNDataset(AChange : Boolean; n : integer) : TDataset; overload;
  42. Function GetFieldDataset : TDataSet; overload;
  43. Function GetFieldDataset(AChange : Boolean) : TDataSet; overload;
  44. procedure StartTest;
  45. procedure StopTest;
  46. end;
  47. { TTestDataLink }
  48. TTestDataLink = class(TDataLink)
  49. protected
  50. {$IFDEF fpc}
  51. procedure DataEvent(Event: TDataEvent; Info: Ptrint); override;
  52. {$ELSE}
  53. procedure DataEvent(Event: TDataEvent; Info: longint); override;
  54. {$ENDIF}
  55. end;
  56. const
  57. DataEventnames : Array [TDataEvent] of String[21] =
  58. ('deFieldChange', 'deRecordChange', 'deDataSetChange', 'deDataSetScroll',
  59. 'deLayoutChange', 'deUpdateRecord', 'deUpdateState', 'deCheckBrowseMode',
  60. 'dePropertyChange', 'deFieldListChange', 'deFocusControl' ,'deParentScroll',
  61. 'deConnectChange', 'deReconcileError', 'deDisabledStateChange');
  62. const
  63. testValuesCount = 25;
  64. testFloatValues : Array[0..testValuesCount-1] of double = (-maxSmallint-1,-maxSmallint,-256,-255,-128,-127,-1,0,1,127,128,255,256,maxSmallint,maxSmallint+1,0.123456,-0.123456,4.35,12.434E7,9.876e-5,123.45678,2.4,3.2,0.4,23);
  65. testCurrencyValues : Array[0..testValuesCount-1] of currency = (-100,-65.5,-54.34,-43.34,-2.50,-0.2,45.40,0.3,45.4,127,128,255,256,45,0.3,45.4,127,128,255,256,45,1234.56,43.23,43.43,99.88);
  66. testIntValues : Array[0..testValuesCount-1] of integer = (-maxInt,-maxInt+1,-maxSmallint-1,-maxSmallint,-256,-255,-128,-127,-1,0,1,127,128,255,256,maxSmallint,maxSmallint+1,MaxInt-1,MaxInt,100,130,150,-150,-132,234);
  67. testSmallIntValues : Array[0..testValuesCount-1] of smallint = (-maxSmallint,-maxSmallint+1,-256,-255,-128,-127,-1,0,1,127,128,255,256,maxSmallint,maxSmallint-1,100,110,120,130,150,-150,-132,234,231,42);
  68. testLargeIntValues : Array[0..testValuesCount-1] of smallint = (-MaxSIntValue,-MaxSIntValue+1,-maxInt-1,-maxInt+1,-maxSmallint,-maxSmallint+1,-256,-255,-128,-127,-1,0,1,127,128,255,256,maxSmallint,maxSmallint-1,maxSmallint+1,MaxInt-1,MaxInt,MaxSIntValue-1,MaxSIntValue,235253244);
  69. testBooleanValues : Array[0..testValuesCount-1] of boolean = (true,false,false,true,true,false,false,true,false,true,true,true,false,false,false,false,true,true,true,true,false,true,true,false,false);
  70. testStringValues : Array[0..testValuesCount-1] of string = (
  71. '',
  72. 'a',
  73. 'ab',
  74. 'abc',
  75. 'abcd',
  76. 'abcde',
  77. 'abcdef',
  78. 'abcdefg',
  79. 'abcdefgh',
  80. 'abcdefghi',
  81. 'abcdefghij',
  82. 'lMnOpQrStU',
  83. '1234567890',
  84. '_!@#$%^&*(',
  85. '_!@#$%^&*(',
  86. // ' ''quotes'' ',
  87. ')-;:/?.<>',
  88. '~`|{}- =', // note that there's no \ (backslash) since some db's uses that as escape-character
  89. ' WRaP ',
  90. 'wRaP ',
  91. ' wRAP',
  92. 'this',
  93. 'is',
  94. 'fun',
  95. 'VB7^',
  96. 'vdfbst'
  97. );
  98. testDateValues : Array[0..testValuesCount-1] of string = (
  99. '2000-01-01',
  100. '1999-12-31',
  101. '2004-02-29',
  102. '2004-03-01',
  103. '1991-02-28',
  104. '1991-03-01',
  105. '2040-10-16',
  106. '1977-09-29',
  107. '1800-03-30',
  108. '1650-05-10',
  109. '1754-06-04',
  110. '0904-04-12',
  111. '0199-07-09',
  112. '0001-01-01',
  113. '0031-11-02',
  114. '1899-12-29',
  115. '1899-12-30',
  116. '1899-12-31',
  117. '1977-09-29',
  118. '1917-12-29',
  119. '0079-11-29',
  120. '1997-11-29',
  121. '0001-01-01',
  122. '1997-11-29',
  123. '1900-01-01'
  124. );
  125. var dbtype,
  126. dbconnectorname,
  127. dbconnectorparams,
  128. dbname,
  129. dbuser,
  130. dbhostname,
  131. dbpassword : string;
  132. DataEvents : string;
  133. DBConnector : TDBConnector;
  134. testValues : Array [TFieldType,0..testvaluescount -1] of string;
  135. procedure InitialiseDBConnector;
  136. implementation
  137. uses
  138. sqldbtoolsunit,
  139. dbftoolsunit,
  140. memdstoolsunit,
  141. inifiles;
  142. constructor TDBConnector.create;
  143. begin
  144. CreateFieldDataset;
  145. CreateNDatasets;
  146. FUsedDatasets := TFPList.Create;
  147. end;
  148. destructor TDBConnector.destroy;
  149. begin
  150. FUsedDatasets.Destroy;
  151. DropNDatasets;
  152. DropFieldDataset;
  153. end;
  154. procedure TDBConnector.ResetNDatasets;
  155. begin
  156. DropNDatasets;
  157. CreateNDatasets;
  158. end;
  159. procedure TDBConnector.ResetFieldDataset;
  160. begin
  161. DropFieldDataset;
  162. CreateFieldDataset;
  163. end;
  164. procedure TDBConnector.DataEvent(dataset : tdataset);
  165. begin
  166. DataEvents := DataEvents + 'DataEvent' + ';';
  167. end;
  168. function TDBConnector.GetNDataset(n: integer): TDataset;
  169. begin
  170. Result := GetNDataset(False,n);
  171. end;
  172. procedure ReadIniFile;
  173. var IniFile : TIniFile;
  174. begin
  175. IniFile := TIniFile.Create(getcurrentdir + PathDelim + 'database.ini');
  176. dbtype:='';
  177. if Paramcount>0 then
  178. dbtype := ParamStr(1);
  179. if (dbtype='') or not inifile.SectionExists(dbtype) then
  180. dbtype := IniFile.ReadString('Database','Type','');
  181. dbconnectorname := IniFile.ReadString(dbtype,'Connector','');
  182. dbname := IniFile.ReadString(dbtype,'Name','');
  183. dbuser := IniFile.ReadString(dbtype,'User','');
  184. dbhostname := IniFile.ReadString(dbtype,'Hostname','');
  185. dbpassword := IniFile.ReadString(dbtype,'Password','');
  186. dbconnectorparams := IniFile.ReadString(dbtype,'ConnectorParams','');
  187. IniFile.Free;
  188. end;
  189. procedure InitialiseDBConnector;
  190. var DBConnectorClass : TPersistentClass;
  191. i : integer;
  192. begin
  193. testValues[ftString] := testStringValues;
  194. testValues[ftDate] := testDateValues;
  195. for i := 0 to testValuesCount-1 do
  196. begin
  197. testValues[ftFloat,i] := FloatToStr(testFloatValues[i]);
  198. testValues[ftSmallint,i] := IntToStr(testSmallIntValues[i]);
  199. testValues[ftInteger,i] := IntToStr(testIntValues[i]);
  200. testValues[ftLargeint,i] := IntToStr(testLargeIntValues[i]);
  201. DecimalSeparator:=',';
  202. testValues[ftCurrency,i] := CurrToStr(testCurrencyValues[i]);
  203. DecimalSeparator:='.';
  204. testValues[ftBCD,i] := CurrToStr(testCurrencyValues[i]);
  205. end;
  206. if dbconnectorname = '' then raise Exception.Create('There is no db-connector specified');
  207. DBConnectorClass := GetClass('T'+dbconnectorname+'DBConnector');
  208. if assigned(DBConnectorClass) then
  209. DBConnector := TDBConnectorClass(DBConnectorClass).create
  210. else Raise Exception.Create('Unknown db-connector specified');
  211. end;
  212. { TTestDataLink }
  213. {$IFDEF FPC}
  214. procedure TTestDataLink.DataEvent(Event: TDataEvent; Info: Ptrint);
  215. {$ELSE}
  216. procedure TTestDataLink.DataEvent(Event: TDataEvent; Info: Longint);
  217. {$ENDIF}
  218. begin
  219. DataEvents := DataEvents + DataEventnames[Event] + ':' + inttostr(info) + ';';
  220. inherited DataEvent(Event, Info);
  221. end;
  222. { TDBConnector }
  223. function TDBConnector.GetNDataset(AChange : Boolean; n: integer): TDataset;
  224. begin
  225. if AChange then FChangedDatasets[n] := True;
  226. Result := InternalGetNDataset(n);
  227. FUsedDatasets.Add(Result);
  228. end;
  229. function TDBConnector.GetFieldDataset: TDataSet;
  230. begin
  231. Result := GetFieldDataset(False);
  232. end;
  233. function TDBConnector.GetFieldDataset(AChange: Boolean): TDataSet;
  234. begin
  235. if AChange then FChangedFieldDataset := True;
  236. Result := InternalGetFieldDataset;
  237. FUsedDatasets.Add(Result);
  238. end;
  239. procedure TDBConnector.StartTest;
  240. begin
  241. // Do nothing?
  242. end;
  243. procedure TDBConnector.StopTest;
  244. var i : integer;
  245. ds : TDataset;
  246. begin
  247. for i := 0 to FUsedDatasets.Count -1 do
  248. begin
  249. ds := tdataset(FUsedDatasets[i]);
  250. if ds.active then ds.Close;
  251. ds.Free;
  252. end;
  253. FUsedDatasets.Clear;
  254. if FChangedFieldDataset then ResetFieldDataset;
  255. for i := 0 to MaxDataSet do if FChangedDatasets[i] then
  256. begin
  257. ResetNDatasets;
  258. fillchar(FChangedDatasets,sizeof(FChangedDatasets),ord(False));
  259. break;
  260. end;
  261. end;
  262. initialization
  263. ReadIniFile;
  264. end.