25
242

11 data providers-cursogxxbr

Embed Size (px)

Citation preview

Page 1: 11 data providers-cursogxxbr

242

Page 2: 11 data providers-cursogxxbr

243

Vamos supor que a partir de nosso Billing System, queremos enviar um sistema de devedores e credores, umalistagem dos recibos correspondentes ao último faturamento. Se trata de informação hierárquica (a informaçãoa ser enviada é a de recibos, cada um dos quais possui determinados dados).

XML é o formato mais usual de troca de informação hierárquica, ainda não sabemos o que vai acontecer nofuturo neste aspecto (por exemplo se vai voltar a ser um formato comum ou formato Json).

Page 3: 11 data providers-cursogxxbr

244

Tendo o mesmo SDT Bill que definimos quando estudamos os tipos de dados estruturados (ali o chamamosBill SDT, aqui o chamaremos Bill), estamos utilizando um procedimento com os seguintes parâmetros:

parm( in: &start, in: &end, out: &bills );

sendo &start e &end variáveis de tipo Date que recebem a faixa de faturamento, e &bills uma variável collectiondo SDT Bill.

Observe que estamos utilizando o Data Selector ActiveCustomers para filtrar pelos clientes ativos e utilizando afórmula inline sum, onde unicamente somamos os totais daquelas faturas que pertencem ao cliente da atualiteração do For each e cujas datas se encontrem na faixa informada e tenham o valor True no atributoBooleano InvoicePendingFlag.

Este atributo será alterado a False uma vez que a fatura foi processada dentro do processo de geração derecibos que iniciamos aqui mas que completaremos mais adiante, quando estudarmos as formas de atualizar ainformação da base de dados (aqui somente estamos obtendo a informação dos recibos, mas ainda não osregistraremos na base de dados... ).

Page 4: 11 data providers-cursogxxbr

245

Todo procedimento toma um Input, e mediante alguma transformação, obtêm um Output.

Para obter o Input tendo certa linguagem (em GeneXus se trata da base de dados, basta nomear os atributos,como pode ser visto no exemplo, a direita das atribuições; assim como também se obtêm os parâmetros).

Para realizar a Transformação possui outra linguagem (o código que podemos ver no exemplo) e depois paraexpressar o Output outro mais.

Como pode ver-se, no caso dos procedimentos GeneXus, tanto o Input como o Output se encontram situadosdentro do próprio código de Transformação. Pode se dizer que o foco está colocado na transformação.

Desta forma o propósito do procedimento, sua saída, fica obscura dentro desse código, que mescla:• elementos de saída,

• com elementos de transformação (em nosso caso, o comando for each, o método add e o operadornew, que implementam o armado da coleção de recibos)• e com elementos de entrada.

Page 5: 11 data providers-cursogxxbr

246

Com um Data Provider, o foco está situado na linguagem de saída: observe que é indicado numa estruturahierárquica do que é composto esse Output.

Depois, para cada elemento da estrutura hierárquica, terá que indicar no Source do Data Provider, como secalcula.

Portanto, basta observar o lado esquerdo para deduzir qual será a estrutura resultante.

Depois, é suficiente indicar o formato desejado para essa estrutura hierárquica resultante...

Page 6: 11 data providers-cursogxxbr

247

Depois, uma mesma informação estruturada, pode ser representada utilizando diferentes formatos existentes.

Essa é a idéia do Data Provider. Se num futuro aparecer um novo formato de representação de informaçãoestruturada, o Data Provider continuará sendo o mesmo. GeneXus implementará o método de transformaçãopara esse formato, e somente terá que utilizá-lo.

Page 7: 11 data providers-cursogxxbr

248

Até aqui fizemos uma análise descritiva. Surge a seguinte pergunta: Como em GeneXus representamos asestruturas hierárquicas de dados?

A saída de um Data Provider será um SDT (ou uma coleção de SDTs).

Depois, com essa saída se realiza o desejado, em particular, convertê-la ao formato XML, com o método toXmldos SDTs.

Vejamos como declaramos a saída... não será da forma convencional (como parâmetro de out da regraparm)...

Page 8: 11 data providers-cursogxxbr

249

