Newer
Older
cactus / src / main / java / com / cube / sql / SQLExecutor.java
@agalyaramadoss agalyaramadoss on 16 Feb 11 KB version update with 21
package com.cube.sql;

import com.cube.cql.CQLParser;
import com.cube.cql.QueryExecutor;
import com.cube.storage.StorageEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * SQL Executor - Executes SQL statements by translating to internal operations
 */
public class SQLExecutor {
    
    private static final Logger logger = LoggerFactory.getLogger(SQLExecutor.class);
    
    private final QueryExecutor queryExecutor;
    private final StorageEngine storageEngine;
    
    public static class SQLResult {
        private final boolean success;
        private final String message;
        private final List<Map<String, String>> rows;
        private final int rowsAffected;
        
        public SQLResult(boolean success, String message, List<Map<String, String>> rows, int rowsAffected) {
            this.success = success;
            this.message = message;
            this.rows = rows != null ? rows : new ArrayList<>();
            this.rowsAffected = rowsAffected;
        }
        
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public List<Map<String, String>> getRows() { return rows; }
        public int getRowsAffected() { return rowsAffected; }
        
        public static SQLResult success(String message) {
            return new SQLResult(true, message, null, 0);
        }
        
        public static SQLResult success(String message, int rowsAffected) {
            return new SQLResult(true, message, null, rowsAffected);
        }
        
        public static SQLResult success(List<Map<String, String>> rows) {
            return new SQLResult(true, "Query executed successfully", rows, rows.size());
        }
        
        public static SQLResult error(String message) {
            return new SQLResult(false, message, null, 0);
        }
    }
    
    public SQLExecutor(QueryExecutor queryExecutor, StorageEngine storageEngine) {
        this.queryExecutor = queryExecutor;
        this.storageEngine = storageEngine;
    }
    
    /**
     * Execute SQL statement
     */
    public SQLResult execute(String sql) {
        try {
            SQLParser.ParsedSQL parsedSQL = SQLParser.parse(sql);
            
            logger.info("Executing SQL: {} (Type: {})", sql, parsedSQL.getType());
            
            switch (parsedSQL.getType()) {
                case SELECT:
                    return executeSelect(parsedSQL);
                case INSERT:
                    return executeInsert(parsedSQL);
                case UPDATE:
                    return executeUpdate(parsedSQL);
                case DELETE:
                    return executeDelete(parsedSQL);
                case CREATE_TABLE:
                    return executeCreateTable(parsedSQL);
                case DROP_TABLE:
                    return executeDropTable(parsedSQL);
                case DESCRIBE:
                    return executeDescribe(parsedSQL);
                case SHOW_TABLES:
                    return executeShowTables();
                default:
                    return SQLResult.error("Unsupported SQL type: " + parsedSQL.getType());
            }
        } catch (Exception e) {
            logger.error("SQL execution error", e);
            return SQLResult.error("Error: " + e.getMessage());
        }
    }
    
    /**
     * Execute SELECT statement
     */
    private SQLResult executeSelect(SQLParser.ParsedSQL sql) {
        try {
            // Build CQL query
            StringBuilder cql = new StringBuilder("SELECT ");
            
            if (sql.getSelectColumns().contains("*")) {
                cql.append("*");
            } else {
                cql.append(String.join(", ", sql.getSelectColumns()));
            }
            
            cql.append(" FROM ").append(sql.getKeyspace()).append(".").append(sql.getTable());
            
            if (!sql.getWhereClause().isEmpty()) {
                cql.append(" WHERE ");
                List<String> conditions = new ArrayList<>();
                for (Map.Entry<String, String> entry : sql.getWhereClause().entrySet()) {
                    conditions.add(entry.getKey() + " = '" + entry.getValue() + "'");
                }
                cql.append(String.join(" AND ", conditions));
            }
            
            // Execute via CQL
            CQLParser.ParsedQuery parsedQuery = CQLParser.parse(cql.toString());
            QueryExecutor.Result result = queryExecutor.execute(parsedQuery);
            
            if (result.isSuccess()) {
                return SQLResult.success(convertRows(result.getRows()));
            } else {
                return SQLResult.error(result.getMessage());
            }
            
        } catch (Exception e) {
            return SQLResult.error("SELECT error: " + e.getMessage());
        }
    }
    
    /**
     * Execute INSERT statement
     */
    private SQLResult executeInsert(SQLParser.ParsedSQL sql) {
        try {
            // Build CQL query
            StringBuilder cql = new StringBuilder("INSERT INTO ");
            cql.append(sql.getKeyspace()).append(".").append(sql.getTable());
            cql.append(" (");
            
            List<String> columns = new ArrayList<>(sql.getColumns().keySet());
            cql.append(String.join(", ", columns));
            cql.append(") VALUES (");
            
            List<String> values = new ArrayList<>();
            for (String col : columns) {
                values.add("'" + sql.getColumns().get(col) + "'");
            }
            cql.append(String.join(", ", values));
            cql.append(")");
            
            // Execute via CQL
            CQLParser.ParsedQuery parsedQuery = CQLParser.parse(cql.toString());
            QueryExecutor.Result result = queryExecutor.execute(parsedQuery);
            
            if (result.isSuccess()) {
                return SQLResult.success(result.getMessage(), result.getRowsAffected());
            } else {
                return SQLResult.error(result.getMessage());
            }
            
        } catch (Exception e) {
            return SQLResult.error("INSERT error: " + e.getMessage());
        }
    }
    
