This is an automated email from the ASF dual-hosted git repository. aradzinski pushed a commit to branch NLPCRAFT-13 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
The following commit(s) were added to refs/heads/NLPCRAFT-13 by this push: new 8124404 WIP. 8124404 is described below commit 8124404b20799e33bd970f55868d0f90ffb34220 Author: Aaron Radzinzski <aradzin...@datalingvo.com> AuthorDate: Sun Mar 22 15:54:50 2020 -0700 WIP. --- .../scala/org/apache/nlpcraft/model/NCToken.java | 26 +++++ .../model/tools/sqlgen/NCSqlExtractor.java | 107 ++++++++++++++++++ ...hemaBuilder.java => NCSqlExtractorBuilder.java} | 28 +++-- .../model/tools/sqlgen/NCSqlExtractors.java | 71 ------------ .../model/tools/sqlgen/NCSqlSchemaBuilder.java | 9 +- ...tractorsImpl.scala => NCSqlExtractorImpl.scala} | 119 ++++++++++++++++++--- 6 files changed, 256 insertions(+), 104 deletions(-) diff --git a/src/main/scala/org/apache/nlpcraft/model/NCToken.java b/src/main/scala/org/apache/nlpcraft/model/NCToken.java index cb18e8a..9b59723 100644 --- a/src/main/scala/org/apache/nlpcraft/model/NCToken.java +++ b/src/main/scala/org/apache/nlpcraft/model/NCToken.java @@ -161,6 +161,19 @@ public interface NCToken extends NCMetadata { List<String> getAliases(); /** + * Tests whether or not this token has given alias. It is equivalent to: + * <pre class="brush: java"> + * return getAliases().contains(alias); + * </pre> + * + * @param alias Alias to test. + * @return <code>True</code> if this token has alias <code>alias</code>, {@code false} otherwise. + */ + default boolean isOfAlias(String alias) { + return getAliases().contains(alias); + } + + /** * Gets the value if this token was detected via element's value (or its synonyms). Otherwise * returns {@code null}. Only applicable for user-defined model elements (built-in tokens * do not have values). @@ -180,6 +193,19 @@ public interface NCToken extends NCMetadata { List<String> getGroups(); /** + * Tests whether or not this token belongs to the given group. It is equivalent to: + * <pre class="brush: java"> + * return getGroups().contains(grp); + * </pre> + * + * @param grp Group to test. + * @return <code>True</code> if this token belongs to the group <code>grp</code>, {@code false} otherwise. + */ + default boolean isOfGroup(String grp) { + return getGroups().contains(grp); + } + + /** * Gets start character index of this token in the original text. * * @return Start character index of this token. diff --git a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java new file mode 100644 index 0000000..fa1eb07 --- /dev/null +++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractor.java @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +package org.apache.nlpcraft.model.tools.sqlgen; + +import org.apache.nlpcraft.model.*; +import java.util.*; + +/** + * Utility methods for extracting various SQL components from {@link NCToken} tokens. Instances + * of this interface are created using {@link NCSqlExtractorBuilder} builder. + * + * @see NCSqlExtractorBuilder + */ +public interface NCSqlExtractor { + /** + * Extracts limit object from the token. + * + * @param limitTok Limit token with ID <code>nlpcraft:limit</code>. + * @return SQL limit object extracted from given token. + * @throws NCSqlException Thrown in case of any errors. + */ + NCSqlLimit extractLimit(NCToken limitTok); + + /** + * Extracts date range conditions object from given tokens. + * + * @param colTok Token representing detected SQL column (i.e. detected model element that belongs + * to <code>column</code> group). + * @param dateTok Date range token with ID <code>nlpcraft:date</code>. + * @return List of date range conditions extracted from given parameters. + * @throws NCSqlException Thrown in case of any errors. + */ + List<NCSqlSimpleCondition> extractDateRangeConditions(NCToken colTok, NCToken dateTok); + + /** + * + * @param colTok + * @param numTok + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + List<NCSqlSimpleCondition> extractNumConditions(NCToken colTok, NCToken numTok); + + /** + * + * @param valToks + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + List<NCSqlInCondition> extractInConditions(NCToken... valToks); + + /** + * + * @param sortTok + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + NCSqlSort extractSort(NCToken sortTok); + + /** + * + * @param aggrFunTok + * @param aggrGrpTok + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + NCSqlAggregate extractAggregate(NCToken aggrFunTok, NCToken aggrGrpTok); + + /** + * + * @param tblTok + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + NCSqlTable extractTable(NCToken tblTok); + + /** + * + * @param colTok + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + NCSqlColumn extractColumn(NCToken colTok); + + /** + * + * @param dateTok + * @return + * @throws NCSqlException Thrown in case of any errors. + */ + NCSqlDateRange extractDateRange(NCToken dateTok); +} diff --git a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractorBuilder.java similarity index 52% copy from src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java copy to src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractorBuilder.java index 15ccd01..67e3a8f 100644 --- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java +++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractorBuilder.java @@ -17,27 +17,25 @@ package org.apache.nlpcraft.model.tools.sqlgen; -import org.apache.nlpcraft.model.NCModel; -import org.apache.nlpcraft.model.tools.sqlgen.impl.NCSqlExtractorsImpl; +import org.apache.nlpcraft.model.*; +import org.apache.nlpcraft.model.tools.sqlgen.impl.*; /** - * Builds object presentation of SQL schema for given data model. Data model must be - * generated by {@link NCSqlModelGenerator} class. + * Builder for {@link NCSqlExtractor} instances. * * @see NCSqlModelGenerator - * @see NCSqlExtractors + * @see NCSqlExtractor */ -public class NCSqlSchemaBuilder { +public class NCSqlExtractorBuilder { /** - * Builds object presentation for SQL schema from given data model. - * - * @param model Data model to generate object SQL schema presentation. Note that the model must be - * generated by {@link NCSqlModelGenerator} class. - * @return Object presentation of the SQL schema for a given data model. - * @throws NCSqlException Thrown in case of any errors. - * @see NCSqlModelGenerator + * Builds and returns new SQL extractor for given SQL schema and parsing variant. + * + * @param schema SQL schema object to create an extractor for. + * @param variant Parsing variant (i.e. list of all tokens) to act as a context for + * the extraction wherever necessary. + * @return Newly created SQL extractor. */ - public static NCSqlSchema makeSchema(NCModel model) { - return NCSqlExtractorsImpl.makeSchema(model); + public static NCSqlExtractor build(NCSqlSchema schema, NCVariant variant) { + return new NCSqlExtractorImpl(schema, variant); } } diff --git a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractors.java b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractors.java deleted file mode 100644 index f085c8b..0000000 --- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlExtractors.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -package org.apache.nlpcraft.model.tools.sqlgen; - -import org.apache.nlpcraft.model.*; -import org.apache.nlpcraft.model.tools.sqlgen.impl.*; -import java.util.*; - -/** - * Utility method for extracting SQL components from {@link NCToken} tokens. - */ -public class NCSqlExtractors { - /** - * Extracts limit object from given parameters. - * - * @param schema SQL schema. - * @param variant Parsing variant. - * @param limitTok Limit token with ID <code>nlpcraft:limit</code>. - * @return SQL limit object extracted from given parsing variant and limit token. - */ - public static NCSqlLimit extractLimit(NCSqlSchema schema, NCVariant variant, NCToken limitTok) { - return NCSqlExtractorsImpl.extractLimit(schema, variant, limitTok); - } - - public static List<NCSqlSimpleCondition> extractDateRangeConditions(NCSqlSchema schema, NCToken colTok, NCToken dateTok) { - return NCSqlExtractorsImpl.extractDateRangeConditions(schema, colTok, dateTok); - } - - public static List<NCSqlSimpleCondition> extractNumConditions(NCSqlSchema schema, NCToken colTok, NCToken numTok) { - return NCSqlExtractorsImpl.extractNumConditions(schema, colTok, numTok); - } - - public static List<NCSqlInCondition> extractValuesConditions(NCSqlSchema schema, NCToken... allValsToks) { - return NCSqlExtractorsImpl.extractValuesConditions(schema, allValsToks); - } - - public static NCSqlSort extractSorts(NCSqlSchema schema, NCVariant variant, NCToken sortTok) { - return NCSqlExtractorsImpl.extractSorts(schema, variant, sortTok); - } - - public static NCSqlAggregate extractAggregate(NCSqlSchema schema, NCVariant variant, NCToken aggrFunc, NCToken aggrGroupOpt) { - return NCSqlExtractorsImpl.extractAggregate(schema, variant, aggrFunc, aggrGroupOpt); - } - - public static NCSqlTable extractTable(NCSqlSchema schema, NCToken tok) { - return NCSqlExtractorsImpl.extractTable(schema, tok); - } - - public static NCSqlColumn extractColumn(NCSqlSchema schema, NCToken tok) { - return NCSqlExtractorsImpl.extractColumn(schema, tok); - } - - public static NCSqlDateRange extractDateRange(NCToken tok) { - return NCSqlExtractorsImpl.extractDateRange(tok); - } -} diff --git a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java index 15ccd01..a238286 100644 --- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java +++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/NCSqlSchemaBuilder.java @@ -18,14 +18,13 @@ package org.apache.nlpcraft.model.tools.sqlgen; import org.apache.nlpcraft.model.NCModel; -import org.apache.nlpcraft.model.tools.sqlgen.impl.NCSqlExtractorsImpl; +import org.apache.nlpcraft.model.tools.sqlgen.impl.NCSqlExtractorImpl; /** - * Builds object presentation of SQL schema for given data model. Data model must be - * generated by {@link NCSqlModelGenerator} class. + * Builder for {@link NCSqlSchema} instances. * * @see NCSqlModelGenerator - * @see NCSqlExtractors + * @see NCSqlExtractor */ public class NCSqlSchemaBuilder { /** @@ -38,6 +37,6 @@ public class NCSqlSchemaBuilder { * @see NCSqlModelGenerator */ public static NCSqlSchema makeSchema(NCModel model) { - return NCSqlExtractorsImpl.makeSchema(model); + return NCSqlExtractorImpl.makeSchema(model); } } diff --git a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorsImpl.scala b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala similarity index 85% rename from src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorsImpl.scala rename to src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala index 1430a0f..9a340c9 100644 --- a/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorsImpl.scala +++ b/src/main/scala/org/apache/nlpcraft/model/tools/sqlgen/impl/NCSqlExtractorImpl.scala @@ -25,14 +25,92 @@ import org.apache.nlpcraft.model.{NCModel, NCToken, NCVariant} import scala.collection.JavaConverters._ -object NCSqlExtractorsImpl { - private def extractSqlColumn(schema: NCSqlSchema, colTok: NCToken): NCSqlColumn = { - val tab: String = colTok.meta("sql:tablename") +/** + * + */ +class NCSqlExtractorImpl(schema: NCSqlSchema, variant: NCVariant) extends NCSqlExtractor { + require(schema != null) + require(variant != null) + + /** + * + * @param tok + * @param id + */ + private def checkTokenId(tok: NCToken, id: String): Unit = + if (tok.getId != id) + throw new NCSqlException(s"Expected token ID '$id' but got: $tok") + + /** + * + * @param tok + * @param grp + */ + private def checkGroup(tok: NCToken, grp: String): Unit = + if (!tok.isOfGroup(grp)) + throw new NCSqlException(s"Token does not belong to the group '$grp': $tok") + + /** + * + * @param name + * @return + */ + private def findSchemaTable(name: String): NCSqlTable = + schema.getTables.asScala.find(_.getTable == name).getOrElse(throw new NCSqlException(s"Table not found: $name")) + + /** + * + * @param cols + * @param tbl + * @param col + * @return + */ + private def findSchemaColumn(cols: util.List[NCSqlColumn], tbl: String, col: String): NCSqlColumn = + cols.asScala.find(_.getColumn == col).getOrElse(throw new NCSqlException(s"Column not found: $tbl.$col")) + + override def extractLimit(limitTok: NCToken) = ??? + + override def extractDateRangeConditions(colTok: NCToken, dateTok: NCToken) = ??? + + override def extractNumConditions(colTok: NCToken, numTok: NCToken) = ??? + + override def extractInConditions(valToks: NCToken*) = ??? + + override def extractSort(sortTok: NCToken) = ??? + + override def extractAggregate(aggrFunTok: NCToken, aggrGrpTok: NCToken) = ??? + + override def extractTable(tblTok: NCToken): NCSqlTable = { + checkGroup(tblTok, "table") + + findSchemaTable(tblTok.meta("sql:name")) + } + + override def extractColumn(colTok: NCToken): NCSqlColumn = { + checkGroup(colTok, "column") + + val tbl: String = colTok.meta("sql:tablename") val col: String = colTok.meta("sql:name") - - findSchemaColumn(findSchemaTable(schema, tab).getColumns, tab, col) + + findSchemaColumn(findSchemaTable(tbl).getColumns, tbl, col) } - + + + + + + + + + + + + /** + * + * @param variant + * @param tok + * @return + */ private def getLinkBySingleIndex(variant: Seq[NCToken], tok: NCToken): NCToken = { val idxs: util.List[Integer] = tok.meta(s"${tok.getId}:indexes") @@ -52,11 +130,6 @@ object NCSqlExtractorsImpl { throw new NCSqlException(s"Token not found with index: $idx") } - private def findSchemaTable(schema: NCSqlSchema, name: String): NCSqlTable = - schema.getTables.asScala.find(_.getTable == name).getOrElse(throw new NCSqlException(s"Table not found: $name")) - - private def findSchemaColumn(cols: util.List[NCSqlColumn], tab: String, col: String): NCSqlColumn = - cols.asScala.find(_.getColumn == col).getOrElse(throw new NCSqlException(s"Table not found: $tab.$col")) private def getWithGroup(tok: NCToken, group: String): Seq[NCToken] = (Seq(tok) ++ tok.findPartTokens().asScala).flatMap(p ⇒ if (p.getGroups.contains(group)) Some(p) else None) @@ -100,8 +173,18 @@ object NCSqlExtractorsImpl { def findAnyColumnToken(tok: NCToken): NCToken = findAnyColumnTokenOpt(tok).getOrElse(throw new NCSqlException(s"No columns found for token: $tok")) - + + + /** + * + * @param schema + * @param variant + * @param limitTok + * @return + */ def extractLimit(schema: NCSqlSchema, variant: NCVariant, limitTok: NCToken): NCSqlLimit = { + checkTokenId(limitTok, "nlpcraft:limit") + // Skips indexes to simplify. val limit: Double = limitTok.meta("nlpcraft:limit:limit") @@ -111,8 +194,18 @@ object NCSqlExtractorsImpl { limitTok.meta("nlpcraft:limit:asc") ) } - + + /** + * + * @param schema + * @param colTok + * @param dateTok + * @return + */ def extractDateRangeConditions(schema: NCSqlSchema, colTok: NCToken, dateTok: NCToken): util.List[NCSqlSimpleCondition] = { + checkTokenId(dateTok, "nlpcraft:date") + checkGroup(colTok, "column") + val col = extractSqlColumn(schema, colTok) val range = extractDateRange(dateTok)