Browse Source

+ Split out in version 3 and 4

michael 21 years ago
parent
commit
42e818fd52
5 changed files with 965 additions and 42 deletions
  1. 3 27
      fcl/db/mysql/Makefile
  2. 1 1
      fcl/db/mysql/Makefile.fpc
  3. 5 2
      fcl/db/mysql/mtest.pp
  4. 941 0
      fcl/db/mysql/mysqldb3.pp
  5. 15 12
      fcl/db/mysql/mysqldb4.pp

+ 3 - 27
fcl/db/mysql/Makefile

@@ -1,8 +1,8 @@
 #
-# Don't edit, this file is generated by FPCMake Version 1.1 [2004/09/04]
+# Don't edit, this file is generated by FPCMake Version 1.1 [2004/08/31]
 #
 default: all
-MAKEFILETARGETS=linux go32v2 win32 os2 freebsd beos netbsd amiga atari sunos qnx netware openbsd wdosx palmos macos darwin emx watcom morphos netwlibc
+MAKEFILETARGETS=linux go32v2 win32 os2 freebsd beos netbsd amiga atari sunos qnx netware openbsd wdosx palmos macos darwin emx watcom morphos
 BSDs = freebsd netbsd openbsd darwin
 UNIXs = linux $(BSDs) sunos qnx
 FORCE:
@@ -214,7 +214,7 @@ UNITSDIR:=$(wildcard $(FPCDIR)/units/$(OS_TARGET))
 endif
 PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages/base $(FPCDIR)/packages/extra)
 override PACKAGE_NAME=fcl
-override TARGET_UNITS+=mysqldb
+override TARGET_UNITS+=mysqldb4 mysqldb3
 override TARGET_RSTS+=mysqldb
 override TARGET_EXAMPLES+=mtest
 override CLEAN_UNITS+=mysql mysql_com mysql_version
@@ -555,12 +555,6 @@ STATICLIBPREFIX=
 FPCMADE=fpcmade.nw
 ZIPSUFFIX=nw
 endif
-ifeq ($(OS_TARGET),netwlibc)
-EXEEXT=.nlm
-STATICLIBPREFIX=
-FPCMADE=fpcmade.nwl
-ZIPSUFFIX=nwl
-endif
 ifeq ($(OS_TARGET),macos)
 BATCHEXT=
 EXEEXT=
@@ -713,18 +707,6 @@ FPCMADE=fpcmade.nw
 ZIPSUFFIX=nw
 EXEEXT=.nlm
 endif
-ifeq ($(OS_TARGET),netwlibc)
-STATICLIBPREFIX=
-PPUEXT=.ppu
-OEXT=.o
-ASMEXT=.s
-SMARTEXT=.sl
-STATICLIBEXT=.a
-SHAREDLIBEXT=.nlm
-FPCMADE=fpcmade.nwl
-ZIPSUFFIX=nwl
-EXEEXT=.nlm
-endif
 ifeq ($(OS_TARGET),macos)
 BATCHEXT=
 PPUEXT=.ppu
@@ -1159,12 +1141,6 @@ REQUIRE_PACKAGES_RTL=1
 REQUIRE_PACKAGES_MYSQL=1
 endif
 endif
-ifeq ($(OS_TARGET),netwlibc)
-ifeq ($(CPU_TARGET),i386)
-REQUIRE_PACKAGES_RTL=1
-REQUIRE_PACKAGES_MYSQL=1
-endif
-endif
 ifdef REQUIRE_PACKAGES_RTL
 PACKAGEDIR_RTL:=$(firstword $(subst /Makefile.fpc,,$(strip $(wildcard $(addsuffix /rtl/$(OS_TARGET)/Makefile.fpc,$(PACKAGESDIR))))))
 ifneq ($(PACKAGEDIR_RTL),)

+ 1 - 1
fcl/db/mysql/Makefile.fpc

@@ -6,7 +6,7 @@
 main=fcl
 
 [target]
-units=mysqldb
+units=mysqldb4 mysqldb3
 rsts=mysqldb
 examples=mtest
 