Aqui vemos para o exemplo que estamos estudando, que tendo o SDT definido Bills, collection, que coincidecom a estrutura que se infere do Source do Data Provider ‘GetBills’, terá que declarar esse SDT napropriedade Output do Data Provider.

Mas não é a única possibilidade ... veremos outra na página seguinte, onde terá sentido a propriedadeCollection.

Page 9: 11 data providers-cursogxxbr

250

Se ao invés de ter o SDT collection Bills, tivéssemos o que aparece acima, Bill, então, poderíamos programar oSource do Data Provider como vemos e depois configurar a propriedade Collection em ‘True’, e uma novapropriedade é aberta, Collection Name, que permitirá dar nome para a coleção.

Este Data Provider é equivalente ao anterior.

Observe que neste caso não é necessário colocar a raiz da hierarquia, Bills, que se infere a propriedade‘Collection Name’. De todas as formas, mesmo não sendo requerido pode-se programar o Source da mesmaforma que o anterior, isto é, com o grupo Bills iniciando a hierarquia.

Bills

{Bill using ActiveCustomers()

{...

}}

Nota: a cláusula using, assim como os where que veremos em seguida, o order, etc., poderão serespecificadas tanto no grupo Bills, como no grupo Bill, em casos como este. Em seguida voltaremos nessetema.

Page 10: 11 data providers-cursogxxbr

251

Os Data Providers resolvem eficientemente um tipo de problema: aquele que consiste em retornar dadosestruturados. Para esse tipo de problemas contávamos com os procedimentos, mas sua desvantagem evidenteera que necessitávamos implementar a forma de armar essas estruturas com operações de baixo nível, comoagregar um item a uma coleção com Add, e pedir memória (new). Assim mesmo, se tivesse que fazer cálculoscomplexos para dar valor a cada membro da estrutura, os elementos de saída estariam incorporados nocódigo, o resultado do Procedimento não acaba sendo de fácil visualização.

Todos estes inconvenientes são evitados com Data Provider. O foco aqui está na saída, razão pela qual aoolhar já se sabe a estrutura do Output. Sendo declarativo, livre da forma que está implementada a carga doSDT. GeneXus se encarrega disso.

Quanto mais declarativo for uma ferramenta, mais fácil de programar, mais adaptável as mudanças, maisindependente de uma implementação particular. GeneXus tende a ser o mais declarativo possível e cada vezprogramar menos ‘procedural’. A forma declarativa tira do programador o problema e passa para aimplementação da ferramenta. Quanto mais inteligente for ferramenta, menos o programador precisa resolver oproblema: basta enunciá-lo.

Page 11: 11 data providers-cursogxxbr

252

Um Data Provider também pode receber parâmetros através da regra parm, mas se diferencia de umprocedimento onde todos os parâmetros podem ser de entrada/saída, aqui somente poderão ser de entrada.

Por outro lado, um procedimento que devolve informação estruturada é feito mediante uma variável que secarrega no código, e que deve declarar-se como de saída, no último parâmetro da regra parm.

Em um Data Provider, a declaração do tipo de dados de saída se faz mediante as propriedades Output, não naregra parm.

A chamada a partir de qualquer objeto GeneXus de um Data Provider é idêntica a chamada de umprocedimento, isto é, com udp.

Lembre que ao chamar um objeto e não especificar o método de chamada, se assume udp.

A variável &TheBills deverá estar declarada no objeto GeneXus que se realiza a chamada. É a variável na qualse devolve o resultado. Lembre que se o SDT definido na KB é o correspondente aos itens individuais: Bill, (enão a coleção Bills), então a variável &TheBills será definida como Collection, de tipo de dados Bill.Depois, com a estrutura hierárquica devolvida pode, por exemplo, ser convertida ao formato desejado, comoXML.

Importante:Como veremos, um Data Provider não somente pode retornar um SDT ou coleção de SDT, como tambémoutro tipo, o Business Component, que também representa informação estruturada. Olhar esse tema paracompletar o conhecimento de Data Providers.

Page 12: 11 data providers-cursogxxbr

253

O exemplo que podemos ver aqui é parecido ao que trabalhamos. Agregamos o elemento BillQuantity. Tire unsinstantes para pensar como deverá ser o SDT BillsInfo, para que se iguale com este Source. A esquerda o queapresentamos.

