database.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  5. Free Pascal development team
  6. TDatabase and related objects implementation
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. { ---------------------------------------------------------------------
  14. TDatabase
  15. ---------------------------------------------------------------------}
  16. Procedure TDatabase.CheckConnected;
  17. begin
  18. If Not Connected Then
  19. DatabaseError(SNotConnected,Self);
  20. end;
  21. Procedure TDatabase.CheckDisConnected;
  22. begin
  23. If Connected Then
  24. DatabaseError(SConnected,Self);
  25. end;
  26. procedure TDataBase.Loaded;
  27. begin
  28. inherited;
  29. if FOpenAfterRead then
  30. SetConnected(true);
  31. end;
  32. procedure TDataBase.SetConnected (Value : boolean);
  33. begin
  34. If Value<>FConnected then
  35. begin
  36. If Value then
  37. begin
  38. if csReading in ComponentState then
  39. begin
  40. FOpenAfterRead := true;
  41. exit;
  42. end
  43. else
  44. // try
  45. DoInternalConnect;
  46. // except
  47. // on e: EDatabaseError do DoInternalDisconnect;
  48. // raise;
  49. // end; {try}
  50. end
  51. else
  52. begin
  53. Closedatasets;
  54. Closetransactions;
  55. DoInternalDisConnect;
  56. if csloading in ComponentState then
  57. FOpenAfterRead := false;
  58. end;
  59. FConnected:=Value;
  60. end;
  61. end;
  62. procedure TDatabase.Notification(AComponent: TComponent; Operation: TOperation);
  63. begin
  64. //!! To be implemented.
  65. end;
  66. constructor TDatabase.Create(AOwner: TComponent);
  67. begin
  68. Inherited Create(AOwner);
  69. FParams:=TStringlist.Create;
  70. FDatasets:=TList.Create;
  71. FTransactions:=TList.Create;
  72. end;
  73. destructor TDatabase.Destroy;
  74. begin
  75. Connected:=False;
  76. RemoveDatasets;
  77. RemoveTransactions;
  78. FDatasets.Free;
  79. FTransactions.Free;
  80. FParams.Free;
  81. Inherited Destroy;
  82. end;
  83. procedure TDatabase.Close;
  84. begin
  85. Connected:=False;
  86. end;
  87. procedure TDatabase.CloseDataSets;
  88. Var I : longint;
  89. begin
  90. If Assigned(FDatasets) then
  91. begin
  92. For I:=FDatasets.Count-1 downto 0 do
  93. TDBDataset(FDatasets[i]).Close;
  94. end;
  95. end;
  96. procedure TDatabase.CloseTransactions;
  97. Var I : longint;
  98. begin
  99. If Assigned(FTransactions) then
  100. begin
  101. For I:=FTransactions.Count-1 downto 0 do
  102. TDBTransaction(FTransactions[i]).EndTransaction;
  103. end;
  104. end;
  105. procedure TDatabase.RemoveDataSets;
  106. Var I : longint;
  107. begin
  108. If Assigned(FDatasets) then
  109. For I:=FDataSets.Count-1 downto 0 do
  110. TDBDataset(FDataSets[i]).Database:=Nil;
  111. end;
  112. procedure TDatabase.RemoveTransactions;
  113. Var I : longint;
  114. begin
  115. If Assigned(FTransactions) then
  116. For I:=FTransactions.Count-1 downto 0 do
  117. TDBTransaction(FTransactions[i]).Database:=Nil;
  118. end;
  119. procedure TDatabase.Open;
  120. begin
  121. Connected:=True;
  122. end;
  123. Function TDatabase.GetDataSetCount : Longint;
  124. begin
  125. If Assigned(FDatasets) Then
  126. Result:=FDatasets.Count
  127. else
  128. Result:=0;
  129. end;
  130. Function TDatabase.GetTransactionCount : Longint;
  131. begin
  132. If Assigned(FTransactions) Then
  133. Result:=FTransactions.Count
  134. else
  135. Result:=0;
  136. end;
  137. Function TDatabase.GetDataset(Index : longint) : TDBDataset;
  138. begin
  139. If Assigned(FDatasets) then
  140. Result:=TDBDataset(FDatasets[Index])
  141. else
  142. DatabaseError(SNoDatasets);
  143. end;
  144. Function TDatabase.GetTransaction(Index : longint) : TDBtransaction;
  145. begin
  146. If Assigned(FTransactions) then
  147. Result:=TDBTransaction(FTransactions[Index])
  148. else
  149. DatabaseError(SNoTransactions);
  150. end;
  151. procedure TDatabase.RegisterDataset (DS : TDBDataset);
  152. Var I : longint;
  153. begin
  154. I:=FDatasets.IndexOf(DS);
  155. If I=-1 then
  156. FDatasets.Add(DS)
  157. else
  158. DatabaseErrorFmt(SDatasetRegistered,[DS.Name]);
  159. end;
  160. procedure TDatabase.RegisterTransaction (TA : TDBTransaction);
  161. Var I : longint;
  162. begin
  163. I:=FTransactions.IndexOf(TA);
  164. If I=-1 then
  165. FTransactions.Add(TA)
  166. else
  167. DatabaseErrorFmt(STransactionRegistered,[TA.Name]);
  168. end;
  169. procedure TDatabase.UnRegisterDataset (DS : TDBDataset);
  170. Var I : longint;
  171. begin
  172. I:=FDatasets.IndexOf(DS);
  173. If I<>-1 then
  174. FDatasets.Delete(I)
  175. else
  176. DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]);
  177. end;
  178. procedure TDatabase.UnRegisterTransaction (TA : TDBTransaction);
  179. Var I : longint;
  180. begin
  181. I:=FTransactions.IndexOf(TA);
  182. If I<>-1 then
  183. FTransactions.Delete(I)
  184. else
  185. DatabaseErrorFmt(SNoTransactionRegistered,[TA.Name]);
  186. end;
  187. { ---------------------------------------------------------------------
  188. TDBdataset
  189. ---------------------------------------------------------------------}
  190. Procedure TDBDataset.SetDatabase (Value : TDatabase);
  191. begin
  192. CheckInactive;
  193. If Value<>FDatabase then
  194. begin
  195. If Assigned(FDatabase) then
  196. FDatabase.UnregisterDataset(Self);
  197. If Value<>Nil Then
  198. Value.RegisterDataset(Self);
  199. FDatabase:=Value;
  200. end;
  201. end;
  202. Procedure TDBDataset.SetTransaction (Value : TDBTransaction);
  203. begin
  204. CheckInactive;
  205. If Value<>FTransaction then
  206. begin
  207. If Assigned(FTransaction) then
  208. FTransaction.UnregisterDataset(Self);
  209. If Value<>Nil Then
  210. Value.RegisterDataset(Self);
  211. FTransaction:=Value;
  212. end;
  213. end;
  214. Procedure TDBDataset.CheckDatabase;
  215. begin
  216. If (FDatabase=Nil) then
  217. DatabaseError(SErrNoDatabaseAvailable,Self)
  218. end;
  219. Destructor TDBDataset.Destroy;
  220. begin
  221. Database:=Nil;
  222. Transaction:=Nil;
  223. Inherited;
  224. end;
  225. { ---------------------------------------------------------------------
  226. TDBTransaction
  227. ---------------------------------------------------------------------}
  228. procedure TDBTransaction.SetActive(Value : boolean);
  229. begin
  230. if FActive and (not Value) then
  231. EndTransaction
  232. else if (not FActive) and Value then
  233. if csLoading in ComponentState then
  234. begin
  235. FOpenAfterRead := true;
  236. exit;
  237. end
  238. else
  239. StartTransaction;
  240. end;
  241. procedure TDBTransaction.Loaded;
  242. begin
  243. inherited;
  244. if FOpenAfterRead then SetActive(true);
  245. end;
  246. Procedure TDBTransaction.CheckActive;
  247. begin
  248. If not FActive Then
  249. DatabaseError(STransNotActive,Self);
  250. end;
  251. Procedure TDBTransaction.CheckInActive;
  252. begin
  253. If FActive Then
  254. DatabaseError(STransActive,Self);
  255. end;
  256. Procedure TDBTransaction.CloseTrans;
  257. begin
  258. FActive := false;
  259. end;
  260. Procedure TDBTransaction.OpenTrans;
  261. begin
  262. FActive := true;
  263. end;
  264. Procedure TDBTransaction.SetDatabase (Value : TDatabase);
  265. begin
  266. CheckInactive;
  267. If Value<>FDatabase then
  268. begin
  269. If Assigned(FDatabase) then
  270. FDatabase.UnregisterTransaction(Self);
  271. If Value<>Nil Then
  272. Value.RegisterTransaction(Self);
  273. FDatabase:=Value;
  274. end;
  275. end;
  276. constructor TDBTransaction.create(AOwner : TComponent);
  277. begin
  278. inherited create(AOwner);
  279. FDatasets:=TList.Create;
  280. end;
  281. Procedure TDBTransaction.CheckDatabase;
  282. begin
  283. If (FDatabase=Nil) then
  284. DatabaseError(SErrNoDatabaseAvailable,Self)
  285. end;
  286. procedure TDBTransaction.CloseDataSets;
  287. Var I : longint;
  288. begin
  289. If Assigned(FDatasets) then
  290. begin
  291. For I:=FDatasets.Count-1 downto 0 do
  292. TDBDataset(FDatasets[i]).Close;
  293. end;
  294. end;
  295. Destructor TDBTransaction.Destroy;
  296. begin
  297. Database:=Nil;
  298. RemoveDatasets;
  299. FDatasets.Free;
  300. Inherited;
  301. end;
  302. procedure TDBTransaction.RemoveDataSets;
  303. Var I : longint;
  304. begin
  305. If Assigned(FDatasets) then
  306. For I:=FDataSets.Count-1 downto 0 do
  307. TDBDataset(FDataSets[i]).Transaction:=Nil;
  308. end;
  309. Function TDBTransaction.GetDataSetCount : Longint;
  310. begin
  311. If Assigned(FDatasets) Then
  312. Result:=FDatasets.Count
  313. else
  314. Result:=0;
  315. end;
  316. procedure TDBTransaction.UnRegisterDataset (DS : TDBDataset);
  317. Var I : longint;
  318. begin
  319. I:=FDatasets.IndexOf(DS);
  320. If I<>-1 then
  321. FDatasets.Delete(I)
  322. else
  323. DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]);
  324. end;
  325. procedure TDBTransaction.RegisterDataset (DS : TDBDataset);
  326. Var I : longint;
  327. begin
  328. I:=FDatasets.IndexOf(DS);
  329. If I=-1 then
  330. FDatasets.Add(DS)
  331. else
  332. DatabaseErrorFmt(SDatasetRegistered,[DS.Name]);
  333. end;
  334. Function TDBTransaction.GetDataset(Index : longint) : TDBDataset;
  335. begin
  336. If Assigned(FDatasets) then
  337. Result:=TDBDataset(FDatasets[Index])
  338. else
  339. DatabaseError(SNoDatasets);
  340. end;
  341. {
  342. $Log$
  343. Revision 1.9 2004-12-05 00:05:38 michael
  344. patch to enable RecNo and DisplayFormat
  345. Revision 1.8 2004/11/05 08:32:02 michael
  346. TBufDataset.inc:
  347. - replaced Freemem by Reallocmem, Free by FreeAndNil
  348. Database.inc:
  349. - Moved Active property from TSQLTransaction to TDBTransaction
  350. - Gives an error if the database of an active transaction is changed
  351. Dataset.inc
  352. - Don't distribute events if FDisableControlsCount > 0
  353. - Replaced FActive by FState<>dsInactive
  354. - Set EOF after append
  355. db.pp:
  356. - Removed duplicate definition of TAlignment
  357. - Moved Active property from TSQLTransaction to TDBTransaction
  358. - Replaced FActive by FState<>dsInactive
  359. - Gives an error if the database of an active transaction is changed
  360. sqldb:
  361. - Moved Active property from TSQLTransaction to TDBTransaction
  362. - replaced Freemem by Reallocmem, Free by FreeAndNil
  363. IBConnection:
  364. - Moved FSQLDAAllocated to the cursor
  365. PQConnection:
  366. - Don't try to free the statement if a fatal error occured
  367. Revision 1.7 2004/10/27 07:23:13 michael
  368. + Patch from Joost Van der Sluis to fix transactions
  369. Revision 1.6 2004/09/26 16:55:24 michael
  370. * big patch from Joost van der Sluis
  371. bufdataset.inc:
  372. fix getrecord (prior)
  373. getcanmodify default false
  374. database.inc / db.inc:
  375. Added transactions
  376. dataset.inc:
  377. raise error if trying to insert into an readonly dataset
  378. db.inc:
  379. remove published properties from bufdataset
  380. changed ancestor of tbufdataset to tdbdataset
  381. Revision 1.5 2004/07/25 11:32:40 michael
  382. * Patches from Joost van der Sluis
  383. interbase.pp:
  384. * Removed unused Fprepared
  385. * Changed the error message 'database connect string not filled
  386. in' to 'database connect string (databasename) not filled in'
  387. * Preparestatement and execute now checks if transaction is
  388. assigned (in stead of crashing if it isn't) and if the
  389. transaction isn't started, it calls starttransaction.
  390. dataset.inc:
  391. * In DoInternalOpen the buffers are now initialised before the
  392. dataset is set into browse-state
  393. database.inc and db.pp:
  394. * If the dataset is created from a stream, the database is opened
  395. after the dataset is read completely
  396. Revision 1.4 2003/08/16 16:42:21 michael
  397. + Fixes in TDBDataset etc. Changed MySQLDb to use database as well
  398. Revision 1.3 2002/09/07 15:15:22 peter
  399. * old logs removed and tabs fixed
  400. }