+ 5 - 2
fcl/db/mysql/mtest.pp

@@ -17,7 +17,7 @@
 {$H+}
 program mtest;
 
-uses db,sysutils,mysqldb;
+uses db,sysutils, mysqldb4; // change to mysqldb3 if you are using version 3.
 
 Procedure Log(Const Msg : String);
 begin
@@ -200,7 +200,10 @@ end.
 
 {
    $Log$
-   Revision 1.3  2003-08-16 16:42:21  michael
+   Revision 1.4  2004-09-30 19:36:00  michael
+   + Split out in version 3 and 4
+
+   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

+ 941 - 0
fcl/db/mysql/mysqldb3.pp

@@ -0,0 +1,941 @@
+unit MySQLDB3;
+
+{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, db, mysql3,mysql3_com;
+
+type
+  PMySQLDatasetBookmark = ^TMySQLDatasetBookmark;
+  TMySQLDatasetBookmark = record
+                          BookmarkData: Integer;
+                          BookmarkFlag: TBookmarkFlag;
+                          end;
+
+  Pinteger = ^Integer;
+
+  TMySQLDatabase = class(TDatabase)
+  Private
+    FMYSQL: PMYSQL;
+    FServerInfo: 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;
+    FLastInsertID: Integer;
+    FLoadingFieldDefs: Boolean;
+
+    procedure DoClose;
+    procedure DoQuery;
+    procedure DoGetResult;
+
+    procedure CalculateSizes;
+    procedure LoadBufferFromData(Buffer: PChar);
+  protected
+    Function FMySQL : PMySQL;
+    procedure SetSQL(const Value: TStrings);
+    function InternalStrToFloat(S: string): Extended;
+    function InternalStrToDate(S: string): TDateTime;
+    function InternalStrToTime(S: string): TDateTime;
+    function InternalStrToDateTime(S: string): TDateTime;
+    function InternalStrToTimeStamp(S: string): TDateTime;
+
+    function MySQLFieldToFieldType(AType: enum_field_types; ASize: Integer;
+         var NewType: TFieldType; var NewSize: Integer): Boolean;
+    function MySQLDataSize(AType: enum_field_types; ASize: Integer): Integer;
+    function MySQLWriteFieldData(AType: enum_field_types; ASize: Integer; Source: PChar;
+       Dest: PChar): Integer;
+
+
+    function GetCanModify: Boolean; override;
+    { Mandatory overrides }
+    // Record buffer methods:
+    function AllocRecordBuffer: PChar; override;
+    procedure FreeRecordBuffer(var Buffer: PChar); override;
+    procedure InternalInitRecord(Buffer: PChar); override;
+    function GetRecord(Buffer: PChar; GetMode: TGetMode; DoCheck: Boolean): TGetResult; override;
+    function GetRecordSize: Word; override;
+    procedure SetFieldData(Field: TField; Buffer: Pointer); override;
+    // Bookmark methods:
+    procedure GetBookmarkData(Buffer: PChar; Data: Pointer); override;
+    function GetBookmarkFlag(Buffer: PChar): TBookmarkFlag; override;
+    procedure InternalGotoBookmark(ABookmark: Pointer); override;
+    procedure InternalSetToRecord(Buffer: PChar); override;
+    procedure SetBookmarkFlag(Buffer: PChar; Value: TBookmarkFlag); override;
+    procedure SetBookmarkData(Buffer: PChar; Data: Pointer); override;
+    // Navigational methods:
+    procedure InternalFirst; override;
+    procedure InternalLast; override;
+    // Editing methods:
+    procedure InternalAddRecord(Buffer: Pointer; DoAppend: Boolean); override;
+    procedure InternalDelete; override;
+    procedure InternalPost; override;
+    // Misc methods:
+    procedure InternalClose; override;
+    procedure InternalHandleException; override;
+    procedure InternalInitFieldDefs; override;
+    procedure InternalOpen; override;
+    function IsCursorOpen: Boolean; override;
+    { Optional overrides }
+    function GetRecordCount: Integer; override;
+    function GetRecNo: Integer; override;
+    procedure SetRecNo(Value: Integer); override;
+  public
+    constructor Create(AOwner: TComponent); override;
+    destructor Destroy; override;
+
+    procedure ExecSQL;
+
+    // TDataset method
+    function GetFieldData(Field: TField; Buffer: Pointer): Boolean; override;
+
+    property AffectedRows: QWord read FAffectedRows;
+    property LastInsertID: Integer read FLastInsertID;
+  published
+    property Active;
+    property Database;  
+    property SQL: TStrings read FSQL write SetSQL;
+    property BeforeOpen;
+    property AfterOpen;
+    property BeforeClose;
+    property AfterClose;
+    property BeforeInsert;
+    property AfterInsert;
+    property BeforeEdit;
+    property AfterEdit;
+    property BeforePost;
+    property AfterPost;
+    property BeforeCancel;
+    property AfterCancel;
+    property BeforeDelete;
+    property AfterDelete;
+    property BeforeScroll;
+    property AfterScroll;
+    property OnDeleteError;
+    property OnEditError;
+  end;
+
+  EMySQLError = Class(Exception);
+
+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 }
+
+constructor TMySQLDataset.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  FSQL := TStringList.Create;
+  FBufferSize := 0;
+  FRecordSize := 0;
+  FCurrentRecord := -1;
+  FLoadingFieldDefs := False;
+  FAffectedRows := 0;
+  FLastInsertID := -1;
+  FMYSQLRES := nil;
+end;
+
+destructor TMySQLDataset.Destroy;
+begin
+  Close;
+  FSQL.Free;
+  inherited destroy;
+end;
+
+function TMySQLDataset.AllocRecordBuffer: PChar;
+begin
+  Result := AllocMem(FBufferSize);
+end;
+
+procedure TMySQLDataset.FreeRecordBuffer(var Buffer: PChar);
+begin
+  If (@Buffer<>nil) then
+    FreeMem(Buffer);
+end;
+
+procedure TMySQLDataset.GetBookmarkData(Buffer: PChar; Data: Pointer);
+begin
+  PInteger(Data)^ := PMySQLDatasetBookmark(Buffer + FRecordSize)^.BookmarkData;
+end;
+
+function TMySQLDataset.GetBookmarkFlag(Buffer: PChar): TBookmarkFlag;
+begin
+  Result:=PMySQLDatasetBookmark(Buffer + FRecordSize)^.BookmarkFlag;
+end;
+
+function TMySQLDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
+
+var
+  I, FC: Integer;
+  fld: TMYSQL_FIELD;
+  CurBuf: PChar;
+  
+begin
+  Result := False;
+  CurBuf := ActiveBuffer;
+  FC := mysql_num_fields(FMYSQLRES);
+  for I := 0 to FC-1 do
+    begin
+    fld := mysql_fetch_field_direct(FMYSQLRES, I);
+    if Field.FieldName = fld.name then
+      begin
+      Move(CurBuf^, PChar(Buffer)^, MySQLDataSize(fld.ftype, fld.length));
+      if Field.DataType in [ftString{, ftWideString}] then
+        begin
+        Result := PChar(buffer)^ <> #0;
+        if Result then
+          // Terminate string (necessary for enum fields)
+          PChar(buffer)[fld.length] := #0;
+        end
+      else
+        Result := True;
+      break;
+      end
+    else
+      Inc(CurBuf, MySQLDataSize(fld.ftype, fld.length));
+    end;
+end;
+
+function TMySQLDataset.GetRecNo: Integer;
+begin
+  UpdateCursorPos;
+  if (FCurrentRecord=-1) and (RecordCount > 0) then
+    Result:=1
+  else
+    Result:=FCurrentRecord+1;
+end;
+
+function TMySQLDataset.GetRecord(Buffer: PChar; GetMode: TGetMode;
+  DoCheck: Boolean): TGetResult;
+begin
+  if RecordCount < 1 then
+    Result := grEOF
+  else
+    begin
+    Result := grOk;
+    case GetMode of
+      gmPrior:
+        if FCurrentRecord <= 0 then
+          begin
+          Result := grBOF;
+          FCurrentRecord := -1;
+          end
+        else
+          Dec(FCurrentRecord);
+      gmCurrent:
+        if (FCurrentRecord<0) or (FCurrentRecord>=RecordCount) then
+          Result := grError;
+      gmNext:
+        if FCurrentRecord>=RecordCount-1 then
+          Result := grEOF
+        else
+          Inc(FCurrentRecord);
+     end;
+     if (Result=grOK) then
+       begin
+       LoadBufferFromData(Buffer);
+       with PMySQLDatasetBookmark(Buffer + FRecordSize)^ do
+         begin
+         BookmarkData := FCurrentRecord;
+         BookmarkFlag := bfCurrent;
+         end;
+       end
+     else
+       if (Result=grError) and (DoCheck) then
+         DatabaseError(SerrNoData,Self);
+     end;
+end;
+
+function TMySQLDataset.GetRecordCount: Integer;
+begin
+  Result:=mysql_num_rows(FMYSQLRES);
+end;
+
+function TMySQLDataset.GetRecordSize: Word;
+begin
+  Result:=FRecordSize;
+end;
+
+procedure TMySQLDataset.InternalAddRecord(Buffer: Pointer; DoAppend: Boolean);
+begin
+
+end;
+
+procedure TMySQLDataset.InternalClose;
+begin
+  FCurrentRecord := -1;
+  DoClose;
+  if DefaultFields then
+    DestroyFields;
+end;
+
+procedure TMySQLDataset.InternalDelete;
+begin
+
+end;
+
+procedure TMySQLDataset.InternalFirst;
+begin
+  FCurrentRecord := -1;
+end;
+
+procedure TMySQLDataset.InternalGotoBookmark(ABookmark: Pointer);
+begin
+  FCurrentRecord := PInteger(ABookmark)^;
+end;
+
+procedure TMySQLDataset.InternalHandleException;
+begin
+  //     Application.HandleException(self);
+end;
+
+procedure TMySQLDataset.InternalInitFieldDefs;
+
+var
+  I, FC: Integer;
+  field: TMYSQL_FIELD;
+  DFT: TFieldType;
+  DFS: Integer;
+  WasClosed: Boolean;
+  
+begin
+  if FLoadingFieldDefs then Exit;
+  FLoadingFieldDefs := True;
+  try
+    WasClosed := not IsCursorOpen;
+    if WasClosed then
+      begin
+      DoQuery;
+      DoGetResult;
+      end;
+    try
+      FieldDefs.Clear;
+      FC := mysql_num_fields(FMYSQLRES);
+      for I := 0 to FC-1 do
+        begin
+        field := mysql_fetch_field_direct(FMYSQLRES, I);
+        if MySQLFieldToFieldType(field.ftype, field.length, DFT, DFS) then
+            TFieldDef.Create(FieldDefs, field.name, DFT, DFS, False, I+1);
+        end;
+    finally
+      if WasClosed then
+        DoClose;
+    end;
+  finally
+    FLoadingFieldDefs := False;
+  end;
+end;
+
+procedure TMySQLDataset.InternalInitRecord(Buffer: PChar);
+begin
+  FillChar(Buffer^, FBufferSize, 0);
+end;
+
+procedure TMySQLDataset.InternalLast;
+begin
+  FCurrentRecord := RecordCount;
+end;
+
+procedure TMySQLDataset.InternalOpen;
+begin
+  CheckDatabase;
+  FMYSQLRES := nil;
+  try
+    DoQuery;
+    DoGetResult;
+    FCurrentRecord := -1;
+    InternalInitFieldDefs;
+    if DefaultFields then
+      CreateFields;
+    CalculateSizes;
+    BindFields(True);
+  except
+    DoClose;
+    raise;
+  end;
+  BookMarkSize:=SizeOf(Longint);
+end;
+
+procedure TMySQLDataset.InternalSetToRecord(Buffer: PChar);
+begin
+  FCurrentRecord := PMySQLDatasetBookmark(Buffer + FRecordSize)^.BookmarkData;
+end;
+
+function TMySQLDataset.IsCursorOpen: Boolean;
+begin
+  Result:=(FMYSQLRES<>nil);
+end;
+
+procedure TMySQLDataset.SetBookmarkData(Buffer: PChar; Data: Pointer);
+begin
+  PMySQLDatasetBookmark(Buffer + FRecordSize)^.BookmarkData := PInteger(Data)^;
+end;
+
+procedure TMySQLDataset.SetBookmarkFlag(Buffer: PChar;
+  Value: TBookmarkFlag);
+begin
+  PMySQLDatasetBookmark(Buffer + FRecordSize)^.BookmarkFlag := Value;
+end;
+
+procedure TMySQLDataset.SetFieldData(Field: TField; Buffer: Pointer);
+begin
+
+end;
+
+procedure TMySQLDataset.SetRecNo(Value: Integer);
+begin
+  if (Value >= 0) and (Value <= RecordCount-1) then
+    begin
+    FCurrentRecord := Value-1;
+    Resync([]);
+    end;
+end;
+
+procedure TMySQLDataset.SetSQL(const Value: TStrings);
+begin
+  FSQL.Assign(Value);
+  FieldDefs.Clear;
+end;
+
+procedure TMySQLDataset.ExecSQL;
+begin
+  try
+    DoQuery;
+  finally
+    DoClose;
+  end;
+end;
+
+
+procedure TMySQLDataset.InternalPost;
+begin
+
+end;
+
+function TMySQLDataset.MySQLFieldToFieldType(AType: enum_field_types; ASize: Integer;
+   var NewType: TFieldType; var NewSize: Integer): Boolean;
+begin
+  Result := True;
+  case AType of
+    FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG,
+    FIELD_TYPE_INT24:
+      begin
+      NewType := ftInteger;
+      NewSize := 0;
+      end;
+    FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
+      begin
+      NewType := ftFloat;
+      NewSize := 0;
+      end;
+    FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATETIME:
+      begin
+      NewType := ftDateTime;
+      NewSize := 0;
+      end;
+    FIELD_TYPE_DATE:
+      begin
+      NewType := ftDate;
+      NewSize := 0;
+      end;
+    FIELD_TYPE_TIME:
+      begin
+      NewType := ftTime;
+      NewSize := 0;
+      end;
+    FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET:
+      begin
+      NewType := ftString;
+      NewSize := ASize;
+      end;
+  else
+    Result := False;
+  end;
+end;
+
+procedure TMySQLDataset.CalculateSizes;
+var
+  I, FC: Integer;
+  field: TMYSQL_FIELD;
+begin
+  FRecordSize := 0;
+  FC := mysql_num_fields(FMYSQLRES);
+  for I := 0 to FC-1 do
+    begin
+    field := mysql_fetch_field_direct(FMYSQLRES, I);
+    FRecordSize := FRecordSize + MySQLDataSize(field.ftype, field.length);
+    end;
+  FBufferSize := FRecordSize + SizeOf(TMySQLDatasetBookmark);
+end;
+
+procedure TMySQLDataset.LoadBufferFromData(Buffer: PChar);
+
+var
+  I, FC, CT: Integer;
+  field: TMYSQL_FIELD;
+  row: TMYSQL_ROW;
+  
+begin
+  mysql_data_seek(FMYSQLRES, FCurrentRecord);
+  row := mysql_fetch_row(FMYSQLRES);
+  if row = nil then
+     MySQLError(FMySQL,SErrFetchingData,Self);
+  FC := mysql_num_fields(FMYSQLRES);
+  for I := 0 to FC-1 do
+    begin
+    field := mysql_fetch_field_direct(FMYSQLRES, I);
+    CT := MySQLWriteFieldData(field.ftype, field.length, row^, Buffer);
+    Inc(Buffer, CT);
+    Inc(row);
+    end;
+end;
+
+
+function TMySQLDataset.MySQLDataSize(AType: enum_field_types;
+  ASize: Integer): Integer;
+begin
+  Result := 0;
+  case AType of
+    FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG,
+    FIELD_TYPE_INT24:
+      begin
+      Result := SizeOf(Integer);
+      end;
+    FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
+      begin
+      Result := SizeOf(Double);
+      end;
+    FIELD_TYPE_TIMESTAMP, FIELD_TYPE_DATE, FIELD_TYPE_TIME, FIELD_TYPE_DATETIME:
+      begin
+      Result := SizeOf(TDateTime);
+      end;
+    FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET:
+      begin
+      Result := ASize;
+      end;
+  end;
+end;
+
+function TMySQLDataset.MySQLWriteFieldData(AType: enum_field_types;
+  ASize: Integer; Source, Dest: PChar): Integer;
+  
+var
+  VI: Integer;
+  VF: Double;
+  VD: TDateTime;
+  
+begin
+  Result := 0;
+  case AType of
+    FIELD_TYPE_TINY, FIELD_TYPE_SHORT, FIELD_TYPE_LONG, FIELD_TYPE_LONGLONG,
+    FIELD_TYPE_INT24:
+      begin
+      Result := SizeOf(Integer);
+      if Source <> '' then
+        VI := StrToInt(Source)
+      else
+        VI := 0;
+      Move(VI, Dest^, Result);
+      end;
+    FIELD_TYPE_DECIMAL, FIELD_TYPE_FLOAT, FIELD_TYPE_DOUBLE:
+      begin
+      Result := SizeOf(Double);
+      if Source <> '' then
+        VF := InternalStrToFloat(Source)
+      else
+        VF := 0;
+      Move(VF, Dest^, Result);
+      end;
+    FIELD_TYPE_TIMESTAMP:
+      begin
+      Result := SizeOf(TDateTime);
+      if Source <> '' then
+        VD := InternalStrToTimeStamp(Source)
+      else
+        VD := 0;
+      Move(VD, Dest^, Result);
+      end;
+    FIELD_TYPE_DATETIME:
+      begin
+      Result := SizeOf(TDateTime);
+      if Source <> '' then
+        VD := InternalStrToDateTime(Source)
+      else
+        VD := 0;
+      Move(VD, Dest^, Result);
+      end;
+    FIELD_TYPE_DATE:
+      begin
+      Result := SizeOf(TDateTime);
+      if Source <> '' then
+        VD := InternalStrToDate(Source)
+      else
+        VD := 0;
+      Move(VD, Dest^, Result);
+      end;
+    FIELD_TYPE_TIME:
+      begin
+      Result := SizeOf(TDateTime);
+      if Source <> '' then
+        VD := InternalStrToTime(Source)
+      else
+        VD := 0;
+      Move(VD, Dest^, Result);
+      end;
+    FIELD_TYPE_VAR_STRING, FIELD_TYPE_STRING, FIELD_TYPE_ENUM, FIELD_TYPE_SET:
+      begin
+      Result := ASize;
+      if Source <> '' then
+        Move(Source^, Dest^, Result)
+      else
+        Dest^ := #0;
+      end;
+  end;
+end;
+
+function TMySQLDataset.InternalStrToFloat(S: string): Extended;
+
+var
+  I: Integer;
+  Tmp: string;
+  
+begin
+  Tmp := '';
+  for I := 1 to Length(S) do
+    begin
+    if not (S[I] in ['0'..'9', '+', '-', 'E', 'e']) then
+      Tmp := Tmp + DecimalSeparator
+    else
+      Tmp := Tmp + S[I];
+    end;
+  Result := StrToFloat(Tmp);
+end;
+
+function TMySQLDataset.InternalStrToDate(S: string): TDateTime;
+
+var
+  EY, EM, ED: Word;
+  
+begin
+  EY := StrToInt(Copy(S,1,4));
+  EM := StrToInt(Copy(S,6,2));
+  ED := StrToInt(Copy(S,9,2));
+  if (EY = 0) or (EM = 0) or (ED = 0) then
+    Result:=0
+  else
+    Result:=EncodeDate(EY, EM, ED);
+end;
+
+function TMySQLDataset.InternalStrToDateTime(S: string): TDateTime;
+
+var
+  EY, EM, ED: Word;
+  EH, EN, ES: Word;
+  
+begin
+  EY := StrToInt(Copy(S, 1, 4));
+  EM := StrToInt(Copy(S, 6, 2));
+  ED := StrToInt(Copy(S, 9, 2));
+  EH := StrToInt(Copy(S, 11, 2));
+  EN := StrToInt(Copy(S, 14, 2));
+  ES := StrToInt(Copy(S, 17, 2));
+  if (EY = 0) or (EM = 0) or (ED = 0) then
+    Result := 0
+  else
+    Result := EncodeDate(EY, EM, ED);
+  Result := Result + EncodeTime(EH, EN, ES, 0);
+end;
+
+function TMySQLDataset.InternalStrToTime(S: string): TDateTime;
+
+var
+  EH, EM, ES: Word;
+
+begin
+  EH := StrToInt(Copy(S, 1, 2));
+  EM := StrToInt(Copy(S, 4, 2));
+  ES := StrToInt(Copy(S, 7, 2));
+  Result := EncodeTime(EH, EM, ES, 0);
+end;
+
+function TMySQLDataset.InternalStrToTimeStamp(S: string): TDateTime;
+
+var
+  EY, EM, ED: Word;
+  EH, EN, ES: Word;
+  
+begin
+  EY := StrToInt(Copy(S, 1, 4));
+  EM := StrToInt(Copy(S, 5, 2));
+  ED := StrToInt(Copy(S, 7, 2));
+  EH := StrToInt(Copy(S, 9, 2));
+  EN := StrToInt(Copy(S, 11, 2));
+  ES := StrToInt(Copy(S, 13, 2));
+  if (EY = 0) or (EM = 0) or (ED = 0) then
+    Result := 0
+  else
+    Result := EncodeDate(EY, EM, ED);
+  Result := Result + EncodeTime(EH, EN, ES, 0);;
+end;
+
+procedure TMySQLDataset.DoClose;
+begin
+  try
+    if FMYSQLRES <> nil then
+       mysql_free_result(FMYSQLRES);
+   finally
+      FMYSQLRES := nil;
+   end;
+end;
+
+procedure TMySQLDataset.DoQuery;
+var
+  Query: PChar;
+  
+begin
+  Query := FSQL.GetText;
+  try
+    if mysql_query(FMySQL,Query) <> 0 then
+      MySQLError(FMYSQL,SErrExecuting,Self);
+  finally
+    StrDispose(Query);
+  end;
+  FAffectedRows := mysql_affected_rows(FMYSQL);
+  FLastInsertID := mysql_insert_id(FMYSQL);
+end;
+
+function TMySQLDataset.GetCanModify: Boolean;
+begin
+  Result := False;
+end;
+
+procedure TMySQLDataset.DoGetResult;
+begin
+  FMYSQLRES := mysql_store_result(FMYSQL);
+  if (FMYSQLRES=nil) then
+     MySQLError(FMYSQL,SErrGettingResult,Self);
+  FAffectedRows := mysql_affected_rows(FMYSQL);
+end;
+
+function TMySQLDataset.FMySQL: PMySQL;
+begin
+  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
+  if (FMySQL=Nil) then
+    New(FMySQL);
+  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);
+end;
+
+end.
+
+
+{
+  $Log$
+  Revision 1.1  2004-09-30 19:36:00  michael
+  + Split out in version 3 and 4
+
+  Revision 1.6  2004/09/29 20:26:48  michael
+  + Adapted to version 4 of mysql
+
+  Revision 1.5  2004/09/20 07:13:38  michael
+  + Database property published
+
+  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)
+  * Result strings for enums etc. are now correctly terminated
+  * Fixed a memory leak in DoQuery: The query string didn't get released
+
+  Revision 1.2  2002/09/07 15:15:23  peter
+    * old logs removed and tabs fixed
+
+}

