I am trying to make a full text search using Golang with Gin as my router and SQLC for SQL code gen. I get an empty list whether i bind the Query as URI or query. PLease help.
type searchProductRequest struct {
q string `form:"q" binding:"required"`
PageSize int32 `form:"page_size" binding:"required,min=1,max=10"`
}
func (server *Server) searchProduct(ctx *gin.Context) {
var req searchProductRequest
if err := ctx.ShouldBindQuery(&req); err != nil {
ctx.JSON(http.StatusBadRequest, errorResponse(err))
return
}
arg := db.SearchProductParams{
Limit: req.PageSize,
SearchQuery: req.q,
}
product, err := server.store.SearchProduct(ctx, arg)
if err != nil {
if err == sql.ErrNoRows {
ctx.JSON(http.StatusNotFound, errorResponse(err))
return
}
ctx.JSON(http.StatusInternalServerError, errorResponse(err))
return
}
ctx.JSON(http.StatusOK, product)
}
Below is the query function:
const searchProduct = `-- name: SearchProduct :many
SELECT id, name, owner, price, description, imgs_url, imgs_name, created_at, tsv
FROM products
WHERE textsearchable_index_col @@ to_tsquery($2)
ORDER BY created_at DESC
LIMIT $1
`
type SearchProductParams struct {
Limit int32 `json:"limit"`
SearchQuery string `json:"search_query"`
}
func (q *Queries) SearchProduct(ctx context.Context, arg SearchProductParams) ([]Product, error) {
rows, err := q.db.QueryContext(ctx, searchProduct, arg.Limit, arg.SearchQuery)
if err != nil {
return nil, err
}
defer rows.Close()
items := []Product{}
for rows.Next() {
var i Product
if err := rows.Scan(
&i.ID,
&i.Name,
&i.Owner,
&i.Price,
&i.Description,
pq.Array(&i.ImgsUrl),
pq.Array(&i.ImgsName),
&i.CreatedAt,
&i.Tsv,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
Running the SQL Raw Query against my db, i get the products with the query i sent. Below is the sql query:
-- name: SearchProduct :many
SELECT *
FROM products
WHERE textsearchable_index_col @@ to_tsquery(sqlc.arg(search_query))
ORDER BY created_at DESC
LIMIT $1;
I have tried to pass the request as a URI and as form parameter in postman, but both methods still return a 200 status with an empty list. Please, what is wrong with the function? What am i doing wrong? This is my third month learning GO.
q
, because it starts with a lower case letter, is unexported, which means it is inaccessible to any code outside of the package in which it was declared. Including reflection, which is used by the bind methods to which you are passing req
. In other words, change q
to Q
.
And here's the official language specification on the matter: https://go.dev/ref/spec#Exported_identifiers