diff options
author | Tschaen, Brendan <ctschaen@att.com> | 2019-04-18 11:08:14 -0400 |
---|---|---|
committer | Tschaen, Brendan <ctschaen@att.com> | 2019-04-18 11:31:57 -0400 |
commit | 601050a535e916c0ff52826fbe2c61b798c74530 (patch) | |
tree | 137402ea91c92dcc9b41d5b431ca797c50dc621b /mdbc-server | |
parent | eff522e4e38b11432f518d1b43fda01d8d387ca4 (diff) |
Switch to calcite query parser
Handle SQL Joins
Return Schema/DB and table as range
Change-Id: I9455da1e9118bc547bf28e5f22cce2cf044ce75a
Issue-ID: MUSIC-380
Signed-off-by: Tschaen, Brendan <ctschaen@att.com>
Diffstat (limited to 'mdbc-server')
-rwxr-xr-x | mdbc-server/src/main/java/org/onap/music/mdbc/MDBCUtils.java | 3 | ||||
-rwxr-xr-x | mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java | 7 | ||||
-rwxr-xr-x | mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java | 25 | ||||
-rw-r--r-- | mdbc-server/src/main/java/org/onap/music/mdbc/query/Operation.java | 37 | ||||
-rw-r--r-- | mdbc-server/src/main/java/org/onap/music/mdbc/query/QueryProcessor.java | 205 | ||||
-rw-r--r-- | mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperation.java | 33 | ||||
-rwxr-xr-x | mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperationType.java (renamed from mdbc-server/src/main/java/org/onap/music/mdbc/tables/OperationType.java) | 6 | ||||
-rwxr-xr-x | mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java | 9 | ||||
-rwxr-xr-x | mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java | 14 | ||||
-rwxr-xr-x | mdbc-server/src/test/java/org/onap/music/mdbc/MDBCUtilsTest.java | 8 | ||||
-rw-r--r-- | mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java | 97 |
11 files changed, 215 insertions, 229 deletions
diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/MDBCUtils.java b/mdbc-server/src/main/java/org/onap/music/mdbc/MDBCUtils.java index ae115bf..32d456e 100755 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/MDBCUtils.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/MDBCUtils.java @@ -37,6 +37,7 @@ import org.onap.music.logging.format.ErrorSeverity; import org.onap.music.logging.format.ErrorTypes; import org.onap.music.mdbc.mixins.MusicMixin; import org.onap.music.mdbc.mixins.Utils; +import org.onap.music.mdbc.query.SQLOperation; import org.onap.music.mdbc.tables.Operation; import org.onap.music.mdbc.tables.StagingTable; @@ -96,7 +97,7 @@ public class MDBCUtils { return prop; } - public static List<Range> getTables(Map<String,List<String>> queryParsed){ + public static List<Range> getTables(Map<String,List<SQLOperation>> queryParsed){ List<Range> ranges = new ArrayList<>(); for(String table: queryParsed.keySet()){ ranges.add(new Range(table)); diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java index 02b5415..3db6c3f 100755 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java @@ -53,6 +53,7 @@ import org.onap.music.mdbc.ownership.Dag; import org.onap.music.mdbc.ownership.DagNode; import org.onap.music.mdbc.ownership.OwnershipAndCheckpoint; import org.onap.music.mdbc.query.QueryProcessor; +import org.onap.music.mdbc.query.SQLOperation; import org.onap.music.mdbc.tables.MusicTxDigestDaemon; import org.onap.music.mdbc.tables.MusicRangeInformationRow; import org.onap.music.mdbc.tables.StagingTable; @@ -501,13 +502,13 @@ public class MdbcConnection implements Connection { * can be synchronized before a SELECT, for those databases that do not support SELECT triggers. * @param sql the SQL statement that is about to be executed */ - public void preStatementHook(final String sql) throws MDBCServiceException { + public void preStatementHook(final String sql) throws MDBCServiceException, SQLException { //TODO: verify ownership of keys here //Parse tables from the sql query - Map<String, List<String>> tableToInstruction = QueryProcessor.extractTableFromQuery(sql); + Map<String, List<SQLOperation>> tableToInstruction = QueryProcessor.parseSqlQuery(sql); //Check ownership of keys List<Range> queryTables = MDBCUtils.getTables(tableToInstruction); - if(this.partition!=null ){ + if (this.partition!=null) { List<Range> snapshot = this.partition.getSnapshot(); if(snapshot!=null){ queryTables.addAll(snapshot); diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java index 338839a..6d6e691 100755 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java @@ -43,8 +43,9 @@ import org.onap.music.logging.EELFLoggerDelegate; import org.onap.music.mdbc.MDBCUtils; import org.onap.music.mdbc.Range; import org.onap.music.mdbc.TableInfo; +import org.onap.music.mdbc.query.SQLOperation; +import org.onap.music.mdbc.query.SQLOperationType; import org.onap.music.mdbc.tables.Operation; -import org.onap.music.mdbc.tables.OperationType; import org.onap.music.mdbc.tables.StagingTable; import net.sf.jsqlparser.JSQLParserException; @@ -578,16 +579,16 @@ NEW.field refers to the new value } } - private OperationType toOpEnum(String operation) throws NoSuchFieldException { + private SQLOperation toOpEnum(String operation) throws NoSuchFieldException { switch (operation.toLowerCase()) { case "i": - return OperationType.INSERT; + return SQLOperation.INSERT; case "d": - return OperationType.DELETE; + return SQLOperation.DELETE; case "u": - return OperationType.UPDATE; + return SQLOperation.UPDATE; case "s": - return OperationType.SELECT; + return SQLOperation.SELECT; default: logger.error(EELFLoggerDelegate.errorLogger,"Invalid operation selected: ["+operation+"]"); throw new NoSuchFieldException("Invalid operation enum"); @@ -614,7 +615,7 @@ NEW.field refers to the new value biggestIx = Integer.max(biggestIx,ix); smallestIx = Integer.min(smallestIx,ix); String op = rs.getString("OP"); - OperationType opType = toOpEnum(op); + SQLOperation opType = toOpEnum(op); String tbl = rs.getString("TABLENAME"); String newRowStr = rs.getString("ROWDATA"); String rowStr = rs.getString("KEYDATA"); @@ -951,10 +952,10 @@ NEW.field refers to the new value StringBuilder sqlInverse = null; switch (op.getOperationType()) { case INSERT: - sqlInverse = constructUpdate(op.getTable() , OperationType.UPDATE, op.getKey(), cols, vals); + sqlInverse = constructUpdate(op.getTable() , SQLOperation.UPDATE, op.getKey(), cols, vals); break; case UPDATE: - sqlInverse = constructInsert(op.getTable() , OperationType.INSERT, cols, vals); + sqlInverse = constructInsert(op.getTable() , SQLOperation.INSERT, cols, vals); break; default: break; @@ -982,7 +983,7 @@ NEW.field refers to the new value } return sql; } - private StringBuilder constructDelete(String r, OperationType op, JSONObject key) { + private StringBuilder constructDelete(String r, SQLOperation op, JSONObject key) { StringBuilder sql = new StringBuilder(); sql.append(op + " FROM "); sql.append(r + " WHERE "); @@ -990,7 +991,7 @@ NEW.field refers to the new value sql.append(";"); return sql; } - private StringBuilder constructInsert(String r, OperationType op, ArrayList<String> cols, + private StringBuilder constructInsert(String r, SQLOperation op, ArrayList<String> cols, ArrayList<Object> vals) { StringBuilder sql = new StringBuilder(); String sep; @@ -1010,7 +1011,7 @@ NEW.field refers to the new value sql.append(");"); return sql; } - private StringBuilder constructUpdate(String r, OperationType op, JSONObject key, ArrayList<String> cols, + private StringBuilder constructUpdate(String r, SQLOperation op, JSONObject key, ArrayList<String> cols, ArrayList<Object> vals) { StringBuilder sql = new StringBuilder(); String sep; diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/query/Operation.java b/mdbc-server/src/main/java/org/onap/music/mdbc/query/Operation.java deleted file mode 100644 index 6c2d52b..0000000 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/query/Operation.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * ============LICENSE_START==================================================== - * org.onap.music.mdbc - * ============================================================================= - * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved. - * ============================================================================= - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END====================================================== - */ - -package org.onap.music.mdbc.query; - -public enum Operation { - - INSERT("W"), SELECT("R"), UPDATE("W"), DELETE("W"), TABLE("T"); - - String operation; - - String getOperation() { - return this.operation; - } - - Operation(String operation) { - this.operation = operation; - } - - }
\ No newline at end of file diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/query/QueryProcessor.java b/mdbc-server/src/main/java/org/onap/music/mdbc/query/QueryProcessor.java index 4134540..fc41cf6 100644 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/query/QueryProcessor.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/query/QueryProcessor.java @@ -20,6 +20,7 @@ package org.onap.music.mdbc.query; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -27,11 +28,13 @@ import java.util.Map; import org.apache.calcite.avatica.util.Casing; import org.apache.calcite.avatica.util.Quoting; +import org.apache.calcite.sql.SqlBasicCall; import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlIdentifier; import org.apache.calcite.sql.SqlInsert; +import org.apache.calcite.sql.SqlJoin; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlNode; -import org.apache.calcite.sql.SqlNodeList; import org.apache.calcite.sql.SqlSelect; import org.apache.calcite.sql.SqlUpdate; import org.apache.calcite.sql.fun.SqlInOperator; @@ -45,21 +48,10 @@ import org.apache.calcite.sql.validate.SqlConformanceEnum; import org.apache.calcite.util.Util; import org.onap.music.logging.EELFLoggerDelegate; -import net.sf.jsqlparser.JSQLParserException; -import net.sf.jsqlparser.parser.CCJSqlParserUtil; -import net.sf.jsqlparser.statement.delete.Delete; -import net.sf.jsqlparser.statement.insert.Insert; -import net.sf.jsqlparser.statement.select.Select; -import net.sf.jsqlparser.statement.update.Update; -import net.sf.jsqlparser.statement.create.table.CreateTable; -import net.sf.jsqlparser.util.TablesNamesFinder; - public class QueryProcessor { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(QueryProcessor.class); - public List<String> tables = null; - public QueryProcessor() { } @@ -81,21 +73,29 @@ public class QueryProcessor { /** * * @param query - * @return map of table name to {@link org.onap.music.mdbc.query.Operation} + * @return map of table name to {@link org.onap.music.mdbc.query.SQLOperation} * @throws SqlParseException */ - public static Map<String, List<Operation>> parseSqlQuery(String query) throws SqlParseException { + public static Map<String, List<SQLOperation>> parseSqlQuery(String query) throws SQLException { logger.info(EELFLoggerDelegate.applicationLogger, "Parsing query: "+query); - Map<String, List<Operation>> tableOpsMap = new HashMap<>(); + query = query.trim(); + if (query.endsWith(";")) { + query = query.substring(0, query.length() - 1); + } + Map<String, List<SQLOperation>> tableOpsMap = new HashMap<>(); //for Create no need to check locks. if(query.toUpperCase().startsWith("CREATE")) { logger.error(EELFLoggerDelegate.errorLogger, "CREATE TABLE DDL not currently supported currently."); return tableOpsMap; } - /*SqlParser parser = SqlParser.create(query); - SqlNode sqlNode = parser.parseQuery();*/ - SqlNode sqlNode = getSqlParser(query).parseStmt(); + SqlNode sqlNode; + try { + sqlNode = getSqlParser(query).parseStmt(); + } catch (SqlParseException e) { + logger.error(EELFLoggerDelegate.errorLogger, "Unable to parse query: " + query +". " + e.getMessage()); + throw new SQLException("Unable to parse query: " + query); + } SqlBasicVisitor<Void> visitor = new SqlBasicVisitor<Void>() { @@ -108,7 +108,6 @@ public class QueryProcessor { }; - // sqlNode.accept(new SqlAnalyzer()); sqlNode.accept(visitor); switch (sqlNode.getKind()) { case INSERT: @@ -126,123 +125,89 @@ public class QueryProcessor { return tableOpsMap; } - private static void parseInsert(SqlInsert sqlNode, Map<String, List<Operation>> tableOpsMap) { - SqlInsert sqlInsert = (SqlInsert) sqlNode; + private static void parseInsert(SqlInsert sqlInsert, Map<String, List<SQLOperation>> tableOpsMap) { String tableName = sqlInsert.getTargetTable().toString(); //handle insert into select query if (sqlInsert.getSource().getKind()==SqlKind.SELECT) { parseSelect((SqlSelect) sqlInsert.getSource(), tableOpsMap); } - List<Operation> Ops = tableOpsMap.get(tableName); + List<SQLOperation> Ops = tableOpsMap.get(tableName); if (Ops == null) Ops = new ArrayList<>(); - Ops.add(Operation.INSERT); + Ops.add(SQLOperation.INSERT); tableOpsMap.put(tableName, Ops); } - private static void parseUpdate(SqlUpdate sqlNode, Map<String, List<Operation>> tableOpsMap) { - SqlUpdate sqlUpdate = (SqlUpdate) sqlNode; - String tableName = sqlUpdate.getTargetTable().toString(); - List<Operation> Ops = tableOpsMap.get(tableName); - if (Ops == null) - Ops = new ArrayList<>(); - Ops.add(Operation.UPDATE); - tableOpsMap.put(tableName, Ops); + private static void parseUpdate(SqlUpdate sqlUpdate, Map<String, List<SQLOperation>> tableOpsMap) { + SqlNode targetTable = sqlUpdate.getTargetTable(); + switch (targetTable.getKind()) { + case IDENTIFIER: + addIdentifierToMap(tableOpsMap, (SqlIdentifier) targetTable, SQLOperation.UPDATE); + break; + default: + logger.error("Unable to process: " + targetTable.getKind() + " query"); + } } - private static void parseSelect(SqlSelect sqlNode, Map<String, List<Operation>> tableOpsMap ) { - SqlSelect sqlSelect = (SqlSelect) sqlNode; - SqlNodeList selectList = sqlSelect.getSelectList(); - String tables = sqlSelect.getFrom().toString(); - String[] tablesArr = tables.split(","); - - for (String table : tablesArr) { - - String tableName = null; - if(table.contains("`")) { - String[] split = table.split("`"); - tableName = split[1]; - } else { - tableName = table; - } - List<Operation> Ops = tableOpsMap.get(tableName); - if (Ops == null) Ops = new ArrayList<>(); - Ops.add(Operation.SELECT); - tableOpsMap.put(tableName, Ops); + private static void parseSelect(SqlSelect sqlSelect, Map<String, List<SQLOperation>> tableOpsMap ) { + SqlNode from = sqlSelect.getFrom(); + switch (from.getKind()) { + case IDENTIFIER: + addIdentifierToMap(tableOpsMap, (SqlIdentifier) from, SQLOperation.SELECT); + break; + case AS: + SqlBasicCall as = (SqlBasicCall) from; + SqlNode node = as.getOperandList().get(0); + addIdentifierToMap(tableOpsMap, (SqlIdentifier) node, SQLOperation.SELECT); + break; + case JOIN: + parseJoin((SqlJoin) from, tableOpsMap); + break; + default: + logger.error("Unable to process: " + from.getKind() + " query"); } } - @Deprecated - public static Map<String, List<String>> extractTableFromQuery(String sqlQuery) { - List<String> tables = null; - Map<String, List<String>> tableOpsMap = new HashMap<>(); - try { - net.sf.jsqlparser.statement.Statement stmt = CCJSqlParserUtil.parse(sqlQuery); - if (stmt instanceof Insert) { - Insert s = (Insert) stmt; - String tbl = s.getTable().getName(); - List<String> Ops = tableOpsMap.get(tbl); - if (Ops == null) - Ops = new ArrayList<>(); - Ops.add(Operation.INSERT.getOperation()); - tableOpsMap.put(tbl, Ops); - logger.debug(EELFLoggerDelegate.applicationLogger, "Inserting into table: " + tbl); - } else { - String tbl; - String where = ""; - if (stmt instanceof Update) { - Update u = (Update) stmt; - tbl = u.getTables().get(0).getName(); - List<String> Ops = tableOpsMap.get(tbl); - if (Ops == null) - Ops = new ArrayList<>(); - if (u.getWhere() != null) { - where = u.getWhere().toString(); - logger.debug(EELFLoggerDelegate.applicationLogger, "Updating table: " + tbl); - Ops.add(Operation.UPDATE.getOperation()); - } else { - Ops.add(Operation.TABLE.getOperation()); - } - tableOpsMap.put(tbl, Ops); - } else if (stmt instanceof Delete) { - Delete d = (Delete) stmt; - tbl = d.getTable().getName(); - List<String> Ops = tableOpsMap.get(tbl); - if (Ops == null) - Ops = new ArrayList<>(); - if (d.getWhere() != null) { - where = d.getWhere().toString(); - Ops.add(Operation.DELETE.getOperation()); - } else { - Ops.add(Operation.TABLE.getOperation()); - } - tableOpsMap.put(tbl, Ops); - logger.debug(EELFLoggerDelegate.applicationLogger, "Deleting from table: " + tbl); - } else if (stmt instanceof Select) { - TablesNamesFinder tablesNamesFinder = new TablesNamesFinder(); - tables = tablesNamesFinder.getTableList(stmt); - for (String table : tables) { - List<String> Ops = tableOpsMap.get(table); - if (Ops == null) - Ops = new ArrayList<>(); - Ops.add(Operation.SELECT.getOperation()); - tableOpsMap.put(table, Ops); - } - } else if (stmt instanceof CreateTable) { - CreateTable ct = (CreateTable) stmt; - List<String> Ops = new ArrayList<>(); - Ops.add(Operation.TABLE.getOperation()); - tableOpsMap.put(ct.getTable().getName(), Ops); - } else { - logger.error(EELFLoggerDelegate.errorLogger, "Not recognized sql type:" + stmt.getClass()); - tbl = ""; - } - } - } catch (JSQLParserException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + private static void parseJoin(SqlJoin join, Map<String, List<SQLOperation>> tableOpsMap) { + switch (join.getLeft().getKind()) { + case IDENTIFIER: + addIdentifierToMap(tableOpsMap, (SqlIdentifier) join.getLeft(), SQLOperation.SELECT); + break; + case AS: + SqlBasicCall as = (SqlBasicCall) join.getLeft(); + SqlNode node = as.getOperandList().get(0); + addIdentifierToMap(tableOpsMap, (SqlIdentifier) node, SQLOperation.SELECT); + break; + default: + logger.error("Error parsing join. Can't process left type: " + join.getLeft().getKind()); } - return tableOpsMap; + + switch (join.getRight().getKind()) { + case IDENTIFIER: + addIdentifierToMap(tableOpsMap, (SqlIdentifier) join.getRight(), SQLOperation.SELECT); + break; + case AS: + SqlBasicCall as = (SqlBasicCall) join.getRight(); + SqlNode node = as.getOperandList().get(0); + addIdentifierToMap(tableOpsMap, (SqlIdentifier) node, SQLOperation.SELECT); + break; + default: + logger.error("Error parsing join. Can't process left type: " + join.getRight().getKind()); + } + } + + /** + * Add the identifier, the range in the query, to the map + * @param tableOpsMap + * @param identifier + * @param op + */ + private static void addIdentifierToMap(Map<String, List<SQLOperation>> tableOpsMap, SqlIdentifier identifier, + SQLOperation op) { + List<SQLOperation> opList = tableOpsMap.get(identifier.toString()); + if (opList == null) opList = new ArrayList<>(); + opList.add(op); + tableOpsMap.put(identifier.toString(), opList); } } diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperation.java b/mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperation.java new file mode 100644 index 0000000..f211801 --- /dev/null +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperation.java @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START==================================================== org.onap.music.mdbc + * ============================================================================= Copyright (C) 2018 AT&T Intellectual + * Property. All rights reserved. ============================================================================= Licensed + * under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + * ============LICENSE_END====================================================== + */ + +package org.onap.music.mdbc.query; + +public enum SQLOperation { + + INSERT(SQLOperationType.WRITE), SELECT(SQLOperationType.READ), UPDATE(SQLOperationType.WRITE), + DELETE(SQLOperationType.WRITE), TABLE(SQLOperationType.TABLE); + + SQLOperationType opType; + + public SQLOperationType getOperationType() { + return this.opType; + } + + SQLOperation(SQLOperationType operation) { + this.opType = operation; + } + +} diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/OperationType.java b/mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperationType.java index 696f642..8d8b1b5 100755 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/OperationType.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperationType.java @@ -17,8 +17,8 @@ * limitations under the License. * ============LICENSE_END====================================================== */ -package org.onap.music.mdbc.tables; +package org.onap.music.mdbc.query; -public enum OperationType{ - DELETE, UPDATE, INSERT, SELECT +public enum SQLOperationType { + READ, WRITE, TABLE; } diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java index eda6191..d406ad3 100755 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java @@ -24,19 +24,20 @@ import java.io.Serializable; import org.json.JSONObject; import org.json.JSONTokener; import org.onap.music.exceptions.MDBCServiceException; - +import org.onap.music.mdbc.query.SQLOperation; +import org.onap.music.mdbc.query.SQLOperationType; import static java.util.Objects.hash; public final class Operation implements Serializable{ private static final long serialVersionUID = -1215301985078183104L; - final OperationType TYPE; + final SQLOperation TYPE; final String VAL; final String KEY; final String TABLE; - public Operation(String table,OperationType type, String newVal, String key) { + public Operation(String table, SQLOperation type, String newVal, String key) { TABLE = table; TYPE = type; VAL = newVal; @@ -72,7 +73,7 @@ public final class Operation implements Serializable{ return keys; } - public OperationType getOperationType() { + public SQLOperation getOperationType() { return this.TYPE; } diff --git a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java index 26ee73c..4fdd7ac 100755 --- a/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java +++ b/mdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java @@ -36,6 +36,8 @@ import org.onap.music.mdbc.proto.ProtoDigest.Digest.CompleteDigest; import org.onap.music.mdbc.proto.ProtoDigest.Digest.CompleteDigest.Builder; import org.onap.music.mdbc.proto.ProtoDigest.Digest.Row; import org.onap.music.mdbc.proto.ProtoDigest.Digest.Row.OpType; +import org.onap.music.mdbc.query.SQLOperation; +import org.onap.music.mdbc.query.SQLOperationType; public class StagingTable { @@ -105,8 +107,8 @@ public class StagingTable { } for(Row row : completeDigest.getRowsList()){ final OpType type = row.getType(); - OperationType newType = (type==OpType.INSERT)?OperationType.INSERT:(type==OpType.DELETE)? - OperationType.DELETE:OperationType.UPDATE; + SQLOperation newType = (type==OpType.INSERT)?SQLOperation.INSERT:(type==OpType.DELETE)? + SQLOperation.DELETE:SQLOperation.UPDATE; operations.add(new Operation(row.getTable(),newType,row.getVal(),row.getKey())); } } @@ -176,13 +178,13 @@ public class StagingTable { return isBuilderInitialized(); } - synchronized public void addOperation(Range range, OperationType type, String newVal, String keys) + synchronized public void addOperation(Range range, SQLOperation type, String newVal, String keys) throws MDBCServiceException { if(!builderInitialized){ throw new MDBCServiceException("This type of staging table is unmutable, please use the constructor" + "with no parameters"); } - OpType newType = (type==OperationType.INSERT)?OpType.INSERT:(type==OperationType.DELETE)? + OpType newType = (type==SQLOperation.INSERT)?OpType.INSERT:(type==SQLOperation.DELETE)? OpType.DELETE:OpType.UPDATE; Row.Builder rowBuilder = Row.newBuilder().setTable(range.getTable()).setType(newType).setVal(newVal); if(keys!=null){ @@ -209,8 +211,8 @@ public class StagingTable { ArrayList<Operation> newOperations = new ArrayList<>(); for(Row row : digestBuilder.getRowsList()){ final OpType type = row.getType(); - OperationType newType = (type==OpType.INSERT)?OperationType.INSERT:(type==OpType.DELETE)? - OperationType.DELETE:OperationType.UPDATE; + SQLOperation newType = (type==OpType.INSERT)?SQLOperation.INSERT:(type==OpType.DELETE)? + SQLOperation.DELETE:SQLOperation.UPDATE; newOperations.add(new Operation(row.getTable(),newType,row.getVal(),row.getKey())); } return newOperations; diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/MDBCUtilsTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/MDBCUtilsTest.java index a9cf88a..4703d0e 100755 --- a/mdbc-server/src/test/java/org/onap/music/mdbc/MDBCUtilsTest.java +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/MDBCUtilsTest.java @@ -22,16 +22,12 @@ package org.onap.music.mdbc; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.io.IOException; import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.HashSet; import org.json.JSONObject; -import org.junit.Ignore; import org.junit.Test; import org.onap.music.exceptions.MDBCServiceException; -import org.onap.music.mdbc.tables.OperationType; +import org.onap.music.mdbc.query.SQLOperation; import org.onap.music.mdbc.tables.StagingTable; public class MDBCUtilsTest { @@ -40,7 +36,7 @@ public class MDBCUtilsTest { public void toStringTest1() { StagingTable table = new StagingTable(); try { - table.addOperation(new Range("TABLE1"),OperationType.INSERT,(new JSONObject(new String[]{"test3", "Test4"})).toString(),null); + table.addOperation(new Range("TABLE1"),SQLOperation.INSERT,(new JSONObject(new String[]{"test3", "Test4"})).toString(),null); } catch (MDBCServiceException e) { fail(); } diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java index e39cc95..e76533e 100644 --- a/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java @@ -16,23 +16,20 @@ package org.onap.music.mdbc.query; import static org.junit.Assert.*; -import java.io.IOException; +import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.apache.calcite.sql.parser.SqlParseException; import org.junit.Test; -import org.onap.music.mdbc.tables.MusicTxDigestDaemon; -import org.onap.music.mdbc.tables.StagingTable; public class QueryProcessorTest { @Test - public void tableQuery() throws Exception { + public void tableQuery() throws SQLException { String sqlQuery = "CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20))"; - HashMap<String, List<Operation>> expectedOut = new HashMap<>(); - List<Operation> op = new ArrayList<>(); + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> op = new ArrayList<>(); // no table ops for now // op.add(Operation.TABLE); // expectedOut.put("pet", op); @@ -40,23 +37,33 @@ public class QueryProcessorTest { } @Test - public void selectQuery() throws SqlParseException { - String sqlQuery = "SELECT name, age FROM table1 t1"; - HashMap<String, List<Operation>> expectedOut = new HashMap<>(); - List<Operation> t1op = new ArrayList<>(); - t1op.add(Operation.SELECT); - expectedOut.put("TABLE1", t1op); + public void selectQuery() throws SQLException { + String sqlQuery = "SELECT name, age FROM DB.table1 t1;"; + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + t1op.add(SQLOperation.SELECT); + expectedOut.put("DB.TABLE1", t1op); + assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); + } + + @Test + public void selectQuery1() throws SQLException { + String sqlQuery = "SELECT name, age FROM DB.table1;"; + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + t1op.add(SQLOperation.SELECT); + expectedOut.put("DB.TABLE1", t1op); assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); } @Test - public void selectQuery2Table() throws SqlParseException { + public void selectQuery2Table() throws SQLException { String sqlQuery = "SELECT name, age FROM table1 t1, table2 t2 WHERE t1.id = t2.id"; - HashMap<String, List<Operation>> expectedOut = new HashMap<>(); - List<Operation> t1op = new ArrayList<>(); - List<Operation> t2op = new ArrayList<>(); - t1op.add(Operation.SELECT); - t2op.add(Operation.SELECT); + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + List<SQLOperation> t2op = new ArrayList<>(); + t1op.add(SQLOperation.SELECT); + t2op.add(SQLOperation.SELECT); expectedOut.put("TABLE1", t1op); expectedOut.put("TABLE2", t2op); assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); @@ -66,40 +73,56 @@ public class QueryProcessorTest { } @Test - public void insertQuery() throws SqlParseException { + public void insertQuery() throws SQLException { String sqlQuery = "INSERT INTO Employees (id, name) values ('1','Vikram')"; - HashMap<String, List<Operation>> expectedOut = new HashMap<>(); - List<Operation> t1op = new ArrayList<>(); - t1op.add(Operation.INSERT); + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + t1op.add(SQLOperation.INSERT); expectedOut.put("EMPLOYEES", t1op); assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); } @Test - public void updateQuery() throws SqlParseException { - String sqlQuery = "UPDATE Employees SET id = 1 WHERE id = 2"; - HashMap<String, List<Operation>> expectedOut = new HashMap<>(); - List<Operation> t1op = new ArrayList<>(); - t1op.add(Operation.UPDATE); - expectedOut.put("EMPLOYEES", t1op); + public void updateQuery() throws SQLException { + String sqlQuery = "UPDATE Db.Employees SET id = 1 WHERE id = 2"; + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + t1op.add(SQLOperation.UPDATE); + expectedOut.put("DB.EMPLOYEES", t1op); assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); - sqlQuery = "UPDATE Employees SET id = 1"; + sqlQuery = "UPDATE db.Employees SET id = 1"; assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); } @Test - public void insertSelect() throws SqlParseException { + public void insertSelect() throws SQLException { String sqlQuery = "INSERT INTO table1 (CustomerName, City, Country) SELECT SupplierName, City, Country FROM table2"; - HashMap<String, List<Operation>> expectedOut = new HashMap<>(); - List<Operation> t1op = new ArrayList<>(); - List<Operation> t2op = new ArrayList<>(); - t1op.add(Operation.INSERT); - t2op.add(Operation.SELECT); + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + List<SQLOperation> t2op = new ArrayList<>(); + t1op.add(SQLOperation.INSERT); + t2op.add(SQLOperation.SELECT); expectedOut.put("TABLE1", t1op); expectedOut.put("TABLE2", t2op); assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); } - + + @Test + public void selectJoin() throws SQLException { + String sqlQuery = + "SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate " + + "FROM Orders " + + "INNER JOIN DB.Customers ON Orders.CustomerID=Customers.CustomerID;"; + + HashMap<String, List<SQLOperation>> expectedOut = new HashMap<>(); + List<SQLOperation> t1op = new ArrayList<>(); + List<SQLOperation> t2op = new ArrayList<>(); + t1op.add(SQLOperation.SELECT); + t2op.add(SQLOperation.SELECT); + expectedOut.put("ORDERS", t1op); + expectedOut.put("DB.CUSTOMERS", t2op); + assertEquals(expectedOut, QueryProcessor.parseSqlQuery(sqlQuery)); + } } |