feat: add kafka admin integration
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
//go:build mysql
|
||||
// +build mysql
|
||||
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
t "github.com/tinode/chat/server/store/types"
|
||||
)
|
||||
|
||||
func (a *adapter) TenantInternalAdminQuery(id t.TenantID, query string, countQuery string, args []any, page, perPage int) (*t.InternalAdminQueryResult, error) {
|
||||
tenantAdp, err := a.routedTenantAdapter(id)
|
||||
if err != nil {
|
||||
return nil, t.ErrMalformed
|
||||
}
|
||||
if tenantAdp != a {
|
||||
return tenantAdp.TenantInternalAdminQuery(id, query, countQuery, args, page, perPage)
|
||||
}
|
||||
if strings.TrimSpace(query) == "" || strings.TrimSpace(countQuery) == "" {
|
||||
return nil, t.ErrMalformed
|
||||
}
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
if perPage <= 0 || perPage > 200 {
|
||||
perPage = 20
|
||||
}
|
||||
offset := (page - 1) * perPage
|
||||
ctx, cancel := a.getContext()
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
var total int64
|
||||
if err = a.db.GetContext(ctx, &total, countQuery, args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
queryArgs := append(append([]any{}, args...), perPage, offset)
|
||||
rows, err := a.db.QueryxContext(ctx, query+" LIMIT ? OFFSET ?", queryArgs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items, err := scanInternalAdminRows(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &t.InternalAdminQueryResult{Items: items, Total: total, Page: page, PerPage: perPage}, nil
|
||||
}
|
||||
|
||||
func (a *adapter) TenantInternalAdminQueryOne(id t.TenantID, query string, args []any) (map[string]any, error) {
|
||||
tenantAdp, err := a.routedTenantAdapter(id)
|
||||
if err != nil {
|
||||
return nil, t.ErrMalformed
|
||||
}
|
||||
if tenantAdp != a {
|
||||
return tenantAdp.TenantInternalAdminQueryOne(id, query, args)
|
||||
}
|
||||
if strings.TrimSpace(query) == "" {
|
||||
return nil, t.ErrMalformed
|
||||
}
|
||||
ctx, cancel := a.getContext()
|
||||
if cancel != nil {
|
||||
defer cancel()
|
||||
}
|
||||
rows, err := a.db.QueryxContext(ctx, query+" LIMIT 1", args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
items, err := scanInternalAdminRows(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(items) == 0 {
|
||||
return nil, t.ErrNotFound
|
||||
}
|
||||
return items[0], nil
|
||||
}
|
||||
|
||||
func scanInternalAdminRows(rows *sqlx.Rows) ([]map[string]any, error) {
|
||||
items := []map[string]any{}
|
||||
for rows.Next() {
|
||||
row := map[string]any{}
|
||||
if err := rows.MapScan(row); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for key, value := range row {
|
||||
row[key] = normalizeInternalAdminValue(value)
|
||||
}
|
||||
items = append(items, row)
|
||||
}
|
||||
return items, rows.Err()
|
||||
}
|
||||
|
||||
func normalizeInternalAdminValue(value any) any {
|
||||
switch v := value.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
case []byte:
|
||||
raw := strings.TrimSpace(string(v))
|
||||
if raw == "" {
|
||||
return ""
|
||||
}
|
||||
if (strings.HasPrefix(raw, "{") && strings.HasSuffix(raw, "}")) || (strings.HasPrefix(raw, "[") && strings.HasSuffix(raw, "]")) {
|
||||
var parsed any
|
||||
if json.Unmarshal([]byte(raw), &parsed) == nil {
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
return raw
|
||||
case time.Time:
|
||||
return v.UTC().Format(time.RFC3339Nano)
|
||||
case sql.NullTime:
|
||||
if v.Valid {
|
||||
return v.Time.UTC().Format(time.RFC3339Nano)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return value
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user