func (g *Generator) generateConstantsColumns(w io.Writer, table *pqt.Table) { fmt.Fprintf(w, `%s%s = "%s" `, g.name("table"), g.public(table.Name), table.FullName()) for _, name := range sortedColumns(table.Columns) { fmt.Fprintf(w, `%s%sColumn%s = "%s" `, g.name("table"), g.public(table.Name), g.public(name), name) } }
func (g *Generator) generateRepositoryFindOneByPrimaryKey(code *bytes.Buffer, table *pqt.Table) { entityName := g.name(table.Name) pk, ok := table.PrimaryKey() if !ok { return } fmt.Fprintf(code, `func (r *%sRepositoryBase) %s%s(%s %s) (*%sEntity, error) {`, entityName, g.name("FindOneBy"), g.public(pk.Name), g.private(pk.Name), g.generateColumnTypeString(pk, modeMandatory), entityName, ) fmt.Fprintf(code, `var ( ent %sEntity )`, entityName) code.WriteRune('\n') fmt.Fprint(code, "query := `SELECT ") for i, c := range table.Columns { fmt.Fprintf(code, "%s", c.Name) if i != len(table.Columns)-1 { code.WriteRune(',') } code.WriteRune('\n') } fmt.Fprintf(code, " FROM %s WHERE %s = $1`", table.FullName(), pk.Name) fmt.Fprintf(code, ` err := r.db.QueryRow(query, %s).Scan( `, g.private(pk.Name)) for _, c := range table.Columns { fmt.Fprintf(code, "&ent.%s,\n", g.propertyName(c.Name)) } fmt.Fprint(code, `) if err != nil { return nil, err } return &ent, nil } `) }
func (g *Generator) generateRepositoryDeleteOneByPrimaryKey(code *bytes.Buffer, table *pqt.Table) { entityName := g.name(table.Name) pk, ok := table.PrimaryKey() if !ok { return } fmt.Fprintf(code, ` func (r *%sRepositoryBase) %s%s(%s %s) (int64, error) { query := "DELETE FROM %s WHERE %s = $1" res, err := r.db.Exec(query, %s) if err != nil { return 0, err } return res.RowsAffected() } `, entityName, g.name("DeleteOneBy"), g.public(pk.Name), g.private(pk.Name), g.generateColumnTypeString(pk, 1), table.FullName(), pk.Name, g.private(pk.Name)) }
func timestampable(t *pqt.Table) { t.AddColumn(pqt.NewColumn("created_at", pqt.TypeTimestampTZ(), pqt.WithNotNull(), pqt.WithDefault("NOW()"))). AddColumn(pqt.NewColumn("updated_at", pqt.TypeTimestampTZ(), pqt.WithDefault("NOW()", pqt.EventUpdate))) }
func (g *Generator) generateRepositoryUpdateOneByPrimaryKey(w io.Writer, table *pqt.Table) { entityName := g.name(table.Name) pk, ok := table.PrimaryKey() if !ok { return } fmt.Fprintf(w, "func (r *%sRepositoryBase) %s%s(%s %s, patch *%sPatch) (*%sEntity, error) {\n", entityName, g.name("UpdateOneBy"), g.public(pk.Name), g.private(pk.Name), g.generateColumnTypeString(pk, modeMandatory), entityName, entityName) fmt.Fprintf(w, "update := pqcomp.New(1, %d)\n", len(table.Columns)) fmt.Fprintf(w, "update.AddArg(%s)\n", g.private(pk.Name)) fmt.Fprintln(w, "") ColumnsLoop: for _, c := range table.Columns { if c == pk { continue ColumnsLoop } if _, ok := c.DefaultOn(pqt.EventInsert, pqt.EventUpdate); ok { switch c.Type { case pqt.TypeTimestamp(), pqt.TypeTimestampTZ(): fmt.Fprintf(w, "if patch.%s != nil {\n", g.propertyName(c.Name)) } } else if g.canBeNil(c, modeOptional) { fmt.Fprintf(w, "if patch.%s != nil {\n", g.propertyName(c.Name)) } fmt.Fprint(w, "update.AddExpr(") g.writeTableNameColumnNameTo(w, c.Table.Name, c.Name) fmt.Fprintf(w, ", pqcomp.Equal, patch.%s)\n", g.propertyName(c.Name)) if d, ok := c.DefaultOn(pqt.EventUpdate); ok { switch c.Type { case pqt.TypeTimestamp(), pqt.TypeTimestampTZ(): fmt.Fprint(w, `} else {`) fmt.Fprint(w, "update.AddExpr(") g.writeTableNameColumnNameTo(w, c.Table.Name, c.Name) fmt.Fprintf(w, `, pqcomp.Equal, "%s")`, d) } } if _, ok := c.DefaultOn(pqt.EventInsert, pqt.EventUpdate); ok { switch c.Type { case pqt.TypeTimestamp(), pqt.TypeTimestampTZ(): fmt.Fprint(w, "\n}\n") } } else if g.canBeNil(c, modeOptional) { fmt.Fprint(w, "\n}\n") } } fmt.Fprintf(w, ` if update.Len() == 0 { return nil, errors.New("%s update failure, nothing to update") }`, entityName) fmt.Fprintf(w, ` query := "UPDATE %s SET " for update.Next() { if !update.First() { query += ", " } query += update.Key() + " " + update.Oper() + " " + update.PlaceHolder() } query += " WHERE %s = $1 RETURNING " + strings.Join(r.columns, ", ") var e %sEntity err := r.db.QueryRow(query, update.Args()...).Scan( `, table.FullName(), pk.Name, entityName) for _, c := range table.Columns { fmt.Fprintf(w, "&e.%s,\n", g.propertyName(c.Name)) } fmt.Fprint(w, `) if err != nil { return nil, err } return &e, nil } `) }
func (g *Generator) generateRepositoryUpdateOneByUniqueConstraint(w io.Writer, table *pqt.Table) { entityName := g.name(table.Name) var unique []*pqt.Constraint for _, c := range tableConstraints(table) { if c.Type == pqt.ConstraintTypeUnique { unique = append(unique, c) } } if len(unique) < 1 { return } for _, u := range unique { arguments := "" methodName := "UpdateOneBy" for i, c := range u.Columns { if i != 0 { methodName += "And" arguments += ", " } methodName += g.public(c.Name) arguments += fmt.Sprintf("%s %s", g.private(columnForeignName(c)), g.generateColumnTypeString(c, modeMandatory)) } fmt.Fprintf(w, `func (r *%sRepositoryBase) %s(%s, patch *%sPatch) (*%sEntity, error) { `, entityName, g.name(methodName), arguments, entityName, entityName) fmt.Fprintf(w, "update := pqcomp.New(%d, %d)\n", len(u.Columns), len(table.Columns)) for _, c := range u.Columns { fmt.Fprintf(w, "update.AddArg(%s)\n", g.private(columnForeignName(c))) } pk, pkOK := table.PrimaryKey() ColumnsLoop: for _, c := range table.Columns { if pkOK && c == pk { continue ColumnsLoop } for _, uc := range u.Columns { if c == uc { continue } } if _, ok := c.DefaultOn(pqt.EventInsert, pqt.EventUpdate); ok { switch c.Type { case pqt.TypeTimestamp(), pqt.TypeTimestampTZ(): fmt.Fprintf(w, "if patch.%s != nil {\n", g.propertyName(c.Name)) } } else if g.canBeNil(c, modeOptional) { fmt.Fprintf(w, "if patch.%s != nil {\n", g.propertyName(c.Name)) } fmt.Fprint(w, "update.AddExpr(") g.writeTableNameColumnNameTo(w, c.Table.Name, c.Name) fmt.Fprintf(w, ", pqcomp.Equal, patch.%s)\n", g.propertyName(c.Name)) if d, ok := c.DefaultOn(pqt.EventUpdate); ok { switch c.Type { case pqt.TypeTimestamp(), pqt.TypeTimestampTZ(): fmt.Fprint(w, `} else {`) fmt.Fprint(w, "update.AddExpr(") g.writeTableNameColumnNameTo(w, c.Table.Name, c.Name) fmt.Fprintf(w, `, pqcomp.Equal, "%s")`, d) } } if _, ok := c.DefaultOn(pqt.EventInsert, pqt.EventUpdate); ok { switch c.Type { case pqt.TypeTimestamp(), pqt.TypeTimestampTZ(): fmt.Fprint(w, "\n}\n") } } else if g.canBeNil(c, modeOptional) { fmt.Fprint(w, "\n}\n") } } fmt.Fprintf(w, ` if update.Len() == 0 { return nil, errors.New("%s update failure, nothing to update") }`, entityName) fmt.Fprintf(w, ` query := "UPDATE %s SET " for update.Next() { if !update.First() { query += ", " } query += update.Key() + " " + update.Oper() + " " + update.PlaceHolder() } `, table.FullName()) fmt.Fprint(w, `query += " WHERE `) for i, c := range u.Columns { if i != 0 { fmt.Fprint(w, " AND ") } fmt.Fprintf(w, "%s = $%d", c.Name, i+1) } fmt.Fprintf(w, ` RETURNING " + strings.Join(r.columns, ", ") if r.dbg { if err := r.log.Log("msg", query, "function", "%s"); err != nil { return nil, err } } var e %sEntity err := r.db.QueryRow(query, update.Args()...).Scan( `, methodName, entityName) for _, c := range table.Columns { fmt.Fprintf(w, "&e.%s,\n", g.propertyName(c.Name)) } fmt.Fprint(w, `) if err != nil { return nil, err } return &e, nil } `) } }
func (g *Generator) generateRepositoryFindOneByUniqueConstraint(code *bytes.Buffer, table *pqt.Table) { entityName := g.name(table.Name) var unique []*pqt.Constraint for _, c := range tableConstraints(table) { if c.Type == pqt.ConstraintTypeUnique { unique = append(unique, c) } } if len(unique) < 1 { return } for _, u := range unique { arguments := "" methodName := "FindOneBy" for i, c := range u.Columns { if i != 0 { methodName += "And" arguments += ", " } methodName += g.public(c.Name) arguments += fmt.Sprintf("%s %s", g.private(columnForeignName(c)), g.generateColumnTypeString(c, modeMandatory)) } fmt.Fprintf(code, `func (r *%sRepositoryBase) %s(%s) (*%sEntity, error) {`, entityName, g.name(methodName), arguments, entityName) fmt.Fprintf(code, `var ( ent %sEntity )`, entityName) code.WriteRune('\n') fmt.Fprint(code, "query := `SELECT ") for i, c := range table.Columns { if i != 0 { code.WriteString(", ") } fmt.Fprintf(code, "%s", c.Name) } fmt.Fprintf(code, " FROM %s WHERE ", table.FullName()) for i, c := range u.Columns { if i != 0 { fmt.Fprint(code, " AND ") } fmt.Fprintf(code, "%s = $%d", c.Name, i+1) } fmt.Fprintln(code, "`") fmt.Fprint(code, "err := r.db.QueryRow(query, ") for i, c := range u.Columns { if i != 0 { fmt.Fprint(code, ", ") } fmt.Fprintf(code, "%s", g.private(columnForeignName(c))) } fmt.Fprint(code, ").Scan(\n") for _, c := range table.Columns { fmt.Fprintf(code, "&ent.%s,\n", g.propertyName(c.Name)) } fmt.Fprint(code, `) if err != nil { return nil, err } return &ent, nil } `) } }