1. Vadim Ne.
  2. internship-spring-redesigned

Commits

Vadim Ne.  committed f14de0f

Import all source code for this task

  • Participants
  • Parent commits aa22e85
  • Branches master

Comments (0)

Files changed (98)

File database-services-api/pom.xml

View file
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>gd-internship-masterproject-spring</artifactId>
+        <groupId>gd-internship-masterproject-spring</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>database-services-api</artifactId>
+    <packaging>jar</packaging>
+    <version>2.0</version>
+    <name>Database Services API</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>gd-internship-masterproject-spring</groupId>
+            <artifactId>libngram</artifactId>
+            <version>3.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>gd-internship-masterproject-spring</groupId>
+            <artifactId>libngram-database</artifactId>
+            <version>2.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}-${project.version}</finalName>
+    </build>
+
+</project>

File database-services-api/src/main/java/databaseServicesApi/DatabaseAdderInterface.java

View file
+package databaseServicesApi;
+
+import libngram.PhraseDataHolder;
+
+public interface DatabaseAdderInterface {
+    void clearDatabase();
+
+    void addToDatabase(PhraseDataHolder data);
+}

File database-services-api/src/main/java/databaseServicesApi/NgramDto.java

View file
+package databaseServicesApi;
+
+/**
+ * It's supposed that object gets validated data. Object doesn't do validation.
+ */
+public class NgramDto {
+    private final String data;
+    private final int count;
+
+    public NgramDto(String data, int count) {
+        this.data = data;
+        this.count = count;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public int getCount() {
+        return count;
+    }
+}

File database-services-api/src/main/java/databaseServicesApi/NgramsDatabaseReaderInterface.java

View file
+package databaseServicesApi;
+
+import java.util.List;
+
+public interface NgramsDatabaseReaderInterface {
+    NgramDto searchNgramByDataFullMatch(String ngramData);
+
+    List<NgramDto> getListOfNgrams(NgramsListQueryObject ngramsListQuery);
+
+    int getAmountOfNgramsInDatabase();
+}

File database-services-api/src/main/java/databaseServicesApi/NgramsListQueryObject.java

View file
+package databaseServicesApi;
+
+public class NgramsListQueryObject {
+    public static class NgramsListQueryBuilder {
+        //required
+        private int amount;
+        private int offsetPage;
+
+        //optional
+        private String orderByFieldNameString;
+        private NgramsSortFieldName orderByFieldName;
+        private String orderString;
+        private Order order;
+
+        public NgramsListQueryBuilder(int amount, int offsetPage) {
+            this.amount = amount;
+            this.offsetPage = offsetPage;
+        }
+
+        public NgramsListQueryBuilder orderByField(Enum fieldName) {
+            if (fieldName == null)
+                this.orderByFieldNameString = "";
+            else
+                this.orderByFieldNameString = fieldName.name();
+            return this;
+        }
+
+        public NgramsListQueryBuilder order(Enum order) {
+            if (order == null)
+                this.orderString = "";
+            else
+                this.orderString = order.name();
+            return this;
+        }
+
+        public NgramsListQueryObject build() throws QueryObjectBuilderValidationError {
+            if (amount < 1) {
+                throw new QueryObjectBuilderValidationError("Amount of items in list is negative or zero.");
+            }
+
+            if (offsetPage < 0) {
+                throw new QueryObjectBuilderValidationError("Offset page number is negative.");
+            }
+
+            try {
+                orderByFieldName = NgramsSortFieldName.valueOf(orderByFieldNameString);
+            } catch (Exception e) {
+                orderByFieldName = null;
+                //throw new QueryObjectBuilderValidationError("Field name to order is incorrect.");
+            }
+
+            try {
+                order = Order.valueOf(orderString);
+            } catch (Exception e) {
+                order = null;
+                //throw new QueryObjectBuilderValidationError("Order tag is incorrect.");
+            }
+
+            return new NgramsListQueryObject(this);
+        }
+    }
+
+    //required
+    private final int amount;
+    private final int offsetPage;
+
+    //optional
+    private final NgramsSortFieldName orderByFieldName;
+    private final Order order;
+
+    private NgramsListQueryObject(NgramsListQueryBuilder ngramsListQueryBuilder) {
+        this.amount = ngramsListQueryBuilder.amount;
+        this.offsetPage = ngramsListQueryBuilder.offsetPage;
+        this.orderByFieldName = ngramsListQueryBuilder.orderByFieldName;
+        this.order = ngramsListQueryBuilder.order;
+    }
+
+    public int getAmount() {
+        return amount;
+    }
+
+    public int getOffsetPage() {
+        return offsetPage;
+    }
+
+    public NgramsSortFieldName getOrderByFieldName() {
+        return orderByFieldName;
+    }
+
+    public Order getOrder() {
+        return order;
+    }
+}

File database-services-api/src/main/java/databaseServicesApi/NgramsSortFieldName.java

View file
+package databaseServicesApi;
+
+public enum NgramsSortFieldName {
+    name, count
+}

File database-services-api/src/main/java/databaseServicesApi/Order.java

View file
+package databaseServicesApi;
+
+public enum Order {
+    asc, desc
+}

File database-services-api/src/main/java/databaseServicesApi/QueryObjectBuilderValidationError.java

View file
+package databaseServicesApi;
+
+public class QueryObjectBuilderValidationError extends Exception {
+    public QueryObjectBuilderValidationError(String message) {
+        super(message);
+    }
+}

File database-services-api/src/main/java/databaseServicesApi/WordForNgramWithCountDto.java

View file
+package databaseServicesApi;
+
+/**
+ * It's supposed that object gets validated data. Object doesn't do validation.
+ */
+public class WordForNgramWithCountDto {
+    private final String word;
+    private final int count;
+
+    public WordForNgramWithCountDto(String word, int count) {
+        this.word = word;
+        this.count = count;
+    }
+
+    public String getWord() {
+        return word;
+    }
+
+    public int getCount() {
+        return count;
+    }
+}

File database-services-api/src/main/java/databaseServicesApi/WordsDatabaseReaderInterface.java

View file
+package databaseServicesApi;
+
+import java.util.List;
+
+public interface WordsDatabaseReaderInterface {
+    List<WordForNgramWithCountDto> getListOfWordsWithCounters(WordsListQueryObject wordsListQuery);
+
+    int getAmountOfWordsWithCountersInDatabase(String ngramData, String partOfWord);
+}

File database-services-api/src/main/java/databaseServicesApi/WordsListQueryObject.java

View file
+package databaseServicesApi;
+
+import org.apache.commons.lang3.StringUtils;
+
+public class WordsListQueryObject {
+    public static class WordsListQueryBuilder {
+        //required
+        private String ngramData;
+        private int amountOfElements;
+        private int offsetPage;
+        private String wordToSearchPattern;
+
+        //optional
+        private String orderByFieldNameString;
+        private WordsSortFieldName orderByFieldName;
+        private String orderString;
+        private Order order;
+
+        public WordsListQueryBuilder(String ngramData, int amountOfElements, int offsetPage, String wordToSearchPattern) {
+            this.ngramData = ngramData;
+            this.amountOfElements = amountOfElements;
+            this.offsetPage = offsetPage;
+            this.wordToSearchPattern = wordToSearchPattern;
+        }
+
+        public WordsListQueryBuilder orderByField(Enum fieldName) {
+            if (fieldName == null)
+                this.orderByFieldNameString = "";
+            else
+                this.orderByFieldNameString = fieldName.name();
+            return this;
+        }
+
+        public WordsListQueryBuilder order(Enum order) {
+            if (order == null)
+                this.orderString = "";
+            else
+                this.orderString = order.name();
+            return this;
+        }
+
+        public WordsListQueryObject build() throws QueryObjectBuilderValidationError {
+            if (StringUtils.isEmpty(ngramData)) {
+                throw new QueryObjectBuilderValidationError("N-gram data is not defined.");
+            }
+
+            if (amountOfElements < 1) {
+                throw new QueryObjectBuilderValidationError("Amount of items in list is negative or zero.");
+            }
+
+            if (offsetPage < 0) {
+                throw new QueryObjectBuilderValidationError("Offset page number is negative.");
+            }
+
+            if (StringUtils.isEmpty(wordToSearchPattern)) {
+                throw new QueryObjectBuilderValidationError("Word search pattern is null or empty.");
+            }
+
+            try {
+                orderByFieldName = WordsSortFieldName.valueOf(orderByFieldNameString);
+            } catch (Exception e) {
+                orderByFieldName = null;
+            }
+
+            try {
+                order = Order.valueOf(orderString);
+            } catch (Exception e) {
+                order = null;
+            }
+
+            return new WordsListQueryObject(this);
+        }
+    }
+
+    //required
+    private final int amountOfElements;
+    private final int offsetPage;
+    private String ngramData;
+    private String wordToSearchPattern;
+
+    //optional
+    private final WordsSortFieldName orderByFieldName;
+    private final Order order;
+
+    private WordsListQueryObject(WordsListQueryBuilder wordsListQueryBuilder) {
+        this.amountOfElements = wordsListQueryBuilder.amountOfElements;
+        this.offsetPage = wordsListQueryBuilder.offsetPage;
+        this.ngramData = wordsListQueryBuilder.ngramData;
+        this.wordToSearchPattern = wordsListQueryBuilder.wordToSearchPattern;
+        this.orderByFieldName = wordsListQueryBuilder.orderByFieldName;
+        this.order = wordsListQueryBuilder.order;
+    }
+
+    public int getAmountOfElements() {
+        return amountOfElements;
+    }
+
+    public int getOffsetPage() {
+        return offsetPage;
+    }
+
+    public String getNgramData() {
+        return ngramData;
+    }
+
+    public String getWordToSearchPattern() {
+        return wordToSearchPattern;
+    }
+
+    public WordsSortFieldName getOrderByFieldName() {
+        return orderByFieldName;
+    }
+
+    public Order getOrder() {
+        return order;
+    }
+}

File database-services-api/src/main/java/databaseServicesApi/WordsSortFieldName.java

View file
+package databaseServicesApi;
+
+public enum WordsSortFieldName {
+    word, count
+}

File database-services-impl/pom.xml

View file
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>gd-internship-masterproject-spring</artifactId>
+        <groupId>gd-internship-masterproject-spring</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>database-services-impl</artifactId>
+    <packaging>jar</packaging>
+    <version>2.0</version>
+    <name>Database Services Implementation</name>
+
+    <dependencies>
+        <!-- Depends on commons-io -->
+        <dependency>
+            <groupId>gd-internship-masterproject-spring</groupId>
+            <artifactId>libngram</artifactId>
+            <version>3.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>gd-internship-masterproject-spring</groupId>
+            <artifactId>libngram-database</artifactId>
+            <version>2.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>gd-internship-masterproject-spring</groupId>
+            <artifactId>database-services-api</artifactId>
+            <version>2.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}-${project.version}</finalName>
+    </build>
+
+</project>

