{ $Id: PDOResult.pas 23 2007-01-19 22:06:28Z jmarino $

############################################################################################

	Pascal Data Objects Library
	Copyright © 2006 John Marino, http://www.synsport.com
	Project site: http://pdo.sourceforge.net

############################################################################################

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

############################################################################################}

unit PDOResult;

interface

{$I directives.inc}

uses PDOStatement, Classes, PDOCompatibility, SysUtils, PDOUtilsMySQL,
     PDOSysUtils, PDOInterfaces;

type
    TResult = class (TInterfacedObject, IPDOResult)
        private
            FValue:                   Variant;
            FRawString:               AnsiString;
            FNull:                    Boolean;
            function getValue:        Variant; virtual;
            function getNull:         Boolean;
        public
            property value:           Variant READ FValue;
            property null:            Boolean READ FNull;
            function asString:        AnsiString;
            function asUnicodeString: WideString;
            function asPChar:         PChar;
            function asByte:          Byte;
            function asShortInt:      ShortInt;
            function asWord:          Word;
            function asSmallInt:      SmallInt;
            function asLongWord:      LongWord;
            function asCardinal:      Cardinal;
            function asLongInt:       LongInt;
            function asInteger:       Integer;
            function asInt64:         Int64;
            function asSingle:        Single;
            function asDouble:        Double;
            function asExtended:      Extended;
            function asBoolean:       Boolean;
            function asDate:          TDateTime; virtual; abstract;
            function asTime:          TDateTime; virtual; abstract;
            function asTimestamp:     TDateTime; virtual; abstract;
            function asAsciiStream:   TStream;
            function asBytes:         TByteDynArray;
            constructor create (nativeType: TZSQLType; stringRep: Ansistring;
                nullValue: Boolean{; decFormatting: TFormatSettings});
        protected
            property rawString: AnsiString read FRawString;
        end;

implementation

constructor TResult.create(nativeType: TZSQLType; stringRep: Ansistring;
                nullValue: Boolean);
begin
    self.FRawString := stringRep;
    self.FNull := nullValue;
    case nativeType of
        stString:        self.FValue := self.asString;
        stByte:          self.FValue := self.asByte;
        stShort:         self.FValue := self.asSmallInt;
        stLong:          self.FValue := self.asInteger;
        stInteger:       self.FValue := self.asInt64;
        stFloat:         self.FValue := self.asSingle;
        stDouble:        self.FValue := self.asDouble;
        stBigDecimal:    self.FValue := self.asExtended;
        stBoolean:       self.FValue := self.asBoolean;
        stDate:          self.FValue := self.asDate;
        stTime:          self.FValue := self.asTime;
        stTimestamp:     self.FValue := self.asTimestamp;
        stUnicodeString: self.FValue := self.asUnicodeString;
        stBytes:         self.FValue := self.asBytes;
        stAsciiStream:   self.FValue := self.asString;
        stUnicodeStream: self.FValue := self.asUnicodeString;
        stBinaryStream:  self.FValue := self.asBytes;

    else
        {tUnknown}
        self.FValue := 0;
    end;
 end;

function TResult.asBytes: TByteDynArray;
Begin
    Result := StrToBytes(self.FRawString);
End;

function TResult.asAsciiStream: TStream;
Begin
    Result := TStringStream.Create (self.FRawString);
End;

function TResult.asBoolean: Boolean;
var
    full64: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    Result := (full64 <> 0);
End;

function TResult.asExtended: Extended;
Begin
    Result := StrToFloatDef(self.FRawString,0);
End;

function TResult.asDouble: Double;
var
    full64: Extended;
Begin
    full64 := StrToFloatDef(self.FRawString,0);
    Result := full64;       {overflow problem/typecast doesn't work?}
End;

function TResult.asSingle: Single;
var
    full64: Extended;
Begin
    full64 := StrToFloatDef(self.FRawString,0);
    Result := full64;       {overflow problem/typecast doesn't work?}
End;

function TResult.asByte: Byte;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FF;
    Result := Byte(full64 and bitmask);
End;

function TResult.asShortInt: ShortInt;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FF;
    Result := ShortInt(full64 and bitmask);
End;

function TResult.asWord: Word;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FFFF;
    Result := Word(full64 and bitmask);
End;

function TResult.asSmallInt: SmallInt;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FFFF;
    Result := smallInt(full64 and bitmask);
End;

function TResult.asLongWord: LongWord;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FFFFFFFF;
    Result := LongWord(full64 and bitmask);
End;

function TResult.asCardinal: Cardinal;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FFFFFFFF;
    Result := Cardinal(full64 and bitmask);
End;

function TResult.asLongInt: LongInt;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FFFFFFFF;
    Result := LongInt(full64 and bitmask);
End;

function TResult.asInteger: Integer;
var
    full64: Int64;
    bitmask: Int64;
Begin
    full64 := strToInt64Def(self.FRawString, 0);
    bitmask := $FFFFFFFF;
    Result := Integer(full64 and bitmask);
End;

function TResult.asInt64: Int64;
Begin
    Result := strToInt64Def(self.FRawString, 0);
End;

function TResult.asPChar: PChar;
Begin
    Result := PChar(self.FRawString);
End;

function TResult.asUnicodeString: WideString;
Begin
    Result := self.FRawString;
End;

function TResult.asString: AnsiString;
Begin
    Result := self.FRawString;
End;

function TResult.getValue: Variant;
Begin
    Result := self.FValue;
End;

function TResult.getNull: Boolean;
Begin
    Result := self.FNull;
End;

end.