testdbbasics.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. unit TestDBBasics;
  2. {$IFDEF FPC}
  3. {$mode Delphi}{$H+}
  4. {$ENDIF}
  5. interface
  6. uses
  7. fpcunit, testutils, testregistry, testdecorator,
  8. Classes, SysUtils, db;
  9. type
  10. { TTestDBBasics }
  11. TTestDBBasics = class(TTestCase)
  12. private
  13. procedure TestfieldDefinition(AFieldType : TFieldType;ADatasize : integer;var ADS : TDataset; var AFld: TField);
  14. protected
  15. procedure SetUp; override;
  16. procedure TearDown; override;
  17. published
  18. procedure TestSupportIntegerFields;
  19. procedure TestSupportSmallIntFields;
  20. procedure TestSupportStringFields;
  21. procedure TestSupportBooleanFields;
  22. procedure TestSupportFloatFields;
  23. procedure TestSupportLargeIntFields;
  24. procedure TestSupportDateFields;
  25. procedure TestIsEmpty;
  26. procedure TestAppendOnEmptyDataset;
  27. procedure TestInsertOnEmptyDataset;
  28. procedure TestBufDatasetCancelUpdates; //bug 6938
  29. procedure TestEofAfterFirst; //bug 7211
  30. procedure TestBufDatasetCancelUpdates1;
  31. procedure TestDoubleClose;
  32. procedure TestAssignFieldftString;
  33. procedure TestAssignFieldftFixedChar;
  34. procedure TestSelectQueryBasics;
  35. procedure TestPostOnlyInEditState;
  36. procedure TestMove; // bug 5048
  37. procedure TestActiveBufferWhenClosed;
  38. procedure TestEOFBOFClosedDataset;
  39. procedure TestDataEventsResync;
  40. procedure TestBug7007;
  41. procedure TestdeFieldListChange;
  42. procedure TestLastAppendCancel; // bug 5058
  43. procedure TestRecNo; // bug 5061
  44. procedure TestSetRecNo; // bug 6919
  45. end;
  46. { TSQLTestSetup }
  47. TDBBasicsTestSetup = class(TTestSetup)
  48. protected
  49. procedure OneTimeSetup; override;
  50. procedure OneTimeTearDown; override;
  51. end;
  52. implementation
  53. uses toolsunit, bufdataset;
  54. procedure TTestDBBasics.TestIsEmpty;
  55. begin
  56. if not (DBConnector.GetNDataset(5) is TBufDataset) then
  57. Ignore('This test only applies to TBufDataset and descendents.');
  58. with tbufdataset(DBConnector.GetNDataset(True,1)) do
  59. begin
  60. open;
  61. delete;
  62. refresh;
  63. applyupdates;
  64. AssertTrue(IsEmpty);
  65. end;
  66. end;
  67. procedure TTestDBBasics.TestAppendOnEmptyDataset;
  68. begin
  69. with DBConnector.GetNDataset(0) do
  70. begin
  71. open;
  72. AssertTrue(CanModify);
  73. AssertTrue(eof);
  74. AssertTrue(bof);
  75. append;
  76. AssertFalse(Bof);
  77. AssertTrue(Eof);
  78. post;
  79. AssertFalse(eof);
  80. AssertFalse(bof);
  81. end;
  82. end;
  83. procedure TTestDBBasics.TestInsertOnEmptyDataset;
  84. begin
  85. with DBConnector.GetNDataset(0) do
  86. begin
  87. open;
  88. AssertTrue(CanModify);
  89. AssertTrue(eof);
  90. AssertTrue(bof);
  91. AssertTrue(IsEmpty);
  92. insert;
  93. AssertTrue(Bof);
  94. AssertTrue(Eof);
  95. AssertFalse(IsEmpty);
  96. post;
  97. AssertFalse(IsEmpty);
  98. AssertFalse(eof);
  99. AssertFalse(bof);
  100. end;
  101. end;
  102. procedure TTestDBBasics.TestSelectQueryBasics;
  103. var b : TFieldType;
  104. begin
  105. with DBConnector.GetNDataset(1) do
  106. begin
  107. Open;
  108. AssertEquals(1,RecNo);
  109. AssertEquals(1,RecordCount);
  110. AssertEquals(2,FieldCount);
  111. AssertTrue(CompareText('ID',fields[0].FieldName)=0);
  112. AssertTrue(CompareText('ID',fields[0].DisplayName)=0);
  113. AssertTrue('The datatype of the field ''ID'' is incorrect, it should be ftInteger',ftInteger=fields[0].DataType);
  114. AssertTrue(CompareText('NAME',fields[1].FieldName)=0);
  115. AssertTrue(CompareText('NAME',fields[1].DisplayName)=0);
  116. AssertTrue(ftString=fields[1].DataType);
  117. AssertEquals(1,fields[0].Value);
  118. AssertEquals('TestName1',fields[1].Value);
  119. Close;
  120. end;
  121. end;
  122. procedure TTestDBBasics.TestPostOnlyInEditState;
  123. begin
  124. with DBConnector.GetNDataset(1) do
  125. begin
  126. open;
  127. AssertException('Post was called in a non-edit state',EDatabaseError,Post);
  128. end;
  129. end;
  130. procedure TTestDBBasics.TestMove;
  131. var i,count : integer;
  132. aDatasource : TDataSource;
  133. aDatalink : TDataLink;
  134. ABufferCount : Integer;
  135. begin
  136. aDatasource := TDataSource.Create(nil);
  137. aDatalink := TTestDataLink.Create;
  138. aDatalink.DataSource := aDatasource;
  139. ABufferCount := 11;
  140. aDatalink.BufferCount := ABufferCount;
  141. DataEvents := '';
  142. for count := 0 to 32 do
  143. begin
  144. aDatasource.DataSet := DBConnector.GetNDataset(count);
  145. with aDatasource.Dataset do
  146. begin
  147. i := 1;
  148. Open;
  149. AssertEquals('deUpdateState:0;',DataEvents);
  150. DataEvents := '';
  151. while not EOF do
  152. begin
  153. AssertEquals(i,fields[0].AsInteger);
  154. AssertEquals('TestName'+inttostr(i),fields[1].AsString);
  155. inc(i);
  156. Next;
  157. if (i > ABufferCount) and not EOF then
  158. AssertEquals('deCheckBrowseMode:0;deDataSetScroll:-1;',DataEvents)
  159. else
  160. AssertEquals('deCheckBrowseMode:0;deDataSetScroll:0;',DataEvents);
  161. DataEvents := '';
  162. end;
  163. AssertEquals(count,i-1);
  164. close;
  165. AssertEquals('deUpdateState:0;',DataEvents);
  166. DataEvents := '';
  167. end;
  168. end;
  169. end;
  170. procedure TTestDBBasics.TestdeFieldListChange;
  171. var i,count : integer;
  172. aDatasource : TDataSource;
  173. aDatalink : TDataLink;
  174. ds : TDataset;
  175. begin
  176. aDatasource := TDataSource.Create(nil);
  177. aDatalink := TTestDataLink.Create;
  178. aDatalink.DataSource := aDatasource;
  179. ds := DBConnector.GetNDataset(1);
  180. with ds do
  181. begin
  182. aDatasource.DataSet := ds;
  183. DataEvents := '';
  184. open;
  185. Fields.add(tfield.Create(DBConnector.GetNDataset(1)));
  186. AssertEquals('deUpdateState:0;deFieldListChange:0;',DataEvents);
  187. DataEvents := '';
  188. fields.Clear;
  189. AssertEquals('deFieldListChange:0;',DataEvents)
  190. end;
  191. aDatasource.Free;
  192. aDatalink.Free;
  193. end;
  194. procedure TTestDBBasics.TestActiveBufferWhenClosed;
  195. begin
  196. with DBConnector.GetNDataset(0) do
  197. begin
  198. AssertNull(ActiveBuffer);
  199. open;
  200. AssertFalse('Activebuffer of an empty dataset shouldn''t be nil',ActiveBuffer = nil);
  201. end;
  202. end;
  203. procedure TTestDBBasics.TestEOFBOFClosedDataset;
  204. begin
  205. with DBConnector.GetNDataset(1) do
  206. begin
  207. AssertTrue(EOF);
  208. AssertTrue(BOF);
  209. open;
  210. close;
  211. AssertTrue(EOF);
  212. AssertTrue(BOF);
  213. end;
  214. end;
  215. procedure TTestDBBasics.TestDataEventsResync;
  216. var i,count : integer;
  217. aDatasource : TDataSource;
  218. aDatalink : TDataLink;
  219. ds : tdataset;
  220. begin
  221. aDatasource := TDataSource.Create(nil);
  222. aDatalink := TTestDataLink.Create;
  223. aDatalink.DataSource := aDatasource;
  224. ds := DBConnector.GetNDataset(6);
  225. ds.BeforeScroll := DBConnector.DataEvent;
  226. with ds do
  227. begin
  228. aDatasource.DataSet := ds;
  229. open;
  230. DataEvents := '';
  231. Resync([rmExact]);
  232. AssertEquals('deDataSetChange:0;',DataEvents);
  233. DataEvents := '';
  234. next;
  235. AssertEquals('deCheckBrowseMode:0;DataEvent;deDataSetScroll:0;',DataEvents);
  236. close;
  237. end;
  238. aDatasource.Free;
  239. aDatalink.Free;
  240. end;
  241. procedure TTestDBBasics.TestLastAppendCancel;
  242. var count : integer;
  243. begin
  244. for count := 0 to 32 do with DBConnector.GetNDataset(count) do
  245. begin
  246. open;
  247. Last;
  248. Append;
  249. Cancel;
  250. AssertEquals(count,fields[0].asinteger);
  251. AssertEquals(count,RecordCount);
  252. Close;
  253. end;
  254. end;
  255. procedure TTestDBBasics.TestRecNo;
  256. var i : longint;
  257. passed : boolean;
  258. begin
  259. with DBConnector.GetNDataset(0) do
  260. begin
  261. // Accessing RecNo on a closed dataset should raise an EDatabaseError or should
  262. // return 0
  263. passed := false;
  264. try
  265. i := recno;
  266. except on E: Exception do
  267. begin
  268. passed := E.classname = EDatabaseError.className
  269. end;
  270. end;
  271. if not passed then
  272. AssertEquals('Failed to get the RecNo from a closed dataset',0,RecNo);
  273. // Accessing Recordcount on a closed dataset should raise an EDatabaseError or should
  274. // return 0
  275. passed := false;
  276. try
  277. i := recordcount;
  278. except on E: Exception do
  279. begin
  280. passed := E.classname = EDatabaseError.className
  281. end;
  282. end;
  283. if not passed then
  284. AssertEquals('Failed to get the Recordcount from a closed dataset',0,RecNo);
  285. Open;
  286. AssertEquals(0,RecordCount);
  287. AssertEquals(0,RecNo);
  288. first;
  289. AssertEquals(0,RecordCount);
  290. AssertEquals(0,RecNo);
  291. last;
  292. AssertEquals(0,RecordCount);
  293. AssertEquals(0,RecNo);
  294. append;
  295. AssertEquals(0,RecNo);
  296. AssertEquals(0,RecordCount);
  297. first;
  298. AssertEquals(0,RecNo);
  299. AssertEquals(0,RecordCount);
  300. append;
  301. FieldByName('id').AsInteger := 1;
  302. AssertEquals(0,RecNo);
  303. AssertEquals(0,RecordCount);
  304. first;
  305. AssertEquals(1,RecNo);
  306. AssertEquals(1,RecordCount);
  307. last;
  308. AssertEquals(1,RecNo);
  309. AssertEquals(1,RecordCount);
  310. append;
  311. FieldByName('id').AsInteger := 1;
  312. AssertEquals(0,RecNo);
  313. AssertEquals(1,RecordCount);
  314. Close;
  315. end;
  316. end;
  317. procedure TTestDBBasics.TestSetRecNo;
  318. begin
  319. with DBConnector.GetNDataset(15) do
  320. begin
  321. Open;
  322. RecNo := 1;
  323. AssertEquals(1,fields[0].AsInteger);
  324. AssertEquals(1,RecNo);
  325. RecNo := 2;
  326. AssertEquals(2,fields[0].AsInteger);
  327. AssertEquals(2,RecNo);
  328. RecNo := 8;
  329. AssertEquals(8,fields[0].AsInteger);
  330. AssertEquals(8,RecNo);
  331. RecNo := 15;
  332. AssertEquals(15,fields[0].AsInteger);
  333. AssertEquals(15,RecNo);
  334. RecNo := 3;
  335. AssertEquals(3,fields[0].AsInteger);
  336. AssertEquals(3,RecNo);
  337. RecNo := 14;
  338. AssertEquals(14,fields[0].AsInteger);
  339. AssertEquals(14,RecNo);
  340. RecNo := 15;
  341. AssertEquals(15,fields[0].AsInteger);
  342. AssertEquals(15,RecNo);
  343. // test for exceptions...
  344. { RecNo := 16;
  345. AssertEquals(15,fields[0].AsInteger);
  346. AssertEquals(15,RecNo);}
  347. Close;
  348. end;
  349. end;
  350. procedure TTestDBBasics.SetUp;
  351. begin
  352. DBConnector.StartTest;
  353. end;
  354. procedure TTestDBBasics.TearDown;
  355. begin
  356. DBConnector.StopTest;
  357. end;
  358. procedure TTestDBBasics.TestEofAfterFirst;
  359. begin
  360. with DBConnector.GetNDataset(0) do
  361. begin
  362. open;
  363. AssertTrue(eof);
  364. AssertTrue(BOF);
  365. first;
  366. AssertTrue(eof);
  367. AssertTrue(BOF);
  368. end;
  369. end;
  370. procedure TTestDBBasics.TestfieldDefinition(AFieldType : TFieldType;ADatasize : integer;var ADS : TDataset; var AFld: TField);
  371. var i : byte;
  372. begin
  373. ADS := DBConnector.GetFieldDataset;
  374. ADS.Open;
  375. AFld := ADS.FindField('F'+FieldTypeNames[AfieldType]);
  376. AssertNotNull('Fields of the type ' + FieldTypeNames[AfieldType] + ' are not supported by this type of dataset',AFld);
  377. AssertTrue(Afld.DataType = AFieldType);
  378. AssertEquals(ADatasize,Afld.DataSize );
  379. end;
  380. procedure TTestDBBasics.TestSupportIntegerFields;
  381. var i : byte;
  382. ds : TDataset;
  383. Fld : TField;
  384. begin
  385. TestfieldDefinition(ftInteger,4,ds,Fld);
  386. for i := 0 to testValuesCount-1 do
  387. begin
  388. AssertEquals(testIntValues[i],Fld.AsInteger);
  389. ds.Next;
  390. end;
  391. ds.close;
  392. end;
  393. procedure TTestDBBasics.TestSupportSmallIntFields;
  394. var i : byte;
  395. ds : TDataset;
  396. Fld : TField;
  397. begin
  398. TestfieldDefinition(ftSmallint,2,ds,Fld);
  399. for i := 0 to testValuesCount-1 do
  400. begin
  401. AssertEquals(testSmallIntValues[i],Fld.AsInteger);
  402. ds.Next;
  403. end;
  404. ds.close;
  405. end;
  406. procedure TTestDBBasics.TestSupportStringFields;
  407. var i : byte;
  408. ds : TDataset;
  409. Fld : TField;
  410. begin
  411. TestfieldDefinition(ftString,11,ds,Fld);
  412. for i := 0 to testValuesCount-1 do
  413. begin
  414. AssertEquals(testStringValues[i],Fld.AsString);
  415. ds.Next;
  416. end;
  417. ds.close;
  418. end;
  419. procedure TTestDBBasics.TestSupportBooleanFields;
  420. var i : byte;
  421. ds : TDataset;
  422. Fld : TField;
  423. begin
  424. TestfieldDefinition(ftBoolean,2,ds,Fld);
  425. for i := 0 to testValuesCount-1 do
  426. begin
  427. AssertEquals(testBooleanValues[i],Fld.AsBoolean);
  428. ds.Next;
  429. end;
  430. ds.close;
  431. end;
  432. procedure TTestDBBasics.TestSupportFloatFields;
  433. var i : byte;
  434. ds : TDataset;
  435. Fld : TField;
  436. begin
  437. TestfieldDefinition(ftFloat,8,ds,Fld);
  438. for i := 0 to testValuesCount-1 do
  439. begin
  440. AssertEquals(testFloatValues[i],Fld.AsFloat);
  441. ds.Next;
  442. end;
  443. ds.close;
  444. end;
  445. procedure TTestDBBasics.TestSupportLargeIntFields;
  446. var i : byte;
  447. ds : TDataset;
  448. Fld : TField;
  449. begin
  450. TestfieldDefinition(ftLargeint,8,ds,Fld);
  451. for i := 0 to testValuesCount-1 do
  452. begin
  453. AssertEquals(testLargeIntValues[i],Fld.AsLargeInt);
  454. ds.Next;
  455. end;
  456. ds.close;
  457. end;
  458. procedure TTestDBBasics.TestSupportDateFields;
  459. var i : byte;
  460. ds : TDataset;
  461. Fld : TField;
  462. begin
  463. TestfieldDefinition(ftDate,8,ds,Fld);
  464. for i := 0 to testValuesCount-1 do
  465. begin
  466. AssertEquals(testDateValues[i],FormatDateTime('yyyy/mm/dd',Fld.AsDateTime));
  467. ds.Next;
  468. end;
  469. ds.close;
  470. end;
  471. procedure TTestDBBasics.TestDoubleClose;
  472. begin
  473. with DBConnector.GetNDataset(1) do
  474. begin
  475. close;
  476. close;
  477. open;
  478. close;
  479. close;
  480. end;
  481. end;
  482. procedure TTestDBBasics.TestAssignFieldftString;
  483. var AParam : TParam;
  484. AField : TField;
  485. begin
  486. AParam := TParam.Create(nil);
  487. with DBConnector.GetNDataset(1) do
  488. begin
  489. open;
  490. AField := fieldbyname('name');
  491. AParam.AssignField(AField);
  492. AssertTrue(ftString=AParam.DataType);
  493. close;
  494. end;
  495. AParam.Free;
  496. end;
  497. procedure TTestDBBasics.TestAssignFieldftFixedChar;
  498. var AParam : TParam;
  499. AField : TField;
  500. begin
  501. AParam := TParam.Create(nil);
  502. with DBConnector.GetNDataset(1) do
  503. begin
  504. open;
  505. AField := fieldbyname('name');
  506. (AField as tstringfield).FixedChar := true;
  507. AParam.AssignField(AField);
  508. AssertTrue(ftFixedChar=AParam.DataType);
  509. close;
  510. end;
  511. AParam.Free;
  512. end;
  513. procedure TTestDBBasics.TestBufDatasetCancelUpdates;
  514. var i : byte;
  515. begin
  516. if not (DBConnector.GetNDataset(5) is TBufDataset) then
  517. Ignore('This test only applies to TBufDataset and descendents.');
  518. with DBConnector.GetNDataset(5) as TBufDataset do
  519. begin
  520. open;
  521. next;
  522. next;
  523. edit;
  524. FieldByName('name').AsString := 'changed';
  525. post;
  526. next;
  527. delete;
  528. CancelUpdates;
  529. First;
  530. for i := 1 to 5 do
  531. begin
  532. AssertEquals(i,fields[0].AsInteger);
  533. AssertEquals('TestName'+inttostr(i),fields[1].AsString);
  534. Next;
  535. end;
  536. end;
  537. end;
  538. procedure TTestDBBasics.Testbug7007;
  539. var
  540. datalink1: tdatalink;
  541. datasource1: tdatasource;
  542. query1: TDataSet;
  543. begin
  544. query1:= DBConnector.GetNDataset(6);
  545. datalink1:= TTestDataLink.create;
  546. datasource1:= tdatasource.create(nil);
  547. try
  548. datalink1.datasource:= datasource1;
  549. datasource1.dataset:= query1;
  550. datalink1.datasource:= datasource1;
  551. DataEvents := '';
  552. query1.open;
  553. datalink1.buffercount:= query1.recordcount;
  554. AssertEquals('deUpdateState:0;',DataEvents);
  555. AssertEquals(0, datalink1.ActiveRecord);
  556. AssertEquals(6, datalink1.RecordCount);
  557. AssertEquals(6, query1.RecordCount);
  558. AssertEquals(1, query1.RecNo);
  559. DataEvents := '';
  560. query1.append;
  561. AssertEquals('deCheckBrowseMode:0;deUpdateState:0;deDataSetChange:0;',DataEvents);
  562. AssertEquals(5, datalink1.ActiveRecord);
  563. AssertEquals(6, datalink1.RecordCount);
  564. AssertEquals(6, query1.RecordCount);
  565. AssertTrue(query1.RecNo in [0,7]);
  566. DataEvents := '';
  567. query1.cancel;
  568. AssertEquals('deCheckBrowseMode:0;deUpdateState:0;deDataSetChange:0;',DataEvents);
  569. AssertEquals(5, datalink1.ActiveRecord);
  570. AssertEquals(6, datalink1.RecordCount);
  571. AssertEquals(6, query1.RecordCount);
  572. AssertEquals(6, query1.RecNo);
  573. finally
  574. datalink1.free;
  575. datasource1.free;
  576. end;
  577. end;
  578. procedure TTestDBBasics.TestBufDatasetCancelUpdates1;
  579. var i : byte;
  580. begin
  581. if not (DBConnector.GetNDataset(5) is TBufDataset) then
  582. Ignore('This test only applies to TBufDataset and descendents.');
  583. with DBConnector.GetNDataset(5) as TBufDataset do
  584. begin
  585. open;
  586. next;
  587. next;
  588. delete;
  589. insert;
  590. FieldByName('id').AsInteger := 100;
  591. post;
  592. CancelUpdates;
  593. last;
  594. for i := 5 downto 1 do
  595. begin
  596. AssertEquals(i,fields[0].AsInteger);
  597. AssertEquals('TestName'+inttostr(i),fields[1].AsString);
  598. Prior;
  599. end;
  600. end;
  601. end;
  602. { TSQLTestSetup }
  603. procedure TDBBasicsTestSetup.OneTimeSetup;
  604. begin
  605. InitialiseDBConnector;
  606. end;
  607. procedure TDBBasicsTestSetup.OneTimeTearDown;
  608. begin
  609. FreeAndNil(DBConnector);
  610. end;
  611. initialization
  612. RegisterTestDecorator(TDBBasicsTestSetup, TTestDBBasics);
  613. end.