mysqlconn.inc 20 KB

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