ClientDataSet - LookUp/Gravar/Ler - Cache Máquina Cliente
05/12/2005
0
Estou utilizando DBExpress... delphi7/query/provider/clientdataset/firebird.
A título de exemplo:
-> usuario_nivel
-> usuario
Na tabela -> usuario_nivel ... tenho os campos
un_chave -> 1, 2, 3, ...
... mais campos
un_nivel -> administrador, técnico, desenvolvedor, ...
na tabela -> usuario ... tenho os campos
usu_chave -> 1, 2, 3, ...
... mais campos
un_chave (ligação com usuario_nivel) -> 1, 2, 3...
Para buscas de dados em tabelas que conténham muitos dados, pretendo chamar uma tela só para a pesquisa (utilizar sql e recuperar a chave_primária) e trazer para o form que chamou, a chave primária localizada, e posicionar o registro para permitir ediçao... etc, etc.... :)
Mas... Como os campos da tabela citada no exemplo acima -> ´usuario_nivel´, praticamente não mudam os valores, gostaria de saber se é melhor fazer um lookup utilizando um dblookupcombobox (me informaram que todos os dados são trazidos do servidor quando se utiliza o dblookcupcombox) ou se tem como fazer isto vindo de um ´arquivo que ficaria em cache nas máquinas cliente?.
Tipo -> Algo como um SavetoFile/Loadfromfile... :)
Enfim... Esse tipo de cache com ClientDataSet eu não sei se é ´possível fazer´ e ´como fazer´ :) para que eu possa utilizar com o ´dblookupcombox´ de uma maneira mais eficaz/rápida.
Se for possível criar este cache, pretendo utilizar a mesma técnica para outras ligações/lookups que retornam poucos dados ou dados que pouco mudam...
Tipo -> Outras tabelas auxiliares tais como: profissao, estado civil, cidades, sexo, etc.
* aproveito ainda para perguntar :)
* se é possivel ler e gravar em cache
* como eu faço para detectar/atualizar neste cache
* possíveis atualizações de dados caso ocorram
* nas tabelas auxiliares que estão no banco/servidor firebird?
desculpem a carta :)
Grato pelas Ajudas...
Luciano-User-BA
Userba
Posts
06/12/2005
Raserafim
ao abrir a aplicação no cliente vc abre tb o ClientDataSet:
ClientDataSet.Open
neste momento o CLientDataSet vai abrir a query que o ProviderDataSet está associado e trazer os registros, depois vai fechar automaticamente a query. agora os dados vão ficar sempre em memória, e no cliente, assim os dados são acessados muito rapidamente. vc pode fazer isso tb, por exemplo, em uma tabela bairros.
06/12/2005
Raserafim
06/12/2005
Emerson Nascimento
numa edição anterior da revista ClubeDelphi - não lembro qual - é abordado esse tema. a sugestão é a seguinte: seu clientdataset com dados ´estrangeiros´ (lookup) estará preparado para abrir um xml que conterá as informações. vamos chamá-lo de ´niveis_usuario.xml´.
você criará uma rotina para procurar pelo arquivo. caso não o encontre ou caso a data de criação ultrapasse 5 dias (ou quantos dias você queira) você traz os dados novamente e sobrepõe o xml. então, antes de abrir o clientdataset, você sempre deve executar a tal rotina.
dessa forma, durante esses 5 dias os dados estarão nesse xml, sem a necessidade de leitura no banco de dados.
você também pode colocar um botão para forçar a atualização dessas informações no momento em que o usuário desejar.
- claro. quando você utiliza ClientDataset´s, tudo está sendo feito em cache. as informações somente serão gravadas fisicamente após um ApplyUpdates sem erros.
- isso pode ser feitos através de [url=http://www.borland.com/resources/en/pdf/white_papers/ib_events.pdf]eventos[/url].
06/12/2005
Userba
Valeu... Já fiz uns testes e funcionou legal.
*** Utilizei o parametro -> dfXMLUTF8 para que pudesse gravar/ler os dados acentuados corretamente.
no oncreate do form:
if fileexists(´niveis_usuario.xml´) then dm_usuario.cds_nivel.LoadFromFile(´niveis_usuario.xml´);
dm_usuario.cds_nivel.Open;
if not fileexists(´niveis_usuario.xml´) then dm_usuario.cds_nivel.SaveToFile(´niveis_usuario.xml´, dfXMLUTF8);
É que... por não saber como funcionava o processo não soube me explicar :)
... O que eu queria saber era se depois de utilizado um ´savetofile´, o clientedataset poderia comparar/identificar possíveis alterações nos dados que estão na base de dados no servidor com o arquivo XML criado na máquina cliente e promover a atualização automaticamente.
Mas acho que vc já deu as respostas :) Tenho que fazer isto manualmente... vou adaptar a rotina para detectar um prazo na data de criação e disponibilizar um button para atualizar manualmente, conforme suas sugestões.
* Aproveitando para esclarecer :) ... Quando o LoadFromFile é executado o clientdataset mostra os dados do arquivo XML (observei isto). Isto quer dizer que o SQLQuery ou SQLDataSet nem abre? Hummm... Se funcina assim... Isso é bom mesmo.
* Eu estava por fora dos metódos SAVE... LOAD...FILE, XMLs, etc... do clientedataset.
Valeu cara... Sua dica foi 10.
Luciano-User-BA
06/12/2005
Userba
Valeu... Já fiz uns testes e funcionou legal.
*** Utilizei o parametro -> dfXMLUTF8 para que pudesse gravar/ler os dados acentuados corretamente.
no oncreate do form:
if fileexists(´niveis_usuario.xml´) then dm_usuario.cds_nivel.LoadFromFile(´niveis_usuario.xml´);
dm_usuario.cds_nivel.Open;
if not fileexists(´niveis_usuario.xml´) then dm_usuario.cds_nivel.SaveToFile(´niveis_usuario.xml´, dfXMLUTF8);
É que... por não saber como funcionava o processo não soube me explicar :)
... O que eu queria saber era se depois de utilizado um ´savetofile´, o clientedataset poderia comparar/identificar possíveis alterações nos dados que estão na base de dados no servidor com o arquivo XML criado na máquina cliente e promover a atualização automaticamente.
Mas acho que vc já deu as respostas :) Tenho que fazer isto manualmente... vou adaptar a rotina para detectar um prazo na data de criação e disponibilizar um button para atualizar manualmente, conforme suas sugestões.
* Aproveitando para esclarecer :) ... Quando o LoadFromFile é executado o clientdataset mostra os dados do arquivo XML (observei isto). Isto quer dizer que o SQLQuery ou SQLDataSet nem abre? Hummm... Se funcina assim... Isso é bom mesmo.
* Eu estava por fora dos metódos SAVE... LOAD...FILE, XMLs, etc... do clientedataset.
Valeu cara... Sua dica foi 10.
Luciano-User-BA
06/12/2005
Emerson Nascimento
você configura seu ClientDataset normalmente: ProviderName, CommandText, etc. e, em FileName, coloca o nome do arquivo xml desejado. depois você cria uma rotina mais ou menos assim (não testei):
procedure TForm1.AbreDatasetXML( var Dataset: TClientDataset ); var NomeArquivo: string; CriaArquivo: boolean; begin NomeArquivo := Dataset.FileName; Dataset.Close; if NomeArquivo <> ´´ then begin if FileExists(NomeArquivo) then // se existe o arquivo, verifico se ele tem mais de 5 dias CriaArquivo := Trunc(Now - FileDateToDateTime(FileAge(NomeArquivo))) > 5 else CriaArquivo := True; if CriaArquivo then begin Dataset.FileName := ´´; // limpa o nome do arquivo e abre o dataset Dataset.Open; // com as informações do CommandText/ProviderName Dataset.SaveToFile(NomeArquivo, dfXMLUTF8); Dataset.Close; Dataset.FileName := NomeArquivo; end; Dataset.Open; end; end;
aí, vc abre os clientdatasets xml a partir dessa procedure.
AbreDatasetXML( ClientDataset_UsuarioNiveis );
se o clientdataset tiver um arquivo informado na sua propriedade FileName, a procedure se encarrega de todo o processo.
06/12/2005
Userba
É ... Com uma função assim, o código fica centralizado, precisando passar apenas o ClientDataSet como parâmetro. Vou colocar num module que abre os CDS auxiliares e testar, se não funcionar eu posto aqui, senão... o pessoal já fica sabendo que sua dica funciona beleza.
Cara! brigadão mesmo pelas dicas... E pela função de brinde :).
Luciano-User-BA
Clique aqui para fazer login e interagir na Comunidade :)