Setup dos Dados
Introdução
Com o Netuno o desenvolvimento das aplicações passa primeiro pela construção da base de dados, através da construção dos formulário e campos.
E quando se trabalha em equipa ou é preciso passar o desenvolvimento da aplicação para outro ambiente, é necessário criar um backup da base de dados acompanhado do código.
Assim no destino será necessário reconfigurar a base de dados e assim a aplicação vai poder ser executada como foi desenvolvida na sua origem.
O problema deste processo é o esforço de se lembrar sempre de criar um novo backup cada vez que há uma alteração na base de dados. E quantas mais pessoas estão envolvidas no desenvolvimento e/ou quanto mais ambientes há para publicar a aplicação, mais complicado se torna este processo.
Então o Netuno para resolver este problema traz um sistema de setup das aplicações, onde gera automaticamente a estrutura da base de dados (schema), e adicionalmente permite ser programado manualmente o carregamento dos dados iniciais através de scripts adicionais.
Também permite alterar o tipo de servidor de base de dados garantindo que o setup será executado com normalidade e a aplicação sem qualquer problema. Isto quer dizer que a aplicação pode ser desenvolvida em H2DataBase e com o schemas gerados automaticamente poderá alterar a conexão da base de dados da aplicação para PostgreSQL ou MariaDB. Na primeira execução da aplicação sobre a nova base de dados tudo será reconstruído, independente da alteração do tipo de servidor de base de dados.
Então permite que a base de dados seja completamente alterada sem ter impacto no desenvolvimento já realizado.
Os arquivos de programação do setup encontram-se dentro da pasta da aplicação em:
server/setup
Configuração de Setup
Nas configurações de ambiente das aplicações que ficam em:
/apps/MINHA_APP/config/_development.json/apps/MINHA_APP/config/_production.json
Poderá manipular o comportamento do 'setup' através das configurações:
...
"setup": {
"enabled": true,
"schema": {
"auto_create": true,
"execution": true
},
"scripts": {
"execution": true
}
},
...
enabled: boolean > default true
Define se o setup está ativo ou não, e assim ativa ou desativa, na primeira vez que a aplicação será executada, a execução das operações de setup dos dados.
schema.auto_create: boolean > default true
Permite ao Netuno saber se deve ou não gerar os arquivos de schema de base de dados sempre que é criado ou alterado algum formulário ou campo.
schema.execution: boolean > default true
Controla se o schema deve ser executado ou não durante as operações de setup realizadas na primeira execução da aplicação.
scripts.execution: boolean > default true
Ativa ou desativa a execução dos scripts adicionais durante as operações de setup realizadas na primeira execução da aplicação.
Schema
Durante a criação ou alteração dos formulários e campos na interface web do Netuno será gerado os arquivos de schema dentro da pasta setup com da seguinte forma:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
server/setup/_schema-NOME_DO_FORMULARIO.js
server/setup/_schema-NOME_DO_FORMULARIO.py
server/setup/_schema-NOME_DO_FORMULARIO.rb
server/setup/_schema-NOME_DO_FORMULARIO.kts
server/setup/_schema-NOME_DO_FORMULARIO.groovy
Onde haverá um arquivo _schema-*** para cada formulário existente na aplicação.
Estes arquivos não devem ser alterados manualmente por que são gerados automaticamente pelo Netuno.
Assim, caso altere o conteúdo destes arquivos, numa próxima geração dos schemas serão substituídos automaticamente e as alterações realizadas diretamente nos arquivos serão perdidas.
Para a geração automática do schema de base de dados ser executada é preciso certificar-se que a configuração schema.auto_create está ativa, e que a pasta setup existe dentro da pasta server.
Scripts
Scripts de código programado à medida são arquivos localizados na pasta setup que não comecem com _.
O principal objetivo destes scripts é carregar os dados garantindo que a base de dados contém a informação mínima necessária para o correto funcionamento da aplicação.
Assim quando a aplicação for reconfigurada noutro ambiente será automaticamente carregada com os dados iniciais ficando pronta para começar a sua utilização.
Para realizar estas operações de carregamento de dados deverá utilizar as funções do recurso _db.
Os scripts são executados a seguir à execução dos schemas pela ordem alfanumérica do nome dos arquivos
que não iniciam com _.
Iniciar o nome dos arquivos com uma sequência numérica é o ideal para definir a ordem de execução, portanto os scripts personalizados são executados pela ordem do nome dos arquivos que não iniciam com
_.
Inserir Dados Personalizados
E, para poupar o trabalho de realizar consultas na base de dados, para verificar se poderá ser feito o insert
de dados ou não, o Netuno disponibiliza a função insertIfNotExists.
Esta função verifica se existem os dados exatamente como eles estão definidos na base de dados, se não existirem então realiza a sua criação.
Um exemplo da sua utilização será carregar os campos Código e Nome do formulário Tipo de Território, onde o nome da tabela é tipo_territorio e tem as colunas codigo e nome, para tal bastará criar o arquivo com o seguinte conteúdo:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nome", "Continental")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nome", "Arquipelágico")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nome", "Marítimo")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nome", "Aéreo")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nome", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nome", "Arquipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nome", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nome", "Aéreo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nome", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nome", "Arquipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nome", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nome", "Aéreo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nome", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nome", "Arquipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nome", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nome", "Aéreo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nome", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nome", "Arquipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nome", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nome", "Aéreo")
)
Ciclo de Processamento
Como já foi explicado, o setup apenas é executado na primeira execução da aplicação.
E a ordem de execução é:
_start- executa o arquivo de inicialização que pode conter qualquer tipo de programação customizada:- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
MINHA_APP/server/setup/_start.js
MINHA_APP/server/setup/_start.py
MINHA_APP/server/setup/_start.rb
MINHA_APP/server/setup/_start.kts
MINHA_APP/server/setup/_start.groovy
_cleanup- executa a remoção de formulários, relatórios e os respectivos campos programaticamente:- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
MINHA_APP/server/setup/_cleanup.js
MINHA_APP/server/setup/_cleanup.py
MINHA_APP/server/setup/_cleanup.rb
MINHA_APP/server/setup/_cleanup.kts
MINHA_APP/server/setup/_cleanup.groovy
_schema-*- executa todos os scripts com o prefixo _schema-, contém os comandos de criação dos formulários, relatórios e os respectivos campos:- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
MINHA_APP/server/setup/_schema-estrutura_autogerada.jsMINHA_APP/server/setup/_schema-categoria.jsMINHA_APP/server/setup/_schema-produto.jsMINHA_APP/server/setup/_schema-cliente.js
MINHA_APP/server/setup/_schema-estrutura_autogerada.pyMINHA_APP/server/setup/_schema-categoria.pyMINHA_APP/server/setup/_schema-produto.pyMINHA_APP/server/setup/_schema-cliente.py
MINHA_APP/server/setup/_schema-estrutura_autogerada.rbMINHA_APP/server/setup/_schema-categoria.rbMINHA_APP/server/setup/_schema-produto.rbMINHA_APP/server/setup/_schema-cliente.rb
MINHA_APP/server/setup/_schema-estrutura_autogerada.ktsMINHA_APP/server/setup/_schema-categoria.ktsMINHA_APP/server/setup/_schema-produto.ktsMINHA_APP/server/setup/_schema-cliente.kts
MINHA_APP/server/setup/_schema-estrutura_autogerada.groovyMINHA_APP/server/setup/_schema-categoria.groovyMINHA_APP/server/setup/_schema-produto.groovyMINHA_APP/server/setup/_schema-cliente.groovy
001-outros_scripts- executa os arquivos de scripts programados à medida, são todos os arquivos que não começam com_e que provavelmente conterão os inserts de dados iniciais necessários ou outros desenvolvimentos personalizados, por exemplo:- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
MINHA_APP/server/setup/001-insere_dados_personalizados.jsMINHA_APP/server/setup/002-categoria.jsMINHA_APP/server/setup/003-produto.jsMINHA_APP/server/setup/004-cliente.js
MINHA_APP/server/setup/001-insere_dados_personalizados.pyMINHA_APP/server/setup/002-categoria.pyMINHA_APP/server/setup/003-produto.pyMINHA_APP/server/setup/004-cliente.py
MINHA_APP/server/setup/001-insere_dados_personalizados.rbMINHA_APP/server/setup/002-categoria.rbMINHA_APP/server/setup/003-produto.rbMINHA_APP/server/setup/004-cliente.rb
MINHA_APP/server/setup/001-insere_dados_personalizados.ktsMINHA_APP/server/setup/002-categoria.ktsMINHA_APP/server/setup/003-produto.ktsMINHA_APP/server/setup/004-cliente.kts
MINHA_APP/server/setup/001-insere_dados_personalizados.groovyMINHA_APP/server/setup/002-categoria.groovyMINHA_APP/server/setup/003-produto.groovyMINHA_APP/server/setup/004-cliente.groovy
- _end - executa o arquivo de finalização que pode conter qualquer tipo de programação customizada:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
MINHA_APP/server/setup/_end.js
MINHA_APP/server/setup/_end.py
MINHA_APP/server/setup/_end.rb
MINHA_APP/server/setup/_end.kts
MINHA_APP/server/setup/_end.groovy
Ou seja, é permitida a criação de código à medida nos scripts start e end para realizar algumas operações que façam sentido serem executadas previamente ao setup ou mesmo quando este é concluído.
Convém reforçar que este ciclo de processamento é executado sempre que a aplicação é executada pela primeira vez, por isso é que é necessário garantir a verificação da existência dos dados antes de realizar a sua criação.
Certifique-se que as seguintes configurações de ambiente se encontram ativas para permitir a execução deste
processo nos arquivos MINHA_APP/config/_development.json ou MINHA_APP/config/_production.json consoante o
ambiente:
-
Ativa ou desativa completamente a execução de qualquer operação de setup:
setup.enabled = true|false -
Ativa ou desativa a execução dos _schemas-:
setup.schema.execution = true|false -
Ativa ou desativa a execução dos scripts:
setup.scripts.execution = true|false
Limpeza
Para programar a remoção de formulários e campos devemos utilizar o script _cleanup.js, o que garante
que todos os ambientes que sincronizam os arquivos do projeto, na execução do setup a estrutura será removida,
caso exista.
Exemplo do script de limpeza:
- JavaScript
- Python
- Ruby
- Kotlin
- Groovy
// Remove o formulário zona:
_form.dropIfExists("zona");
// Remove o campo subarea_id do formulário area:
_form.dropFieldIfExists("area", "subarea_id");
# Remove o formulário zona:
_form.dropIfExists("zona")
# Remove o campo subarea_id do formulário area:
_form.dropFieldIfExists("area", "subarea_id")
# Remove o formulário zona:
_form.dropIfExists("zona")
# Remove o campo subarea_id do formulário area:
_form.dropFieldIfExists("area", "subarea_id")
// Remove o formulário zona:
_form.dropIfExists("zona")
// Remove o campo subarea_id do formulário area:
_form.dropFieldIfExists("area", "subarea_id")
// Remove o formulário zona:
_form.dropIfExists("zona")
// Remove o campo subarea_id do formulário area:
_form.dropFieldIfExists("area", "subarea_id")
DBML
Sempre que o Netuno executa o setup dos dados é gerado o arquivo:
server/setup/_db-schema.dbml
Este é o arquivo com toda a estrutura de dados que pode ser utilizado com Inteligência Artificial.
Com base no conteúdo do DBML a Inteligência Artificial entende a estrutura de dados e pode gerar queries SQL precisas.
Experimente utilizar este arquivo como anexo no prompt e peça para gerar queries SQL complexas, vai conseguir obter bons resultados.
Conclusão
O processo de setup das aplicações no Netuno tem como principais funções:
- _schema-: gera automaticamente toda a estrutura de formulários e relatórios com os seus repectivos campos, que permitem garantir toda a coerência da estrutura da base de dados da aplicação, principalmente quando a aplicação é executada com uma nova base de dados vazia.
- scripts: realizar operações de base de dados para garantir que a aplicação contém os dados obrigatórios previamente carregados sempre que é executada pela primeira vez.
Desta forma o Netuno permite que as aplicações funcionem em novos ambientes, mesmo que altere o tipo de base de dados, garantindo o correto funcionamento da aplicação sem a necessidade de realizar backups e restore das bases de dados.
Permitindo adicionalmente que todo o código de configuração gerado de forma automática e manual seja versionado com o GIT, por exemplo.