Middle+
func (r *OrderRepository) GetActiveOrderIDs(ctx context.Context, offset, limit int) ([]uint32, error) { var ( res []uint32 args []interface{} ) query := `SELECT id FROM "order" WHERE is_terminated = false LIMIT $1 OFFSET $2;` args = append(args, limit, offset) rows, err := r.slave.Query(ctx, query, args...) if err != nil { return nil, err } for rows.Next() { var orderID uint32 if err = rows.Scan(&orderID); err != nil { return nil, err } res = append(res, orderID) } return res, nil }
sobes.tech MI
Válasz az MI-től
Ebben a Go módszerben adatbázislekérdezést hajtanak végre az aktív rendelések azonosítóinak lekérésére lapozással (offset és limit).
A kód helyesen használja az előkészített lekérdezést paraméterekkel, ami megakadályozza az SQL-injektálást.
Azonban néhány javaslat a fejlesztéshez:
- Ajánlott a
rowslezárása használat után, hogy elkerüljük az erőforrás szivárgást:
rows, err := r.slave.Query(ctx, query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
-
A ciklus után használható a
rows.Err()a iterációs hibák ellenőrzésére. -
A LIMIT és OFFSET paraméterek általában ebben a sorrendben vannak, de a lekérdezésben LIMIT $1 OFFSET $2 szerepel, ami helyes, ha limit és offset ebben a sorrendben kerül átadásra.
-
Nagy adatmennyiség esetén érdemes lehet kurzorokat vagy streaming feldolgozást alkalmazni.
Példa a rows lezárásával és hibák ellenőrzésével:
rows, err := r.slave.Query(ctx, query, args...)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var orderID uint32
if err = rows.Scan(&orderID); err != nil {
return nil, err
}
res = append(res, orderID)
}
if err = rows.Err(); err != nil {
return nil, err
}
return res, nil