View Javadoc
1   /******************************************************************************
2    * DatabaseImpl.java - Implement the BuckoFIBS database API.
3    * $Id$
4    * 
5    * BuckoFIBS - Backgammon by BuckoSoft
6    * Copyright© 2009,2010 - Dick Balaska - BuckoSoft, Corp.
7    * 
8    * $Log$
9    * Revision 1.11  2011/05/10 05:47:41  dick
10   * Always set the groupId when storing a PlayerGroup.
11   *
12   * Revision 1.10  2011/05/09 17:09:39  dick
13   * HibernateUtil goes from static to an object, so that during test we can keep
14   * reinstantiating it.
15   *
16   * Revision 1.9  2011/05/08 21:41:40  dick
17   * Add support for a test (in memory) database.
18   *
19   * Revision 1.8  2011/01/01 20:28:56  dick
20   * Add some debug for groups.
21   *
22   * Revision 1.7  2011/01/01 02:32:43  dick
23   * Manging GroupOfPlayers and PlayerGroups satisfactorily.
24   *
25   * Revision 1.6  2011/01/01 01:26:57  dick
26   * Load the PlayerGroups
27   *
28   * Revision 1.5  2010/12/31 05:29:25  dick
29   * Add support for reading and writing GroupOfPlayers.
30   *
31   * Revision 1.4  2010/12/24 02:59:42  dick
32   * WinLoss becomes a light object instead of a String.
33   *
34   * Revision 1.3  2010/03/03 13:12:21  inim
35   * Replaced (c) sign in comment mangled by CVS default encoding back to UTF-8
36   *
37   * Revision 1.2  2010/03/03 12:19:48  inim
38   * Moved source to UTF8 encoding from CP1252 encoding. To this end all source files' (c) message was updated to "Copyright© 2009,2010 - Dick Balaska - BuckoSoft, Corp.". This replaces the (c) sign to UTF8, and adds the new year 2010.
39   *
40   * Revision 1.1  2010/02/04 05:57:53  inim
41   * Mavenized project folder layout
42   *
43   * Revision 1.6  2010/01/29 23:07:08  dick
44   * Remove aborted RatingGraphConfig, it's a properties object.
45   *
46   * Revision 1.5  2010/01/27 02:09:37  dick
47   * Preliminary RatingGraphConfig work.
48   *
49   * Revision 1.4  2010/01/23 06:16:06  dick
50   * Update finishedMatches for an opponent.
51   *
52   * Revision 1.3  2009/03/04 19:01:58  dick
53   * Add getFinishedMatches(pid).
54   *
55   * Revision 1.2  2009/02/21 18:00:01  dick
56   * Add getAllRatingsByDate()
57   *
58   * Revision 1.1  2009/02/20 10:24:33  dick
59   * Implement the BuckoFIBS database API.
60   *
61   */
62  
63  /* 
64   * This program is free software: you can redistribute it and/or modify
65   * it under the terms of the GNU General Public License as published by
66   * the Free Software Foundation, either version 3 of the License, or
67   * (at your option) any later version.
68   *
69   * This program is distributed in the hope that it will be useful,
70   * but WITHOUT ANY WARRANTY; without even the implied warranty of
71   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
72   * GNU General Public License for more details.
73   *
74   * You should have received a copy of the GNU General Public License
75   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
76   *
77   * The Original Code is BuckoFIBS, <http://www.buckosoft.com/BuckoFIBS/>.
78   * The Initial Developer of the Original Code is Dick Balaska and BuckoSoft, Corp.
79   */
80  
81  package com.buckosoft.fibs.BuckoFIBS.db;
82  
83  import java.util.Iterator;
84  import java.util.LinkedList;
85  import java.util.List;
86  
87  import org.hibernate.Session;
88  import org.slf4j.Logger;
89  import org.slf4j.LoggerFactory;
90  
91  import com.buckosoft.fibs.domain.FinishedMatch;
92  import com.buckosoft.fibs.domain.GroupOfPlayers;
93  import com.buckosoft.fibs.domain.Player;
94  import com.buckosoft.fibs.domain.PlayerGroup;
95  
96  /** Implement the BuckoFIBS database API.
97   * @author Dick Balaska
98   * @since 2009/02/18
99   * @version $Revision$ <br> $Date$
100  * @see <a href="http://cvs.buckosoft.com/Projects/BuckoFIBS/BuckoFIBS/src/main/java/com/buckosoft/fibs/BuckoFIBS/db/DatabaseImpl.java">cvs DatabaseImpl.java</a>
101  */
102 public class DatabaseImpl implements Database {
103 	private	final static boolean DEBUG = false;
104     private Logger logger = LoggerFactory.getLogger(getClass());
105 
106 	private boolean	virgin = true;
107 	
108 	private	List<FinishedMatch>	finishedMatches;
109 	private String	url = null;
110 	private	int		activeProfile = 0;
111 	
112 	HibernateUtil	hibernateUtil;
113 
114 	public DatabaseImpl() {
115 		hibernateUtil = new HibernateUtil();
116 	}
117 
118 	/** Set the URL we use to connect to the database.
119 	 * Not really an URL, more of a token to select an internal URL to use.
120 	 * @param url The test harness sets this to "mem" to use an in-memory database.
121 	 */
122 	public void setURL(String url) {
123 		this.url = url;
124 	}
125 
126 	public void setActiveProfile(int activeProfile) {
127 		this.activeProfile = activeProfile;
128 		this.finishedMatches = null;			// force to re-read the finishedMatches
129 	}
130 
131 	private void initDB() {
132 		if (virgin)
133 			hibernateUtil.maybeCreateNewDatabase(url);
134 		virgin = false;
135 	}
136 	public void shutdown() {
137 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
138 		session.close();
139 	}
140 	/* (non-Javadoc)
141 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#store(com.buckosoft.fibs.domain.Player)
142 	 */
143 	@Override
144 	public void store(Player player) {
145 		initDB();
146 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
147 		session.beginTransaction();
148 		session.save(player);
149 		session.getTransaction().commit();
150 
151 	}
152 
153 	/* (non-Javadoc)
154 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#getPlayer(int)
155 	 */
156 	@Override
157 	public Player getPlayer(int id) {
158 		initDB();
159 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
160 		session.beginTransaction();
161 		Player p = null;
162 		try {
163 			p = (Player)session.createQuery("from Player where id = ?")
164 					.setInteger(0, id).uniqueResult();
165 		} catch (Exception e) {
166 			e.printStackTrace();
167 			return(null);
168 		}
169 		session.getTransaction().commit();
170 		return p;
171 	}
172 
173 	/* (non-Javadoc)
174 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#getPlayer(java.lang.String)
175 	 */
176 	@Override
177 	public Player getPlayer(String name) {
178 		initDB();
179 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
180 		session.beginTransaction();
181 		Player p = null;
182 		try {
183 			p = (Player)session.createQuery("from Player where name = ?")
184 					.setString(0, name).uniqueResult();
185 		} catch (Exception e) {
186 			e.printStackTrace();
187 			return(null);
188 		}
189 		session.getTransaction().commit();
190 		return p;
191 	}
192 
193 	/* (non-Javadoc)
194 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#store(com.buckosoft.fibs.domain.FinishedMatch)
195 	 */
196 	@Override
197 	public void store(FinishedMatch finishedMatch) {
198 		finishedMatch.setProfileId(this.activeProfile);
199 		initDB();
200 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
201 		session.beginTransaction();
202 		session.save(finishedMatch);
203 		session.getTransaction().commit();
204 		this.finishedMatches = null;
205 	}
206 
207 	@SuppressWarnings("unchecked")
208 	private	void getFinishedMatches() {
209 		initDB();
210 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
211 		session.beginTransaction();
212 		List<?> list = session.createQuery("from FinishedMatch where profileId = ? ORDER BY MatchDate")
213 						.setInteger(0, this.activeProfile).list();
214 		finishedMatches = (List<FinishedMatch>) list;
215 		session.getTransaction().commit();
216 	}
217 
218 	/* (non-Javadoc)
219 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#getAllRatingsByDate()
220 	 */
221 	@Override
222 	public double[] getAllRatingsByDate() {
223 		if (this.finishedMatches == null)
224 			getFinishedMatches();
225 		double[] dd = new double[this.finishedMatches.size()];
226 		int i = 0;
227 		for (FinishedMatch fm : this.finishedMatches) {
228 			dd[i++] = fm.getRatingAfterMatch();
229 		}
230 		return dd;
231 	}
232 
233 	/* (non-Javadoc)
234 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#updateOpponent(com.buckosoft.fibs.domain.Player)
235 	 */
236 	@Override
237 	public void updateOpponent(Player p) {
238 		if (this.finishedMatches == null)
239 			getFinishedMatches();
240 		if (p.getId() == 0) {
241 			Player p1 = this.getPlayer(p.getName());
242 			if (p1 != null)
243 				p.setId(p1.getId());
244 			else
245 				return;
246 		}
247 		int w = 0;
248 		int l = 0;
249 		for (FinishedMatch fm : this.finishedMatches) {
250 			if (fm.getOpponentId() == p.getId()) {
251 				if (fm.getYourScore() > fm.getOpponentScore())
252 					w++;
253 				else
254 					l++;
255 			}
256 		}
257 		if (w != 0 || l != 0)
258 			p.setWinLoss(w, l);
259 	}
260 
261 	/* (non-Javadoc)
262 	 * @see com.buckosoft.fibs.BuckoFIBS.db.Database#getFinishedMatches(int)
263 	 */
264 	@Override
265 	public List<FinishedMatch> getFinishedMatches(int pid) {
266 		List<FinishedMatch> matches = new LinkedList<FinishedMatch>();
267 		if (this.finishedMatches == null)
268 			getFinishedMatches();
269 		if (this.finishedMatches == null)
270 			return(matches);
271 		for (FinishedMatch fm : this.finishedMatches) {
272 			if (fm.getOpponentId() == pid)
273 				matches.add(fm);
274 		}
275 		return(matches);
276 	}
277 
278 	@SuppressWarnings("unchecked")
279 	public	List<GroupOfPlayers> getGroupsOfPlayers() {
280 		initDB();
281 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
282 		session.beginTransaction();
283 		List<?> list = session.createQuery("from GroupOfPlayers").list();
284 		List<GroupOfPlayers> ll = (List<GroupOfPlayers>) list;
285 		for (GroupOfPlayers gop : ll) {
286 			loadPlayerGroups(gop);
287 			gop.setDirty(false);
288 		}
289 		session.getTransaction().commit();
290 		return(ll);
291 	}
292 
293 	@SuppressWarnings("unchecked")
294 	private void loadPlayerGroups(GroupOfPlayers groupOfPlayers) {
295 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
296 		List<?> list = session.createQuery("from PlayerGroup where groupId = ?").setInteger(0, groupOfPlayers.getId()).list();
297 		List<PlayerGroup> lpg = (List<PlayerGroup>)list;
298 		for (PlayerGroup pg : lpg) {
299 			if (DEBUG)
300 				logger.info("load PlayerGroup: id: " + pg.getId() + " gid: " + pg.getGroupId() + " pid: " + pg.getPlayerId());
301 			pg.setDirty(false);
302 		}
303 		groupOfPlayers.setPlayerGroups(lpg);
304 	}
305 
306 	@SuppressWarnings("unchecked")
307 	public void store(List<GroupOfPlayers> groupList) {
308 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
309 		session.beginTransaction();
310 		for (GroupOfPlayers gop : groupList) {
311 			if (gop.isDirty()) {
312 				store(gop);
313 				gop.setDirty(false);
314 			}
315 		}
316 		session.flush();
317 		if (DEBUG) {
318 			List<?> list = session.createQuery("from PlayerGroup ").list();
319 			List<PlayerGroup> lpg = (List<PlayerGroup>)list;
320 			for (PlayerGroup pg : lpg) {
321 				logger.info("store PlayerGroup: id: " + pg.getId() + " gid: " + pg.getGroupId() + " pid: " + pg.getPlayerId());
322 			}
323 		}
324 		session.getTransaction().commit();
325 	}
326 
327 	private void store(GroupOfPlayers groupOfPlayers) {
328 		Session session = hibernateUtil.getSessionFactory().getCurrentSession();
329 		if (DEBUG)
330 			logger.info("db: Store=" + groupOfPlayers.getGroupName());
331 		session.saveOrUpdate(groupOfPlayers);
332 		Iterator<PlayerGroup> iter = groupOfPlayers.getPlayerGroups().iterator();
333 		while (iter.hasNext()) {
334 			PlayerGroup pg = iter.next();
335 			if (pg.isTagForDelete()) {
336 				session.delete(pg);
337 				iter.remove();
338 			} else if (pg.isDirty()) {
339 				pg.setGroupId(groupOfPlayers.getId());
340 				session.save(pg);
341 				pg.setDirty(false);
342 			}
343 		}
344 	}
345 }