1 package org.bitrepository.service.database;
2
3 import java.sql.Connection;
4 import java.sql.SQLException;
5
6 import org.bitrepository.settings.referencesettings.DatabaseSpecifics;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9
10
11
12
13
14
15
16
17
18
19
20 public abstract class DatabaseManager {
21 private Logger log = LoggerFactory.getLogger(getClass());
22 private static final String derbyDriver = "org.apache.derby.jdbc.EmbeddedDriver";
23 private static final String postgressDriver = "org.postgresql.Driver";
24 protected DBConnector connector = null;
25
26
27
28
29
30
31
32 public DBConnector getConnector() {
33 DatabaseSpecifics ds = getDatabaseSpecifics();
34 if(ds.getDriverClass().equals(derbyDriver)) {
35 return getDerbyConnection();
36 } else if(ds.getDriverClass().equals(postgressDriver)) {
37 return getPostgresConnection();
38 } else {
39 throw new IllegalStateException("The database driver: '" + ds.getDriverClass() + "' is not supported."
40 + " Supported drivers are: '" + derbyDriver + "' and '" + postgressDriver + "'.");
41 }
42
43
44 }
45
46
47
48
49
50
51
52 private DBConnector getPostgresConnection() {
53 if(connector == null) {
54 obtainConnection();
55 }
56 if(needsMigration()) {
57 throw new IllegalStateException("Automatic migration of postgres databases are not supported. "+
58 "The database on: " + getDatabaseSpecifics().getDatabaseURL() +
59 " needs manuel migration.");
60 }
61
62 return connector;
63 }
64
65
66
67
68
69
70 private DBConnector getDerbyConnection() {
71 if(connector == null) {
72 try {
73 obtainConnection();
74 } catch (IllegalStateException e) {
75 if(allowAutoCreate()) {
76 log.warn("Failed to connect to database, attempting to create it");
77 createDatabase();
78 } else {
79 log.error("Failed to connect to database, autocreation is disabled");
80 throw e;
81 }
82 }
83 if(connector == null) {
84 obtainConnection();
85 }
86 log.info("Checking if the database needs to be migrated.");
87 if(needsMigration()) {
88 if(allowAutoMigrate()) {
89 log.warn("Database needs to be migrated, attempting to automigrate.");
90 migrateDatabase();
91 } else {
92 log.error("Database needs migration, automigrations is disabled.");
93 throw new IllegalStateException("Database needs migration, automigrations is disabled.");
94 }
95 } else {
96 log.info("Database migration was not needed.");
97 }
98 }
99 return connector;
100 }
101
102
103
104
105
106 protected abstract DatabaseSpecifics getDatabaseSpecifics();
107
108
109
110
111
112 protected abstract DatabaseMigrator getMigrator();
113
114
115
116
117
118 protected abstract boolean needsMigration();
119
120
121
122
123
124
125 protected abstract String getDatabaseCreationScript();
126
127
128
129
130
131 protected void obtainConnection() throws IllegalStateException {
132 log.debug("Obtaining db connection.");
133 connector = new DBConnector(getDatabaseSpecifics());
134 Connection connection = connector.getConnection();
135 try {
136 connection.close();
137 } catch (SQLException e) {
138 log.warn("Connection opened for testing connectivaty failed to close", e);
139 }
140 log.debug("Obtained db connection.");
141 }
142
143
144
145
146 private void migrateDatabase() {
147 DatabaseMigrator migrator = getMigrator();
148 if(migrator != null) {
149 migrator.migrate();
150 } else {
151 throw new IllegalStateException("The database was attempted migrated, but no migrator was available.");
152 }
153 }
154
155 private boolean allowAutoMigrate() {
156 DatabaseSpecifics ds = getDatabaseSpecifics();
157 if(ds.isSetAllowAutoMigrate()) {
158 return ds.isAllowAutoMigrate();
159 } else {
160 return true;
161 }
162 }
163
164 private boolean allowAutoCreate() {
165 DatabaseSpecifics ds = getDatabaseSpecifics();
166 if(ds.isSetAllowAutoCreate()) {
167 return ds.isAllowAutoCreate();
168 } else {
169 return true;
170 } }
171
172
173
174
175 private void createDatabase() {
176 DatabaseCreator databaseCreator = new DatabaseCreator();
177 databaseCreator.createDatabase(getDatabaseSpecifics(), getDatabaseCreationScript());
178 }
179
180 }