Files
workspace/code/app/app-go/pkg/db/select.go
T
2026-06-25 16:47:54 +08:00

186 lines
3.1 KiB
Go

package db
import (
"allapp-go/pkg/logger"
"context"
"fmt"
"strconv"
"strings"
"go.uber.org/zap"
)
func (c *Client) LoadData(
ctx context.Context,
viewName string,
searchCondition string,
orderBy string,
searchColumns []string,
args []any,
) ([]map[string]any, error) {
selectCols := "*"
if len(searchColumns) > 0 {
selectCols = strings.Join(searchColumns, ", ")
}
where := ""
if searchCondition != "" {
where = " WHERE " + searchCondition
}
order := ""
if orderBy != "" {
order = " ORDER BY " + orderBy
}
sql := fmt.Sprintf(
"SELECT %s FROM %s%s%s",
selectCols,
viewName,
where,
order,
)
logger.FromCtx(ctx).Info("LoadData",
zap.String("sql", sql),
zap.Any("args", args),
)
return c.query(ctx, sql, args...)
}
func (c *Client) LoadDataPage(
ctx context.Context,
viewName string,
searchCondition string,
orderBy string,
searchColumns []string,
args []any,
page int,
pageSize int,
) ([]map[string]any, int, error) {
selectCols := "*"
if len(searchColumns) > 0 {
selectCols = strings.Join(searchColumns, ", ")
}
where := ""
if searchCondition != "" {
where = " WHERE " + searchCondition
}
// 1. COUNT 查询
countSQL := fmt.Sprintf("SELECT COUNT(*) FROM %s%s", viewName, where)
countSQL = convertPlaceholder(countSQL)
var total int
err := c.pool.QueryRow(ctx, countSQL, args...).Scan(&total)
if err != nil {
return nil, 0, err
}
// 2. 分页数据查询
order := ""
if orderBy != "" {
order = " ORDER BY " + orderBy
}
offset := (page - 1) * pageSize
dataSQL := fmt.Sprintf(
"SELECT %s FROM %s%s%s LIMIT %d OFFSET %d",
selectCols,
viewName,
where,
order,
pageSize,
offset,
)
logger.FromCtx(ctx).Info("LoadDataPage",
zap.String("countSQL", countSQL),
zap.String("dataSQL", dataSQL),
zap.Any("args", args),
zap.Int("total", total),
)
rows, err := c.query(ctx, dataSQL, args...)
if err != nil {
return nil, 0, err
}
return rows, total, nil
}
func (c *Client) LoadDataBySQL(
ctx context.Context,
sql string,
args []any,
) ([]map[string]any, error) {
logger.FromCtx(ctx).Info("LoadDataBySQL",
zap.String("sql", sql),
zap.Any("args", args),
)
return c.query(ctx, sql, args...)
}
func (c *Client) query(ctx context.Context, sql string, args ...any) ([]map[string]any, error) {
sql = convertPlaceholder(sql)
rows, err := c.pool.Query(ctx, sql, args...)
if err != nil {
return nil, err
}
defer rows.Close()
fields := rows.FieldDescriptions()
result := make([]map[string]any, 0, 16)
for rows.Next() {
values, err := rows.Values()
if err != nil {
return nil, err
}
row := make(map[string]any, len(values))
for i := range fields {
if i < len(values) {
row[string(fields[i].Name)] = values[i]
}
}
result = append(result, row)
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func convertPlaceholder(sql string) string {
var sb strings.Builder
sb.Grow(len(sql))
argIndex := 1
for i := 0; i < len(sql); i++ {
if sql[i] == '?' {
sb.WriteByte('$')
sb.WriteString(strconv.Itoa(argIndex))
argIndex++
} else {
sb.WriteByte(sql[i])
}
}
return sb.String()
}