From 3400f8462893d7b53d986ef0d3ce5f6d8484af58 Mon Sep 17 00:00:00 2001 From: LO Kam Tao Leo Date: Tue, 25 Oct 2022 18:12:12 +0100 Subject: [PATCH] Basic search for CORPUS --- pom.xml | 5 ++ src/main/java/org/leolo/nrdatad/App.java | 22 ++++++ src/main/java/org/leolo/nrdatad/db/BaseDao.java | 14 ++++ src/main/java/org/leolo/nrdatad/db/CORPUSDao.java | 53 ++++++++------- .../java/org/leolo/nrdatad/db/ParameterStore.java | 53 +++++++++++++++ src/main/java/org/leolo/nrdatad/db/SearchMode.java | 10 +++ .../org/leolo/nrdatad/db/mariadb/CORPUSDao.java | 79 ++++++++++++++++++++-- src/main/java/org/leolo/nrdatad/model/CORPUS.java | 13 ++++ 8 files changed, 220 insertions(+), 29 deletions(-) create mode 100644 src/main/java/org/leolo/nrdatad/db/ParameterStore.java diff --git a/pom.xml b/pom.xml index 3ee36d2..fb7697d 100644 --- a/pom.xml +++ b/pom.xml @@ -72,6 +72,11 @@ json 20220924 + + org.apache.commons + commons-collections4 + 4.4 + diff --git a/src/main/java/org/leolo/nrdatad/App.java b/src/main/java/org/leolo/nrdatad/App.java index 2292666..96d70aa 100644 --- a/src/main/java/org/leolo/nrdatad/App.java +++ b/src/main/java/org/leolo/nrdatad/App.java @@ -4,13 +4,17 @@ package org.leolo.nrdatad; import org.apache.commons.cli.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.leolo.nrdatad.db.CORPUSDao; import org.leolo.nrdatad.db.DatabaseManager; import org.leolo.nrdatad.cron.ReferenceDataJob; +import org.leolo.nrdatad.model.CORPUS; import org.quartz.*; import org.quartz.impl.StdSchedulerFactory; import java.io.IOException; import java.lang.reflect.InvocationTargetException; +import java.sql.SQLException; +import java.util.Collection; /** * Hello world! @@ -90,9 +94,27 @@ public class App { return; } loadCronJob(); + new Thread(()->{testRefData();}).start(); while(true); } + private void testRefData() { + log.atInfo().log("Testing reference data"); + ConfigurationManager conf = ConfigurationManager.getInstance(); + CORPUSDao.Query query = new CORPUSDao.QueryBuilder() + .addCrsCode("ECR").addCrsCode("VIC") + .addDescription("croydon").build(); + try { + Collection list = conf.getDatabaseManager().getCORPUSDao().executeQuery(query); + log.atDebug().log("{} entries found", list.size()); + for(CORPUS corpus:list){ + log.atDebug().log("Found entry : {}", corpus); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + private void loadCronJob() { log.atDebug().log("Start loading cron jobs"); try { diff --git a/src/main/java/org/leolo/nrdatad/db/BaseDao.java b/src/main/java/org/leolo/nrdatad/db/BaseDao.java index e78fd13..d0b04c8 100644 --- a/src/main/java/org/leolo/nrdatad/db/BaseDao.java +++ b/src/main/java/org/leolo/nrdatad/db/BaseDao.java @@ -27,4 +27,18 @@ public abstract class BaseDao { } } + protected String getQueryParams(int count){ + if(count <= 0){ + throw new IllegalArgumentException("count must be greater than 0"); + } + StringBuilder sb = new StringBuilder(); + for(int i=0;i0){ + sb.append(","); + } + sb.append("?"); + } + return sb.toString(); + } + } diff --git a/src/main/java/org/leolo/nrdatad/db/CORPUSDao.java b/src/main/java/org/leolo/nrdatad/db/CORPUSDao.java index a0af137..f359c11 100644 --- a/src/main/java/org/leolo/nrdatad/db/CORPUSDao.java +++ b/src/main/java/org/leolo/nrdatad/db/CORPUSDao.java @@ -1,12 +1,10 @@ package org.leolo.nrdatad.db; +import org.apache.commons.collections4.SetUtils; import org.leolo.nrdatad.model.CORPUS; import java.sql.SQLException; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; public abstract class CORPUSDao extends BaseDao{ @@ -23,32 +21,39 @@ public abstract class CORPUSDao extends BaseDao{ private Set description = new HashSet<>(); SearchMode searchMode = SearchMode.MATCH_ALL_GROUP; - public void setSearchMode(SearchMode searchMode) { + public QueryBuilder setSearchMode(SearchMode searchMode) { this.searchMode = searchMode; + return this; } - public void addStanox(String stanox){ + public QueryBuilder addStanox(String stanox){ this.stanox.add(stanox); + return this; } - public void addUicCode(String uicCode){ + public QueryBuilder addUicCode(String uicCode){ this.uicCode.add(uicCode); + return this; } - public void addCrsCode(String crsCode){ + public QueryBuilder addCrsCode(String crsCode){ this.crsCode.add(crsCode); + return this; } - public void addTiplocCode(String tiplocCode){ + public QueryBuilder addTiplocCode(String tiplocCode){ this.tiplocCode.add(tiplocCode); + return this; } - public void addNlcCode(String nlcCode){ + public QueryBuilder addNlcCode(String nlcCode){ this.nlcCode.add(nlcCode); + return this; } - public void addDescription(String description){ + public QueryBuilder addDescription(String description){ this.description.add(description); + return this; } public Query build(){ @@ -66,40 +71,40 @@ public abstract class CORPUSDao extends BaseDao{ SearchMode searchMode = SearchMode.MATCH_ALL_GROUP; private Query(Set stanox, Set uicCode, Set crsCode, Set tiplocCode, Set nlcCode, Set description, SearchMode searchMode) { - this.stanox = stanox; - this.uicCode = uicCode; - this.crsCode = crsCode; - this.tiplocCode = tiplocCode; - this.nlcCode = nlcCode; - this.description = description; + this.stanox = Collections.unmodifiableSet(stanox); + this.uicCode = Collections.unmodifiableSet(uicCode); + this.crsCode = Collections.unmodifiableSet(crsCode); + this.tiplocCode = Collections.unmodifiableSet(tiplocCode); + this.nlcCode = Collections.unmodifiableSet(nlcCode); + this.description = Collections.unmodifiableSet(description); this.searchMode = searchMode; } - protected Set getStanox() { + public Set getStanox() { return stanox; } - protected Set getUicCode() { + public Set getUicCode() { return uicCode; } - protected Set getCrsCode() { + public Set getCrsCode() { return crsCode; } - protected Set getTiplocCode() { + public Set getTiplocCode() { return tiplocCode; } - protected Set getNlcCode() { + public Set getNlcCode() { return nlcCode; } - protected Set getDescription() { + public Set getDescription() { return description; } - protected SearchMode getSearchMode() { + public SearchMode getSearchMode() { return searchMode; } } diff --git a/src/main/java/org/leolo/nrdatad/db/ParameterStore.java b/src/main/java/org/leolo/nrdatad/db/ParameterStore.java new file mode 100644 index 0000000..1a4e295 --- /dev/null +++ b/src/main/java/org/leolo/nrdatad/db/ParameterStore.java @@ -0,0 +1,53 @@ +package org.leolo.nrdatad.db; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ParameterStore extends ArrayList { + + @Override + public int indexOf(Object o) { + return super.indexOf(o)+1; + } + + @Override + public int lastIndexOf(Object o) { + return super.lastIndexOf(o)+1; + } + + @Override + public String get(int index) { + return super.get(index-1); + } + + @Override + public String set(int index, String element) { + return super.set(index-1, element); + } + + @Override + public void add(int index, String element) { + super.add(index-1, element); + } + + @Override + public String remove(int index) { + return super.remove(index-1); + } + + @Override + public boolean addAll(int index, Collection c) { + return super.addAll(index-1, c); + } + + @Override + protected void removeRange(int fromIndex, int toIndex) { + super.removeRange(fromIndex-1, toIndex-1); + } + + @Override + public List subList(int fromIndex, int toIndex) { + return super.subList(fromIndex-1, toIndex-1); + } +} diff --git a/src/main/java/org/leolo/nrdatad/db/SearchMode.java b/src/main/java/org/leolo/nrdatad/db/SearchMode.java index 28e2118..11de03c 100644 --- a/src/main/java/org/leolo/nrdatad/db/SearchMode.java +++ b/src/main/java/org/leolo/nrdatad/db/SearchMode.java @@ -1,7 +1,17 @@ package org.leolo.nrdatad.db; public enum SearchMode { + + /** + * Indicate all condition must be matched + */ MATCH_ALL, + /** + * Indicate at least one condition in every group must be matched + */ MATCH_ALL_GROUP, + /** + * Indicate at least one condition must be matched. + */ MATCH_ANY; } diff --git a/src/main/java/org/leolo/nrdatad/db/mariadb/CORPUSDao.java b/src/main/java/org/leolo/nrdatad/db/mariadb/CORPUSDao.java index 3a2b7e6..9e26daf 100644 --- a/src/main/java/org/leolo/nrdatad/db/mariadb/CORPUSDao.java +++ b/src/main/java/org/leolo/nrdatad/db/mariadb/CORPUSDao.java @@ -4,13 +4,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; import org.leolo.nrdatad.db.DatabaseManager; +import org.leolo.nrdatad.db.ParameterStore; +import org.leolo.nrdatad.db.SearchMode; import org.leolo.nrdatad.model.CORPUS; import java.sql.*; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Vector; +import java.util.*; public class CORPUSDao extends org.leolo.nrdatad.db.CORPUSDao { @@ -22,7 +21,77 @@ public class CORPUSDao extends org.leolo.nrdatad.db.CORPUSDao { @Override public Collection executeQuery(org.leolo.nrdatad.db.CORPUSDao.Query query) throws SQLException { - return null; + Vector corpuses = new Vector<>(); + ParameterStore params = new ParameterStore(); + StringBuilder sql = new StringBuilder(); + if(query.getSearchMode()== SearchMode.MATCH_ALL_GROUP || query.getSearchMode()==SearchMode.MATCH_ANY){ + sql.append("SELECT * FROM corpus WHERE "); + String keyWord; + if(query.getSearchMode() == SearchMode.MATCH_ALL_GROUP){ + sql.append("1=1 "); + keyWord = "AND "; + }else{ + sql.append("1=0 "); + keyWord = "OR "; + } + if(query.getStanox().size()>0){ + sql.append(keyWord).append("stanox IN (") + .append(getQueryParams(query.getStanox().size())).append(") "); + params.addAll(query.getStanox()); + } + if(query.getUicCode().size()>0){ + sql.append(keyWord).append("uic_code IN (") + .append(getQueryParams(query.getUicCode().size())).append(") "); + params.addAll(query.getUicCode()); + } + if(query.getCrsCode().size()>0){ + sql.append(keyWord).append("crs_code IN (") + .append(getQueryParams(query.getCrsCode().size())).append(") "); + params.addAll(query.getCrsCode()); + } + if(query.getTiplocCode().size()>0){ + sql.append(keyWord).append("tiploc_code IN (") + .append(getQueryParams(query.getTiplocCode().size())).append(") "); + params.addAll(query.getTiplocCode()); + } + if(query.getNlcCode().size()>0){ + sql.append(keyWord).append("nlc_code IN(") + .append(getQueryParams(query.getNlcCode().size())).append(") "); + params.addAll(query.getNlcCode()); + } + if(query.getDescription().size()>0){ + sql.append(keyWord).append("("); + boolean hasDesc = false; + for(String str:query.getDescription()){ + if(hasDesc){ + sql.append("OR "); + } + sql.append("(`desc` LIKE ? OR short_desc LIKE ? ) "); + hasDesc = true; + params.add("%"+str+"%"); + params.add("%"+str+"%"); + } + sql.append(") "); + } + log.atDebug().log("SQL={}",sql); + }else{ + log.always().log("Search mode {} is yet to be implemented.", query.getSearchMode()); + } + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql.toString()) + ){ + for(int i=1;i<=params.size();i++){ + log.atDebug().log("Param {} = {}", i, params.get(i)); + setString(pstmt, i, params.get(i)); + } + try(ResultSet rs = pstmt.executeQuery()){ + while(rs.next()){ + corpuses.add(parseCORPUS(rs)); + } + } + } + return corpuses; } @Override diff --git a/src/main/java/org/leolo/nrdatad/model/CORPUS.java b/src/main/java/org/leolo/nrdatad/model/CORPUS.java index 7106ba7..5663f1a 100644 --- a/src/main/java/org/leolo/nrdatad/model/CORPUS.java +++ b/src/main/java/org/leolo/nrdatad/model/CORPUS.java @@ -81,4 +81,17 @@ public class CORPUS { public int hashCode() { return Objects.hash(stanoxCode, uicCode, crsCode, tiplocCode, nlcCode, longDescription, shortDescription); } + + @Override + public String toString() { + return "CORPUS{" + + "stanoxCode='" + stanoxCode + '\'' + + ", uicCode='" + uicCode + '\'' + + ", crsCode='" + crsCode + '\'' + + ", tiplocCode='" + tiplocCode + '\'' + + ", nlcCode='" + nlcCode + '\'' + + ", longDescription='" + longDescription + '\'' + + ", shortDescription='" + shortDescription + '\'' + + '}'; + } }