Depois de muito procurar, não encontrei nada específico para minha necessidade. Como nossos sistemas trabalham desconectados da base de dados, queria uma forma de fazer isto no DataSnap.


Qual é então o objetivo deste artigo? Mostrar como fazer um servidor DataSnap retornar um XMLData que será utilizado para preencher um ClientDataSet através de JSon.

Vamos lá. Primeiramente, no servidor, criamos uma função que retornará um XMLData do ClientDataSet no formato JSon. Para quem não conhece, o XMLData do ClientDataSet é um conjunto de dados que nos permite exportar um ClientDataSet e importar em outro com toda a mesma estrutura e dados.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function TControllerGeral.ObterDadosDataSetJSon(const Fields, Table: string): TJsonString;
var
  vSQL : string;
  Reader : TDbxReader;
  cdsAux : TClientDataSet;
begin
  result := TJSONString.Create('');
 
  vSQL := 'Select ' + Fields + ' from ' + Table;
  Reader := GetRecords(vSQL);
 
  if Assigned(Reader) then begin
      cdsAux := TClientDataSet.Create(nil);
      try
        TDBXDataSetReader.CopyReaderToClientDataSet(Reader, cdsAux);
        result := TJSONString.Create(cdsAux.XMLData);
      finally
        FreeAndNil(Reader);
        cdsAux.Free;
     end;
  end;
end;
1
2
3
4
5
6
7
8
9
10
11
12
13
function TControllerGeral.GetRecords(const vSQL: String): TDBXReader;
var
  cmd: TDBXCommand;
begin
  cmd := ModuloConexaoDB.SQLConnection.DBXConnection.CreateCommand; // dmServerContainer.GetConnection.DBXConnection.CreateCommand;
  try
    cmd.Text := vSQL;
    Result := cmd.ExecuteQuery;
  except
    on E:Exception do
      MessageDLG(E.Message, mtError, [mbOK], 0);
  end;
end;

Já no lado cliente, basta utilizar uma função para retornar os dados e importá-lo no ClientDataSet. Assim, teremos toda a estrutura de dados que foi buscada no servidor do lado cliente, sem necessidade de se utilizar DataSetProvider e totalmente RestFull.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
procedure TfrmPrincipal.Button6Click(Sender: TObject);
var
  vXMLData : string;
  vGeral   : TControllerGeral;
begin
  screen.cursor := crHourGlass;
  cdsProdutos.Close;
  vGeral := TControllerGeral.Create();
 
  try
   vXMLData := vGeral.ObterDataSetServidor('*', 'Produtos');
   //vXMLData := copy(vXMLData, 2, length(vXMLData) -2); //-- retira aspas inicio e fim
   cdsProdutos.XMLData := vXMLData;
   cdsProdutos.Open;
  finally
    vGeral.Free;
    screen.cursor := crDefault;
  end;
end;
Anúncios