diff --git a/src/main/java/org/leolo/nrdatad/cron/ReferenceDataJob.java b/src/main/java/org/leolo/nrdatad/cron/ReferenceDataJob.java index 76b3dec..6f78246 100644 --- a/src/main/java/org/leolo/nrdatad/cron/ReferenceDataJob.java +++ b/src/main/java/org/leolo/nrdatad/cron/ReferenceDataJob.java @@ -27,7 +27,7 @@ public class ReferenceDataJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { log.atInfo().log("Load reference data triggered at {}", context.getFireTime()); - //There are 3 different kind of reference data. Create 3 thread and deal with them + //There are 2 different kind of reference data. Create 2 thread and deal with them new Thread(()->{processCORPUS();}).start(); new Thread(()->{processSMART();}).start(); } diff --git a/src/main/java/org/leolo/nrdatad/db/ParameterStore.java b/src/main/java/org/leolo/nrdatad/db/ParameterStore.java index 1a4e295..bd54497 100644 --- a/src/main/java/org/leolo/nrdatad/db/ParameterStore.java +++ b/src/main/java/org/leolo/nrdatad/db/ParameterStore.java @@ -1,5 +1,7 @@ package org.leolo.nrdatad.db; +import org.jetbrains.annotations.NotNull; + import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -11,6 +13,16 @@ public class ParameterStore extends ArrayList { return super.indexOf(o)+1; } + public void addAllObject(@NotNull Collection c){ + for(Object obj:c){ + add(c.toString()); + } + } + + public void addObject(Object obj){ + add(obj==null?null:obj.toString()); + } + @Override public int lastIndexOf(Object o) { return super.lastIndexOf(o)+1; diff --git a/src/main/java/org/leolo/nrdatad/db/SmartDao.java b/src/main/java/org/leolo/nrdatad/db/SmartDao.java index a7cec0a..59edd68 100644 --- a/src/main/java/org/leolo/nrdatad/db/SmartDao.java +++ b/src/main/java/org/leolo/nrdatad/db/SmartDao.java @@ -1,9 +1,16 @@ package org.leolo.nrdatad.db; +import org.leolo.nrdatad.model.Corpus; import org.leolo.nrdatad.model.Smart; +import org.leolo.nrdatad.model.SmartEvent; +import org.leolo.nrdatad.model.SmartStepType; +import org.leolo.nrdatad.util.Range; import java.sql.SQLException; import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; public abstract class SmartDao extends BaseDao{ @@ -21,5 +28,202 @@ public abstract class SmartDao extends BaseDao{ } } + public abstract Collection searchSmartByBerth(String fromBerth, String toBerth) throws SQLException; + + public abstract Collection searchFromByBerth(String fromBerth) throws SQLException; + + public abstract Collection searchToBerth(String toBerth) throws SQLException; + + public abstract Collection searchSmartByBerthLine(String fromBerth, String toBerth, String fromLine, String toLine) throws SQLException; + public abstract Collection searchSmartByFromBerthLine(String fromBerth,String fromLine) throws SQLException; + public abstract Collection searchSmartByToBerthLine(String toBerth, String toLine) throws SQLException; + + public abstract Collection searchSmartByStanox(String stanox) throws SQLException; + + + public abstract Collection executeQuery(Query query) throws SQLException; + + + public static class QueryBuilder{ + private Set td = new HashSet<>(); + private Set fromBerth = new HashSet<>(); + private Set toBerth = new HashSet<>(); + private Set fromLine = new HashSet<>(); + private Set toLine = new HashSet<>(); + private Set> berthOffset = new HashSet<>(); + private Set platform = new HashSet<>(); + private Set event = new HashSet<>(); + private Set route = new HashSet<>(); + private Set stanox = new HashSet<>(); + private Set stationName = new HashSet<>(); + private Set stepType = new HashSet<>(); + private Set comment = new HashSet<>(); + private SearchMode searchMode = SearchMode.MATCH_ALL_GROUP; + + public QueryBuilder addTd(String td){ + this.td.add(td); + return this; + } + + public QueryBuilder addFromBerth(String fromBerth){ + this.fromBerth.add(fromBerth); + return this; + } + + public QueryBuilder addToBerth(String toBerth){ + this.toBerth.add(toBerth); + return this; + } + + public QueryBuilder addFromLine(String fromLine){ + this.fromLine.add(fromLine); + return this; + } + + public QueryBuilder addToLine(String toLine){ + this.toLine.add(toLine); + return this; + } + + public QueryBuilder addBerthOffset(int bound1, int bound2){ + this.berthOffset.add(new Range<>(bound1, bound2)); + return this; + } + + public QueryBuilder addPlatform(String platform){ + this.platform.add(platform); + return this; + } + + public QueryBuilder addEvent(SmartEvent event){ + this.event.add(event); + return this; + } + + public QueryBuilder addRoute(String route){ + this.route.add(route); + return this; + } + + public QueryBuilder addStanox(String stanox){ + this.stanox.add(stanox); + return this; + } + + public QueryBuilder addStationName(String stationName){ + this.stationName.add(stationName); + return this; + } + + public QueryBuilder addStepType(SmartStepType stepType){ + this.stepType.add(stepType); + return this; + } + + public QueryBuilder addComment(String comment){ + this.comment.add(comment); + return this; + } + + public QueryBuilder setSearchMode(SearchMode searchMode){ + this.searchMode=searchMode; + return this; + } + + public Query build(){ + return new Query(td, fromBerth, toBerth, fromLine, toLine, berthOffset, platform, event, route, stanox, stationName, stepType, comment, searchMode); + } + } + + public static class Query{ + + private Set td; + private Set fromBerth; + private Set toBerth; + private Set fromLine; + private Set toLine; + private Set> berthOffset; + private Set platform; + private Set event; + private Set route; + private Set stanox; + private Set stationName; + private Set stepType; + private Set comment; + private SearchMode searchMode = SearchMode.MATCH_ALL_GROUP; + + public Query(Set td, Set fromBerth, Set toBerth, Set fromLine, Set toLine, Set> berthOffset, Set platform, Set event, Set route, Set stanox, Set stationName, Set stepType, Set comment, SearchMode searchMode) { + this.td = Collections.unmodifiableSet(td); + this.fromBerth = Collections.unmodifiableSet(fromBerth); + this.toBerth = Collections.unmodifiableSet(toBerth); + this.fromLine = Collections.unmodifiableSet(fromLine); + this.toLine = Collections.unmodifiableSet(toLine); + this.berthOffset = Collections.unmodifiableSet(berthOffset); + this.platform = Collections.unmodifiableSet(platform); + this.event = Collections.unmodifiableSet(event); + this.route = Collections.unmodifiableSet(route); + this.stanox = Collections.unmodifiableSet(stanox); + this.stationName = Collections.unmodifiableSet(stationName); + this.stepType = Collections.unmodifiableSet(stepType); + this.comment = Collections.unmodifiableSet(comment); + this.searchMode = searchMode; + } + + public Set getTd() { + return td; + } + + public Set getFromBerth() { + return fromBerth; + } + + public Set getToBerth() { + return toBerth; + } + + public Set getFromLine() { + return fromLine; + } + + public Set getToLine() { + return toLine; + } + + public Set> getBerthOffset() { + return berthOffset; + } + + public Set getPlatform() { + return platform; + } + + public Set getEvent() { + return event; + } + + public Set getRoute() { + return route; + } + + public Set getStanox() { + return stanox; + } + + public Set getStationName() { + return stationName; + } + + public Set getStepType() { + return stepType; + } + + public Set getComment() { + return comment; + } + + public SearchMode getSearchMode() { + return searchMode; + } + } } diff --git a/src/main/java/org/leolo/nrdatad/db/mariadb/SmartDao.java b/src/main/java/org/leolo/nrdatad/db/mariadb/SmartDao.java index 8db8550..33cce28 100644 --- a/src/main/java/org/leolo/nrdatad/db/mariadb/SmartDao.java +++ b/src/main/java/org/leolo/nrdatad/db/mariadb/SmartDao.java @@ -1,15 +1,21 @@ package org.leolo.nrdatad.db.mariadb; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.leolo.nrdatad.db.DatabaseManager; +import org.leolo.nrdatad.db.ParameterStore; +import org.leolo.nrdatad.db.SearchMode; import org.leolo.nrdatad.model.Smart; +import org.leolo.nrdatad.model.SmartEvent; +import org.leolo.nrdatad.model.SmartStepType; +import org.leolo.nrdatad.util.Range; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Statement; +import java.sql.*; import java.util.Collection; +import java.util.Vector; public class SmartDao extends org.leolo.nrdatad.db.SmartDao { + Logger log = LogManager.getLogger(); public SmartDao(DatabaseManager manager) { super(manager); @@ -83,4 +89,234 @@ public class SmartDao extends org.leolo.nrdatad.db.SmartDao { stmt.executeUpdate("TRUNCATE TABLE smart"); } } + + private Smart parseResultSet(ResultSet rs) throws SQLException{ + Smart smart = new Smart(); + smart.setSmartId(rs.getInt("smart_id")); + smart.setTd(rs.getString("td")); + smart.setFromBerth(rs.getString("from_berth")); + smart.setToBerth(rs.getString("to_berth")); + smart.setFromLine(rs.getString("from_line")); + smart.setToLine(rs.getString("to_line")); + smart.setBerthOffset(rs.getInt("berth_offset")); + smart.setPlatform(rs.getString("platform")); + smart.setEvent(SmartEvent.parseCode(rs.getString("event"))); + smart.setRoute(rs.getString("route")); + smart.setStanox(rs.getString("stanox")); + smart.setStationName(rs.getString("station_name")); + smart.setStepType(SmartStepType.parseCode(rs.getString("step_type"))); + smart.setComment(rs.getString("comment")); + return smart; + } + + @Override + public Collection searchSmartByBerth(String fromBerth, String toBerth) throws SQLException { + Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM smart WHERE from_berth = ? AND to_berth = ?"); + ){ + pstmt.setString(1, fromBerth); + pstmt.setString(2, toBerth); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection searchFromByBerth(String fromBerth) throws SQLException { + Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM smart WHERE from_berth =?"); + ){ + pstmt.setString(1, fromBerth); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection searchToBerth(String toBerth) throws SQLException {Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM smart WHERE to_berth = ?"); + ){ + pstmt.setString(1, toBerth); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection searchSmartByBerthLine(String fromBerth, String toBerth, String fromLine, String toLine) throws SQLException { + Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT * FROM smart WHERE from_berth = ? AND to_berth = ? AND from_line = ? AND to_line = ?"); + ){ + pstmt.setString(1, fromBerth); + pstmt.setString(2, toBerth); + pstmt.setString(3, fromLine); + pstmt.setString(4, toLine); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection searchSmartByFromBerthLine(String fromBerth, String fromLine) throws SQLException { + Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT * FROM smart WHERE from_berth = ? AND to_berth = ? AND from_line = ? AND to_line = ?"); + ){ + pstmt.setString(1, fromBerth); + pstmt.setString(2, fromLine); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection searchSmartByToBerthLine(String toBerth, String toLine) throws SQLException { + Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT * FROM smart WHERE from_berth = ? AND to_berth = ? AND from_line = ? AND to_line = ?"); + ){ + pstmt.setString(1, toBerth); + pstmt.setString(2, toLine); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection searchSmartByStanox(String stanox) throws SQLException {Vector vector = new Vector<>(); + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT * FROM smart WHERE stanox = ?"); + ){ + pstmt.setString(1, stanox); + try(ResultSet rs = pstmt.executeQuery()){ + vector.add(parseResultSet(rs)); + } + } + return vector; + } + + @Override + public Collection executeQuery(Query query) throws SQLException { + Vector smarts = new Vector<>(); + ParameterStore ps = new ParameterStore(); + StringBuilder sql = new StringBuilder(); + if(query.getSearchMode()== SearchMode.MATCH_ALL_GROUP || query.getSearchMode()==SearchMode.MATCH_ANY){ + sql.append("SELECT * FROM smart 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.getTd().size()>0){ + sql.append(keyWord).append("td IN (").append(getQueryParams(query.getTd().size())).append(") "); + ps.addAll(query.getTd()); + } + if(query.getFromBerth().size()>0){ + sql.append(keyWord).append("from_berth IN(").append(getQueryParams(query.getFromBerth().size())).append(") "); + ps.addAll(query.getFromBerth()); + } + if(query.getToBerth().size()>0){ + sql.append(keyWord).append("to_berth IN(").append(getQueryParams(query.getToBerth().size())).append(") "); + ps.addAll(query.getToBerth()); + } + if(query.getFromLine().size()>0){ + sql.append(keyWord).append("from_line IN(").append(getQueryParams(query.getFromLine().size())).append(") "); + ps.addAll(query.getFromLine()); + } + if (query.getToLine().size()>0){ + sql.append(keyWord).append("to_line (").append(getQueryParams(query.getToLine().size())).append(") "); + ps.addAll(query.getToLine()); + } + if (query.getBerthOffset().size()>0){ + sql.append(keyWord).append("(1=0 "); + for(Range range: query.getBerthOffset()){ + sql.append("OR (berth_offset BETWEEN ? AND ?) "); + ps.addObject(range.getLowerBound()); + ps.addObject(range.getUpperBound()); + } + sql.append(") "); + } + if(query.getPlatform().size()>0){ + sql.append(keyWord).append("platform IN(").append(getQueryParams(query.getPlatform().size())).append(") "); + ps.addAll(query.getPlatform()); + } + if(query.getEvent().size()>0){ + sql.append(keyWord).append("event IN(").append(getQueryParams(query.getEvent().size())).append(") "); + ps.addAllObject(query.getEvent()); + } + if(query.getRoute().size()>0){ + sql.append(keyWord).append("route IN(").append(getQueryParams(query.getRoute().size())).append(") "); + ps.addAll(query.getRoute()); + } + if(query.getStanox().size()>0){ + sql.append(keyWord).append("stanox IN(").append(getQueryParams(query.getStanox().size())).append(") "); + ps.addAll(query.getStanox()); + } + if(query.getStationName().size()>0){ + sql.append(keyWord).append("(1=0 "); + for(String stationName: query.getStationName()){ + sql.append("OR station_name LIKE ? "); + ps.add("%"+stationName+"%"); + } + sql.append(") "); + } + if(query.getStepType().size()>0){ + sql.append(keyWord).append("step_type IN(").append(getQueryParams(query.getStepType().size())).append(") "); + ps.addAllObject(query.getStepType()); + } + if(query.getComment().size()>0){ + sql.append(keyWord).append("(1=0 "); + for(String comment: query.getComment()){ + sql.append("OR comment LIKE ? "); + ps.add("%"+comment+"%"); + } + sql.append(") "); + } + } + try( + Connection conn = getConnection(); + PreparedStatement pstmt = conn.prepareStatement(sql.toString()) + ){ + for(int i=1;i<=ps.size();i++){ + log.atDebug().log("Param {} = {}", i, ps.get(i)); + setString(pstmt, i, ps.get(i)); + } + try(ResultSet rs = pstmt.executeQuery()){ + while(rs.next()){ + smarts.add(parseResultSet(rs)); + } + } + } + return smarts; + } }