zoukankan      html  css  js  c++  java
  • adoquery.parameters流化

    unit WebAdoStream;

    {****************************************************************

            单元名称:WebAdoStream.pas

            创建日期:2009-10-01

            创建者    本模块改编于 New Midas VCL Library(1.00)JxStream.pas

            功能:     

            当前版本:

            Emaildcopyboy@tom.com

            QQ:445235526

     

    ***************************************************************}

    interface

     

    uses Windows, Classes, SysUtils, SqlTimSt, FMTBcd, Variants, db, adodb;

     

    type

      // 存贮版本错误.

      EPersistVersion = class(Exception);

      EPersistError = class(Exception);

      EClassNotFound = class(EPersistError);

      EWriterError = class(EPersistError);

      EReaderError = class(EPersistError);

      // Unicode编码类型.

      TStrTransferFormat = (tfUtf16LE, tfUtf16BE, tfUtf8);

      // 数据写入(以小端格式写入)

      TWAStreamWriter = class

      private

        FStream: TStream;

        FTransferFormat: TStrTransferFormat; // 未用

        procedure Write7BitEncodedInt(value: LongInt);

        // 写入shortstring. 适用于写入ClassName, 因为这些属性以

        // ShortString存在, 如果转换为String再写入, 则多了构造

        // String的步骤, 速度较慢

        procedure WriteShortString(const value: ShortString);

      public

        property Stream: TStream read FStream write FStream;

        property TransferFormat: TStrTransferFormat read FTransferFormat write FTransferFormat;

        procedure WriteBuffer(const Buffer; Count: Longint);

        procedure WriteShortInt(value: ShortInt);

        procedure WriteSmallInt(value: SmallInt);

        procedure WriteLongInt(value: LongInt);

        procedure WriteInt64(value: Int64);

        procedure WriteByte(value: Byte);

        procedure WriteWord(value: Word);

        procedure WriteLongWord(value: LongWord);

        procedure WriteCurrency(value: Currency);

        procedure WriteSingle(value: Single);

        procedure WriteDouble(value: Double);

        procedure WriteBool(value: Boolean);

        procedure WriteDateTime(value: TDateTime);

        procedure WriteAscii(value: string);

        procedure WriteString(value: string);

        procedure WriteOleString(value: WideString);

        procedure WriteBinary(const Buffer; Size: Integer);

        procedure WriteTimeStamp(const ATimeStamp: TSqlTimeStamp);

        procedure WriteFMTBcd(const ABcd: TBcd);

        procedure WriteVariant(const V: Variant);

        procedure WriteObjectProps(Obj: TPersistent);

      end;

     

      // 数据读取(以小端读取)

      TWAStreamReader = class

      private

        FStream: TStream;

        FTransferFormat: TStrTransferFormat;

        function Read7BitEncodedInt: LongInt;

        function ReadShortString: string;

      public

        property Stream: TStream read FStream write FStream;

        property TransferFormat: TStrTransferFormat read FTransferFormat write FTransferFormat;

        procedure ReadBuffer(var Buffer; Count: Longint);

        function ReadShortInt: ShortInt;

        function ReadSmallInt: SmallInt;

        function ReadLongInt: LongInt;

        function ReadInt64: Int64;

        function ReadByte: Byte;

        function ReadWord: Word;

        function ReadLongWord: LongWord;

        function ReadCurrency: Currency;

        function ReadSingle: Single;

        function ReadDouble: Double;

        function ReadBool: Boolean;

        function ReadDateTime: TDateTime;

        // 读取ASCII字符串, 长度<=255, 多则截断.

        function ReadAscii(len: Byte): string;

        function ReadString: string;

        function ReadOleString: WideString;

        function ReadBinary: string;

        function ReadStream: TStream;

        procedure ReadTimeStamp(var ATimeStamp: TSqlTimeStamp);

        procedure ReadFMTBcd(var ABcd: TBcd);

        function ReadVariant: Variant;

        procedure ReadObjectProps(Obj: TPersistent);

      end;

    function AdoQuerySaveTostream(Adoq: Tadoquery): TMemoryStream;

    function AdoQueryLoadFromstream(Adoq: Tadoquery; Stream: TMemoryStream): boolean;

     

    implementation

    uses TypInfo;

     

    resourcestring

      SInvalidVariantType = '无效的Variant类型 %d';

      SClassNotFound = 'class %s not found.';

      SWriterError = 'Stream write error.';

      SReaderError = 'Stream read error.';

      SPersistClassError = 'Persistable class not supported.';

      SPersistTypeNotSupported = 'Type %s not supported';

     

    type

      PIntArray = ^TIntArray;

      TIntArray = array[0..0] of Integer;

     

    const

      SimpleArrayTypes = [varSmallInt, varInteger, varSingle, varDouble, varCurrency,

        varDate, varBoolean, varShortInt, varByte, varWord, varLongWord];

     

      VariantSize: array[0..varLongWord] of Word = (0, 0, SizeOf(SmallInt), SizeOf(Integer),

        SizeOf(Single), SizeOf(Double), SizeOf(Currency), SizeOf(TDateTime), 0, 0,

        SizeOf(Integer), SizeOf(WordBool), 0, 0, 0, 0, SizeOf(ShortInt), SizeOf(Byte),

        SizeOf(Word), SizeOf(LongWord));

     

      CMinVarType = $100;

      StreamFMTBcdID = CMinVarType + 1;

      StreamSQLTimeStampID = CMinVarType + 2;

     

     

    { TWAStreamWriter }

     

    procedure TWAStreamWriter.Write7BitEncodedInt(value: Integer);

    begin

      while value > $80 do

      begin

        WriteByte(Byte(value or $80));

        value := value shr 7;

      end;

      WriteByte(value and $FF);

    end;

     

    procedure TWAStreamWriter.WriteAscii(value: string);

    var

      len: Integer;

    begin

      len := Length(value);

      if len > 255 then

        len := 255;

      if len > 0 then WriteBuffer(PChar(value)^, len);

    end;

     

    procedure TWAStreamWriter.WriteBinary(const Buffer; Size: Integer);

    begin

      Write7BitEncodedInt(Size);

      WriteBuffer(Buffer, Size);

    end;

     

    procedure TWAStreamWriter.WriteBool(value: Boolean);

    begin

      if value then

        WriteByte(1)

      else

        WriteByte(0);

    end;

     

    procedure TWAStreamWriter.WriteBuffer(const Buffer; Count: Integer);

    begin

      if (Count <> 0) and (Stream.Write(Buffer, Count) <> Count) then

        raise EWriterError.Create(SWriterError);

    end;

     

    procedure TWAStreamWriter.WriteByte(value: Byte);

    begin

      WriteBuffer(value, 1);

    end;

     

    procedure TWAStreamWriter.WriteCurrency(value: Currency);

    begin

    //  h2n_Data8(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteDateTime(value: TDateTime);

    begin

    //  h2n_Data8(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteDouble(value: Double);

    begin

    //  h2n_Data8(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteFMTBcd(const ABcd: TBcd);

    begin

      with ABcd do

      begin

        WriteByte(Precision);

        WriteByte(SignSpecialPlaces);

        WriteBuffer(Fraction, SizeOf(Fraction));

      end;

    end;

     

    procedure TWAStreamWriter.WriteInt64(value: Int64);

    begin

    //  h2n_Data8(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteLongInt(value: Integer);

    begin

    //  h2n_Data4(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteLongWord(value: LongWord);

    begin

    //  h2n_Data4(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteObjectProps(Obj: TPersistent);

      procedure WriteCollection(Coll: TCollection);

      var

        I: Integer;

      begin

        WriteObjectProps(Coll);

        WriteLongInt(Coll.Count);

        for I := 0 to Coll.Count - 1 do

          WriteObjectProps(Coll.Items[I]);

      end;

     

    var

      TypData: PTypeData;

      PropCount, I, OrdVal: Integer;

      Int64Val: Int64;

      DblVal: Double;

      StrVal: string;

      ObjVal: TObject;

      WVal: WideString;

      VarVal: Variant;

      Props: PPropList;

      PropInfo: PPropInfo;

    begin

      TypData := GetTypeData(Obj.ClassInfo);

      if TypData <> nil then

      begin

        PropCount := TypData.PropCount;

        if PropCount > 0 then

        begin

          GetMem(Props, PropCount * SizeOf(PPropInfo));

          try

            PropCount := GetPropList(PTypeInfo(Obj.ClassInfo), tkProperties, Props);

     

            for I := 0 to PropCount - 1 do

            begin

              PropInfo := Props^[I];

              with PropInfo^ do

              begin

                case PropType^.Kind of

                  tkInteger:

                    begin

                      OrdVal := GetOrdProp(Obj, PropInfo);

                      WriteLongInt(OrdVal);

    //                  case GetTypeData(PropType^).OrdType of

    //                    otSByte, otUByte: WriteByte(OrdVal);

    //                    otSWord, otUWord: WriteWord(OrdVal);

    //                    otSLong, otULong: WriteLongInt(OrdVal);

    //                  end;

                    end;

     

                  tkInt64:

                    begin

                      Int64Val := GetInt64Prop(Obj, PropInfo);

                      WriteInt64(Int64Val);

                    end;

     

                  tkEnumeration:

                    begin

                      OrdVal := GetOrdProp(Obj, PropInfo);

                      WriteByte(OrdVal);

                    end;

     

                  tkFloat:

                    begin

                      DblVal := GetFloatProp(Obj, PropInfo);

                      WriteDouble(DblVal);

                    end;

     

                  tkLString,

                    tkString:

                    begin

                      StrVal := GetStrProp(Obj, PropInfo);

                      WriteString(StrVal);

                    end;

     

                  tkWString:

                    begin

                      WVal := GetWideStrProp(Obj, PropInfo);

                      WriteOleString(WVal);

                    end;

     

                  tkClass:

                    begin

                      ObjVal := GetObjectProp(Obj, PropInfo);

                      if ObjVal is TStrings then

                        WriteString(TStrings(ObjVal).CommaText)

                      else if ObjVal is TCollection then

                        WriteCollection(TCollection(ObjVal))

                      else if ObjVal is TPersistent then

                        WriteObjectProps(TPersistent(ObjVal))

                      else

                        raise EPersistError.Create(SPersistClassError);

                    end;

     

                  tkSet:

                    begin

                      OrdVal := GetOrdProp(Obj, PropInfo);

                      WriteLongInt(OrdVal);

                    end;

     

                  tkChar:

                    begin

                      OrdVal := GetOrdProp(Obj, PropInfo);

                      WriteByte(OrdVal);

                    end;

     

                  tkWChar:

                    begin

                      OrdVal := GetOrdProp(Obj, PropInfo);

                      WriteSmallInt(OrdVal);

                    end;

     

                  tkVariant:

                    begin

                      VarVal := TypInfo.GetVariantProp(Obj, PropInfo);

                      WriteVariant(VarVal);

                    end;

     

                  tkDynArray:

                    begin

                      TypData := GetTypeData(PropInfo.PropType^);

                      assert(TypData <> nil);

                    end;

                else

                  raise EPersistError.CreateFmt(SPersistTypeNotSupported,

                    [GetEnumName(TypeInfo(TTypeKind), Ord(PropInfo.PropType^.Kind))]);

                    {

                    tkArray,

                    tkRecord,

                    tkMethod,

                    tkInterface,

                    tkDynArray

                    }

                end; // case

              end; // with

            end; // for

          finally

            FreeMem(Props, PropCount * SizeOf(PPropInfo));

          end;

        end;

      end;

    end;

     

    procedure TWAStreamWriter.WriteOleString(value: WideString);

    var

      S: string;

      len: Integer;

    begin

      S := Utf8Encode(value);

      len := Length(S);

      Write7BitEncodedInt(len);

      if len > 0 then

        WriteBuffer(PChar(S)^, len);

    end;

     

    procedure TWAStreamWriter.WriteShortInt(value: ShortInt);

    begin

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteShortString(const value: ShortString);

    begin

      WriteByte(Length(value));

      WriteBuffer(value[1], Length(value));

    end;

     

    procedure TWAStreamWriter.WriteSingle(value: Single);

    begin

    //  h2n_Data4(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteSmallInt(value: SmallInt);

    begin

    //  value := Word(h2n_Word(Word(value)));

      WriteBuffer(value, SizeOf(value));

    end;

     

    procedure TWAStreamWriter.WriteString(value: string);

    var

      S: string;

      len: Integer;

    begin

      S := AnsiToUtf8(value);

      len := Length(S);

      Write7BitEncodedInt(len);

      if len > 0 then

        WriteBuffer(PChar(S)^, len);

    end;

     

    procedure TWAStreamWriter.WriteTimeStamp(const ATimeStamp: TSqlTimeStamp);

    begin

      with ATimeStamp do

      begin

        WriteSmallInt(Year);

        WriteWord(Month);

        WriteWord(Day);

        WriteWord(Hour);

        WriteWord(Minute);

        WriteWord(Second);

        WriteLongWord(Fractions);

      end;

    end;

     

    procedure TWAStreamWriter.WriteVariant(const V: Variant);

     

      procedure WriteArray(const V: Variant);

      var

        VType: Word;

        VSize, DimCount, I, ElemSize: Integer;

        LoDim, HiDim: PIntArray;

        Indices: array of Integer;

        P: Pointer;

        V2: Variant;

      begin

        VType := VarType(V) and varTypeMask;

        DimCount := VarArrayDimCount(V);

        VSize := SizeOf(Integer) * DimCount;

        GetMem(LoDim, VSize);

        GetMem(HiDim, VSize);

        try

          for I := 1 to DimCount do

          begin

            LoDim[I - 1] := VarArrayLowBound(V, I);

            HiDim[I - 1] := VarArrayHighBound(V, I);

          end;

          WriteWord(VType or varArray);

          WriteWord(DimCount);

          WriteBuffer(LoDim^, VSize);

          WriteBuffer(HiDim^, VSize);

     

          if VType in SimpleArrayTypes then

          begin

            ElemSize := VariantSize[VType];

            Assert(ElemSize <> 0);

            VSize := 1;

            for I := 0 to DimCount - 1 do

              VSize := (HiDim[I] - LoDim[I] + 1) * VSize;

            VSize := VSize * ElemSize;

            P := VarArrayLock(V);

            try

              WriteLongInt(VSize);

              WriteBuffer(P^, VSize);

            finally

              VarArrayUnlock(V);

            end;

          end

          else

          begin

            SetLength(Indices, DimCount);

     

            for I := 0 to DimCount - 1 do

              Indices[I] := LoDim[I];

     

            while True do

            begin

              V2 := VarArrayGet(V, Indices);

              WriteVariant(V2);

              Inc(Indices[DimCount - 1]);

              if Indices[DimCount - 1] > HiDim[DimCount - 1] then

                for i := DimCount - 1 downto 0 do

                  if Indices[i] > HiDim[i] then

                  begin

                    if i = 0 then Exit;

                    Inc(Indices[i - 1]);

                    Indices[i] := LoDim[i];

                  end;

            end;

          end;

        finally

          FreeMem(LoDim);

          FreeMem(HiDim);

        end;

      end;

     

    var

      VType: Word;

      W: WideString;

    begin

      VType := VarType(V);

      if (VType and varArray) <> 0 then

        WriteArray(V)

      else

        case VType and varTypeMask of

          varEmpty, varNull:

            begin

              WriteWord(VType);

            end;

          varString:

            begin

              WriteWord(VType and varTypeMask);

              WriteString(V);

            end;

          varOleStr:

            begin

              WriteWord(VType and varTypeMask);

              W := V;

              WriteOleString(W);

            end;

          varVariant:

            begin

              if VType and varByRef <> varByRef then

                raise EWriteError.CreateFmt(SInvalidVariantType, [VType]);

              WriteVariant(Variant(TVarData(V).VPointer^));

            end;

        else begin

            if VarIsFMTBcd(V) then

            begin

              WriteWord(StreamFMTBcdID);

              WriteFMTBcd(VarToBcd(V));

            end

            else if VarIsSQLTimeStamp(V) then

            begin

              WriteWord(StreamSQLTimeStampID);

              WriteTimeStamp(VarToSQLTimeStamp(V));

            end

            else begin

              WriteWord(VType and varTypeMask);

              case VType and varTypeMask of

                varSmallint: WriteSmallInt(V);

                varInteger: WriteLongInt(V);

                varSingle: WriteSingle(V);

                varDouble: WriteDouble(V);

                varCurrency: WriteCurrency(V);

                varDate: WriteDateTime(V);

                varError: WriteLongInt(V);

                varBoolean: WriteBool(V);

                varShortInt: WriteShortInt(V);

                varByte: WriteByte(V);

                varWord: WriteWord(V);

                varLongWord: WriteLongWord(V);

                varInt64: WriteInt64(V);

              else

                raise EWriteError.CreateFmt(SInvalidVariantType, [VType]);

              end;

            end;

          end;

        end;

    end;

     

    procedure TWAStreamWriter.WriteWord(value: Word);

    begin

    //  value := h2n_Word(value);

      WriteBuffer(value, SizeOf(value));

    end;

     

    { TWAStreamReader }

     

    function TWAStreamReader.Read7BitEncodedInt: LongInt;

    var

      n: Byte;

      offset: Integer;

    begin

      offset := 0;

      Result := 0;

      repeat

        n := ReadByte;

        Result := Result or ((n and $7F) shl offset);

        Inc(offset, 7);

      until (n and $80) = 0;

    end;

     

    function TWAStreamReader.ReadAscii(len: Byte): string;

    begin

      if len > 0 then

      begin

        SetLength(Result, len);

        ReadBuffer(PChar(Result)^, len);

      end

      else

        Result := '';

    end;

     

    function TWAStreamReader.ReadBinary: string;

    var

      Len: Integer;

    begin

      Len := Read7BitEncodedInt;

      SetLength(Result, Len);

      ReadBuffer(PChar(Result)^, Len);

    end;

     

    function TWAStreamReader.ReadStream: Tstream;

    var

      Len: Integer;

    begin

      Len := Read7BitEncodedInt;

      Result := Tstream.Create;

      ReadBuffer(Result, Len);

    end;

     

    function TWAStreamReader.ReadBool: Boolean;

    begin

      Result := (ReadByte <> 0);

    end;

     

    procedure TWAStreamReader.ReadBuffer(var Buffer; Count: Integer);

    begin

      if (Count <> 0) and (Stream.Read(Buffer, Count) <> Count) then

        raise EReaderError.Create(SReaderError);

    end;

     

    function TWAStreamReader.ReadByte: Byte;

    begin

      ReadBuffer(Result, 1);

    end;

     

    function TWAStreamReader.ReadCurrency: Currency;

    begin

      ReadBuffer(Result, SizeOf(Currency));

    end;

     

    function TWAStreamReader.ReadDateTime: TDateTime;

    begin

      ReadBuffer(Result, SizeOf(TDateTime));

    end;

     

    function TWAStreamReader.ReadDouble: Double;

    begin

      ReadBuffer(Result, SizeOf(Double));

    end;

     

    procedure TWAStreamReader.ReadFMTBcd(var ABcd: TBcd);

    begin

      with ABcd do

      begin

        Precision := ReadByte;

        SignSpecialPlaces := ReadByte;

        ReadBuffer(Fraction, SizeOf(Fraction));

      end;

    end;

     

    function TWAStreamReader.ReadInt64: Int64;

    begin

      ReadBuffer(Result, SizeOf(Int64));

    end;

     

    function TWAStreamReader.ReadLongInt: LongInt;

    begin

      ReadBuffer(Result, SizeOf(LongInt));

    end;

     

    function TWAStreamReader.ReadLongWord: LongWord;

    begin

      ReadBuffer(Result, SizeOf(LongWord));

    end;

     

    procedure TWAStreamReader.ReadObjectProps(Obj: TPersistent);

      procedure ReadCollection(Coll: TCollection);

      var

        I, Len: Integer;

        Item: TCollectionItem;

      begin

        ReadObjectProps(Coll);

        Len := ReadLongInt;

        for I := 0 to Len - 1 do

        begin

          Item := Coll.Add;

          ReadObjectProps(Item);

        end;

      end;

    var

      TypData: PTypeData;

      PropCount, I, OrdVal: Integer;

      Props: PPropList;

      Int64Val: Int64;

      DblVal: Double;

      StrVal: string;

      ObjVal: TObject;

      WVal: WideString;

      VarVal: Variant;

      PropInfo: PPropInfo;

    begin

      TypData := GetTypeData(Obj.ClassInfo);

      if TypData <> nil then

      begin

        PropCount := TypData.PropCount;

        if PropCount > 0 then

        begin

          GetMem(Props, PropCount * SizeOf(PPropInfo));

          try

            PropCount := GetPropList(PTypeInfo(Obj.ClassInfo), tkProperties, Props);

     

            for I := 0 to PropCount - 1 do

            begin

              PropInfo := Props^[I];

              with PropInfo^ do

              begin

                case PropType^.Kind of

                  tkInteger:

                    begin

                      OrdVal := ReadLongInt;

                      SetOrdProp(Obj, PropInfo, OrdVal);

                    end;

     

                  tkInt64:

                    begin

                      Int64Val := ReadInt64;

                      SetInt64Prop(Obj, PropInfo, Int64Val);

                    end;

     

                  tkEnumeration:

                    begin

                      OrdVal := ReadByte;

                      SetOrdProp(Obj, PropInfo, OrdVal);

                    end;

     

                  tkFloat:

                    begin

                      DblVal := ReadDouble;

                      SetFloatProp(Obj, PropInfo, DblVal);

                    end;

     

                  tkLString,

                    tkString:

                    begin

                      StrVal := ReadString;

                      SetStrProp(Obj, PropInfo, StrVal);

                    end;

     

                  tkWString:

                    begin

                      WVal := ReadOleString;

                      SetWideStrProp(Obj, PropInfo, WVal);

                    end;

     

                  tkClass:

                    begin

                      ObjVal := GetObjectProp(Obj, PropInfo);

                      if not (ObjVal is TPersistent) then

                        raise EPersistError.Create(SPersistClassError);

     

                      if ObjVal is TStrings then

                      begin

                        StrVal := ReadString;

                        TStrings(ObjVal).CommaText := StrVal;

                      end

                      else if ObjVal is TCollection then

                        ReadCollection(TCollection(ObjVal))

                      else

                        ReadObjectProps(TPersistent(ObjVal));

                    end;

     

                  tkSet:

                    begin

                      OrdVal := ReadLongint;

                      SetOrdProp(Obj, PropInfo, OrdVal);

                    end;

     

                  tkChar:

                    begin

                      OrdVal := ReadByte;

                      SetOrdProp(Obj, PropInfo, OrdVal);

                    end;

     

                  tkWChar:

                    begin

                      OrdVal := ReadSmallInt;

                      SetOrdProp(Obj, PropInfo, OrdVal);

                    end;

     

                  tkVariant:

                    begin

                      VarVal := ReadVariant;

                      SetVariantProp(Obj, PropInfo, VarVal);

                    end;

                else

                  raise EPersistError.CreateFmt(SPersistTypeNotSupported,

                    [GetEnumName(TypeInfo(TTypeKind), Ord(PropInfo.PropType^.Kind))]);

                end; // case

              end; // with

            end; // for

          finally

            FreeMem(Props, PropCount * SizeOf(PPropInfo));

          end;

        end;

      end;

    end;

     

    function TWAStreamReader.ReadOleString: WideString;

    var

      len: Integer;

      s: string;

    begin

      len := Read7BitEncodedInt;

      if len > 0 then

      begin

        SetLength(s, len);

        ReadBuffer(PChar(s)^, len);

        Result := Utf8Decode(s);

      end

      else

      begin

        Result := '';

      end;

    end;

     

    function TWAStreamReader.ReadShortInt: ShortInt;

    begin

      ReadBuffer(Result, SizeOf(ShortInt));

    end;

     

    function TWAStreamReader.ReadShortString: string;

    var

      Len: Integer;

    begin

      Result := '';

      Len := ReadByte;

      if Len = 0 then Exit;

      SetLength(Result, Len);

      ReadBuffer(PChar(Result)^, Len);

    end;

     

    function TWAStreamReader.ReadSingle: Single;

    begin

      ReadBuffer(Result, SizeOf(Single));

    end;

     

    function TWAStreamReader.ReadSmallInt: SmallInt;

    begin

      ReadBuffer(Result, SizeOf(SmallInt));

    end;

     

    function TWAStreamReader.ReadString: string;

    begin

      Result := ReadOleString;

    end;

     

    procedure TWAStreamReader.ReadTimeStamp(var ATimeStamp: TSqlTimeStamp);

    begin

      with ATimeStamp do

      begin

        Year := ReadSmallInt;

        Month := ReadWord;

        Day := ReadWord;

        Hour := ReadWord;

        Minute := ReadWord;

        Second := ReadWord;

        Fractions := ReadLongWord;

      end;

    end;

     

    function TWAStreamReader.ReadVariant: Variant;

     

      procedure ReadArray(VType: Word; var V: Variant);

      var

        DimCount: Word;

        VSize, I: Integer;

        LoDim, HiDim, Bounds, Indices: array of Integer;

        P: Pointer;

        V2: Variant;

      begin

        VType := VType and varTypeMask;

        DimCount := ReadWord;

        VSize := DimCount * SizeOf(Integer);

        SetLength(LoDim, DimCount);

        SetLength(HiDim, DimCount);

        SetLength(Bounds, DimCount * 2);

        ReadBuffer(LoDim[0], VSize);

        ReadBuffer(HiDim[0], VSize);

        for I := 0 to DimCount - 1 do

        begin

          Bounds[I * 2] := LoDim[I];

          Bounds[I * 2 + 1] := HiDim[I];

        end;

        V := VarArrayCreate(Bounds, VType);

     

        if VType in SimpleArrayTypes then

        begin

          VSize := ReadLongInt;

          P := VarArrayLock(V);

          try

            ReadBuffer(P^, VSize);

          finally

            VarArrayUnlock(V);

          end;

        end

        else

        begin

          SetLength(Indices, DimCount);

          for I := 0 to DimCount - 1 do

            Indices[I] := LoDim[I];

     

          while True do

          begin

            V2 := ReadVariant;

            VarArrayPut(V, V2, Indices);

            Inc(Indices[DimCount - 1]);

            if Indices[DimCount - 1] > HiDim[DimCount - 1] then

              for i := DimCount - 1 downto 0 do

                if Indices[i] > HiDim[i] then

                begin

                  if i = 0 then Exit;

                  Inc(Indices[i - 1]);

                  Indices[i] := LoDim[i];

                end;

          end;

        end;

      end;

     

    var

      VType: Word;

      ABcd: TBcd;

      ATimeStamp: TSQLTimeStamp;

    begin

      VType := ReadWord;

      if VType and varArray <> 0 then

        ReadArray(VType, Result)

      else

        case VType of

          varEmpty: VarClear(Result);

          varNull: Result := Null;

          varString: Result := ReadString;

          varOleStr: Result := ReadOleString;

          varVariant: Result := ReadVariant;

          varSmallint: Result := ReadSmallint;

          varInteger: Result := ReadLongInt;

          varSingle: Result := ReadSingle;

          varDouble: Result := ReadDouble;

          varCurrency: Result := ReadCurrency;

          varDate: Result := ReadDateTime;

          varError:

            begin

              Result := ReadLongInt;

              TVarData(Result).VType := varError;

            end;

          varBoolean: Result := ReadBool;

          varShortInt: Result := ReadShortInt;

          varByte: Result := ReadByte;

          varWord: Result := ReadWord;

          varLongWord: Result := ReadLongWord;

          varInt64: Result := ReadInt64;

        else

          if VType = StreamFMTBcdID then

          begin

            Self.ReadFMTBcd(ABcd);

            Result := VarFMTBcdCreate(ABcd);

          end

          else if VType = StreamSQLTimeStampID then

          begin

            ReadTimeStamp(ATimeStamp);

            Result := VarSQLTimeStampCreate(ATimeStamp);

          end

          else

            raise EReadError.CreateFmt(SInvalidVariantType, [VType]);

        end;

    end;

     

    function TWAStreamReader.ReadWord: Word;

    begin

      ReadBuffer(Result, SizeOf(Word));

    end;

     

    //下列2个过程由Dcopyboy编写

    function AdoQuerySaveTostream(Adoq: Tadoquery): TMemoryStream;

    var

      aa: TWAStreamWriter;

      i, b: integer;

      Stream: TMemoryStream;

    begin

      aa := TWAStreamWriter.Create;

      aa.Stream := TMemoryStream.Create;

      aa.WriteString(Adoq.SQL.Text);

      b := Adoq.Parameters.Count;

      aa.WriteSmallInt(b);

      for i := 0 to b - 1 do begin

        aa.WriteString(adoq.Parameters[i].Name);

        if adoq.Parameters[i].DataType = ftGraphic then begin

          aa.WriteByte(250);

          aa.WriteVariant(adoq.Parameters[i].Value);

        end

        else if adoq.Parameters[i].DataType = ftMemo then begin

          aa.WriteByte(249);

          aa.WriteVariant(adoq.Parameters[i].Value);

        end

        else if adoq.Parameters[i].DataType = ftFmtMemo then begin

          aa.WriteByte(248);

          aa.WriteVariant(adoq.Parameters[i].Value);

        end

        else if adoq.Parameters[i].DataType = ftblob then begin

          aa.WriteByte(247);

          aa.WriteVariant(adoq.Parameters[i].Value);

        end

        else begin

          aa.WriteByte(1);

          aa.WriteVariant(adoq.Parameters[i].Value);

        end;

      end;

      Result := TMemoryStream(aa.Stream);

      aa.Free;

    end;

     

    function AdoQueryLoadFromstream(Adoq: Tadoquery; Stream: TMemoryStream): boolean;

    var

      aa: TWAStreamReader;

      i, b: integer;

      Stream1: TMemoryStream;

      PName: string;

      Ptype: word;

      MyValue: Variant;

    begin

      aa := TWAStreamReader.Create;

      aa.Stream := TMemoryStream.Create;

      Stream.Position := 0;

      TMemoryStream(aa.Stream).LoadFromStream(stream);

      Adoq.Close;

      aa.Stream.Position := 0;

      adoq.SQL.Text := aa.ReadString;

      b := aa.ReadSmallInt;

      for i := 0 to b - 1 do begin

        PName := aa.ReadString;

        Ptype := aa.ReadByte;

        if ptype = 250 then begin

          adoq.Parameters.ParamByName(Pname).DataType := ftGraphic;

          adoq.Parameters.ParamByName(Pname).Value := aa.ReadVariant;

          adoq.Parameters.ParamByName(Pname).DataType := ftGraphic;

        end

        else if ptype = 249 then begin

          adoq.Parameters.ParamByName(Pname).DataType := ftMemo;

          adoq.Parameters.ParamByName(Pname).Value := aa.ReadVariant;

          adoq.Parameters.ParamByName(Pname).DataType := ftMemo;

        end

        else if ptype = 248 then begin

          adoq.Parameters.ParamByName(Pname).DataType := ftFmtMemo;

          adoq.Parameters.ParamByName(Pname).Value := aa.ReadVariant;

          adoq.Parameters.ParamByName(Pname).DataType := ftFmtMemo;

        end

        else if ptype = 247 then begin

          adoq.Parameters.ParamByName(Pname).DataType := ftblob;

          adoq.Parameters.ParamByName(Pname).Value := aa.ReadVariant;

          adoq.Parameters.ParamByName(Pname).DataType := ftblob;

        end

        else begin

          adoq.Parameters.ParamByName(Pname).Value := aa.ReadVariant;

        end;

      end;

      aa.Free;

      Result := true;

    end;

     

    end.

     

    unit Unit1;

     

    interface

     

    uses

      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

      Dialogs, StdCtrls, WebAdoStream, DB, ADODB, ExtCtrls, ComCtrls, jpeg;

     

    type

      TForm1 = class(TForm)

        Button1: TButton;

        ADOConnection1: TADOConnection;

        ADOQuery1: TADOQuery;

        RichEdit1: TRichEdit;

        Image1: TImage;

        Button2: TButton;

        Button3: TButton;

        Button4: TButton;

        Button5: TButton;

        procedure Button1Click(Sender: TObject);

        procedure Button2Click(Sender: TObject);

        procedure Button3Click(Sender: TObject);

        procedure Button4Click(Sender: TObject);

        procedure Button5Click(Sender: TObject);

      private

        { Private declarations }

      public

        { Public declarations }

      end;

     

    var

      Form1: TForm1;

     

    implementation

     

    {$R *.dfm}

     

    {

    //测试用表:

    CREATE TABLE [dbo].[test] (

     [f1] [float] NULL ,

     [f2] [int] NULL ,

     [f3] [money] NULL ,

     [f4] [numeric](18, 0) NULL ,

     [f5] [real] NULL ,

     [d1] [datetime] NULL ,

     [c1] [char] (10) NULL ,

     [c2] [varchar] (50) NULL ,

     [b1] [ntext] NULL ,

     [b2] [text] NULL ,

     [b3] [image] NULL ,

     [B4] [image] NULL ,

     [id] [int] IDENTITY (1, 1) NOT NULL

    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

    }

     

    procedure TForm1.Button1Click(Sender: TObject);

    var

      Stream1: TMemoryStream;

    begin

      ADOQuery1.Close;

      ADOQuery1.SQL.Text := 'Insert into test ( f1,f2,f3,f4,f5,d1,c1,c2,b1,b2,b3,b4) ' +

        ' values ( :f1,:f2,:f3,:f4,:f5,:d1,:c1,:c2,:b1,:b2,:b3,:b4) ';

      ADOQuery1.Parameters.ParamByName('f1').Value := 10;

      ADOQuery1.Parameters.ParamByName('f2').Value := 20;

      ADOQuery1.Parameters.ParamByName('f3').Value := 30;

      ADOQuery1.Parameters.ParamByName('f4').Value := 40;

      ADOQuery1.Parameters.ParamByName('f5').Value := 50;

      ADOQuery1.Parameters.ParamByName('d1').Value := now();

      ADOQuery1.Parameters.ParamByName('c1').Value := '字段1';

      ADOQuery1.Parameters.ParamByName('c2').Value := '字段2';

      ADOQuery1.Parameters.ParamByName('b1').LoadFromFile('本草纲目.txt', ftMemo);

      ADOQuery1.Parameters.ParamByName('b2').LoadFromFile('本草纲目.txt', ftMemo);

      ADOQuery1.Parameters.ParamByName('b3').LoadFromFile('东阳.jpg', ftblob);

      ADOQuery1.Parameters.ParamByName('b4').LoadFromFile('东阳.jpg', ftGraphic);

      Stream1 := TMemoryStream.Create;

      Stream1.LoadFromStream(AdoQuerySaveTostream(ADOQuery1));

      stream1.SaveToFile('c:/parastreamtest');

      Stream1.Free;

      Stream1 := TMemoryStream.Create;

      stream1.LoadFromFile('c:/parastreamtest');

      ADOQuery1.Close;

      ADOQuery1.sql.clear;

      AdoQueryLoadFromstream(ADOQuery1, Stream1);

      ADOQuery1.ExecSQL;

      Stream1.Free;

    end;

     

    procedure TForm1.Button2Click(Sender: TObject);

    var

      Stream1: TMemoryStream;

    begin

      RichEdit1.Lines.Clear;

      ADOQuery1.Close;

      ADOQuery1.SQL.Text := 'select b1 from test ';

      ADOQuery1.open;

      Stream1 := TMemoryStream.Create;

      Tmemofield(ADOQuery1.FieldByName('b1')).SaveToStream(stream1);

      stream1.Position := 0;

      RichEdit1.Lines.LoadFromStream(stream1);

      stream1.free;

    end;

     

    procedure TForm1.Button3Click(Sender: TObject);

    var

      Stream1: TMemoryStream;

    begin

      RichEdit1.Lines.Clear;

      ADOQuery1.Close;

      ADOQuery1.SQL.Text := 'select b2 from test ';

      ADOQuery1.open;

      Stream1 := TMemoryStream.Create;

      Tmemofield(ADOQuery1.FieldByName('b2')).SaveToStream(stream1);

      stream1.Position := 0;

      RichEdit1.Lines.LoadFromStream(stream1);

      stream1.free;

     

    end;

     

    procedure TForm1.Button4Click(Sender: TObject);

    var

      Stream1: TMemoryStream;

      Jpeg1: TJPEGImage;

    begin

      ADOQuery1.Close;

      ADOQuery1.SQL.Text := 'select b3 from test ';

      ADOQuery1.open;

      Stream1 := TMemoryStream.Create;

      Tblobfield(ADOQuery1.FieldByName('b3')).SaveToStream(stream1);

      stream1.Position := 0;

      Jpeg1 := TJPEGImage.Create;

      Jpeg1.LoadFromStream(stream1);

      stream1.free;

      Image1.Picture.Assign(jpeg1);

      jpeg1.Free;

    end;

     

    procedure TForm1.Button5Click(Sender: TObject);

    var

      Stream1: TMemoryStream;

      Jpeg1: TJPEGImage;

    begin

      ADOQuery1.Close;

      ADOQuery1.SQL.Text := 'select b4 from test ';

      ADOQuery1.open;

      Stream1 := TMemoryStream.Create;

      Tblobfield(ADOQuery1.FieldByName('b4')).SaveToStream(stream1);

      stream1.Position := 0;

      Jpeg1 := TJPEGImage.Create;

      Jpeg1.LoadFromStream(stream1);

      stream1.free;

      Image1.Picture.Assign(jpeg1);

      jpeg1.Free;

     

    end;

     

    end.

     

     

     

     

  • 相关阅读:
    6. Flask请求和响应
    5. Flask模板
    FW:Software Testing
    What is the difference between modified duration, effective duration and duration?
    How to push master to QA branch in GIT
    FTPS Firewall
    Query performance optimization of Vertica
    (Forward)5 Public Speaking Tips That'll Prepare You for Any Interview
    (转)The remote certificate is invalid according to the validation procedure
    Change
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940651.html
Copyright © 2011-2022 走看看