O Source não precisa ser escrito da mesma forma que a estrutura do SDT. Se o SDT ter um membro collectionde um item determinado, podemos omitir do Source o Item como grupo. Exemplo: com o SDT que temosacima, poderíamos ter escrito o Data Provider:

Billsnfo{

Bills{

BillDate = &todayCustomerName = CustomerName

BillInvoicePeriodStartDate = &startBillInvoicePeriodEndDate = &end

BillAmount = sum (InvoiceAmount, ... )&quantity = &quantity + 1

}BillQuantity = &quantity

}

Com o mesmo resultado. GeneXus tem inteligência suficiente para matchear com o SDT.

Page 13: 11 data providers-cursogxxbr

254

Page 14: 11 data providers-cursogxxbr

255

No exemplo, o grupo de nome Bill será repetitivo. Por que? Para responder a pergunta, vamos fazer outra: e sefor um for each, onde substitua os elementos da esquerda das atribuições por variáveis? Neste caso apresença de CustomerName a direita da segunda atribuição permite afirmar que tem tabela base:CUSTOMER.

Por tanto o grupo será repetitivo, iterando sobre a tabela CUSTOMER.

No exemplo que estamos trabalhando, temos a cláusula:

Bill using ActiveCustomers()

igual:

For each using ActiveCustomers()

se o atributo CustomerName não estivesse na segunda atribuição, da mesma forma seria com tabela base,pela presença do atributo CustomerStatus no Data Selector ‘ActiveCustomers’.

Observe que o grupo de nome BillsInfo, de forma diferente, não será repetitivo, não possui cláusulasassociadas, e os elementos que contêm estão definidos a base de variáveis e não de atributos:

BillQuantity = &quantity&quantity = 0

E o que acontece com o grupo Bills? Observe que neste caso, é um grupo que somente possui outro grupo. Ogrupo contido será repetitivo, porque Bills será uma coleção de Bill. Por este motivo, o subgrupo Bill poderia seromitido (somente deixar Bills) e que fique implícito. Deste modo, as cláusulas do grupo que permitem definirorder, filtros, defined by, podem ser associadas a este grupo.

Page 15: 11 data providers-cursogxxbr

256

Se a condição estiver no grupo Clients, seria aplicada para os dois subgrupos Client. Por isso é permitido queas cláusulas operem nos grupos repetitivos (itens), e não somente do grupo que é coleção de itens.

Page 16: 11 data providers-cursogxxbr

257

Page 17: 11 data providers-cursogxxbr

258

Page 18: 11 data providers-cursogxxbr

259

Page 19: 11 data providers-cursogxxbr

260

A informação completa desse tema em inglês pode ser encontrada em nossa comunidade wiki, na página:

http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Data+Provider+Language

Page 20: 11 data providers-cursogxxbr

261

Page 21: 11 data providers-cursogxxbr

262

Page 22: 11 data providers-cursogxxbr

263

Page 23: 11 data providers-cursogxxbr

264

Não mencionamos, mas de forma intuitiva podemos pensar, de ter um par de grupos “aninhados” (um grupoque, entre outras coisas, contêm outro), se cada um deve acessar a base de dados, então as tabelas base,assim como o critério de navegação são determinados exatamente da mesma forma que no caso de um par defor eachs anhidados.

Por esse motivo, no exemplo, o grupo Country possui tabela base COUNTRY; o grupo Customers possuitabela base CUSTOMER, e terá um join entre ambas tabelas na hora de recuperar a informação para carregara coleção de países. Isto é, para cada registro de COUNTRY será carregada a informação de seus atributosCountryId e CountryName nos elementos Id e Name do item Country do SDT coleção “Countries” que estivercarregando, e depois percorrerá a tabela CUSTOMER filtrando por aqueles registros para os quaisCUSTOMER.CountryId = COUNTRY.CountryId, carregando para cada um os elementos Id e Name.

A presença da cláusula OutputIfDetail faz que somente se apresentam na saída aqueles países que possuamclientes associados. Se um país da base de dados não tiver nenhum cliente, então não será apresentado comoitem da coleção de saída, “Countries”.

Page 24: 11 data providers-cursogxxbr

265

Page 25: 11 data providers-cursogxxbr

266