
//////////////////////////////////////////////////
//  MySQL Data Access Components
//  Copyright © 1998-2014 Devart. All right reserved.
//////////////////////////////////////////////////

{$IFNDEF CLR}
{$I MyDac.inc}
unit MyDataTypeMapUni;
{$ENDIF}

interface

uses
  CRDataTypeMap;

const
  myBase           = 200;

  myBit            = myBase + 1;
  myTiny           = myBase + 2;
  myTinyUnsigned   = myBase + 3;
  mySmall          = myBase + 4;
  mySmallUnsigned  = myBase + 5;
  myMedium         = myBase + 6;
  myMediumUnsigned = myBase + 7;
  myInt            = myBase + 8;
  myIntUnsigned    = myBase + 9;
  myBigint         = myBase + 10;
  myBigintUnsigned = myBase + 11;
  myFloat          = myBase + 12;
  myDouble         = myBase + 13;
  myDecimal        = myBase + 14;
  myDate           = myBase + 15;
  myTime           = myBase + 16;
  myDatetime       = myBase + 17;
  myTimestamp      = myBase + 18;
  myYear           = myBase + 19;
  myChar           = myBase + 20;
  myVarchar        = myBase + 21;
  myBinary         = myBase + 22;
  myVarbinary      = myBase + 23;
  myTinyBlob       = myBase + 24;
  myBlob           = myBase + 25;
  myTinyText       = myBase + 26;
  myText           = myBase + 27;
  myEnum           = myBase + 28;
  mySet            = myBase + 29;

type
  TMyMapRules = class (TCRMapRules)
  public
    class function GetConverterManager: TConverterManager; override;
  end;

  TMyConverterManager = class(TConverterManager)
  public
    constructor Create;

    class function GetDBProvider: Word; override;
    class function GetDBType(SQLType: Word;
      const LengthInBytes, Flags: longword; const CharsetNr: integer): Word;
  end;

implementation

uses
  MemData,
{$IFNDEF UNIDACPRO}
  MyCall;
{$ELSE}
  MyCallUni;
{$ENDIF}

var
  MyConverterManager: TMyConverterManager;

{ Functions }

procedure InitMyTypes;
begin
  DBTypeInfos.Add(myBit,           'Bit',                True,  False);
  DBTypeInfos.Add(myTiny,          'Tinyint',            True,  False);
  DBTypeInfos.Add(myTinyUnsigned,  'Tinyint Unsigned',   True,  False);
  DBTypeInfos.Add(mySmall,         'Smallint',           False, False);
  DBTypeInfos.Add(mySmallUnsigned, 'Smallint Unsigned',  False, False);
  DBTypeInfos.Add(myMedium,        'Mediumint',          False, False);
  DBTypeInfos.Add(myMediumUnsigned,'Mediumint Unsigned', False, False);
  DBTypeInfos.Add(myInt,           'Integer',            False, False);
  DBTypeInfos.Add(myIntUnsigned,   'Integer Unsigned',   False, False);
  DBTypeInfos.Add(myBigint,        'Bigint',             True,  False);
  DBTypeInfos.Add(myBigintUnsigned,'Bigint Unsigned',    True,  False);
  DBTypeInfos.Add(myFloat,         'Float',              False, False);
  DBTypeInfos.Add(myDouble,        'Double',             False, False);
  DBTypeInfos.Add(myDecimal,       'Decimal',            True,  True);
  DBTypeInfos.Add(myDate,          'Date',               False, False);
  DBTypeInfos.Add(myTime,          'Time',               False, False);
  DBTypeInfos.Add(myDatetime,      'Datetime',           False, False);
  DBTypeInfos.Add(myTimestamp,     'Timestamp',          True,  False);
  DBTypeInfos.Add(myYear,          'Year',               True,  False);
  DBTypeInfos.Add(myChar,          'Char',               True,  False);
  DBTypeInfos.Add(myVarchar,       'Varchar',            True,  False);
  DBTypeInfos.Add(myBinary,        'Binary',             True,  False);
  DBTypeInfos.Add(myVarbinary,     'Varbinary',          True,  False);
  DBTypeInfos.Add(myTinyBlob,      'TinyBlob',           False, False);
