+ Fixes in TDBDataset etc. Changed MySQLDb to use database as well

This commit is contained in:
michael 2003-08-16 16:42:21 +00:00
parent df1fa8669a
commit 2e6d07b89e
7 changed files with 725 additions and 584 deletions

View File

@ -66,6 +66,8 @@ constructor TDatabase.Create(AOwner: TComponent);
begin begin
Inherited Create(AOwner); Inherited Create(AOwner);
FParams:=TStringlist.Create;
FDatasets:=TList.Create;
end; end;
destructor TDatabase.Destroy; destructor TDatabase.Destroy;
@ -74,6 +76,7 @@ begin
Connected:=False; Connected:=False;
RemoveDatasets; RemoveDatasets;
FDatasets.Free; FDatasets.Free;
FParams.Free;
Inherited Destroy; Inherited Destroy;
end; end;
@ -173,9 +176,27 @@ begin
end; end;
end; end;
Procedure TDBDataset.CheckDatabase;
begin
If (FDatabase=Nil) then
DatabaseError(SErrNoDatabaseAvailable,Self)
end;
Destructor TDBDataset.Destroy;
begin
Database:=Nil;
Inherited;
end;
{ {
$Log$ $Log$
Revision 1.3 2002-09-07 15:15:22 peter Revision 1.4 2003-08-16 16:42:21 michael
+ Fixes in TDBDataset etc. Changed MySQLDb to use database as well
Revision 1.3 2002/09/07 15:15:22 peter
* old logs removed and tabs fixed * old logs removed and tabs fixed
} }

View File

