
//////////////////////////////////////////////////
//  InterBase Data Access Components
//  Copyright © 2006-2014 Devart. All right reserved.
//////////////////////////////////////////////////

{$IFNDEF CLR}
{$I IbDac.inc}
unit IBCDataTypeMapUni;
{$ENDIF}

interface

uses
  DB, CRDataTypeMap,
{$IFNDEF UNIDACPRO}
  IBCCall;
{$ELSE}
  IBCCallUni;
{$ENDIF}

const
  ibcBase       = 400;

  ibcBoolean    = ibcBase + 1;
  ibcSmallint   = ibcBase + 2;
  ibcInteger    = ibcBase + 3;
  ibcBigint     = ibcBase + 4;
  ibcFloat      = ibcBase + 5;
  ibcDouble     = ibcBase + 6;
  ibcDecimal    = ibcBase + 7;
  ibcNumeric    = ibcBase + 8;
  ibcDate       = ibcBase + 9;
  ibcTime       = ibcBase + 10;
  ibcTimestamp  = ibcBase + 11;
  ibcChar       = ibcBase + 12;
  ibcVarchar    = ibcBase + 13;
  ibcCharBin    = ibcBase + 14;
  ibcVarcharBin = ibcBase + 15;
  ibcBlob       = ibcBase + 16;
  ibcText       = ibcBase + 17;

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

  TIBCConverterManager = class(TConverterManager)
  public
    constructor Create;

    class function GetDBProvider: Word; override;
    class function GetDBType(SQLType: Word; const SQLSubType: integer): Word;
  end;

implementation

uses
  MemData,
{$IFNDEF UNIDACPRO}
  IBCClasses;
{$ELSE}
  IBCClassesUni;
{$ENDIF}

var
  IBCConverterManager: TIBCConverterManager;

{$IFDEF VER6P}
{$IFNDEF FPC}
  {$DEFINE _FMTBCD_}
{$ENDIF}
{$ENDIF}

{ Functions }

procedure InitIBCTypes;
begin
  DBTypeInfos.Add(ibcBoolean,   'Boolean',    False, False);
  DBTypeInfos.Add(ibcSmallint,  'Smallint',   False, False);
  DBTypeInfos.Add(ibcInteger,   'Integer',    False, False);
  DBTypeInfos.Add(ibcBigint,    'Bigint',     False, False);
  DBTypeInfos.Add(ibcFloat,     'Float',      False, False);
  DBTypeInfos.Add(ibcDouble,    'Double',     False, False);
  DBTypeInfos.Add(ibcDecimal,   'Decimal',    True,  True);
  DBTypeInfos.Add(ibcNumeric,   'Numeric',    True,  True);
  DBTypeInfos.Add(ibcDate,      'Date',       False, False);
  DBTypeInfos.Add(ibcTime,      'Time',       False, False);
  DBTypeInfos.Add(ibcTimestamp, 'Timestamp',  False, False);
  DBTypeInfos.Add(ibcChar,      'Char',       True,  False);
  DBTypeInfos.Add(ibcVarchar,   'Varchar',    True,  False);
  DBTypeInfos.Add(ibcCharBin,   'Binary',    True,  False);
  DBTypeInfos.Add(ibcVarcharBin,'Varbinary', True,  False);
  DBTypeInfos.Add(ibcBlob,      'Blob',       False, False);
  DBTypeInfos.Add(ibcText,      'Text',       False, False);
end;

{ TIBCMapRules }

class function TIBCMapRules.GetConverterManager: TConverterManager;
begin
  Result := IBCConverterManager;
end;

{ TIBCConverterManager }

constructor TIBCConverterManager.Create;
begin
  inherited;

{$IFDEF _FMTBCD_}
  AddFetchConverter(ibcDecimal, -1, -1, -1, -1, dtFloat);
  AddFetchConverter(ibcDecimal, -1, -1, -1, -1, dtBCD, dtFloat);
  AddFetchConverter(ibcDecimal, -1, -1, -1, -1, dtFmtBCD);

  AddFetchConverter(ibcNumeric, -1, -1, -1, -1, dtFloat);
  AddFetchConverter(ibcNumeric, -1, -1, -1, -1, dtBCD, dtFloat);
  AddFetchConverter(ibcNumeric, -1, -1, -1, -1, dtFmtBCD);
{$ELSE}
  AddFetchConverter(ibcDecimal, -1, -1, -1, -1, dtFloat);
  AddFetchConverter(ibcDecimal, -1, -1, -1, -1, dtBCD, dtFloat);

  AddFetchConverter(ibcNumeric, -1, -1, -1, -1, dtFloat);
  AddFetchConverter(ibcNumeric, -1, -1, -1, -1, dtBCD, dtFloat);
{$ENDIF}

  AddFetchConverter(ibcChar, dtString);
  AddFetchConverter(ibcChar, dtWideString);

  AddFetchConverter(ibcVarchar, dtString);
  AddFetchConverter(ibcVarchar, dtWideString);

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

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

class function TIBCConverterManager.GetDBProvider: Word;
begin
  Result := ibcBase;
end;

class function TIBCConverterManager.GetDBType(SQLType: Word;
  const SQLSubType: integer): Word;
begin
  case SQLType of
    SQL_BOOLEAN:
      Result := ibcBoolean;
    SQL_SHORT:
      case SQLSubType of
        0: Result := ibcSmallint;
        1: Result := ibcNumeric;
        2: Result := ibcDecimal;
      else
        Result := 0;
      end;
    SQL_LONG:
      case SQLSubType of
        0: Result := ibcInteger;
        1: Result := ibcNumeric;
        2: Result := ibcDecimal;
      else
        Result := 0;
      end;
    SQL_INT64:
      case SQLSubType of
        0: Result := ibcBigint;
        1: Result := ibcNumeric;
        2: Result := ibcDecimal;
      else
        Result := 0;
      end;
    SQL_FLOAT:
      Result := ibcFloat;
    SQL_DOUBLE:
      Result := ibcDouble;
    SQL_TYPE_DATE:
      Result := ibcDate;
    SQL_TYPE_TIME:
      Result := ibcTime;
    SQL_TIMESTAMP:
      Result := ibcTimestamp;
    SQL_TEXT:
      if SQLSubType = CH_OCTETS then
        Result := ibcCharBin
      else
        Result := ibcChar;
    SQL_VARYING:
      if SQLSubType = CH_OCTETS then
        Result := ibcVarcharBin
      else
        Result := ibcVarchar;
    SQL_QUAD, SQL_BLOB:
      if SQLSubType = isc_blob_text then
        Result := ibcText
      else
        Result := ibcBlob;
  else
    Result := 0;
  end;
end;

initialization
  InitIBCTypes;
  IBCConverterManager := TIBCConverterManager.Create;

finalization
  IBCConverterManager.Free;

end.
