--- title: Acessando Datasets source: https://tdn.totvs.com/display/fluig/Acessando+Datasets path: \Plataforma Documentação técnica\Desenvolvimento sobre a plataforma\Desenvolvimento de Datasets\Acessando Datasets.md --- # Índice - 1 [Objetivo](#AcessandoDatasets-Objetivo) - 2 [Pré-requisitos](#AcessandoDatasets-Pré-requisitos) - 3 [Acessando um Dataset](#AcessandoDatasets-AcessandoumDataset) - 3.1 [Widgets](#AcessandoDatasets-Widgets) - 3.2 [Via pontos de customização](#AcessandoDatasets-eventos-de-formulariosViapontosdecustomização) - 3.2.1 [Exemplo:](#AcessandoDatasets-Exemplo:) - 3.2.2 [Constraints Avançadas](#AcessandoDatasets-ConstraintsAvançadas) - 3.2.3 [Exemplificação de uso de Constraints](#AcessandoDatasets-ExemplificaçãodeusodeConstraints) - 3.3 [Nova funcionalidade de pesquisa de informação de datasets](#AcessandoDatasets-Novafuncionalidadedepesquisadeinformaçãodedatasets) - 3.4 [Formulários](#AcessandoDatasets-Formulários) - 3.4.1 [Via JavaScript em formulário](#AcessandoDatasets-ViaJavaScriptemformulário) - 3.4.2 [Via Tags no Formulário](#AcessandoDatasets-ViaTagsnoFormulário) - 3.5 [Webservices](#AcessandoDatasets-Webservices) - 3.6 [Via DataTable](#AcessandoDatasets-ViaDataTable) - 3.7 [Acessar dataset via API](#AcessandoDatasets-AcessardatasetviaAPI) - 3.7.1 [Via serviço REST](#AcessandoDatasets-ViaserviçoREST) # Objetivo --- Um Dataset pode ser acessado de várias formas: no desenvolvimento de widgets, formulários, *webservices*, eventos globais, eventos de formulários e eventos de processos. O objetivo desse guia é mostrar como acessar o Dataset nestes cenários. # Pré-requisitos --- Para que se tenha uma compreensão completa destas informações, alguns conhecimentos são considerados pré-requisitos, entre eles: - Visão geral sobre o TOTVS Fluig Plataforma e sobre o [Desenvolvimento de Datasets](../Desenvolvimento de Datasets.md). Atenção! A partir das atualizações **1.6.5 Liquid**, **1.7.0 Lake** e **1.7.1 Crystal Lake**, os *select* passados por *constraint* em dataset serão bloqueados pelo serviço. Orientamos a leitura da documentação [Datasets acessando banco de dados externo](Datasets acessando banco de dados externo.md) que contém um exemplo da correta utilização do procedimento. # Acessando um *Dataset* --- Vários locais da plataforma podem fazer uso dos dados retornados pelos *Datasets*. Serão apresentadas abaixo as variações na forma de acessá-los ou de manuseá-los. ## Widgets No desenvolvimento de um widget, é possível acessar dados de *Datasets*, através da linguagem *Javascript*, utilizando a biblioteca *DatasetFactory*. Consulte a documentação [Integrando widget com formulários/datasets da plataforma](../../Recurso de Páginas e Widgets (WCM)/Construção de Widgets e Layouts/Widgets/Como criar um widget que busque conteúdo/Integrando widget com formuláriosdatasets do Fluig Plataforma.md). ## Via pontos de customização Quando um *Dataset* é acessado via um ponto de customização como eventos globais, eventos de processos, eventos de formulário ou mesmo em outros *Datasets*, isto é feito através de chamadas JavaScript que serão executadas no lado servidor. O exemplo abaixo apresenta um exemplo simples de chamada a um *Dataset*: ``` function doTest1() { var dataset = DatasetFactory.getDataset("group", null, null, null); return dataset.rowsCount; } ``` No exemplo acima, o código JavaScript faz o acesso ao Dataset interno [*group*](http://tdn.totvs.com/display/fluig/Datasets+internos+fluig#Datasetsinternosfluig-group-Gruposdeusu%C3%A1rios), e retorna a quantidade de linhas disponíveis (rowsCount). O objeto **DatasetFactory** é a "porta de entrada" para o acesso a qualquer *Dataset*. Além de permitir a carga de um *Dataset*, ela também permite navegar entre todos os *Datasets* disponíveis no sistema. O acesso a um *Dataset* é feito através do método **getDataset** do objeto **DatasetFactory**, onde seus parâmetros são: - **Nome do Dataset:** Nome do Dataset a ser buscado; - **Campos:** Array com os campos do Dataset que serão retornados. Caso seja informado null, retorna todos os campos do Dataset; - **Constraints:** Array com os condições de busca do Dataset. Caso seja informado null, retorna todos os registros do Dataset. - **Ordem:** Array com os campos para ordenação dos registros do Dataset. Caso seja informado null, retorna os registros com a ordenação padrão. Já para a criação das constraints é utilizado o método **createConstraint**do objeto **DatasetFactory**, onde seus parâmetros são: - **Campo:** Nome do campo que será filtrado; - **Valor Inicial:** Valor inicial da faixa de valores do filtro - **Valor Final:** Valor final da faixa de valores do filtro - **Tipo:** Tipo da condição, podendo ser: - **MUST:** indica que todos os registros do Dataset devem satisfazer a esta condição. - **SHOULD:** indica que os registros do Dataset podem ou não atender à condição. Esse tipo é mais comum quando se necessita que um mesmo campo tenha valores A ou B (onde cada um será uma condição de busca com tipo SHOULD). - **MUST\_NOT:** indica que nenhum dos registros pode satisfazer a condição. Após a criação da constraint, é possível informar que esta será utilizada na consulta em formato de LIKE, ou seja, o valor retornado poderá conter qualquer letra ou sequência de letras no lugar do símbolo '%'. Isso é feito chamando o método setLikeSearch(true) para a constraint que se deseja este comportamento, conforme exemplificado na implementação abaixo, na constraint c5, onde pretende-se retornar todos os registros que NÃO possuam (pois é uma constraint MUST\_NOT) a palavra "teste" na descrição do documento. Exemplo: ``` function doTest2() { //Monta as constraints para consulta var c1 = DatasetFactory.createConstraint("activeVersion", "true", "true", ConstraintType.MUST); var c2 = DatasetFactory.createConstraint("publisherId", "adm", "adm", ConstraintType.MUST_NOT); var c3 = DatasetFactory.createConstraint("documentType", "1", "1", ConstraintType.SHOULD); var c4 = DatasetFactory.createConstraint("documentType", "2", "2", ConstraintType.SHOULD); var c5 = DatasetFactory.createConstraint("documentDescription", "%teste%", "%teste%", ConstraintType.MUST_NOT); c5.setLikeSearch(true); var constraints = new Array(c1, c2, c3, c4, c5); //Define os campos para ordenação var sortingFields = new Array("documentPK.documentId"); //Busca o dataset var dataset = DatasetFactory.getDataset("document", null, constraints, sortingFields); for(var i = 0; i < dataset.rowsCount; i++) { log.info(dataset.getValue(i, "documentPK.documentId")); } } ``` Após a criação da constraint, utiliza-se a função likeSearch utilizando a biblioteca vcXMLRPC.js, deve ser adicionado mais um parâmetro no método DatasetFactory.createConstraint, e não utilizar o método setLikeSearch(true). Exemplo: ``` var c5 = DatasetFactory.createConstraint("documentDescription", "%teste%", "%teste%", ConstraintType.MUST_NOT, true); ``` Isto é válido apenas para a utilização da biblioteca vcXMLRPC.js. Aqui é feito o uso de duas constrainsts do tipo SHOULD. A primeira indica que o campo 'documentType' pode retornar os registros do tipo 2. Já a segunda constraint indica que o campo documentDescription pode retornar todos os registros que possuam pelo menos a palavra teste em seu corpo, e isso se deve ao like estar habilitado por meio de "setLikeSearch(true)" ##### Exemplo: ``` function doTest3() { //Monta as constraints para consulta var c1 = DatasetFactory.createConstraint("documentType", "2", "2", ConstraintType.SHOULD); var c2 = DatasetFactory.createConstraint("documentDescription", "%teste%", "%teste%", ConstraintType.SHOULD); c2.setLikeSearch(true); var constraints = new Array(c1, c2); //Define os campos para ordenação var sortingFields = new Array("documentPK.documentId"); //Busca o dataset var dataset = DatasetFactory.getDataset("document", null, constraints, sortingFields); return dataset; } ``` ##### Constraints Avançadas Existe uma constraint em especial que é utilizada para limitar o número de registros na consulta SQL chamada de **sqlLimit**. Então é possível definir o número máximo de registros que uma consulta SQL pode retornar, porém o número de registros pode ser menor que o esperado, devido algumas validações que são feitas após o retorno dos dados. Por exemplo: O **sqlLimit** tem um valor 100 e é feita uma consulta em um serviço de dados de uma definição de formulário, esta consulta retornará os 100 registros, porém após isso são executadas validações para verificar se o formulário está ativo e se o usuário corrente tem permissão para visualizar os dados fazendo com que o retorno possa ser menor que 100. Para o **sqlLimit** é utilizada a seguinte sintaxe: ``` DatasetFactory.createConstraint("sqlLimit", "10", "10", ConstraintType.MUST); ``` Importante O valor considerado no sqlLimit é sempre o **initialValue**, o que for informado no finalValue não será considerado. Existe outra constraint especial utilizada somente para acesso a Datasets de definições de formulário, ela indica se ao buscar o serviço de dados devem ser retornados APENAS os dados dos formulários da definição de formulário principal. A constraint é a **onlyMainCards** e por padrão seu valor é false, ou seja, são retornados os dados dos formulários da definição de formulário principal e das definições de formulários filhas. ``` DatasetFactory.createConstraint("onlyMainCards", "true", "true", ConstraintType.MUST); ``` Observação O valor considerado no onlyMainCards é sempre o initialValue, o que for informado no finalValue não será considerado. Existe ainda, outra constraint especial que é a **checkSecurity** essa constraint é válida somente para Datasets de formulário e quando utilizada, fará o retorno dos registros do formulário validarem a segurança, ou seja, o Dataset retornará somente os registros de formulário que o usuário possua permissão para visualização. ``` DatasetFactory.createConstraint("checkSecurity", "true", "true", ConstraintType.MUST); ``` Atenção As constraints são aplicáveis apenas a Datasets internos. Em Datasets avançados, elas podem não ser suportadas, pois os dados provêm de fontes externas. No entanto, é possível implementar filtros na codificação do Dataset, desde que o desenvolvedor tenha preparado o código para aceitar e processar essas restrições, manipulando o objeto retornado para remover informações desnecessárias. Dica A constraint 'offset' define o ponto de início da pesquisa no dataset, permitindo a implementação de paginação. ``` DatasetFactory.createConstraint("offset", "10", "10", ConstraintType.MUST); ``` A constraint *offset* permite definir quantos registros iniciais devem ser ignorados no resultado da consulta, retornando os próximos registros. Exemplo: Ao usar a constraint *offset* com o valor *10*, os primeiros 10 registros encontrados na consulta serão ignorados, e os próximos registros serão retornados conforme o limite definido. ##### Exemplificação de uso de Constraints Considere os valores da tabela abaixo sendo utilizadas como um serviço de dados a partir de uma definição de formulário para exemplificação dos exemplos: | Código | Nome | Cidade | | --- | --- | --- | | 1 | Javier Spiva | São Paulo | | 2 | Cody Ballow | Rio de Janeiro | | 3 | Javier Naramore | São Paulo | | 4 | Max Nevius | Rio de Janeiro | | 5 | Noemi Roiger | São Paulo | | 6 | Lonnie Cadwallader | Rio de Janeiro | | 7 | Lorrie Spece | Brasília | Verifique os exemplos de retorno de dados abaixo: Para retornar somente as linhas que os códigos estejam entre 1 á 4 usar a seguinte constraint: ``` var c1 = DatasetFactory.createConstraint("Código", "1", "4", ConstraintType.MUST); ``` Retorno: | Código | Nome | Cidade | | --- | --- | --- | | 1 | Javier Spiva | São Paulo | | 2 | Cody Ballow | Rio de Janeiro | | 3 | Javier Naramore | São Paulo | | 4 | Max Nevius | Rio de Janeiro | Para retornar somente as linhas que os nomes sejam "Noemi Roiger", "Javier Naramore" e "Lonnie Cadwallader" ou que a cidade seja Brasília, usar as seguintes constraints: ``` var c1 = DatasetFactory.createConstraint("nome", "Noemi Roiger", "Noemi Roiger", ConstraintType.SHOULD); var c2 = DatasetFactory.createConstraint("nome", "Javier Naramore", " Javier Naramore", ConstraintType.SHOULD); var c3 = DatasetFactory.createConstraint("nome", "Lonnie Cadwallader", "Lonnie Cadwallader", ConstraintType.SHOULD); var c4 = DatasetFactory.createConstraint("cidade", "Brasília", "Brasília", ConstraintType. SHOULD); ``` Retorno: | Código | Nome | Cidade | | --- | --- | --- | | 3 | Javier Naramore | São Paulo | | 5 | Noemi Roiger | São Paulo | | 6 | Lonnie Cadwallader | Rio de Janeiro | | 7 | Lorrie Spece | Brasília | Para retornar todas as linhas exceto onde a cidade seja Brasília, usar a seguinte constraint: ``` var c1 = DatasetFactory.createConstraint("cidade", "Brasília", "Brasília", ConstraintType.MUST_NOT); ``` Retorno: | Código | Nome | Cidade | | --- | --- | --- | | 1 | Javier Spiva | São Paulo | | 2 | Cody Ballow | Rio de Janeiro | | 3 | Javier Naramore | São Paulo | | 4 | Max Nevius | Rio de Janeiro | | 5 | Noemi Roiger | São Paulo | | 6 | Lonnie Cadwallader | Rio de Janeiro | ## Nova funcionalidade de pesquisa de informação de datasets --- No exemplo abaixo, o código JavaScript faz o acesso ao Dataset interno **“documents”**, e retorna a quantidade de linhas disponíveis . O objeto datasets é a **"porta de entrada"** para o acesso a qualquer Dataset. Além de permitir a carga de um Dataset, ela também permite navegar entre todos os Datasets disponíveis no sistema. ``` function doTest1() { var listDocuments = datasets.get("document").search({}); return listDocuments.length; } ``` O acesso a um Dataset é feito através do método **get** do objeto **dataset**, passando o parâmetro - **Nome do Dataset:** Nome do Dataset a ser buscado; No método **search** é informado os parâmetros que irão compor os filtros, ordenação e limite da busca. **Campo:** Nome do campo que será filtrado. - **Value**: Valor a ser filtrado, - **Not**: Séria para a mesma lógica de **MUST\_NOT**, onde não deve satisfazer condição ou valor passado. - **Like:** Realizar pesquisa para encontrar correspondência com o valor informado. - **Between:** Esse parâmetro é para realizar a pesquisa entre um valor inicial e final. - **SHOULD:** Indica que os registros do Dataset podem ou não atender à condição. Esse tipo é mais comum quando se necessita que um mesmo campo tenha valores A ou B (onde cada um será uma condição de busca com tipo **SHOULD**). **Limit:** Total de registros que irá ser retornado. **Offset:** Define quantas linhas devem ser puladas antes que os resultados comecem a ser retornados. **Order:** Especifica a coluna pela qual deseja ordenar os resultados. Exemplo da utilização do **search** com os **filtros, limit e offset**. ``` var listDocuments = datasets.get("document").search({ "documentType": { "value": ["1", "2"], "not": "true", "like": "true", "between": ["1", "2"] }, "order": ["documentPK.documentId"], "limit": 50, "offset": 20 }); ``` O parâmetro **SHOULD,** deve ser utilizado da seguinte forma. ``` var listDocuments = datasets.get("document").search({ "documentType": ["1", "2"] }); ``` **Observação**: Por enquanto é permitido utilizar apenas uma vez o **SHOULD**, não vai ser permitido utilizar para dois tipos diferentes. **Retorno dos registros.** O retorno dos registros é feito no formato JSON. Exemplo: ``` [{ "versionDescription" : "", "visualization" : null, "inheritApprovers" : false, "imutable" : null, "downloadEnabled" : false, "metaListId" : 0 }] ``` Para recuperar os dados e adicionar nas colunas do dataset, é possível recuperar os dados de duas formas - **[index][“campo”]**, passando a String do campo - **[index].campo**, ou pelo objeto. **Observação:** Para campos que é necessário acessar outros dados, como o id e a versão do documento, vai ser possível recuperar passando a String dentro de uma chave, **“[index]["documentPK.documentId"]”.** Nos exemplos a seguir, será mostrado das duas formas. No exemplo a seguir é feito uma busca dos documentos com o filtro do tipo **SHOULD,** onde e para retornar os documentos do tipo 1 e 2 **(Pasta e documento).** ``` var newDataset = DatasetBuilder.newDataset(); newDataset.addColumn("Document ID"); newDataset.addColumn("Document version"); newDataset.addColumn("Document Name"); newDataset.addColumn("Document Type"); var listDocuments = datasets.get("document").search({ "documentType": ["1", "2"] }); for(var index = 0; index < listDocuments.length; index++) { newDataset.addRow([ listDocuments[index]["documentPK.documentId"], listDocuments[index]["documentPK.version"], listDocuments[index].documentDescription, listDocuments[index].documentType ]); } return newDataset; ``` **** No exemplo a seguir, será realizada a pesquisa de documentos para retornar os registros que contenham a palavra **“API”,** utilizando o like e como o limite de cinco registros. ``` var newDataset = DatasetBuilder.newDataset(); newDataset.addColumn("Document ID"); newDataset.addColumn("Document version"); newDataset.addColumn("Document Name"); newDataset.addColumn("Document Type"); var listDocuments = datasets.get("document").search({ "documentDescription": { "value": "%API%", "like": true }, "limit": 5 }); for(var index = 0; index < listDocuments.length; index++) { newDataset.addRow([ listDocuments[index]["documentPK.documentId"], listDocuments[index]["documentPK.version"], listDocuments[index].documentDescription, listDocuments[index]["documentType"] ]); } return newDataset; ```  ## Formulários Em formulários, é possível que um ou mais campos possam exibir ou consultar dados de Datasets utilizando Javascript ou tags. ### Via JavaScript em formulário --- É possível acessar os Datasets via código JavaScript no HTML de uma definição de formulário utilizando a biblioteca **vcXMLRPC.js**para utilização do *DatasetFactory*. Para isto, basta incluir a linha abaixo antes da tag body do HTML: ``` ``` Importante Este modelo de acesso faz com que o Dataset seja transportado do servidor para o cliente, ou seja, o navegador do usuário. Por isso, é importante observar a quantidade de informações que será manuseada, caso contrário pode-se ter problemas de consumo excessivo de banda ou performance. **Exemplo:** ``` function showNewDatasetFull() { var div = document.getElementById("datasetDiv"); //Busca o dataset try { var dataset = DatasetFactory.getDataset("colleague"); div.innerHTML = showDataset(dataset); } catch(erro) { div.innerHTML = erro; } } function showDataset(dataset) { var tabela = "
| " + dataset.columns[i] + " | "; } tabela += "
|---|
| " + row[dataset.columns[y]] + " | "; } tabela += "