package com.flipkart.foxtrot.sql; import com.fasterxml.jackson.databind.ObjectMapper; import com.flipkart.foxtrot.common.ActionResponse; import com.flipkart.foxtrot.common.Table; import com.flipkart.foxtrot.common.TableFieldMapping; import com.flipkart.foxtrot.core.querystore.QueryExecutor; import com.flipkart.foxtrot.core.querystore.QueryStore; import com.flipkart.foxtrot.core.table.TableMetadataManager; import com.flipkart.foxtrot.sql.query.FqlActionQuery; import com.flipkart.foxtrot.sql.query.FqlDescribeTable; import com.flipkart.foxtrot.sql.query.FqlShowTablesQuery; import com.flipkart.foxtrot.sql.responseprocessors.Flattener; import com.flipkart.foxtrot.sql.responseprocessors.FlatteningUtils; import com.flipkart.foxtrot.sql.responseprocessors.model.FlatRepresentation; import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; public class FqlEngine { private static final Logger logger = LoggerFactory.getLogger(FqlEngine.class.getSimpleName()); private TableMetadataManager tableMetadataManager; private QueryStore queryStore; private QueryExecutor queryExecutor; private ObjectMapper mapper; public FqlEngine(TableMetadataManager tableMetadataManager, QueryStore queryStore, QueryExecutor queryExecutor, ObjectMapper mapper) { this.tableMetadataManager = tableMetadataManager; this.queryStore = queryStore; this.queryExecutor = queryExecutor; this.mapper = mapper; } public FlatRepresentation parse(final String fql) throws Exception { QueryTranslator translator = new QueryTranslator(); FqlQuery query = translator.translate(fql); FlatRepresentation response = new QueryProcessor(tableMetadataManager, queryStore, queryExecutor, mapper).process(query); logger.debug("Flat Response: " + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(response)); return response; } private static final class QueryProcessor implements FqlQueryVisitor { private TableMetadataManager tableMetadataManager; private QueryStore queryStore; private QueryExecutor queryExecutor; private ObjectMapper mapper; private FlatRepresentation result; private QueryProcessor(TableMetadataManager tableMetadataManager, QueryStore queryStore, QueryExecutor queryExecutor, ObjectMapper mapper) { this.tableMetadataManager = tableMetadataManager; this.queryStore = queryStore; this.queryExecutor = queryExecutor; this.mapper = mapper; } public FlatRepresentation process(FqlQuery query) throws Exception { query.receive(this); return result; } @Override public void visit(FqlDescribeTable fqlDescribeTable) throws Exception { TableFieldMapping fieldMetaData = queryStore.getFieldMappings(fqlDescribeTable.getTableName()); result = FlatteningUtils.genericMultiRowParse( mapper.valueToTree(fieldMetaData.getMappings()), Lists.newArrayList("field", "type"), "field"); } @Override public void visit(FqlShowTablesQuery fqlShowTablesQuery) throws Exception { List<Table> tables = tableMetadataManager.get(); result = FlatteningUtils.genericMultiRowParse( mapper.valueToTree(tables), Lists.newArrayList("name", "ttl"), "name"); } @Override public void visit(FqlActionQuery fqlActionQuery) throws Exception { logger.info("Generated query: " + mapper.writeValueAsString(fqlActionQuery.getActionRequest())); ActionResponse actionResponse = queryExecutor.execute(fqlActionQuery.getActionRequest()); Flattener flattener = new Flattener(mapper, fqlActionQuery.getActionRequest(), fqlActionQuery.getSelectedFields()); actionResponse.accept(flattener); result = flattener.getFlatRepresentation(); } } }