mysql4conn.pas 17 KB

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