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;
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/12710175.html

浙公网安备 33010602011771号