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.postgresql.Driver;
23 import org.waarp.common.database.DbConstant;
24 import org.waarp.common.database.DbPreparedStatement;
25 import org.waarp.common.database.DbRequest;
26 import org.waarp.common.database.DbSession;
27 import org.waarp.common.database.data.DbDataModel;
28 import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
29 import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
30 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
31 import org.waarp.common.logging.SysErrLogger;
32 import org.waarp.common.logging.WaarpLogger;
33 import org.waarp.common.logging.WaarpLoggerFactory;
34
35 import java.sql.DriverManager;
36 import java.sql.SQLException;
37 import java.sql.Types;
38
39
40
41
42 public abstract class DbModelPostgresql extends DbModelAbstract {
43
44
45
46 private static final WaarpLogger logger =
47 WaarpLoggerFactory.getLogger(DbModelPostgresql.class);
48
49 private static final DbType type = DbType.PostGreSQL;
50
51 protected static class DbTypeResolverPostgreSQL
52 extends DbModelAbstract.DbTypeResolver {
53
54 @Override
55 public final String getType(final int sqlType) {
56 return DBType.getType(sqlType);
57 }
58
59 @Override
60 public final DbType getDbType() {
61 return type;
62 }
63 }
64
65 static {
66 dbTypeResolver = new DbTypeResolverPostgreSQL();
67 }
68
69 protected Boolean useIsValid;
70
71 @Override
72 public final DbType getDbType() {
73 return type;
74 }
75
76
77
78
79
80
81 protected DbModelPostgresql() throws WaarpDatabaseNoConnectionException {
82 if (DbModelFactory.classLoaded.contains(type.name())) {
83 return;
84 }
85 try {
86 DriverManager.registerDriver(new Driver());
87 DbModelFactory.classLoaded.add(type.name());
88 } catch (final SQLException e) {
89
90 logger.error(
91 "Cannot register Driver " + type.name() + ' ' + e.getMessage());
92 DbConstant.error(e);
93 throw new WaarpDatabaseNoConnectionException(
94 "Cannot load database drive:" + type.name(), e);
95 }
96
97
98
99
100
101
102
103
104
105
106
107 }
108
109 protected enum DBType {
110 CHAR(Types.CHAR, " CHAR(3) "),
111 VARCHAR(Types.VARCHAR, " VARCHAR(" + MAX_VARCHAR + ") "),
112 NVARCHAR(Types.NVARCHAR, " VARCHAR(" + MAX_KEY_VARCHAR + ") "),
113 LONGVARCHAR(Types.LONGVARCHAR, " VARCHAR(" + MAX_LONGVARCHAR + ") "),
114 BIT(Types.BIT, " BOOLEAN "), TINYINT(Types.TINYINT, " INT2 "),
115 SMALLINT(Types.SMALLINT, " SMALLINT "), INTEGER(Types.INTEGER, " INTEGER "),
116 BIGINT(Types.BIGINT, " BIGINT "), REAL(Types.REAL, " REAL "),
117 DOUBLE(Types.DOUBLE, " DOUBLE PRECISION "),
118 VARBINARY(Types.VARBINARY, " BYTEA "), DATE(Types.DATE, " DATE "),
119 TIMESTAMP(Types.TIMESTAMP, " TIMESTAMP(3) ");
120
121 public final int type;
122
123 public final String constructor;
124
125 DBType(final int type, final String constructor) {
126 this.type = type;
127 this.constructor = constructor;
128 }
129
130 public static String getType(final int sqltype) {
131 switch (sqltype) {
132 case Types.CHAR:
133 return CHAR.constructor;
134 case Types.VARCHAR:
135 return VARCHAR.constructor;
136 case Types.NVARCHAR:
137 return NVARCHAR.constructor;
138 case Types.LONGVARCHAR:
139 return LONGVARCHAR.constructor;
140 case Types.BIT:
141 return BIT.constructor;
142 case Types.TINYINT:
143 return TINYINT.constructor;
144 case Types.SMALLINT:
145 return SMALLINT.constructor;
146 case Types.INTEGER:
147 return INTEGER.constructor;
148 case Types.BIGINT:
149 return BIGINT.constructor;
150 case Types.REAL:
151 return REAL.constructor;
152 case Types.DOUBLE:
153 return DOUBLE.constructor;
154 case Types.VARBINARY:
155 return VARBINARY.constructor;
156 case Types.DATE:
157 return DATE.constructor;
158 case Types.TIMESTAMP:
159 return TIMESTAMP.constructor;
160 default:
161 return null;
162 }
163 }
164 }
165
166 @Override
167 public void resetSequence(final DbSession session, final long newvalue)
168 throws WaarpDatabaseNoConnectionException {
169 final String action =
170 "ALTER SEQUENCE " + DbDataModel.fieldseq + " MINVALUE " +
171 (DbConstant.ILLEGALVALUE + 1) + " RESTART WITH " + newvalue;
172 final DbRequest request = new DbRequest(session);
173 try {
174 request.query(action);
175 } catch (final WaarpDatabaseNoConnectionException e) {
176 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
177 } catch (final WaarpDatabaseSqlException e) {
178 SysErrLogger.FAKE_LOGGER.ignoreLog(e);
179 } finally {
180 request.close();
181 }
182 logger.warn(action);
183 }
184
185 @Override
186 public long nextSequence(final DbSession dbSession)
187 throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException,
188 WaarpDatabaseNoDataException {
189 long result;
190 final String action = "SELECT NEXTVAL('" + DbDataModel.fieldseq + "')";
191 final DbPreparedStatement preparedStatement =
192 new DbPreparedStatement(dbSession);
193 try {
194 preparedStatement.createPrepareStatement(action);
195
196 preparedStatement.executeQuery();
197 if (preparedStatement.getNext()) {
198 try {
199 result = preparedStatement.getResultSet().getLong(1);
200 } catch (final SQLException e) {
201 throw new WaarpDatabaseSqlException(e);
202 }
203 return result;
204 } else {
205 throw new WaarpDatabaseNoDataException(
206 "No sequence found. Must be initialized first");
207 }
208 } finally {
209 preparedStatement.realClose();
210 }
211 }
212
213 @Override
214 protected final String validConnectionString() {
215 return "select 1";
216 }
217
218 @Override
219 public final String limitRequest(final String allfields, final String request,
220 final int nb) {
221 if (nb == 0) {
222 return request;
223 }
224 return request + " LIMIT " + nb;
225 }
226
227 }