package main
import (
"context"
"database/sql"
"errors"
"fmt"
"gotesting/db"
"log"
"net/http"
"github.com/mattn/go-sqlite3"
)
type query[RES, ID any] func(context.Context, ID) (RES, error)
func RunQuery[RES, ID any](ctx context.Context, query query[RES, ID], id ID) (RES, int, error) {
res, err := query(ctx, id)
if err != nil {
switch true {
case ctx.Err() == context.DeadlineExceeded:
return res, http.StatusGatewayTimeout, errors.New("query took too long")
case errors.Is(err, sql.ErrNoRows):
return res, http.StatusNotFound, errors.New("datas not found")
case errors.As(err, &sqlite3.Error{ExtendedCode: sqlite3.ErrConstraintUnique}):
return res, http.StatusBadRequest, errors.New("one or more fields already exists in the database")
case errors.As(err, &sqlite3.Error{ExtendedCode: sqlite3.ErrConstraintCheck}):
return res, http.StatusBadRequest, errors.New("one or more fields in the query are invalid")
default:
log.Println(err)
return res, http.StatusInternalServerError, errors.New("database error")
}
}
return res, 0, nil
}
func main() {
db.InitDB()
user, status, err := RunQuery(context.Background(), db.Query.GetUser, 67_69_420)
if err != nil {
log.Fatal(status, err)
}
fmt.Println(user)
}