View Javadoc

1   package org.inigma.utopia.sync;
2   
3   import java.sql.ResultSet;
4   import java.sql.SQLException;
5   import java.sql.Timestamp;
6   import java.util.Calendar;
7   import java.util.List;
8   
9   import javax.sql.DataSource;
10  
11  import org.inigma.utopia.Army;
12  import org.inigma.utopia.Coordinate;
13  import org.inigma.utopia.Kingdom;
14  import org.inigma.utopia.Military;
15  import org.inigma.utopia.Personality;
16  import org.inigma.utopia.Province;
17  import org.inigma.utopia.Race;
18  import org.inigma.utopia.Rank;
19  import org.inigma.utopia.Relation;
20  import org.inigma.utopia.Science;
21  import org.inigma.utopia.Stance;
22  import org.inigma.utopia.Survey;
23  import org.inigma.utopia.utils.CalendarUtils;
24  import org.springframework.beans.factory.annotation.Autowired;
25  import org.springframework.dao.EmptyResultDataAccessException;
26  import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
27  import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
28  
29  public class DataSyncTemplate extends SimpleJdbcTemplate {
30      private static final String EXISTS_KINGDOM = "SELECT id FROM kingdom WHERE id=? ";
31      private static final String EXISTS_PROVINCE = "SELECT id FROM province WHERE id=? ";
32      private static final String EXISTS_SCIENCE = "SELECT id FROM science WHERE id=? ";
33      private static final String EXISTS_SURVEY = "SELECT id FROM survey WHERE id=? ";
34      private static final String EXISTS_MILITARY = "SELECT id FROM military WHERE id=? ";
35  
36      private static final String SELECT_SYNC_KINGDOM = "SELECT id, last_update, kingdom, island, name, relation, stance, "
37          + "war_count, war_win, war_nwdiff "
38          + "FROM kingdom "
39          + "WHERE last_update > ? ";
40      private static final String SELECT_SYNC_PROVINCE = "SELECT id, kingdom_id, last_update, name, acres, gender, leader, "
41          + "networth, race, rank, personality, peasants, gold, food, runes, trade, thieves, wizards, "
42          + "soldiers, offspecs, defspecs, elites, horses, prisoners, offense, defense "
43          + "FROM province "
44          + "WHERE last_update > ? "
45          + "OR id IN (SELECT province_id FROM science WHERE last_update > ? "
46          + "  UNION ALL "
47          + "  SELECT province_id FROM survey WHERE last_update > ? "
48          + "  UNION ALL "
49          + "  SELECT province_id FROM military WHERE last_update > ? )";
50  
51      private static final String SELECT_KINGDOM = "SELECT id, last_update, kingdom, island, name, relation, stance, "
52          + "war_count, war_win, war_nwdiff "
53          + "FROM kingdom "
54          + "WHERE kingdom = ? "
55          + "AND island = ? ";
56      private static final String SELECT_KINGDOM_BY_ID = "SELECT id, last_update, kingdom, island, name, relation, stance, "
57          + "war_count, war_win, war_nwdiff "
58          + "FROM kingdom "
59          + "WHERE id = ? ";
60      private static final String INSERT_KINGDOM = "INSERT INTO kingdom(id, last_update, kingdom, island, name, relation, "
61          + "stance, war_count, war_win, war_nwdiff) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
62      private static final String UPDATE_KINGDOM = "UPDATE kingdom SET last_update=?, name=?, relation=?, stance=?, "
63          + "war_count=?, war_win=?, war_nwdiff=? "
64          + "WHERE id=? "
65          + "AND last_update < ?";
66  
67      private static final String SELECT_PROVINCE_BY_NAME = "SELECT id, kingdom_id, last_update, name, acres, gender, leader, "
68          + "networth, race, rank, personality, peasants, gold, food, runes, trade, thieves, wizards, "
69          + "soldiers, offspecs, defspecs, elites, horses, prisoners, offense, defense "
70          + "FROM province "
71          + "WHERE name=? ";
72      private static final String INSERT_PROVINCE = "INSERT INTO province(id, kingdom_id, last_update, name, acres, "
73          + "gender, leader, networth, race, rank, personality, peasants, gold, food, runes, trade, thieves, wizards, "
74          + "soldiers, offspecs, defspecs, elites, horses, prisoners, offense, defense) "
75          + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
76      private static final String UPDATE_PROVINCE = "UPDATE province "
77          + "SET kingdom_id=?, last_update=?, name=?, acres=?, "
78          + "gender=?, leader=?, networth=?, race=?, rank=?, personality=?, peasants=?, gold=?, food=?, runes=?, "
79          + "trade=?, thieves=?, wizards=?, soldiers=?, offspecs=?, defspecs=?, elites=?, horses=?, prisoners=?, "
80          + "offense=?, defense=? "
81          + "WHERE id=? "
82          + "AND last_update < ?";
83  
84      private static final String SELECT_SCIENCE = "SELECT id, province_id, last_update, alchemy, tools, housing, food, "
85          + " military, crime, channeling "
86          + "FROM science "
87          + "WHERE province_id=? ";
88      private static final String INSERT_SCIENCE = "INSERT INTO science(id, province_id, last_update, alchemy, tools, "
89          + " housing, food, military, crime, channeling) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
90      private static final String UPDATE_SCIENCE = "UPDATE science SET last_update=?, alchemy=?, tools=?, housing=?, "
91          + "food=?, military=?, crime=?, channeling=? "
92          + "WHERE id=? "
93          + "AND last_update < ? ";
94  
95      private static final String SELECT_SURVEY = "SELECT id, province_id, last_update, efficiency, barren, homes, farms, "
96          + "mills, banks, training_grounds, barracks, armories, forts, guard_stations, hospitals, guilds, towers, "
97          + "thief_dens, watchtowers, libraries, schools, stables, dungeons "
98          + "FROM survey "
99          + "WHERE province_id=?";
100     private static final String INSERT_SURVEY = "INSERT INTO survey(id, province_id, last_update, efficiency, barren, "
101         + "homes, farms, mills, banks, training_grounds, barracks, armories, forts, guard_stations, hospitals, guilds, "
102         + "towers, thief_dens, watchtowers, libraries, schools, stables, dungeons) "
103         + "VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
104     private static final String UPDATE_SURVEY = "UPDATE survey SET last_update=?, efficiency=?, barren=?, homes=?, "
105         + "farms=?, mills=?, banks=?, training_grounds=?, barracks=?, armories=?, forts=?, guard_stations=?, "
106         + "hospitals=?, guilds=?, towers=?, thief_dens=?, watchtowers=?, libraries=?, schools=?, stables=?, dungeons=? "
107         + "WHERE id=? "
108         + "AND last_update < ? ";
109 
110     private static final String SELECT_MILITARY = "SELECT id, province_id, last_update, offense, defense, raw_ind "
111         + "FROM military "
112         + "WHERE province_id=? ";
113     private static final String INSERT_MILITARY = "INSERT INTO military(id, province_id, last_update, offense, defense, "
114         + "raw_ind) VALUES(?, ?, ?, ?, ?, ?) ";
115     private static final String UPDATE_MILITARY = "UPDATE military SET last_update=?, offense=?, defense=?, raw_ind=? "
116         + "WHERE id=? "
117         + "AND last_update < ? ";
118     private static final String SELECT_ARMY = "SELECT id, military_id, generals, soldiers, offspecs, defspecs, elites, "
119         + "horses, spoils, eta "
120         + "FROM army "
121         + "WHERE military_id=? ";
122     private static final String INSERT_ARMY = "INSERT INTO army(id, military_id, generals, soldiers, offspecs, "
123         + "defspecs, elites, horses, spoils, eta) "
124         + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ";
125     private static final String DELETE_ARMIES = "DELETE FROM army WHERE military_id=? ";
126 
127     @Autowired
128     public DataSyncTemplate(DataSource ds) {
129         super(ds);
130     }
131 
132     public Kingdom getKingdom(int kingdom, int island) {
133         try {
134             return queryForObject(SELECT_KINGDOM, kingdomMapper, kingdom, island);
135         } catch (EmptyResultDataAccessException e) {
136             Kingdom k = new Kingdom(new Coordinate(kingdom, island));
137             Calendar update = CalendarUtils.getCalendar();
138             update.setTimeInMillis(0);
139             k.setLastUpdate(update);
140             return k;
141         }
142     }
143 
144     public Province getProvinceByName(String name) {
145         try {
146             return queryForObject(SELECT_PROVINCE_BY_NAME, provinceMapper, name);
147         } catch (EmptyResultDataAccessException e) {
148             Province province = new Province();
149             province.setName(name);
150             province.getLastUpdate().setTimeInMillis(0);
151             return province;
152         }
153     }
154 
155     public Kingdom getKingdomById(String id) {
156         return queryForObject(SELECT_KINGDOM_BY_ID, kingdomMapper, id);
157     }
158 
159     public List<Kingdom> getKingdomSyncList(Calendar lastUpdate) {
160         return query(SELECT_SYNC_KINGDOM, kingdomMapper, lastUpdate);
161     }
162 
163     public List<Province> getProvinceSyncList(Calendar lastUpdate) {
164         return query(SELECT_SYNC_PROVINCE, provinceMapper, lastUpdate, lastUpdate, lastUpdate, lastUpdate);
165     }
166 
167     public boolean updateKingdom(Kingdom kingdom) {
168         int updated = 0;
169         try {
170             queryForObject(EXISTS_KINGDOM, String.class, kingdom.getId());
171             updated = update(UPDATE_KINGDOM, kingdom.getLastUpdate(), kingdom.getName(), kingdom.getRelation().toString(),
172                     kingdom.getStance().toString(), kingdom.getWarCount(), kingdom.getWarWins(),
173                     kingdom.getWarNetworthDiff(), kingdom.getId(), kingdom.getLastUpdate());
174         } catch (EmptyResultDataAccessException e) {
175             updated = update(INSERT_KINGDOM, kingdom.getId(), kingdom.getLastUpdate(),
176                     kingdom.getLocation().getKingdom(), kingdom.getLocation().getIsland(), kingdom.getName(),
177                     kingdom.getRelation().toString(), kingdom.getStance().toString(), kingdom.getWarCount(),
178                     kingdom.getWarWins(), kingdom.getWarNetworthDiff());
179         }
180         return updated > 0;
181     }
182 
183     public boolean updateProvince(Province province) {
184         int updated = 0;
185         Coordinate coord = province.getCoordinate();
186         Calendar update = province.getLastUpdate();
187         Kingdom kingdom = getKingdom(coord.getKingdom(), coord.getIsland());
188         if (kingdom.getLastUpdate().getTimeInMillis() == 0) {
189             kingdom.setLastUpdate(province.getLastUpdate());
190             updateKingdom(kingdom);
191         }
192         try {
193             queryForObject(EXISTS_PROVINCE, String.class, province.getId());
194             updated = update(UPDATE_PROVINCE, kingdom.getId(), update, province.getName(), province.getAcres(),
195                     province.isGender(), province.getLeader(), province.getNetworth(), province.getRace().toString(),
196                     province.getRank().toString(), province.getPersonality().toString(), province.getPeasants(),
197                     province.getGold(), province.getFood(), province.getRunes(), province.getTradeBalance(),
198                     province.getThieves(), province.getWizards(), province.getSoldiers(), province.getOffspecs(),
199                     province.getDefspecs(), province.getElites(), province.getHorses(), province.getPrisoners(),
200                     province.getOffense(), province.getDefense(), province.getId(), update);
201         } catch (EmptyResultDataAccessException e) {
202             updated = update(INSERT_PROVINCE, province.getId(), kingdom.getId(), update, province.getName(),
203                     province.getAcres(), province.isGender(), province.getLeader(), province.getNetworth(),
204                     province.getRace().toString(), province.getRank().toString(), province.getPersonality().toString(),
205                     province.getPeasants(), province.getGold(), province.getFood(), province.getRunes(),
206                     province.getTradeBalance(), province.getThieves(), province.getWizards(), province.getSoldiers(),
207                     province.getOffspecs(), province.getDefspecs(), province.getElites(), province.getHorses(),
208                     province.getPrisoners(), province.getOffense(), province.getDefense());
209         }
210         return updated > 0;
211     }
212 
213     public boolean updateMilitary(Military military) {
214         int updated = 0;
215         String provinceId = military.getProvince().getId();
216         Calendar update = military.getLastUpdate();
217         try {
218             queryForObject(EXISTS_MILITARY, String.class, military.getId());
219             updated = update(UPDATE_MILITARY, update, military.getOffense(), military.getDefense(), military.isRaw(),
220                     military.getId(), update);
221         } catch (EmptyResultDataAccessException e) {
222             updated = update(INSERT_MILITARY, military.getId(), provinceId, update, military.getOffense(),
223                     military.getDefense(), military.isRaw());
224         }
225         update(DELETE_ARMIES, military.getId());
226         for (Army army : military.getArmies()) {
227             update(INSERT_ARMY, army.getId(), military.getId(), army.getGenerals(), army.getSoldiers(),
228                     army.getOffspecs(), army.getDefspecs(), army.getElites(), army.getHorses(), army.getSpoils(),
229                     army.getReturnTime());
230         }
231         return updated > 0;
232     }
233 
234     public boolean updateScience(Science science) {
235         int updated = 0;
236         String provinceId = science.getProvince().getId();
237         Calendar update = science.getLastUpdate();
238         try {
239             queryForObject(EXISTS_SCIENCE, String.class, science.getId());
240             updated = update(UPDATE_SCIENCE, update, science.getAlchemy(), science.getTools(), science.getHousing(),
241                     science.getFood(), science.getMilitary(), science.getCrime(), science.getChanneling(),
242                     science.getId(), update);
243         } catch (EmptyResultDataAccessException e) {
244             updated = update(INSERT_SCIENCE, science.getId(), provinceId, update, science.getAlchemy(),
245                     science.getTools(), science.getHousing(), science.getFood(), science.getMilitary(),
246                     science.getCrime(), science.getChanneling());
247         }
248         return updated > 0;
249     }
250 
251     public boolean updateSurvey(Survey survey) {
252         int updated = 0;
253         String provinceId = survey.getProvince().getId();
254         Calendar update = survey.getLastUpdate();
255         try {
256             queryForObject(EXISTS_SURVEY, String.class, survey.getId());
257             updated = update(UPDATE_SURVEY, update, survey.getEfficiency(), survey.getBarren(), survey.getHomes(),
258                     survey.getFarms(), survey.getMills(), survey.getBanks(), survey.getTrainingGrounds(),
259                     survey.getBarracks(), survey.getArmories(), survey.getForts(), survey.getGuardStations(),
260                     survey.getHospitals(), survey.getGuilds(), survey.getTowers(), survey.getThievesDens(),
261                     survey.getWatchtowers(), survey.getLibraries(), survey.getSchools(), survey.getStables(),
262                     survey.getDungeons(), survey.getId(), update);
263         } catch (EmptyResultDataAccessException e) {
264             updated = update(INSERT_SURVEY, survey.getId(), provinceId, update, survey.getEfficiency(),
265                     survey.getBarren(), survey.getHomes(), survey.getFarms(), survey.getMills(), survey.getBanks(),
266                     survey.getTrainingGrounds(), survey.getBarracks(), survey.getArmories(), survey.getForts(),
267                     survey.getGuardStations(), survey.getHospitals(), survey.getGuilds(), survey.getTowers(),
268                     survey.getThievesDens(), survey.getWatchtowers(), survey.getLibraries(), survey.getSchools(),
269                     survey.getStables(), survey.getDungeons());
270         }
271         return updated > 0;
272     }
273     
274     private Calendar getCalendar(Timestamp ts) {
275         Calendar time = CalendarUtils.getCalendar();
276         time.setTimeInMillis(ts.getTime());
277         return time;
278     }
279 
280     private ParameterizedRowMapper<Kingdom> kingdomMapper = new ParameterizedRowMapper<Kingdom>() {
281         public Kingdom mapRow(ResultSet rs, int rowNum) throws SQLException {
282             Coordinate coord = new Coordinate();
283             coord.setKingdom(rs.getInt("kingdom"));
284             coord.setIsland(rs.getInt("island"));
285             Kingdom kingdom = new Kingdom(coord);
286             kingdom.setId(rs.getString("id"));
287             kingdom.setLastUpdate(getCalendar(rs.getTimestamp("last_update")));
288             kingdom.setName(rs.getString("name"));
289             kingdom.setRelation(Relation.valueOf(rs.getString("relation")));
290             kingdom.setStance(Stance.valueOf(rs.getString("stance")));
291             kingdom.setWarCount(rs.getInt("war_count"));
292             kingdom.setWarWins(rs.getInt("war_win"));
293             kingdom.setWarNetworthDiff(rs.getInt("war_nwdiff"));
294             return kingdom;
295         }
296     };
297 
298     private ParameterizedRowMapper<Province> provinceMapper = new ParameterizedRowMapper<Province>() {
299         public Province mapRow(ResultSet rs, int rowNum) throws SQLException {
300             Kingdom kingdom = getKingdomById(rs.getString("kingdom_id"));
301             Province province = new Province(rs.getString("name"), kingdom.getLocation());
302             province.setId(rs.getString("id"));
303             province.setKingdomId(rs.getString("kingdom_id"));
304             Timestamp timestamp = rs.getTimestamp("last_update");
305             province.getLastUpdate().setTimeInMillis(timestamp.getTime());
306             province.setAcres(rs.getInt("acres"));
307             province.setGender(rs.getBoolean("gender"));
308             province.setName(rs.getString("name"));
309             province.setLeader(rs.getString("leader"));
310             province.setNetworth(rs.getInt("networth"));
311             province.setRace(Race.valueOf(rs.getString("race")));
312             province.setRank(Rank.valueOf(rs.getString("rank")));
313             province.setPersonality(Personality.valueOf(rs.getString("personality")));
314             province.setPeasants(rs.getInt("peasants"));
315             province.setGold(rs.getInt("gold"));
316             province.setFood(rs.getInt("food"));
317             province.setRunes(rs.getInt("runes"));
318             province.setTradeBalance(rs.getInt("trade"));
319             province.setThieves(rs.getInt("thieves"));
320             province.setWizards(rs.getInt("wizards"));
321             province.setSoldiers(rs.getInt("soldiers"));
322             province.setOffspecs(rs.getInt("offspecs"));
323             province.setDefspecs(rs.getInt("defspecs"));
324             province.setElites(rs.getInt("elites"));
325             province.setHorses(rs.getInt("horses"));
326             province.setPrisoners(rs.getInt("prisoners"));
327             province.setOffense(rs.getInt("offense"));
328             province.setDefense(rs.getInt("defense"));
329 
330             try {
331                 Science science = queryForObject(SELECT_SCIENCE, scienceMapper, province.getId());
332                 science.setProvince(province);
333                 province.setScience(science);
334             } catch (EmptyResultDataAccessException ignore) {
335                 province.getScience().getLastUpdate().setTimeInMillis(0);
336             }
337 
338             try {
339                 Survey survey = queryForObject(SELECT_SURVEY, surveyMapper, province.getId());
340                 survey.setProvince(province);
341                 province.setSurvey(survey);
342             } catch (EmptyResultDataAccessException ignore) {
343                 province.getSurvey().getLastUpdate().setTimeInMillis(0);
344             }
345 
346             try {
347                 Military military = queryForObject(SELECT_MILITARY, militaryMapper, province.getId());
348                 military.setProvince(province);
349                 province.setMilitary(military);
350             } catch (EmptyResultDataAccessException ignore) {
351                 province.getMilitary().getLastUpdate().setTimeInMillis(0);
352             }
353 
354             return province;
355         }
356     };
357 
358     private ParameterizedRowMapper<Army> armyMapper = new ParameterizedRowMapper<Army>() {
359         public Army mapRow(ResultSet rs, int rowNum) throws SQLException {
360             Army army = new Army();
361             army.setId(rs.getString("id"));
362             army.setGenerals(rs.getInt("generals"));
363             army.getReturnTime().setTimeInMillis(rs.getTimestamp("eta").getTime());
364             army.setSoldiers(rs.getInt("soldiers"));
365             army.setOffspecs(rs.getInt("offspecs"));
366             army.setDefspecs(rs.getInt("defspecs"));
367             army.setElites(rs.getInt("elites"));
368             army.setHorses(rs.getInt("horses"));
369             army.setSpoils(rs.getInt("spoils"));
370             return army;
371         }
372     };
373 
374     private ParameterizedRowMapper<Military> militaryMapper = new ParameterizedRowMapper<Military>() {
375         public Military mapRow(ResultSet rs, int rowNum) throws SQLException {
376             Military military = new Military();
377             military.setId(rs.getString("id"));
378             military.getLastUpdate().setTimeInMillis(rs.getTimestamp("last_update").getTime());
379             military.setOffense(rs.getInt("offense"));
380             military.setDefense(rs.getInt("defense"));
381             military.setRaw(rs.getBoolean("raw_ind"));
382             military.setArmies(query(SELECT_ARMY, armyMapper, military.getId()));
383             for (Army army : military.getArmies()) {
384                 army.setMilitary(military);
385             }
386             return military;
387         }
388     };
389 
390     private ParameterizedRowMapper<Science> scienceMapper = new ParameterizedRowMapper<Science>() {
391         public Science mapRow(ResultSet rs, int rowNum) throws SQLException {
392             Science science = new Science();
393             science.setId(rs.getString("id"));
394             science.getLastUpdate().setTimeInMillis(rs.getTimestamp("last_update").getTime());
395             science.setAlchemy(rs.getInt("alchemy"));
396             science.setTools(rs.getInt("tools"));
397             science.setHousing(rs.getInt("housing"));
398             science.setFood(rs.getInt("food"));
399             science.setMilitary(rs.getInt("military"));
400             science.setCrime(rs.getInt("crime"));
401             science.setChanneling(rs.getInt("channeling"));
402             return science;
403         }
404     };
405 
406     private ParameterizedRowMapper<Survey> surveyMapper = new ParameterizedRowMapper<Survey>() {
407         public Survey mapRow(ResultSet rs, int rowNum) throws SQLException {
408             Survey survey = new Survey();
409             survey.setId(rs.getString("id"));
410             survey.getLastUpdate().setTimeInMillis(rs.getTimestamp("last_update").getTime());
411             survey.setEfficiency(rs.getFloat("efficiency"));
412             survey.setBarren(rs.getInt("barren"));
413             survey.setHomes(rs.getInt("homes"));
414             survey.setFarms(rs.getInt("farms"));
415             survey.setMills(rs.getInt("mills"));
416             survey.setBanks(rs.getInt("banks"));
417             survey.setTrainingGrounds(rs.getInt("training_grounds"));
418             survey.setBarracks(rs.getInt("barracks"));
419             survey.setArmories(rs.getInt("armories"));
420             survey.setForts(rs.getInt("forts"));
421             survey.setGuardStations(rs.getInt("guard_stations"));
422             survey.setHospitals(rs.getInt("hospitals"));
423             survey.setGuilds(rs.getInt("guilds"));
424             survey.setTowers(rs.getInt("towers"));
425             survey.setThievesDens(rs.getInt("thief_dens"));
426             survey.setWatchtowers(rs.getInt("watchtowers"));
427             survey.setLibraries(rs.getInt("libraries"));
428             survey.setSchools(rs.getInt("schools"));
429             survey.setStables(rs.getInt("stables"));
430             survey.setDungeons(rs.getInt("dungeons"));
431             return survey;
432         }
433     };
434 }