database.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
  4. Free Pascal development team
  5. TDatabase and related objects implementation
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { ---------------------------------------------------------------------
  13. TDatabase
  14. ---------------------------------------------------------------------}
  15. Procedure TDatabase.CheckConnected;
  16. begin
  17. If Not Connected Then
  18. DatabaseError(SNotConnected,Self);
  19. end;
  20. Procedure TDatabase.CheckDisConnected;
  21. begin
  22. If Connected Then
  23. DatabaseError(SConnected,Self);
  24. end;
  25. procedure TDatabase.DoConnect;
  26. begin
  27. DoInternalConnect;
  28. FConnected := True;
  29. end;
  30. procedure TDatabase.DoDisconnect;
  31. begin
  32. Closedatasets;
  33. Closetransactions;
  34. DoInternalDisConnect;
  35. if csloading in ComponentState then
  36. FOpenAfterRead := false;
  37. FConnected := False;
  38. end;
  39. function TDatabase.GetConnected: boolean;
  40. begin
  41. Result:= FConnected;
  42. end;
  43. constructor TDatabase.Create(AOwner: TComponent);
  44. begin
  45. Inherited Create(AOwner);
  46. FParams:=TStringlist.Create;
  47. FDatasets:=TList.Create;
  48. FTransactions:=TList.Create;
  49. end;
  50. destructor TDatabase.Destroy;
  51. begin
  52. Connected:=False;
  53. RemoveDatasets;
  54. RemoveTransactions;
  55. FDatasets.Free;
  56. FTransactions.Free;
  57. FParams.Free;
  58. Inherited Destroy;
  59. end;
  60. procedure TDatabase.CloseDataSets;
  61. Var I : longint;
  62. begin
  63. If Assigned(FDatasets) then
  64. begin
  65. For I:=FDatasets.Count-1 downto 0 do
  66. TDataset(FDatasets[i]).Close;
  67. end;
  68. end;
  69. procedure TDatabase.CloseTransactions;
  70. Var I : longint;
  71. begin
  72. If Assigned(FTransactions) then
  73. begin
  74. For I:=FTransactions.Count-1 downto 0 do
  75. TDBTransaction(FTransactions[i]).EndTransaction;
  76. end;
  77. end;
  78. procedure TDatabase.RemoveDataSets;
  79. Var I : longint;
  80. begin
  81. If Assigned(FDatasets) then
  82. For I:=FDataSets.Count-1 downto 0 do
  83. TDBDataset(FDataSets[i]).Database:=Nil;
  84. end;
  85. procedure TDatabase.RemoveTransactions;
  86. Var I : longint;
  87. begin
  88. If Assigned(FTransactions) then
  89. For I:=FTransactions.Count-1 downto 0 do
  90. TDBTransaction(FTransactions[i]).Database:=Nil;
  91. end;
  92. Function TDatabase.GetDataSetCount : Longint;
  93. begin
  94. If Assigned(FDatasets) Then
  95. Result:=FDatasets.Count
  96. else
  97. Result:=0;
  98. end;
  99. Function TDatabase.GetTransactionCount : Longint;
  100. begin
  101. If Assigned(FTransactions) Then
  102. Result:=FTransactions.Count
  103. else
  104. Result:=0;
  105. end;
  106. Function TDatabase.GetDataset(Index : longint) : TDataset;
  107. begin
  108. If Assigned(FDatasets) then
  109. Result:=TDataset(FDatasets[Index])
  110. else
  111. begin
  112. result := nil;
  113. DatabaseError(SNoDatasets);
  114. end;
  115. end;
  116. Function TDatabase.GetTransaction(Index : longint) : TDBtransaction;
  117. begin
  118. If Assigned(FTransactions) then
  119. Result:=TDBTransaction(FTransactions[Index])
  120. else
  121. begin
  122. result := nil;
  123. DatabaseError(SNoTransactions);
  124. end;
  125. end;
  126. procedure TDatabase.RegisterDataset (DS : TDBDataset);
  127. Var I : longint;
  128. begin
  129. I:=FDatasets.IndexOf(DS);
  130. If I=-1 then
  131. FDatasets.Add(DS)
  132. else
  133. DatabaseErrorFmt(SDatasetRegistered,[DS.Name]);
  134. end;
  135. procedure TDatabase.RegisterTransaction (TA : TDBTransaction);
  136. Var I : longint;
  137. begin
  138. I:=FTransactions.IndexOf(TA);
  139. If I=-1 then
  140. FTransactions.Add(TA)
  141. else
  142. DatabaseErrorFmt(STransactionRegistered,[TA.Name]);
  143. end;
  144. procedure TDatabase.UnRegisterDataset (DS : TDBDataset);
  145. Var I : longint;
  146. begin
  147. I:=FDatasets.IndexOf(DS);
  148. If I<>-1 then
  149. FDatasets.Delete(I)
  150. else
  151. DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]);
  152. end;
  153. procedure TDatabase.UnRegisterTransaction (TA : TDBTransaction);
  154. Var I : longint;
  155. begin
  156. I:=FTransactions.IndexOf(TA);
  157. If I<>-1 then
  158. FTransactions.Delete(I)
  159. else
  160. DatabaseErrorFmt(SNoTransactionRegistered,[TA.Name]);
  161. end;
  162. { ---------------------------------------------------------------------
  163. TDBdataset
  164. ---------------------------------------------------------------------}
  165. Procedure TDBDataset.SetDatabase (Value : TDatabase);
  166. begin
  167. If Value<>FDatabase then
  168. begin
  169. CheckInactive;
  170. If Assigned(FDatabase) then
  171. FDatabase.UnregisterDataset(Self);
  172. If Value<>Nil Then
  173. Value.RegisterDataset(Self);
  174. FDatabase:=Value;
  175. end;
  176. end;
  177. Procedure TDBDataset.SetTransaction (Value : TDBTransaction);
  178. begin
  179. CheckInactive;
  180. If Value<>FTransaction then
  181. begin
  182. If Assigned(FTransaction) then
  183. FTransaction.UnregisterDataset(Self);
  184. If Value<>Nil Then
  185. Value.RegisterDataset(Self);
  186. FTransaction:=Value;
  187. end;
  188. end;
  189. Procedure TDBDataset.CheckDatabase;
  190. begin
  191. If (FDatabase=Nil) then
  192. DatabaseError(SErrNoDatabaseAvailable,Self)
  193. end;
  194. Destructor TDBDataset.Destroy;
  195. begin
  196. Database:=Nil;
  197. Transaction:=Nil;
  198. Inherited;
  199. end;
  200. { ---------------------------------------------------------------------
  201. TDBTransaction
  202. ---------------------------------------------------------------------}
  203. procedure TDBTransaction.SetActive(Value : boolean);
  204. begin
  205. if FActive and (not Value) then
  206. EndTransaction
  207. else if (not FActive) and Value then
  208. if csLoading in ComponentState then
  209. begin
  210. FOpenAfterRead := true;
  211. exit;
  212. end
  213. else
  214. StartTransaction;
  215. end;
  216. procedure TDBTransaction.Loaded;
  217. begin
  218. inherited;
  219. try
  220. if FOpenAfterRead then SetActive(true);
  221. except
  222. if csDesigning in Componentstate then
  223. InternalHandleException
  224. else
  225. raise;
  226. end;
  227. end;
  228. Procedure TDBTransaction.InternalHandleException;
  229. begin
  230. if assigned(classes.ApplicationHandleException) then
  231. classes.ApplicationHandleException(self)
  232. else
  233. ShowException(ExceptObject,ExceptAddr);
  234. end;
  235. Procedure TDBTransaction.CheckActive;
  236. begin
  237. If not FActive Then
  238. DatabaseError(STransNotActive,Self);
  239. end;
  240. Procedure TDBTransaction.CheckInActive;
  241. begin
  242. If FActive Then
  243. DatabaseError(STransActive,Self);
  244. end;
  245. Procedure TDBTransaction.CloseTrans;
  246. begin
  247. FActive := false;
  248. end;
  249. Procedure TDBTransaction.OpenTrans;
  250. begin
  251. FActive := true;
  252. end;
  253. Procedure TDBTransaction.SetDatabase (Value : TDatabase);
  254. begin
  255. If Value<>FDatabase then
  256. begin
  257. CheckInactive;
  258. If Assigned(FDatabase) then
  259. FDatabase.UnregisterTransaction(Self);
  260. If Value<>Nil Then
  261. Value.RegisterTransaction(Self);
  262. FDatabase:=Value;
  263. end;
  264. end;
  265. constructor TDBTransaction.create(AOwner : TComponent);
  266. begin
  267. inherited create(AOwner);
  268. FDatasets:=TList.Create;
  269. end;
  270. Procedure TDBTransaction.CheckDatabase;
  271. begin
  272. If (FDatabase=Nil) then
  273. DatabaseError(SErrNoDatabaseAvailable,Self)
  274. end;
  275. procedure TDBTransaction.CloseDataSets;
  276. Var I : longint;
  277. begin
  278. If Assigned(FDatasets) then
  279. begin
  280. For I:=FDatasets.Count-1 downto 0 do
  281. TDBDataset(FDatasets[i]).Close;
  282. end;
  283. end;
  284. Destructor TDBTransaction.Destroy;
  285. begin
  286. Database:=Nil;
  287. RemoveDatasets;
  288. FDatasets.Free;
  289. Inherited;
  290. end;
  291. procedure TDBTransaction.RemoveDataSets;
  292. Var I : longint;
  293. begin
  294. If Assigned(FDatasets) then
  295. For I:=FDataSets.Count-1 downto 0 do
  296. TDBDataset(FDataSets[i]).Transaction:=Nil;
  297. end;
  298. Function TDBTransaction.GetDataSetCount : Longint;
  299. begin
  300. If Assigned(FDatasets) Then
  301. Result:=FDatasets.Count
  302. else
  303. Result:=0;
  304. end;
  305. procedure TDBTransaction.UnRegisterDataset (DS : TDBDataset);
  306. Var I : longint;
  307. begin
  308. I:=FDatasets.IndexOf(DS);
  309. If I<>-1 then
  310. FDatasets.Delete(I)
  311. else
  312. DatabaseErrorFmt(SNoDatasetRegistered,[DS.Name]);
  313. end;
  314. procedure TDBTransaction.RegisterDataset (DS : TDBDataset);
  315. Var I : longint;
  316. begin
  317. I:=FDatasets.IndexOf(DS);
  318. If I=-1 then
  319. FDatasets.Add(DS)
  320. else
  321. DatabaseErrorFmt(SDatasetRegistered,[DS.Name]);
  322. end;
  323. Function TDBTransaction.GetDataset(Index : longint) : TDBDataset;
  324. begin
  325. If Assigned(FDatasets) then
  326. Result:=TDBDataset(FDatasets[Index])
  327. else
  328. begin
  329. result := nil;
  330. DatabaseError(SNoDatasets);
  331. end;
  332. end;
  333. { ---------------------------------------------------------------------
  334. TCustomConnection
  335. ---------------------------------------------------------------------}
  336. procedure TCustomConnection.SetAfterConnect(const AValue: TNotifyEvent);
  337. begin
  338. if FAfterConnect=AValue then exit;
  339. FAfterConnect:=AValue;
  340. end;
  341. function TCustomConnection.GetDataSet(Index: Longint): TDataSet;
  342. begin
  343. Result := nil;
  344. end;
  345. function TCustomConnection.GetDataSetCount: Longint;
  346. begin
  347. Result := 0;
  348. end;
  349. procedure TCustomConnection.InternalHandleException;
  350. begin
  351. if assigned(classes.ApplicationHandleException) then
  352. classes.ApplicationHandleException(self)
  353. else
  354. ShowException(ExceptObject,ExceptAddr);
  355. end;
  356. procedure TCustomConnection.SetAfterDisconnect(const AValue: TNotifyEvent);
  357. begin
  358. if FAfterDisconnect=AValue then exit;
  359. FAfterDisconnect:=AValue;
  360. end;
  361. procedure TCustomConnection.SetBeforeConnect(const AValue: TNotifyEvent);
  362. begin
  363. if FBeforeConnect=AValue then exit;
  364. FBeforeConnect:=AValue;
  365. end;
  366. procedure TCustomConnection.SetConnected(Value: boolean);
  367. begin
  368. If Value<>Connected then
  369. begin
  370. If Value then
  371. begin
  372. if csReading in ComponentState then
  373. begin
  374. FStreamedConnected := true;
  375. exit;
  376. end
  377. else
  378. begin
  379. if Assigned(BeforeConnect) then
  380. BeforeConnect(self);
  381. if FLoginPrompt then if assigned(FOnLogin) then
  382. FOnLogin(self,'','');
  383. DoConnect;
  384. if Assigned(AfterConnect) then
  385. AfterConnect(self);
  386. end;
  387. end
  388. else
  389. begin
  390. if Assigned(BeforeDisconnect) then
  391. BeforeDisconnect(self);
  392. DoDisconnect;
  393. if Assigned(AfterDisconnect) then
  394. AfterDisconnect(self);
  395. end;
  396. end;
  397. end;
  398. procedure TCustomConnection.SetBeforeDisconnect(const AValue: TNotifyEvent);
  399. begin
  400. if FBeforeDisconnect=AValue then exit;
  401. FBeforeDisconnect:=AValue;
  402. end;
  403. procedure TCustomConnection.DoConnect;
  404. begin
  405. // Do nothing yet
  406. end;
  407. procedure TCustomConnection.DoDisconnect;
  408. begin
  409. // Do nothing yet
  410. end;
  411. function TCustomConnection.GetConnected: boolean;
  412. begin
  413. Result := False;
  414. end;
  415. procedure TCustomConnection.Loaded;
  416. begin
  417. inherited Loaded;
  418. try
  419. if FStreamedConnected then
  420. SetConnected(true);
  421. except
  422. if csDesigning in Componentstate then
  423. InternalHandleException
  424. else
  425. raise;
  426. end;
  427. end;
  428. procedure TCustomConnection.Close;
  429. begin
  430. Connected := False;
  431. end;
  432. destructor TCustomConnection.Destroy;
  433. begin
  434. Connected:=False;
  435. Inherited Destroy;
  436. end;
  437. procedure TCustomConnection.Open;
  438. begin
  439. Connected := True;
  440. end;