//DBTypeInfos.Add(myMediumBlob,    'MediumBlob',         False, False);
  DBTypeInfos.Add(myBlob,          'Blob',               False, False);
//DBTypeInfos.Add(myLongBlob,      'LongBlob',           False, False);
  DBTypeInfos.Add(myTinyText,      'TinyText',           False, False);
//DBTypeInfos.Add(myMediumText,    'MediumText',         False, False);
  DBTypeInfos.Add(myText,          'Text',               False, False);
//DBTypeInfos.Add(myLongText,      'LongText',           False, False);
  DBTypeInfos.Add(myEnum,          'Enum',               False, False);
  DBTypeInfos.Add(mySet,           'Set',                False, False);
end;

{ TMyMapRules }

class function TMyMapRules.GetConverterManager: TConverterManager;
begin
  Result := MyConverterManager;
end;

{ TMyConverterManager }

constructor TMyConverterManager.Create;
begin
  inherited;

  AddFetchConverter(myBit,  1,  8, -1, -1, dtBoolean, dtUInt16);
  AddFetchConverter(myBit,  1,  8, -1, -1, dtInt8,    dtUInt16);
  AddFetchConverter(myBit,  1,  8, -1, -1, dtInt16,   dtUInt16);
  AddFetchConverter(myBit,  1,  8, -1, -1, dtUInt16,  dtUInt16);
  AddFetchConverter(myBit,  1,  8, -1, -1, dtInt32,   dtUInt16);
  AddFetchConverter(myBit,  1,  8, -1, -1, dtUInt32,  dtUInt16);
  AddFetchConverter(myBit,  1,  8, -1, -1, dtInt64,   dtUInt16);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtBoolean, dtUInt32);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtInt8,    dtUInt32);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtInt16,   dtUInt32);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtUInt16,  dtUInt32);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtInt32,   dtUInt32);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtUInt32,  dtUInt32);
  AddFetchConverter(myBit,  9, 32, -1, -1, dtInt64,   dtUInt32);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtBoolean, dtInt64);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtInt8,    dtInt64);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtInt16,   dtInt64);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtUInt16,  dtInt64);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtInt32,   dtInt64);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtUInt32,  dtInt64);
  AddFetchConverter(myBit, 33, 64, -1, -1, dtInt64,   dtInt64);

  AddFetchConverter(myTiny, 1,  4, -1, -1, dtBoolean,dtInt8);
  AddFetchConverter(myTiny, 1,  4, -1, -1, dtInt8,   dtInt8);
  AddFetchConverter(myTiny, 1,  4, -1, -1, dtInt16,  dtInt8);
  AddFetchConverter(myTiny, 1,  4, -1, -1, dtUInt16, dtInt8);
  AddFetchConverter(myTiny, 1,  4, -1, -1, dtInt32,  dtInt8);
  AddFetchConverter(myTiny, 1,  4, -1, -1, dtUInt32, dtInt8);
  AddFetchConverter(myTiny, 1,  4, -1, -1, dtInt64,  dtInt8);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtBoolean,dtInt16);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtInt8,   dtInt16);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtInt16,  dtInt16);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtUInt16, dtInt16);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtInt32,  dtInt16);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtUInt32, dtInt16);
  AddFetchConverter(myTiny, 5, -1, -1, -1, dtInt64,  dtInt16);

  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtBoolean,dtUInt8);
  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtInt8,   dtUInt8);
  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtInt16,  dtUInt8);
  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtUInt16, dtUInt8);
  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtInt32,  dtUInt8);
  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtUInt32, dtUInt8);
  AddFetchConverter(myTinyUnsigned, 1,  3, -1, -1, dtInt64,  dtUInt8);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtBoolean,dtUInt16);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtInt8,   dtUInt16);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtInt16,  dtUInt16);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtUInt16, dtUInt16);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtInt32,  dtUInt16);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtUInt32, dtUInt16);
  AddFetchConverter(myTinyUnsigned, 4, -1, -1, -1, dtInt64,  dtUInt16);

  AddFetchConverter(myBigint,  1,  9, -1, -1, dtInt8,  dtInt32);
  AddFetchConverter(myBigint,  1,  9, -1, -1, dtInt16, dtInt32);
  AddFetchConverter(myBigint,  1,  9, -1, -1, dtUInt16,dtInt32);
  AddFetchConverter(myBigint,  1,  9, -1, -1, dtInt32, dtInt32);
  AddFetchConverter(myBigint,  1,  9, -1, -1, dtUInt32,dtInt32);
  AddFetchConverter(myBigint,  1,  9, -1, -1, dtInt64, dtInt32);
  AddFetchConverter(myBigint, 10, 20, -1, -1, dtInt8,  dtInt64);
  AddFetchConverter(myBigint, 10, 20, -1, -1, dtInt16, dtInt64);
  AddFetchConverter(myBigint, 10, 20, -1, -1, dtUInt16,dtInt64);
  AddFetchConverter(myBigint, 10, 20, -1, -1, dtInt32, dtInt64);
  AddFetchConverter(myBigint, 10, 20, -1, -1, dtUInt32,dtInt64);
  AddFetchConverter(myBigint, 10, 20, -1, -1, dtInt64, dtInt64);

  AddFetchConverter(myBigintUnsigned,  1,  9, -1, -1, dtInt8,  dtInt32);
  AddFetchConverter(myBigintUnsigned,  1,  9, -1, -1, dtInt16, dtInt32);
  AddFetchConverter(myBigintUnsigned,  1,  9, -1, -1, dtUInt16,dtInt32);
  AddFetchConverter(myBigintUnsigned,  1,  9, -1, -1, dtInt32, dtInt32);
  AddFetchConverter(myBigintUnsigned,  1,  9, -1, -1, dtUInt32,dtInt32);
  AddFetchConverter(myBigintUnsigned,  1,  9, -1, -1, dtInt64, dtInt32);
  AddFetchConverter(myBigintUnsigned, 10, 20, -1, -1, dtInt8,  dtInt64);
  AddFetchConverter(myBigintUnsigned, 10, 20, -1, -1, dtInt16, dtInt64);
  AddFetchConverter(myBigintUnsigned, 10, 20, -1, -1, dtUInt16,dtInt64);
  AddFetchConverter(myBigintUnsigned, 10, 20, -1, -1, dtInt32, dtInt64);
  AddFetchConverter(myBigintUnsigned, 10, 20, -1, -1, dtUInt32,dtInt64);
  AddFetchConverter(myBigintUnsigned, 10, 20, -1, -1, dtInt64, dtInt64);
{$IFDEF VER6P}
{$IFNDEF FPC}
  AddFetchConverter(myBigintUnsigned, dtFmtBCD);
{$ENDIF}
{$ENDIF}
  AddFetchConverter(myBigintUnsigned, dtString);

  AddFetchConverter(myDecimal,  1,  4, 0, 0, dtInt8,   dtInt16);
  AddFetchConverter(myDecimal,  1,  4, 0, 0, dtInt16,  dtInt16);
  AddFetchConverter(myDecimal,  1,  4, 0, 0, dtUInt16, dtInt16);
  AddFetchConverter(myDecimal,  1,  4, 0, 0, dtInt32,  dtInt16);
  AddFetchConverter(myDecimal,  1,  4, 0, 0, dtUInt32, dtInt16);
  AddFetchConverter(myDecimal,  1,  4, 0, 0, dtInt64,  dtInt16);
  AddFetchConverter(myDecimal,  5,  9, 0, 0, dtInt8,   dtInt32);
  AddFetchConverter(myDecimal,  5,  9, 0, 0, dtInt16,  dtInt32);
  AddFetchConverter(myDecimal,  5,  9, 0, 0, dtUInt16, dtInt32);
  AddFetchConverter(myDecimal,  5,  9, 0, 0, dtInt32,  dtInt32);
  AddFetchConverter(myDecimal,  5,  9, 0, 0, dtUInt32, dtInt32);
  AddFetchConverter(myDecimal,  5,  9, 0, 0, dtInt64,  dtInt32);
  AddFetchConverter(myDecimal, 10, -1, 0, 0, dtInt8,   dtInt64);
  AddFetchConverter(myDecimal, 10, -1, 0, 0, dtInt16,  dtInt64);
  AddFetchConverter(myDecimal, 10, -1, 0, 0, dtUInt16, dtInt64);
  AddFetchConverter(myDecimal, 10, -1, 0, 0, dtInt32,  dtInt64);
  AddFetchConverter(myDecimal, 10, -1, 0, 0, dtUInt32, dtInt64);
  AddFetchConverter(myDecimal, 10, -1, 0, 0, dtInt64,  dtInt64);

  AddFetchConverter(myDecimal, dtString);
  AddFetchConverter(myDecimal, dtFloat);
  AddFetchConverter(myDecimal, dtBCD);
{$IFDEF VER6P}
{$IFNDEF FPC}
  AddFetchConverter(myDecimal, dtFmtBCD);
{$ENDIF}
{$ENDIF}

  AddFetchConverter(myChar, dtBytes, dtString);
  AddFetchConverter(myChar, dtVarBytes, dtString);
  AddFetchConverter(myChar, dtString);
  AddFetchConverter(myChar, dtWideString);

  AddFetchConverter(myVarchar, dtBytes, dtString);
  AddFetchConverter(myVarchar, dtVarBytes, dtString);
  AddFetchConverter(myVarchar, dtString);
  AddFetchConverter(myVarchar, dtWideString);

  AddFetchConverter(myBinary, dtBytes);
  AddFetchConverter(myBinary, dtVarBytes);
  AddFetchConverter(myBinary, dtString);
  AddFetchConverter(myBinary, dtWideString);

  AddFetchConverter(myVarbinary, dtBytes);
  AddFetchConverter(myVarbinary, dtVarBytes);
  AddFetchConverter(myVarbinary, dtString);
  AddFetchConverter(myVarbinary, dtWideString);

  AddFetchConverter(myEnum, dtString);
  AddFetchConverter(myEnum, dtWideString);

  AddFetchConverter(mySet, dtString);
  AddFetchConverter(mySet, dtWideString);

  AddFetchConverter(myTinyBlob, dtMemo);
  AddFetchConverter(myTinyBlob, dtWideMemo);
  AddFetchConverter(myTinyBlob, dtString,     dtMemo);
  AddFetchConverter(myTinyBlob, dtWideString, dtWideMemo);

  AddFetchConverter(myBlob, dtMemo);
  AddFetchConverter(myBlob, dtWideMemo);
  AddFetchConverter(myBlob, dtString,     dtMemo);
  AddFetchConverter(myBlob, dtWideString, dtWideMemo);

  AddFetchConverter(myTinyText, dtMemo);
  AddFetchConverter(myTinyText, dtWideMemo);
  AddFetchConverter(myTinyText, dtString,     dtMemo);
  AddFetchConverter(myTinyText, dtWideString, dtWideMemo);

  AddFetchConverter(myText, dtMemo);
  AddFetchConverter(myText, dtWideMemo);
  AddFetchConverter(myText, dtString,     dtMemo);
  AddFetchConverter(myText, dtWideString, dtWideMemo);
