mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-22 03:38:35 +02:00
* Patch from Joost van der Sluis
- Made it possible to run 'show...' queries for MySQL - Use of the dynamically loaded library (mysql4dyn) - implemented UpdateIndexDefs - Support for more then one query for each connection
This commit is contained in:
parent
f04a7f8f86
commit
35a249fc8f
@ -2,10 +2,17 @@ unit mysql4conn;
|
|||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
{$Define LinkDynamically}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,sqldb,mysql4,mysql4_com,db;
|
Classes, SysUtils,sqldb,db,
|
||||||
|
{$IfDef LinkDynamically}
|
||||||
|
mysql4dyn,mysql4_comdyn;
|
||||||
|
{$Else}
|
||||||
|
mysql4,mysql4_com;
|
||||||
|
{$EndIf}
|
||||||
|
|
||||||
Type
|
Type
|
||||||
TMySQLTransaction = Class(TSQLHandle)
|
TMySQLTransaction = Class(TSQLHandle)
|
||||||
@ -14,6 +21,7 @@ Type
|
|||||||
|
|
||||||
TMySQLCursor = Class(TSQLHandle)
|
TMySQLCursor = Class(TSQLHandle)
|
||||||
protected
|
protected
|
||||||
|
FQMySQL : PMySQL;
|
||||||
FRes: PMYSQL_RES; { Record pointer }
|
FRes: PMYSQL_RES; { Record pointer }
|
||||||
FNeedData : Boolean;
|
FNeedData : Boolean;
|
||||||
FStatement : String;
|
FStatement : String;
|
||||||
@ -30,7 +38,9 @@ Type
|
|||||||
FMySQL : PMySQL;
|
FMySQL : PMySQL;
|
||||||
function GetClientInfo: string;
|
function GetClientInfo: string;
|
||||||
function GetServerStatus: String;
|
function GetServerStatus: String;
|
||||||
|
procedure ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar);
|
||||||
protected
|
protected
|
||||||
|
function StrToStatementType(s : string) : TStatementType; override;
|
||||||
Procedure ConnectToServer; virtual;
|
Procedure ConnectToServer; virtual;
|
||||||
Procedure SelectDatabase; virtual;
|
Procedure SelectDatabase; virtual;
|
||||||
function MySQLDataType(AType: enum_field_types; ASize: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean;
|
function MySQLDataType(AType: enum_field_types; ASize: Integer; var NewType: TFieldType; var NewSize: Integer): Boolean;
|
||||||
@ -56,6 +66,8 @@ Type
|
|||||||
function StartdbTransaction(trans : TSQLHandle) : boolean; override;
|
function StartdbTransaction(trans : TSQLHandle) : boolean; override;
|
||||||
procedure CommitRetaining(trans : TSQLHandle); override;
|
procedure CommitRetaining(trans : TSQLHandle); override;
|
||||||
procedure RollBackRetaining(trans : TSQLHandle); override;
|
procedure RollBackRetaining(trans : TSQLHandle); override;
|
||||||
|
procedure UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string); override;
|
||||||
|
|
||||||
Public
|
Public
|
||||||
Property ServerInfo : String Read FServerInfo;
|
Property ServerInfo : String Read FServerInfo;
|
||||||
Property HostInfo : String Read FHostInfo;
|
Property HostInfo : String Read FHostInfo;
|
||||||
@ -75,6 +87,8 @@ Type
|
|||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
uses dbconst;
|
||||||
|
|
||||||
{ TMySQLConnection }
|
{ TMySQLConnection }
|
||||||
|
|
||||||
Resourcestring
|
Resourcestring
|
||||||
@ -103,10 +117,20 @@ begin
|
|||||||
DatabaseError(Msg,Comp);
|
DatabaseError(Msg,Comp);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TMySQLConnection.StrToStatementType(s : string) : TStatementType;
|
||||||
|
|
||||||
|
begin
|
||||||
|
S:=Lowercase(s);
|
||||||
|
if s = 'show' then exit(stSelect);
|
||||||
|
result := inherited StrToStatementType(s);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TMySQLConnection.GetClientInfo: string;
|
function TMySQLConnection.GetClientInfo: string;
|
||||||
begin
|
begin
|
||||||
CheckConnected;
|
CheckConnected;
|
||||||
Result:=strpas(mysql_get_client_info);
|
// Ask MvC
|
||||||
|
Result:=strpas(pchar(mysql_get_client_info));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMySQLConnection.GetServerStatus: String;
|
function TMySQLConnection.GetServerStatus: String;
|
||||||
@ -115,7 +139,19 @@ begin
|
|||||||
Result := mysql_stat(FMYSQL);
|
Result := mysql_stat(FMYSQL);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMySQLConnection.ConnectMySQL(var HMySQL : PMySQL;H,U,P : pchar);
|
||||||
|
|
||||||
|
begin
|
||||||
|
if (HMySQL=Nil) then
|
||||||
|
New(HMySQL);
|
||||||
|
mysql_init(HMySQL);
|
||||||
|
HMySQL:=mysql_real_connect(HMySQL,PChar(H),PChar(U),Pchar(P),Nil,0,Nil,0);
|
||||||
|
If (HMySQL=Nil) then
|
||||||
|
MySQlError(Nil,SErrServerConnectFailed,Self);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TMySQLConnection.ConnectToServer;
|
procedure TMySQLConnection.ConnectToServer;
|
||||||
|
|
||||||
Var
|
Var
|
||||||
H,U,P : String;
|
H,U,P : String;
|
||||||
|
|
||||||
@ -123,12 +159,7 @@ begin
|
|||||||
H:=HostName;
|
H:=HostName;
|
||||||
U:=UserName;
|
U:=UserName;
|
||||||
P:=Password;
|
P:=Password;
|
||||||
if (FMySQL=Nil) then
|
ConnectMySQL(FMySQL,pchar(H),pchar(U),pchar(P));
|
||||||
New(FMySQL);
|
|
||||||
mysql_init(FMySQL);
|
|
||||||
FMySQL:=mysql_real_connect(FMySQL,PChar(H),PChar(U),Pchar(P),Nil,0,Nil,0);
|
|
||||||
If (FMySQL=Nil) then
|
|
||||||
MySQlError(Nil,SErrServerConnectFailed,Self);
|
|
||||||
FServerInfo := strpas(mysql_get_server_info(FMYSQL));
|
FServerInfo := strpas(mysql_get_server_info(FMYSQL));
|
||||||
FHostInfo := strpas(mysql_get_host_info(FMYSQL));
|
FHostInfo := strpas(mysql_get_host_info(FMYSQL));
|
||||||
end;
|
end;
|
||||||
@ -141,6 +172,9 @@ end;
|
|||||||
|
|
||||||
procedure TMySQLConnection.DoInternalConnect;
|
procedure TMySQLConnection.DoInternalConnect;
|
||||||
begin
|
begin
|
||||||
|
{$IfDef LinkDynamically}
|
||||||
|
InitialiseMysql4;
|
||||||
|
{$EndIf}
|
||||||
inherited DoInternalConnect;
|
inherited DoInternalConnect;
|
||||||
ConnectToServer;
|
ConnectToServer;
|
||||||
SelectDatabase;
|
SelectDatabase;
|
||||||
@ -151,6 +185,10 @@ begin
|
|||||||
inherited DoInternalDisconnect;
|
inherited DoInternalDisconnect;
|
||||||
mysql_close(FMySQL);
|
mysql_close(FMySQL);
|
||||||
FMySQL:=Nil;
|
FMySQL:=Nil;
|
||||||
|
{$IfDef LinkDynamically}
|
||||||
|
ReleaseMysql4;
|
||||||
|
{$EndIf}
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TMySQLConnection.GetHandle: pointer;
|
function TMySQLConnection.GetHandle: pointer;
|
||||||
@ -181,6 +219,11 @@ begin
|
|||||||
begin
|
begin
|
||||||
C.FRes:=Nil;
|
C.FRes:=Nil;
|
||||||
end;
|
end;
|
||||||
|
if (c.FQMySQL <> Nil) then
|
||||||
|
begin
|
||||||
|
mysql_close(c.FQMySQL);
|
||||||
|
c.FQMySQL:=Nil;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMySQLConnection.PrepareStatement(cursor: TSQLHandle;
|
procedure TMySQLConnection.PrepareStatement(cursor: TSQLHandle;
|
||||||
@ -191,6 +234,9 @@ begin
|
|||||||
FStatement:=Buf;
|
FStatement:=Buf;
|
||||||
if StatementType=stSelect then
|
if StatementType=stSelect then
|
||||||
FNeedData:=True;
|
FNeedData:=True;
|
||||||
|
ConnectMySQL(FQMySQL,FMySQL^.host,FMySQL^.user,FMySQL^.passwd);
|
||||||
|
if mysql_select_db(FQMySQL,pchar(DatabaseName))<>0 then
|
||||||
|
MySQLError(FQMySQL,SErrDatabaseSelectFailed,Self);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -218,14 +264,14 @@ begin
|
|||||||
C:=Cursor as TMysqlCursor;
|
C:=Cursor as TMysqlCursor;
|
||||||
If (C.FRes=Nil) then
|
If (C.FRes=Nil) then
|
||||||
begin
|
begin
|
||||||
if mysql_query(FMySQL,Pchar(C.FStatement))<>0 then
|
if mysql_query(c.FQMySQL,Pchar(C.FStatement))<>0 then
|
||||||
MySQLError(FMYSQL,Format(SErrExecuting,[StrPas(mysql_error(FMySQL))]),Self)
|
MySQLError(c.FQMYSQL,Format(SErrExecuting,[StrPas(mysql_error(c.FQMySQL))]),Self)
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
C.RowsAffected := mysql_affected_rows(FMYSQL);
|
C.RowsAffected := mysql_affected_rows(c.FQMYSQL);
|
||||||
C.LastInsertID := mysql_insert_id(FMYSQL);
|
C.LastInsertID := mysql_insert_id(c.FQMYSQL);
|
||||||
if C.FNeedData then
|
if C.FNeedData then
|
||||||
C.FRes:=mysql_use_result(FMySQL);
|
C.FRes:=mysql_use_result(c.FQMySQL);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -280,7 +326,6 @@ var
|
|||||||
field: PMYSQL_FIELD;
|
field: PMYSQL_FIELD;
|
||||||
DFT: TFieldType;
|
DFT: TFieldType;
|
||||||
DFS: Integer;
|
DFS: Integer;
|
||||||
WasClosed: Boolean;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// Writeln('MySQL: Adding fielddefs');
|
// Writeln('MySQL: Adding fielddefs');
|
||||||
@ -288,7 +333,7 @@ begin
|
|||||||
If (C.FRes=Nil) then
|
If (C.FRes=Nil) then
|
||||||
begin
|
begin
|
||||||
// Writeln('res is nil');
|
// Writeln('res is nil');
|
||||||
MySQLError(FMySQL,SErrNoQueryResult,Self);
|
MySQLError(c.FQMySQL,SErrNoQueryResult,Self);
|
||||||
end;
|
end;
|
||||||
// Writeln('MySQL: have result');
|
// Writeln('MySQL: have result');
|
||||||
FC:=mysql_num_fields(C.FRes);
|
FC:=mysql_num_fields(C.FRes);
|
||||||
@ -329,7 +374,7 @@ begin
|
|||||||
if C.Row=nil then
|
if C.Row=nil then
|
||||||
begin
|
begin
|
||||||
// Writeln('LoadFieldsFromBuffer: row=nil');
|
// Writeln('LoadFieldsFromBuffer: row=nil');
|
||||||
MySQLError(FMySQL,SErrFetchingData,Self);
|
MySQLError(c.FQMySQL,SErrFetchingData,Self);
|
||||||
end;
|
end;
|
||||||
Row:=C.Row;
|
Row:=C.Row;
|
||||||
FC := mysql_num_fields(C.FRES);
|
FC := mysql_num_fields(C.FRES);
|
||||||
@ -520,55 +565,43 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Function GetSQLStatementType(SQL : String) : TStatementType;
|
procedure TMySQLConnection.UpdateIndexDefs(var IndexDefs : TIndexDefs;TableName : string);
|
||||||
|
|
||||||
Var
|
var qry : TSQLQuery;
|
||||||
L : Integer;
|
|
||||||
cmt : boolean;
|
|
||||||
P,PE,PP : PChar;
|
|
||||||
S : string;
|
|
||||||
T : TStatementType;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result:=stNone;
|
if not assigned(Transaction) then
|
||||||
L:=Length(SQL);
|
DatabaseError(SErrConnTransactionnSet);
|
||||||
If (L=0) then
|
|
||||||
Exit;
|
qry := tsqlquery.Create(nil);
|
||||||
P:=Pchar(SQL);
|
qry.transaction := Transaction;
|
||||||
PP:=P;
|
qry.database := Self;
|
||||||
Cmt:=False;
|
with qry do
|
||||||
While ((P-PP)<L) do
|
|
||||||
begin
|
begin
|
||||||
if not (P^ in [' ',#13,#10,#9]) then
|
ReadOnly := True;
|
||||||
begin
|
sql.clear;
|
||||||
if not Cmt then
|
sql.add('show index from ' + TableName);
|
||||||
begin
|
open;
|
||||||
// Check for comment.
|
|
||||||
Cmt:=(P^='/') and (((P-PP)<=L) and (P[1]='*'));
|
|
||||||
if not (cmt) then
|
|
||||||
Break;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
// Check for end of comment.
|
|
||||||
Cmt:=Not( (P^='*') and (((P-PP)<=L) and (P[1]='/')) );
|
|
||||||
If not cmt then
|
|
||||||
Inc(p);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
inc(P);
|
|
||||||
end;
|
end;
|
||||||
PE:=P+1;
|
|
||||||
While ((PE-PP)<L) and (PE^ in ['0'..'9','a'..'z','A'..'Z','_']) do
|
while not qry.eof do with IndexDefs.AddIndexDef do
|
||||||
Inc(PE);
|
begin
|
||||||
Setlength(S,PE-P);
|
Name := trim(qry.fieldbyname('Key_name').asstring);
|
||||||
Move(P^,S[1],(PE-P));
|
Fields := trim(qry.fieldbyname('Column_name').asstring);
|
||||||
S:=Lowercase(s);
|
If Name = 'PRIMARY' then options := options + [ixPrimary];
|
||||||
For t:=stselect to strollback do
|
If qry.fieldbyname('Non_unique').asinteger = 0 then options := options + [ixUnique];
|
||||||
if (S=StatementTokens[t]) then
|
qry.next;
|
||||||
Exit(t);
|
{ while (name = qry.fields[0].asstring) and (not qry.eof) do
|
||||||
|
begin
|
||||||
|
Fields := Fields + ';' + trim(qry.Fields[2].asstring);
|
||||||
|
qry.next;
|
||||||
|
end;}
|
||||||
|
end;
|
||||||
|
qry.close;
|
||||||
|
qry.free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TMySQLConnection.GetTransactionHandle(trans: TSQLHandle): pointer;
|
function TMySQLConnection.GetTransactionHandle(trans: TSQLHandle): pointer;
|
||||||
begin
|
begin
|
||||||
Result:=Nil;
|
Result:=Nil;
|
||||||
|
Loading…
Reference in New Issue
Block a user