Nenhuma descrição
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

query.go 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. package functions
  2. import (
  3. "encoding/csv"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "strings"
  8. "time"
  9. "git.x2erp.com/qdy/go-base/types"
  10. "github.com/jmoiron/sqlx"
  11. )
  12. // QueryToJSON 执行查询并返回JSON格式数据(统一返回QueryResult)
  13. func QueryToJSON(db *sqlx.DB, sql string) *types.QueryResult {
  14. startTime := time.Now()
  15. result := &types.QueryResult{}
  16. if sql == "" {
  17. result.Success = false
  18. result.Error = "SQL query cannot be empty"
  19. result.Time = time.Since(startTime).String()
  20. return result
  21. }
  22. rows, err := db.Query(sql)
  23. if err != nil {
  24. result.Success = false
  25. result.Error = fmt.Sprintf("Query execution failed: %v", err)
  26. result.Time = time.Since(startTime).String()
  27. return result
  28. }
  29. defer rows.Close()
  30. columns, err := rows.Columns()
  31. if err != nil {
  32. result.Success = false
  33. result.Error = fmt.Sprintf("Failed to get columns: %v", err)
  34. result.Time = time.Since(startTime).String()
  35. return result
  36. }
  37. var results []map[string]interface{}
  38. count := 0
  39. for rows.Next() {
  40. count++
  41. values := make([]interface{}, len(columns))
  42. valuePtrs := make([]interface{}, len(columns))
  43. for i := range columns {
  44. valuePtrs[i] = &values[i]
  45. }
  46. if err := rows.Scan(valuePtrs...); err != nil {
  47. result.Success = false
  48. result.Error = fmt.Sprintf("Failed to scan row: %v", err)
  49. result.Time = time.Since(startTime).String()
  50. return result
  51. }
  52. resultMap := make(map[string]interface{})
  53. for i, col := range columns {
  54. // 完全不处理类型,直接赋值,让 json.Marshal 自己处理
  55. resultMap[col] = values[i]
  56. }
  57. results = append(results, resultMap)
  58. }
  59. if err := rows.Err(); err != nil {
  60. result.Success = false
  61. result.Error = fmt.Sprintf("Row iteration error: %v", err)
  62. result.Time = time.Since(startTime).String()
  63. return result
  64. }
  65. jsonData, err := json.Marshal(results)
  66. if err != nil {
  67. result.Success = false
  68. result.Error = fmt.Sprintf("JSON marshal failed: %v", err)
  69. result.Time = time.Since(startTime).String()
  70. return result
  71. }
  72. result.Success = true
  73. result.Data = map[string]interface{}{
  74. "json": string(jsonData),
  75. "rows": results,
  76. "count": count,
  77. }
  78. result.Count = count
  79. result.Time = time.Since(startTime).String()
  80. return result
  81. }
  82. // QueryToCSV 查询并返回 CSV 字节数据(包含表头)
  83. func QueryToCSV(db *sqlx.DB, sql string) ([]byte, error) {
  84. if sql == "" {
  85. return nil, fmt.Errorf("SQL query cannot be empty")
  86. }
  87. rows, err := db.Query(sql)
  88. if err != nil {
  89. return nil, fmt.Errorf("query execution failed: %v", err)
  90. }
  91. defer rows.Close()
  92. columns, err := rows.Columns()
  93. if err != nil {
  94. return nil, fmt.Errorf("failed to get columns: %v", err)
  95. }
  96. var builder strings.Builder
  97. writer := csv.NewWriter(&builder)
  98. // 写入表头
  99. //if err := writer.Write(columns); err != nil {
  100. // return nil, fmt.Errorf("failed to write CSV header: %v", err)
  101. //}
  102. count := 0
  103. for rows.Next() {
  104. count++
  105. values := make([]interface{}, len(columns))
  106. valuePtrs := make([]any, len(columns))
  107. for i := range columns {
  108. valuePtrs[i] = &values[i]
  109. }
  110. if err := rows.Scan(valuePtrs...); err != nil {
  111. return nil, fmt.Errorf("failed to scan row: %v", err)
  112. }
  113. // 所有值转为字符串
  114. row := make([]string, len(columns))
  115. for i, val := range values {
  116. if val == nil {
  117. row[i] = ""
  118. } else {
  119. row[i] = fmt.Sprintf("%v", val)
  120. }
  121. }
  122. if err := writer.Write(row); err != nil {
  123. return nil, fmt.Errorf("failed to write CSV row: %v", err)
  124. }
  125. }
  126. writer.Flush()
  127. if err := writer.Error(); err != nil {
  128. return nil, fmt.Errorf("failed to flush CSV: %v", err)
  129. }
  130. if err := rows.Err(); err != nil {
  131. return nil, fmt.Errorf("row iteration error: %v", err)
  132. }
  133. return []byte(builder.String()), nil
  134. }
  135. // ExecuteQueryWithColumns 执行查询并返回完整结果(包含列信息)
  136. func QueryWithColumns(db *sqlx.DB, sql string) *types.QueryResult {
  137. startTime := time.Now()
  138. result := &types.QueryResult{}
  139. if sql == "" {
  140. result.Success = false
  141. result.Error = "SQL query cannot be empty"
  142. result.Time = time.Since(startTime).String()
  143. return result
  144. }
  145. rows, err := db.Query(sql)
  146. if err != nil {
  147. result.Success = false
  148. result.Error = fmt.Sprintf("Query execution failed: %v", err)
  149. result.Time = time.Since(startTime).String()
  150. return result
  151. }
  152. defer rows.Close()
  153. columns, err := rows.Columns()
  154. if err != nil {
  155. result.Success = false
  156. result.Error = fmt.Sprintf("Failed to get columns: %v", err)
  157. result.Time = time.Since(startTime).String()
  158. return result
  159. }
  160. var results []map[string]interface{}
  161. count := 0
  162. for rows.Next() {
  163. count++
  164. values := make([]interface{}, len(columns))
  165. valuePtrs := make([]interface{}, len(columns))
  166. for i := range columns {
  167. valuePtrs[i] = &values[i]
  168. }
  169. if err := rows.Scan(valuePtrs...); err != nil {
  170. result.Success = false
  171. result.Error = fmt.Sprintf("Failed to scan row: %v", err)
  172. result.Time = time.Since(startTime).String()
  173. return result
  174. }
  175. resultRow := make(map[string]interface{})
  176. for i, col := range columns {
  177. val := values[i]
  178. switch v := val.(type) {
  179. case []byte:
  180. resultRow[col] = string(v)
  181. case time.Time:
  182. resultRow[col] = v.Format(time.RFC3339)
  183. default:
  184. resultRow[col] = v
  185. }
  186. }
  187. results = append(results, resultRow)
  188. }
  189. if err := rows.Err(); err != nil {
  190. result.Success = false
  191. result.Error = fmt.Sprintf("Row iteration error: %v", err)
  192. result.Time = time.Since(startTime).String()
  193. return result
  194. }
  195. result.Success = true
  196. result.Data = results
  197. result.Count = count
  198. result.Time = time.Since(startTime).String()
  199. return result
  200. }
  201. // ExecuteQueryDataOnly 执行查询并返回纯数据(不包含列信息,性能更高)
  202. func QueryDataOnly(db *sqlx.DB, sql string) *types.QueryResult {
  203. startTime := time.Now()
  204. result := &types.QueryResult{}
  205. if sql == "" {
  206. result.Success = false
  207. result.Error = "SQL query cannot be empty"
  208. result.Time = time.Since(startTime).String()
  209. return result
  210. }
  211. rows, err := db.Query(sql)
  212. if err != nil {
  213. result.Success = false
  214. result.Error = fmt.Sprintf("Query execution failed: %v", err)
  215. result.Time = time.Since(startTime).String()
  216. return result
  217. }
  218. defer rows.Close()
  219. columns, err := rows.Columns()
  220. if err != nil {
  221. result.Success = false
  222. result.Error = fmt.Sprintf("Failed to get columns: %v", err)
  223. result.Time = time.Since(startTime).String()
  224. return result
  225. }
  226. var results []interface{}
  227. count := 0
  228. for rows.Next() {
  229. count++
  230. values := make([]interface{}, len(columns))
  231. valuePtrs := make([]interface{}, len(columns))
  232. for i := range columns {
  233. valuePtrs[i] = &values[i]
  234. }
  235. if err := rows.Scan(valuePtrs...); err != nil {
  236. result.Success = false
  237. result.Error = fmt.Sprintf("Failed to scan row: %v", err)
  238. result.Time = time.Since(startTime).String()
  239. return result
  240. }
  241. resultRow := make([]interface{}, len(columns))
  242. for i, val := range values {
  243. switch v := val.(type) {
  244. case []byte:
  245. resultRow[i] = string(v)
  246. case time.Time:
  247. resultRow[i] = v.Format(time.RFC3339)
  248. default:
  249. resultRow[i] = v
  250. }
  251. }
  252. results = append(results, resultRow)
  253. }
  254. if err := rows.Err(); err != nil {
  255. result.Success = false
  256. result.Error = fmt.Sprintf("Row iteration error: %v", err)
  257. result.Time = time.Since(startTime).String()
  258. return result
  259. }
  260. result.Success = true
  261. result.Data = map[string]interface{}{
  262. "rows": results,
  263. "count": count,
  264. }
  265. result.Count = count
  266. result.Time = time.Since(startTime).String()
  267. return result
  268. }
  269. // ExecuteQueryCSV 执行查询并返回CSV格式数据
  270. func QueryCSV(db *sqlx.DB, sql string, includeHeader bool) *types.QueryResult {
  271. startTime := time.Now()
  272. result := &types.QueryResult{}
  273. if sql == "" {
  274. result.Success = false
  275. result.Error = "SQL query cannot be empty"
  276. result.Time = time.Since(startTime).String()
  277. return result
  278. }
  279. rows, err := db.Query(sql)
  280. if err != nil {
  281. result.Success = false
  282. result.Error = fmt.Sprintf("Query execution failed: %v", err)
  283. result.Time = time.Since(startTime).String()
  284. return result
  285. }
  286. defer rows.Close()
  287. columns, err := rows.Columns()
  288. if err != nil {
  289. result.Success = false
  290. result.Error = fmt.Sprintf("Failed to get columns: %v", err)
  291. result.Time = time.Since(startTime).String()
  292. return result
  293. }
  294. var csvBuilder strings.Builder
  295. writer := csv.NewWriter(&csvBuilder)
  296. if includeHeader {
  297. if err := writer.Write(columns); err != nil {
  298. result.Success = false
  299. result.Error = fmt.Sprintf("Failed to write CSV header: %v", err)
  300. result.Time = time.Since(startTime).String()
  301. return result
  302. }
  303. }
  304. count := 0
  305. for rows.Next() {
  306. count++
  307. values := make([]interface{}, len(columns))
  308. valuePtrs := make([]interface{}, len(columns))
  309. for i := range columns {
  310. valuePtrs[i] = &values[i]
  311. }
  312. if err := rows.Scan(valuePtrs...); err != nil {
  313. result.Success = false
  314. result.Error = fmt.Sprintf("Failed to scan row: %v", err)
  315. result.Time = time.Since(startTime).String()
  316. return result
  317. }
  318. rowData := make([]string, len(columns))
  319. for i, val := range values {
  320. if val == nil {
  321. rowData[i] = ""
  322. continue
  323. }
  324. switch v := val.(type) {
  325. case []byte:
  326. rowData[i] = string(v)
  327. case string:
  328. rowData[i] = v
  329. case int, int8, int16, int32, int64:
  330. rowData[i] = fmt.Sprintf("%d", v)
  331. case uint, uint8, uint16, uint32, uint64:
  332. rowData[i] = fmt.Sprintf("%d", v)
  333. case float32, float64:
  334. rowData[i] = fmt.Sprintf("%f", v)
  335. case bool:
  336. if v {
  337. rowData[i] = "true"
  338. } else {
  339. rowData[i] = "false"
  340. }
  341. case time.Time:
  342. rowData[i] = v.Format(time.RFC3339)
  343. default:
  344. rowData[i] = fmt.Sprintf("%v", v)
  345. }
  346. }
  347. if err := writer.Write(rowData); err != nil {
  348. result.Success = false
  349. result.Error = fmt.Sprintf("Failed to write CSV row: %v", err)
  350. result.Time = time.Since(startTime).String()
  351. return result
  352. }
  353. }
  354. if err := rows.Err(); err != nil {
  355. result.Success = false
  356. result.Error = fmt.Sprintf("Row iteration error: %v", err)
  357. result.Time = time.Since(startTime).String()
  358. return result
  359. }
  360. writer.Flush()
  361. if err := writer.Error(); err != nil {
  362. result.Success = false
  363. result.Error = fmt.Sprintf("Failed to flush CSV: %v", err)
  364. result.Time = time.Since(startTime).String()
  365. return result
  366. }
  367. result.Success = true
  368. result.Data = map[string]interface{}{
  369. "csv": csvBuilder.String(),
  370. "count": count,
  371. "includeHeader": includeHeader,
  372. }
  373. result.Count = count
  374. result.Time = time.Since(startTime).String()
  375. return result
  376. }
  377. // ExecuteQueryCSVStream 流式返回CSV数据
  378. func QueryCSVStream(db *sqlx.DB, sql string, w io.Writer, includeHeader bool) (int, error) {
  379. rows, err := db.Query(sql)
  380. if err != nil {
  381. return 0, err
  382. }
  383. defer rows.Close()
  384. columns, err := rows.Columns()
  385. if err != nil {
  386. return 0, err
  387. }
  388. writer := csv.NewWriter(w)
  389. count := 0
  390. if includeHeader {
  391. if err := writer.Write(columns); err != nil {
  392. return 0, err
  393. }
  394. }
  395. for rows.Next() {
  396. count++
  397. values := make([]interface{}, len(columns))
  398. valuePtrs := make([]interface{}, len(columns))
  399. for i := range columns {
  400. valuePtrs[i] = &values[i]
  401. }
  402. if err := rows.Scan(valuePtrs...); err != nil {
  403. return count, err
  404. }
  405. rowData := make([]string, len(columns))
  406. for i, val := range values {
  407. if val == nil {
  408. rowData[i] = ""
  409. continue
  410. }
  411. rowData[i] = fmt.Sprintf("%v", val)
  412. }
  413. if err := writer.Write(rowData); err != nil {
  414. return count, err
  415. }
  416. }
  417. writer.Flush()
  418. if err := writer.Error(); err != nil {
  419. return count, err
  420. }
  421. if err := rows.Err(); err != nil {
  422. return count, err
  423. }
  424. return count, nil
  425. }