Houve um tempo que executar tarefas em “background” era um tortura.
Com a evolução de hardware e software, fazer uso de computação paralela passou a ser tão
fácil quanto um desafio em resistir ao seu uso.

Introduzida na versão XE7, um “thread” passou a rodar considerando o balanceamento entre
os processadores presentes na unidade de processamento.

Associar o uso de métodos anônimos facilitou em muito todo o trabalho:
[code lang=”pascal”]
TThread.CreateAnonymousThread(
procedure begin
// execute aqui o seu código
….
// se precisar sincronizar atualização de
// controles da janela
TThread.Queue(nil,
procedure begin
// aqui deve incluir a atualização
// dos controles da janela;
// ex: label1.caption := ‘texto’;
end);
end).Start;
[/code]

A introdução de Class Helper no delphi ajudou o desenvolvedor a incluir novas
funcionalidades nas classes nativas do delphi – você tem uma idéia de um
recursos dos sonhos e gostaria de implementar lá na classe base, use Class
Helper.

Extendendo o TDataset:
[code lang=”pascal”]
TDatasetHelper = class helper for TDataset
public
procedure Run(AProc:TProc<TDataset>);
end;

procedure TDatasetHelper.Run(AProc: TProc<TDataset>);
begin // executa em um thread separada
TThread.CreateAnonymousThread(
procedure begin
if assigned(AProc) then
AProc(self);
end
).Start;
end;
[/code]
O exemplo implementa a capacidade de uso da “procedure” RUN(…) por
qualquer classe com herança de TDataset.

Trabalhando com o novo procedimento:

O procedimento RUN por finalidade executar em um processo paralelo (uma
nova TThread) a rotina que estiver implementando no TProc.
[code lang=”pascal”]
var total:double;
begin
query1.run(
procedure (ds:TDataset) // rotina a executar em paralelo.
begin
ds.first;
while ds.eof=false do
begin
total := total + xxxxx;
ds.next;
end;
end);
end;

[/code]

O Firebird aceita usar o Order By indicando o nome da coluna (o mais conhecido), o número da coluna ou pelo apelido da coluna.

Exemplo usando o nome da coluna:
[code lang=”SQL”]
select
codigo, nome, preco, (preco * 1.05) precoPrazo
from fb_prod
order by nome Rows 10
[/code]

Exemplo usando o número da coluna
[code lang=”SQL”]
select
codigo, nome, preco, (preco * 1.05) precoPrazo
from fb_prod
order by 4 Rows 10
[/code]

Exemplo usando o apelido da coluna:
[code lang=”SQL”]
select
codigo, nome, preco, (preco * 1.05) precoPrazo
from fb_prod
order by precoPrazo Rows 10
[/code]

O Firebird tem duas formas diferentes de limitar o número de linhas:

First/Skip   ou

Rows/To    (mais nova)

Exemplo:

select codigo, nome from clientes Rows 10 To 15

Retorna as linhas de número 10 até a linha 15 (primeira linha=1)

Se rows>0 sem indicar o To retorna as N linhas a partir do primeiro registro.

Se rows=0 não retorna nenhuma linha.

Se rows <0 vai gerar uma exceção.

 

Com a crescente número de amigos que estão navegando em serviços
cambiáveis entre aplicativos (ou linguagens), serializar um TDataset pode ser
uma solução simples e “stander” de mercado para troca de informações.
Depois de muitas idas e vindas vou deixar o resultado do trabalho que já fiz
sobre o assunto

uses System.uJson, Data.DB.Helper;
function DatasetToJson( const ADataset:TDataset ) : string;
begin
result := ADataset.ToJson;
end;

Fonte: Data.DB.Helper.pas System.uJSON.pas

SWEEP é um recurso que limpa registros lixo do banco de dados. Quando um registro é excluído (DELETE) ou feito (UPDATE) o firebird mantem uma cópia antiga do registro no arquivo do banco de dados (MEUBANCO.FDB), ainda que esta cópia não seja visualizada ao fazer o SELECT no banco de dados.

