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