mysql4conn.pas 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. unit mysql4conn;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,sqldb,mysql4,mysql4_com,db;
  6. Type
  7. TMySQLTransaction = Class(TSQLHandle)
  8. protected
  9. end;
  10. TMySQLCursor = Class(TSQLHandle)
  11. protected
  12. FRes: PMYSQL_RES; { Record pointer }
  13. FNeedData : Boolean;
  14. FStatement : String;
  15. Row : TMYSQL_ROW;
  16. RowsAffected : Int64;
  17. LastInsertID : Int64;
  18. end;
  19. TMySQLConnection = class (TSQLConnection)
  20. private
  21. FDialect: integer;
  22. FHostInfo: String;
  23. FServerInfo: String;
  24. FMySQL : PMySQL;
  25. function GetClientInfo: string;
  26. function GetServerStatus: String;
  27. protected
  28. Procedure ConnectToServer; virtual;
  29. Procedure SelectDatabase; virtual;
  30. function MySQLDataSize(AType: enum_field_types; ASize: Integer): Integer;
  31. function MySQLDataType(AType: enum_field_types; ASize: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean;
  32. function MySQLWriteData(AType: enum_field_types; ASize: Integer; Source, Dest: PChar): Integer;
  33. // SQLConnection methods
  34. procedure DoInternalConnect; override;
  35. procedure DoInternalDisconnect; override;
  36. function GetHandle : pointer; override;
  37. Function AllocateCursorHandle : TSQLHandle; override;
  38. Function AllocateTransactionHandle : TSQLHandle; override;
  39. procedure FreeStatement(cursor : TSQLHandle); override;
  40. procedure PrepareStatement(cursor: TSQLHandle;ATransaction : TSQLTransaction;buf : string); override;
  41. procedure FreeFldBuffers(cursor : TSQLHandle); override;
  42. procedure Execute(cursor: TSQLHandle;atransaction:tSQLtransaction); override;
  43. procedure AddFieldDefs(cursor: TSQLHandle; FieldDefs : TfieldDefs); override;
  44. function GetFieldSizes(cursor : TSQLHandle) : integer; override;
  45. function Fetch(cursor : TSQLHandle) : boolean; override;
  46. procedure LoadFieldsFromBuffer(cursor : TSQLHandle;buffer: pchar); override;
  47. function GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean; override;
  48. function GetTransactionHandle(trans : TSQLHandle): pointer; override;
  49. function Commit(trans : TSQLHandle) : boolean; override;
  50. function RollBack(trans : TSQLHandle) : boolean; override;
  51. function StartdbTransaction(trans : TSQLHandle) : boolean; override;
  52. procedure CommitRetaining(trans : TSQLHandle); override;
  53. procedure RollBackRetaining(trans : TSQLHandle); override;
  54. Public
  55. Property ServerInfo : String Read FServerInfo;
  56. Property HostInfo : String Read FHostInfo;
  57. property ClientInfo: string read GetClientInfo;
  58. property ServerStatus : String read GetServerStatus;
  59. published
  60. property Dialect : integer read FDialect write FDialect;
  61. property DatabaseName;
  62. property HostName;
  63. property KeepConnection;
  64. property LoginPrompt;
  65. property Params;
  66. property OnLogin;
  67. end;
  68. EMySQLError = Class(Exception);
  69. implementation
  70. { TMySQLConnection }
  71. Resourcestring
  72. SErrServerConnectFailed = 'Server connect failed.';
  73. SErrDatabaseSelectFailed = 'failed to select database: %s';
  74. SErrDatabaseCreate = 'Failed to create database: %s';
  75. SErrDatabaseDrop = 'Failed to drop database: %s';
  76. SErrNoData = 'No data for record';
  77. SErrExecuting = 'Error executing query: %s';
  78. SErrFetchingdata = 'Error fetching row data: %s';
  79. SErrGettingResult = 'Error getting result set: %s';
  80. SErrNoQueryResult = 'No result from query.';
  81. Procedure MySQlError(R : PMySQL;Msg: String;Comp : TComponent);
  82. Var
  83. MySQLMsg : String;
  84. begin
  85. If (R<>Nil) then
  86. begin
  87. MySQLMsg:=Strpas(mysql_error(R));
  88. DatabaseErrorFmt(Msg,[MySQLMsg],Comp);
  89. end
  90. else
  91. DatabaseError(Msg,Comp);
  92. end;
  93. function TMySQLConnection.GetClientInfo: string;
  94. begin
  95. CheckConnected;
  96. Result:=strpas(mysql_get_client_info);
  97. end;
  98. function TMySQLConnection.GetServerStatus: String;
  99. begin
  100. CheckConnected;
  101. Result := mysql_stat(FMYSQL);
  102. end;
  103. procedure TMySQLConnection.ConnectToServer;
  104. Var
  105. H,U,P : String;
  106. begin
  107. H:=HostName;
  108. U:=UserName;
  109. P:=Password;
  110. if (FMySQL=Nil) then
  111. New(FMySQL);
  112. mysql_init(FMySQL);
  113. FMySQL:=mysql_real_connect(FMySQL,PChar(H),PChar(U),Pchar(P),Nil,0,Nil,0);
  114. If (FMySQL=Nil) then
  115. MySQlError(Nil,SErrServerConnectFailed,Self);
  116. FServerInfo := strpas(mysql_get_server_info(FMYSQL));
  117. FHostInfo := strpas(mysql_get_host_info(FMYSQL));
  118. end;
  119. procedure TMySQLConnection.SelectDatabase;
  120. begin
  121. if mysql_select_db(FMySQL,pchar(DatabaseName))<>0 then
  122. MySQLError(FMySQL,SErrDatabaseSelectFailed,Self);
  123. end;
  124. procedure TMySQLConnection.DoInternalConnect;
  125. begin
  126. inherited DoInternalConnect;
  127. ConnectToServer;
  128. SelectDatabase;
  129. end;
  130. procedure TMySQLConnection.DoInternalDisconnect;
  131. begin
  132. inherited DoInternalDisconnect;
  133. mysql_close(FMySQL);
  134. FMySQL:=Nil;
  135. end;
  136. function TMySQLConnection.GetHandle: pointer;
  137. begin
  138. Result:=FMySQL;
  139. end;
  140. function TMySQLConnection.AllocateCursorHandle: TSQLHandle;
  141. begin
  142. Result:=TMySQLCursor.Create;
  143. end;
  144. function TMySQLConnection.AllocateTransactionHandle: TSQLHandle;
  145. begin
  146. Result:=TMySQLTransaction.Create;
  147. end;
  148. procedure TMySQLConnection.FreeStatement(cursor: TSQLHandle);
  149. Var
  150. C : TMySQLCursor;
  151. begin
  152. C:=Cursor as TMysqlCursor;
  153. if c.StatementType=stSelect then
  154. c.FNeedData:=False;
  155. If (C.FRes<>Nil) then
  156. begin
  157. C.FRes:=Nil;
  158. end;
  159. end;
  160. procedure TMySQLConnection.PrepareStatement(cursor: TSQLHandle;
  161. ATransaction: TSQLTransaction; buf: string);
  162. begin
  163. With Cursor as TMysqlCursor do
  164. begin
  165. FStatement:=Buf;
  166. if StatementType=stSelect then
  167. FNeedData:=True;
  168. end
  169. end;
  170. procedure TMySQLConnection.FreeFldBuffers(cursor: TSQLHandle);
  171. Var
  172. C : TMySQLCursor;
  173. begin
  174. C:=Cursor as TMysqlCursor;
  175. If (C.FRes<>Nil) then
  176. begin
  177. Mysql_free_result(C.FRes);
  178. C.FRes:=Nil;
  179. end;
  180. end;
  181. procedure TMySQLConnection.Execute(cursor: TSQLHandle;
  182. atransaction: tSQLtransaction);
  183. Var
  184. C : TMySQLCursor;
  185. begin
  186. C:=Cursor as TMysqlCursor;
  187. If (C.FRes=Nil) then
  188. begin
  189. if mysql_query(FMySQL,Pchar(C.FStatement))<>0 then
  190. MySQLError(FMYSQL,Format(SErrExecuting,[StrPas(mysql_error(FMySQL))]),Self)
  191. else
  192. begin
  193. C.RowsAffected := mysql_affected_rows(FMYSQL);
  194. C.LastInsertID := mysql_insert_id(FMYSQL);
  195. if C.FNeedData then
  196. C.FRes:=mysql_use_result(FMySQL);
  197. end;
  198. end;
  199. end;
  200. function TMySQLConnection.MySQLDataSize(AType: enum_field_types; ASize: Integer): Integer;
  201. begin
  202. Result := 0;
  203. case AType of
  204. FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG,
  205. FIELD_TYPE_INT24:
  206. begin
  207. Result := SizeOf(Integer);
  208. end;
  209. FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
  210. begin
  211. Result := SizeOf(Double);
  212. end;
  213. FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATE, FIELD_TYPE_TIME, FIELD_TYPE_DATETIME:
  214. begin
  215. Result := SizeOf(TDateTime);
  216. end;
  217. FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET:
  218. begin
  219. Result := ASize;
  220. end;
  221. end;
  222. end;
  223. function TMySQLConnection.MySQLDataType(AType: enum_field_types; ASize: Integer;
  224. var NewType: TFieldType; var NewSize: Integer): Boolean;
  225. begin
  226. Result := True;
  227. case AType of
  228. FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG,
  229. FIELD_TYPE_INT24:
  230. begin
  231. NewType := ftInteger;
  232. NewSize := 0;
  233. end;
  234. FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
  235. begin
  236. NewType := ftFloat;
  237. NewSize := 0;
  238. end;
  239. FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATETIME:
  240. begin
  241. NewType := ftDateTime;
  242. NewSize := 0;
  243. end;
  244. FIELD_TYPE_DATE:
  245. begin
  246. NewType := ftDate;
  247. NewSize := 0;
  248. end;
  249. FIELD_TYPE_TIME:
  250. begin
  251. NewType := ftTime;
  252. NewSize := 0;
  253. end;
  254. FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET:
  255. begin
  256. NewType := ftString;
  257. NewSize := ASize;
  258. end;
  259. else
  260. Result := False;
  261. end;
  262. end;
  263. procedure TMySQLConnection.AddFieldDefs(cursor: TSQLHandle;
  264. FieldDefs: TfieldDefs);
  265. var
  266. C : TMySQLCursor;
  267. I, FC: Integer;
  268. field: PMYSQL_FIELD;
  269. DFT: TFieldType;
  270. DFS: Integer;
  271. WasClosed: Boolean;
  272. begin
  273. // Writeln('MySQL: Adding fielddefs');
  274. C:=(Cursor as TMySQLCursor);
  275. If (C.FRes=Nil) then
  276. begin
  277. // Writeln('res is nil');
  278. MySQLError(FMySQL,SErrNoQueryResult,Self);
  279. end;
  280. // Writeln('MySQL: have result');
  281. FC:=mysql_num_fields(C.FRes);
  282. For I:= 0 to FC-1 do
  283. begin
  284. field := mysql_fetch_field_direct(C.FRES, I);
  285. // Writeln('MySQL: creating fielddef ',I+1);
  286. if MySQLDataType(field^.ftype, field^.length, DFT, DFS) then
  287. TFieldDef.Create(FieldDefs, field^.name, DFT, DFS, False, I+1);
  288. end;
  289. // Writeln('MySQL: Finished adding fielddefs');
  290. end;
  291. function TMySQLConnection.GetFieldSizes(cursor: TSQLHandle): integer;
  292. var
  293. I, FC: Integer;
  294. field: PMYSQL_FIELD;
  295. C : TMySQLCursor;
  296. begin
  297. // Writeln('GetFieldSizes');
  298. C:=Cursor as TMySQLCursor;
  299. Result:=0;
  300. FC:=mysql_num_fields(C.FRES);
  301. for I:=0 to FC-1 do
  302. begin
  303. field := mysql_fetch_field_direct(C.FRES, I);
  304. Result:=Result+MySQLDataSize(field^.ftype, field^.length);
  305. end;
  306. // Writeln('GetFieldSizes result :',Result);
  307. end;
  308. function TMySQLConnection.Fetch(cursor: TSQLHandle): boolean;
  309. Var
  310. C : TMySQLCursor;
  311. begin
  312. C:=Cursor as TMySQLCursor;
  313. C.Row:=MySQL_Fetch_row(C.FRes);
  314. Result:=(C.Row<>Nil);
  315. end;
  316. procedure TMySQLConnection.LoadFieldsFromBuffer(cursor: TSQLHandle;
  317. buffer: pchar);
  318. var
  319. I, FC, CT: Integer;
  320. field: PMYSQL_FIELD;
  321. row : TMYSQL_ROW;
  322. C : TMySQLCursor;
  323. begin
  324. // Writeln('LoadFieldsFromBuffer');
  325. C:=Cursor as TMySQLCursor;
  326. if C.Row=nil then
  327. begin
  328. // Writeln('LoadFieldsFromBuffer: row=nil');
  329. MySQLError(FMySQL,SErrFetchingData,Self);
  330. end;
  331. Row:=C.Row;
  332. FC := mysql_num_fields(C.FRES);
  333. for I := 0 to FC-1 do
  334. begin
  335. field := mysql_fetch_field_direct(C.FRES, I);
  336. CT := MySQLWriteData(field^.ftype, field^.length, Row^, Buffer);
  337. Inc(Buffer, CT);
  338. Inc(Row);
  339. end;
  340. end;
  341. function InternalStrToFloat(S: string): Extended;
  342. var
  343. I: Integer;
  344. Tmp: string;
  345. begin
  346. Tmp := '';
  347. for I := 1 to Length(S) do
  348. begin
  349. if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then
  350. Tmp := Tmp + DecimalSeparator
  351. else
  352. Tmp := Tmp + S[I];
  353. end;
  354. Result := StrToFloat(Tmp);
  355. end;
  356. function InternalStrToDate(S: string): TDateTime;
  357. var
  358. EY, EM, ED: Word;
  359. begin
  360. EY := StrToInt(Copy(S,1,4));
  361. EM := StrToInt(Copy(S,6,2));
  362. ED := StrToInt(Copy(S,9,2));
  363. if (EY = 0) or (EM = 0) or (ED = 0) then
  364. Result:=0
  365. else
  366. Result:=EncodeDate(EY, EM, ED);
  367. end;
  368. function InternalStrToDateTime(S: string): TDateTime;
  369. var
  370. EY, EM, ED: Word;
  371. EH, EN, ES: Word;
  372. begin
  373. EY := StrToInt(Copy(S, 1, 4));
  374. EM := StrToInt(Copy(S, 6, 2));
  375. ED := StrToInt(Copy(S, 9, 2));
  376. EH := StrToInt(Copy(S, 11, 2));
  377. EN := StrToInt(Copy(S, 14, 2));
  378. ES := StrToInt(Copy(S, 17, 2));
  379. if (EY = 0) or (EM = 0) or (ED = 0) then
  380. Result := 0
  381. else
  382. Result := EncodeDate(EY, EM, ED);
  383. Result := Result + EncodeTime(EH, EN, ES, 0);
  384. end;
  385. function InternalStrToTime(S: string): TDateTime;
  386. var
  387. EH, EM, ES: Word;
  388. begin
  389. EH := StrToInt(Copy(S, 1, 2));
  390. EM := StrToInt(Copy(S, 4, 2));
  391. ES := StrToInt(Copy(S, 7, 2));
  392. Result := EncodeTime(EH, EM, ES, 0);
  393. end;
  394. function InternalStrToTimeStamp(S: string): TDateTime;
  395. var
  396. EY, EM, ED: Word;
  397. EH, EN, ES: Word;
  398. begin
  399. EY := StrToInt(Copy(S, 1, 4));
  400. EM := StrToInt(Copy(S, 5, 2));
  401. ED := StrToInt(Copy(S, 7, 2));
  402. EH := StrToInt(Copy(S, 9, 2));
  403. EN := StrToInt(Copy(S, 11, 2));
  404. ES := StrToInt(Copy(S, 13, 2));
  405. if (EY = 0) or (EM = 0) or (ED = 0) then
  406. Result := 0
  407. else
  408. Result := EncodeDate(EY, EM, ED);
  409. Result := Result + EncodeTime(EH, EN, ES, 0);;
  410. end;
  411. function TMySQLConnection.MySQLWriteData(AType: enum_field_types;ASize: Integer; Source, Dest: PChar): Integer;
  412. var
  413. VI: Integer;
  414. VF: Double;
  415. VD: TDateTime;
  416. Src : String;
  417. begin
  418. Result := 0;
  419. If (Source<>Nil) Then
  420. Src:=StrPas(Source)
  421. else
  422. Src:='';
  423. case AType of
  424. FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG,
  425. FIELD_TYPE_INT24:
  426. begin
  427. Result:=SizeOf(Integer);
  428. if (Src<>'') then
  429. VI := StrToInt(Src)
  430. else
  431. VI := 0;
  432. Move(VI, Dest^, Result);
  433. end;
  434. FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
  435. begin
  436. Result := SizeOf(Double);
  437. if Src <> '' then
  438. VF := InternalStrToFloat(Src)
  439. else
  440. VF := 0;
  441. Move(VF, Dest^, Result);
  442. end;
  443. FIELD_TYPE_TIMESTAMP:
  444. begin
  445. Result := SizeOf(TDateTime);
  446. if Src <> '' then
  447. VD := InternalStrToTimeStamp(Src)
  448. else
  449. VD := 0;
  450. Move(VD, Dest^, Result);
  451. end;
  452. FIELD_TYPE_DATETIME:
  453. begin
  454. Result := SizeOf(TDateTime);
  455. if Src <> '' then
  456. VD := InternalStrToDateTime(Src)
  457. else
  458. VD := 0;
  459. Move(VD, Dest^, Result);
  460. end;
  461. FIELD_TYPE_DATE:
  462. begin
  463. Result := SizeOf(TDateTime);
  464. if Src <> '' then
  465. VD := InternalStrToDate(Src)
  466. else
  467. VD := 0;
  468. Move(VD, Dest^, Result);
  469. end;
  470. FIELD_TYPE_TIME:
  471. begin
  472. Result := SizeOf(TDateTime);
  473. if Src <> '' then
  474. VD := InternalStrToTime(Src)
  475. else
  476. VD := 0;
  477. Move(VD, Dest^, Result);
  478. end;
  479. FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET:
  480. begin
  481. Result := ASize;
  482. { Write('Moving string of size ',asize,' : ');
  483. P:=Source;
  484. If (P<>nil) then
  485. While P[0]<>#0 do
  486. begin
  487. Write(p[0]);
  488. inc(p);
  489. end;
  490. Writeln;
  491. } if Src<> '' then
  492. Move(Source^, Dest^, Result)
  493. else
  494. Dest^ := #0;
  495. end;
  496. end;
  497. end;
  498. function TMySQLConnection.GetFieldData(Cursor : TSQLHandle;Field: TField; FieldDefs : TfieldDefs; Buffer: Pointer;currbuff : pchar): Boolean;
  499. var
  500. I, FC: Integer;
  501. fld: PMYSQL_FIELD;
  502. C : TMySQLCursor;
  503. begin
  504. Result := False;
  505. C:=Cursor as TMySQLCursor;
  506. FC:= mysql_num_fields(C.FRES);
  507. I:=0;
  508. While (I<FC) and not Result do
  509. begin
  510. fld:=mysql_fetch_field_direct(C.FRES,I);
  511. if CompareText(Field.FieldName,fld^.name)=0 then
  512. begin
  513. Move(CurrBuff^, PChar(Buffer)^, MySQLDataSize(fld^.ftype, fld^.length));
  514. if Field.DataType in [ftString{, ftWideString}] then
  515. begin
  516. Result:=PChar(buffer)^<>#0;
  517. if Result then
  518. PChar(buffer)[fld^.length]:=#0;
  519. end
  520. else
  521. Result := True;
  522. end;
  523. Inc(CurrBuff, MySQLDataSize(fld^.ftype, fld^.length));
  524. Inc(I);
  525. end;
  526. end;
  527. Function GetSQLStatementType(SQL : String) : TStatementType;
  528. Var
  529. L : Integer;
  530. cmt : boolean;
  531. P,PE,PP : PChar;
  532. S : string;
  533. T : TStatementType;
  534. begin
  535. Result:=stNone;
  536. L:=Length(SQL);
  537. If (L=0) then
  538. Exit;
  539. P:=Pchar(SQL);
  540. PP:=P;
  541. Cmt:=False;
  542. While ((P-PP)<L) do
  543. begin
  544. if not (P^ in [' ',#13,#10,#9]) then
  545. begin
  546. if not Cmt then
  547. begin
  548. // Check for comment.
  549. Cmt:=(P^='/') and (((P-PP)<=L) and (P[1]='*'));
  550. if not (cmt) then
  551. Break;
  552. end
  553. else
  554. begin
  555. // Check for end of comment.
  556. Cmt:=Not( (P^='*') and (((P-PP)<=L) and (P[1]='/')) );
  557. If not cmt then
  558. Inc(p);
  559. end;
  560. end;
  561. inc(P);
  562. end;
  563. PE:=P+1;
  564. While ((PE-PP)<L) and (PE^ in ['0'..'9','a'..'z','A'..'Z','_']) do
  565. Inc(PE);
  566. Setlength(S,PE-P);
  567. Move(P^,S[1],(PE-P));
  568. S:=Lowercase(s);
  569. For t:=stselect to strollback do
  570. if (S=StatementTokens[t]) then
  571. Exit(t);
  572. end;
  573. {function TMySQLConnection.GetStatementType(cursor: TSQLHandle): tStatementType;
  574. Var
  575. C : TMySQLCursor;
  576. begin
  577. C:=Cursor as TMySQLCursor;
  578. Result:=GetSQLStatementType(C.FStatement);
  579. end;}
  580. function TMySQLConnection.GetTransactionHandle(trans: TSQLHandle): pointer;
  581. begin
  582. Result:=Nil;
  583. end;
  584. function TMySQLConnection.Commit(trans: TSQLHandle): boolean;
  585. begin
  586. // Do nothing.
  587. end;
  588. function TMySQLConnection.RollBack(trans: TSQLHandle): boolean;
  589. begin
  590. // Do nothing
  591. end;
  592. function TMySQLConnection.StartdbTransaction(trans: TSQLHandle): boolean;
  593. begin
  594. // Do nothing
  595. end;
  596. procedure TMySQLConnection.CommitRetaining(trans: TSQLHandle);
  597. begin
  598. // Do nothing
  599. end;
  600. procedure TMySQLConnection.RollBackRetaining(trans: TSQLHandle);
  601. begin
  602. // Do nothing
  603. end;
  604. end.