Ué? É ADODataSet ou ClientDataSet?
Olá a todos novamente.
Primeiramente quero pedir dois milhões de desculpas por não ter postado nestas últimas semanas... Mudei de emprego, estou em novo projeto e agora as coisas estão voltando para os eixos.
Indo diretamente ao assunto (o bom de escrever na net é que a reclamação só vem em forma de comentário mais tarde hehe), vou mostrar duas coisas muito legais no componente TADODataSet.
Quem conhece o TClientDataSet sabe de suas inúmeras vantagens ao desenvolver aplicativos com acesso a bases de dados (inclusive 'desconectado'). Este componente é parte da tecnologia MIDAS (google, por favor!) que principalmente visa desenvolvimento em várias camadas, sendo o TClientDataSet usado na parte de apresentação (interface), o DataSetProvider no meio e qualquer descendente de TDataSet (TADODataSet, TSQLDataSet, TBDEDataSet, etc) na parte de acesso ao servidor de banco de dados.
Além desta forma há várias outras de se trabalhar com o TClientDataSet - Isso é assunto para um (ou até mais) post inteiro dedicado a isso - Um aspecto muito interessante do TClientDataSet é que ele trabalha com dados no cache local do aplicativo, guardando as alterações feitas nos dados em um pacote transacional e aplicando tudo de uma vez no servidor quando ordenado. Outra forma é trabalhar totalmente desconectado, usando dados em memória ou de um arquivo XML. Isso é muito útil quando nós precisamos guardar parâmetros do aplicativo ou 'tabelas auxiliares' que não ficam no banco de dados.
MIDAS é uma tecnologia da Borland e se você usá-la para desenvolver deve enviar a biblioteca midas.dll junto com seu aplicativo - Quem usa Delphi 7 tem opção de compilar a MIDAS junto com o aplicativo: só adicionar a unit MidasLib na seção uses de qualquer unit do projeto.
Quem não quer (ou não pode) usar MIDAS não precisa se desesperar! O componente TADODataSet possui quase todas (senão todas) essas funcionalidades também. Com ele você pode:
- Trabalhar conectado com banco de dados;
- Enviar cada ação realizada ao banco de dados; ou
- Trabalhar no cache local e enviar um pacote transacional completo;
- Trabalhar com o DataSet em memória;
- Ler e gravar diretamente de um arquivo XML
Oba! XML! Legal! Vou fazer isso, e aquilo e zás, e zás.... Caaaaalma.....
Embora a parada do XML seja muito boa vou logo alertando: O Formato é o padrão do formato de XML ADO (não é ADO.NET) da Microsoft. Eu nunca testei, mas em teoria dá para interagir com um Recordset de uma aplicação VB ou ASP, porque é o mesmo objeto COM. Vou fazer este teste depois e mandar o resultado aqui.
Ah! Que droga! É verdade... mas o TClientDataSet é assim também. Ele usa um formato de XML padrão da Borland. Nada impede de você codificar por quilometragem e montar um super-hiper-mega-ultra programa que é o XML-o-matic que faz tudo... Eu e o Gerson estamos estudando uma forma de fazer tal coisa, mas isso é assunto para outro post (e outra viagem!).
Bem, para aqueles que tiveram paciência de ler até aqui, chegou a parte que todos estavam esperando: Vamos ver (mais ou menos) na prática.
Na Palheta ADO você encontra o ADODataSet. Ao analisar as propriedades dele repare na LockType. Os valores mais usados são ltOptimistic e ltBatchOptimistic.
O ltOptimistic é o modo de travamento de registro padrão que os outros DataSets operam e o ltBatchOptimistic também, mas com uma diferença entre eles: o ltBatchOptimistic trabalha com atualizações em cache local, enquanto o ltOptimistic leva cada alteração para o servidor de BD.
Então, para trabalhar com ele conectado no BD e a interface conectada diretamente nele, uma boa opção é usar o LockType como ltBatchOptimistic. Aí, os métodos Post e Delete não vão gravar direto no BD. Os dados vão efetivamente para o banco quando você (o DataSet) chamar o método UpdateBatch. Legal, né? Já dá pra fazer aquele mestre-detalhes complexo com um pacote transacional.
Se você trabalhar no esquema multicamadas (n-tier), onde vai usar ADODataSet na parte servidora, DataSetProvider para transmitir os dados de lá pra cá e daqui pra lá, e o ClientDataSet na parte da interface, uma boa pedida e deixar o ADODataSet como unidirecional. Com ele unidirecional aloca menos memória da aplicação servidora e faz o acesso mais rápido aos dados, já que ele só sabe mover o cursor para frente. Para fazer isso defina a propriedade CursorType como ctOpenForwardOnly. Ele trabalha como o SQLDataSet do DBExpress.
Caso você queira trabalhar com ele em memória ou com arquivo XML (ou seja, sem tomar conhecimento de servidor de banco de dados), você também pode. É Só abrir o Fields Editor (duplo-clique no componente) e ir adicionando campos da mesma forma que você cria campos calculados ou lookups, mas estes são do tipo fkData, ao invés de fkCalculated ou fkLookup. Aí, para poder ter acesso a estes dados em memória (e conectar a DBGrid, DBEdit, etc, etc e até fazer lookup é só chamar o método CreateDataSet do ADODataSet antes de trabalhar com ele.
Quando o ADODataSet está ativo (Active como True), é possível salvar o pacote de dados em formato XML ou ADTG, um formato binário proprietário da MS. Basta chamar o método SaveToFile do ADODataSet, especificando qual é o arquivo e qual o formato (pfADTG ou pfXML).
Quando você define a propriedade CommandType para ctFile você pode definir na propriedade CommandText o caminho para um arquivo XML ou ADTG com os dados (ou só a estrutura também) que ele passa a trabalhar diretamente neste arquivo. Aí, para gravar alterações é só chamar o método SaveToFile passando '' para o nome do arquivo (aí ele usa o CommandText) e o formato que está usando.
Acabou sendo um pouco mais longo do que eu pensava mas, mais uma vez, me desculpe pela grande falta nestas semanas e obrigado pela força de sempre. Como usual, a seção de comentários está à vontade. Não deixe de comentar, deixar sugestões, dicas e qualquer coisa que quiser...
Grande abraço e até a próxima.