mysqlconn.inc 17 KB

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