1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 package org.melati.poem.dbms;
43
44 import org.melati.poem.*;
45 import org.melati.poem.SQLType;
46
47 import java.sql.*;
48
49
50
51
52 public class Oracle extends AnsiStandard {
53
54
55
56
57
58
59 public static int oracleTextHack = 4000;
60
61
62
63
64 public Oracle() {
65 setDriverClassName("oracle.jdbc.OracleDriver");
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 @Override
90 public String getStringSqlDefinition(int size) throws SQLException {
91 if (size < 0) {
92 return "CLOB";
93 }
94 return super.getStringSqlDefinition(size);
95 }
96
97 @Override
98 public String getLongSqlDefinition() {
99 return "NUMBER";
100 }
101
102 @Override
103 public String getSqlDefinition(String sqlTypeName) {
104 if (sqlTypeName.equals("BOOLEAN")) {
105 return ("CHAR(1)");
106 }
107 return super.getSqlDefinition(sqlTypeName);
108 }
109
110 @Override
111 public String sqlBooleanValueOfRaw(Object raw) {
112 if ((Boolean) raw)
113 return "1";
114 else
115 return "0";
116 }
117
118
119
120
121 public static class OracleStringPoemType extends StringPoemType {
122
123
124
125
126
127
128
129 public OracleStringPoemType(boolean nullable, int size) {
130 super(nullable, size);
131 }
132
133 protected boolean _canRepresent(SQLPoemType<?> other) {
134 return ((sqlTypeCode() == Types.VARCHAR || sqlTypeCode() == Types.CLOB)
135 && (other.sqlTypeCode() == Types.VARCHAR || other.sqlTypeCode() == Types.CLOB)
136 ) &&
137 (
138 (getSize() == oracleTextHack && ((StringPoemType) other).getSize() == -1)
139 ||
140 (getSize() == -1 &&
141 ((StringPoemType) other).getSize() == oracleTextHack)
142 ||
143 ((getSize() >= ((StringPoemType) other).getSize())));
144 }
145
146
147
148
149
150
151 public <O> PoemType<O> canRepresent(PoemType<O> other) {
152 return other instanceof StringPoemType &&
153 _canRepresent((StringPoemType) other) &&
154 !(!getNullable() && (other).getNullable()) ?
155 other : null;
156 }
157
158 }
159
160 @Override
161 public String getBinarySqlDefinition(int size) throws SQLException {
162 return "BLOB";
163 }
164
165 @Override
166 public String unreservedName(String name) {
167 if (name.equalsIgnoreCase("user")) name = "melati_" + name;
168 if (name.equalsIgnoreCase("group")) name = "melati_" + name;
169 return name.toUpperCase();
170 }
171
172 @Override
173 public String melatiName(String name) {
174 if (name == null) return null;
175 if (name.equalsIgnoreCase("melati_user")) name = "user";
176 if (name.equalsIgnoreCase("melati_group")) name = "group";
177 return name.toLowerCase();
178 }
179
180 @Override
181 public <S, O> PoemType<O> canRepresent(PoemType<S> storage, PoemType<O> type) {
182 if ((storage instanceof IntegerPoemType &&
183 type instanceof BigDecimalPoemType) &&
184 !(!storage.getNullable() && type.getNullable())) {
185 return type;
186 }
187 if ((storage instanceof IntegerPoemType &&
188 type instanceof LongPoemType) &&
189 !(!storage.getNullable() && type.getNullable())) {
190 return type;
191 } else {
192 return storage.canRepresent(type);
193 }
194 }
195
196 @Override
197 public SQLPoemType<?> defaultPoemTypeOfColumnMetaData(ResultSet md)
198 throws SQLException {
199 System.err.println("TYPE_NAME:" + md.getString("TYPE_NAME"));
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 if (md.getString("TYPE_NAME").equals("VARCHAR2"))
218 return
219 new OracleStringPoemType(
220 md.getInt("NULLABLE") ==
221 DatabaseMetaData.columnNullable,
222 md.getInt("COLUMN_SIZE"));
223 if (md.getString("TYPE_NAME").equals("CLOB"))
224 return
225 new OracleStringPoemType(
226 md.getInt("NULLABLE") ==
227 DatabaseMetaData.columnNullable,
228 md.getInt("COLUMN_SIZE"));
229 if (md.getString("TYPE_NAME").equals("CHAR"))
230 return
231 new OracleBooleanPoemType(
232 md.getInt("NULLABLE") ==
233 DatabaseMetaData.columnNullable);
234 if (md.getString("TYPE_NAME").equals("BLOB"))
235 return new BinaryPoemType(
236 md.getInt("NULLABLE") == DatabaseMetaData.columnNullable,
237 md.getInt("COLUMN_SIZE"));
238 if (md.getString("TYPE_NAME").equals("FLOAT"))
239 return new DoublePoemType(
240 md.getInt("NULLABLE") == DatabaseMetaData.columnNullable);
241 if (
242 md.getString("TYPE_NAME").equals("NUMBER"))
243 return new IntegerPoemType(
244 md.getInt("NULLABLE") == DatabaseMetaData.columnNullable);
245
246 return super.defaultPoemTypeOfColumnMetaData(md);
247 }
248
249 @Override
250 public String getForeignKeyDefinition(String tableName, String fieldName,
251 String targetTableName, String targetTableFieldName, String fixName) {
252 String q = " ADD (CONSTRAINT FK_" + tableName + "_" + fieldName + ") " +
253 "FOREIGN KEY (" + getQuotedName(fieldName) + ") " +
254 "REFERENCES " + getQuotedName(targetTableName) +
255 "(" + getQuotedName(targetTableFieldName) + ")";
256
257
258
259
260 if (fixName.equals("delete"))
261 q += " ON DELETE CASCADE";
262 if (fixName.equals("clear"))
263 q += " ON DELETE SET NULL";
264 return q;
265 }
266
267 @Override
268 public String getPrimaryKeyDefinition(String fieldName) {
269 return " ADD (CONSTRAINT PK_" + fieldName +
270 " PRIMARY KEY(" + getQuotedName(fieldName) + "))";
271 }
272
273 @Override
274 public String booleanTrueExpression(Column<Boolean> booleanColumn) {
275 return booleanColumn.fullQuotedName() + "=1";
276 }
277
278 @Override
279 public String getSqlDefaultValue(SQLType<?> sqlType) {
280 if (sqlType instanceof BooleanPoemType) {
281 return ("0");
282 }
283 return super.getSqlDefaultValue(sqlType);
284 }
285
286
287
288
289 public static class OracleBooleanPoemType extends BooleanPoemType {
290
291
292
293
294
295
296 public OracleBooleanPoemType(boolean nullable) {
297 super(nullable);
298 }
299
300 protected Boolean _getRaw(ResultSet rs, int col) throws SQLException {
301 synchronized (rs) {
302 boolean v = rs.getBoolean(col);
303 return rs.wasNull() ? null : (v ? Boolean.TRUE : Boolean.FALSE);
304 }
305 }
306
307 protected void _setRaw(PreparedStatement ps, int col, Object bool)
308 throws SQLException {
309 ps.setInt(col, (Boolean) bool ? 1 : 0);
310 }
311
312 }
313 }