1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package p3j.database.hibernate;
17
18 import james.SimSystem;
19 import james.core.data.DBConnectionData;
20 import james.core.util.StopWatch;
21
22 import java.sql.Connection;
23 import java.sql.DriverManager;
24 import java.sql.SQLException;
25 import java.util.ArrayList;
26 import java.util.List;
27 import java.util.logging.Level;
28
29 import org.hibernate.SessionFactory;
30 import org.hibernate.Transaction;
31 import org.hibernate.cfg.Configuration;
32 import org.hibernate.classic.Session;
33 import org.hibernate.criterion.Order;
34 import org.hibernate.criterion.Restrictions;
35 import org.hibernate.tool.hbm2ddl.SchemaExport;
36
37 import p3j.database.IP3MDatabase;
38 import p3j.database.IProjectionResultsIterator;
39 import p3j.experiment.results.ResultsOfTrial;
40 import p3j.misc.MatrixDimension;
41 import p3j.misc.Misc;
42 import p3j.misc.math.Matrix;
43 import p3j.misc.math.Matrix2D;
44 import p3j.pppm.ProjectionModel;
45 import p3j.pppm.parameters.Parameter;
46 import p3j.pppm.parameters.ParameterAssignment;
47 import p3j.pppm.parameters.ParameterInstance;
48 import p3j.pppm.parameters.Parameters;
49 import p3j.pppm.parameters.Population;
50 import p3j.pppm.sets.Set;
51 import p3j.pppm.sets.SetType;
52
53
54
55
56
57
58
59
60
61
62 public class P3MDatabase implements IP3MDatabase {
63
64
65 private static String hibernateConfigFile = Misc.DEFAULT_HIBERNATE_CONFIG_FILE;
66
67
68 private static final int DEFAULT_FLUSH_FREQ = 50;
69
70
71 private boolean alwaysFlush = true;
72
73
74 private Configuration config;
75
76
77 private SessionFactory sessionFactory;
78
79
80 private Session session;
81
82
83 private Session resultStorageSession;
84
85
86 private int resultStorageCounter;
87
88
89
90
91
92 private int resultStorageFlushFrequency = DEFAULT_FLUSH_FREQ;
93
94
95
96
97 public P3MDatabase() {
98 this(P3MDatabase.hibernateConfigFile);
99 }
100
101
102
103
104
105
106
107 public P3MDatabase(String configurationFile) {
108 config = new Configuration().configure(configurationFile);
109 }
110
111 @Override
112 public void init(DBConnectionData dbConn) {
113 config.setProperty("hibernate.connection.username", dbConn.getUser())
114 .setProperty("hibernate.connection.password", dbConn.getPassword())
115 .setProperty("hibernate.connection.url", dbConn.getUrl());
116 sessionFactory = config.buildSessionFactory();
117 }
118
119 @Override
120 public void open() {
121 if (session == null) {
122 session = sessionFactory.openSession();
123 }
124 }
125
126 @Override
127 public void clear() {
128 SimSystem.report(Level.INFO, "CLEARING DB...");
129 SchemaExport export = new SchemaExport(config);
130 export.create(true, true);
131 }
132
133 @Override
134 public void close() {
135 if (session != null) {
136 session.close();
137 }
138 if (sessionFactory != null) {
139 sessionFactory.close();
140 }
141 }
142
143
144
145
146 protected void dbChanged() {
147 if (alwaysFlush) {
148 session.flush();
149 }
150 }
151
152
153
154
155
156
157
158 public void save(Object o) {
159 Transaction t = session.beginTransaction();
160 session.save(o);
161 t.commit();
162 dbChanged();
163 }
164
165
166
167
168
169
170
171 public void delete(Object o) {
172 Transaction t = session.beginTransaction();
173 session.delete(o);
174 t.commit();
175 dbChanged();
176 }
177
178
179
180 @Override
181 public Parameter newParameter(String name, boolean genDep,
182 MatrixDimension height, MatrixDimension width, Population population) {
183 Parameter param = getParameter(name);
184 if (param == null) {
185 param = new Parameter(-1, genDep, name, height, width, population);
186 save(param);
187 }
188 return param;
189 }
190
191 @Override
192 public Parameter getParameter(String name) {
193 List<Parameter> parameters = Misc.autoCast(session.createQuery(
194 "from Parameter where name='" + name + "'").list());
195 if (parameters.size() > 1) {
196 throw new ConstraintException(
197 "Ambiguity: there are two parameters with the same name '" + name
198 + "'");
199 }
200 if (parameters.size() == 1) {
201 return parameters.get(0);
202 }
203 return null;
204 }
205
206 @Override
207 public List<Parameter> getAllParameters() {
208 List<Parameter> parameters = Misc.autoCast(session.createQuery(
209 "from Parameter").list());
210 return parameters;
211 }
212
213 @Override
214 public boolean deleteParameter(Parameter parameter) {
215 delete(parameter);
216 return true;
217 }
218
219
220
221 @Override
222 public ParameterInstance newParameterInstance(int comparisonIndex,
223 Parameter param, int generation) {
224 ParameterInstance instance = getParameterInstance(param, generation);
225 if (instance == null) {
226 instance = new ParameterInstance(comparisonIndex, param, generation);
227 save(instance);
228 }
229 return instance;
230 }
231
232 @Override
233 public ParameterInstance getParameterInstance(Parameter param, int generation) {
234 List<ParameterInstance> instances = Misc.autoCast(session
235 .createCriteria(ParameterInstance.class)
236 .add(Restrictions.eq("parameter", param))
237 .add(Restrictions.eq("generation", generation)).list());
238 if (instances.size() > 1) {
239 throw new ConstraintException(
240 "Ambiguity: there are two parameter instances for parameter '"
241 + param.getName() + "' and generation " + generation);
242 }
243 if (instances.size() == 1) {
244 return instances.get(0);
245 }
246 return null;
247 }
248
249 @Override
250 public List<ParameterInstance> getAllParameterInstances() {
251 List<ParameterInstance> instances = Misc.autoCast(session.createQuery(
252 "from ParameterInstance").list());
253 return instances;
254 }
255
256 @Override
257 public boolean deleteParameterInstance(ParameterInstance instance) {
258 delete(instance);
259 return true;
260 }
261
262
263
264 @Override
265 public Matrix newMatrix(Matrix2D value) {
266 Matrix matrix = getMatrix(value);
267 if (matrix == null) {
268 matrix = new Matrix(value);
269 save(matrix);
270 }
271 return matrix;
272 }
273
274 @Override
275 public Matrix getMatrix(Matrix2D value) {
276 List<Matrix> matrices = Misc
277 .autoCast(session.createCriteria(Matrix.class)
278 .add(Restrictions.eq("hash", Matrix2D.calculateHashCode(value)))
279 .list());
280 List<Matrix> equalMatrices = new ArrayList<Matrix>();
281 for (Matrix matrix : matrices) {
282 if (matrix.getValue().equals(value)) {
283 equalMatrices.add(matrix);
284 }
285 }
286 if (equalMatrices.size() == 1) {
287 return equalMatrices.get(0);
288 }
289 return null;
290 }
291
292 @Override
293 public List<Matrix> getAllMatrices() {
294 List<Matrix> matrices = Misc.autoCast(session.createQuery("from Matrix")
295 .list());
296 return matrices;
297 }
298
299 @Override
300 public boolean deleteMatrix(Matrix matrix) {
301 delete(matrix);
302 return true;
303 }
304
305
306
307 @Override
308 public ParameterAssignment newParameterAssignment(
309 ParameterInstance paramInstance, String name, String description,
310 double probability, double deviation, Matrix2D value) {
311 Matrix matrix = newMatrix(value);
312 ParameterAssignment assignment = new ParameterAssignment(paramInstance,
313 name, description, probability, deviation, matrix);
314 save(assignment);
315 return assignment;
316 }
317
318 @Override
319 public List<ParameterAssignment> getAllParameterAssignments(
320 ParameterInstance param) {
321 List<ParameterAssignment> assignments = Misc.autoCast(session
322 .createCriteria(ParameterAssignment.class)
323 .add(Restrictions.eq("paramInstance", param)).list());
324 return assignments;
325 }
326
327 @Override
328 public boolean deleteParameterAssignment(ParameterAssignment assignment) {
329 delete(assignment);
330 return true;
331 }
332
333 @Override
334 public void saveParameterAssignment(ParameterAssignment assignment) {
335 save(assignment);
336 }
337
338
339
340 @Override
341 public Set newSet(List<ParameterInstance> defParams, String name,
342 String desc, double prob) {
343 Set set = new Set(defParams, name, desc, prob);
344 save(set);
345 return set;
346 }
347
348 @Override
349 public void saveSet(Set set) {
350 save(set);
351 }
352
353 @Override
354 public List<Set> getAllSets() {
355 return Misc.autoCast(session.createCriteria(Set.class).list());
356 }
357
358 @Override
359 public boolean deleteSet(Set set) {
360 delete(set);
361 return true;
362 }
363
364
365
366 @Override
367 public SetType newSetType(String name, String description) {
368 SetType setType = new SetType(name, description);
369 save(setType);
370 return setType;
371 }
372
373 @Override
374 public List<SetType> getAllSetTypes() {
375 List<SetType> setTypes = Misc.autoCast(session
376 .createCriteria(SetType.class).list());
377 return setTypes;
378 }
379
380 @Override
381 public void saveSetType(SetType setType) {
382 save(setType);
383 }
384
385 @Override
386 public boolean deleteSeType(SetType setType) {
387 delete(setType);
388 return true;
389 }
390
391
392
393 @Override
394 public void newProjection(ProjectionModel projection) {
395
396 List<Parameter> parameters = Parameters.getInstance().getParams();
397 List<ParameterInstance> allInstances = projection
398 .getAllParameterInstances();
399 int comparisonIndex = 0;
400 for (int j = 0; j < projection.getGenerations(); j++) {
401 for (int i = 0; i < parameters.size(); i++) {
402 Parameter parameter = parameters.get(i);
403 if (parameter.isGenerationDependent()) {
404 allInstances
405 .add(newParameterInstance(++comparisonIndex, parameter, j));
406 } else if (j == 0) {
407 allInstances.add(newParameterInstance(++comparisonIndex, parameter,
408 -1));
409 }
410 }
411 }
412 projection.init();
413 save(projection);
414 }
415
416 @Override
417 public boolean deleteProjection(ProjectionModel projection) {
418 delete(projection);
419 return true;
420 }
421
422 @Override
423 public List<ProjectionModel> getAllProjections() {
424 List<ProjectionModel> projections = Misc.autoCast(session.createQuery(
425 "from ProjectionModel").list());
426 return projections;
427 }
428
429 @Override
430 public ProjectionModel getProjectionByID(int id) {
431 List<ProjectionModel> pModels = Misc.autoCast(session
432 .createCriteria(ProjectionModel.class).add(Restrictions.eq("ID", id))
433 .list());
434 if (pModels.size() > 1) {
435 throw new ConstraintException(
436 "DB consistency: Two duplicate projection models with the same ID '"
437 + id + "' !");
438 }
439 if (pModels.size() == 1) {
440 return pModels.get(0);
441 }
442 return null;
443 }
444
445 @Override
446 public void saveProjection(ProjectionModel projection) {
447 save(projection);
448 }
449
450
451
452
453
454
455
456
457
458 public static Exception testConnection(DBConnectionData dbConnData) {
459 Connection c = null;
460 try {
461 c = DriverManager.getConnection(dbConnData.getUrl(),
462 dbConnData.getUser(), dbConnData.getPassword());
463 if (c == null) {
464 throw new IllegalArgumentException(
465 "Connection created by driver manager is null.");
466 }
467 } catch (Exception ex) {
468 return ex;
469 } finally {
470 try {
471 if (c != null) {
472 c.close();
473 }
474 } catch (SQLException e) {
475 return e;
476 }
477 }
478 return null;
479 }
480
481
482
483
484
485
486
487
488
489
490
491
492
493 public static Exception testConnection(String dbURL, String dbUserName,
494 String dbPassword) {
495 return testConnection(new DBConnectionData(dbURL, dbUserName, dbPassword,
496 null));
497 }
498
499 @Override
500 public synchronized void saveTrialResults(ResultsOfTrial resultOfTrial) {
501 if (resultStorageSession == null) {
502 resultStorageSession = sessionFactory.openSession();
503 }
504 StopWatch sw = new StopWatch();
505 sw.start();
506 Transaction resultStorageTransaction = resultStorageSession
507 .beginTransaction();
508 resultStorageSession.save(resultOfTrial);
509 resultStorageTransaction.commit();
510 resultStorageCounter++;
511 if (resultStorageCounter % resultStorageFlushFrequency == 0) {
512 resultStorageSession.flush();
513 resultStorageSession.clear();
514 }
515 sw.stop();
516 SimSystem.report(Level.INFO,
517 "Time for result storage in database:" + sw.elapsedMilliseconds());
518 }
519
520 @Override
521 public List<ResultsOfTrial> getAllResults(ProjectionModel projection) {
522 List<ResultsOfTrial> results = Misc.autoCast(session
523 .createCriteria(ResultsOfTrial.class)
524 .add(Restrictions.eq("projection", projection))
525 .addOrder(Order.asc("ID")).list());
526 return results;
527 }
528
529 @Override
530 public void deleteResult(ResultsOfTrial resultOfTrial) {
531 delete(resultOfTrial);
532 }
533
534 @Override
535 public void deleteAllResults(ProjectionModel projection) {
536 Transaction t = session.beginTransaction();
537 for (ResultsOfTrial results : getAllResults(projection)) {
538 session.delete(results);
539 }
540 t.commit();
541 dbChanged();
542 }
543
544 @Override
545 public IProjectionResultsIterator getResultIterator(ProjectionModel projection) {
546 return new ProjectionResultsIterator(sessionFactory, projection.getID());
547 }
548
549 @Override
550 public void clearCache(Object o) {
551 session.evict(o);
552 session.flush();
553 }
554
555
556
557
558
559
560 public static String getHibernateConfigFile() {
561 return hibernateConfigFile;
562 }
563
564
565
566
567
568
569
570 public static void setHibernateConfigFile(String hibernateConfigFile) {
571 P3MDatabase.hibernateConfigFile = hibernateConfigFile;
572 }
573 }