|
|
@@ -107,47 +107,33 @@ func (e *QueryExecutor) QueryToJSON(sql string) *types.QueryResult {
|
|
107
|
107
|
return result
|
|
108
|
108
|
}
|
|
109
|
109
|
|
|
110
|
|
-// QueryToCSV 查询并返回 CSV 字符串(包含表头,统一返回QueryResult)
|
|
111
|
|
-func (e *QueryExecutor) QueryToCSV(sql string) *types.QueryResult {
|
|
112
|
|
- startTime := time.Now()
|
|
113
|
|
- result := &types.QueryResult{}
|
|
|
110
|
+// QueryToCSV 查询并返回 CSV 字节数据(包含表头)
|
|
|
111
|
+func (e *QueryExecutor) QueryToCSV(sql string) ([]byte, error) {
|
|
114
|
112
|
|
|
115
|
113
|
if sql == "" {
|
|
116
|
|
- result.Success = false
|
|
117
|
|
- result.Error = "SQL query cannot be empty"
|
|
118
|
|
- result.Time = time.Since(startTime).String()
|
|
119
|
|
- return result
|
|
|
114
|
+ return nil, fmt.Errorf("SQL query cannot be empty")
|
|
120
|
115
|
}
|
|
121
|
116
|
|
|
122
|
117
|
rows, err := e.db.Query(sql)
|
|
123
|
118
|
if err != nil {
|
|
124
|
|
- result.Success = false
|
|
125
|
|
- result.Error = fmt.Sprintf("Query execution failed: %v", err)
|
|
126
|
|
- result.Time = time.Since(startTime).String()
|
|
127
|
|
- return result
|
|
|
119
|
+ return nil, fmt.Errorf("query execution failed: %v", err)
|
|
128
|
120
|
}
|
|
129
|
121
|
defer rows.Close()
|
|
130
|
122
|
|
|
131
|
123
|
columns, err := rows.Columns()
|
|
132
|
124
|
if err != nil {
|
|
133
|
|
- result.Success = false
|
|
134
|
|
- result.Error = fmt.Sprintf("Failed to get columns: %v", err)
|
|
135
|
|
- result.Time = time.Since(startTime).String()
|
|
136
|
|
- return result
|
|
|
125
|
+ return nil, fmt.Errorf("failed to get columns: %v", err)
|
|
137
|
126
|
}
|
|
138
|
127
|
|
|
139
|
128
|
var builder strings.Builder
|
|
140
|
129
|
writer := csv.NewWriter(&builder)
|
|
141
|
|
- count := 0
|
|
142
|
130
|
|
|
143
|
131
|
// 写入表头
|
|
144
|
132
|
if err := writer.Write(columns); err != nil {
|
|
145
|
|
- result.Success = false
|
|
146
|
|
- result.Error = fmt.Sprintf("Failed to write CSV header: %v", err)
|
|
147
|
|
- result.Time = time.Since(startTime).String()
|
|
148
|
|
- return result
|
|
|
133
|
+ return nil, fmt.Errorf("failed to write CSV header: %v", err)
|
|
149
|
134
|
}
|
|
150
|
135
|
|
|
|
136
|
+ count := 0
|
|
151
|
137
|
for rows.Next() {
|
|
152
|
138
|
count++
|
|
153
|
139
|
values := make([]interface{}, len(columns))
|
|
|
@@ -157,10 +143,7 @@ func (e *QueryExecutor) QueryToCSV(sql string) *types.QueryResult {
|
|
157
|
143
|
}
|
|
158
|
144
|
|
|
159
|
145
|
if err := rows.Scan(valuePtrs...); err != nil {
|
|
160
|
|
- result.Success = false
|
|
161
|
|
- result.Error = fmt.Sprintf("Failed to scan row: %v", err)
|
|
162
|
|
- result.Time = time.Since(startTime).String()
|
|
163
|
|
- return result
|
|
|
146
|
+ return nil, fmt.Errorf("failed to scan row: %v", err)
|
|
164
|
147
|
}
|
|
165
|
148
|
|
|
166
|
149
|
// 所有值转为字符串
|
|
|
@@ -174,37 +157,20 @@ func (e *QueryExecutor) QueryToCSV(sql string) *types.QueryResult {
|
|
174
|
157
|
}
|
|
175
|
158
|
|
|
176
|
159
|
if err := writer.Write(row); err != nil {
|
|
177
|
|
- result.Success = false
|
|
178
|
|
- result.Error = fmt.Sprintf("Failed to write CSV row: %v", err)
|
|
179
|
|
- result.Time = time.Since(startTime).String()
|
|
180
|
|
- return result
|
|
|
160
|
+ return nil, fmt.Errorf("failed to write CSV row: %v", err)
|
|
181
|
161
|
}
|
|
182
|
162
|
}
|
|
183
|
163
|
|
|
184
|
164
|
writer.Flush()
|
|
185
|
165
|
if err := writer.Error(); err != nil {
|
|
186
|
|
- result.Success = false
|
|
187
|
|
- result.Error = fmt.Sprintf("Failed to flush CSV: %v", err)
|
|
188
|
|
- result.Time = time.Since(startTime).String()
|
|
189
|
|
- return result
|
|
|
166
|
+ return nil, fmt.Errorf("failed to flush CSV: %v", err)
|
|
190
|
167
|
}
|
|
191
|
168
|
|
|
192
|
169
|
if err := rows.Err(); err != nil {
|
|
193
|
|
- result.Success = false
|
|
194
|
|
- result.Error = fmt.Sprintf("Row iteration error: %v", err)
|
|
195
|
|
- result.Time = time.Since(startTime).String()
|
|
196
|
|
- return result
|
|
|
170
|
+ return nil, fmt.Errorf("row iteration error: %v", err)
|
|
197
|
171
|
}
|
|
198
|
172
|
|
|
199
|
|
- result.Success = true
|
|
200
|
|
- result.Data = map[string]interface{}{
|
|
201
|
|
- "csv": builder.String(),
|
|
202
|
|
- "count": count,
|
|
203
|
|
- "includeHeader": true,
|
|
204
|
|
- }
|
|
205
|
|
- result.Count = count
|
|
206
|
|
- result.Time = time.Since(startTime).String()
|
|
207
|
|
- return result
|
|
|
173
|
+ return []byte(builder.String()), nil
|
|
208
|
174
|
}
|
|
209
|
175
|
|
|
210
|
176
|
// ExecuteQueryWithColumns 执行查询并返回完整结果(包含列信息)
|