package builder import ( "database/sql" "fmt" "html" "math" "strconv" "golang-fave/engine/sqlw" "golang-fave/engine/utils" "golang-fave/engine/wrapper" ) type DataTableRow struct { DBField string DBExp string NameInTable string Classes string CallBack func(values *[]string) string } func DataTable( wrap *wrapper.Wrapper, table string, order_by string, order_way string, data *[]DataTableRow, action func(values *[]string) string, pagination_url string, custom_sql_count func() (int, error), custom_sql_data func(limit_offset int, pear_page int) (*sqlw.Rows, error), pagination_enabled bool, ) string { var num int var err error if pagination_enabled { if custom_sql_count != nil { num, err = custom_sql_count() wrap.LogCpError(&err) } else { err = wrap.DB.QueryRow(wrap.R.Context(), "SELECT COUNT(*) FROM `"+table+"`;").Scan(&num) if *wrap.LogCpError(&err) != nil { return "" } } } else { num = 0 } pear_page := 10 max_pages := int(math.Ceil(float64(num) / float64(pear_page))) curr_page := 1 p := wrap.R.URL.Query().Get("p") if p != "" { pi, err := strconv.Atoi(p) if err != nil { curr_page = 1 } else { if pi < 1 { curr_page = 1 } else if pi > max_pages { curr_page = max_pages } else { curr_page = pi } } } limit_offset := curr_page*pear_page - pear_page result := `` result += `` result += `` qsql := "" if custom_sql_data == nil { qsql = "SELECT" } for i, column := range *data { if column.NameInTable != "" { classes := column.Classes if classes != "" { classes = " " + classes } result += `` } if custom_sql_data == nil { if column.DBExp == "" { qsql += " `" + column.DBField + "`" } else { qsql += " " + column.DBExp + " as `" + column.DBField + "`" } if i+1 < len(*data) { qsql += "," } } } if custom_sql_data == nil { qsql += " FROM `" + table + "` ORDER BY `" + order_by + "` " + order_way + " LIMIT ?, ?;" } if action != nil { result += `` } result += `` result += `` result += `` if num > 0 || !pagination_enabled { have_records := false var rows *sqlw.Rows var err error if custom_sql_data == nil { rows, err = wrap.DB.Query(wrap.R.Context(), qsql, limit_offset, pear_page) } else { rows, err = custom_sql_data(limit_offset, pear_page) } if *wrap.LogCpError(&err) == nil { values := make([]sql.NullString, len(*data)) scan := make([]interface{}, len(values)) for i := range values { scan[i] = &values[i] } for rows.Next() { err = rows.Scan(scan...) if *wrap.LogCpError(&err) == nil { if !have_records { have_records = true } result += `` for i, val := range values { if (*data)[i].NameInTable != "" { classes := (*data)[i].Classes if classes != "" { classes = " " + classes } if (*data)[i].CallBack == nil { result += `` } else { result += `` } } } if action != nil { result += `` } result += `` } } rows.Close() } if !have_records { result += `` } } else { result += `` } result += `
` + html.EscapeString(column.NameInTable) + ` 
` + html.EscapeString(string(val.String)) + `` + (*data)[i].CallBack(utils.SqlNullStringToString(&values)) + `` + action(utils.SqlNullStringToString(&values)) + `
No data
No data
` // Show page navigation only if pages more then one if pagination_enabled { if max_pages > 1 { result += `` } } return result }