Como a remoção de dados do arquivo consome tempo de processamento considerável, o Firebird não o faz constantemente, mas sim, de períodos em períodos. Se a instalação padrão do MEUBANCO.FDB for de 20.000 registro, ou seja, quando atinge este número de registro o banco executa automaticamente um SWEEP do banco de dados (limpa o lixo).

Como ele não escolhe a hora mais adequada para executar o SWEEP, muitas vezes o banco o executa exatamente quando o usuário mais esta precisando acessar o banco. Quando isto ocorre, o banco aumenta o tempo de resposta tornando perceptível ao usuário.

Em instalações de uso intenso, uma possibilidade é desabilitar este processo automático e passar a faze-lo em momento programados. Ex: quando liga a máquina, ou ainda, programada para executar fora do expediente.


*Como desabilitar o SWEEP

gfix -h 0 localhost:c:\dados\meubanco.fdb -user sysdba -password masterkey

Ao desabilitar o SWEEP o banco deixará de fazer limpeza dos registros inválidos, razão que é preciso montar um processo de execute o SWEEP manualmente (obrigatório). Se por o SWEEP deixar de ser feito por um período que acumule muitos registros inválidos, será afetado o desempenho do banco de dados, até que o SWEEP seja executa; Executar o SWEEP quando reinicia o banco de dados, pode ser uma opção bastante interessante.

*Para alterar o SWEEP para 1000

gfix -h 1000 localhost:c:\dados\meubanco.fdb -user sysdba -password masterkey

*Executar SWEEP Manual

gfix -sweep localhost:c:\dados\meubanco.fdb -user sysdba -password masterkey

Em uma estratégia de execução manual, pode gerar um script (uma bat) e registrar a execução no agendador de tarefas para fazer todos os dias a noite quando o uso do banco é baixo, assim irá manter melhor controle sobre a performance do banco durante os períodos de maior atividade.

O uso de Datasnap como cliente de acesso ao servidor JSON é resultante de uma combinação de componentes do delphi para completar a chamada. Se do lado do Servidor há um Datasnap então o lado cliente é facilitado ao coletar informações dos métodos exportados pelo servidor e geração do cliente automático. A implementação do servidor JSON pode apresentar uma variedade muito grande de formato de publicação (ou não) dos seus métodos, o que pode se tornar bastante trabalhoso a implementação do cliente.

Simplificando o trabalho:

TRESTSocialClient


Encapsula os componentes necessário para efetivar uma troca de informações entre do servidor para o cliente.

 public
    function Response: TRESTResponse;
    function Request: TRESTRequest;
    function Auth2: TOAuth2Authenticator;
    property AccessToken: string read GetAccessToken write SetAccessToken;
    procedure Clear; virtual;
    constructor create(ow: TComponent); override;
    destructor destroy; override;
    function Get(url: string; AResource: string = ''): string; virtual;
    function GetStream(AUrl: string; AResource: string; AStream: TStream)
      : integer; virtual;
    function SendStream(AUrl, AResource: string; AStream: TStream)
      : integer; virtual;
    function Post(url: string; AResource: string = ''): string; virtual;


 
 var rsp:string;
  with TRESTSocialClient.create(nil) do
  try
    rsp := Get('http://meuservidor/xxxx', '/GetCliente?codigo=1');  // chama o servidor                                                                 para pegar GetCliente.... finally
     free;
  end;

TRESTSocialClientDataset


Herança de TRESTSocialClient que associa a resposta do servidor um Dataset.

  with TRESTSocialClientDataset.create(nil) do
  try
    // pode indica um DATASET, para obter o retorno
    Dataset := MeuDataset;   // se nao for informado retorna um Dataset   TFDMemTable
    rootElement := 'result';  // espera um Array com as linhas da tabela;  
    rsp := Get('http://meuservidor/xxxx', '/GetCliente?codigo=1');  
                                                         // chama o servidor                                                                para pegar GetCliente....  
  finally
     free;
  end;

Exemplo:  REST.Social