You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nlpcraft.apache.org by se...@apache.org on 2020/05/19 10:39:00 UTC

[incubator-nlpcraft] branch NLPCRAFT-30 updated: SQL model example javadoc and code comment added.

This is an automated email from the ASF dual-hosted git repository.

sergeykamov pushed a commit to branch NLPCRAFT-30
in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git


The following commit(s) were added to refs/heads/NLPCRAFT-30 by this push:
     new afbe804  SQL model example javadoc and code comment added.
afbe804 is described below

commit afbe804f05d55d30c61862234e33339852d66131
Author: Sergey Kamov <se...@apache.org>
AuthorDate: Tue May 19 13:38:48 2020 +0300

    SQL model example javadoc and code comment added.
---
 .../apache/nlpcraft/examples/sql/SqlModel.scala    | 155 ++++++++++--------
 .../nlpcraft/examples/sql/db/SqlAccess.scala       |  22 ++-
 .../apache/nlpcraft/examples/sql/db/SqlBeans.scala |  28 ++--
 .../nlpcraft/examples/sql/db/SqlBuilder.scala      | 175 +++++++++++++++------
 .../nlpcraft/examples/sql/db/SqlServer.scala       |   2 +-
 .../nlpcraft/examples/sql/db/SqlValueLoader.scala  |   3 +-
 .../probe/mgrs/nlp/NCProbeEnrichmentManager.scala  |   2 -
 .../mgrs/nlp/enrichers/NCEnrichersTestBeans.scala  |   3 +-
 8 files changed, 261 insertions(+), 129 deletions(-)

diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala b/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala
index 335945f..3581da1 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/SqlModel.scala
@@ -26,6 +26,14 @@ import org.apache.nlpcraft.model.tools.sqlgen._
 import scala.collection.JavaConverters._
 import scala.language.implicitConversions
 
+/**
+  * SQL model.
+  *
+  * Simple version of SQL access model which supports two intents.
+  * First - generic intent which allows to process set of common questions.
+  * Second - modified version of first intent, which uses implicit sort element definition.
+  * Second is developed as an example of way by which this model can be extended to support more complicated questions comparing to generic case.
+  */
 class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_model.yaml") with LazyLogging {
     private final val GSON = new Gson()
     private final val SCHEMA = NCSqlSchemaBuilder.makeSchema(this)
@@ -33,11 +41,11 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     case class Condition(column: NCToken, condition: NCToken)
     
     /**
+      * Converts SQL execution result to JSON.
       *
-      * @param res
-      * @param sql
-      * @param params
-      * @return
+      * @param res SQL result.
+      * @param sql SQL query.
+      * @param params SQL query parameters.
       */
     private def toJson(res: SqlResult, sql: String, params: Seq[Any]): String = {
         val m = new java.util.HashMap[String, Any]()
@@ -50,11 +58,11 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
 
         GSON.toJson(m)
     }
-    
+
     /**
-      * 
-      * @param error
-      * @return
+      * Converts execution error to JSON.
+      *
+      * @param error Error text.
       */
     private def toJson(error: String): String = {
         val m = new java.util.HashMap[String, Any]()
@@ -65,14 +73,13 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     }
     
     /**
-      * Complex element contains 2 tokens: column + date ot numeric condition.
+      * Prepares condition based on token which contains column definition and condition token ID.
       *
-      * @param t
-      * @param condTokId
-      * @return
+      * @param colWrapperTok Token which contains column.
+      * @param condTokId Condition token ID.
       */