+ 15 - 12
fcl/db/mysql/mysqldb.pp → fcl/db/mysql/mysqldb4.pp

@@ -1,11 +1,11 @@
-unit MySQLDB;
+unit MySQLDB4;
 
 {$H+}
 
 interface
 
 uses
-  SysUtils, Classes, db, mysql,mysql_com;
+  SysUtils, Classes, db, mysql4,mysql4_com;
 
 type
   PMySQLDatasetBookmark = ^TMySQLDatasetBookmark;
@@ -227,7 +227,7 @@ function TMySQLDataset.GetFieldData(Field: TField; Buffer: Pointer): Boolean;
 
 var
   I, FC: Integer;
-  fld: TMYSQL_FIELD;
+  fld: PMYSQL_FIELD;
   CurBuf: PChar;
   
 begin
@@ -239,7 +239,7 @@ begin
     fld := mysql_fetch_field_direct(FMYSQLRES, I);
     if Field.FieldName = fld^.name then
       begin
-      Move(CurBuf^, PChar(Buffer)^, MySQLDataSize(fld^._type, fld^.length));
+      Move(CurBuf^, PChar(Buffer)^, MySQLDataSize(fld^.ftype, fld^.length));
       if Field.DataType in [ftString{, ftWideString}] then
         begin
         Result := PChar(buffer)^ <> #0;
