FreeGrid Go server helper
=========================

freegrid/freegrid.go   package freegrid, standard library only, Go 1.22+

  freegrid.ReadRequest(body)   reads restDatasource's request (paging, sort, filters, quick filter, advanced filter, grouping)
  (*Query).Build(r)            turns it into SQL: Where, OrderBy, Page, Args, CountArgs, Group
  freegrid.ReadRows(rows)      rows for the {"rows", "total"} response, dates as "YYYY-MM-DD"
  freegrid.ReadSave(body)      {"created", "updated", "deleted"} from saveChanges()

  q := &freegrid.Query{
      Columns: map[string]freegrid.Column{"orderNo": {SQL: "ORDER_NO", Type: freegrid.Text}, "qty": {SQL: "QTY", Type: freegrid.Number}},
      Dialect:     freegrid.Limit,    // or freegrid.Standard (OFFSET ? ROWS FETCH NEXT ? ROWS ONLY)
      Placeholder: freegrid.Question, // or freegrid.Dollar (pgx, lib/pq), freegrid.AtP (go-mssqldb)
  }
  r, err := freegrid.ReadRequest(body)
  sql, err := q.Build(r)
  db.Query("SELECT ... FROM ORDERS"+sql.Where+sql.OrderBy+sql.Page, sql.Args...)

Copy the freegrid folder into your module and import it as <your module>/freegrid.

Only the columns you list can be sorted, filtered or grouped; every value is a bound parameter.
A bad number or date, an unknown filter op or too many values raises GridError: answer 400 { message }.
LIKE searches use ESCAPE '!', so % and _ typed in a filter are matched as text.

What the grid sends and what to answer, with a full example server:
  https://freegrid.app/docs/server/     (English)
  https://freegrid.app/ko/docs/server/  (한국어)

Use is covered by the FreeGrid license: https://freegrid.app/pricing/
