@designliquido/delegua-entidades 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -0
- package/fontes/analisador-dicas.d.ts +49 -0
- package/fontes/analisador-dicas.d.ts.map +1 -0
- package/fontes/analisador-dicas.js +145 -0
- package/fontes/analisador-dicas.js.map +1 -0
- package/fontes/cache-consultas.d.ts +39 -0
- package/fontes/cache-consultas.d.ts.map +1 -0
- package/fontes/cache-consultas.js +98 -0
- package/fontes/cache-consultas.js.map +1 -0
- package/fontes/carregador-lotes.d.ts +64 -0
- package/fontes/carregador-lotes.d.ts.map +1 -0
- package/fontes/carregador-lotes.js +148 -0
- package/fontes/carregador-lotes.js.map +1 -0
- package/fontes/carregador-preguicoso.d.ts +34 -0
- package/fontes/carregador-preguicoso.d.ts.map +1 -0
- package/fontes/carregador-preguicoso.js +157 -0
- package/fontes/carregador-preguicoso.js.map +1 -0
- package/fontes/colecao.d.ts +74 -0
- package/fontes/colecao.d.ts.map +1 -0
- package/fontes/colecao.js +374 -0
- package/fontes/colecao.js.map +1 -0
- package/fontes/construtor-consulta.d.ts +129 -0
- package/fontes/construtor-consulta.d.ts.map +1 -0
- package/fontes/construtor-consulta.js +446 -0
- package/fontes/construtor-consulta.js.map +1 -0
- package/fontes/contexto-entidades.d.ts +119 -0
- package/fontes/contexto-entidades.d.ts.map +1 -0
- package/fontes/contexto-entidades.js +329 -0
- package/fontes/contexto-entidades.js.map +1 -0
- package/fontes/detector-n-mais-um.d.ts +87 -0
- package/fontes/detector-n-mais-um.d.ts.map +1 -0
- package/fontes/detector-n-mais-um.js +225 -0
- package/fontes/detector-n-mais-um.js.map +1 -0
- package/fontes/entidade.d.ts +82 -0
- package/fontes/entidade.d.ts.map +1 -0
- package/fontes/entidade.js +467 -0
- package/fontes/entidade.js.map +1 -0
- package/fontes/erros/erro-concorrencia.d.ts +11 -0
- package/fontes/erros/erro-concorrencia.d.ts.map +1 -0
- package/fontes/erros/erro-concorrencia.js +18 -0
- package/fontes/erros/erro-concorrencia.js.map +1 -0
- package/fontes/erros/erro-tabela-nao-encontrada.d.ts +4 -0
- package/fontes/erros/erro-tabela-nao-encontrada.d.ts.map +1 -0
- package/fontes/erros/erro-tabela-nao-encontrada.js +11 -0
- package/fontes/erros/erro-tabela-nao-encontrada.js.map +1 -0
- package/fontes/erros/erro-validacao.d.ts +9 -0
- package/fontes/erros/erro-validacao.d.ts.map +1 -0
- package/fontes/erros/erro-validacao.js +13 -0
- package/fontes/erros/erro-validacao.js.map +1 -0
- package/fontes/erros/index.d.ts +4 -0
- package/fontes/erros/index.d.ts.map +1 -0
- package/fontes/erros/index.js +20 -0
- package/fontes/erros/index.js.map +1 -0
- package/fontes/gerenciador-cache.d.ts +87 -0
- package/fontes/gerenciador-cache.d.ts.map +1 -0
- package/fontes/gerenciador-cache.js +147 -0
- package/fontes/gerenciador-cache.js.map +1 -0
- package/fontes/ilc/gerador-definicoes.d.ts +13 -0
- package/fontes/ilc/gerador-definicoes.d.ts.map +1 -0
- package/fontes/ilc/gerador-definicoes.js +96 -0
- package/fontes/ilc/gerador-definicoes.js.map +1 -0
- package/fontes/ilc/gerador-entidades.d.ts +10 -0
- package/fontes/ilc/gerador-entidades.d.ts.map +1 -0
- package/fontes/ilc/gerador-entidades.js +318 -0
- package/fontes/ilc/gerador-entidades.js.map +1 -0
- package/fontes/ilc/leitor-configuracao.d.ts +32 -0
- package/fontes/ilc/leitor-configuracao.d.ts.map +1 -0
- package/fontes/ilc/leitor-configuracao.js +124 -0
- package/fontes/ilc/leitor-configuracao.js.map +1 -0
- package/fontes/ilc/migracoes.d.ts +3 -0
- package/fontes/ilc/migracoes.d.ts.map +1 -0
- package/fontes/ilc/migracoes.js +215 -0
- package/fontes/ilc/migracoes.js.map +1 -0
- package/fontes/ilc/semeadura.d.ts +2 -0
- package/fontes/ilc/semeadura.d.ts.map +1 -0
- package/fontes/ilc/semeadura.js +50 -0
- package/fontes/ilc/semeadura.js.map +1 -0
- package/fontes/indicadores-performance/executor-analise-performance.d.ts +80 -0
- package/fontes/indicadores-performance/executor-analise-performance.d.ts.map +1 -0
- package/fontes/indicadores-performance/executor-analise-performance.js +212 -0
- package/fontes/indicadores-performance/executor-analise-performance.js.map +1 -0
- package/fontes/indicadores-performance/index.d.ts +26 -0
- package/fontes/indicadores-performance/index.d.ts.map +1 -0
- package/fontes/indicadores-performance/index.js +199 -0
- package/fontes/indicadores-performance/index.js.map +1 -0
- package/fontes/interfaces-tipos/analise-n1-interface.d.ts +13 -0
- package/fontes/interfaces-tipos/analise-n1-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/analise-n1-interface.js +3 -0
- package/fontes/interfaces-tipos/analise-n1-interface.js.map +1 -0
- package/fontes/interfaces-tipos/atributo-interface.d.ts +30 -0
- package/fontes/interfaces-tipos/atributo-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/atributo-interface.js +3 -0
- package/fontes/interfaces-tipos/atributo-interface.js.map +1 -0
- package/fontes/interfaces-tipos/coluna-computada-interface.d.ts +16 -0
- package/fontes/interfaces-tipos/coluna-computada-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/coluna-computada-interface.js +3 -0
- package/fontes/interfaces-tipos/coluna-computada-interface.js.map +1 -0
- package/fontes/interfaces-tipos/configuracao-banco-dados-interface.d.ts +48 -0
- package/fontes/interfaces-tipos/configuracao-banco-dados-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/configuracao-banco-dados-interface.js +3 -0
- package/fontes/interfaces-tipos/configuracao-banco-dados-interface.js.map +1 -0
- package/fontes/interfaces-tipos/entidade-interface.d.ts +37 -0
- package/fontes/interfaces-tipos/entidade-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/entidade-interface.js +3 -0
- package/fontes/interfaces-tipos/entidade-interface.js.map +1 -0
- package/fontes/interfaces-tipos/ganchos.d.ts +12 -0
- package/fontes/interfaces-tipos/ganchos.d.ts.map +1 -0
- package/fontes/interfaces-tipos/ganchos.js +3 -0
- package/fontes/interfaces-tipos/ganchos.js.map +1 -0
- package/fontes/interfaces-tipos/index.d.ts +17 -0
- package/fontes/interfaces-tipos/index.d.ts.map +1 -0
- package/fontes/interfaces-tipos/index.js +33 -0
- package/fontes/interfaces-tipos/index.js.map +1 -0
- package/fontes/interfaces-tipos/indice-interface.d.ts +16 -0
- package/fontes/interfaces-tipos/indice-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/indice-interface.js +3 -0
- package/fontes/interfaces-tipos/indice-interface.js.map +1 -0
- package/fontes/interfaces-tipos/informacao-consulta-interface.d.ts +12 -0
- package/fontes/interfaces-tipos/informacao-consulta-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/informacao-consulta-interface.js +3 -0
- package/fontes/interfaces-tipos/informacao-consulta-interface.js.map +1 -0
- package/fontes/interfaces-tipos/muito-para-muitos-interface.d.ts +33 -0
- package/fontes/interfaces-tipos/muito-para-muitos-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/muito-para-muitos-interface.js +3 -0
- package/fontes/interfaces-tipos/muito-para-muitos-interface.js.map +1 -0
- package/fontes/interfaces-tipos/opcoes-serializacao-interface.d.ts +14 -0
- package/fontes/interfaces-tipos/opcoes-serializacao-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/opcoes-serializacao-interface.js +3 -0
- package/fontes/interfaces-tipos/opcoes-serializacao-interface.js.map +1 -0
- package/fontes/interfaces-tipos/polimorfico-interface.d.ts +32 -0
- package/fontes/interfaces-tipos/polimorfico-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/polimorfico-interface.js +3 -0
- package/fontes/interfaces-tipos/polimorfico-interface.js.map +1 -0
- package/fontes/interfaces-tipos/relacionamento-interface.d.ts +23 -0
- package/fontes/interfaces-tipos/relacionamento-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/relacionamento-interface.js +3 -0
- package/fontes/interfaces-tipos/relacionamento-interface.js.map +1 -0
- package/fontes/interfaces-tipos/restricao-interface.d.ts +14 -0
- package/fontes/interfaces-tipos/restricao-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/restricao-interface.js +3 -0
- package/fontes/interfaces-tipos/restricao-interface.js.map +1 -0
- package/fontes/interfaces-tipos/semente-interface.d.ts +7 -0
- package/fontes/interfaces-tipos/semente-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/semente-interface.js +3 -0
- package/fontes/interfaces-tipos/semente-interface.js.map +1 -0
- package/fontes/interfaces-tipos/tabela-interface.d.ts +12 -0
- package/fontes/interfaces-tipos/tabela-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/tabela-interface.js +3 -0
- package/fontes/interfaces-tipos/tabela-interface.js.map +1 -0
- package/fontes/interfaces-tipos/transacao-interface.d.ts +35 -0
- package/fontes/interfaces-tipos/transacao-interface.d.ts.map +1 -0
- package/fontes/interfaces-tipos/transacao-interface.js +3 -0
- package/fontes/interfaces-tipos/transacao-interface.js.map +1 -0
- package/fontes/migracoes/executor-migracoes.d.ts +14 -0
- package/fontes/migracoes/executor-migracoes.d.ts.map +1 -0
- package/fontes/migracoes/executor-migracoes.js +177 -0
- package/fontes/migracoes/executor-migracoes.js.map +1 -0
- package/fontes/migracoes/gerador-migracoes.d.ts +15 -0
- package/fontes/migracoes/gerador-migracoes.d.ts.map +1 -0
- package/fontes/migracoes/gerador-migracoes.js +108 -0
- package/fontes/migracoes/gerador-migracoes.js.map +1 -0
- package/fontes/migracoes/migracao.d.ts +35 -0
- package/fontes/migracoes/migracao.d.ts.map +1 -0
- package/fontes/migracoes/migracao.js +66 -0
- package/fontes/migracoes/migracao.js.map +1 -0
- package/fontes/migracoes/semeador.d.ts +18 -0
- package/fontes/migracoes/semeador.d.ts.map +1 -0
- package/fontes/migracoes/semeador.js +109 -0
- package/fontes/migracoes/semeador.js.map +1 -0
- package/fontes/rastreador-mudancas.d.ts +27 -0
- package/fontes/rastreador-mudancas.d.ts.map +1 -0
- package/fontes/rastreador-mudancas.js +94 -0
- package/fontes/rastreador-mudancas.js.map +1 -0
- package/fontes/relacionamento.d.ts +11 -0
- package/fontes/relacionamento.d.ts.map +1 -0
- package/fontes/relacionamento.js +15 -0
- package/fontes/relacionamento.js.map +1 -0
- package/fontes/roteador-bancos.d.ts +50 -0
- package/fontes/roteador-bancos.d.ts.map +1 -0
- package/fontes/roteador-bancos.js +90 -0
- package/fontes/roteador-bancos.js.map +1 -0
- package/fontes/serializador.d.ts +46 -0
- package/fontes/serializador.d.ts.map +1 -0
- package/fontes/serializador.js +79 -0
- package/fontes/serializador.js.map +1 -0
- package/fontes/taquigrafia.d.ts +41 -0
- package/fontes/taquigrafia.d.ts.map +1 -0
- package/fontes/taquigrafia.js +96 -0
- package/fontes/taquigrafia.js.map +1 -0
- package/fontes/tipos.d.ts +3 -0
- package/fontes/tipos.d.ts.map +1 -0
- package/fontes/tipos.js +3 -0
- package/fontes/tipos.js.map +1 -0
- package/fontes/transacao.d.ts +81 -0
- package/fontes/transacao.d.ts.map +1 -0
- package/fontes/transacao.js +243 -0
- package/fontes/transacao.js.map +1 -0
- package/fontes/validacoes/validador.d.ts +19 -0
- package/fontes/validacoes/validador.d.ts.map +1 -0
- package/fontes/validacoes/validador.js +157 -0
- package/fontes/validacoes/validador.js.map +1 -0
- package/index.d.ts +36 -0
- package/index.d.ts.map +1 -0
- package/index.js +59 -0
- package/index.js.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<br>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<h3 align="center">Delégua Entidades</h3>
|
|
5
|
+
<p align="center">
|
|
6
|
+
Biblioteca Node.js com o intuito de trabalhar com entidades de dados, com base nas instruções da <a href="https://github.com/DesignLiquido/delegua" target="_blank">Linguagem Delégua</a>, junto com o framework <a href="https://github.com/DesignLiquido/liquido" target="_blank">Liquido</a>.
|
|
7
|
+
</p>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://github.com/DesignLiquido/delegua-entidades/issues" target="_blank">
|
|
12
|
+
<img src="https://img.shields.io/github/issues/DesignLiquido/delegua-entidades" />
|
|
13
|
+
</a>
|
|
14
|
+
<img src="https://img.shields.io/github/stars/DesignLiquido/delegua-entidades" />
|
|
15
|
+
<img src="https://img.shields.io/github/forks/DesignLiquido/delegua-entidades" />
|
|
16
|
+
<a href="https://www.npmjs.com/package/DesignLiquido/delegua-entidades" target="_blank">
|
|
17
|
+
<img src="https://img.shields.io/npm/v/DesignLiquido/delegua-entidades" />
|
|
18
|
+
</a>
|
|
19
|
+
<img src="https://img.shields.io/npm/dw/DesignLiquido/delegua-entidades" />
|
|
20
|
+
<img src="https://img.shields.io/github/license/DesignLiquido/delegua-entidades" />
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
## Motivação
|
|
24
|
+
|
|
25
|
+
[LinConEs](https://github.com/DesignLiquido/LinConEs) nasceu da necessidade de uma linguagem de consulta em português. No entanto, escrever código de produção diretamente com uma linguagem de consulta pode ocasionar uma série de problemas, como por exemplo ataques por _SQL Injection_, uma técnica bem conhecida em que uma consulta pode ser forjada para executar operações não desejadas pelos desenvolvedores originais.
|
|
26
|
+
|
|
27
|
+
Entidades é uma biblioteca para Delégua que trabalha com estruturas de manipulação de dados em alto nível, e que torna possível uma série de funcionalidades, como por exemplo:
|
|
28
|
+
|
|
29
|
+
- Gerar código em linguagem de consulta de maneira segura, a partir de classes e objetos em Delégua, observando parâmetros e impedindo a injeção de outras consultas indesejadas nas operações da sua aplicação;
|
|
30
|
+
- Trabalhar de maneira agnóstica, não importando qual tecnologia de dados esteja sendo usada, seja a própria memória do servidor, um banco de dados, etc.
|
|
31
|
+
|
|
32
|
+
Essa biblioteca usa uma outra biblioteca chamada `lincones-js`, onde uma lógica menos especializada é implementada para ler sentenças escritas em LinConEs e traduzi-las para SQL. Como um passo intermediário dessa tradução, há a geração de objetos de alto nível que representam comandos a serem executados em SQL. Esta biblioteca, portanto, utiliza código Delégua para também gerar esses objetos de operações de bancos de dados de alto nível, que então são utilizados por bibliotecas especializadas em uma ou outra tecnologia para a geração do SQL final.
|
|
33
|
+
|
|
34
|
+
### Inspiração
|
|
35
|
+
|
|
36
|
+
- [Active Record (Ruby on Rails)](https://guides.rubyonrails.org/active_record_basics.html);
|
|
37
|
+
- [SQLAlchemy (Python)](https://www.sqlalchemy.org/)
|
|
38
|
+
- [Entity Framework (.NET)](https://learn.microsoft.com/en-us/aspnet/entity-framework)
|
|
39
|
+
|
|
40
|
+
## Utilização
|
|
41
|
+
|
|
42
|
+
Esta biblioteca funciona por si só apenas com [Delégua](https://github.com/DesignLiquido/delegua), mas seu maior proveito ocorre com a utilização de outras bibliotecas, usadas para escrever diversas aplicações, como sistemas Web usando [Líquido](https://github.com/DesignLiquido/liquido). Ao usar apenas por si só, toda a geração de sentenças pode ser feita ou em LinConEs, ou em SQL ANSI. Ao ser combinadas com outras bibliotecas, pode ser usada na geração de SQL mais direcionado, como por exemplo para SQLite ou PostgreSQL.
|
|
43
|
+
|
|
44
|
+
O ponto de entrada dessa biblioteca é uma classe chamada `ContextoEntidades`. Esta classe contém uma série do que chamamos de coleções de dados. Cada coleção é mapeada ou como uma _collection_ de documentos ou registros (por exemplo, se usamos NoSQL), ou como uma tabela de banco de dados (quando o banco de dados é relacional). É cada uma dessas classes de coleções que geram as sentenças que as bibliotecas tecnológicas utilizam.
|
|
45
|
+
|
|
46
|
+
Para melhor ilustrar este funcionamento, vamos supor uma tabela de banco de dados de artigos. Cada artigo possui um identificador (abreviado como `id`), um título (texto) e um conteúdo (também texto). Em Delégua, cada linha desta tabela pode ser mapeada como a seguinte classe:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
classe Artigo {
|
|
50
|
+
id: numero
|
|
51
|
+
titulo: texto
|
|
52
|
+
conteudo: texto
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Se queremos selecionar todos os artigos dessa classe e imprimi-los usando apenass Delégua, podemos fazê-lo da seguinte forma:
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
const entidades = importar('entidades')
|
|
60
|
+
const contexto = entidades.Contexto()
|
|
61
|
+
const artigos = contexto.colecao(Artigo).todos()
|
|
62
|
+
escreva(artigos) // Imprime a lista de todos os artigos encontrados.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Colunas computadas
|
|
66
|
+
|
|
67
|
+
Colunas computadas podem ser declaradas com o decorador `@computada`, informando a expressao SQL e se a coluna e persistida:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
classe Pedido {
|
|
71
|
+
id: numero
|
|
72
|
+
quantidade: numero
|
|
73
|
+
preco: numero
|
|
74
|
+
|
|
75
|
+
@computada({ expressao: "quantidade * preco", persistida: verdadeiro })
|
|
76
|
+
total: numero
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Colunas computadas nao sao incluídas em inserts/updates, mas podem ser lidas normalmente nas consultas.
|
|
81
|
+
|
|
82
|
+
### Comandos
|
|
83
|
+
|
|
84
|
+
Entidades conta com alguns comandos de seleção e manipulação de dados:
|
|
85
|
+
|
|
86
|
+
- `contexto.colecao(Modelo).todos()`
|
|
87
|
+
- `contexto.colecao(Modelo).obterPorId()`
|
|
88
|
+
- `contexto.colecao(Modelo).obterPorCondicao()`
|
|
89
|
+
|
|
90
|
+
Há também comandos de geração de SQL, se for interessante obter a consulta gerada antes da execução:
|
|
91
|
+
|
|
92
|
+
- `contexto.modelo(Modelo).gerarSQLSelecionar()`
|
|
93
|
+
|
|
94
|
+
## Execução por linha de comando
|
|
95
|
+
|
|
96
|
+
Este pacote não funciona sozinho em modo por linha de comando. É necessário também instalar um dos pacotes específicos de tecnologia de LinConEs.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sistema de Dicas de Otimização
|
|
3
|
+
*
|
|
4
|
+
* Fornece recomendações para otimizar consultas baseado em padrões detectados.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum TipoDica {
|
|
7
|
+
INDICE_AUSENTE = "INDICE_AUSENTE",
|
|
8
|
+
N_MAIS_1 = "N_MAIS_1",
|
|
9
|
+
SELECAO_DESNECESSARIA = "SELECAO_DESNECESSARIA",
|
|
10
|
+
JUNCAO_REDUNDANTE = "JUNCAO_REDUNDANTE",
|
|
11
|
+
PAGINACAO_FALTANTE = "PAGINACAO_FALTANTE",
|
|
12
|
+
ORDEM_INEFICIENTE = "ORDEM_INEFICIENTE",
|
|
13
|
+
USAR_CARGA_ANTECIPADA = "USAR_CARGA_ANTECIPADA",
|
|
14
|
+
USAR_CARGA_EM_LOTE = "USAR_CARGA_EM_LOTE",
|
|
15
|
+
CACHE_RECOMENDADA = "CACHE_RECOMENDADA"
|
|
16
|
+
}
|
|
17
|
+
export declare enum NivelSeveridade {
|
|
18
|
+
CRITICO = "CRITICO",
|
|
19
|
+
ALTO = "ALTO",
|
|
20
|
+
MEDIO = "MEDIO",
|
|
21
|
+
BAIXO = "BAIXO",
|
|
22
|
+
INFO = "INFO"
|
|
23
|
+
}
|
|
24
|
+
export interface Dica {
|
|
25
|
+
tipo: TipoDica;
|
|
26
|
+
severidade: NivelSeveridade;
|
|
27
|
+
mensagem: string;
|
|
28
|
+
sugestao: string;
|
|
29
|
+
metrica?: {
|
|
30
|
+
nome: string;
|
|
31
|
+
valor: number;
|
|
32
|
+
unidade: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export declare class AnalisadorDicas {
|
|
36
|
+
/**
|
|
37
|
+
* Analisa consulta e retorna dicas de otimização
|
|
38
|
+
*/
|
|
39
|
+
static analisar(sql: string, metricasExecucao?: {
|
|
40
|
+
tempoMs: number;
|
|
41
|
+
linhas: number;
|
|
42
|
+
contagemJuncoes: number;
|
|
43
|
+
}): Dica[];
|
|
44
|
+
/**
|
|
45
|
+
* Formata dicas para exibição
|
|
46
|
+
*/
|
|
47
|
+
static formatarDicas(dicas: Dica[]): string;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=analisador-dicas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analisador-dicas.d.ts","sourceRoot":"","sources":["../../fontes/analisador-dicas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oBAAY,QAAQ;IAChB,cAAc,mBAAmB;IACjC,QAAQ,aAAa;IACrB,qBAAqB,0BAA0B;IAC/C,iBAAiB,sBAAsB;IACvC,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;IACvC,qBAAqB,0BAA0B;IAC/C,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;CAC1C;AAED,oBAAY,eAAe;IACvB,OAAO,YAAY;IACnB,IAAI,SAAS;IACb,KAAK,UAAU;IACf,KAAK,UAAU;IACf,IAAI,SAAS;CAChB;AAED,MAAM,WAAW,IAAI;IACjB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,eAAe,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;CACL;AAED,qBAAa,eAAe;IACxB;;OAEG;IACH,MAAM,CAAC,QAAQ,CACX,GAAG,EAAE,MAAM,EACX,gBAAgB,CAAC,EAAE;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,eAAe,EAAE,MAAM,CAAC;KAC3B,GACF,IAAI,EAAE;IAoET;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM;CAwD9C"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Sistema de Dicas de Otimização
|
|
4
|
+
*
|
|
5
|
+
* Fornece recomendações para otimizar consultas baseado em padrões detectados.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.AnalisadorDicas = exports.NivelSeveridade = exports.TipoDica = void 0;
|
|
9
|
+
var TipoDica;
|
|
10
|
+
(function (TipoDica) {
|
|
11
|
+
TipoDica["INDICE_AUSENTE"] = "INDICE_AUSENTE";
|
|
12
|
+
TipoDica["N_MAIS_1"] = "N_MAIS_1";
|
|
13
|
+
TipoDica["SELECAO_DESNECESSARIA"] = "SELECAO_DESNECESSARIA";
|
|
14
|
+
TipoDica["JUNCAO_REDUNDANTE"] = "JUNCAO_REDUNDANTE";
|
|
15
|
+
TipoDica["PAGINACAO_FALTANTE"] = "PAGINACAO_FALTANTE";
|
|
16
|
+
TipoDica["ORDEM_INEFICIENTE"] = "ORDEM_INEFICIENTE";
|
|
17
|
+
TipoDica["USAR_CARGA_ANTECIPADA"] = "USAR_CARGA_ANTECIPADA";
|
|
18
|
+
TipoDica["USAR_CARGA_EM_LOTE"] = "USAR_CARGA_EM_LOTE";
|
|
19
|
+
TipoDica["CACHE_RECOMENDADA"] = "CACHE_RECOMENDADA";
|
|
20
|
+
})(TipoDica || (exports.TipoDica = TipoDica = {}));
|
|
21
|
+
var NivelSeveridade;
|
|
22
|
+
(function (NivelSeveridade) {
|
|
23
|
+
NivelSeveridade["CRITICO"] = "CRITICO";
|
|
24
|
+
NivelSeveridade["ALTO"] = "ALTO";
|
|
25
|
+
NivelSeveridade["MEDIO"] = "MEDIO";
|
|
26
|
+
NivelSeveridade["BAIXO"] = "BAIXO";
|
|
27
|
+
NivelSeveridade["INFO"] = "INFO";
|
|
28
|
+
})(NivelSeveridade || (exports.NivelSeveridade = NivelSeveridade = {}));
|
|
29
|
+
class AnalisadorDicas {
|
|
30
|
+
/**
|
|
31
|
+
* Analisa consulta e retorna dicas de otimização
|
|
32
|
+
*/
|
|
33
|
+
static analisar(sql, metricasExecucao) {
|
|
34
|
+
const dicas = [];
|
|
35
|
+
// Detecta SELECT *
|
|
36
|
+
if (sql.toLowerCase().includes("select *")) {
|
|
37
|
+
dicas.push({
|
|
38
|
+
tipo: TipoDica.SELECAO_DESNECESSARIA,
|
|
39
|
+
severidade: NivelSeveridade.MEDIO,
|
|
40
|
+
mensagem: "Consulta usa SELECT * (todas as colunas)",
|
|
41
|
+
sugestao: "Especifique apenas as colunas necessárias para melhorar performance"
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Detecta múltiplos JOINs
|
|
45
|
+
const juncoes = (sql.match(/join/gi) || []).length;
|
|
46
|
+
if (juncoes > 2) {
|
|
47
|
+
dicas.push({
|
|
48
|
+
tipo: TipoDica.JUNCAO_REDUNDANTE,
|
|
49
|
+
severidade: NivelSeveridade.ALTO,
|
|
50
|
+
mensagem: `Consulta tem ${juncoes} junções (acima do recomendado)`,
|
|
51
|
+
sugestao: "Considere usar eager loading ou reorganizar a estrutura de dados",
|
|
52
|
+
metrica: {
|
|
53
|
+
nome: "Junções",
|
|
54
|
+
valor: juncoes,
|
|
55
|
+
unidade: "quantidade"
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// Detecta falta de LIMIT
|
|
60
|
+
if (!sql.toLowerCase().includes("limit") && !sql.toLowerCase().includes("top")) {
|
|
61
|
+
dicas.push({
|
|
62
|
+
tipo: TipoDica.PAGINACAO_FALTANTE,
|
|
63
|
+
severidade: NivelSeveridade.ALTO,
|
|
64
|
+
mensagem: "Consulta sem LIMITE pode retornar muitas linhas",
|
|
65
|
+
sugestao: "Adicione paginação com LIMITE e DESLOCAMENTO para dados em larga escala"
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Análise de desempenho se métricas disponíveis
|
|
69
|
+
if (metricasExecucao) {
|
|
70
|
+
if (metricasExecucao.tempoMs > 1000 && metricasExecucao.linhas > 10000) {
|
|
71
|
+
dicas.push({
|
|
72
|
+
tipo: TipoDica.CACHE_RECOMENDADA,
|
|
73
|
+
severidade: NivelSeveridade.ALTO,
|
|
74
|
+
mensagem: "Consulta lenta com muitos resultados",
|
|
75
|
+
sugestao: "Use cache para resultados desta consulta ou otimize índices",
|
|
76
|
+
metrica: {
|
|
77
|
+
nome: "Tempo",
|
|
78
|
+
valor: metricasExecucao.tempoMs,
|
|
79
|
+
unidade: "ms"
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (metricasExecucao.tempoMs > 500 && juncoes > 0) {
|
|
84
|
+
dicas.push({
|
|
85
|
+
tipo: TipoDica.USAR_CARGA_EM_LOTE,
|
|
86
|
+
severidade: NivelSeveridade.MEDIO,
|
|
87
|
+
mensagem: "JOINs resultando em consulta lenta",
|
|
88
|
+
sugestao: "Considere usar carga em lote em vez de junções diretas"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return dicas;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Formata dicas para exibição
|
|
96
|
+
*/
|
|
97
|
+
static formatarDicas(dicas) {
|
|
98
|
+
if (dicas.length === 0) {
|
|
99
|
+
return "✅ Nenhuma dica de otimização necessária";
|
|
100
|
+
}
|
|
101
|
+
const linhas = [
|
|
102
|
+
`📋 Dicas de Otimização (${dicas.length} encontrada${dicas.length > 1 ? 's' : ''}):`,
|
|
103
|
+
""
|
|
104
|
+
];
|
|
105
|
+
// Agrupa por severidade
|
|
106
|
+
const porSeveridade = new Map();
|
|
107
|
+
for (const dica of dicas) {
|
|
108
|
+
if (!porSeveridade.has(dica.severidade)) {
|
|
109
|
+
porSeveridade.set(dica.severidade, []);
|
|
110
|
+
}
|
|
111
|
+
porSeveridade.get(dica.severidade).push(dica);
|
|
112
|
+
}
|
|
113
|
+
// Ordem de severidade
|
|
114
|
+
const ordem = [
|
|
115
|
+
NivelSeveridade.CRITICO,
|
|
116
|
+
NivelSeveridade.ALTO,
|
|
117
|
+
NivelSeveridade.MEDIO,
|
|
118
|
+
NivelSeveridade.BAIXO,
|
|
119
|
+
NivelSeveridade.INFO
|
|
120
|
+
];
|
|
121
|
+
for (const severidade of ordem) {
|
|
122
|
+
const dicasPorSev = porSeveridade.get(severidade);
|
|
123
|
+
if (!dicasPorSev)
|
|
124
|
+
continue;
|
|
125
|
+
const icone = {
|
|
126
|
+
[NivelSeveridade.CRITICO]: "🔴",
|
|
127
|
+
[NivelSeveridade.ALTO]: "🟠",
|
|
128
|
+
[NivelSeveridade.MEDIO]: "🟡",
|
|
129
|
+
[NivelSeveridade.BAIXO]: "🔵",
|
|
130
|
+
[NivelSeveridade.INFO]: "ℹ️"
|
|
131
|
+
};
|
|
132
|
+
linhas.push(`\n${icone[severidade]} ${severidade}:`);
|
|
133
|
+
for (const dica of dicasPorSev) {
|
|
134
|
+
linhas.push(` • ${dica.mensagem}`);
|
|
135
|
+
linhas.push(` → ${dica.sugestao}`);
|
|
136
|
+
if (dica.metrica) {
|
|
137
|
+
linhas.push(` | ${dica.metrica.nome}: ${dica.metrica.valor} ${dica.metrica.unidade}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return linhas.join("\n");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.AnalisadorDicas = AnalisadorDicas;
|
|
145
|
+
//# sourceMappingURL=analisador-dicas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analisador-dicas.js","sourceRoot":"","sources":["../../fontes/analisador-dicas.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAEH,IAAY,QAUX;AAVD,WAAY,QAAQ;IAChB,6CAAiC,CAAA;IACjC,iCAAqB,CAAA;IACrB,2DAA+C,CAAA;IAC/C,mDAAuC,CAAA;IACvC,qDAAyC,CAAA;IACzC,mDAAuC,CAAA;IACvC,2DAA+C,CAAA;IAC/C,qDAAyC,CAAA;IACzC,mDAAuC,CAAA;AAC3C,CAAC,EAVW,QAAQ,wBAAR,QAAQ,QAUnB;AAED,IAAY,eAMX;AAND,WAAY,eAAe;IACvB,sCAAmB,CAAA;IACnB,gCAAa,CAAA;IACb,kCAAe,CAAA;IACf,kCAAe,CAAA;IACf,gCAAa,CAAA;AACjB,CAAC,EANW,eAAe,+BAAf,eAAe,QAM1B;AAcD,MAAa,eAAe;IACxB;;OAEG;IACH,MAAM,CAAC,QAAQ,CACX,GAAW,EACX,gBAIC;QAED,MAAM,KAAK,GAAW,EAAE,CAAC;QAEzB,mBAAmB;QACnB,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,qBAAqB;gBACpC,UAAU,EAAE,eAAe,CAAC,KAAK;gBACjC,QAAQ,EAAE,0CAA0C;gBACpD,QAAQ,EAAE,qEAAqE;aAClF,CAAC,CAAC;QACP,CAAC;QAED,0BAA0B;QAC1B,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACnD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YACd,KAAK,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,iBAAiB;gBAChC,UAAU,EAAE,eAAe,CAAC,IAAI;gBAChC,QAAQ,EAAE,gBAAgB,OAAO,iCAAiC;gBAClE,QAAQ,EAAE,kEAAkE;gBAC5E,OAAO,EAAE;oBACL,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,OAAO;oBACd,OAAO,EAAE,YAAY;iBACxB;aACJ,CAAC,CAAC;QACP,CAAC;QAED,yBAAyB;QACzB,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7E,KAAK,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,QAAQ,CAAC,kBAAkB;gBACjC,UAAU,EAAE,eAAe,CAAC,IAAI;gBAChC,QAAQ,EAAE,iDAAiD;gBAC3D,QAAQ,EAAE,yEAAyE;aACtF,CAAC,CAAC;QACP,CAAC;QAED,gDAAgD;QAChD,IAAI,gBAAgB,EAAE,CAAC;YACnB,IAAI,gBAAgB,CAAC,OAAO,GAAG,IAAI,IAAI,gBAAgB,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;gBACrE,KAAK,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,QAAQ,CAAC,iBAAiB;oBAChC,UAAU,EAAE,eAAe,CAAC,IAAI;oBAChC,QAAQ,EAAE,sCAAsC;oBAChD,QAAQ,EAAE,6DAA6D;oBACvE,OAAO,EAAE;wBACL,IAAI,EAAE,OAAO;wBACb,KAAK,EAAE,gBAAgB,CAAC,OAAO;wBAC/B,OAAO,EAAE,IAAI;qBAChB;iBACJ,CAAC,CAAC;YACP,CAAC;YAED,IAAI,gBAAgB,CAAC,OAAO,GAAG,GAAG,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChD,KAAK,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,QAAQ,CAAC,kBAAkB;oBACjC,UAAU,EAAE,eAAe,CAAC,KAAK;oBACjC,QAAQ,EAAE,oCAAoC;oBAC9C,QAAQ,EAAE,wDAAwD;iBACrE,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAa;QAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,yCAAyC,CAAC;QACrD,CAAC;QAED,MAAM,MAAM,GAAG;YACX,2BAA2B,KAAK,CAAC,MAAM,cAAc,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI;YACpF,EAAE;SACL,CAAC;QAEF,wBAAwB;QACxB,MAAM,aAAa,GAAG,IAAI,GAAG,EAA2B,CAAC;QACzD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBACtC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC3C,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QAED,sBAAsB;QACtB,MAAM,KAAK,GAAG;YACV,eAAe,CAAC,OAAO;YACvB,eAAe,CAAC,IAAI;YACpB,eAAe,CAAC,KAAK;YACrB,eAAe,CAAC,KAAK;YACrB,eAAe,CAAC,IAAI;SACvB,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;YAC7B,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,WAAW;gBAAE,SAAS;YAE3B,MAAM,KAAK,GAAG;gBACV,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI;gBAC/B,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI;gBAC5B,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,IAAI;gBAC7B,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,IAAI;gBAC7B,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,IAAI;aAC/B,CAAC;YAEF,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC;YAErD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEtC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CACP,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAC9E,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;CACJ;AA1ID,0CA0IC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare class CacheConsultas<T = any> {
|
|
2
|
+
private cache;
|
|
3
|
+
private limite;
|
|
4
|
+
private estatisticas;
|
|
5
|
+
constructor(limite?: number);
|
|
6
|
+
/**
|
|
7
|
+
* Gera chave única para a consulta
|
|
8
|
+
*/
|
|
9
|
+
private gerarChave;
|
|
10
|
+
/**
|
|
11
|
+
* Obtém consulta do cache se existir
|
|
12
|
+
*/
|
|
13
|
+
obter(sql: string, parametros?: any[]): T | null;
|
|
14
|
+
/**
|
|
15
|
+
* Armazena consulta no cache
|
|
16
|
+
*/
|
|
17
|
+
armazenar(sql: string, consulta: T, parametros?: any[]): void;
|
|
18
|
+
/**
|
|
19
|
+
* Remove entrada menos usada/mais antiga
|
|
20
|
+
*/
|
|
21
|
+
private limparEntrada;
|
|
22
|
+
/**
|
|
23
|
+
* Limpa todo o cache
|
|
24
|
+
*/
|
|
25
|
+
limparTudo(): void;
|
|
26
|
+
/**
|
|
27
|
+
* Retorna estatísticas de cache
|
|
28
|
+
*/
|
|
29
|
+
obterEstatisticas(): {
|
|
30
|
+
tamanho: number;
|
|
31
|
+
limite: number;
|
|
32
|
+
acertos: number;
|
|
33
|
+
extravios: number;
|
|
34
|
+
limpezas: number;
|
|
35
|
+
taxaAcerto: string;
|
|
36
|
+
utilizacao: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=cache-consultas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-consultas.d.ts","sourceRoot":"","sources":["../../fontes/cache-consultas.ts"],"names":[],"mappings":"AAYA,qBAAa,cAAc,CAAC,CAAC,GAAG,GAAG;IAC/B,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAIlB;gBAEU,MAAM,GAAE,MAAY;IAIhC;;OAEG;IACH,OAAO,CAAC,UAAU;IAKlB;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI;IAehD;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IAe7D;;OAEG;IACH,OAAO,CAAC,aAAa;IAsBrB;;OAEG;IACH,UAAU,IAAI,IAAI;IAKlB;;OAEG;IACH,iBAAiB;;;;;;;;;CAgBpB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CacheConsultas = void 0;
|
|
4
|
+
class CacheConsultas {
|
|
5
|
+
constructor(limite = 100) {
|
|
6
|
+
this.cache = new Map();
|
|
7
|
+
this.estatisticas = {
|
|
8
|
+
acertos: 0,
|
|
9
|
+
extravios: 0,
|
|
10
|
+
limpezas: 0
|
|
11
|
+
};
|
|
12
|
+
this.limite = limite;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Gera chave única para a consulta
|
|
16
|
+
*/
|
|
17
|
+
gerarChave(sql, parametros = []) {
|
|
18
|
+
const parametrosStr = JSON.stringify(parametros);
|
|
19
|
+
return `${sql}:${parametrosStr}`;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Obtém consulta do cache se existir
|
|
23
|
+
*/
|
|
24
|
+
obter(sql, parametros) {
|
|
25
|
+
const chave = this.gerarChave(sql, parametros);
|
|
26
|
+
const entrada = this.cache.get(chave);
|
|
27
|
+
if (entrada) {
|
|
28
|
+
entrada.acessos++;
|
|
29
|
+
entrada.ultimoAcesso = new Date();
|
|
30
|
+
this.estatisticas.acertos++;
|
|
31
|
+
return entrada.consulta;
|
|
32
|
+
}
|
|
33
|
+
this.estatisticas.extravios++;
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Armazena consulta no cache
|
|
38
|
+
*/
|
|
39
|
+
armazenar(sql, consulta, parametros) {
|
|
40
|
+
const chave = this.gerarChave(sql, parametros);
|
|
41
|
+
// Limpar se cache cheio
|
|
42
|
+
if (this.cache.size >= this.limite) {
|
|
43
|
+
this.limparEntrada();
|
|
44
|
+
}
|
|
45
|
+
this.cache.set(chave, {
|
|
46
|
+
consulta,
|
|
47
|
+
acessos: 0,
|
|
48
|
+
ultimoAcesso: new Date()
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Remove entrada menos usada/mais antiga
|
|
53
|
+
*/
|
|
54
|
+
limparEntrada() {
|
|
55
|
+
let chaveParaRemover = null;
|
|
56
|
+
let menorPontuacao = Infinity;
|
|
57
|
+
for (const [chave, entrada] of this.cache.entries()) {
|
|
58
|
+
// Pontuação = acessos + dias desde último acesso (penalidade)
|
|
59
|
+
const diasDesdeAcesso = (new Date().getTime() - entrada.ultimoAcesso.getTime()) / (1000 * 60 * 60 * 24);
|
|
60
|
+
const pontuacao = entrada.acessos - (diasDesdeAcesso * 0.1);
|
|
61
|
+
if (pontuacao < menorPontuacao) {
|
|
62
|
+
menorPontuacao = pontuacao;
|
|
63
|
+
chaveParaRemover = chave;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (chaveParaRemover) {
|
|
67
|
+
this.cache.delete(chaveParaRemover);
|
|
68
|
+
this.estatisticas.limpezas++;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Limpa todo o cache
|
|
73
|
+
*/
|
|
74
|
+
limparTudo() {
|
|
75
|
+
this.cache.clear();
|
|
76
|
+
this.estatisticas = { acertos: 0, extravios: 0, limpezas: 0 };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Retorna estatísticas de cache
|
|
80
|
+
*/
|
|
81
|
+
obterEstatisticas() {
|
|
82
|
+
const total = this.estatisticas.acertos + this.estatisticas.extravios;
|
|
83
|
+
const taxaAcerto = total > 0
|
|
84
|
+
? ((this.estatisticas.acertos / total) * 100).toFixed(2)
|
|
85
|
+
: "0.00";
|
|
86
|
+
return {
|
|
87
|
+
tamanho: this.cache.size,
|
|
88
|
+
limite: this.limite,
|
|
89
|
+
acertos: this.estatisticas.acertos,
|
|
90
|
+
extravios: this.estatisticas.extravios,
|
|
91
|
+
limpezas: this.estatisticas.limpezas,
|
|
92
|
+
taxaAcerto: `${taxaAcerto}%`,
|
|
93
|
+
utilizacao: `${((this.cache.size / this.limite) * 100).toFixed(2)}%`
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.CacheConsultas = CacheConsultas;
|
|
98
|
+
//# sourceMappingURL=cache-consultas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-consultas.js","sourceRoot":"","sources":["../../fontes/cache-consultas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Carregador em Lote (DataLoader)
|
|
3
|
+
*
|
|
4
|
+
* Agrupa múltiplas requisições de relacionamentos em poucas queries,
|
|
5
|
+
* evitando o problema N+1 através de batching inteligente.
|
|
6
|
+
*/
|
|
7
|
+
interface ConfiguracaoLote {
|
|
8
|
+
tamanhoLote: number;
|
|
9
|
+
intervaloMs: number;
|
|
10
|
+
cache: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class CarregadorLote<T> {
|
|
13
|
+
private funcaoCarregamento;
|
|
14
|
+
private fila;
|
|
15
|
+
private tempoMaximo;
|
|
16
|
+
private cache;
|
|
17
|
+
private configuracao;
|
|
18
|
+
constructor(funcaoCarregamento: (chaves: any[]) => Promise<Map<any, T>>, config?: Partial<ConfiguracaoLote>);
|
|
19
|
+
/**
|
|
20
|
+
* Solicita carregamento de um item
|
|
21
|
+
*/
|
|
22
|
+
carregar(chave: any): Promise<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Processa lote de carregamentos
|
|
25
|
+
*/
|
|
26
|
+
private processar;
|
|
27
|
+
/**
|
|
28
|
+
* Limpa cache
|
|
29
|
+
*/
|
|
30
|
+
limparCache(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Retorna estatísticas
|
|
33
|
+
*/
|
|
34
|
+
obterEstatisticas(): {
|
|
35
|
+
filaAtual: number;
|
|
36
|
+
tamanhoCache: number;
|
|
37
|
+
tamanhoLote: number;
|
|
38
|
+
intervaloMs: number;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Gerenciador de Carregadores em Lote para Relacionamentos
|
|
43
|
+
*/
|
|
44
|
+
export declare class GerenciadorCarregadoresLote {
|
|
45
|
+
private carregadores;
|
|
46
|
+
/**
|
|
47
|
+
* Cria carregador para um relacionamento específico
|
|
48
|
+
*/
|
|
49
|
+
criarCarregador<T>(chave: string, funcaoCarregamento: (ids: any[]) => Promise<Map<any, T>>, config?: Partial<ConfiguracaoLote>): CarregadorLote<T>;
|
|
50
|
+
/**
|
|
51
|
+
* Obtém carregador existente
|
|
52
|
+
*/
|
|
53
|
+
obterCarregador<T>(chave: string): CarregadorLote<T> | null;
|
|
54
|
+
/**
|
|
55
|
+
* Limpa todos os carregadores
|
|
56
|
+
*/
|
|
57
|
+
limparTodos(): void;
|
|
58
|
+
/**
|
|
59
|
+
* Obtém status de todos os carregadores
|
|
60
|
+
*/
|
|
61
|
+
obterStatus(): Record<string, any>;
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=carregador-lotes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"carregador-lotes.d.ts","sourceRoot":"","sources":["../../fontes/carregador-lotes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,UAAU,gBAAgB;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;CAClB;AAQD,qBAAa,cAAc,CAAC,CAAC;IAOrB,OAAO,CAAC,kBAAkB;IAN9B,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,YAAY,CAAmB;gBAG3B,kBAAkB,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EACnE,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAStC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;IAwBhC;;OAEG;YACW,SAAS;IA2CvB;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,iBAAiB;;;;;;CAQpB;AAED;;GAEG;AACH,qBAAa,2BAA2B;IACpC,OAAO,CAAC,YAAY,CAA+C;IAEnE;;OAEG;IACH,eAAe,CAAC,CAAC,EACb,KAAK,EAAE,MAAM,EACb,kBAAkB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EACxD,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACnC,cAAc,CAAC,CAAC,CAAC;IAMpB;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IAI3D;;OAEG;IACH,WAAW,IAAI,IAAI;IAOnB;;OAEG;IACH,WAAW;CASd"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Carregador em Lote (DataLoader)
|
|
4
|
+
*
|
|
5
|
+
* Agrupa múltiplas requisições de relacionamentos em poucas queries,
|
|
6
|
+
* evitando o problema N+1 através de batching inteligente.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.GerenciadorCarregadoresLote = exports.CarregadorLote = void 0;
|
|
10
|
+
class CarregadorLote {
|
|
11
|
+
constructor(funcaoCarregamento, config) {
|
|
12
|
+
this.funcaoCarregamento = funcaoCarregamento;
|
|
13
|
+
this.fila = [];
|
|
14
|
+
this.tempoMaximo = null;
|
|
15
|
+
this.cache = new Map();
|
|
16
|
+
this.configuracao = {
|
|
17
|
+
tamanhoLote: config?.tamanhoLote ?? 100,
|
|
18
|
+
intervaloMs: config?.intervaloMs ?? 16,
|
|
19
|
+
cache: config?.cache ?? true
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Solicita carregamento de um item
|
|
24
|
+
*/
|
|
25
|
+
carregar(chave) {
|
|
26
|
+
return new Promise((resolver, rejeitar) => {
|
|
27
|
+
// Verifica cache primeiro
|
|
28
|
+
if (this.configuracao.cache) {
|
|
29
|
+
const chaveStr = String(chave);
|
|
30
|
+
const emCache = this.cache.get(chaveStr);
|
|
31
|
+
if (emCache) {
|
|
32
|
+
return resolver(emCache);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Adiciona à fila
|
|
36
|
+
this.fila.push({ chave, resolver, rejeitar });
|
|
37
|
+
// Processa se atingiu tamanho do lote
|
|
38
|
+
if (this.fila.length >= this.configuracao.tamanhoLote) {
|
|
39
|
+
this.processar();
|
|
40
|
+
}
|
|
41
|
+
else if (!this.tempoMaximo) {
|
|
42
|
+
// Agenda processamento após delay
|
|
43
|
+
this.tempoMaximo = setTimeout(() => this.processar(), this.configuracao.intervaloMs);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Processa lote de carregamentos
|
|
49
|
+
*/
|
|
50
|
+
async processar() {
|
|
51
|
+
const loteAtual = this.fila.splice(0, this.configuracao.tamanhoLote);
|
|
52
|
+
if (this.tempoMaximo) {
|
|
53
|
+
clearTimeout(this.tempoMaximo);
|
|
54
|
+
this.tempoMaximo = null;
|
|
55
|
+
}
|
|
56
|
+
if (loteAtual.length === 0)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
const chaves = loteAtual.map(r => r.chave);
|
|
60
|
+
const resultados = await this.funcaoCarregamento(chaves);
|
|
61
|
+
// Distribui resultados
|
|
62
|
+
for (const requisicao of loteAtual) {
|
|
63
|
+
const resultado = resultados.get(requisicao.chave);
|
|
64
|
+
if (resultado !== undefined) {
|
|
65
|
+
// Armazena em cache
|
|
66
|
+
if (this.configuracao.cache) {
|
|
67
|
+
this.cache.set(String(requisicao.chave), resultado);
|
|
68
|
+
}
|
|
69
|
+
requisicao.resolver(resultado);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
requisicao.rejeitar(new Error(`Nenhum resultado para chave: ${requisicao.chave}`));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (erro) {
|
|
77
|
+
// Rejeita todos em caso de erro
|
|
78
|
+
for (const requisicao of loteAtual) {
|
|
79
|
+
requisicao.rejeitar(erro);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Processa próximo lote se houver
|
|
83
|
+
if (this.fila.length > 0) {
|
|
84
|
+
this.processar();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Limpa cache
|
|
89
|
+
*/
|
|
90
|
+
limparCache() {
|
|
91
|
+
this.cache.clear();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Retorna estatísticas
|
|
95
|
+
*/
|
|
96
|
+
obterEstatisticas() {
|
|
97
|
+
return {
|
|
98
|
+
filaAtual: this.fila.length,
|
|
99
|
+
tamanhoCache: this.cache.size,
|
|
100
|
+
tamanhoLote: this.configuracao.tamanhoLote,
|
|
101
|
+
intervaloMs: this.configuracao.intervaloMs
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.CarregadorLote = CarregadorLote;
|
|
106
|
+
/**
|
|
107
|
+
* Gerenciador de Carregadores em Lote para Relacionamentos
|
|
108
|
+
*/
|
|
109
|
+
class GerenciadorCarregadoresLote {
|
|
110
|
+
constructor() {
|
|
111
|
+
this.carregadores = new Map();
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Cria carregador para um relacionamento específico
|
|
115
|
+
*/
|
|
116
|
+
criarCarregador(chave, funcaoCarregamento, config) {
|
|
117
|
+
const carregador = new CarregadorLote(funcaoCarregamento, config);
|
|
118
|
+
this.carregadores.set(chave, carregador);
|
|
119
|
+
return carregador;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Obtém carregador existente
|
|
123
|
+
*/
|
|
124
|
+
obterCarregador(chave) {
|
|
125
|
+
return this.carregadores.get(chave) || null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Limpa todos os carregadores
|
|
129
|
+
*/
|
|
130
|
+
limparTodos() {
|
|
131
|
+
for (const carregador of this.carregadores.values()) {
|
|
132
|
+
carregador.limparCache();
|
|
133
|
+
}
|
|
134
|
+
this.carregadores.clear();
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Obtém status de todos os carregadores
|
|
138
|
+
*/
|
|
139
|
+
obterStatus() {
|
|
140
|
+
const status = {};
|
|
141
|
+
for (const [chave, carregador] of this.carregadores.entries()) {
|
|
142
|
+
status[chave] = carregador.obterEstatisticas();
|
|
143
|
+
}
|
|
144
|
+
return status;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.GerenciadorCarregadoresLote = GerenciadorCarregadoresLote;
|
|
148
|
+
//# sourceMappingURL=carregador-lotes.js.map
|