@@ -252,7 +252,7 @@ begin
       break;
       end
     else
-      Inc(CurBuf, MySQLDataSize(fld^._type, fld^.length));
+      Inc(CurBuf, MySQLDataSize(fld^.ftype, fld^.length));
     end;
 end;
 
@@ -353,7 +353,7 @@ procedure TMySQLDataset.InternalInitFieldDefs;
 
 var
   I, FC: Integer;
-  field: TMYSQL_FIELD;
+  field: PMYSQL_FIELD;
   DFT: TFieldType;
   DFS: Integer;
   WasClosed: Boolean;
@@ -374,7 +374,7 @@ begin
       for I := 0 to FC-1 do
         begin
         field := mysql_fetch_field_direct(FMYSQLRES, I);
-        if MySQLFieldToFieldType(field^._type, field^.length, DFT, DFS) then
+        if MySQLFieldToFieldType(field^.ftype, field^.length, DFT, DFS) then
             TFieldDef.Create(FieldDefs, field^.name, DFT, DFS, False, I+1);
         end;
     finally
@@ -516,14 +516,14 @@ end;
 procedure TMySQLDataset.CalculateSizes;
 var
   I, FC: Integer;
-  field: TMYSQL_FIELD;
+  field: PMYSQL_FIELD;
 begin
   FRecordSize := 0;
   FC := mysql_num_fields(FMYSQLRES);
   for I := 0 to FC-1 do
     begin
     field := mysql_fetch_field_direct(FMYSQLRES, I);
