1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.waarp.common.database.model;
21
22 import org.h2.Driver;
23 import org.h2.jdbcx.JdbcConnectionPool;
24 import org.waarp.common.database.DbAdmin;
25 import org.waarp.common.database.DbConstant;
26 import org.waarp.common.database.DbPreparedStatement;
27 import org.waarp.common.database.DbRequest;
28 import org.waarp.common.database.DbSession;
29 import org.waarp.common.database.data.DbDataModel;
30 import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
31 import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
32 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
33 import org.waarp.common.logging.WaarpLogger;
34 import org.waarp.common.logging.WaarpLoggerFactory;
35
36 import java.sql.Connection;
37 import java.sql.DriverManager;
38 import java.sql.SQLException;
39 import java.sql.Types;
40
41
42
43
44 public abstract class DbModelH2 extends DbModelAbstract {
45
46
47
48 private static final WaarpLogger logger =
49 WaarpLoggerFactory.getLogger(DbModelH2.class);
50
51 private static final DbType type = DbType.H2;
52
53 protected static class DbTypeResolverH2
54 extends DbModelAbstract.DbTypeResolver {
55
56 @Override
57 public final String getType(final int sqlType) {
58 return DBType.getType(sqlType);
59 }
60
61 @Override
62 public final String getCreateTable() {
63 return "CREATE TABLE IF NOT EXISTS ";
64 }
65
66 @Override
67 public final String getCreateIndex() {
68 return "CREATE INDEX IF NOT EXISTS ";
69 }
70
71 @Override
72 public final DbType getDbType() {
73 return type;
74 }
75 }
76
77 static {
78 dbTypeResolver = new DbTypeResolverH2();
79 }
80
81 protected JdbcConnectionPool pool;
82
83 @Override
84 public final DbType getDbType() {
85 return type;
86 }
87
88
89
90
91
92
93
94
95
96
97 protected DbModelH2(final String dbserver, final String dbuser,
98 final String dbpasswd)
99 throws WaarpDatabaseNoConnectionException {
100 this();
101 pool = JdbcConnectionPool.create(dbserver, dbuser, dbpasswd);
102 pool.setMaxConnections(DbConstant.MAXCONNECTION);
103 pool.setLoginTimeout(DbConstant.DELAYMAXCONNECTION);
104 logger.info("Some info: MaxConn: {} LogTimeout: {}",
105 pool.getMaxConnections(), pool.getLoginTimeout());
106 }
107
108
109
110
111
112
113 protected DbModelH2() throws WaarpDatabaseNoConnectionException {
114 if (DbModelFactory.classLoaded.contains(type.name())) {
115 return;
116 }
117 try {
118 DriverManager.registerDriver(new Driver());
119 DbModelFactory.classLoaded.add(type.name());
120 } catch (final SQLException e) {
121
122 logger.error(
123 "Cannot register Driver " + type.name() + ' ' + e.getMessage());
124 DbConstant.error(e);
125 throw new WaarpDatabaseNoConnectionException(
126 "Cannot load database drive:" + type.name(), e);
127 }
128 }
129
130 @Override
131 public final void releaseResources() {
132 if (pool != null) {
133 pool.dispose();
134 }
135 pool = null;
136 }
137
138 @Override
139 public synchronized int currentNumberOfPooledConnections() {
140 if (pool != null) {
141 return pool.getActiveConnections();
142 }
143 return DbAdmin.getNbConnection();
144 }
145
146 @Override
147 public final Connection getDbConnection(final String server,
148 final String user,
149 final String passwd)
150 throws SQLException {
151 synchronized (this) {
152 if (pool != null) {
153 try {
154 return pool.getConnection();
155 } catch (final SQLException e) {
156
157 pool.dispose();
158 pool = JdbcConnectionPool.create(server, user, passwd);
159 pool.setMaxConnections(DbConstant.MAXCONNECTION);
160 pool.setLoginTimeout(DbConstant.DELAYMAXCONNECTION);
161 logger.info("Some info: MaxConn: {} LogTimeout: {}",
162 pool.getMaxConnections(), pool.getLoginTimeout());
163 return pool.getConnection();
164 }
165 }
166 }
167 return super.getDbConnection(server, user, passwd);
168 }
169
170 protected enum DBType {
171 CHAR(Types.CHAR, " CHAR(3) "),
172 VARCHAR(Types.VARCHAR, " VARCHAR(" + MAX_VARCHAR + ") "),
173 NVARCHAR(Types.NVARCHAR, " VARCHAR(" + MAX_KEY_VARCHAR + ") "),
174 LONGVARCHAR(Types.LONGVARCHAR, " VARCHAR(" + MAX_LONGVARCHAR + ") "),
175 BIT(Types.BIT, " BOOLEAN "), TINYINT(Types.TINYINT, " TINYINT "),
176 SMALLINT(Types.SMALLINT, " SMALLINT "), INTEGER(Types.INTEGER, " INTEGER "),
177 BIGINT(Types.BIGINT, " BIGINT "), REAL(Types.REAL, " REAL "),
178 DOUBLE(Types.DOUBLE, " DOUBLE "),
179 VARBINARY(Types.VARBINARY, " VARBINARY(" + (MAX_BINARY * 2) + ") "),
180 DATE(Types.DATE, " DATE "), TIMESTAMP(Types.TIMESTAMP, " TIMESTAMP(3) "),
181 CLOB(Types.CLOB, " CLOB "), BLOB(Types.BLOB, " BLOB ");
182
183 public final int type;
184
185 public final String constructor;
186
187 DBType(final int type, final String constructor) {
188 this.type = type;
189 this.constructor = constructor;
190 }
191
192 public static String getType(final int sqltype) {
193 switch (sqltype) {
194 case Types.CHAR:
195 return CHAR.constructor;
196 case Types.VARCHAR:
197 return VARCHAR.constructor;
198 case Types.NVARCHAR:
199 return NVARCHAR.constructor;
200 case Types.LONGVARCHAR:
201 return LONGVARCHAR.constructor;
202 case Types.BIT:
203 return BIT.constructor;
204 case Types.TINYINT:
205 return TINYINT.constructor;
206 case Types.SMALLINT:
207 return SMALLINT.constructor;
208 case Types.INTEGER:
209 return INTEGER.constructor;
210 case Types.BIGINT:
211 return BIGINT.constructor;
212 case Types.REAL:
213 return REAL.constructor;
214 case Types.DOUBLE:
215 return DOUBLE.constructor;
216 case Types.VARBINARY:
217 return VARBINARY.constructor;
218 case Types.DATE:
219 return DATE.constructor;
220 case Types.TIMESTAMP:
221 return TIMESTAMP.constructor;
222 case Types.CLOB:
223 return CLOB.constructor;
224 case Types.BLOB:
225 return BLOB.constructor;
226 default:
227 return null;
228 }
229 }
230 }
231
232 @Override
233 public void resetSequence(final DbSession session, final long newvalue)
234 throws WaarpDatabaseNoConnectionException {
235 final String action =
236 "ALTER SEQUENCE " + DbDataModel.fieldseq + " RESTART WITH " + newvalue;
237 final DbRequest request = new DbRequest(session);
238 try {
239 request.query(action);
240 } catch (final WaarpDatabaseNoConnectionException e) {
241 logger.warn("ResetSequences Error", e);
242 } catch (final WaarpDatabaseSqlException e) {
243 logger.warn("ResetSequences Error", e);
244 } finally {
245 request.close();
246 }
247 logger.warn(action);
248 }
249
250 @Override
251 public long nextSequence(final DbSession dbSession)
252 throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException,
253 WaarpDatabaseNoDataException {
254 long result;
255 final String action = "SELECT NEXTVAL('" + DbDataModel.fieldseq + "')";
256 final DbPreparedStatement preparedStatement =
257 new DbPreparedStatement(dbSession);
258 try {
259 preparedStatement.createPrepareStatement(action);
260
261 preparedStatement.executeQuery();
262 if (preparedStatement.getNext()) {
263 try {
264 result = preparedStatement.getResultSet().getLong(1);
265 } catch (final SQLException e) {
266 throw new WaarpDatabaseSqlException(e);
267 }
268 return result;
269 } else {
270 throw new WaarpDatabaseNoDataException(
271 "No sequence found. Must be initialized first");
272 }
273 } finally {
274 preparedStatement.realClose();
275 }
276 }
277
278 @Override
279 protected final String validConnectionString() {
280 return "select 1";
281 }
282
283 @Override
284 public final String limitRequest(final String allfields, final String request,
285 final int nb) {
286 if (nb == 0) {
287 return request;
288 }
289 return request + " LIMIT " + nb;
290 }
291
292 }