@ -1145,7 +1145,10 @@ type
Private Private
FDatabase : TDatabase; FDatabase : TDatabase;
Procedure SetDatabase (Value : TDatabase); Procedure SetDatabase (Value : TDatabase);
Protected
Procedure CheckDatabase;
Public Public
Destructor destroy; override;
Property DataBase : TDatabase Read FDatabase Write SetDatabase; Property DataBase : TDatabase Read FDatabase Write SetDatabase;
end; end;
@ -1161,7 +1164,7 @@ type
FConnected : Boolean; FConnected : Boolean;
FDataBaseName : String; FDataBaseName : String;
FDataSets : TList; FDataSets : TList;
FDirectOry : String; FDirectory : String;
FKeepConnection : Boolean; FKeepConnection : Boolean;
FLoginPrompt : Boolean; FLoginPrompt : Boolean;
FOnLogin : TLoginEvent; FOnLogin : TLoginEvent;
@ -1459,7 +1462,10 @@ end.
{ {
$Log$ $Log$
Revision 1.9 2003-05-15 15:15:15 michael Revision 1.10 2003-08-16 16:42:21 michael
+ Fixes in TDBDataset etc. Changed MySQLDb to use database as well
Revision 1.9 2003/05/15 15:15:15 michael
+ Database class in TDBDataset is public, not published + Database class in TDBDataset is public, not published
Revision 1.8 2003/05/08 21:52:41 michael Revision 1.8 2003/05/08 21:52:41 michael

View File

@ -43,9 +43,15 @@ Const
SDatasetReadOnly = 'Dataset is read-only.'; SDatasetReadOnly = 'Dataset is read-only.';
SNeedField = 'Field %s is required, but not supplied.'; SNeedField = 'Field %s is required, but not supplied.';
SNotInEditState = 'Operation not allowed, dataset "%s" is not in an edit state.'; SNotInEditState = 'Operation not allowed, dataset "%s" is not in an edit state.';
SErrNoDatabaseAvailable = 'Invalid operation: Not attached to database';
{ {
$Log$ $Log$
Revision 1.4 2002-09-07 15:15:23 peter Revision 1.5 2003-08-16 16:42:21 michael
+ Fixes in TDBDataset etc. Changed MySQLDb to use database as well
Revision 1.4 2002/09/07 15:15:23 peter
* old logs removed and tabs fixed * old logs removed and tabs fixed
} }

View File

@ -1,8 +1,8 @@
# #
# Don't edit, this file is generated by FPCMake Version 1.1 [2003/04/01] # Don't edit, this file is generated by FPCMake Version 1.1 [2003/06/26]
# #
default: all default: all
MAKEFILETARGETS=linux go32v2 win32 os2 freebsd beos netbsd amiga atari sunos qnx netware openbsd wdosx palmos macos macosx emx MAKEFILETARGETS=linux win32
override PATH:=$(subst \,/,$(PATH)) override PATH:=$(subst \,/,$(PATH))
ifeq ($(findstring ;,$(PATH)),) ifeq ($(findstring ;,$(PATH)),)
inUnix=1 inUnix=1
@ -32,7 +32,7 @@ inOS2=1
endif endif
endif endif
else else
ifneq ($(findstring cygwin,$(MACHTYPE)),) ifneq ($(findstring cygdrive,$(PATH)),)
inCygWin=1 inCygWin=1
endif endif
endif endif
@ -205,7 +205,7 @@ endif
PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/extra) PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
override PACKAGE_NAME=fcl override PACKAGE_NAME=fcl
override TARGET_UNITS+=mysqldb override TARGET_UNITS+=mysqldb
override TARGET_EXAMPLES+=testm override TARGET_EXAMPLES+=mtest
override CLEAN_UNITS+=mysql mysql_com mysql_version override CLEAN_UNITS+=mysql mysql_com mysql_version
override INSTALL_FPCPACKAGE=y override INSTALL_FPCPACKAGE=y
override COMPILER_OPTIONS+=-S2 override COMPILER_OPTIONS+=-S2
@ -519,6 +519,12 @@ ifeq ($(OS_TARGET),macos)
EXEEXT= EXEEXT=
FPCMADE=fpcmade.mcc FPCMADE=fpcmade.mcc
endif endif
ifeq ($(OS_TARGET),darwin)
EXEEXT=
HASSHAREDLIB=1
FPCMADE=fpcmade.darwin
ZIPSUFFIX=darwin
endif
else else
ifeq ($(OS_TARGET),go32v1) ifeq ($(OS_TARGET),go32v1)
PPUEXT=.pp1 PPUEXT=.pp1
@ -877,76 +883,40 @@ TAREXT=.tar.gz
endif endif
override REQUIRE_PACKAGES=rtl mysql override REQUIRE_PACKAGES=rtl mysql
ifeq ($(OS_TARGET),linux) ifeq ($(OS_TARGET),linux)
ifeq ($(CPU_TARGET),i386)
REQUIRE_PACKAGES_RTL=1 REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1 REQUIRE_PACKAGES_MYSQL=1
endif endif
ifeq ($(OS_TARGET),go32v2) endif
ifeq ($(OS_TARGET),linux)
ifeq ($(CPU_TARGET),m68k)
REQUIRE_PACKAGES_RTL=1 REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1 REQUIRE_PACKAGES_MYSQL=1
endif endif
endif
ifeq ($(OS_TARGET),linux)
ifeq ($(CPU_TARGET),powerpc)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
endif
ifeq ($(OS_TARGET),linux)
ifeq ($(CPU_TARGET),sparc)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
endif
ifeq ($(OS_TARGET),linux)
ifeq ($(CPU_TARGET),x86_64)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
endif
ifeq ($(OS_TARGET),win32) ifeq ($(OS_TARGET),win32)
ifeq ($(CPU_TARGET),i386)
REQUIRE_PACKAGES_RTL=1 REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1 REQUIRE_PACKAGES_MYSQL=1
endif endif
ifeq ($(OS_TARGET),os2)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),freebsd)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),beos)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),netbsd)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),amiga)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),atari)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),sunos)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),qnx)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),netware)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),openbsd)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),wdosx)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),palmos)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),macos)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),macosx)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif
ifeq ($(OS_TARGET),emx)
REQUIRE_PACKAGES_RTL=1
REQUIRE_PACKAGES_MYSQL=1
endif endif
ifdef REQUIRE_PACKAGES_RTL ifdef REQUIRE_PACKAGES_RTL
PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/$(OS_TARGET)/Makefile.fpc,$(PACKAGESDIR)))))) PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/$(OS_TARGET)/Makefile.fpc,$(PACKAGESDIR))))))
@ -1119,7 +1089,7 @@ override COMPILER:=$(FPC) $(FPCOPT)
ifeq (,$(findstring -s ,$(COMPILER))) ifeq (,$(findstring -s ,$(COMPILER)))
EXECPPAS= EXECPPAS=
else else
ifeq ($(OS_SOURCE),$(OS_TARGET)) ifeq ($(FULL_SOURCE),$(FULL_TARGET))
EXECPPAS:=@$(PPAS) EXECPPAS:=@$(PPAS)
endif endif
endif endif

View File

@ -7,7 +7,7 @@ main=fcl
[target] [target]
units=mysqldb units=mysqldb
examples=testm examples=mtest
[clean] [clean]
units=mysql mysql_com mysql_version units=mysql mysql_com mysql_version