-    FRecordSize := FRecordSize + MySQLDataSize(field^._type, field^.length);
+    FRecordSize := FRecordSize + MySQLDataSize(field^.ftype, field^.length);
     end;
   FBufferSize := FRecordSize + SizeOf(TMySQLDatasetBookmark);
 end;
@@ -532,7 +532,7 @@ procedure TMySQLDataset.LoadBufferFromData(Buffer: PChar);
 
 var
   I, FC, CT: Integer;
-  field: TMYSQL_FIELD;
+  field: PMYSQL_FIELD;
   row: TMYSQL_ROW;
   
 begin
@@ -544,7 +544,7 @@ begin
   for I := 0 to FC-1 do
     begin
     field := mysql_fetch_field_direct(FMYSQLRES, I);
-    CT := MySQLWriteFieldData(field^._type, field^.length, row^, Buffer);
+    CT := MySQLWriteFieldData(field^.ftype, field^.length, row^, Buffer);
     Inc(Buffer, CT);
     Inc(row);
     end;
@@ -921,7 +921,10 @@ end.
 
 {
   $Log$
-  Revision 1.6  2004-09-29 20:26:48  michael
+  Revision 1.1  2004-09-30 19:36:00  michael
+  + Split out in version 3 and 4
+
+  Revision 1.6  2004/09/29 20:26:48  michael
   + Adapted to version 4 of mysql
 
   Revision 1.5  2004/09/20 07:13:38  michael