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