Secuencia ADO
unidad ncSerializeADO; interfaz utiliza SysUtils, clases, variantes, DB, ADODB, ADOInt, ComObj, ActiveX, OleCtrls; // SysUtils: necesita TBytes // Clases: Necesito TBytesStream // ADODB: Necesita TPersistFormat // ADOInt: Necesita función PersistFormatEnum // ActiveX: necesita IStream función RecordsetToStream (const aRecordset: _Recordset; aFormat: TPersistFormat): TBytesStream; función RecordsetToBytes (const aRecordset: _Recordset; aFormat: TPersistFormat = pfADTG): TBytes; función StreamToRecordset (const aStream: TBytesStream; aConnection: TADOConnection = nil): _Recordset; función BytesToRecordset (const aBytes: TBytes; aConnection: TADOConnection = nil): _Recordset; función VariantToBytes (aVar: Variant): TBytes; función BytesToVariant (aBytes: TBytes): Variante; función ParametersToBytes (aParameters: TParameters): TBytes; procedimiento BytesToParameters (aBytes: TBytes; aParameters: TParameters); implementación usa ncSources; función VariantToBytes (aVar: Variant): TBytes; era VariantType: TVarType; BufLen: entero; empezar VariantType: = FindVarData (aVar) ^. VType; SetLength (Result, SizeOf (VariantType)); move (VariantType, Result [0], SizeOf (VariantType)); BufLen: = Longitud (Resultado); si no (VariantType en [varEmpty, varNull]) entonces empezar 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); más raise Exception.Create ('No se puede empacar el parámetro especificado'); final; final; final; función BytesToVariant (aBytes: TBytes): Variante; era VariantType: TVarType; Ofs: entero; empezar move (aBytes [0], VariantType, SizeOf (VariantType)); Ofs: = SizeOf (VariantType); si no (VariantType en [varEmpty, varNull]) entonces empezar case VariantType of varEmpty: Resultado: = Variantes. Sin firmar; varNull: Resultado: = Variantes. Nulo; varByte, varSmallint, varShortInt, varInteger, varWord, varLongWord: Resultado: = ReadInteger (aBytes, Ofs); varSingle, varDouble: Resultado: = ReadDouble (aBytes, Ofs); varCurrency: Resultado: = ReadCurrency (aBytes, Ofs); varDate: Resultado: = ReadDate (aBytes, Ofs); varBoolean: Resultado: = ReadBool (aBytes, Ofs); varInt64, varUInt64: Resultado: = ReadInt64 (aBytes, Ofs); varOleStr, varStrArg, varString, varUString: Resultado: = ReadString (aBytes, Ofs); más raise Exception.Create ('No se puede empacar el parámetro especificado'); final; final; final; función ParametersToBytes (aParameters: TParameters): TBytes; era BufLen: entero; i: entero; empezar BufLen: = 0; WriteInteger (aParameters.Count, Result, BufLen); para i: = 0 a aParameters.Count - 1 do WriteBytes (VariantToBytes (aParameters.Items [i] .Value), Result, BufLen); final; procedimiento BytesToParameters (aBytes: TBytes; aParameters: TParameters); era ParameterCount: Integer; Ofs: entero; i: entero; empezar if Longitud (aBytes)> 0 entonces empezar Ofs: = 0; si no está asignado (aParameters) entonces raise Exception.Create ('Parámetros objeto no asignado'); ParameterCount: = ReadInteger (aBytes, Ofs); si ParameterCount <> aParameters.Count entonces raise Exception.Create ('Los parámetros del flujo de bytes difieren de los parámetros de SQL'); para i: = 0 a ParameterCount - 1 do aParameters.Items [i] .Value: = BytesToVariant (ReadBytes (aBytes, Ofs)); final; final; función RecordsetToStream (const aRecordset: _Recordset; aFormat: TPersistFormat): TBytesStream; era ADOStream: IStream; empezar // Crea una secuencia para contener los datos Resultado: = TBytesStream.Create; tratar // Dado que ADO no puede escribir directamente en una secuencia de Delphi, debemos ajustar la secuencia de Delphi ADOStream: = TStreamAdapter.Create (Result, soReference) como IStream; tratar // Guarde el contenido del conjunto de registros en la secuencia aRecordset.Save (ADOStream, PersistFormatEnum (aFormat)); finalmente ADOStream: = nulo; final; // El flujo ahora contiene los datos // Posiciona la transmisión al inicio Resultado.Posición: = 0; excepto Resultado libre; elevar final; final; función RecordsetToBytes (const aRecordset: _Recordset; aFormat: TPersistFormat = pfADTG): TBytes; era tmpSS: TBytesStream; empezar tmpSS: = RecordsetToStream (aRecordset, aFormat); tratar Resultado: = tmpSS.Bytes; finalmente tmpSS.Free; final; final; función StreamToRecordset (const aStream: TBytesStream; aConnection: TADOConnection = nil): _Recordset; era ADOStream: IStream; empezar Resultado: = CoRecordset.Create; tratar // Dado que ADO no puede escribir directamente en una secuencia de Delphi, debemos ajustar la secuencia de Delphi ADOStream: = TStreamAdapter.Create (aStream, soReference) como IStream; tratar // Guardar el contenido de la secuencia en el conjunto de registros Result.Open (ADOStream, EmptyParam, adOpenKeyset, adLockBatchOptimistic, adCmdFile); // Necesita establecer Set_ActiveConnection para poder actualizar un conjunto de registros. si asignado (aConnection) entonces Result.Set_ActiveConnection (aConnection.ConnectionObject); finalmente ADOStream: = nulo; final; excepto Resultado: = nulo; elevar final; final; función BytesToRecordset (const aBytes: TBytes; aConnection: TADOConnection = nil): _Recordset; era Stream: TBytesStream; empezar Stream: = TBytesStream.Create (aBytes); tratar Stream.Position: = 0; Resultado: = StreamToRecordset (Stream, aConnection); finalmente Stream.Free; final; final; final.
función TReadyQueryItem.Update (aUpdates: _recordset): TBytes; era tmpDS: TADODataSet; empezar FSerialiser.Aququire; tratar tmpDS: = TADODataSet.Create (nil); tratar tmpDS.Recordset: = aUpdates; tmpDS.Recordset.Set_ActiveConnection (ADOQuery.Connection.ConnectionObject); tmpDS.Recordset.UpdateBatch (adAffectAll); // tmpDS.Recordset.Filter: = adFilterAffectedRecords; Resultado: = RecordsetToBytes (tmpDS.Recordset, pfADTG); finalmente tmpDS.Free; final; finalmente FSerialiser.Release; final; final; procedimiento TReadyQueryItem.GetTablesForSQL; era i: entero; empezar Tablas. // Obtenga para cada campo la tabla de la que proviene para i: = 0 a ADOQuery.Recordset.Fields.Count - 1 do si VarIsStr (ADOQuery.Recordset.Fields.Item [i] .Properties.Item ['BASETABLENAME']. Value) entonces Tables.Add (ADOQuery.Recordset.Fields.Item [i] .Properties.Item ['BASETABLENAME']. Value); final;