package com.cube.api;
import com.cube.sql.SQLExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.*;
/**
* SQL API Controller - Execute SQL statements via REST API
*/
@RestController
@RequestMapping("/api/v1/sql")
public class SQLController {
private static final Logger logger = LoggerFactory.getLogger(SQLController.class);
@Autowired(required = false)
private SQLExecutor sqlExecutor;
/**
* Execute SQL statement
*
* POST /api/v1/sql/execute
* Body: { "sql": "SELECT * FROM users.profiles WHERE id = 'user-1'" }
*/
@PostMapping("/execute")
public ResponseEntity<Map<String, Object>> execute(@RequestBody Map<String, String> request) {
if (sqlExecutor == null) {
return ResponseEntity.status(503).body(Map.of(
"success", false,
"message", "SQL executor not initialized"
));
}
String sql = request.get("sql");
if (sql == null || sql.trim().isEmpty()) {
return ResponseEntity.badRequest().body(Map.of(
"success", false,
"message", "SQL statement is required"
));
}
try {
logger.info("Executing SQL: {}", sql);
SQLExecutor.SQLResult result = sqlExecutor.execute(sql);
Map<String, Object> response = new LinkedHashMap<>();
response.put("success", result.isSuccess());
response.put("message", result.getMessage());
if (result.getRows() != null && !result.getRows().isEmpty()) {
response.put("rows", result.getRows());
response.put("rowCount", result.getRows().size());
}
if (result.getRowsAffected() > 0) {
response.put("rowsAffected", result.getRowsAffected());
}
return ResponseEntity.ok(response);
} catch (Exception e) {
logger.error("SQL execution error", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false,
"message", "Error: " + e.getMessage()
));
}
}
/**
* Execute multiple SQL statements (batch)
*
* POST /api/v1/sql/batch
* Body: { "statements": ["INSERT ...", "UPDATE ...", "SELECT ..."] }
*/
@PostMapping("/batch")
public ResponseEntity<Map<String, Object>> executeBatch(@RequestBody Map<String, List<String>> request) {
if (sqlExecutor == null) {
return ResponseEntity.status(503).body(Map.of(
"success", false,
"message", "SQL executor not initialized"
));
}
List<String> statements = request.get("statements");
if (statements == null || statements.isEmpty()) {
return ResponseEntity.badRequest().body(Map.of(
"success", false,
"message", "SQL statements are required"
));
}
try {
List<Map<String, Object>> results = new ArrayList<>();
int successCount = 0;
int failureCount = 0;
for (String sql : statements) {
SQLExecutor.SQLResult result = sqlExecutor.execute(sql);
Map<String, Object> resultMap = new LinkedHashMap<>();
resultMap.put("sql", sql);
resultMap.put("success", result.isSuccess());
resultMap.put("message", result.getMessage());
if (result.getRows() != null && !result.getRows().isEmpty()) {
resultMap.put("rowCount", result.getRows().size());
}
results.add(resultMap);
if (result.isSuccess()) {
successCount++;
} else {
failureCount++;
}
}
Map<String, Object> response = new LinkedHashMap<>();
response.put("success", failureCount == 0);
response.put("total", statements.size());
response.put("successful", successCount);
response.put("failed", failureCount);
response.put("results", results);
return ResponseEntity.ok(response);
} catch (Exception e) {
logger.error("Batch execution error", e);
return ResponseEntity.internalServerError().body(Map.of(
"success", false,
"message", "Error: " + e.getMessage()
));
}
}
}