refatoração do drive de pilão de dados
This commit is contained in:
parent
1ee3565d3d
commit
f6c203ee3e
31 changed files with 887 additions and 554 deletions
258
src/pilao-de-dados/Pilao/index.ts
Normal file
258
src/pilao-de-dados/Pilao/index.ts
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/** Drive completo do piilão de dados */
|
||||
|
||||
import crossFetch from "cross-fetch"
|
||||
import { nomeVariavel } from "p-comuns"
|
||||
|
||||
import { respostaComuns, type tipoResposta } from "p-respostas"
|
||||
import type { z } from "zod"
|
||||
|
||||
import type { zp_enviar_registros } from "../_enviar_registros"
|
||||
import { PREFIXO_PILAO, type zp_deletar_registros } from "../variaveis"
|
||||
import type { visoes } from "../visoes"
|
||||
import type { tipo_pilao_api } from "./pilao-api.ts"
|
||||
import type { tipoConstrutorPilao } from "./tipagem"
|
||||
|
||||
class ClassPilao {
|
||||
#produto: string
|
||||
#conta: string
|
||||
#emDesenvolvimento: boolean
|
||||
#ver_log: boolean
|
||||
#registrosParaEnvio: Record<
|
||||
string,
|
||||
z.infer<typeof zp_enviar_registros>["registros"]
|
||||
> = {}
|
||||
#codigosParaDeletar: Record<
|
||||
string,
|
||||
z.infer<typeof zp_deletar_registros>["codigos"]
|
||||
> = {}
|
||||
|
||||
constructor({
|
||||
conta,
|
||||
produto,
|
||||
emDesenvolvimento = false,
|
||||
ver_log = false,
|
||||
}: tipoConstrutorPilao & { ver_log?: boolean; emDesenvolvimento?: boolean }) {
|
||||
this.#produto = produto
|
||||
this.#conta = conta
|
||||
this.#emDesenvolvimento = emDesenvolvimento
|
||||
this.#ver_log = ver_log
|
||||
}
|
||||
|
||||
#gerarUrl(acao: string, extraPath?: string): { rota: string; url: string } {
|
||||
const rota = `${PREFIXO_PILAO}/${this.#conta}/${this.#produto}/${acao}${
|
||||
extraPath ? `/${extraPath}` : ""
|
||||
}`
|
||||
const url = `${this.baseUrlApi}${rota}`
|
||||
return { rota, url }
|
||||
}
|
||||
|
||||
rotaEnviarRegistros() {
|
||||
return this.#gerarUrl("enviar-registros")
|
||||
}
|
||||
|
||||
rotaDeletarRegistro() {
|
||||
return this.#gerarUrl("deletar-registros")
|
||||
}
|
||||
|
||||
rotaConsultarSerie(tipoVisao: keyof typeof visoes | ":tipoVisao") {
|
||||
return this.#gerarUrl("consultar-serie", tipoVisao)
|
||||
}
|
||||
|
||||
rotaIframeSerie(tipoVisao: keyof typeof visoes | ":tipoVisao") {
|
||||
const rota = `${PREFIXO_PILAO}/${this.#conta}/${this.#produto}/consultar-serie/${tipoVisao}`
|
||||
const url = `${this.baseUrlSite}${rota}`
|
||||
return { rota, url }
|
||||
}
|
||||
|
||||
rotaFuncaoApi(funcao: keyof tipo_pilao_api | ":funcao") {
|
||||
return this.#gerarUrl("API", funcao)
|
||||
}
|
||||
|
||||
async consultarApi<T extends keyof tipo_pilao_api>(
|
||||
funcao: T,
|
||||
parametros: tipo_pilao_api[T]["pr"],
|
||||
): Promise<tipoResposta<tipo_pilao_api[T]["rs"]>> {
|
||||
try {
|
||||
const response = await crossFetch(this.rotaFuncaoApi(funcao).url, {
|
||||
body: JSON.stringify(parametros),
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
return await response.json()
|
||||
} catch (erro) {
|
||||
console.error(erro)
|
||||
return respostaComuns.erroInterno({
|
||||
erro,
|
||||
local: nomeVariavel({ ClassPilao }),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
get baseUrlApi() {
|
||||
return this.#emDesenvolvimento
|
||||
? "http://localhost:5080"
|
||||
: "https://carro-de-boi.idz.one"
|
||||
}
|
||||
|
||||
get baseUrlSite() {
|
||||
return this.#emDesenvolvimento
|
||||
? "http://localhost:5081"
|
||||
: "https://carro-de-boi.idz.one"
|
||||
}
|
||||
|
||||
validarCliente(_: any): tipoResposta<tipoConstrutorPilao> {
|
||||
if (!_?.conta) return respostaComuns.erro("Conta não informada")
|
||||
if (!_?.produto) return respostaComuns.erro("Produto não informado")
|
||||
return respostaComuns.valor(_)
|
||||
}
|
||||
|
||||
adicionarRegistroParaEnviar(
|
||||
tabela: string,
|
||||
...registros: z.infer<typeof zp_enviar_registros>["registros"]
|
||||
) {
|
||||
this.#registrosParaEnvio[tabela] = [
|
||||
...(this.#registrosParaEnvio[tabela] || []),
|
||||
...registros,
|
||||
]
|
||||
return this
|
||||
}
|
||||
|
||||
adicionarCodigoParaDeletar(
|
||||
tabela: string,
|
||||
...codigos: z.infer<typeof zp_deletar_registros>["codigos"]
|
||||
) {
|
||||
this.#codigosParaDeletar[tabela] = [
|
||||
...(this.#codigosParaDeletar[tabela] || []),
|
||||
...codigos,
|
||||
]
|
||||
return this
|
||||
}
|
||||
|
||||
private async processarRegistros(
|
||||
url: string,
|
||||
registros: any[],
|
||||
tabela: string,
|
||||
acao: string,
|
||||
): Promise<tipoResposta<true>> {
|
||||
const tamanhoBlocos = 1000
|
||||
while (registros.length > 0) {
|
||||
const bloco = registros
|
||||
.splice(0, tamanhoBlocos)
|
||||
.map((r) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(r).map(([k, v]) => [k, v === undefined ? null : v]),
|
||||
),
|
||||
)
|
||||
const resp = await crossFetch(url, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ tabela, registros: bloco }),
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.catch((e) =>
|
||||
respostaComuns.erro(`Erro ao ${acao} registros`, [e.message]),
|
||||
)
|
||||
|
||||
if (resp.eErro) return resp
|
||||
}
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
|
||||
async #salvarEnviarRegistros(): Promise<tipoResposta<true>> {
|
||||
for (const tabela of Object.keys(this.#registrosParaEnvio)) {
|
||||
const registros = this.#registrosParaEnvio[tabela] || []
|
||||
const url = this.rotaEnviarRegistros().url
|
||||
if (this.#ver_log)
|
||||
console.log(
|
||||
`[PILÃO]: Enviando ${registros.length} registros na tabela "${tabela}" para "${url}".`,
|
||||
)
|
||||
const resp = await this.processarRegistros(
|
||||
url,
|
||||
registros,
|
||||
tabela,
|
||||
"enviar",
|
||||
)
|
||||
if (resp.eErro) return resp
|
||||
this.#registrosParaEnvio[tabela] = []
|
||||
}
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
|
||||
async #salvarDeletarRegistros(): Promise<tipoResposta<true>> {
|
||||
for (const tabela of Object.keys(this.#codigosParaDeletar)) {
|
||||
const codigos = [...(this.#codigosParaDeletar[tabela] || [])]
|
||||
const url = this.rotaDeletarRegistro().url
|
||||
const resp = await this.processarRegistros(
|
||||
url,
|
||||
codigos,
|
||||
tabela,
|
||||
"deletar",
|
||||
)
|
||||
if (resp.eErro) return resp
|
||||
}
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
|
||||
async salvarRegistros(): Promise<tipoResposta<true>> {
|
||||
const re = await this.#salvarEnviarRegistros()
|
||||
if (re.eErro) return re
|
||||
const rd = await this.#salvarDeletarRegistros()
|
||||
if (rd.eErro) return rd
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
|
||||
serieConsultar<T extends keyof typeof visoes>(
|
||||
tipoVisao: T,
|
||||
parametros: z.infer<(typeof visoes)[T]>,
|
||||
) {
|
||||
const dados = async (): Promise<
|
||||
tipoResposta<{
|
||||
registros: any[]
|
||||
legenda: string
|
||||
serie: z.infer<(typeof visoes)[T]>
|
||||
}>
|
||||
> => {
|
||||
const url = this.rotaConsultarSerie(tipoVisao).url
|
||||
const resp = await crossFetch(url.toString(), {
|
||||
method: "POST",
|
||||
body: JSON.stringify(parametros),
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.catch((e) =>
|
||||
respostaComuns.erro("Erro ao enviar registros", [e.message]),
|
||||
)
|
||||
|
||||
if (this.#ver_log)
|
||||
console.log(
|
||||
`[PILÃO]: buscar dados de "${JSON.stringify(parametros)}" para "${url}".`,
|
||||
)
|
||||
return resp
|
||||
}
|
||||
|
||||
const url = (): string => {
|
||||
const vUrl = this.rotaIframeSerie(tipoVisao).url
|
||||
const serie = encodeURIComponent(JSON.stringify(parametros, null, 2))
|
||||
if (this.#ver_log)
|
||||
console.log(
|
||||
`[PILÃO]: Serie Consultar url de "${JSON.stringify(serie)}" para "${vUrl}".`,
|
||||
)
|
||||
return `${vUrl}?serie=${serie}`
|
||||
}
|
||||
|
||||
return {
|
||||
dados,
|
||||
url,
|
||||
}
|
||||
}
|
||||
|
||||
urlLaboratorio() {
|
||||
const rota = `${PREFIXO_PILAO}/${this.#conta}/${this.#produto}/laboratório`
|
||||
const url = `${this.baseUrlSite}${rota}`
|
||||
return { rota, url }
|
||||
}
|
||||
}
|
||||
|
||||
export const Pilao = (
|
||||
_: tipoConstrutorPilao & { ver_log?: boolean; emDesenvolvimento?: boolean },
|
||||
) => new ClassPilao(_)
|
||||
32
src/pilao-de-dados/Pilao/pilao-api.ts.ts
Executable file
32
src/pilao-de-dados/Pilao/pilao-api.ts.ts
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
import type { z } from "zod"
|
||||
import type { zp_registrar_base_dados } from "../_enviar_registros"
|
||||
|
||||
/**
|
||||
* {
|
||||
* 'rota':{
|
||||
* pr:{}// paramentros de entrada
|
||||
* rs:{}// resposta
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
export type tipo_pilao_api = {
|
||||
/** retorna da data e hora do servido em formato iso */
|
||||
estado_servidor: {
|
||||
pr: {}
|
||||
rs: {
|
||||
data_hora: string
|
||||
}
|
||||
}
|
||||
tabelas: {
|
||||
pr: {}
|
||||
rs: z.infer<typeof zp_registrar_base_dados>[]
|
||||
}
|
||||
|
||||
unicos: {
|
||||
pr: {
|
||||
tabela: string
|
||||
coluna: string
|
||||
}
|
||||
rs: any[]
|
||||
}
|
||||
}
|
||||
1
src/pilao-de-dados/Pilao/tipagem.ts
Normal file
1
src/pilao-de-dados/Pilao/tipagem.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export type tipoConstrutorPilao = { produto: string; conta: string }
|
||||
|
|
@ -1,13 +1,5 @@
|
|||
import node_fetch from "cross-fetch"
|
||||
import type { tipoResposta } from "p-respostas"
|
||||
import { respostaComuns } from "p-respostas"
|
||||
import { z } from "zod"
|
||||
import {
|
||||
urlPilao,
|
||||
z_tipo_coluna_base_dados,
|
||||
type zp_deletar_registros,
|
||||
type zp_produto_conta,
|
||||
} from "./variaveis"
|
||||
import { z_tipo_coluna_base_dados } from "./variaveis"
|
||||
|
||||
export const zp_registrar_base_dados = z.object({
|
||||
tabela: z.string(),
|
||||
|
|
@ -32,135 +24,3 @@ export const zp_enviar_registros = z.object({
|
|||
),
|
||||
),
|
||||
})
|
||||
|
||||
class ClassPilaoEnviar {
|
||||
__conta: string | undefined
|
||||
__produto: string | undefined
|
||||
__emDesenvolvimento: boolean | undefined
|
||||
__ver_log: boolean | undefined
|
||||
__tabela: string | undefined
|
||||
__registrosParaEnvio: z.infer<typeof zp_enviar_registros>["registros"] = []
|
||||
__codigosParaDeletar: string[] = []
|
||||
|
||||
constructor({
|
||||
conta,
|
||||
produto,
|
||||
emDesenvolvimento,
|
||||
ver_log,
|
||||
}: z.infer<typeof zp_produto_conta>) {
|
||||
this.__conta = conta
|
||||
this.__produto = produto
|
||||
this.__emDesenvolvimento = emDesenvolvimento
|
||||
this.__ver_log = ver_log
|
||||
}
|
||||
|
||||
tabela(tabela: string) {
|
||||
this.__tabela = tabela
|
||||
return this
|
||||
}
|
||||
|
||||
adicionarRegistroParaEnviar(
|
||||
...registro: z.infer<typeof zp_enviar_registros>["registros"]
|
||||
) {
|
||||
this.__registrosParaEnvio.push(...registro)
|
||||
return this
|
||||
}
|
||||
|
||||
adicionarCodigoParaDeletar(
|
||||
...codigos: z.infer<typeof zp_deletar_registros>["codigos"]
|
||||
) {
|
||||
this.__codigosParaDeletar.push(...codigos)
|
||||
return this
|
||||
}
|
||||
|
||||
async __salvar_enviar_registros(): Promise<tipoResposta<true>> {
|
||||
const registros = this.__registrosParaEnvio
|
||||
|
||||
const url = new URL(
|
||||
`${
|
||||
urlPilao(this.__emDesenvolvimento).api
|
||||
}/enviar_registros/${this.__produto}/${this.__conta}`,
|
||||
)
|
||||
|
||||
if (this.__ver_log)
|
||||
console.log(
|
||||
`[PILÃO]: Enviando "${registros.length}" registros na tabela "${this.__tabela}" para "${url}".`,
|
||||
)
|
||||
|
||||
const tamanhoBlocos = 1000
|
||||
|
||||
while (registros.length > 0) {
|
||||
const bloco = registros
|
||||
.splice(0, tamanhoBlocos)
|
||||
.map((r) =>
|
||||
Object.fromEntries(
|
||||
Object.entries(r).map(([k, v]) => [k, v === undefined ? null : v]),
|
||||
),
|
||||
)
|
||||
|
||||
const resp = await node_fetch(url.toString(), {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ tabela: this.__tabela, registros: bloco }),
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.catch((e) =>
|
||||
respostaComuns.erro("Erro ao enviar registros", [e.message]),
|
||||
)
|
||||
.then((r) => r as tipoResposta<true>)
|
||||
|
||||
if (resp.eErro) {
|
||||
return resp
|
||||
}
|
||||
}
|
||||
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
|
||||
async __salvar_deletar_registros() {
|
||||
const codigos = [...this.__codigosParaDeletar]
|
||||
|
||||
const url = new URL(
|
||||
`${
|
||||
urlPilao(this.__emDesenvolvimento).api
|
||||
}/deletar_registros/${this.__produto}/${this.__conta}`,
|
||||
)
|
||||
|
||||
const tamanhoBlocos = 1000
|
||||
|
||||
while (codigos.length > 0) {
|
||||
const bloco = codigos.splice(0, tamanhoBlocos)
|
||||
const resp = await node_fetch(url.toString(), {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ tabela: this.__tabela, codigos: bloco }),
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.catch((e) =>
|
||||
respostaComuns.erro("Erro ao enviar registros", [e.message]),
|
||||
)
|
||||
.then((r) => r as tipoResposta<true>)
|
||||
|
||||
if (resp.eErro) {
|
||||
return resp
|
||||
}
|
||||
}
|
||||
|
||||
this.__codigosParaDeletar
|
||||
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
|
||||
async salvar() {
|
||||
const re = await this.__salvar_enviar_registros()
|
||||
if (re.eErro) return re
|
||||
|
||||
const rd = await this.__salvar_deletar_registros()
|
||||
if (rd.eErro) return rd
|
||||
|
||||
return respostaComuns.valor(true)
|
||||
}
|
||||
}
|
||||
|
||||
export const PilaoEnviar = (_: z.infer<typeof zp_produto_conta>) =>
|
||||
new ClassPilaoEnviar(_)
|
||||
|
|
|
|||
|
|
@ -1,67 +1,8 @@
|
|||
import node_fetch from "cross-fetch"
|
||||
import type { tipoResposta } from "p-respostas"
|
||||
import { respostaComuns } from "p-respostas"
|
||||
import { z } from "zod"
|
||||
import { operadores_pilao, urlPilao, type zp_produto_conta } from "./variaveis"
|
||||
import type { visoes } from "./visoes"
|
||||
import { operadores_pilao } from "./variaveis"
|
||||
|
||||
export const z_filtro = z.object({
|
||||
coluna: z.string(),
|
||||
valor: z.any(),
|
||||
operador: operadores_pilao,
|
||||
})
|
||||
|
||||
export const serie_consultar =
|
||||
(cliente: z.infer<typeof zp_produto_conta>) =>
|
||||
<T extends keyof typeof visoes>(
|
||||
tipoVisao: T,
|
||||
parametros: z.infer<(typeof visoes)[T]>,
|
||||
) => {
|
||||
const dados = async (): Promise<
|
||||
tipoResposta<{
|
||||
registros: any[]
|
||||
legenda: string
|
||||
serie: z.infer<(typeof visoes)[T]>
|
||||
}>
|
||||
> => {
|
||||
const url = new URL(
|
||||
`${urlPilao(cliente.emDesenvolvimento).api}/${
|
||||
tipoVisao
|
||||
}/${cliente.produto}/${cliente.conta}`,
|
||||
)
|
||||
|
||||
const resp = await node_fetch(url.toString(), {
|
||||
method: "POST",
|
||||
body: JSON.stringify(parametros),
|
||||
headers: { "Content-Type": "application/json" },
|
||||
})
|
||||
.then((r) => r.json())
|
||||
.catch((e) =>
|
||||
respostaComuns.erro("Erro ao enviar registros", [e.message]),
|
||||
)
|
||||
.then((r) => r as tipoResposta<any>)
|
||||
|
||||
if (cliente.ver_log)
|
||||
console.log(
|
||||
`[PILÃO]: buscar dados de "${JSON.stringify(parametros)}" para "${url.href}".`,
|
||||
)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
const url = (): string => {
|
||||
const vUrl = new URL(
|
||||
`${urlPilao(cliente.emDesenvolvimento).site}/${tipoVisao}/${cliente.produto}/${cliente.conta}`,
|
||||
)
|
||||
const serie = encodeURIComponent(JSON.stringify(parametros, null, 2))
|
||||
if (cliente.ver_log)
|
||||
console.log(
|
||||
`[PILÃO]: Serie Consultar url de "${JSON.stringify(serie)}" para "${vUrl.href}".`,
|
||||
)
|
||||
return `${vUrl.href}?serie=${serie}`
|
||||
}
|
||||
return {
|
||||
dados,
|
||||
url,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
export { PREFIXO_PILAO, urlPilao } from "./variaveis"
|
||||
import {
|
||||
PilaoEnviar,
|
||||
zp_enviar_registros,
|
||||
zp_registrar_base_dados,
|
||||
} from "./_enviar_registros"
|
||||
|
|
@ -12,16 +11,17 @@ import {
|
|||
zp_produto_conta,
|
||||
} from "./variaveis"
|
||||
|
||||
import { serie_consultar, z_filtro } from "./_serie_consultar"
|
||||
export * from "./Pilao"
|
||||
|
||||
import { z_filtro } from "./_serie_consultar"
|
||||
import { extruturas_de_campos, visoes } from "./visoes"
|
||||
|
||||
export const pPilao = {
|
||||
zp_deletar_registros,
|
||||
zp_registrar_base_dados,
|
||||
PilaoEnviar,
|
||||
|
||||
zp_enviar_registros,
|
||||
serie_consultar,
|
||||
|
||||
zp_produto_conta,
|
||||
validarZ,
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue