Share Button

Trocar informações entre RECORDs com estrutura diferentes pode ser um trabalho relativamente cansativa. Uma opção é converter o RECORD de origem em JSON e em seguida carregar o JSON no RECORD de destino.
Executar esta atividade é possível fazendo uso das classes RTTI do delphi. Então a idéia mais básica é criar métodos para gerar JSON e carga do JSON com o RECORD desejado.

Uma proposta utilizando generics para lidar com JSON fontes:


 TJsonRecord<T: Record > = class
  public
     /// gerar JSON
    class function ToJson(O: T; const AIgnoreEmpty: Boolean = true;
      const AProcBefore: TProc < TJsonObject >= nil): string;
     /// carregar um JSON
    class procedure FromJson(O: T; AJson: string);
  end;

Considerando uma estrutura de RECORD (origem e destino):

     TRecordOrigem = record
       nome:string;
       email:string;
     end;


     TRecordDestino = record
       nome:string;
       email:string;
       outros:integer;
     end;

A estrutura de identificação do RECORD por generics tem por finalidade aplicar RTTI para descobrir quais os FIELDS disponíveis no RECORD a ser transformado. Assim quando queremos gerar o JSON, fazemos:

   var sJson:string;
       dados : TRecordOrigem;
   ...
   dados.nome := 'xxxx';
   dados.email := 'yyyy';

   sJson := TJsonRecord<TRecordOrigem>.ToJson(dados);   // retorna o JSON

No RECORD de destino, fazendo a carga do JSON:

   var destino:TRecordDestino;
   ...

   TJsonRecord<TRecordDestino>.FromJson(destino,sJson);

Share Button

Trabalhar com RECORD é mais fácil administrar memória quando comparado com classes.

Como cada variável RECORD ocupa um endereço diferente com os dados e controla a sua retirada da memória com mais facilidade, prefiro usar RECORD para fazer CACHE de dados.

Por outro lado, temos vários acessos ao banco de dados que possuem parâmetros que estão nestes RECORD (alguém lembrará um CRUD). Uma solução é utilizar RTTI para ler os valores dos parâmetros que estão armazenados no RECORD e passar os valores para os parâmetros (TParams).

function TALQuery.FillParams<T>(rec: T): TALQuery;
var
  LList: TJsonValuesList;  // unit System.uJson
  LPair:TJsonPair;
  i:integer;
  prm:TParamBase;
begin
  result := self;
  LList := TJsonValuesList.Create();    // unit System.uJson
  try
    TJsonValue.GetRecordList<T>(LList, rec); // carrega os valores do RECORD em um LIST
    for I := 0 to params.count-1 do
         begin
            prm:= params[i];
            LPair := LList.names[ prm.Name ];
            if assigned(LPair) then
              case prm.DataType of
                 ftSmallint,ftInteger:
                   prm.AsInteger := LPair.JsonValue.GetValue<integer>;
                 ftFloat:
                   prm.AsFloat := LPair.JsonValue.GetValue<double>;
                 ftCurrency:
                   prm.AsCurrency := LPair.JsonValue.GetValue<Currency>;
                 ftDateTime,ftDate,ftTime :
                   prm.asDateTime := LPair.JsonValue.getValue<TDateTime>;
               else
                 prm.Value := LPair.JsonValue.getValue<string>;
              end;
         end;
  finally
    LList.free;
  end;
end;


/* aplicando */


Type
    TPedidoRecord = record
      ...
      pedido:integer;
      filial:integer;
      data:TDatetime;
    end;


var qry:   TMinhaQuery;
    rec : TPedidoRecord;
begin
    ....
    qry.fillParams<TPedidoRecord>(rec);
    ...
end;

 

Dependência: System.uJson

 

Share Button

Assim como Class Helper extende classes, Record Helper permite extender
Records.

Quantas vezes já precisou fazer: total := total + x;
Utilizando helper poderia escrever assim: total.add( x );

Código Fonte no GIT