    /**
     * Execute UPDATE statement
     */
    private SQLResult executeUpdate(SQLParser.ParsedSQL sql) {
        try {
            // Build CQL query
            StringBuilder cql = new StringBuilder("UPDATE ");
            cql.append(sql.getKeyspace()).append(".").append(sql.getTable());
            cql.append(" SET ");
            
            List<String> sets = new ArrayList<>();
            for (Map.Entry<String, String> entry : sql.getColumns().entrySet()) {
                sets.add(entry.getKey() + "='" + entry.getValue() + "'");
            }
            cql.append(String.join(", ", sets));
            
            cql.append(" WHERE ");
            List<String> conditions = new ArrayList<>();
            for (Map.Entry<String, String> entry : sql.getWhereClause().entrySet()) {
                conditions.add(entry.getKey() + "='" + entry.getValue() + "'");
            }
            cql.append(String.join(" AND ", conditions));
            
            // Execute via CQL
            CQLParser.ParsedQuery parsedQuery = CQLParser.parse(cql.toString());
            QueryExecutor.Result result = queryExecutor.execute(parsedQuery);
            
            if (result.isSuccess()) {
                return SQLResult.success(result.getMessage(), result.getRowsAffected());
            } else {
                return SQLResult.error(result.getMessage());
            }
            
        } catch (Exception e) {
            return SQLResult.error("UPDATE error: " + e.getMessage());
        }
    }
    
    /**
     * Execute DELETE statement
     */
    private SQLResult executeDelete(SQLParser.ParsedSQL sql) {
        try {
            // Build CQL query
            StringBuilder cql = new StringBuilder("DELETE FROM ");
            cql.append(sql.getKeyspace()).append(".").append(sql.getTable());
            cql.append(" WHERE ");
            
            List<String> conditions = new ArrayList<>();
            for (Map.Entry<String, String> entry : sql.getWhereClause().entrySet()) {
                conditions.add(entry.getKey() + "='" + entry.getValue() + "'");
            }
            cql.append(String.join(" AND ", conditions));
            
            // Execute via CQL
            CQLParser.ParsedQuery parsedQuery = CQLParser.parse(cql.toString());
            QueryExecutor.Result result = queryExecutor.execute(parsedQuery);
            
            if (result.isSuccess()) {
                return SQLResult.success(result.getMessage(), result.getRowsAffected());
            } else {
                return SQLResult.error(result.getMessage());
            }
            
        } catch (Exception e) {
            return SQLResult.error("DELETE error: " + e.getMessage());
        }
    }
    
    /**
     * Execute CREATE TABLE statement
     */
    private SQLResult executeCreateTable(SQLParser.ParsedSQL sql) {
        try {
            // Build CQL query
            StringBuilder cql = new StringBuilder("CREATE TABLE ");
            cql.append(sql.getKeyspace()).append(".").append(sql.getTable());
            cql.append(" (");
            
            List<String> colDefs = new ArrayList<>();
            for (Map.Entry<String, String> entry : sql.getColumnDefinitions().entrySet()) {
                colDefs.add(entry.getKey() + " " + entry.getValue());
            }
            cql.append(String.join(", ", colDefs));
            cql.append(")");
            
            // Execute via CQL
            CQLParser.ParsedQuery parsedQuery = CQLParser.parse(cql.toString());
            QueryExecutor.Result result = queryExecutor.execute(parsedQuery);
            
            if (result.isSuccess()) {
                return SQLResult.success("Table created: " + sql.getKeyspace() + "." + sql.getTable());
            } else {
                return SQLResult.error(result.getMessage());
            }
            
        } catch (Exception e) {
            return SQLResult.error("CREATE TABLE error: " + e.getMessage());
        }
    }
    
    /**
     * Execute DROP TABLE statement
     */
    private SQLResult executeDropTable(SQLParser.ParsedSQL sql) {
        return SQLResult.error("DROP TABLE not yet implemented");
    }
    
    /**
     * Execute DESCRIBE statement
     */
    private SQLResult executeDescribe(SQLParser.ParsedSQL sql) {
        return SQLResult.error("DESCRIBE not yet implemented");
    }
    
    /**
     * Execute SHOW TABLES statement
     */
    private SQLResult executeShowTables() {
        return SQLResult.error("SHOW TABLES not yet implemented");
    }
    
    /**
     * Convert CQL rows to SQL result format
     */
    private List<Map<String, String>> convertRows(List<Map<String, byte[]>> cqlRows) {
        List<Map<String, String>> sqlRows = new ArrayList<>();
        
        for (Map<String, byte[]> cqlRow : cqlRows) {
            Map<String, String> sqlRow = new LinkedHashMap<>();
            for (Map.Entry<String, byte[]> entry : cqlRow.entrySet()) {
                if (entry.getValue() != null) {
                    sqlRow.put(entry.getKey(), new String(entry.getValue()));
                } else {
                    sqlRow.put(entry.getKey(), null);
                }
            }
            sqlRows.add(sqlRow);
        }
        
        return sqlRows;
    }
}