package repository import ( "context" "database/sql" "fmt" "strings" "github.com/luxsin/app-api/internal/model" ) type ModelRepository struct { db *sql.DB } func NewModelRepository(db *sql.DB) *ModelRepository { return &ModelRepository{db: db} } func (r *ModelRepository) List(ctx context.Context, brandName, modelName string) ([]model.Model, error) { brandName = strings.TrimSpace(brandName) modelName = strings.TrimSpace(modelName) const baseQuery = `SELECT id, brand_name, name, form, rig, source, eq_key, create_at FROM model` var ( query string args []any ) switch { case brandName != "": query = baseQuery + " WHERE brand_name = ? ORDER BY name ASC" args = []any{brandName} case modelName != "": query = baseQuery + " WHERE name LIKE ? ORDER BY name ASC" args = []any{"%" + modelName + "%"} default: return []model.Model{}, nil } rows, err := r.db.QueryContext(ctx, query, args...) if err != nil { return nil, fmt.Errorf("query model: %w", err) } defer rows.Close() list := make([]model.Model, 0) for rows.Next() { m, err := scanModel(rows) if err != nil { return nil, err } list = append(list, m) } if err := rows.Err(); err != nil { return nil, fmt.Errorf("iterate model: %w", err) } return list, nil } func scanModel(rows *sql.Rows) (model.Model, error) { var m model.Model var form, rig, source, eqKey sql.NullString if err := rows.Scan( &m.ID, &m.BrandName, &m.Name, &form, &rig, &source, &eqKey, &m.CreateAt, ); err != nil { return model.Model{}, fmt.Errorf("scan model: %w", err) } m.Form = nullStringPtr(form) m.Rig = nullStringPtr(rig) m.Source = nullStringPtr(source) m.EqKey = nullStringPtr(eqKey) return m, nil } func nullStringPtr(ns sql.NullString) *string { if !ns.Valid { return nil } s := ns.String return &s }