viniciussanchez / dataset-serialize

JSON to DataSet and DataSet to JSON converter for Delphi and Lazarus (FPC)
MIT License
645 stars 156 forks source link

Uso de instâncias distintas do TDataSetSerializeConfig e uso da biblioteca de forma segura em Threads. #221

Open maiconsaraiva opened 9 months ago

maiconsaraiva commented 9 months ago

Olá Vinicius, tudo bem? Estamos iniciando o uso da biblioteca, e já gostaria de parabenizar, está fantástica.

Uma necessidade que estou tento e não encontrei é a seguinte: Preciso integrar com uma API especifica e vou definir as configurações usando o "TDataSetSerializeConfig", essa integração é uma replicação de dados que é feita a cada X minutos.

O problema: Eu preciso usar uma configuração de Export do TDataSetSerializeConfig diferente do padrão da aplicação. No código vi que o uso está fixado na instância global "TDataSetSerialize.GetInstance", a exemplo do método TDataSetSerialize.DataSetToJSONObject().

Sendo assim, entendi que hoje não é possível desta forma. Teria que contornar redefinido as configuações antes de cada chamada à API's distintas, correto?

Se for esse o caso e tiver pretensão de trabalhar nela Thread Safe, posso estar ajudando na implementação desse recurso.

viniciussanchez commented 9 months ago

Boa tarde... desculpa a demora em responder. Sim realmente terá esse problema mesmo. Se conseguir deixar ela Thread Safe seria muito bom... e se fizer isso sem quebra de compatibilidade melhor ainda kkkkkkk

maiconsaraiva commented 9 months ago

Boa tarde @viniciussanchez, sem problemas. Obrigado pelo retorno. Por hora, eu consegui resolver usando um TCriticalSection, mais adiante conforme precisar mecher nas configurações novamente, tento fazer esta implementação.

Segue o código que estou usando, caso mais alguém precise:

{Unit usada para abstrair e modificar alguns recursos relacionado à
serialização e deserialização de DataSets no Delphi}
unit Lib.Global.DataSetSerialize;

interface

uses
  DataSet.Serialize, System.SyncObjs;

type
  TDataSetSerializeConfiguracao = (
    dscNaoDefinido, //Usando somente para inicialização, NÃO informe isso no parametro.
    dscPadrao, //Padrão (não definido ainda)
    dscApiGMS //Api do MaisSimples (SisApiServer) (usada atualmente para espelhamento)
  );

  TLibDataSetSerialize = record
    /// <ummary>
    ///   Configura a instância global do DataSetSerialize de acordo com o destino/API desejado.
    /// Esse método deve ser chamado SEMPRE ANTES de qualquer serialização/deserialização usando o DataSetSerialize. <para />
    /// A necessidade deste método pode ser entendida no link abaixo (uma issue aberta no github por Maicon Saraiva):
    /// https://github.com/viniciussanchez/dataset-serialize/issues/221
    /// </summary>
    class procedure ThreadSafeConfigure(AConfiguracaoDesejada: TDataSetSerializeConfiguracao); static;
  end;

implementation

var
  GlobalDataSetConfigCriticalSection: TCriticalSection = nil;
  GlobalConfiguracaoAtual: TDataSetSerializeConfiguracao = dscNaoDefinido;

{ TDataSetSerializeConfigHelperSismais }

class procedure TLibDataSetSerialize.ThreadSafeConfigure(AConfiguracaoDesejada: TDataSetSerializeConfiguracao);
begin
  GlobalDataSetConfigCriticalSection.Enter;
  try
    if AConfiguracaoDesejada <> GlobalConfiguracaoAtual then //Se não mudou então não precisa executar os passo abaixo.
    begin
      case AConfiguracaoDesejada of
        dscPadrao:
          begin
            {Não definido ainda. Por enquanto o DataSetSerialize é usado somente na dcApiGMS, configurar aqui se
            for usar para o resto da aplicação.}
          end;
        dscApiGMS:
          begin
            TDataSetSerializeConfig.GetInstance.Export.ExportNullValues := False;
            TDataSetSerializeConfig.GetInstance.CaseNameDefinition := TCaseNameDefinition.cndNone;
            TDataSetSerializeConfig.GetInstance.Export.FormatDateTime := 'yyyy-mm-dd hh:nn:ss';
            TDataSetSerializeConfig.GetInstance.DateInputIsUTC := False;
            TDataSetSerializeConfig.GetInstance.DateTimeIsISO8601 := False;
          end;
      end;
    end;
  finally
    GlobalDataSetConfigCriticalSection.Leave;
  end;
end;

initialization
  GlobalDataSetConfigCriticalSection := TCriticalSection.Create;
  TLibDataSetSerialize.ThreadSafeConfigure(dscPadrao);

finalization
  if Assigned(GlobalDataSetConfigCriticalSection) then
    GlobalDataSetConfigCriticalSection.Free;

end.