end;

class function TMyConverterManager.GetDBProvider: Word;
begin
  Result := myBase;
end;

class function TMyConverterManager.GetDBType(SQLType: Word;
  const LengthInBytes, Flags: longword; const CharsetNr: integer): Word;

  function IsFlagSetted(const Flag: longword): boolean;
  begin
    Result := (Flags and Flag) <> 0;
  end;

begin
  case SQLType of // Must be sync with TCustomMyDataSet.SetNumberRange
    FIELD_TYPE_DECIMAL, FIELD_TYPE_NEWDECIMAL:
      Result := myDecimal;
    FIELD_TYPE_BIT:
      Result := myBit;
    FIELD_TYPE_TINY:
      if IsFlagSetted(UNSIGNED_FLAG) then
        Result := myTinyUnsigned
      else
        Result := myTiny;
    FIELD_TYPE_SHORT:
      if IsFlagSetted(UNSIGNED_FLAG) then
        Result := mySmallUnsigned
      else
        Result := mySmall;
    FIELD_TYPE_INT24:
      if IsFlagSetted(UNSIGNED_FLAG) then
        Result := myMediumUnsigned
      else
        Result := myMedium;
    FIELD_TYPE_LONG:
      if IsFlagSetted(UNSIGNED_FLAG) then
        Result := myIntUnsigned
      else
        Result := myInt;
    FIELD_TYPE_LONGLONG:
      if IsFlagSetted(UNSIGNED_FLAG) then
        Result := myBigintUnsigned
      else
        Result := myBigint;

    FIELD_TYPE_FLOAT:
      Result := myFloat;
    FIELD_TYPE_DOUBLE:
      Result := myDouble;
    FIELD_TYPE_TIMESTAMP:
      Result := myTimestamp;
    FIELD_TYPE_DATE, FIELD_TYPE_NEWDATE:
      Result := myDate;
    FIELD_TYPE_TIME:
      Result := myTime;
    FIELD_TYPE_DATETIME:
      Result := myDateTime;
    FIELD_TYPE_YEAR:
      Result := myYear;

    FIELD_TYPE_VAR_STRING, FIELD_TYPE_VARCHAR:
      if IsFlagSetted(BINARY_FLAG) and (CharsetNr = 63) then
        Result := myVarbinary
      else
        Result := myVarchar;
    FIELD_TYPE_STRING: begin
      if IsFlagSetted(BINARY_FLAG) and (CharsetNr = 63) then
        Result := myBinary
      else
      if IsFlagSetted(ENUM_FLAG) then
        Result := myEnum
      else
      if IsFlagSetted(SET_FLAG) then
        Result := mySet
      else
        Result := myChar;
    end;

    FIELD_TYPE_NULL:
      Result := myVarchar;
    FIELD_TYPE_ENUM:
      Result := myEnum;
    FIELD_TYPE_SET:
      Result := mySet;

    FIELD_TYPE_TINY_BLOB:
      if IsFlagSetted(BINARY_FLAG) then
        Result := myTinyBlob
      else
        Result := myTinyText;
{    FIELD_TYPE_MEDIUM_BLOB:
      if IsFlagSetted(BINARY_FLAG) then
        Result := myMediumBlob
      else
        Result := myMediumText;
    FIELD_TYPE_LONG_BLOB:
      if IsFlagSetted(BINARY_FLAG) then
        Result := myLongBlob
      else
        Result := myLongText; }
    FIELD_TYPE_GEOMETRY,
    FIELD_TYPE_MEDIUM_BLOB,
    FIELD_TYPE_LONG_BLOB,
    FIELD_TYPE_BLOB: begin
      if LengthInBytes <= 255 then begin
        if IsFlagSetted(BINARY_FLAG) then
          Result := myTinyBlob
        else
          Result := myTinyText;
      end
      else
        if IsFlagSetted(BINARY_FLAG) then
          Result := myBlob
        else
          Result := myText;
    end;
  else
    Result := 0;
  end;
end;

initialization
  InitMyTypes;
  MyConverterManager := TMyConverterManager.Create;

finalization
  MyConverterManager.Free;

end.