-    private def extractColumnAndCondition(t: NCToken, condTokId: String): Condition = {
-        val parts = t.getPartTokens.asScala
+    private def extractColumnAndCondition(colWrapperTok: NCToken, condTokId: String): Condition = {
+        val parts = colWrapperTok.getPartTokens.asScala
 
         require(parts.size == 2)
 
@@ -85,9 +92,11 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     }
     
     /**
+      * Tries to find column definition for given token. It can be token itself or any part of given token.
+      * Returns empty result if column definition not found.
+      * Throws exception if found many column definitions in its parts.
       *
-      * @param tok
-      * @return
+      * @param tok Token.
       */
     private def findAnyColumnTokenOpt(tok: NCToken): Option[NCToken] = {
         val cols =
@@ -111,11 +120,13 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
         findAnyColumnTokenOpt(tok).getOrElse(throw new RuntimeException(s"No columns found for token: $tok"))
     
     /**
+      * Extracts numeric conditions. It creates conditions based on relations between column and numeric value.
+      * Single value conditions list returned for single relation like 'col > 2', 'col <= 3'.
+      * Double values conditions list returned for range relation like 'col > 2 AND col <= 3'.
       *
-      * @param ext
-      * @param colTok
-      * @param numTok
-      * @return
+      * @param ext SQL extractor.
+      * @param colTok Column token.
+      * @param numTok Numeric token.
       */
     private def extractNumConditions(ext: NCSqlExtractor, colTok: NCToken, numTok: NCToken): Seq[SqlSimpleCondition] = {
         val col = ext.extractColumn(colTok)
@@ -151,11 +162,12 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     }
     
     /**
+      * Extracts date range conditions. It creates conditions based on relations between column and date value.
+      * It always returns double values conditions list because date condition processed as range.
       *
-      * @param ext
-      * @param colTok
-      * @param dateTok
-      * @return
+      * @param ext SQL extractor.
+      * @param colTok Column token.
+      * @param dateTok Date token.
       */
     def extractDateRangeConditions(ext: NCSqlExtractor, colTok: NCToken, dateTok: NCToken): Seq[SqlSimpleCondition] = {
         val col = ext.extractColumn(colTok)
@@ -165,10 +177,12 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     }
     
     /**
+      * Extracts 'values' conditions.
+      * It creates conditions based on relations between token values which extracted from given tokens and their column.
+      * These conditions grouped by columns.
       *
-      * @param ext
-      * @param allValsToks
-      * @return
+      * @param ext SQL extractor.
+      * @param allValsToks Values tokens.
       */
     def extractValuesConditions(ext: NCSqlExtractor, allValsToks: Seq[NCToken]): Seq[SqlInCondition] =
         allValsToks.map(tok ⇒ {
@@ -188,17 +202,19 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
             map { case (col, seq) ⇒ SqlInCondition(col, seq.map { case (_, value) ⇒ value})}.toSeq
     
     /**
+      * Select utility method.
+      * It creates and executes SQL request by given parameters.
+      * Parameters are token which contain information by tables, columns etc.
       *
-      * @param ext
-      * @param tabs
-      * @param cols
-      * @param condNums
-      * @param condVals
-      * @param condDates
-      * @param freeDateOpt
-      * @param limitTokOpt
-      * @param sorts
-      * @return
+      * @param ext SQL extractor.
+      * @param tabs Tables tokens.
+      * @param cols Columns tokens.
+      * @param condNums Numeric condition tokens.
+      * @param condVals Values conditions tokens.
+      * @param condDates Date range condition tokens.
+      * @param freeDateOpt Free date token. Optional.
+      * @param limitTokOpt Limit token. Optional.
+      * @param sorts Sorts tokens.
       */
     protected def select0(
         ext: NCSqlExtractor,
@@ -246,18 +262,21 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
         }
     }
 
-    // General case.
     /**
+      * Main generic intent which allows to process set of common questions.
+      * It processes questions which contains tables and column names, column values and some conditions for table columns.
       *
-      * @param ctx
-      * @param tabs
-      * @param cols
-      * @param condNums
-      * @param condVals
-      * @param condDates
-      * @param freeDateOpt
-      * @param sortTokOpt
-      * @param limitTokOpt
+      * @param ctx Intent matching context.
+      * @param tabs Tables tokens. Can be empty.
+      * @param cols Columns tokens. Can be empty.
+      * @param condNums Numeric condition tokens. Can be empty.
+      * @param condVals Values conditions tokens. Can be empty.
+      * @param condDates Date range condition tokens. Can be empty.
+      * @param freeDateOpt Free date token. Optional. Special case.
+      *    Free date detected in sentence is not related to cny concrete table column and relation set programmatically
+      *    based on model configuration.
+      * @param sortTokOpt Sort token. Optional.
+      * @param limitTokOpt Limit token. Optional.
       * @return
       */
     @NCIntent(
@@ -301,19 +320,21 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     }
     
     /**
+      * Second - modified version of main generic intent, which uses implicit sort element definition.
+      * It is developed as an example of way by which this model can be extended to support more complicated questions comparing to generic case.
       *
-      * @param ctx
-      * @param sortTok
-      * @param tabs
-      * @param cols
-      * @param condNums
-      * @param condVals
-      * @param condDates
-      * @param freeDateOpt
-      * @param limitTokOpt
-      * @return
+      * @param ctx Intent matching context.
+      * @param sortTok Sort token. Mandatory. it is defined via user elements 'sort:best' or 'sort:worst'.
+      * @param tabs Tables tokens. Can be empty.
+      * @param cols Columns tokens. Can be empty.
+      * @param condNums Numeric condition tokens. Can be empty.
+      * @param condVals Values conditions tokens. Can be empty.
+      * @param condDates Date range condition tokens. Can be empty.
+      * @param freeDateOpt Free date token. Optional. Special case.
+      *    Free date detected in sentence is not related to cny concrete table column and relation set programmatically
+      *    based on model configuration.
+      * @param limitTokOpt Limit token. Optional.
       */
-    // Case with implicit sort.
     @NCIntent(
         "intent=customSortReport conv=true " +
         "term(sort)={id == 'sort:best' || id == 'sort:worst'} " +
@@ -367,7 +388,20 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
     }
     
     /**
+      * Custom implementation NCModel#onMatchedIntent method.
+      *
+      * It is developed for clear conversation context by some conditions.
+      * In current implementation conversation context is always cleared between user questions,
+      * beside cases of evident clarifying questions.
+      * We suppose that question is clarified if their tokens satisfied one of criteria
+      *  - all these tokens are values (What about 'Exotic Liquids')
+      *  - all these tokens are columns (Give me 'last name')
+      *  - new token is single date token (What about 'tomorrow')
+      *
+      *  If new sentence tokens satisfied any of these criteria,
+      *  conversation context between this and previous questions will not be cleared.
       *
+      *  Note please that selected conversation context clearing behaviour can be modified when new intents added.
       */
     override def onMatchedIntent(m: NCIntentMatch): Boolean = {
         val toks = m.getVariant.getMatchedTokens.asScala
@@ -384,11 +418,6 @@ class SqlModel extends NCModelFileAdapter("org/apache/nlpcraft/examples/sql/sql_
             def isColumn(t: NCToken): Boolean = findAnyColumnTokenOpt(t).isDefined
             def isDate(t: NCToken): Boolean = t.getId == "nlpcraft:date"
 
-            // Conversation supported if:
-            // - all new tokens are values,
-            // - all new tokens are columns,
-            // - new single token is date.
-            // So, this example supports conversation for simple qualifying questions.
             val ok = toks.forall(isValue) || toks.forall(isColumn) || toks.size == 1 && isDate(toks.head)
 
             if (!ok) {
diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlAccess.scala b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlAccess.scala
index 2ca7e41..7b0a218 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlAccess.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlAccess.scala
@@ -35,10 +35,11 @@ object SqlAccess extends LazyLogging {
     private var conn: Connection = _
     
     /**
+      * Selects given query and return result.
+      * Also it keeps all routines by creating and recreating connections to database.
       *
-      * @param qry
-      * @param logResult
-      * @return
+      * @param qry SQl query.
+      * @param logResult Log printing flag. Useful for debugging.
       */
     def select(qry: SqlQuery, logResult: Boolean): SqlResult = {
         def getConnection: Connection = {
@@ -57,6 +58,8 @@ object SqlAccess extends LazyLogging {
                 conn.prepareStatement(qry.sql)
             catch {
                 case e: JdbcSQLException ⇒
+                    close()
+
                     // Connection broken. https://www.h2database.com/javadoc/org/h2/api/ErrorCode.html
                     if (e.getErrorCode != 90067)
                         throw e
@@ -111,6 +114,8 @@ object SqlAccess extends LazyLogging {
         }
         catch {
             case e: SQLException ⇒
+                close()
+
                 conn = null
 
                 logger.warn(
@@ -123,4 +128,15 @@ object SqlAccess extends LazyLogging {
                 throw e
         }
     }
+
+    /**
+      * Closes database connection. It is uses when application support related lifecycle methods.
+      */
+    def close(): Unit =
+        if (conn != null)
+            try
+                conn.close()
+            catch {
+                case _: Exception ⇒ logger.warn("Error closing connection")
+            }
 }
diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBeans.scala b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBeans.scala
index 0082bfc..96510e0 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBeans.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBeans.scala
@@ -20,37 +20,43 @@ package org.apache.nlpcraft.examples.sql.db
 import org.apache.nlpcraft.model.tools.sqlgen.NCSqlColumn
 
 /**
-  *
+  * SQL condition trait.
   */
 sealed trait SqlCondition {
+    /**
+      * Gets condition column.
+      */
     def column: NCSqlColumn
 }
 
 /**
+  * SQL simple condition data holder.
   *
-  * @param column
-  * @param operation
-  * @param value
+  * @param column Condition column.
+  * @param operation Operation between column and it's value.
+  * @param value Condition value.
   */
 case class SqlSimpleCondition(column: NCSqlColumn, operation: String, value: Any) extends SqlCondition
 
 /**
+  * SQL IN condition data holder. It can be changed by list of simple conditions united with OR
   *
-  * @param column
-  * @param values
+  * @param column Condition column.
+  * @param values Condition values.
   */
 case class SqlInCondition(column: NCSqlColumn, values: Seq[Any]) extends SqlCondition
 
 /**
+  * SQL query data holder.
   *
-  * @param sql
-  * @param parameters
+  * @param sql SQL query text with place holders `?` for its parameters.
+  * @param parameters SQL query parameters.
   */
 case class SqlQuery(sql: String, parameters: Seq[Any])
 
 /**
-  *
-  * @param columns
-  * @param rows
+  * SQL execution result data holder.
+  * @param columns Columns names.
+  * @param rows Table of results in string representation, row by row.
   */
 case class SqlResult(columns: Seq[String], rows: Seq[Seq[String]])
\ No newline at end of file
diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBuilder.scala b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBuilder.scala
index eea4ee7..115fb13 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBuilder.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlBuilder.scala
@@ -72,9 +72,9 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
     private var limit: Option[NCSqlLimit] = None
     
     /**
+      * Makes SQL text fragment for given join type.
       *
-      * @param clause
-      * @return
+      * @param clause Join type.
       */
     private def sql(clause: NCSqlJoinType): String =
         clause match {
@@ -89,8 +89,10 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
     
     /**
       *
-      * @param tabs
-      * @return
+      * Makes SQL join fragment for given tables.
+      * It uses tables argument and information about relations between givem tables based on schema information.
+      *
+      * @param tabs Tables.
       */
     private def sql(tabs: Seq[NCSqlTable]): String = {
         val names = tabs.map(_.getTable)
@@ -150,10 +152,40 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
                  refs.mkString(" ")
         }
     }
+
+    /**
+      * Makes SQL text fragment for given column.
+      *
+      * @param clause Column.
+      */
     private def sql(clause: NCSqlColumn): String = s"${clause.getTable}.${clause.getColumn}"
+
+    /**
+      * Makes SQL text fragment for given sort element.
+      *
+      * @param clause Sort element.
+      */
     private def sql(clause: NCSqlSort): String = s"${sql(clause.getColumn)} ${if (clause.isAscending) "ASC" else "DESC"}"
+
+    /**
+      * Makes SQL text fragment for given condition.
+      *
+      * @param clause Condition.
+      */
     private def sql(clause: SqlInCondition): String = s"${sql(clause.column)} IN (${clause.values.indices.map(_ ⇒ "?").mkString(",")})"
+
+    /**
+      * Makes SQL text fragment for given condition.
+      *
+      * @param clause Condition.
+      */
     private def sql(clause: SqlSimpleCondition): String = s"${sql(clause.column)} ${clause.operation} ?"
+
+    /**
+      * Makes SQL text fragment for given condition.
+      *
+      * @param clause Condition.
+      */
     private def sql(clause: SqlCondition): String =
         clause match {
             case x: SqlSimpleCondition ⇒ sql(x)
@@ -162,20 +194,32 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
             case _ ⇒ throw new AssertionError(s"Unexpected condition: $clause")
         }
 
+    /**
+      * Defines, is given column element is DATE or not.
+      *
+      * @param col Column element.
+      */
     private def isDate(col: NCSqlColumn): Boolean = col.getDataType == Types.DATE
+
+    /**
+      * Defines, is given column element is VARCHAR or not.
+      *
+      * @param col Column element.
+      */
     private def isString(col: NCSqlColumn): Boolean = col.getDataType == Types.VARCHAR
     
     /**
+      * Extends given columns list if necessary by some additional columns, based on schema model configuration and free date column.
+      * It can be useful if column list is poor.
       *
-      * @param cols
-      * @param extTabs
-      * @param freeDateColOpt
-      * @return
+      * @param initCols Initially detected columns.
+      * @param extTabs Extra tables list,
+      * @param freeDateColOpt Free date column. Optional.
       */
     private def extendColumns(
-        cols: Seq[NCSqlColumn], extTabs: Seq[NCSqlTable], freeDateColOpt: Option[NCSqlColumn]
+        initCols: Seq[NCSqlColumn], extTabs: Seq[NCSqlTable], freeDateColOpt: Option[NCSqlColumn]
     ): Seq[NCSqlColumn] = {
-        var res = (cols ++ freeDateColOpt.toSeq).distinct
+        var res = (initCols ++ freeDateColOpt.toSeq).distinct
 
         if (res.size < 3)
             res = (res ++
@@ -186,35 +230,36 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
     }
     
     /**
+      * Tries to find sort elements if they are not detected explicitly.
+      * It tries to use sort information from limit element if it is defined, or from model configuration
+      * (default sort columns)
       *
-      * @param sorts
-      * @param tables
-      * @param cols
-      * @return
+      * @param sorts Sort elements.
+      * @param initTables Initially detected tables.
+      * @param extCols Extended columns list.
       */
-    private def extendSort(sorts: Seq[NCSqlSort], tables: Seq[NCSqlTable], cols: Seq[NCSqlColumn]): Seq[NCSqlSort] =
+    private def extendSort(sorts: Seq[NCSqlSort], initTables: Seq[NCSqlTable], extCols: Seq[NCSqlColumn]): Seq[NCSqlSort] =
         sorts.size match {
             case 0 ⇒
-                limit.flatMap(l ⇒ if (cols.contains(l.getColumn)) Some(Seq(limit2Sort(l))) else None).
+                limit.flatMap(l ⇒ if (extCols.contains(l.getColumn)) Some(Seq(limit2Sort(l))) else None).
                     getOrElse(
-                        tables.flatMap(_.getDefaultSort.asScala.
+                        initTables.flatMap(_.getDefaultSort.asScala.
                             // 'Sort' can contain columns from select list only (some databases restriction)
-                            flatMap(sort ⇒ if (cols.contains(sort.getColumn)) Some(sort) else None)
+                            flatMap(sort ⇒ if (extCols.contains(sort.getColumn)) Some(sort) else None)
                         )
                     ).distinct
             case _ ⇒ sorts.distinct
         }
     
     /**
+      * Extends given tables list if necessary by some additional tables,
+      * based on information about relations between model tables.
       *
-      * @param tabs
-      * @throws
-      * @return
+      * @param initTables Initially detected tables.
       */
-    @throws[RuntimeException]
-    private def extendTables(tabs: Seq[NCSqlTable]): Seq[NCSqlTable] = {
+    private def extendTables(initTables: Seq[NCSqlTable]): Seq[NCSqlTable] = {
         val ext =
-            (tabs ++ schemaTabs.filter(tabs.contains).flatMap(_.getExtraTables.asScala.map(schemaTabsByNames))).distinct
+            (initTables ++ schemaTabs.filter(initTables.contains).flatMap(_.getExtraTables.asScala.map(schemaTabsByNames))).distinct
 
         ext.size match {
             case 0 ⇒ throw new RuntimeException("Tables cannot be empty.")
@@ -240,33 +285,37 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
     }
     
     /**
+      * Converts limit element to sort.
       *
-      * @param l
-      * @return
+      * @param l Limit element.
       */
     private def limit2Sort(l: NCSqlLimit): NCSqlSort = NCSqlSortImpl(l.getColumn, l.isAscending)
     
     /**
+      * Sorts given extra columns for select list.
+      * Used following criteria:
+      *  - most important initially detected columns.
+      *  - next, columns from initially detected tables.
+      *  - other extra columns.
       *
-      * @param cols2Sort
-      * @param cols
-      * @param tabs
-      * @return
+      * @param extraCols Extra columns for sorting.
+      * @param initCols Initially detected columns.
+      * @param initTabs Initially detected tables.
       */
-    private def sort(cols2Sort: Seq[NCSqlColumn], cols: Seq[NCSqlColumn], tabs: Seq[NCSqlTable]): Seq[NCSqlColumn] =
-        cols2Sort.sortBy(col ⇒
-            if (cols.contains(col))
+    private def sort(extraCols: Seq[NCSqlColumn], initCols: Seq[NCSqlColumn], initTabs: Seq[NCSqlTable]): Seq[NCSqlColumn] =
+        extraCols.sortBy(col ⇒
+            if (initCols.contains(col))
                 0
-            else if (tabs.contains(schemaTabsByNames(col.getTable)))
+            else if (initTabs.contains(schemaTabsByNames(col.getTable)))
                 1
             else
                 2
         )
     
     /**
+      * Tries to find date sql column by list of tables based model configuration (Default date fields.)
       *
-      * @param initTabs
-      * @return
+      * @param initTabs Initially detected tables.
       */
     private def findDateColumn(initTabs: Seq[NCSqlTable]): Option[NCSqlColumn] =
         schemaTabs.sortBy(t ⇒ {
@@ -287,16 +336,15 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
         }
     
     /**
+      * Extends conditions list by given free data (if it is defined) and
+      * converts conditions to SQL text and parameters list.
       *
-      * @param conds
-      * @param extTabs
-      * @param initTabs
-      * @param freeDateColOpt
-      * @return
+      * @param conds Conditions.
+      * @param initTabs Initially detected tables.
+      * @param freeDateColOpt Free date column. Optional.
       */
     private def extendConditions(
         conds: Seq[SqlCondition],
-        extTabs: Seq[NCSqlTable],
         initTabs: Seq[NCSqlTable],
         freeDateColOpt: Option[NCSqlColumn]
     ): (Seq[String], Seq[Any]) = {
@@ -305,7 +353,7 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
                 case Some(col) ⇒
                     val range = freeDateRangeOpt.getOrElse(throw new AssertionError("Missed date range"))
 
-                    import org.apache.nlpcraft.examples.sql.db.{SqlSimpleCondition => C}
+                    import org.apache.nlpcraft.examples.sql.db.{SqlSimpleCondition ⇒ C}
 
                     (Seq(C(col, ">=", range.getFrom), C(col, "<=", range.getTo)), Seq(range.getFrom, range.getTo))
                 case None ⇒ (Seq.empty, Seq.empty)
@@ -323,17 +371,50 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
         )
     }
 
+    /**
+      * Builder method, which set given argument and returns builder's instance.
+      *
+      * @param tables Tables.
+      */
     def withTables(tables: NCSqlTable*): SqlBuilder = { this.tabs ++= tables; this }
+
+    /**
+      * Builder method, which set given argument and returns builder's instance.
+      *
+      * @param cols Columns.
+      */
     def withColumns(cols: NCSqlColumn*): SqlBuilder = { this.cols ++=  cols; this }
+
+    /**
+      * Builder method, which set given argument and returns builder's instance.
+      *
+      * @param conds Condutions.
+      */
     def withAndConditions(conds: SqlCondition*): SqlBuilder = { this.conds ++= conds; this }
+
+    /**
+      * Builder method, which set given argument and returns builder's instance.
+      *
+      * @param freeDateRange Free date.
+      */
     def withFreeDateRange(freeDateRange: NCSqlDateRange): SqlBuilder = { this.freeDateRangeOpt = Option(freeDateRange); this }
+
+    /**
+      * Builder method, which set given argument and returns builder's instance.
+      *
+      * @param sorts Sort elements.
+      */
     def withSorts(sorts: NCSqlSort*): SqlBuilder = { this.sorts ++= sorts; this }
+
+    /**
+      * Builder method, which set given argument and returns builder's instance.
+      *
+      * @param limit Limit element.
+      */
     def withLimit(limit: NCSqlLimit): SqlBuilder = { this.limit = Option(limit); this }
     
     /**
-      * 
-      * @throws
-      * @return
+      * Main build method.
       */
     @throws[RuntimeException]
     def build(): SqlQuery = {
@@ -372,7 +453,7 @@ case class SqlBuilder(schema: NCSqlSchema) extends LazyLogging {
         sortsNorm = sortsNorm.distinct
 
         val extCols = extendColumns(colsNorm, extTabs, freeDateColOpt)
-        val (extConds, extParams) = extendConditions(condsNorm, extTabs, tabsNorm, freeDateColOpt)
+        val (extConds, extParams) = extendConditions(condsNorm, tabsNorm, freeDateColOpt)
 
         val extSortCols = sort(extCols, colsNorm, tabsNorm).map(sql)
         val distinct = extCols.forall(col ⇒ isString(schemaCols(Key(col.getTable, col.getColumn))))
diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlServer.scala b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlServer.scala
index ebc60ab..06b393f 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlServer.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlServer.scala
@@ -104,7 +104,7 @@ object SqlServer extends LazyLogging {
 }
 
 /**
-  * TODO: add description.
+  * H2 SQL Server Runner.
   */
 object SqlServerRunner extends App {
     SqlServer.start()
diff --git a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala
index 8f98b53..02888cf 100644
--- a/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala
+++ b/src/main/scala/org/apache/nlpcraft/examples/sql/db/SqlValueLoader.scala
@@ -27,7 +27,8 @@ import scala.collection.JavaConverters._
 import scala.language.implicitConversions
 
 /**
- * TODO add description.
+ * Values loader implementation.
+  * This implementation allows to read values for column elements from database.
  */
 class SqlValueLoader extends NCValueLoader with LazyLogging {
     override def load(e: NCElement): java.util.Set[NCValue] = {
diff --git a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
index b4acee9..f7cb78d 100644
--- a/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
+++ b/src/main/scala/org/apache/nlpcraft/probe/mgrs/nlp/NCProbeEnrichmentManager.scala
@@ -374,8 +374,6 @@ object NCProbeEnrichmentManager extends NCService with NCOpenCensusModelStats {
             var step = 0
             var continue = true
 
-            val stopIdxs = nlpSen.filter(_.isStopWord).map(_.index)
-
             while (continue) {
                 step = step + 1
 
diff --git a/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnrichersTestBeans.scala b/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnrichersTestBeans.scala
index 8ff7e65..534c1e0 100644
--- a/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnrichersTestBeans.scala
+++ b/src/test/scala/org/apache/nlpcraft/probe/mgrs/nlp/enrichers/NCEnrichersTestBeans.scala
@@ -285,7 +285,8 @@ case class NCTestUserToken(text: String, id: String) extends NCTestToken {
     require(text != null)
     require(id != null)
 
-    override def toString: String = s"$text(user)<id=$id>"}
+    override def toString: String = s"$text(user)<id=$id>"
+}
 
 // Token and sentence beans and utilities.