View File

@ -13,6 +13,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************} **********************************************************************}
{$mode objfpc}
{$H+}
program mtest; program mtest;
uses db,sysutils,mysqldb; uses db,sysutils,mysqldb;
@ -74,6 +76,7 @@ begin
end; end;
Var Var
Dbase : TMySQLDatabase;
Data : TMysqldataset; Data : TMysqldataset;
I,Count : longint; I,Count : longint;
Bookie : TBookMarkStr; Bookie : TBookMarkStr;
@ -112,16 +115,26 @@ begin
Writeln ('Usage : mtest db user pwd sql'); Writeln ('Usage : mtest db user pwd sql');
Halt(1); Halt(1);
end; end;
Log ('Creating Database');
DBase:=TMySQLDatabase.Create(Nil);
Try
With DBase do
begin
Log('Setting database');
DatabaseName:=Paramstr(1);
Log('Setting user');
UserName:=Paramstr(2);
Log('Setting password');
PassWord := Paramstr(3);
Log('Connecting');
Connected:=True;
end;
Log ('Creating Dataset'); Log ('Creating Dataset');
Data:=TMysqlDataset.Create(Nil); Data:=TMysqlDataset.Create(Nil);
With Data do With Data do
begin Try
Log('Setting database'); Log('Setting database property');
Database:=Paramstr(1); Database:=DBase;
Log('Setting user');
User:=Paramstr(2);
Log('Setting password');
PassWord := Paramstr(3);
Log('Setting SQL'); Log('Setting SQL');
SQL.text := Paramstr(4); SQL.text := Paramstr(4);
Log('Opening Dataset'); Log('Opening Dataset');
@ -176,13 +189,21 @@ begin
Log('Closing Dataset'); Log('Closing Dataset');
Close; Close;
Log('End.'); Log('End.');
Finally
Free; Free;
end; end;
Finally
Writeln('Freeing database');
DBase.free;
end;
end. end.
{ {
$Log$ $Log$
Revision 1.2 2002-09-07 15:15:23 peter Revision 1.3 2003-08-16 16:42:21 michael
+ Fixes in TDBDataset etc. Changed MySQLDb to use database as well
Revision 1.2 2002/09/07 15:15:23 peter
* old logs removed and tabs fixed * old logs removed and tabs fixed
} }

View File

