package main
import (
"io"
"database/sql"
"encoding/json"
"fmt"
"log"
"os"
"regexp"
"strings"
_ "github.com/lib/pq"
)
type Request struct {
DB string `json:"db"`
SQL string `json:"sql"`
Params []any `json:"params"`
}
func main() {
inSql, err := io.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("读取输入失败: %v", err)
}
sqlText := strings.TrimSpace(string(inSql))
if sqlText == "" {
log.Println("未输入 SQL")
return
}
req := Request{
DB: "glot",
SQL: sqlText,
}
if inSql[0] == '{' {
err := json.Unmarshal(inSql, &req)
if err != nil {
log.Println(`{"code": 10000000, "message": "invalid request"}`)
return
}
}
fmt.Println(req)
// 数据库连接参数
connStr := "postgres://glot:glot@192.168.222.222:5432/"+req.DB+"?sslmode=disable"
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatalf("连接数据库失败: %v", err)
}
defer db.Close()
isQuery := isSelectQuery(req.SQL)
if isQuery {
handleQuery(db, req.SQL, req.Params)
} else {
handleExec(db, req.SQL, req.Params)
}
}
// 判断是否是查询语句(简单基于关键字判断)
func isSelectQuery(sqlText string) bool {
re := regexp.MustCompile(`(?i)^\s*(SELECT|WITH)\b`)
return re.MatchString(sqlText)
}
// 处理 SELECT / WITH 等查询语句
func handleQuery(db *sql.DB, query string, params []any) {
rows, err := db.Query(query, params...)
if err != nil {
log.Fatalf("执行查询失败: %v", err)
}
defer rows.Close()
cols, err := rows.Columns()
if err != nil {
log.Fatalf("读取列失败: %v", err)
}
results := []map[string]interface{}{}
for rows.Next() {
// 为每列准备存储空间
values := make([]interface{}, len(cols))
valuePtrs := make([]interface{}, len(cols))
for i := range cols {
valuePtrs[i] = &values[i]
}
if err := rows.Scan(valuePtrs...); err != nil {
log.Fatalf("读取行数据失败: %v", err)
}
rowMap := make(map[string]interface{})
for i, col := range cols {
val := values[i]
// 类型转换处理
if b, ok := val.([]byte); ok {
rowMap[col] = string(b)
} else {
rowMap[col] = val
}
}
results = append(results, rowMap)
}
data, _ := json.MarshalIndent(results, "", " ")
fmt.Println(string(data))
}
// 处理 INSERT / UPDATE / DELETE / CREATE 等语句
func handleExec(db *sql.DB, stmt string, params []any) {
result, err := db.Exec(stmt, params...)
if err != nil {
log.Fatalf("执行语句失败: %v", err)
}
rowsAffected, _ := result.RowsAffected()
lastInsertId, _ := result.LastInsertId()
out := map[string]interface{}{
"rows_affected": rowsAffected,
"last_insert_id": func() interface{} {
if lastInsertId > 0 {
return lastInsertId
}
return nil
}(),
"status": "ok",
}
data, _ := json.MarshalIndent(out, "", " ")
fmt.Println(string(data))
}
module glot-api
go 1.24.5
require (
github.com/nats-io/nats.go master
)