1 package org.apache.torque.templates.transformer.sql;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.List;
25
26 import org.apache.commons.lang.ObjectUtils;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.torque.generator.control.ControllerState;
29 import org.apache.torque.generator.source.SourceElement;
30 import org.apache.torque.generator.source.SourcePath;
31 import org.apache.torque.generator.source.transform.SourceTransformer;
32 import org.apache.torque.generator.source.transform.SourceTransformerException;
33 import org.apache.torque.templates.TemplateOptionName;
34 import org.apache.torque.templates.TorqueSchemaAttributeName;
35 import org.apache.torque.templates.TorqueSchemaElementName;
36 import org.apache.torque.templates.TorqueSchemaIdMethod;
37 import org.apache.torque.templates.platform.Platform;
38 import org.apache.torque.templates.platform.PlatformFactory;
39 import org.apache.torque.templates.transformer.CollectAttributeSetTrueTransformer;
40 import org.apache.torque.templates.transformer.SchemaTypeHelper;
41 import org.apache.torque.templates.transformer.om.OMColumnTransformer;
42 import org.apache.torque.templates.transformer.om.TableChildElementName;
43 import org.apache.torque.templates.typemapping.SchemaType;
44 import org.apache.torque.templates.typemapping.SqlType;
45 import org.apache.torque.templates.typemapping.TypeMap;
46
47
48
49
50 public class SQLTransformer implements SourceTransformer
51 {
52 private final CollectAttributeSetTrueTransformer collectAttributeSetTrueTransformer
53 = new CollectAttributeSetTrueTransformer();
54
55 public SourceElement transform(
56 SourceElement databaseElement,
57 ControllerState controllerState)
58 throws SourceTransformerException
59 {
60 TemplateOptionName.checkRequiredOptions(
61 controllerState,
62 TemplateOptionName.DATABASE);
63
64 List<SourceElement> tableElements = databaseElement.getChildren(
65 TorqueSchemaElementName.TABLE.getName());
66 for (SourceElement tableElement : tableElements)
67 {
68 transformTable(tableElement, controllerState);
69 }
70 return databaseElement;
71 }
72
73 public void transformTable(
74 SourceElement tableElement,
75 ControllerState controllerState)
76 throws SourceTransformerException
77 {
78 Object idMethod = tableElement.getAttribute(
79 TorqueSchemaAttributeName.ID_METHOD.getName());
80 if (idMethod == null)
81 {
82 Object defaultIdMethod = tableElement.getParent().getAttribute(
83 TorqueSchemaAttributeName.DEFAULT_ID_METHOD.getName());
84 if (defaultIdMethod == null)
85 {
86 throw new SourceTransformerException("id Method is not set"
87 + " on table "
88 + tableElement.getAttribute(
89 TorqueSchemaAttributeName.NAME.getName())
90 + " and defaultIdMethod is not set on database");
91 }
92 tableElement.setAttribute(
93 TorqueSchemaAttributeName.ID_METHOD.getName(),
94 defaultIdMethod);
95 }
96 String tableName = (String) tableElement.getAttribute(
97 TorqueSchemaAttributeName.NAME);
98 if (tableElement.getAttribute(
99 SqlAttributeName.PRIMARY_KEY_CONSTRAINT_NAME)
100 == null)
101 {
102 String primaryKeyConstraintName = tableName + "_PK";
103 tableElement.setAttribute(
104 SqlAttributeName.PRIMARY_KEY_CONSTRAINT_NAME,
105 primaryKeyConstraintName);
106 }
107 if (tableElement.getAttribute(SqlAttributeName.SEQUENCE_NAME)
108 == null)
109 {
110 String sequenceName = null;
111 SourceElement idMethodParameterElement = tableElement.getChild(
112 TorqueSchemaElementName.ID_METHOD_PARAMETER);
113 if (idMethodParameterElement != null)
114 {
115 sequenceName = (String) idMethodParameterElement.getAttribute(
116 TorqueSchemaAttributeName.VALUE);
117 }
118 if (StringUtils.isBlank(sequenceName))
119 {
120 sequenceName = tableName + "_SEQ";
121 }
122 tableElement.setAttribute(
123 SqlAttributeName.SEQUENCE_NAME,
124 sequenceName);
125 }
126
127
128 collectAttributeSetTrueTransformer.transform(
129 tableElement,
130 controllerState,
131 TorqueSchemaElementName.COLUMN,
132 TorqueSchemaAttributeName.PRIMARY_KEY,
133 TableChildElementName.PRIMARY_KEYS);
134
135 StringBuilder primaryKeyColumnNames = new StringBuilder();
136 SourceElement primaryKeysElement = tableElement.getChild(
137 TableChildElementName.PRIMARY_KEYS);
138 boolean firstPk = true;
139 for (SourceElement primaryKeyColumn : primaryKeysElement.getChildren())
140 {
141 if (!firstPk)
142 {
143 primaryKeyColumnNames.append(", ");
144 }
145 primaryKeyColumnNames.append(primaryKeyColumn.getAttribute(
146 TorqueSchemaAttributeName.NAME.getName()));
147 firstPk = false;
148 }
149 tableElement.setAttribute(
150 SqlAttributeName.PRIMARY_KEY_COLUMN_NAMES,
151 primaryKeyColumnNames.toString());
152
153
154 int uniqueIndex = 1;
155 for (SourceElement uniqueElement : tableElement.getChildren(
156 TorqueSchemaElementName.UNIQUE.getName()))
157 {
158 if (uniqueElement.getAttribute(
159 TorqueSchemaAttributeName.NAME.getName())
160 == null)
161 {
162 uniqueElement.setAttribute(
163 TorqueSchemaAttributeName.NAME.getName(),
164 uniqueElement.getParent().getAttribute(
165 TorqueSchemaAttributeName.NAME.getName())
166 + "_UQ_" + uniqueIndex);
167 }
168 String uniqueColumnNames = collectAttributes(
169 uniqueElement,
170 TorqueSchemaElementName.UNIQUE_COLUMN.getName(),
171 TorqueSchemaAttributeName.NAME.getName());
172 uniqueElement.setAttribute(
173 SqlAttributeName.UNIQUE_COLUMN_NAMES,
174 uniqueColumnNames);
175 ++uniqueIndex;
176 }
177
178
179 int indexIndex = 1;
180 for (SourceElement indexElement : tableElement.getChildren(
181 TorqueSchemaElementName.INDEX.getName()))
182 {
183 if (indexElement.getAttribute(
184 TorqueSchemaAttributeName.NAME.getName())
185 == null)
186 {
187 indexElement.setAttribute(
188 TorqueSchemaAttributeName.NAME.getName(),
189 indexElement.getParent().getAttribute(
190 TorqueSchemaAttributeName.NAME.getName())
191 + "_IDX_" + indexIndex);
192 }
193 String indexColumnNames = collectAttributes(
194 indexElement,
195 TorqueSchemaElementName.INDEX_COLUMN.getName(),
196 TorqueSchemaAttributeName.NAME.getName());
197 indexElement.setAttribute(
198 SqlAttributeName.INDEX_COLUMN_NAMES,
199 indexColumnNames);
200 indexIndex++;
201 }
202
203 List<SourceElement> columnElements = tableElement.getChildren(
204 TorqueSchemaElementName.COLUMN.getName());
205 for (SourceElement columnElement : columnElements)
206 {
207 transformColumn(columnElement, controllerState);
208 }
209 List<SourceElement> foreignKeyElements = tableElement.getChildren(
210 TorqueSchemaElementName.FOREIGN_KEY.getName());
211
212 int fkIndex = 1;
213 for (SourceElement foreignKeyElemenElement : foreignKeyElements)
214 {
215 transformForeignKey(
216 foreignKeyElemenElement,
217 controllerState,
218 fkIndex);
219 ++fkIndex;
220 }
221 }
222
223
224
225
226
227
228
229
230
231
232
233 private void transformColumn(
234 SourceElement columnElement,
235 ControllerState controllerState)
236 throws SourceTransformerException
237 {
238 String sql = (String) columnElement.getAttribute(
239 SqlAttributeName.DDL_SQL);
240 if (sql == null)
241 {
242 sql = getDdlSql(columnElement, controllerState);
243 columnElement.setAttribute(SqlAttributeName.DDL_SQL, sql);
244 }
245 }
246
247
248
249
250
251
252
253
254
255
256
257
258 private String getDdlSql(
259 SourceElement columnElement,
260 ControllerState controllerState)
261 throws SourceTransformerException
262 {
263 SchemaType schemaType = SchemaTypeHelper.getSchemaType(
264 columnElement,
265 controllerState);
266 SqlType domainType = SchemaTypeHelper.getDomain(
267 columnElement,
268 controllerState);
269 Object size = columnElement.getAttribute(
270 TorqueSchemaAttributeName.SIZE);
271 Object scale = columnElement.getAttribute(
272 TorqueSchemaAttributeName.SCALE);
273 Object defaultValue = columnElement.getAttribute(
274 TorqueSchemaAttributeName.DEFAULT);
275 SqlType sqlType = SchemaTypeHelper.getSqlType(
276 schemaType,
277 domainType,
278 controllerState,
279 ObjectUtils.toString(size, null),
280 ObjectUtils.toString(scale, null),
281 ObjectUtils.toString(defaultValue, null));
282 Platform platform = PlatformFactory.getPlatformFor(
283 controllerState.getStringOption(
284 TemplateOptionName.DATABASE));
285
286 List<String> resultList = new ArrayList<String>();
287
288 String sqlTypeName = sqlType.getSqlTypeName();
289
290 if (platform.hasSize(sqlTypeName))
291 {
292 sqlTypeName += sqlType.printSize(
293 platform.getSizeSuffix(sqlTypeName));
294 }
295
296 resultList.add(sqlTypeName);
297
298 if (StringUtils.isNotEmpty(sqlType.getDefaultValue()))
299 {
300 resultList.add("default");
301
302 if ((SchemaType.DATE == schemaType
303 || SchemaType.TIME == schemaType
304 || SchemaType.TIMESTAMP == schemaType))
305 {
306 if (sqlType.getDefaultValue().startsWith("CURRENT_"))
307 {
308 resultList.add(sqlType.getDefaultValue());
309 }
310 else
311 {
312 Date defaultDate
313 = OMColumnTransformer.getDefaultValueAsDate(
314 sqlType.getDefaultValue());
315 if (SchemaType.DATE == schemaType) {
316 resultList.add(platform.getDateString(defaultDate));
317 }
318 else if (SchemaType.TIME == schemaType)
319 {
320 resultList.add(platform.getTimeString(defaultDate));
321 }
322 else
323 {
324 resultList.add(platform.getTimestampString(
325 defaultDate));
326 }
327 }
328 }
329 else if (TypeMap.isTextType(schemaType))
330 {
331 resultList.add(platform.quoteAndEscape(
332 sqlType.getDefaultValue()));
333 }
334 else
335 {
336 resultList.add(sqlType.getDefaultValue());
337 }
338 }
339
340 boolean primaryKey;
341 {
342 String primaryKeyString = (String) columnElement.getAttribute(
343 TorqueSchemaAttributeName.PRIMARY_KEY);
344 primaryKey = Boolean.parseBoolean(primaryKeyString);
345 }
346 boolean required;
347 {
348 String requiredString = (String) columnElement.getAttribute(
349 TorqueSchemaAttributeName.REQUIRED);
350 required = Boolean.parseBoolean(requiredString);
351 }
352 boolean isNotNull = primaryKey || required;
353 String isNotNullString = platform.getNullString(isNotNull);
354
355 if (platform.createNotNullBeforeAutoincrement())
356 {
357 if (StringUtils.isNotEmpty(isNotNullString))
358 {
359 resultList.add(isNotNullString);
360 }
361 }
362
363
364
365
366 Object idMethod = columnElement.getParent().getAttribute(
367 TorqueSchemaAttributeName.ID_METHOD);
368 if (primaryKey
369 && TorqueSchemaIdMethod.NATIVE.getName().equals(idMethod))
370 {
371 String autoIncrement = platform.getAutoIncrement();
372 if (StringUtils.isNotEmpty(autoIncrement))
373 {
374 resultList.add(autoIncrement);
375 }
376 }
377 if (!platform.createNotNullBeforeAutoincrement())
378 {
379 if (StringUtils.isNotEmpty(isNotNullString))
380 {
381 resultList.add(isNotNullString);
382 }
383 }
384 return StringUtils.join(resultList.iterator(), ' ');
385 }
386
387
388
389
390
391
392
393
394 private void transformForeignKey(
395 SourceElement foreignKeyElement,
396 ControllerState controllerState,
397 int fkIndex)
398 {
399 if (foreignKeyElement.getAttribute(
400 TorqueSchemaAttributeName.NAME.getName())
401 == null)
402 {
403 foreignKeyElement.setAttribute(
404 TorqueSchemaAttributeName.NAME.getName(),
405 foreignKeyElement.getParent().getAttribute(
406 TorqueSchemaAttributeName.NAME.getName())
407 + "_FK_" + fkIndex);
408 }
409 String localColumnsNames = collectAttributes(
410 foreignKeyElement,
411 TorqueSchemaElementName.REFERENCE.getName(),
412 TorqueSchemaAttributeName.LOCAL.getName());
413 foreignKeyElement.setAttribute(
414 SqlAttributeName.LOCAL_COLUMN_NAMES,
415 localColumnsNames);
416 String foreignColumnsNames = collectAttributes(
417 foreignKeyElement,
418 TorqueSchemaElementName.REFERENCE.getName(),
419 TorqueSchemaAttributeName.FOREIGN.getName());
420 foreignKeyElement.setAttribute(
421 SqlAttributeName.FOREIGN_COLUMN_NAMES,
422 foreignColumnsNames);
423 }
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440 private String collectAttributes(
441 SourceElement rootElement,
442 String sourcePath,
443 String attributeName)
444 {
445 StringBuilder result = new StringBuilder();
446 List<SourceElement> toCollectFrom = SourcePath.getElements(
447 rootElement, sourcePath);
448 for (SourceElement sourceElement : toCollectFrom)
449 {
450 Object attributeValue = sourceElement.getAttribute(attributeName);
451 if (attributeValue != null)
452 {
453 if (result.length() > 0)
454 {
455 result.append(", ");
456 }
457 result.append(sourceElement.getAttribute(attributeName));
458 }
459 }
460 return result.toString();
461 }
462 }