Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possibilidade de criar os índices extras via CLI #292

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
17 changes: 16 additions & 1 deletion cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ var dropCmd = &cobra.Command{
},
}

var extraIndexesCmd = &cobra.Command{
Use: "extra-indexes index-1 [index-2 …]",
Short: "Creates extra indexes in the JSON fields",
Args: cobra.MinimumNArgs(1),
RunE: func(_ *cobra.Command, args []string) error {
db, err := loadDatabase()
if err != nil {
return fmt.Errorf("could not find database: %w", err)
}
defer db.Close()
return db.ExtraIndexes(args)
},
}

func addDataDir(c *cobra.Command) *cobra.Command {
c.Flags().StringVarP(&dir, "directory", "d", defaultDataDir, "directory of the downloaded files")
return c
Expand All @@ -80,7 +94,7 @@ func addDatabase(c *cobra.Command) *cobra.Command {

// CLI returns the root command from Cobra CLI tool.
func CLI() *cobra.Command {
for _, c := range []*cobra.Command{createCmd, dropCmd} {
for _, c := range []*cobra.Command{createCmd, dropCmd, extraIndexesCmd} {
addDatabase(c)
}
for _, c := range []*cobra.Command{
Expand All @@ -92,6 +106,7 @@ func CLI() *cobra.Command {
checkCLI(),
createCmd,
dropCmd,
extraIndexesCmd,
transformCLI(),
sampleCLI(),
mirrorCLI(),
Expand Down
1 change: 1 addition & 0 deletions cmd/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type database interface {
CreateCompanies([][]string) error
PostLoad() error
MetaSave(string, string) error
ExtraIndexes(idxs []string) error
// api
GetCompany(string) (string, error)
MetaRead(string) (string, error)
Expand Down
25 changes: 25 additions & 0 deletions db/mongodb.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,28 @@ func (m *MongoDB) GetCompany(cnpj string) (string, error) {
}
return string(b), nil
}

func (m *MongoDB) ExtraIndexes(idxs []string) error {
log.Output(1, "Creating the indexes…")
c := m.db.Collection(companyTableName)
var i []mongo.IndexModel
for _, v := range idxs {
if strings.Contains(v, "qsa_") {
v = strings.ReplaceAll(strings.Replace(v, "qsa_", "", 1), "_", "")
v = fmt.Sprintf("%s_%s", "qsa", v)
}
if strings.Contains(v, "secundario") && strings.Contains(v, "cnae") {
v = fmt.Sprintf("cnaesecundarios_%s", strings.Split(v, "secundarios_")[1])
}
i = append(i, mongo.IndexModel{
Keys: bson.D{{Key: v, Value: 1}},
})
Comment on lines +232 to +241
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essa lógica está verbosa demais, não entendi o input como qsa_ (achava que seria qsa. como sugerido anteriormente), e acho que não precisamos de dois blocos, um para QSA e outro para CNAEs secundários.

Os inputs serão, por exemplo, qsa.codigo_pais e cnaes_secundarios.codigo e queremos qsa_codigopais e cnaessecundarios_codigo, é isso?

Se for:

Suggested change
if strings.Contains(v, "qsa_") {
v = strings.ReplaceAll(strings.Replace(v, "qsa_", "", 1), "_", "")
v = fmt.Sprintf("%s_%s", "qsa", v)
}
if strings.Contains(v, "secundario") && strings.Contains(v, "cnae") {
v = fmt.Sprintf("cnaesecundarios_%s", strings.Split(v, "secundarios_")[1])
}
i = append(i, mongo.IndexModel{
Keys: bson.D{{Key: v, Value: 1}},
})
if strings.Contains(v, ".") {
ps := string.Split(v, ".")
v = fmt.Sprintf("%s_%s", strings.ReplaceAll(ps[0], "_", ""), ps[1])
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eu sei qa lógica não está das mais explicadas. E porque eu pensei no seguinte, se o usuário escrever como está o ouput da API ele vai por:

cnaes_secundarios.codigo
E não como está no mongo que e cnaesecundarios.codigo

Por isso coloquei os ifs de "conversão"

De fato havíamos falado . ao invés de _. Desculpe não sei aonde meu TDAH foi parar.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Já que não está claro, isole essa função e adicione nos testes, aí garantimos, nos testes, que o que a pessoa digitar gera o nome esperado no banco : )

}
r, err := c.Indexes().CreateMany(m.ctx, i)
if err != nil {
return fmt.Errorf("error creating indexes: %w", err)
}
log.Output(1, fmt.Sprintf("%d indexes successfully created in the collection %s", len(r), companyTableName))
return nil

}
32 changes: 32 additions & 0 deletions db/postgres.go
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isso aqui não é uma boa prática: concatenar strings para formar um SQL e escrever SQL dentro do Go. Melhor usar templates — por segurança, por facilidade de leitura e manutenção, e para manter o padrão de todos os outros comandos SQL que o módulo Postgres implementa.

Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,35 @@ func NewPostgreSQL(uri, schema string) (PostgreSQL, error) {
}
return p, nil
}

func (p *PostgreSQL) ExtraIndexes(idxs []string) error {
c := 0
for _, v := range idxs {
t := fmt.Sprintf("((json->'%s'))", v)
name := "json_"

if strings.Contains(v, "qsa") && !strings.Contains(v, "cnae") {
v = strings.Split(v, ".")[1]
t = fmt.Sprintf("(jsonb_extract_path(json, 'qsa', '%s') jsonb_ops)", v)
name += "qsa_"
}

if !strings.Contains(v, "qsa") && strings.Contains(v, "cnae") {
v = strings.Split(v, ".")[1]
t = fmt.Sprintf("(jsonb_extract_path(json, 'cnaes_secundarios', '%s') jsonb_ops)", v)
name += "cnaes_secundarios_"
}
q := fmt.Sprintf(
"CREATE INDEX IF NOT EXISTS idx_%s%s ON %s USING GIN %s;",
name, v, p.CompanyTableName, t,
)
if _, err := p.pool.Exec(context.Background(), q); err != nil {
return fmt.Errorf("error to create indexe %s: %w", v, err)
}
c += 1
}

log.Output(1, fmt.Sprintf("%d Indexes successfully created in the table %s", c, p.CompanyTableName))

return nil
}
Loading