testbasics.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. unit TestBasics;
  2. {$IFDEF FPC}
  3. {$mode objfpc}{$H+}
  4. {$ENDIF}
  5. interface
  6. uses
  7. fpcunit, testutils, testregistry, testdecorator,
  8. Classes, SysUtils, db;
  9. type
  10. { TTestBasics }
  11. TTestBasics = class(TTestCase)
  12. private
  13. function CreateDatasetWith3Fields: TDataset;
  14. protected
  15. published
  16. procedure TestParseSQL;
  17. procedure TestInitFielddefsFromFields;
  18. procedure TestDoubleFieldDef;
  19. procedure TestFieldDefWithoutDS;
  20. procedure TestGetParamList;
  21. procedure TestGetFieldList;
  22. procedure TestExtractFieldName; //move record then copy. Is copy identical? Has record position changed?
  23. procedure TestCheckFieldNames;
  24. procedure TestFindField;
  25. end;
  26. implementation
  27. uses toolsunit;
  28. Type HackedDataset = class(TDataset);
  29. { TTestBasics }
  30. function TTestBasics.CreateDatasetWith3Fields: TDataset;
  31. var
  32. F: TField;
  33. begin
  34. Result := TDataSet.Create(nil);
  35. F := TIntegerField.Create(Result);
  36. F.FieldName := 'Field1';
  37. F.DataSet := Result;
  38. F := TIntegerField.Create(Result);
  39. F.FieldName := 'Field2';
  40. F.DataSet := Result;
  41. F := TIntegerField.Create(Result);
  42. F.FieldName := 'Field3';
  43. F.DataSet := Result;
  44. end;
  45. procedure TTestBasics.TestParseSQL;
  46. var Params : TParams;
  47. ReplStr : string;
  48. pb : TParamBinding;
  49. i : integer;
  50. SQLStr : string;
  51. begin
  52. Params := TParams.Create;
  53. AssertEquals( 'select * from table where id = $1',
  54. params.ParseSQL('select * from table where id = :id',true,True,True,psPostgreSQL));
  55. AssertEquals( 'select * from table where id = $1',
  56. params.ParseSQL('select * from table where id = :id',false,True,True,psPostgreSQL));
  57. AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 where (id = $2)',
  58. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :2)',true,True,True,psPostgreSQL));
  59. AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 where (id = $3) and (test=''$test'')',
  60. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :par3) and (test=''$test'')',true,true,true,psPostgreSQL));
  61. AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 10=$10 11=$11 12=$5 where (id = $3) and (test=''$test'')',
  62. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,true,true,psPostgreSQL));
  63. AssertEquals( 'select * from table where id = $1',
  64. params.ParseSQL('select * from table where id = :id',true,true,false,psSimulated,pb,ReplStr));
  65. AssertEquals('$',ReplStr);
  66. AssertEquals( 'update test set 1=$1 2=$2 3=$3 4=$4 5=$5 6=$6 7=$7 8=$8 9=$9 where (id = $2)',
  67. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :2)',true,true,false,psSimulated,pb,ReplStr));
  68. AssertEquals('$',ReplStr);
  69. AssertEquals( 'update test set 1=$$1 2=$$2 3=$$3 4=$$4 5=$$5 6=$$6 7=$$7 8=$$8 9=$$9 where (id = $$3) and (test=''$test'')',
  70. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 where (id = :par3) and (test=''$test'')',true,true,false,psSimulated,pb,ReplStr));
  71. AssertEquals('$$',ReplStr);
  72. AssertEquals( 'update test set 1=$$1 2=$$2 3=$$3 4=$$4 5=$$5 6=$$6 7=$$7 8=$$8 9=$$9 10=$$10 11=$$11 12=$$5 where (id = $$3) and (test=''$test'')',
  73. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id = :par3) and (test=''$test'')',true,True,True,psSimulated));
  74. AssertEquals('$$',ReplStr);
  75. AssertEquals( 'update test set 1=$$$1 2=$$$2 3=$$$3 4=$$$4 5=$$$5 6=$$$6 7=$$$7 8=$$$8 9=$$$9 10=$$$10 11=$$$11 12=$$$5 where (id$$ = $$$3) and (test$=''$test'')',
  76. params.ParseSQL('update test set 1=:1 2=:2 3=:par3 4=:par4 5=:par5 6=:par6 7=:par7 8=:par8 9=:par9 10=:par10 11=:11 12=:par5 where (id$$ = :par3) and (test$=''$test'')',true,true,False,psSimulated,pb,ReplStr));
  77. AssertEquals('$$$',ReplStr);
  78. AssertEquals( 'select * from table where id = ?',
  79. params.ParseSQL('select * from table where id = :id',true,true,true,psInterbase));
  80. // Test bug 10345
  81. AssertEquals( 'select email from table where upper(email) like ''%''||?||''%''',
  82. params.ParseSQL('select email from table where upper(email) like ''%''||:email||''%''',true,true,true,psInterbase));
  83. // Test escape-sequences:
  84. AssertEquals( 'select * from table where ''id '''' = :id''',
  85. params.ParseSQL('select * from table where ''id '''' = :id''',true,False,True,psPostgreSQL));
  86. AssertEquals( 'select * from table where "id "" = :id"',
  87. params.ParseSQL('select * from table where "id "" = :id"',true,False,True,psPostgreSQL));
  88. AssertEquals( 'select * from table where "id \" = :id"',
  89. params.ParseSQL('select * from table where "id \" = :id"',true,True,False,psPostgreSQL));
  90. AssertEquals( 'select * from table where "id \" = $1',
  91. params.ParseSQL('select * from table where "id \" = :id',true,False,False,psPostgreSQL));
  92. AssertEquals( 'select * from table where "id = :id\',
  93. params.ParseSQL('select * from table where "id = :id\',true,True,True,psInterbase));
  94. // Test strange-field names
  95. AssertEquals( 'select * from table where "field-name" = ?',
  96. params.ParseSQL('select * from table where "field-name" = :"field-name"',true,True,True,psInterbase));
  97. AssertEquals('field-name',Params.Items[0].Name);
  98. AssertEquals( 'select * from table where "field-name" = ?',
  99. params.ParseSQL('select * from table where "field-name" = :"field-name',true,True,True,psInterbase));
  100. // Test more than 99 params - bug 19645
  101. SQLStr := 'update test set';
  102. for i := 1 to 101 do
  103. SQLStr := format('%s field%d=:par%d', [SQLStr,i,i]);
  104. AssertEquals( StringReplace(SQLStr, ':par', '$', [rfReplaceAll]),
  105. Params.ParseSQL(SQLStr, True, True, True, psPostgreSQL) );
  106. // Test comments:
  107. // Simple comment
  108. AssertEquals( 'select * from table where id= --comment :c'#10'$1-$2 or id= --:c'#13'-$3',
  109. Params.ParseSQL('select * from table where id= --comment :c'#10':a-:b or id= --:c'#13'-:d', True, True, True, psPostgreSQL));
  110. // Bracketed comment
  111. AssertEquals( 'select * from table where id=/*comment :c*/$1-$2',
  112. Params.ParseSQL('select * from table where id=/*comment :c*/:a-:b', True, True, True, psPostgreSQL));
  113. AssertEquals( 'select * from table where id=/*comment :c**/$1-$2',
  114. Params.ParseSQL('select * from table where id=/*comment :c**/:a-:b', True, True, True, psPostgreSQL));
  115. // Consecutive comments, with quote in second comment
  116. AssertEquals( '--c1'#10'--c'''#10'select '':a'' from table where id=$1',
  117. Params.ParseSQL('--c1'#10'--c'''#10'select '':a'' from table where id=:id', True, True, True, psPostgreSQL));
  118. Params.Free;
  119. end;
  120. procedure TTestBasics.TestInitFielddefsFromFields;
  121. var ds : TDataset;
  122. F1,F2,F3 : Tfield;
  123. Procedure CompareFieldAndFieldDef(Fld: TField; FldDef : TFieldDef);
  124. begin
  125. AssertEquals(Fld.FieldName,FldDef.Name);
  126. AssertEquals(Fld.Size,FldDef.Size);
  127. AssertEquals(Fld.Required,FldDef.Required);
  128. AssertTrue(Fld.DataType=FldDef.DataType);
  129. end;
  130. begin
  131. ds := TDataset.Create(nil);
  132. try
  133. F1:=TStringField.Create(ds);
  134. F1.Size := 10;
  135. F1.Name := 'StringFld';
  136. F1.FieldName := 'FStringFld';
  137. F1.Required := false;
  138. F1.Dataset:=ds;
  139. F2:=TIntegerField.Create(ds);
  140. F2.Name := 'IntegerFld';
  141. F2.FieldName := 'FIntegerFld';
  142. F2.Required := True;
  143. F2.Dataset:=ds;
  144. F3:=TBCDField.Create(ds);
  145. F3.Name := 'BCDFld';
  146. F3.FieldName := 'FBCDFld';
  147. F3.Required := false;
  148. F3.Dataset:=ds;
  149. (f3 as TBCDField).Precision := 2;
  150. HackedDataset(ds).InitFieldDefsFromfields;
  151. AssertEquals(3,ds.FieldDefs.Count);
  152. CompareFieldAndFieldDef(F1,ds.FieldDefs[0]);
  153. CompareFieldAndFieldDef(F2,ds.FieldDefs[1]);
  154. CompareFieldAndFieldDef(F3,ds.FieldDefs[2]);
  155. finally
  156. ds.Free;
  157. end;
  158. end;
  159. procedure TTestBasics.TestDoubleFieldDef;
  160. var ds : TDataset;
  161. PassException : boolean;
  162. begin
  163. // If a second field with the same name is added to a TFieldDefs, an exception
  164. // should occur
  165. ds := TDataset.create(nil);
  166. try
  167. ds.FieldDefs.Add('Field1',ftInteger);
  168. PassException:=False;
  169. try
  170. ds.FieldDefs.Add('Field1',ftString,10,false)
  171. except
  172. on E: EDatabaseError do PassException := True;
  173. end;
  174. AssertTrue(PassException);
  175. finally
  176. ds.Free;
  177. end;
  178. end;
  179. procedure TTestBasics.TestFieldDefWithoutDS;
  180. var FieldDefs : TFieldDefs;
  181. begin
  182. FieldDefs := TFieldDefs.Create(nil);
  183. try
  184. FieldDefs.Add('test',ftString);
  185. finally
  186. FieldDefs.Free;
  187. end;
  188. end;
  189. procedure TTestBasics.TestGetFieldList;
  190. var
  191. ds: TDataSet;
  192. List: TList;
  193. ExceptionRaised: Boolean;
  194. begin
  195. ds := CreateDatasetWith3Fields;
  196. try
  197. List := TList.Create;
  198. try
  199. //should not
  200. List.Clear;
  201. ds.GetFieldList(List, '');
  202. AssertEquals(0, List.Count);
  203. List.Clear;
  204. ExceptionRaised := False;
  205. try
  206. ds.GetFieldList(List, ' ');
  207. except
  208. on E: EDatabaseError do ExceptionRaised := True;
  209. end;
  210. AssertTrue(ExceptionRaised);
  211. List.Clear;
  212. ds.GetFieldList(List, 'Field1');
  213. AssertEquals(1, List.Count);
  214. List.Clear;
  215. ds.GetFieldList(List, ' Field1 ');
  216. AssertEquals(1, List.Count);
  217. List.Clear;
  218. ds.GetFieldList(List, 'Field1;Field2');
  219. AssertEquals(2, List.Count);
  220. List.Clear;
  221. ds.GetFieldList(List, 'Field1;Field2;');
  222. AssertEquals(2, List.Count);
  223. List.Clear;
  224. ds.GetFieldList(List, 'Field1;Field2;Field3');
  225. AssertEquals(3, List.Count);
  226. finally
  227. List.Destroy;
  228. end;
  229. finally
  230. ds.Destroy;
  231. end;
  232. end;
  233. procedure TTestBasics.TestGetParamList;
  234. var
  235. Params: TParams;
  236. P: TParam;
  237. List: TList;
  238. ExceptionRaised: Boolean;
  239. begin
  240. Params := TParams.Create(nil);
  241. try
  242. P := TParam.Create(Params, ptInput);
  243. P.Name := 'Param1';
  244. P := TParam.Create(Params, ptInput);
  245. P.Name := 'Param2';
  246. P := TParam.Create(Params, ptInput);
  247. P.Name := 'Param3';
  248. List := TList.Create;
  249. try
  250. List.Clear;
  251. Params.GetParamList(List, '');
  252. AssertEquals(0, List.Count);
  253. List.Clear;
  254. ExceptionRaised := False;
  255. try
  256. Params.GetParamList(List, ' ');
  257. except
  258. on E: EDatabaseError do ExceptionRaised := True;
  259. end;
  260. AssertTrue(ExceptionRaised);
  261. List.Clear;
  262. Params.GetParamList(List, 'Param1');
  263. AssertEquals(1, List.Count);
  264. List.Clear;
  265. Params.GetParamList(List, ' Param1 ');
  266. AssertEquals(1, List.Count);
  267. List.Clear;
  268. Params.GetParamList(List, 'Param1;');
  269. AssertEquals(1, List.Count);
  270. List.Clear;
  271. Params.GetParamList(List, 'Param1;Param2');
  272. AssertEquals(2, List.Count);
  273. List.Clear;
  274. Params.GetParamList(List, 'Param1;Param2;Param3');
  275. AssertEquals(3, List.Count);
  276. finally
  277. List.Destroy;
  278. end;
  279. finally
  280. Params.Destroy;
  281. end;
  282. end;
  283. procedure TTestBasics.TestExtractFieldName;
  284. var
  285. i: Integer;
  286. Fields: String;
  287. FieldName: String;
  288. begin
  289. Fields := '';
  290. i := 1;
  291. FieldName := ExtractFieldName(Fields, i);
  292. AssertEquals(1, i);
  293. AssertEquals('', FieldName);
  294. Fields := 'test';
  295. i := 1;
  296. FieldName := ExtractFieldName(Fields, i);
  297. AssertEquals(5, i);
  298. AssertEquals('test', FieldName);
  299. Fields := 'test;';
  300. i := 1;
  301. FieldName := ExtractFieldName(Fields, i);
  302. AssertEquals(6, i);
  303. AssertEquals('test', FieldName);
  304. Fields := ' test ';
  305. i := 1;
  306. FieldName := ExtractFieldName(Fields, i);
  307. AssertEquals(7, i);
  308. AssertEquals('test', FieldName);
  309. Fields := 'test;xxx';
  310. i := 1;
  311. FieldName := ExtractFieldName(Fields, i);
  312. AssertEquals(6, i);
  313. AssertEquals('test', FieldName);
  314. FieldName := ExtractFieldName(Fields, i);
  315. AssertEquals(9, i);
  316. AssertEquals('xxx', FieldName);
  317. end;
  318. procedure TTestBasics.TestCheckFieldNames;
  319. var
  320. ds: TDataSet;
  321. ExceptionRaised: Boolean;
  322. begin
  323. ds := CreateDatasetWith3Fields;
  324. try
  325. ExceptionRaised := False;
  326. try
  327. ds.Fields.CheckFieldNames('');
  328. except
  329. ExceptionRaised := True;
  330. end;
  331. AssertFalse(ExceptionRaised);
  332. ExceptionRaised := False;
  333. try
  334. ds.Fields.CheckFieldNames('Field1;Field2');
  335. except
  336. ExceptionRaised := True;
  337. end;
  338. AssertFalse(ExceptionRaised);
  339. ExceptionRaised := False;
  340. try
  341. ds.Fields.CheckFieldNames('Field1;NonExistentField');
  342. except
  343. ExceptionRaised := True;
  344. end;
  345. AssertTrue(ExceptionRaised);
  346. finally
  347. ds.Destroy;
  348. end;
  349. end;
  350. procedure TTestBasics.TestFindField;
  351. var
  352. ds: TDataSet;
  353. F: TField;
  354. begin
  355. ds := CreateDatasetWith3Fields;
  356. try
  357. F := ds.FindField('');
  358. AssertTrue(F = nil);
  359. F := ds.FindField('field3');
  360. AssertTrue(F <> nil);
  361. F := ds.FindField('NonExistentField');
  362. AssertTrue(F = nil);
  363. finally
  364. ds.Destroy;
  365. end;
  366. end;
  367. initialization
  368. RegisterTest(TTestBasics);
  369. end.