File database-services-impl/src/main/java/databaseServicesImplementation/DatabaseAdder.java

View file
+package databaseServicesImplementation;
+
+import dao.*;
+import dao.entities.Ngram;
+import dao.entities.NgramToWord;
+import dao.entities.WordToPhrase;
+import dao.jdbcDao.IllegalInputSizeException;
+import databaseServicesApi.DatabaseAdderInterface;
+import libngram.PhraseDataHolder;
+import libngram.WordWithNgrams;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Isolation;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@Transactional(isolation = Isolation.READ_COMMITTED)
+public class DatabaseAdder implements DatabaseAdderInterface {
+    @Autowired
+    private PhrasesDao phrasesDao;
+    @Autowired
+    private WordsDao wordsDao;
+    @Autowired
+    private NgramsDao ngramsDao;
+    @Autowired
+    private WordsToPhrasesDao wordsToPhrasesDao;
+    @Autowired
+    private NgramsToWordsDao ngramsToWordsDao;
+
+    /**
+     * Remove all data from all tables.
+     */
+    @Override
+    public void clearDatabase() {
+        ngramsToWordsDao.removeAllEntetiesFromTable();
+        wordsToPhrasesDao.removeAllEntetiesFromTable();
+        ngramsDao.removeAllEntetiesFromTable();
+        wordsDao.removeAllEntetiesFromTable();
+        phrasesDao.removeAllEntetiesFromTable();
+    }
+
+    @Override
+    public void addToDatabase(PhraseDataHolder data) {
+        try {
+            // Insert phrase into table
+            int phraseDbId = phrasesDao.insertNewPhrase(data.getPhrase());
+
+            // Insert Elements into table
+            for (WordWithNgrams wordWithNgrams : data.getWordsWithNgramsList()) {
+                String currentWordData = wordWithNgrams.getWord();
+
+                boolean isWordNew = false;
+
+                int wordDbId = wordsDao.findWordId(currentWordData);
+                if (wordDbId == 0) {
+                    wordDbId = wordsDao.insertNewWord(currentWordData);
+                    isWordNew = true;
+                }
+
+                WordToPhrase wordToPhrase = wordsToPhrasesDao.findWordToPhrase(wordDbId, phraseDbId);
+                if (wordToPhrase == null) {
+                    wordsToPhrasesDao.insertNewWordToPhrase(wordDbId, phraseDbId);
+                } else {
+                    wordToPhrase.incrementCounter();
+                    wordsToPhrasesDao.updateWordToPhraseCounter(wordToPhrase);
+                }
+
+                if (wordWithNgrams.getNgramsList() != null) {
+                    for (String currentNgramData : wordWithNgrams.getNgramsList()) {
+                        // Find and insert ngram into dbTables or increment ngram counter
+                        Ngram ngram = ngramsDao.findByDataString(currentNgramData);
+                        if (ngram == null) {
+                            int newNgramDbIndex = ngramsDao.insertNewNgram(currentNgramData);
+                            ngram = new Ngram(newNgramDbIndex, currentNgramData, 1);
+                        } else {
+                            ngram.incrementCounter();
+                            ngramsDao.updateNgramCounter(ngram);
+                        }
+
+                        // Find and insert ngram_to_word relation of increment ngram in word counter
+                        NgramToWord ngramToWord = ngramsToWordsDao.findNgramToWord(ngram.getId(), wordDbId);
+                        if (ngramToWord == null) {
+                            ngramsToWordsDao.insertNewNgramsToWords(ngram.getId(), wordDbId);
+                        } else {
+                            if (isWordNew) {
+                                ngramToWord.incrementCounter();
+                                ngramsToWordsDao.updateNgramToWordCounter(ngramToWord);
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (IllegalInputSizeException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

File database-services-impl/src/main/java/databaseServicesImplementation/NgramsJdbcReader.java

View file
+package databaseServicesImplementation;
+
+import dao.NgramsDao;
+import dao.daoQueryObjects.NgramsListDaoQueryObject;
+import dao.entities.Ngram;
+import databaseServicesApi.NgramDto;
+import databaseServicesApi.NgramsDatabaseReaderInterface;
+import databaseServicesApi.NgramsListQueryObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional(readOnly = true)
+public class NgramsJdbcReader implements NgramsDatabaseReaderInterface {
+    private NgramsDao ngramsDao;
+
+    @Autowired
+    public NgramsJdbcReader(NgramsDao ngramsDao) {
+        this.ngramsDao = ngramsDao;
+    }
+
+    @Override
+    public NgramDto searchNgramByDataFullMatch(String ngramData) {
+        Ngram ngram = ngramsDao.findByDataString(ngramData);
+        if (ngram != null) {
+            return new NgramDto(ngram.getData(), ngram.getCount());
+        } else return null;
+    }
+
+    @Override
+    public List<NgramDto> getListOfNgrams(NgramsListQueryObject ngramsListQuery) {
+        if (ngramsListQuery == null)
+            return null;
+
+        NgramsListDaoQueryObject ngramsDaoQO = NgramsListQueryObjectToDaoQueryObjectConverter.convert(ngramsListQuery);
+        return NgramsListDaoToDto.convert(ngramsDao.extractListOfNgrams(ngramsDaoQO));
+    }
+
+    @Override
+    public int getAmountOfNgramsInDatabase() {
+        return ngramsDao.extractAmountOfNgrams();
+    }
+}

File database-services-impl/src/main/java/databaseServicesImplementation/NgramsListDaoToDto.java

View file
+package databaseServicesImplementation;
+
+import dao.entities.Ngram;
+import databaseServicesApi.NgramDto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class NgramsListDaoToDto {
+    public static List<NgramDto> convert(List<Ngram> listToConvert) {
+        List<NgramDto> listToReturn = new ArrayList<NgramDto>(listToConvert.size());
+
+        for (Ngram element : listToConvert) {
+            listToReturn.add(new NgramDto(element.getData(), element.getCount()));
+        }
+
+        return listToReturn;
+    }
+}

File database-services-impl/src/main/java/databaseServicesImplementation/NgramsListQueryObjectToDaoQueryObjectConverter.java

View file
+package databaseServicesImplementation;
+
+import dao.daoQueryObjects.NgramsListDaoQueryObject;
+import databaseServicesApi.NgramsListQueryObject;
+
+public class NgramsListQueryObjectToDaoQueryObjectConverter {
+    public static NgramsListDaoQueryObject convert(NgramsListQueryObject ngramsListQuery) {
+        return new NgramsListDaoQueryObject(
+                ngramsListQuery.getAmount(),
+                ngramsListQuery.getOffsetPage(),
+                ngramsListQuery.getOrderByFieldName(),
+                ngramsListQuery.getOrder());
+    }
+}

File database-services-impl/src/main/java/databaseServicesImplementation/WordsJdbcReader.java

View file
+package databaseServicesImplementation;
+
+import dao.NgramsDao;
+import dao.WordsDao;
+import dao.daoQueryObjects.WordsListDaoQueryObject;
+import databaseServicesApi.WordForNgramWithCountDto;
+import databaseServicesApi.WordsDatabaseReaderInterface;
+import databaseServicesApi.WordsListQueryObject;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+@Transactional(readOnly = true)
+public class WordsJdbcReader implements WordsDatabaseReaderInterface {
+    private final WordsDao wordsDao;
+    private final NgramsDao ngramsDao;
+
+    @Autowired
+    public WordsJdbcReader(WordsDao wordsDao, NgramsDao ngramsDao) {
+        this.wordsDao = wordsDao;
+        this.ngramsDao = ngramsDao;
+    }
+
+    @Override
+    public List<WordForNgramWithCountDto> getListOfWordsWithCounters(WordsListQueryObject wordsListQuery) {
+        if (wordsListQuery == null)
+            return null;
+
+        int ngramId = ngramsDao.getIdForNgram(wordsListQuery.getNgramData());
+        WordsListDaoQueryObject wrdsDaoQO = WordsListQueryObjectToDaoQueryObjectConverter.convert(ngramId, wordsListQuery);
+        return WordsListDaoToDto.convert(wordsDao.findAndExtractListOfWordsForNgramByPartialWordMatch(wrdsDaoQO));
+    }
+
+    @Override
+    public int getAmountOfWordsWithCountersInDatabase(String ngramData, String partOfWord) {
+        if (StringUtils.isEmpty(ngramData) || StringUtils.isEmpty(partOfWord))
+            return 0;
+
+        int ngramId = ngramsDao.getIdForNgram(ngramData);
+        if (ngramId > 0) {
+            return wordsDao.extractAmountOfWordsForNgramByItsDataPartialMatch(ngramId, partOfWord);
+        }
+        return 0;
+    }
+}

File database-services-impl/src/main/java/databaseServicesImplementation/WordsListDaoToDto.java

View file
+package databaseServicesImplementation;
+
+import dao.entities.WordForNgramWithCount;
+import databaseServicesApi.WordForNgramWithCountDto;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class WordsListDaoToDto {
+    public static List<WordForNgramWithCountDto> convert(List<WordForNgramWithCount> listToConvert) {
+        List<WordForNgramWithCountDto> listToReturn = new ArrayList<WordForNgramWithCountDto>(listToConvert.size());
+
+        for (WordForNgramWithCount element : listToConvert) {
+            listToReturn.add(new WordForNgramWithCountDto(element.getWord(), element.getCount()));
+        }
+
+        return listToReturn;
+    }
+}

File database-services-impl/src/main/java/databaseServicesImplementation/WordsListQueryObjectToDaoQueryObjectConverter.java

View file
+package databaseServicesImplementation;
+
+import dao.daoQueryObjects.WordsListDaoQueryObject;
+import databaseServicesApi.WordsListQueryObject;
+
+public class WordsListQueryObjectToDaoQueryObjectConverter {
+    public static WordsListDaoQueryObject convert(int ngramId, WordsListQueryObject wordsListQuery) {
+        return new WordsListDaoQueryObject(ngramId,
+                wordsListQuery.getOffsetPage(),
+                wordsListQuery.getAmountOfElements(),
+                wordsListQuery.getWordToSearchPattern(),
+                wordsListQuery.getOrderByFieldName(),
+                wordsListQuery.getOrder());
+    }
+}

File libngram-database/pom.xml

View file
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>gd-internship-masterproject-spring</artifactId>
+        <groupId>gd-internship-masterproject-spring</groupId>
+        <version>1.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>libngram-database</artifactId>
+    <packaging>jar</packaging>
+    <version>2.0</version>
+    <name>Ngram Database Library</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>1.3.174</version>
+        </dependency>
+
+        <dependency>
+            <groupId>gd-internship-masterproject-spring</groupId>
+            <artifactId>libngram</artifactId>
+            <version>3.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}-${project.version}</finalName>
+    </build>
+
+</project>

File libngram-database/src/main/java/dao/AbstractDao.java

View file
+package dao;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+public abstract class AbstractDao {
+    private JdbcTemplate jdbcTemplate;
+
+    public JdbcTemplate getJdbcTemplate() {
+        return jdbcTemplate;
+    }
+
+    @Autowired
+    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+}

File libngram-database/src/main/java/dao/NgramsDao.java

View file
+package dao;
+
+import dao.daoQueryObjects.NgramsListDaoQueryObject;
+import dao.entities.Ngram;
+
+import java.util.List;
+
+public interface NgramsDao {
+
+    Ngram findByDataString(String ngramDataString);
+
+    int getIdForNgram(String ngramDataString);
+
+    List<Ngram> extractListOfNgrams(NgramsListDaoQueryObject ngramsListDaoQueryObject);
+
+    int extractAmountOfNgrams();
+
+    int insertNewNgram(String ngramString);
+
+    void updateNgramCounter(Ngram ngram);
+
+    void removeAllEntetiesFromTable();
+}

File libngram-database/src/main/java/dao/NgramsToWordsDao.java

View file
+package dao;
+
+import dao.entities.NgramToWord;
+
+public interface NgramsToWordsDao {
+
+    NgramToWord findNgramToWord(int id, int wordDbId);
+
+    NgramToWord insertNewNgramsToWords(int ngramId, int wordId);
+
+    void updateNgramToWordCounter(NgramToWord ngramToWord);
+
+    void removeAllEntetiesFromTable();
+}

File libngram-database/src/main/java/dao/PhrasesDao.java

View file
+package dao;
+
+public interface PhrasesDao {
+
+    int insertNewPhrase(String phraseString);
+
+    void removeAllEntetiesFromTable();
+}

File libngram-database/src/main/java/dao/WordsDao.java

View file
+package dao;
+
+import dao.daoQueryObjects.WordsListDaoQueryObject;
+import dao.entities.WordForNgramWithCount;
+
+import java.util.List;
+
+public interface WordsDao {
+
+    int findWordId(String wordDataString);
+
+    List<WordForNgramWithCount> findAndExtractListOfWordsForNgramByPartialWordMatch(WordsListDaoQueryObject wordsListDaoQueryObject);
+
+    int extractAmountOfWordsForNgramByItsDataPartialMatch(int ngramData, String partOfWord);
+
+    int insertNewWord(String wordString);
+
+    void removeAllEntetiesFromTable();
+}

File libngram-database/src/main/java/dao/WordsToPhrasesDao.java

View file
+package dao;
+
+import dao.entities.WordToPhrase;
+
+public interface WordsToPhrasesDao {
+
+    WordToPhrase findWordToPhrase(int wordId, int phraseId);
+
+    WordToPhrase insertNewWordToPhrase(int wordId, int phraseId);
+
+    void updateWordToPhraseCounter(WordToPhrase wordToPhrase);
+
+    void removeAllEntetiesFromTable();
+}

File libngram-database/src/main/java/dao/daoQueryObjects/NgramsListDaoQueryObject.java

View file
+package dao.daoQueryObjects;
+
+public class NgramsListDaoQueryObject {
+    //required
+    private int amount;
+    private int offsetPage;
+
+    //optional
+    private NgramsSortFieldName orderByFieldName;
+    private Order order;
+
+    public NgramsListDaoQueryObject(int amount, int offsetPage, Enum orderByFieldName, Enum order) {
+        this.amount = amount;
+        this.offsetPage = offsetPage;
+
+        if (orderByFieldName == null)
+            this.orderByFieldName = null;
+        else
+            this.orderByFieldName = NgramsSortFieldName.valueOf(orderByFieldName.name());
+
+        if (order == null)
+            this.order = null;
+        else
+            this.order = Order.valueOf(order.name());
+    }
+
+    public int getAmount() {
+        return amount;
+    }
+
+    public int getOffsetPage() {
+        return offsetPage;
+    }
+
+    public NgramsSortFieldName getOrderByFieldName() {
+        return orderByFieldName;
+    }
+
+    public Order getOrder() {
+        return order;
+    }
+}

File libngram-database/src/main/java/dao/daoQueryObjects/NgramsSortFieldName.java

View file
+package dao.daoQueryObjects;
+
+public enum NgramsSortFieldName {
+    name, count
+}

File libngram-database/src/main/java/dao/daoQueryObjects/Order.java

View file
+package dao.daoQueryObjects;
+
+public enum Order {
+    asc, desc
+}

File libngram-database/src/main/java/dao/daoQueryObjects/WordsListDaoQueryObject.java

View file
+package dao.daoQueryObjects;
+
+public class WordsListDaoQueryObject {
+    // required
+    private final int ngramId;
+    private final int offsetPage;
+    private final int amountOfItems;
+    private final String partOfWord;
+
+    // optional
+    private final WordsSortFieldName orderByFieldName;
+    private final Order order;
+
+    public WordsListDaoQueryObject(int ngramId, int pageOffset, int amountOfItems, String partOfWord, Enum orderByFieldName, Enum order) {
+        this.ngramId = ngramId;
+        this.offsetPage = pageOffset;
+        this.amountOfItems = amountOfItems;
+        this.partOfWord = partOfWord;
+
+        if (orderByFieldName == null)
+            this.orderByFieldName = null;
+        else
+            this.orderByFieldName = WordsSortFieldName.valueOf(orderByFieldName.name());
+
+        if (order == null)
+            this.order = null;
+        else
+            this.order = Order.valueOf(order.name());
+    }
+
+    public int getNgramId() {
+        return ngramId;
+    }
+
+    public int getOffsetPage() {
+        return offsetPage;
+    }
+
+    public int getAmountOfItems() {
+        return amountOfItems;
+    }
+
+    public String getPartOfWord() {
+        return partOfWord;
+    }
+
+    public WordsSortFieldName getOrderByFieldName() {
+        return orderByFieldName;
+    }
+
+    public Order getOrder() {
+        return order;
+    }
+}

File libngram-database/src/main/java/dao/daoQueryObjects/WordsSortFieldName.java

View file
+package dao.daoQueryObjects;
+
+public enum WordsSortFieldName {
+    word, count
+}

File libngram-database/src/main/java/dao/entities/Ngram.java

View file
+package dao.entities;
+
+import dao.jdbcDao.IllegalInputSizeException;
+
+public class Ngram {
+    private static final int MAXIMUM_NGRAM_STRING_LENGTH = 20;
+
+    public static final String NGRAM_ID_COLUMN_NAME = "id";
+    public static final String NGRAM_DATA_COLUMN_NAME = "n_gram_data";
+    public static final String NGRAM_COUNT_COLUMN_NAME = "n_gram_count";
+
+    private int id;
+    private final String data;
+    private int count = 0;
+
+    public Ngram(String ngramData) throws IllegalInputSizeException {
+        validateData(ngramData);
+
+        this.data = ngramData;
+    }
+
+    public Ngram(int ngramId, String ngramData, int ngramCount) throws IllegalInputSizeException {
+        this(ngramData);
+
+        validateCount(ngramCount);
+        this.id = ngramId;
+        this.count = ngramCount;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public int getCount() {
+        return count;
+    }
+
+    public void incrementCounter() {
+        count++;
+    }
+
+    private void validateData(String ngramData) throws IllegalInputSizeException {
+        if (ngramData == null || ngramData.isEmpty()) {
+            throw new IllegalArgumentException("Ngram data cannot be null or empty.");
+        }
+
+        if (ngramData.length() < 0 && ngramData.length() > MAXIMUM_NGRAM_STRING_LENGTH) {
+            throw new IllegalInputSizeException("Ngram string length exceeded allowed " + MAXIMUM_NGRAM_STRING_LENGTH + " symbols limit.");
+        }
+    }
+
+    private void validateCount(int ngramCount) {
+        if (ngramCount <= 0) {
+            throw new IllegalArgumentException("Ngram counter can't have negative value.");
+        }
+    }
+}

File libngram-database/src/main/java/dao/entities/NgramToWord.java

View file
+package dao.entities;
+
+public class NgramToWord {
+    public static final String NGRAM_TO_WORD_NGRAM_ID_COLUMN_NAME = "ngram_id";
+    public static final String NGRAM_TO_WORD_WORD_ID_COLUMN_NAME = "word_id";
+    public static final String NGRAM_TO_WORD_NGRAM_IN_WORD_COUNT_COLUMN_NAME = "ngram_in_word_count";
+
+    private int ngramId;
+    private int wordId;
+    private int ngramInWordCount;
+
+    public NgramToWord(int ngramId, int wordId, int ngramInWordCount) {
+        this.ngramId = ngramId;
+        this.wordId = wordId;
+        this.ngramInWordCount = ngramInWordCount;
+    }
+
+    public int getNgramId() {
+        return ngramId;
+    }
+
+    public int getWordId() {
+        return wordId;
+    }
+
+    public int getNgramInWordCount() {
+        return ngramInWordCount;
+    }
+
+    public void incrementCounter() {
+        ngramInWordCount++;
+    }
+}

File libngram-database/src/main/java/dao/entities/WordForNgramWithCount.java

View file
+package dao.entities;
+
+public class WordForNgramWithCount {
+    private String word;
+    private int count;
+
+    public WordForNgramWithCount(String word, int count) {
+        this.word = word;
+        this.count = count;
+    }
+
+    public String getWord() {
+        return word;
+    }
+
+    public int getCount() {
+        return count;
+    }
+}

File libngram-database/src/main/java/dao/entities/WordToPhrase.java

View file
+package dao.entities;
+
+public class WordToPhrase {
+    public static final String WORD_TO_PHRASE_WORD_ID_COLUMN_NAME = "word_id";
+    public static final String WORD_TO_PHRASE_PHRASE_ID_COLUMN_NAME = "phrase_id";
+    public static final String WORD_TO_PHRASE_WORDS_IN_PHRASE_COUNT_COLUMN_NAME = "words_in_phrase_count";
+
+    private int wordId;
+    private int phraseId;
+    private int wordToPhraseCount;
+
+    public WordToPhrase(int wordId, int phraseId, int wordToPhraseCount) {
+        this.wordId = wordId;
+        this.phraseId = phraseId;
+        this.wordToPhraseCount = wordToPhraseCount;
+    }
+
+    public int getWordId() {
+        return wordId;
+    }
+
+    public int getPhraseId() {
+        return phraseId;
+    }
+
+    public int getWordToPhraseCount() {
+        return wordToPhraseCount;
+    }
+
+    public void incrementCounter() {
+        wordToPhraseCount++;
+    }
+}

File libngram-database/src/main/java/dao/jdbcDao/IllegalInputSizeException.java

View file
+package dao.jdbcDao;
+
+public class IllegalInputSizeException extends Exception {
+    public IllegalInputSizeException(String message) {
+        super(message);
+    }
+}

File libngram-database/src/main/java/dao/jdbcDao/JdbcNgramsDao.java

View file
+package dao.jdbcDao;
+
+import dao.AbstractDao;
+import dao.NgramsDao;
+import dao.daoQueryObjects.NgramsListDaoQueryObject;
+import dao.daoQueryObjects.NgramsSortFieldName;
+import dao.daoQueryObjects.Order;
+import dao.entities.Ngram;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.PreparedStatementCreator;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+import org.springframework.stereotype.Repository;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public class JdbcNgramsDao extends AbstractDao implements NgramsDao {
+    private final static String SELECT_NGRAM_BY_NGRAM_STRING_DATA = "SELECT * FROM N_GRAMS WHERE N_GRAM_DATA = ?";
+    private final static String SELECT_AMOUNT_OF_ELEMENTS = "SELECT COUNT(*) FROM N_GRAMS";
+    private final static String INSERT_NEW_NGRAM = "INSERT INTO N_GRAMS(N_GRAM_DATA, N_GRAM_COUNT) VALUES (?, 1)";
+    private final static String UPDATE_NGRAM_COUNTER = "UPDATE N_GRAMS SET N_GRAM_COUNT = ? WHERE ID = ?";
+    private final static String CLEAN_NGRAMS_TABLE = "DELETE FROM N_GRAMS";
+    //------------------------------------------------------------------------------------------------------------------
+    private final static String SELECT_TEN_NGRAMS_GENERAL_PART = "SELECT * FROM N_GRAMS ";
+
+    private final static String SELECT_TEN_NGRAMS_QUERY_DATA_FIELD_NAME_PART = " n_gram_data ";
+    private final static String SELECT_TEN_NGRAMS_QUERY_COUNTER_FIELD_NAME_PART = " n_gram_count ";
+
+    private final static String QUERY_ORDER_BY_CLAUSE = " ORDER BY ";
+    private final static String QUERY_LIMITATION_PART = " LIMIT ? OFFSET ? * 10;";
+    //******************************************************************************************************************
+
+    @Override
+    public Ngram findByDataString(String ngramDataString) {
+        if (ngramDataString == null) {
+            return null;
+        }
+
+        try {
+            return getJdbcTemplate().queryForObject(SELECT_NGRAM_BY_NGRAM_STRING_DATA, new Object[]{ngramDataString},
+                    new RowMapper<Ngram>() {
+                        @Override
+                        public Ngram mapRow(ResultSet rs, int rowNum) throws SQLException {
+                            try {
+                                return new Ngram(
+                                        rs.getInt(Ngram.NGRAM_ID_COLUMN_NAME),
+                                        rs.getString(Ngram.NGRAM_DATA_COLUMN_NAME),
+                                        rs.getInt(Ngram.NGRAM_COUNT_COLUMN_NAME)
+                                );
+                            } catch (IllegalInputSizeException e) {
+                                throw new RuntimeException("Invalid n-gram object from database extracted.");
+                            }
+                        }
+                    });
+        } catch (EmptyResultDataAccessException exception) {
+            return null;
+        }
+    }
+
+    @Override
+    public int getIdForNgram(String ngramDataString) {
+        Ngram ngram = findByDataString(ngramDataString);
+        if (ngram == null) {
+            return 0;
+        }
+        return ngram.getId();
+    }
+
+    @Override
+    public List<Ngram> extractListOfNgrams(NgramsListDaoQueryObject ngramsListDaoQueryObject) {
+        if (ngramsListDaoQueryObject == null) {
+            return null;
+        }
+
+        String querySB;
+
+        int amountOfItems = ngramsListDaoQueryObject.getAmount();
+        int offsetPage = ngramsListDaoQueryObject.getOffsetPage();
+
+        if (ngramsListDaoQueryObject.getOrder() == null && ngramsListDaoQueryObject.getOrderByFieldName() == null) {
+            querySB = SELECT_TEN_NGRAMS_GENERAL_PART + QUERY_LIMITATION_PART;
+        } else {
+            if (ngramsListDaoQueryObject.getOrder() == Order.asc) {
+                if (ngramsListDaoQueryObject.getOrderByFieldName() == NgramsSortFieldName.name) { // ASC by name
+                    querySB = SELECT_TEN_NGRAMS_GENERAL_PART + QUERY_ORDER_BY_CLAUSE + SELECT_TEN_NGRAMS_QUERY_DATA_FIELD_NAME_PART + "ASC" + QUERY_LIMITATION_PART;
+                } else { // ASC by count
+                    querySB = SELECT_TEN_NGRAMS_GENERAL_PART + QUERY_ORDER_BY_CLAUSE + SELECT_TEN_NGRAMS_QUERY_COUNTER_FIELD_NAME_PART + "ASC" + QUERY_LIMITATION_PART;
+                }
+            } else {
+                if (ngramsListDaoQueryObject.getOrderByFieldName() == NgramsSortFieldName.name) { // DESC by name
+                    querySB = SELECT_TEN_NGRAMS_GENERAL_PART + QUERY_ORDER_BY_CLAUSE + SELECT_TEN_NGRAMS_QUERY_DATA_FIELD_NAME_PART + "DESC" + QUERY_LIMITATION_PART;
+                } else { // DESC by count
+                    querySB = SELECT_TEN_NGRAMS_GENERAL_PART + QUERY_ORDER_BY_CLAUSE + SELECT_TEN_NGRAMS_QUERY_COUNTER_FIELD_NAME_PART + "DESC" + QUERY_LIMITATION_PART;
+                }
+            }
+        }
+
+        List<Ngram> listOfNgrams = new ArrayList<Ngram>();
+        List<Map<String, Object>> rows = getJdbcTemplate().queryForList(querySB, amountOfItems, offsetPage);
+
+        if ((rows != null) && (rows.size() > 0)) {
+            for (Map<String, Object> row : rows) {
+                try {
+                    listOfNgrams.add(new Ngram(
+                            (Integer) row.get(Ngram.NGRAM_ID_COLUMN_NAME),
+                            (String) row.get(Ngram.NGRAM_DATA_COLUMN_NAME),
+                            (Integer) row.get(Ngram.NGRAM_COUNT_COLUMN_NAME)
+                    ));
+                } catch (IllegalInputSizeException e) {
+                    throw new RuntimeException("Data is not valid.", e);
+                }
+            }
+        } else {
+            return null;
+        }
+        return listOfNgrams;
+    }
+
+    @Override
+    public int extractAmountOfNgrams() {
+        return getJdbcTemplate().queryForInt(SELECT_AMOUNT_OF_ELEMENTS);
+    }
+
+    @Override
+    public int insertNewNgram(final String ngramString) {
+        if (ngramString == null) {
+            return 0;
+        }
+
+        KeyHolder keyHolder = new GeneratedKeyHolder();
+        getJdbcTemplate().update(
+                new PreparedStatementCreator() {
+                    @Override
+                    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
+                        PreparedStatement ps = con.prepareStatement(INSERT_NEW_NGRAM, new String[]{"id"});
+                        ps.setString(1, ngramString);
+                        return ps;
+                    }
+                }, keyHolder
+        );
+        return keyHolder.getKey().intValue();
+    }
+
+    @Override
+    public void updateNgramCounter(Ngram ngram) {
+        if (ngram != null) {
+            getJdbcTemplate().update(UPDATE_NGRAM_COUNTER, ngram.getCount(), ngram.getId());
+        }
+    }
+
+    @Override
+    public void removeAllEntetiesFromTable() {
+        getJdbcTemplate().update(CLEAN_NGRAMS_TABLE);
+    }
+}

File libngram-database/src/main/java/dao/jdbcDao/JdbcNgramsToWordsDao.java

View file
+package dao.jdbcDao;
+
+import dao.AbstractDao;
+import dao.NgramsToWordsDao;
+import dao.entities.NgramToWord;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Repository;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@Repository
+public class JdbcNgramsToWordsDao extends AbstractDao implements NgramsToWordsDao {
+    private final static String SELECT_NGRAM_TO_WORD_BY_ID = "SELECT * FROM N_GRAMS_TO_WORDS WHERE NGRAM_ID = ? AND WORD_ID = ?";
+    private final static String INSERT_NEW_NGRAM_TO_WORD = "INSERT INTO N_GRAMS_TO_WORDS VALUES (?, ?, 1)";
+    private final static String UPDATE_NGRAM_TO_WORD_COUNTER = "UPDATE N_GRAMS_TO_WORDS SET NGRAM_IN_WORD_COUNT = ? WHERE NGRAM_ID = ? AND WORD_ID = ?";
+    private final static String CLEAN_NGRAMS_TO_WORDS_TABLE = "DELETE FROM N_GRAMS_TO_WORDS";
+
+    @Override
+    public NgramToWord findNgramToWord(int ngramId, int wordId) {
+        if (ngramId == 0 || wordId == 0) {
+            return null;
+        }
+
+        try {
+            return getJdbcTemplate().queryForObject(SELECT_NGRAM_TO_WORD_BY_ID, new Object[]{ngramId, wordId},
+                    new RowMapper<NgramToWord>() {
+                        @Override
+                        public NgramToWord mapRow(ResultSet rs, int rowNum) throws SQLException {
+                            return new NgramToWord(
+                                    rs.getInt(NgramToWord.NGRAM_TO_WORD_NGRAM_ID_COLUMN_NAME),
+                                    rs.getInt(NgramToWord.NGRAM_TO_WORD_WORD_ID_COLUMN_NAME),
+                                    rs.getInt(NgramToWord.NGRAM_TO_WORD_NGRAM_IN_WORD_COUNT_COLUMN_NAME)
+                            );
+                        }
+                    });
+        } catch (DataAccessException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public NgramToWord insertNewNgramsToWords(int ngramId, int wordId) {
+        if (ngramId == 0 && wordId == 0) {
+            return null;
+        }
+
+        int numberOfRowsAffected = getJdbcTemplate().update(INSERT_NEW_NGRAM_TO_WORD, ngramId, wordId);
+        if (numberOfRowsAffected > 0) {
+            return new NgramToWord(ngramId, wordId, 1);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void updateNgramToWordCounter(NgramToWord ngramToWord) {
+        if (ngramToWord != null) {
+            getJdbcTemplate().update(UPDATE_NGRAM_TO_WORD_COUNTER, ngramToWord.getNgramInWordCount(), ngramToWord.getNgramId(), ngramToWord.getWordId());
+        }
+    }
+
+    @Override
+    public void removeAllEntetiesFromTable() {
+        getJdbcTemplate().update(CLEAN_NGRAMS_TO_WORDS_TABLE);
+    }
+}

File libngram-database/src/main/java/dao/jdbcDao/JdbcPhrasesDao.java

View file
+package dao.jdbcDao;
+
+import dao.AbstractDao;
+import dao.PhrasesDao;
+import org.springframework.jdbc.core.PreparedStatementCreator;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+import org.springframework.stereotype.Repository;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+@Repository
+public class JdbcPhrasesDao extends AbstractDao implements PhrasesDao {
+    private final static String INSERT_PHRASE = "INSERT INTO PHRASES(PHRASE_DATA) VALUES(?)";
+    private final static String CLEAN_PHRASES_TABLE = "DELETE FROM PHRASES";
+
+    @Override
+    public int insertNewPhrase(final String phraseString) {
+        if (phraseString == null) {
+            return 0;
+        }
+
+        KeyHolder keyHolder = new GeneratedKeyHolder();
+        getJdbcTemplate().update(
+                new PreparedStatementCreator() {
+                    @Override
+                    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
+                        PreparedStatement ps = con.prepareStatement(INSERT_PHRASE, new String[]{"id"});
+                        ps.setString(1, phraseString);
+                        return ps;
+                    }
+                }, keyHolder
+        );
+        return keyHolder.getKey().intValue();
+    }
+
+    @Override
+    public void removeAllEntetiesFromTable() {
+        getJdbcTemplate().update(CLEAN_PHRASES_TABLE);
+    }
+}

File libngram-database/src/main/java/dao/jdbcDao/JdbcWordsDao.java

View file
+package dao.jdbcDao;
+
+import dao.AbstractDao;
+import dao.WordsDao;
+import dao.daoQueryObjects.Order;
+import dao.daoQueryObjects.WordsListDaoQueryObject;
+import dao.daoQueryObjects.WordsSortFieldName;
+import dao.entities.WordForNgramWithCount;
+import org.springframework.jdbc.core.PreparedStatementCreator;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.support.GeneratedKeyHolder;
+import org.springframework.jdbc.support.KeyHolder;
+import org.springframework.stereotype.Repository;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@Repository
+public class JdbcWordsDao extends AbstractDao implements WordsDao {
+    private final static String SELECT_WORD_BY_DATA = "SELECT * FROM WORDS WHERE word_data = ?";
+    private final static String INSERT_WORD = "INSERT INTO WORDS(WORD_DATA) VALUES (?)";
+    private final static String CLEAN_WORDS_TABLE = "DELETE FROM WORDS";
+
+    private final static String COUNT_TEN_WORDS_FOR_NGRAM_PARTIAL_MATCH =
+            "SELECT COUNT(*) FROM WORDS INNER JOIN N_GRAMS_TO_WORDS ON ID = WORD_ID WHERE NGRAM_ID = ? AND WORD_DATA REGEXP ?";
+    //------------------------------------------------------------------------------------------------------------------
+    private final static String SELECT_TEN_WORDS_WITH_COUNTERS_FOR_NGRAM_BY_PARTIAL_WORD_DATA_GENERAL_PART =
+            "SELECT WORD_DATA, NGRAM_IN_WORD_COUNT FROM WORDS AS A INNER JOIN N_GRAMS_TO_WORDS AS B ON A.ID = B.WORD_ID WHERE NGRAM_ID = ? AND WORD_DATA REGEXP ? ";
+
+    private final static String SELECT_TEN_WORDS_QUERY_DATA_FIELD_NAME_PART = " WORD_DATA ";
+    private final static String SELECT_TEN_WORDS_QUERY_COUNTER_FIELD_PART = " NGRAM_IN_WORD_COUNT ";
+    //******************************************************************************************************************
+    private final static String QUERY_ORDER_BY_CLAUSE = " ORDER BY ";
+    private final static String QUERY_LIMITATION_PART = " LIMIT ? OFFSET ? * 10;";
+    //******************************************************************************************************************
+
+    @Override
+    public int findWordId(String wordDataString) {
+        if (wordDataString == null) {
+            return 0;
+        }
+        try {
+            return getJdbcTemplate().queryForObject(SELECT_WORD_BY_DATA, new Object[]{wordDataString},
+                    new RowMapper<Integer>() {
+                        @Override
+                        public Integer mapRow(ResultSet resultSet, int i) throws SQLException {
+                            return resultSet.getInt("id");
+                        }
+                    });
+        } catch (Exception e) {
+            return 0;
+        }
+    }
+
+    @Override
+    public List<WordForNgramWithCount> findAndExtractListOfWordsForNgramByPartialWordMatch(WordsListDaoQueryObject wordsListDaoQueryObject) {
+        if (wordsListDaoQueryObject == null) {
+            return null;
+        }
+        String querySB;
+
+        int ngramId = wordsListDaoQueryObject.getNgramId();
+        String partOfWord = wordsListDaoQueryObject.getPartOfWord();
+        int amountOfItems = wordsListDaoQueryObject.getAmountOfItems();
+        int offsetPage = wordsListDaoQueryObject.getOffsetPage();
+
+        if (wordsListDaoQueryObject.getOrder() == null && wordsListDaoQueryObject.getOrderByFieldName() == null) {
+            querySB = SELECT_TEN_WORDS_WITH_COUNTERS_FOR_NGRAM_BY_PARTIAL_WORD_DATA_GENERAL_PART + QUERY_LIMITATION_PART;
+        } else {
+            if (wordsListDaoQueryObject.getOrder() == Order.asc) {
+                if (wordsListDaoQueryObject.getOrderByFieldName() == WordsSortFieldName.word) { // ASC by word
+                    querySB = SELECT_TEN_WORDS_WITH_COUNTERS_FOR_NGRAM_BY_PARTIAL_WORD_DATA_GENERAL_PART +
+                            QUERY_ORDER_BY_CLAUSE + SELECT_TEN_WORDS_QUERY_DATA_FIELD_NAME_PART + "ASC" + QUERY_LIMITATION_PART;
+                } else { // ASC by count
+                    querySB = SELECT_TEN_WORDS_WITH_COUNTERS_FOR_NGRAM_BY_PARTIAL_WORD_DATA_GENERAL_PART +
+                            QUERY_ORDER_BY_CLAUSE + SELECT_TEN_WORDS_QUERY_COUNTER_FIELD_PART + "ASC" + QUERY_LIMITATION_PART;
+                }
+            } else {
+                if (wordsListDaoQueryObject.getOrderByFieldName() == WordsSortFieldName.word) { // DESC by word
+                    querySB = SELECT_TEN_WORDS_WITH_COUNTERS_FOR_NGRAM_BY_PARTIAL_WORD_DATA_GENERAL_PART +
+                            QUERY_ORDER_BY_CLAUSE + SELECT_TEN_WORDS_QUERY_DATA_FIELD_NAME_PART + "DESC" + QUERY_LIMITATION_PART;
+                } else { // DESC by count
+                    querySB = SELECT_TEN_WORDS_WITH_COUNTERS_FOR_NGRAM_BY_PARTIAL_WORD_DATA_GENERAL_PART +
+                            QUERY_ORDER_BY_CLAUSE + SELECT_TEN_WORDS_QUERY_COUNTER_FIELD_PART + "DESC" + QUERY_LIMITATION_PART;
+                }
+            }
+        }
+
+        List<WordForNgramWithCount> listOfWordsForNgram = new ArrayList<WordForNgramWithCount>();
+        List<Map<String, Object>> rows = getJdbcTemplate().queryForList(querySB, ngramId, partOfWord, amountOfItems, offsetPage);
+
+        if ((rows != null) && (rows.size() > 0)) {
+            for (Map<String, Object> row : rows) {
+                listOfWordsForNgram.add(new WordForNgramWithCount(
+                        (String) row.get("WORD_DATA"),
+                        (Integer) row.get("NGRAM_IN_WORD_COUNT")
+                ));
+            }
+        } else {
+            return null;
+        }
+        return listOfWordsForNgram;
+    }
+
+    @Override
+    public int extractAmountOfWordsForNgramByItsDataPartialMatch(int ngramData, String partOfWord) {
+        if (ngramData > 0 || partOfWord != null) {
+            return getJdbcTemplate().queryForInt(COUNT_TEN_WORDS_FOR_NGRAM_PARTIAL_MATCH, ngramData, partOfWord);
+        }
+        return 0;
+    }
+
+    @Override
+    public int insertNewWord(final String wordString) {
+        if (wordString == null) {
+            return 0;
+        }
+
+        KeyHolder keyHolder = new GeneratedKeyHolder();
+        getJdbcTemplate().update(
+                new PreparedStatementCreator() {
+                    @Override
+                    public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
+                        PreparedStatement ps = con.prepareStatement(INSERT_WORD, new String[]{"id"});
+                        ps.setString(1, wordString);
+                        return ps;
+                    }
+                }, keyHolder
+        );
+        return keyHolder.getKey().intValue();
+
+    }
+
+    @Override
+    public void removeAllEntetiesFromTable() {
+        getJdbcTemplate().update(CLEAN_WORDS_TABLE);
+    }
+}

File libngram-database/src/main/java/dao/jdbcDao/JdbcWordsToPhrasesDao.java

View file
+package dao.jdbcDao;
+
+import dao.AbstractDao;
+import dao.WordsToPhrasesDao;
+import dao.entities.WordToPhrase;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Repository;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+@Repository
+public class JdbcWordsToPhrasesDao extends AbstractDao implements WordsToPhrasesDao {
+    private final static String SELECT_WORD_TO_PHRASE = "SELECT * FROM WORDS_TO_PHRASES WHERE WORD_ID = ? AND PHRASE_ID = ?";
+    private final static String INSERT_NEW_WORD_TO_PHRASE = "INSERT INTO WORDS_TO_PHRASES VALUES (?, ?, 1);";
+    private final static String UPDATE_WORDS_TO_PHRASES_COUNTER = "UPDATE WORDS_TO_PHRASES SET WORDS_IN_PHRASE_COUNT = ? WHERE WORD_ID = ? AND PHRASE_ID = ?";
+    private final static String CLEAN_WORDS_TO_PHRASES_TABLE = "DELETE FROM WORDS_TO_PHRASES;";
+
+    @Override
+    public WordToPhrase findWordToPhrase(int wordId, int phraseId) {
+        if (wordId == 0 || phraseId == 0) {
+            return null;
+        }
+
+        try {
+            return getJdbcTemplate().queryForObject(SELECT_WORD_TO_PHRASE, new Object[]{wordId, phraseId},
+                    new RowMapper<WordToPhrase>() {
+                        @Override
+                        public WordToPhrase mapRow(ResultSet rs, int rowNum) throws SQLException {
+                            return new WordToPhrase(
+                                    rs.getInt(WordToPhrase.WORD_TO_PHRASE_WORD_ID_COLUMN_NAME),
+                                    rs.getInt(WordToPhrase.WORD_TO_PHRASE_PHRASE_ID_COLUMN_NAME),
+                                    rs.getInt(WordToPhrase.WORD_TO_PHRASE_WORDS_IN_PHRASE_COUNT_COLUMN_NAME)
+                            );
+                        }
+                    });
+        } catch (DataAccessException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public WordToPhrase insertNewWordToPhrase(final int wordId, final int phraseId) {
+        if (wordId == 0 && phraseId == 0) {
+            return null;
+        }
+