• ADO序列


    ADO序列

    此单元,DELPHI7不适用。

    unit ncSerializeADO;
    
    interface
    
    uses SysUtils, Classes, Variants, DB, ADODB, ADOInt, ComObj, ActiveX, OleCtrls;
    
    // SysUtils: Need TBytes
    // Classes: Need TBytesStream
    // ADODB: Need TPersistFormat
    // ADOInt: Need function PersistFormatEnum
    // ActiveX: Need IStream
    
    function RecordsetToStream(const aRecordset: _Recordset; aFormat: TPersistFormat): TBytesStream;
    function RecordsetToBytes(const aRecordset: _Recordset; aFormat: TPersistFormat = pfADTG): TBytes;
    
    function StreamToRecordset(const aStream: TBytesStream; aConnection: TADOConnection = nil): _Recordset;
    function BytesToRecordset(const aBytes: TBytes; aConnection: TADOConnection = nil): _Recordset;
    
    function VariantToBytes(aVar: Variant): TBytes;
    function BytesToVariant(aBytes: TBytes): Variant;
    
    function ParametersToBytes(aParameters: TParameters): TBytes;
    procedure BytesToParameters(aBytes: TBytes; aParameters: TParameters);
    
    implementation
    
    uses ncSources;
    
    function VariantToBytes(aVar: Variant): TBytes;
    var
      VariantType: TVarType;
      BufLen: Integer;
    begin
      VariantType := FindVarData(aVar)^.VType;
      SetLength(Result, SizeOf(VariantType));
      move(VariantType, Result[0], SizeOf(VariantType));
      BufLen := Length(Result);
      if not(VariantType in [varEmpty, varNull]) then
      begin
        case VariantType of
          varByte, varSmallint, varShortInt, varInteger, varWord, varLongWord:
            WriteInteger(aVar, Result, BufLen);
          varSingle, varDouble:
            WriteDouble(aVar, Result, BufLen);
          varCurrency:
            WriteCurrency(aVar, Result, BufLen);
          varDate:
            WriteDate(aVar, Result, BufLen);
          varBoolean:
            WriteBool(aVar, Result, BufLen);
          varInt64, varUInt64:
            WriteInt64(aVar, Result, BufLen);
          varOleStr, varStrArg, varString, varUString:
            WriteString(aVar, Result, BufLen);
        else
          raise Exception.Create('Cannot pack specified parameter');
        end;
      end;
    
    end;
    
    function BytesToVariant(aBytes: TBytes): Variant;
    var
      VariantType: TVarType;
      Ofs: Integer;
    begin
      move(aBytes[0], VariantType, SizeOf(VariantType));
      Ofs := SizeOf(VariantType);
    
      if not(VariantType in [varEmpty, varNull]) then
      begin
        case VariantType of
          varEmpty:
            Result := Variants.Unassigned;
          varNull:
            Result := Variants.Null;
          varByte, varSmallint, varShortInt, varInteger, varWord, varLongWord:
            Result := ReadInteger(aBytes, Ofs);
          varSingle, varDouble:
            Result := ReadDouble(aBytes, Ofs);
          varCurrency:
            Result := ReadCurrency(aBytes, Ofs);
          varDate:
            Result := ReadDate(aBytes, Ofs);
          varBoolean:
            Result := ReadBool(aBytes, Ofs);
          varInt64, varUInt64:
            Result := ReadInt64(aBytes, Ofs);
          varOleStr, varStrArg, varString, varUString:
            Result := ReadString(aBytes, Ofs);
        else
          raise Exception.Create('Cannot pack specified parameter');
        end;
      end;
    
    end;
    
    function ParametersToBytes(aParameters: TParameters): TBytes;
    var
      BufLen: Integer;
      i: Integer;
    begin
      BufLen := 0;
      WriteInteger(aParameters.Count, Result, BufLen);
      for i := 0 to aParameters.Count - 1 do
        WriteBytes(VariantToBytes(aParameters.Items[i].Value), Result, BufLen);
    end;
    
    procedure BytesToParameters(aBytes: TBytes; aParameters: TParameters);
    var
      ParameterCount: Integer;
      Ofs: Integer;
      i: Integer;
    begin
      if Length(aBytes) > 0 then
      begin
        Ofs := 0;
        if not Assigned(aParameters) then
          raise Exception.Create('Parameters object not assigned');
        ParameterCount := ReadInteger(aBytes, Ofs);
        if ParameterCount <> aParameters.Count then
          raise Exception.Create('Bytes stream parameters differ from SQL Parameters');
    
        for i := 0 to ParameterCount - 1 do
          aParameters.Items[i].Value := BytesToVariant(ReadBytes(aBytes, Ofs));
      end;
    end;
    
    function RecordsetToStream(const aRecordset: _Recordset; aFormat: TPersistFormat): TBytesStream;
    var
      ADOStream: IStream;
    begin
      // Create a stream to hold the data
      Result := TBytesStream.Create;
      try
        // Since ADO can't write directly to a Delphi stream, we must wrap the Delphi stream
        ADOStream := TStreamAdapter.Create(Result, soReference) as IStream;
        try
          // Save the content of the recordset to the stream
          aRecordset.Save(ADOStream, PersistFormatEnum(aFormat));
        finally
          ADOStream := nil;
        end;
    
        // The Stream now contains the data
        // Position the stream at the start
        Result.Position := 0;
      except
        Result.Free;
        raise ;
      end;
    end;
    
    function RecordsetToBytes(const aRecordset: _Recordset; aFormat: TPersistFormat = pfADTG): TBytes;
    var
      tmpSS: TBytesStream;
    begin
      tmpSS := RecordsetToStream(aRecordset, aFormat);
      try
        Result := tmpSS.Bytes;
      finally
        tmpSS.Free;
      end;
    end;
    
    
    function StreamToRecordset(const aStream: TBytesStream; aConnection: TADOConnection = nil): _Recordset;
    var
      ADOStream: IStream;
    begin
      Result := CoRecordset.Create;
      try
        // Since ADO can't write directly to a Delphi stream, we must wrap the Delphi stream
        ADOStream := TStreamAdapter.Create(aStream, soReference) as IStream;
        try
          // Save the content of the stream to the recordset
          Result.Open(ADOStream, EmptyParam, adOpenKeyset, adLockBatchOptimistic, adCmdFile);
    
          // You need to Set_ActiveConnection in order to be able to update a recordset.
          if Assigned(aConnection) then
              Result.Set_ActiveConnection(aConnection.ConnectionObject);
        finally
          ADOStream := nil;
        end;
      except
        Result := nil;
        raise ;
      end;
    end;
    
    function BytesToRecordset(const aBytes: TBytes; aConnection: TADOConnection = nil): _Recordset;
    var
      Stream: TBytesStream;
    begin
      Stream := TBytesStream.Create(aBytes);
      try
        Stream.Position := 0;
        Result := StreamToRecordset(Stream, aConnection);
      finally
        Stream.Free;
      end;
    end;
    
    
    end.
    

      

    function TReadyQueryItem.Update(aUpdates: _recordset): TBytes;
    var
      tmpDS: TADODataSet;
    begin
      FSerialiser.Acquire;
      try
        tmpDS := TADODataSet.Create(nil);
        try
          tmpDS.Recordset := aUpdates;
          tmpDS.Recordset.Set_ActiveConnection(ADOQuery.Connection.ConnectionObject);
          tmpDS.Recordset.UpdateBatch(adAffectAll);
          // tmpDS.Recordset.Filter := adFilterAffectedRecords;
          Result := RecordsetToBytes(tmpDS.Recordset, pfADTG);
        finally
          tmpDS.Free;
        end;
      finally
        FSerialiser.Release;
      end;
    end;
    
    procedure TReadyQueryItem.GetTablesForSQL;
    var
      i: Integer;
    begin
      Tables.Clear;
      // Get for every field the table it comes from
      for i := 0 to ADOQuery.Recordset.Fields.Count - 1 do
        if VarIsStr (ADOQuery.Recordset.Fields.Item[i].Properties.Item['BASETABLENAME'].Value) then
          Tables.Add(ADOQuery.Recordset.Fields.Item[i].Properties.Item['BASETABLENAME'].Value);
    end;
    

      

  • 相关阅读:
    (转)SQL Server索引进阶第四篇:页和区
    (转)SQL Server索引进阶第五篇:索引包含列
    CentOS虚拟化服务的配置(转)
    ubuntu 9.04安装xen(转)
    Linux的mount命令详解
    Linux环境下高级文件系统(转)
    安装和使用xenshell(转)
    (转)介绍ice 代理 不错的文章
    mapreduce介绍
    (转)Ubuntu Server Editon 时区设置
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/12710175.html
Copyright © 2020-2023  润新知