aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTschaen, Brendan <ctschaen@att.com>2019-04-18 11:08:14 -0400
committerTschaen, Brendan <ctschaen@att.com>2019-04-18 11:31:57 -0400
commit601050a535e916c0ff52826fbe2c61b798c74530 (patch)
tree137402ea91c92dcc9b41d5b431ca797c50dc621b
parenteff522e4e38b11432f518d1b43fda01d8d387ca4 (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>
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/MDBCUtils.java3
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/MdbcConnection.java7
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/mixins/MySQLMixin.java25
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/query/Operation.java37
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/query/QueryProcessor.java205
-rw-r--r--mdbc-server/src/main/java/org/onap/music/mdbc/query/SQLOperation.java33
-rwxr-xr-xmdbc-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-xmdbc-server/src/main/java/org/onap/music/mdbc/tables/Operation.java9
-rwxr-xr-xmdbc-server/src/main/java/org/onap/music/mdbc/tables/StagingTable.java14
-rwxr-xr-xmdbc-server/src/test/java/org/onap/music/mdbc/MDBCUtilsTest.java8
-rw-r--r--mdbc-server/src/test/java/org/onap/music/mdbc/query/QueryProcessorTest.java97
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));
+ }
}