diff --git a/admin/db.go b/admin/db.go index 9c4fd7f..356d415 100644 --- a/admin/db.go +++ b/admin/db.go @@ -8,8 +8,48 @@ import ( sq "github.com/Masterminds/squirrel" ) -func SelectTable(table string, the_type reflect.Type, limit uint64, page uint64) ([]interface{}, error) { - var results []interface{} +func SearchTable(search string, table string, the_type reflect.Type, limit uint64, page uint64) ([]any, error) { + + var results []any + like := fmt.Sprint("%", search, "%") + + builder := sq.Select("*"). + Limit(limit). + Offset(limit * page). + From(table) + + field_num := the_type.NumField() + var or_clause sq.Or + + for i := 0; i < field_num; i++ { + tag := the_type.Field(i).Tag.Get("db") + or_clause = append(or_clause, sq.Like{tag: like}) + } + + builder = builder.Where(or_clause) + sql_query, args, err := builder.ToSql() + fmt.Println("-------------- SQL QUERY:", sql_query); + + if err != nil { return results, err } + + // BUG: refactor this to share a common func with SelectTable + rows, err := data.DB.Queryx(sql_query, args...) + if err != nil { return results, err } + defer rows.Close() + + for rows.Next() { + the_data := reflect.New(the_type).Interface() + err = rows.StructScan(the_data) + if err != nil { return results, err } + + results = append(results, the_data) + } + + return results, rows.Err() +} + +func SelectTable(table string, the_type reflect.Type, limit uint64, page uint64) ([]any, error) { + var results []any sql_query, args, err := sq.Select("*").Limit(limit).Offset(limit * page).From(table).ToSql() if err != nil { return results, err } @@ -51,7 +91,7 @@ func Insert(table string, value reflect.Value) (int64, int64, error) { type_of := value.Type() field_num := value.NumField() var columns []string - var values []interface{} + var values []any for i := 0; i < field_num; i++ { field := value.Field(i) diff --git a/admin/handlers.go b/admin/handlers.go index 33a81e8..44a15b4 100644 --- a/admin/handlers.go +++ b/admin/handlers.go @@ -25,11 +25,21 @@ func GetApiSelectAll(c *fiber.Ctx) error { type_is := data.Models()[table] page := c.QueryInt("page", 0) - fmt.Println("-------------------------", page) if page < 0 { page = 0 } - result, err := SelectTable(table, type_is, 20, uint64(page)); - if err != nil { return IfErrNil(err, c) } + search := c.Query("search", "") + var result []any + var err error + + if search == "" { + result, err = SelectTable(table, type_is, 20, uint64(page)); + if err != nil { return IfErrNil(err, c) } + } else { + // NOTE: need a 404 here when there's no result? or empty list? + fmt.Println("---------------- SEARCH", search) + result, err = SearchTable(search, table, type_is, 20, uint64(page)); + if err != nil { return IfErrNil(err, c) } + } return c.JSON(result) } diff --git a/static/js/code.js b/static/js/code.js index 9c2105f..e7da7ae 100644 --- a/static/js/code.js +++ b/static/js/code.js @@ -4,17 +4,28 @@ class PaginateTable { this.items = []; this.url = url; this.headers = []; + this.search_query="" } async contents() { if(this.page < 0) this.page = 0; - const resp = await fetch(`${this.url}?page=${this.page}`); + let url = `${this.url}?page=${this.page}`; + + if(this.search_query !== "") { + this.page = 0; + url += `&search=${this.search_query}` + } + + const resp = await fetch(url); console.assert(resp.status == 200, "failed to get it"); - this.items = await resp.json(); + const items = await resp.json(); - this.headers = Object.keys(this.items[0]); + if(items) { + this.items = items; + this.headers = Object.keys(this.items[0]); + } return this.items; } diff --git a/views/admin/table/contents.html b/views/admin/table/contents.html index 766eb19..9c79e05 100644 --- a/views/admin/table/contents.html +++ b/views/admin/table/contents.html @@ -10,8 +10,7 @@ - - +