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.waarp.common.database.DbPreparedStatement;
23 import org.waarp.common.database.DbRequest;
24 import org.waarp.common.database.DbSession;
25 import org.waarp.common.database.data.DbDataModel;
26 import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
27 import org.waarp.common.database.exception.WaarpDatabaseNoDataException;
28 import org.waarp.common.database.exception.WaarpDatabaseSqlException;
29 import org.waarp.common.logging.SysErrLogger;
30 import org.waarp.common.logging.WaarpLogger;
31 import org.waarp.common.logging.WaarpLoggerFactory;
32
33 import java.sql.SQLException;
34 import java.sql.Types;
35 import java.util.concurrent.locks.ReentrantLock;
36
37
38
39
40 public abstract class DbModelCommonMariadbMySql extends DbModelAbstract {
41
42
43
44 private static final WaarpLogger logger =
45 WaarpLoggerFactory.getLogger(DbModelCommonMariadbMySql.class);
46
47 protected enum DBType {
48 CHAR(Types.CHAR, " CHAR(3) "),
49 VARCHAR(Types.VARCHAR, " VARCHAR(" + MAX_VARCHAR + ") "),
50
51
52
53
54
55 NVARCHAR(Types.VARCHAR, " VARCHAR(" + MAX_KEY_VARCHAR + ") "),
56 LONGVARCHAR(Types.LONGVARCHAR, " TEXT "), BIT(Types.BIT, " " + "BOOLEAN "),
57 TINYINT(Types.TINYINT, " TINYINT "), SMALLINT(Types.SMALLINT, " SMALLINT "),
58 INTEGER(Types.INTEGER, " INTEGER "), BIGINT(Types.BIGINT, " BIGINT "),
59 REAL(Types.REAL, " FLOAT "), DOUBLE(Types.DOUBLE, " DOUBLE "),
60 VARBINARY(Types.VARBINARY, " VARBINARY(" + (MAX_BINARY * 2) + ") "),
61 DATE(Types.DATE, " " + "DATE "),
62 TIMESTAMP(Types.TIMESTAMP, " TIMESTAMP(3) ");
63
64 public final int type;
65
66 public final String constructor;
67
68 DBType(final int type, final String constructor) {
69 this.type = type;
70 this.constructor = constructor;
71 }
72
73 public static String getType(final int sqltype) {
74 switch (sqltype) {
75 case Types.CHAR:
76 return CHAR.constructor;
77 case Types.VARCHAR:
78 return VARCHAR.constructor;
79 case Types.NVARCHAR:
80 return NVARCHAR.constructor;
81 case Types.LONGVARCHAR:
82 return LONGVARCHAR.constructor;
83 case Types.BIT:
84 return BIT.constructor;
85 case Types.TINYINT:
86 return TINYINT.constructor;
87 case Types.SMALLINT:
88 return SMALLINT.constructor;
89 case Types.INTEGER:
90 return INTEGER.constructor;
91 case Types.BIGINT:
92 return BIGINT.constructor;
93 case Types.REAL:
94 return REAL.constructor;
95 case Types.DOUBLE:
96 return DOUBLE.constructor;
97 case Types.VARBINARY:
98 return VARBINARY.constructor;
99 case Types.DATE:
100 return DATE.constructor;
101 case Types.TIMESTAMP:
102 return TIMESTAMP.constructor;
103 default:
104 return null;
105 }
106 }
107 }
108
109 private final ReentrantLock lock = new ReentrantLock();
110
111 @Override
112 public void resetSequence(final DbSession session, final long newvalue)
113 throws WaarpDatabaseNoConnectionException {
114 final String action =
115 "UPDATE Sequences SET seq = " + newvalue + " WHERE name = '" +
116 DbDataModel.fieldseq + '\'';
117 final DbRequest request = new DbRequest(session);
118 try {
119 request.query(action);
120 } catch (final WaarpDatabaseNoConnectionException e) {
121 logger.warn("ResetSequence Error", e);
122 } catch (final WaarpDatabaseSqlException e) {
123 logger.warn("ResetSequence Error", e);
124 } finally {
125 request.close();
126 }
127 logger.warn(action);
128 }
129
130 @Override
131 public long nextSequence(final DbSession dbSession)
132 throws WaarpDatabaseNoConnectionException, WaarpDatabaseSqlException,
133 WaarpDatabaseNoDataException {
134 lock.lock();
135 try {
136 long result;
137 String action =
138 "SELECT seq FROM Sequences WHERE name = '" + DbDataModel.fieldseq +
139 "' FOR UPDATE";
140 final DbPreparedStatement preparedStatement =
141 new DbPreparedStatement(dbSession);
142 try {
143 dbSession.getConn().setAutoCommit(false);
144 } catch (final SQLException ignored) {
145 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
146 }
147 try {
148 preparedStatement.createPrepareStatement(action);
149
150 preparedStatement.executeQuery();
151 if (preparedStatement.getNext()) {
152 try {
153 result = preparedStatement.getResultSet().getLong(1);
154 } catch (final SQLException e) {
155 throw new WaarpDatabaseSqlException(e);
156 }
157 } else {
158 throw new WaarpDatabaseNoDataException(
159 "No sequence found. Must be initialized first");
160 }
161 } finally {
162 preparedStatement.realClose();
163 }
164 action =
165 "UPDATE Sequences SET seq = " + (result + 1) + " WHERE name = '" +
166 DbDataModel.fieldseq + '\'';
167 try {
168 preparedStatement.createPrepareStatement(action);
169
170 preparedStatement.executeUpdate();
171 } finally {
172 preparedStatement.realClose();
173 }
174 return result;
175 } finally {
176 try {
177 dbSession.getConn().setAutoCommit(true);
178 } catch (final SQLException ignored) {
179 SysErrLogger.FAKE_LOGGER.ignoreLog(ignored);
180 } finally {
181 lock.unlock();
182 }
183 }
184 }
185
186 @Override
187 protected final String validConnectionString() {
188 return "select 1 from dual";
189 }
190
191 @Override
192 public final String limitRequest(final String allfields, final String request,
193 final int nb) {
194 if (nb == 0) {
195 return request;
196 }
197 return request + " LIMIT " + nb;
198 }
199
200 }