@ -16,44 +16,60 @@ type
Pinteger = ^Integer; Pinteger = ^Integer;
TMySQLDataset = class(TDataSet) TMySQLDatabase = class(TDatabase)
private Private
FSQL: TStrings;
FDatabase: string;
FHost: string;
FPort: Integer;
FUser: string;
FPassword: string;
FRecordSize: Integer;
FBufferSize: Integer;
// MySQL data
FMYSQL: PMYSQL; FMYSQL: PMYSQL;
FMYSQLRES: PMYSQL_RES;
FCurrentRecord: Integer; { Record pointer }
FServerInfo: string; FServerInfo: string;
FHostInfo: string; FHostInfo: string;
function GetHostName: String;
Function GetUserName : String;
procedure SetHostName(const AValue: String);
Procedure SetUserName (Value : String);
Procedure SetPassword (Value : String);
Function GetPassword : String;
Function GetClientInfo : String;
Protected
Procedure ConnectToServer;
Procedure SelectDatabase;
Procedure DoInternalConnect; override;
Procedure DoInternalDisConnect; override;
procedure StartTransaction; override;
procedure EndTransaction; override;
function GetServerStatus: string;
Public
Procedure CreateDatabase;
Procedure DropDatabase;
Property ServerInfo : String Read FServerInfo;
Property HostInfo : String Read FHostInfo;
property ClientInfo: string read GetClientInfo;
property ServerStatus : String read GetServerStatus;
Published
Property UserName : String Read GetUserName Write SetUserName;
Property HostName : String Read GetHostName Write SetHostName;
Property Password : String Read GetPassword Write SetPassword;
end;
TMySQLDataset = class(TDBDataSet)
private
FSQL: TStrings;
FRecordSize: Integer;
FBufferSize: Integer;
// MySQL data
FMYSQLRES: PMYSQL_RES;
FCurrentRecord: Integer; { Record pointer }
FAffectedRows: QWord; FAffectedRows: QWord;
FLastInsertID: Integer; FLastInsertID: Integer;
FLoadingFieldDefs: Boolean; FLoadingFieldDefs: Boolean;
procedure DoOpen;
procedure DoClose; procedure DoClose;
procedure DoQuery; procedure DoQuery;
procedure DoGetResult; procedure DoGetResult;
procedure CalculateSizes; procedure CalculateSizes;
procedure LoadBufferFromData(Buffer: PChar); procedure LoadBufferFromData(Buffer: PChar);
function GetServerStatus: string;
protected protected
procedure SetDatabase(const Value: string); Function FMySQL : PMySQL;
procedure SetSQL(const Value: TStrings); procedure SetSQL(const Value: TStrings);
function GetClientInfo: string;
function InternalStrToFloat(S: string): Extended; function InternalStrToFloat(S: string): Extended;
function InternalStrToDate(S: string): TDateTime; function InternalStrToDate(S: string): TDateTime;
function InternalStrToTime(S: string): TDateTime; function InternalStrToTime(S: string): TDateTime;
@ -109,21 +125,11 @@ type
// TDataset method // TDataset method
function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override; function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
property ServerInfo: string read FServerInfo;
property ClientInfo: string read GetClientInfo;
property HostInfo: string read FHostInfo;
property AffectedRows: QWord read FAffectedRows; property AffectedRows: QWord read FAffectedRows;
property LastInsertID: Integer read FLastInsertID; property LastInsertID: Integer read FLastInsertID;
property ServerStatus: string read GetServerStatus;
published published
property Active; property Active;
property SQL: TStrings read FSQL write SetSQL; property SQL: TStrings read FSQL write SetSQL;
property Database: string read FDatabase write SetDatabase;
property Host: string read FHost write FHost;
property Port: Integer read FPort write FPort;
property User: string read FUser write FUser;
property Password: string read FPassword write FPassword;
property BeforeOpen; property BeforeOpen;
property AfterOpen; property AfterOpen;
property BeforeClose; property BeforeClose;
@ -144,33 +150,53 @@ type
property OnEditError; property OnEditError;
end; end;
EMySQLError = Class(Exception);
implementation implementation
Resourcestring
SErrServerConnectFailed = 'Server connect failed.';
SErrDatabaseSelectFailed = 'failed to select database: %s';
SErrDatabaseCreate = 'Failed to create database: %s';
SErrDatabaseDrop = 'Failed to drop database: %s';
SErrNoData = 'No data for record';
SErrExecuting = 'Error executing query: %s';
SErrFetchingdata = 'Error fetching row data: %s';
SErrGettingResult = 'Error getting result set: %s';
Procedure MySQlError(R : PMySQL;Msg: String;Comp : TComponent);
Var
MySQLMsg : String;
begin
If (R<>Nil) then
begin
MySQLMsg:=Strpas(mysql_error(R));
DatabaseErrorFmt(Msg,[MySQLMsg],Comp);
end
else
DatabaseError(Msg,Comp);
end;
{ TMySQLDataset } { TMySQLDataset }
constructor TMySQLDataset.Create(AOwner: TComponent); constructor TMySQLDataset.Create(AOwner: TComponent);
begin begin
inherited Create(AOwner); inherited Create(AOwner);
FSQL := TStringList.Create; FSQL := TStringList.Create;
FHost := '';
FPort := 0;
FUser := '';
FPassword := '';
FBufferSize := 0; FBufferSize := 0;
FRecordSize := 0; FRecordSize := 0;
FCurrentRecord := -1; FCurrentRecord := -1;
FLoadingFieldDefs := False; FLoadingFieldDefs := False;
FAffectedRows := 0; FAffectedRows := 0;
FLastInsertID := -1; FLastInsertID := -1;
FMYSQL := nil;
FMYSQLRES := nil; FMYSQLRES := nil;
end; end;
destructor TMySQLDataset.Destroy; destructor TMySQLDataset.Destroy;
begin begin
Close;
FSQL.Free; FSQL.Free;
inherited destroy; inherited destroy;
end; end;
@ -182,6 +208,7 @@ end;
procedure TMySQLDataset.FreeRecordBuffer(var Buffer: PChar); procedure TMySQLDataset.FreeRecordBuffer(var Buffer: PChar);
begin begin
If (@Buffer<>nil) then
FreeMem(Buffer); FreeMem(Buffer);
end; end;
@ -196,32 +223,30 @@ begin
end; end;
function TMySQLDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean; function TMySQLDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
var var
I, FC: Integer; I, FC: Integer;
fld: TMYSQL_FIELD; fld: TMYSQL_FIELD;
CurBuf: PChar; CurBuf: PChar;
begin begin
Result := False; Result := False;
CurBuf := ActiveBuffer; CurBuf := ActiveBuffer;
FC := mysql_num_fields(FMYSQLRES); FC := mysql_num_fields(FMYSQLRES);
for I := 0 to FC-1 do for I := 0 to FC-1 do
begin begin
fld := mysql_fetch_field_direct(FMYSQLRES, I); fld := mysql_fetch_field_direct(FMYSQLRES, I);
//if Field.FieldNo = I+1 then
if Field.FieldName = fld.name then if Field.FieldName = fld.name then
begin begin
Move(CurBuf^, PChar(Buffer)^, MySQLDataSize(fld.ftype, fld.length)); Move(CurBuf^, PChar(Buffer)^, MySQLDataSize(fld.ftype, fld.length));
if Field.DataType in [ftString{, ftWideString}] then if Field.DataType in [ftString{, ftWideString}] then
begin begin
Result := PChar(buffer)^ <> #0; Result := PChar(buffer)^ <> #0;
if Result then if Result then
// Terminate string (necessary for enum fields) // Terminate string (necessary for enum fields)
PChar(buffer)[fld.length] := #0; PChar(buffer)[fld.length] := #0;
end else end
else
Result := True; Result := True;
break; break;
end end
@ -265,8 +290,7 @@ begin
else else
Inc(FCurrentRecord); Inc(FCurrentRecord);
end; end;
if (Result=grOK) then
if Result = grOK then
begin begin
LoadBufferFromData(Buffer); LoadBufferFromData(Buffer);
with PMySQLDatasetBookmark(Buffer + FRecordSize)^ do with PMySQLDatasetBookmark(Buffer + FRecordSize)^ do
@ -277,7 +301,7 @@ begin
end end
else else
if (Result=grError) and (DoCheck) then if (Result=grError) and (DoCheck) then
DatabaseError('No record'); DatabaseError(SerrNoData,Self);
end; end;
end; end;
@ -299,9 +323,7 @@ end;
procedure TMySQLDataset.InternalClose; procedure TMySQLDataset.InternalClose;
begin begin
FCurrentRecord := -1; FCurrentRecord := -1;
DoClose; DoClose;
if DefaultFields then if DefaultFields then
DestroyFields; DestroyFields;
end; end;
@ -327,21 +349,21 @@ begin
end; end;
procedure TMySQLDataset.InternalInitFieldDefs; procedure TMySQLDataset.InternalInitFieldDefs;
var var
I, FC: Integer; I, FC: Integer;
field: TMYSQL_FIELD; field: TMYSQL_FIELD;
DFT: TFieldType; DFT: TFieldType;
DFS: Integer; DFS: Integer;
WasClosed: Boolean; WasClosed: Boolean;
begin begin
if FLoadingFieldDefs then Exit; if FLoadingFieldDefs then Exit;
FLoadingFieldDefs := True; FLoadingFieldDefs := True;
try try
WasClosed := not IsCursorOpen; WasClosed := not IsCursorOpen;
if WasClosed then if WasClosed then
begin begin
DoOpen;
DoQuery; DoQuery;
DoGetResult; DoGetResult;
end; end;
@ -356,10 +378,8 @@ begin
end; end;
finally finally
if WasClosed then if WasClosed then
begin
DoClose; DoClose;
end; end;
end;
finally finally
FLoadingFieldDefs := False; FLoadingFieldDefs := False;
end; end;
@ -377,30 +397,21 @@ end;
procedure TMySQLDataset.InternalOpen; procedure TMySQLDataset.InternalOpen;
begin begin
FMYSQL := nil; CheckDatabase;
FMYSQLRES := nil; FMYSQLRES := nil;
try try
DoOpen;
DoQuery; DoQuery;
DoGetResult; DoGetResult;
FCurrentRecord := -1; FCurrentRecord := -1;
InternalInitFieldDefs; InternalInitFieldDefs;
if DefaultFields then if DefaultFields then
CreateFields; CreateFields;
CalculateSizes; CalculateSizes;
BindFields(True); BindFields(True);
except except
DoClose; DoClose;
FMYSQL := nil;
FMYSQLRES := nil;
raise; raise;
end; end;
FServerInfo := mysql_get_server_info(FMYSQL);
FHostInfo := mysql_get_host_info(FMYSQL);
BookMarkSize:=SizeOf(Longint); BookMarkSize:=SizeOf(Longint);
end; end;
@ -411,7 +422,7 @@ end;
function TMySQLDataset.IsCursorOpen: Boolean; function TMySQLDataset.IsCursorOpen: Boolean;
begin begin
Result := FMYSQL <> nil; Result:=(FMYSQLRES<>nil);
end; end;
procedure TMySQLDataset.SetBookmarkData(Buffer: PChar; Data: Pointer); procedure TMySQLDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
@ -447,34 +458,19 @@ end;
procedure TMySQLDataset.ExecSQL; procedure TMySQLDataset.ExecSQL;
begin begin
try
DoOpen;
try try
DoQuery; DoQuery;
finally finally
DoClose; DoClose;
end; end;
finally
FMYSQLRES := nil;
FMYSQL := nil;
end;
end; end;
procedure TMySQLDataset.SetDatabase(const Value: string);
begin
FDatabase := Value;
end;
procedure TMySQLDataset.InternalPost; procedure TMySQLDataset.InternalPost;
begin begin
end; end;
function TMySQLDataset.GetClientInfo: string;
begin
Result := mysql_get_client_info;
end;
function TMySQLDataset.MySQLFieldToFieldType(AType: enum_field_types; ASize: Integer; function TMySQLDataset.MySQLFieldToFieldType(AType: enum_field_types; ASize: Integer;
var NewType: TFieldType; var NewSize: Integer): Boolean; var NewType: TFieldType; var NewSize: Integer): Boolean;
begin begin
@ -532,17 +528,17 @@ begin
end; end;
procedure TMySQLDataset.LoadBufferFromData(Buffer: PChar); procedure TMySQLDataset.LoadBufferFromData(Buffer: PChar);
var var
I, FC, CT: Integer; I, FC, CT: Integer;
field: TMYSQL_FIELD; field: TMYSQL_FIELD;
row: TMYSQL_ROW; row: TMYSQL_ROW;
begin begin
mysql_data_seek(FMYSQLRES, FCurrentRecord); mysql_data_seek(FMYSQLRES, FCurrentRecord);
row := mysql_fetch_row(FMYSQLRES); row := mysql_fetch_row(FMYSQLRES);
if row = nil then if row = nil then
DatabaseError(mysql_error(FMYSQL)); MySQLError(FMySQL,SErrFetchingData,Self);
FC := mysql_num_fields(FMYSQLRES); FC := mysql_num_fields(FMYSQLRES);
for I := 0 to FC-1 do for I := 0 to FC-1 do
begin begin
@ -581,10 +577,12 @@ end;
function TMySQLDataset.MySQLWriteFieldData(AType: enum_field_types; function TMySQLDataset.MySQLWriteFieldData(AType: enum_field_types;
ASize: Integer; Source, Dest: PChar): Integer; ASize: Integer; Source, Dest: PChar): Integer;
var var
VI: Integer; VI: Integer;
VF: Double; VF: Double;
VD: TDateTime; VD: TDateTime;
begin begin
Result := 0; Result := 0;
case AType of case AType of
@ -655,12 +653,13 @@ begin
end; end;
function TMySQLDataset.InternalStrToFloat(S: string): Extended; function TMySQLDataset.InternalStrToFloat(S: string): Extended;
var var
I: Integer; I: Integer;
Tmp: string; Tmp: string;
begin begin
Tmp := ''; Tmp := '';
for I := 1 to Length(S) do for I := 1 to Length(S) do
begin begin
if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then
@ -672,8 +671,10 @@ begin
end; end;
function TMySQLDataset.InternalStrToDate(S: string): TDateTime; function TMySQLDataset.InternalStrToDate(S: string): TDateTime;
var var
EY, EM, ED: Word; EY, EM, ED: Word;
begin begin
EY := StrToInt(Copy(S,1,4)); EY := StrToInt(Copy(S,1,4));
EM := StrToInt(Copy(S,6,2)); EM := StrToInt(Copy(S,6,2));
@ -685,29 +686,30 @@ begin
end; end;
function TMySQLDataset.InternalStrToDateTime(S: string): TDateTime; function TMySQLDataset.InternalStrToDateTime(S: string): TDateTime;
var var
EY, EM, ED: Word; EY, EM, ED: Word;
EH, EN, ES: Word; EH, EN, ES: Word;
begin begin
EY := StrToInt(Copy(S, 1, 4)); EY := StrToInt(Copy(S, 1, 4));
EM := StrToInt(Copy(S, 6, 2)); EM := StrToInt(Copy(S, 6, 2));
ED := StrToInt(Copy(S, 9, 2)); ED := StrToInt(Copy(S, 9, 2));
EH := StrToInt(Copy(S, 11, 2)); EH := StrToInt(Copy(S, 11, 2));
EN := StrToInt(Copy(S, 14, 2)); EN := StrToInt(Copy(S, 14, 2));
ES := StrToInt(Copy(S, 17, 2)); ES := StrToInt(Copy(S, 17, 2));
if (EY = 0) or (EM = 0) or (ED = 0) then if (EY = 0) or (EM = 0) or (ED = 0) then
Result := 0 Result := 0
else else
Result := EncodeDate(EY, EM, ED); Result := EncodeDate(EY, EM, ED);
Result := Result + EncodeTime(EH, EN, ES, 0); Result := Result + EncodeTime(EH, EN, ES, 0);
end; end;
function TMySQLDataset.InternalStrToTime(S: string): TDateTime; function TMySQLDataset.InternalStrToTime(S: string): TDateTime;
var var
EH, EM, ES: Word; EH, EM, ES: Word;
begin begin
EH := StrToInt(Copy(S, 1, 2)); EH := StrToInt(Copy(S, 1, 2));
EM := StrToInt(Copy(S, 4, 2)); EM := StrToInt(Copy(S, 4, 2));
@ -716,23 +718,22 @@ begin
end; end;
function TMySQLDataset.InternalStrToTimeStamp(S: string): TDateTime; function TMySQLDataset.InternalStrToTimeStamp(S: string): TDateTime;
var var
EY, EM, ED: Word; EY, EM, ED: Word;
EH, EN, ES: Word; EH, EN, ES: Word;
begin begin
EY := StrToInt(Copy(S, 1, 4)); EY := StrToInt(Copy(S, 1, 4));
EM := StrToInt(Copy(S, 5, 2)); EM := StrToInt(Copy(S, 5, 2));
ED := StrToInt(Copy(S, 7, 2)); ED := StrToInt(Copy(S, 7, 2));
EH := StrToInt(Copy(S, 9, 2)); EH := StrToInt(Copy(S, 9, 2));
EN := StrToInt(Copy(S, 11, 2)); EN := StrToInt(Copy(S, 11, 2));
ES := StrToInt(Copy(S, 13, 2)); ES := StrToInt(Copy(S, 13, 2));
if (EY = 0) or (EM = 0) or (ED = 0) then if (EY = 0) or (EM = 0) or (ED = 0) then
Result := 0 Result := 0
else else
Result := EncodeDate(EY, EM, ED); Result := EncodeDate(EY, EM, ED);
Result := Result + EncodeTime(EH, EN, ES, 0);; Result := Result + EncodeTime(EH, EN, ES, 0);;
end; end;
@ -741,37 +742,23 @@ begin
try try
if FMYSQLRES <> nil then if FMYSQLRES <> nil then
mysql_free_result(FMYSQLRES); mysql_free_result(FMYSQLRES);
if FMYSQL <> nil then
mysql_close(FMYSQL);
finally finally
FMYSQLRES := nil; FMYSQLRES := nil;
FMYSQL := nil;
end; end;
end; end;
procedure TMySQLDataset.DoOpen;
begin
FMYSQL := mysql_connect(nil, PChar(FHost), PChar(FUser), PChar(FPassword));
if FMYSQL = nil then
DatabaseError('Error connecting to MySQL server');
if FDatabase <> '' then
if mysql_select_db(FMYSQL, PChar(FDatabase)) <> 0 then
DatabaseError(mysql_error(FMYSQL));
end;
procedure TMySQLDataset.DoQuery; procedure TMySQLDataset.DoQuery;
var var
Query: PChar; Query: PChar;
begin begin
Query := FSQL.GetText; Query := FSQL.GetText;
try try
if mysql_query(FMYSQL, Query) <> 0 then if mysql_query(FMySQL,Query) <> 0 then
DatabaseError(mysql_error(FMYSQL)); MySQLError(FMYSQL,SErrExecuting,Self);
finally finally
StrDispose(Query); StrDispose(Query);
end; end;
FAffectedRows := mysql_affected_rows(FMYSQL); FAffectedRows := mysql_affected_rows(FMYSQL);
FLastInsertID := mysql_insert_id(FMYSQL); FLastInsertID := mysql_insert_id(FMYSQL);
end; end;
@ -784,15 +771,142 @@ end;
procedure TMySQLDataset.DoGetResult; procedure TMySQLDataset.DoGetResult;
begin begin
FMYSQLRES := mysql_store_result(FMYSQL); FMYSQLRES := mysql_store_result(FMYSQL);
if FMYSQLRES = nil then if (FMYSQLRES=nil) then
DatabaseError(mysql_error(FMYSQL)); MySQLError(FMYSQL,SErrGettingResult,Self);
FAffectedRows := mysql_affected_rows(FMYSQL); FAffectedRows := mysql_affected_rows(FMYSQL);
end; end;
function TMySQLDataset.GetServerStatus: string; function TMySQLDataset.FMySQL: PMySQL;
begin begin
CheckActive; Result:=(Database as TMySQLDatabase).FMySQL;
end;
{ TMySQLDatabase }
function TMySQLDatabase.GetUserName: String;
begin
result:=Params.values['UserName'];
end;
function TMySQLDatabase.GetHostName: String;
begin
Result:=Params.Values['HostName'];
end;
procedure TMySQLDatabase.SetHostName(const AValue: String);
begin
Params.Values['HostName']:=AValue;
end;
procedure TMySQLDatabase.SetUserName(Value: String);
begin
Params.Values['UserName']:=Value;
end;
procedure TMySQLDatabase.SetPassword(Value: String);
begin
Params.Values['Password']:=Value;
end;
function TMySQLDatabase.GetPassword: String;
begin
Result:=Params.Values['Password'];
end;
function TMySQLDatabase.GetClientInfo: String;
begin
Result:=strpas(mysql_get_client_info);
end;
procedure TMySQLDatabase.ConnectToServer;
Var
H,U,P : String;
begin
H:=HostName;
U:=UserName;
P:=Password;
FMySQL:=mysql_connect(FMySQL,PChar(H),PChar(U),Pchar(P));
If (FMySQL=Nil) then
MySQlError(Nil,SErrServerConnectFailed,Self);
FServerInfo := strpas(mysql_get_server_info(FMYSQL));
FHostInfo := strpas(mysql_get_host_info(FMYSQL));
end;
procedure TMySQLDatabase.SelectDatabase;
begin
if mysql_select_db(FMySQL,pchar(DatabaseName))<>0 then
MySQLError(FMySQL,SErrDatabaseSelectFailed,Self);
end;
procedure TMySQLDatabase.DoInternalConnect;
begin
if (FMySQL<>nil) then
DoInternalDisconnect;
ConnectToServer;
SelectDatabase;
end;
procedure TMySQLDatabase.DoInternalDisConnect;
begin
mysql_close(FMySQL);
FMySQL:=Nil;
FServerInfo:='';
FHostInfo:='';
end;
procedure TMySQLDatabase.StartTransaction;
begin
// Nothing yet
end;
procedure TMySQLDatabase.EndTransaction;
begin
// Nothing yet
end;
procedure TMySQLDatabase.CreateDatabase;
Var
Disconnect : Boolean;
begin
Disconnect:=(FMySQL=Nil);
if Disconnect then
ConnectToServer;
try
if mysql_create_db(FMySQL,Pchar(DatabaseName))<>0 then
MySQLError(FMySQL,SErrDatabaseCreate,Self);
Finally
If Disconnect then
DoInternalDisconnect;
end;
end;
procedure TMySQLDatabase.DropDatabase;
Var
Disconnect : Boolean;
begin
Disconnect:=(FMySQL=Nil);
if Disconnect then
ConnectToServer;
If (FMySQL=Nil) then
ConnectToServer;
try
if mysql_drop_db(FMySQL,Pchar(DatabaseName))<>0 then
MySQLError(FMySQL,SErrDatabaseDrop,Self);
Finally
If Disconnect then
DoInternalDisconnect;
end;
end;
function TMySQLDatabase.GetServerStatus: string;
begin
CheckConnected;
Result := mysql_stat(FMYSQL); Result := mysql_stat(FMYSQL);
end; end;
@ -801,7 +915,10 @@ end.
{ {
$Log$ $Log$
Revision 1.3 2002-11-07 14:27:59 sg Revision 1.4 2003-08-16 16:42:21 michael
+ Fixes in TDBDataset etc. Changed MySQLDb to use database as well
Revision 1.3 2002/11/07 14:27:59 sg
* AffectedRows now is a QWord (to match recent MySQL versions) * AffectedRows now is a QWord (to match recent MySQL versions)
* Result strings for enums etc. are now correctly terminated * Result strings for enums etc. are now correctly terminated
* Fixed a memory leak in DoQuery: The query string didn't get released * Fixed a memory leak in DoQuery: The query string didn't get released