1 package org.apache.torque.engine.database.transform;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.BufferedReader;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import org.apache.torque.engine.database.model.Column;
30 import org.apache.torque.engine.database.model.Database;
31 import org.apache.torque.engine.database.model.ForeignKey;
32 import org.apache.torque.engine.database.model.IDMethod;
33 import org.apache.torque.engine.database.model.Table;
34 import org.apache.torque.engine.sql.ParseException;
35 import org.apache.torque.engine.sql.SQLScanner;
36 import org.apache.torque.engine.sql.Token;
37
38
39
40
41
42
43
44
45
46
47
48 public class SQLToAppData
49 {
50 private String sqlFile;
51 private List tokens;
52 private Token token;
53 private Database appDataDB;
54 private int count;
55 private String databaseType;
56
57
58
59
60
61
62 public SQLToAppData(String sqlFile)
63 {
64 this.sqlFile = sqlFile;
65 }
66
67
68
69
70
71
72
73
74
75 public SQLToAppData(String sqlFile, String databaseType)
76 {
77 this.sqlFile = sqlFile;
78 this.databaseType = databaseType;
79 }
80
81
82
83
84
85
86 public String getSqlFile()
87 {
88 return sqlFile;
89 }
90
91
92
93
94
95
96 public void setSqlFile(String sqlFile)
97 {
98 this.sqlFile = sqlFile;
99 }
100
101
102
103
104
105
106 private void next() throws ParseException
107 {
108 if (count < tokens.size())
109 {
110 token = (Token) tokens.get(count++);
111 }
112 else
113 {
114 throw new ParseException("No More Tokens");
115 }
116 }
117
118
119
120
121
122
123
124
125
126 private void err(String name) throws ParseException
127 {
128 throw new ParseException (name + " at [ line: " + token.getLine()
129 + " col: " + token.getCol() + " ]");
130 }
131
132
133
134
135
136
137 private boolean hasTokens()
138 {
139 return count < tokens.size();
140 }
141
142
143
144
145
146
147 private void create() throws ParseException
148 {
149 next();
150 if (token.getStr().toUpperCase().equals("TABLE"))
151 {
152 create_Table();
153 }
154 }
155
156
157
158
159
160
161 private void create_Table() throws ParseException
162 {
163 next();
164 String tableName = token.getStr();
165 next();
166 if (!token.getStr().equals("("))
167 {
168 err("( expected");
169 }
170 next();
171
172 Table tbl = new Table (tableName);
173
174 while (!token.getStr().equals(";"))
175 {
176 create_Table_Column(tbl);
177 }
178
179 if (tbl.getPrimaryKey().size() == 1)
180 {
181 tbl.setIdMethod(IDMethod.ID_BROKER);
182 }
183 else
184 {
185 tbl.setIdMethod(IDMethod.NO_ID_METHOD);
186 }
187 appDataDB.addTable (tbl);
188 }
189
190
191
192
193
194
195
196 private void create_Table_Column(Table tbl) throws ParseException
197 {
198
199
200
201 if (token.getStr().equals(","))
202 {
203 next();
204 }
205
206 if (token.getStr().toUpperCase().equals("PRIMARY"))
207 {
208 create_Table_Column_Primary(tbl);
209 }
210 else if (token.getStr().toUpperCase().equals("FOREIGN"))
211 {
212 create_Table_Column_Foreign(tbl);
213 }
214 else if (token.getStr().toUpperCase().equals("UNIQUE"))
215 {
216 create_Table_Column_Unique(tbl);
217 }
218 else
219 {
220 create_Table_Column_Data(tbl);
221 }
222 }
223
224
225
226
227
228
229 private void create_Table_Column_Primary (Table tbl) throws ParseException
230 {
231 next();
232 if (!token.getStr().toUpperCase().equals("KEY"))
233 {
234 err("KEY expected");
235 }
236 next();
237 if (!token.getStr().toUpperCase().equals("("))
238 {
239 err("( expected");
240 }
241 next();
242
243 String colName = token.getStr();
244 Column c = tbl.getColumn(colName);
245 if (c == null)
246 {
247 err("Invalid column name: " + colName);
248 }
249 c.setPrimaryKey(true);
250 next();
251 while (token.getStr().equals(","))
252 {
253 next();
254 colName = token.getStr();
255 c = tbl.getColumn(colName);
256 if (c == null)
257 {
258 err("Invalid column name: " + colName);
259 }
260 c.setPrimaryKey(true);
261 next();
262 }
263
264 if (!token.getStr().toUpperCase().equals(")"))
265 {
266 err(") expected");
267 }
268 next();
269 }
270
271
272
273
274
275
276 private void create_Table_Column_Unique(Table tbl) throws ParseException
277 {
278 next();
279 if (!token.getStr().toUpperCase().equals("("))
280 {
281 err("( expected");
282 }
283 next();
284 while (!token.getStr().equals(")"))
285 {
286 if (!token.getStr().equals(","))
287 {
288 String colName = token.getStr();
289 Column c = tbl.getColumn(colName);
290 if (c == null)
291 {
292 err("Invalid column name: " + colName);
293 }
294 c.setUnique(true);
295 }
296 next();
297 }
298 if (!token.getStr().toUpperCase().equals(")"))
299 {
300 err(") expected got: " + token.getStr());
301 }
302
303 next();
304 }
305
306
307
308
309
310
311 private void create_Table_Column_Foreign(Table tbl) throws ParseException
312 {
313 next();
314 if (!token.getStr().toUpperCase().equals("KEY"))
315 {
316 err("KEY expected");
317 }
318 next();
319 if (!token.getStr().toUpperCase().equals("("))
320 {
321 err("( expected");
322 }
323 next();
324
325 ForeignKey fk = new ForeignKey();
326 List localColumns = new ArrayList();
327 tbl.addForeignKey(fk);
328
329 String colName = token.getStr();
330 localColumns.add(colName);
331 next();
332 while (token.getStr().equals(","))
333 {
334 next();
335 colName = token.getStr();
336 localColumns.add(colName);
337 next();
338 }
339 if (!token.getStr().toUpperCase().equals(")"))
340 {
341 err(") expected");
342 }
343
344 next();
345
346 if (!token.getStr().toUpperCase().equals("REFERENCES"))
347 {
348 err("REFERENCES expected");
349 }
350
351 next();
352
353 fk.setForeignTableName(token.getStr());
354
355 next();
356
357 if (token.getStr().toUpperCase().equals("("))
358 {
359 next();
360 int i = 0;
361 fk.addReference((String) localColumns.get(i++), token.getStr());
362 next();
363 while (token.getStr().equals(","))
364 {
365 next();
366 fk.addReference((String) localColumns.get(i++), token.getStr());
367 next();
368 }
369 if (!token.getStr().toUpperCase().equals(")"))
370 {
371 err(") expected");
372 }
373 next();
374 }
375 }
376
377
378
379
380
381
382 private void create_Table_Column_Data(Table tbl) throws ParseException
383 {
384 String columnSize = null;
385 String columnPrecision = null;
386 String columnDefault = null;
387 boolean inEnum = false;
388
389 String columnName = token.getStr();
390 next();
391 String columnType = token.getStr();
392
393 if (columnName.equals(")") && columnType.equals(";"))
394 {
395 return;
396 }
397
398 next();
399
400
401
402 if (columnType.toUpperCase().equals("ENUM"))
403 {
404 inEnum = true;
405 next();
406 while (!token.getStr().equals(")"))
407 {
408
409 next();
410 }
411 while (!token.getStr().equals(","))
412 {
413 if (token.getStr().toUpperCase().equals("DEFAULT"))
414 {
415 next();
416 if (token.getStr().equals("'"))
417 {
418 next();
419 }
420 columnDefault = token.getStr();
421 next();
422 if (token.getStr().equals("'"))
423 {
424 next();
425 }
426 }
427
428 next();
429 }
430 next();
431 columnType = "VARCHAR";
432 }
433 else if (token.getStr().toUpperCase().equals("("))
434 {
435 next();
436 columnSize = token.getStr();
437 next();
438 if (token.getStr().equals(","))
439 {
440 next();
441 columnPrecision = token.getStr();
442 next();
443 }
444
445 if (!token.getStr().equals(")"))
446 {
447 err(") expected");
448 }
449 next();
450 }
451
452 Column col = new Column(columnName);
453 if (columnPrecision != null)
454 {
455 columnSize = columnSize + columnPrecision;
456 }
457 col.setTypeFromString(columnType, columnSize);
458 tbl.addColumn(col);
459
460 if (inEnum)
461 {
462 col.setNotNull(true);
463 if (columnDefault != null)
464 {
465 col.setDefaultValue(columnDefault);
466 }
467 }
468 else
469 {
470 while (!token.getStr().equals(",") && !token.getStr().equals(")"))
471 {
472 if (token.getStr().toUpperCase().equals("NOT"))
473 {
474 next();
475 if (!token.getStr().toUpperCase().equals("NULL"))
476 {
477 err("NULL expected after NOT");
478 }
479 col.setNotNull(true);
480 next();
481 }
482 else if (token.getStr().toUpperCase().equals("PRIMARY"))
483 {
484 next();
485 if (!token.getStr().toUpperCase().equals("KEY"))
486 {
487 err("KEY expected after PRIMARY");
488 }
489 col.setPrimaryKey(true);
490 next();
491 }
492 else if (token.getStr().toUpperCase().equals("UNIQUE"))
493 {
494 col.setUnique(true);
495 next();
496 }
497 else if (token.getStr().toUpperCase().equals("NULL"))
498 {
499 col.setNotNull(false);
500 next();
501 }
502 else if (token.getStr().toUpperCase().equals("AUTO_INCREMENT"))
503 {
504 col.setAutoIncrement(true);
505 next();
506 }
507 else if (token.getStr().toUpperCase().equals("DEFAULT"))
508 {
509 next();
510 if (token.getStr().equals("'"))
511 {
512 next();
513 }
514 col.setDefaultValue(token.getStr());
515 next();
516 if (token.getStr().equals("'"))
517 {
518 next();
519 }
520 }
521 else
522 {
523 StringBuffer line = new StringBuffer();
524 for (Iterator tokenIt = tokens.iterator();
525 tokenIt.hasNext();)
526 {
527 line.append(tokenIt.next());
528 if (tokenIt.hasNext())
529 {
530 line.append(" ");
531 }
532 }
533 throw new ParseException("Error parsing line "
534 + line + " : Unknown token Nr. "
535 + count
536 + " : "
537 + token);
538 }
539 }
540 next();
541 }
542 }
543
544
545
546
547
548
549
550 public Database execute() throws IOException, ParseException
551 {
552 count = 0;
553 appDataDB = new Database(databaseType);
554
555 FileReader fr = new FileReader(sqlFile);
556 BufferedReader br = new BufferedReader(fr);
557 SQLScanner scanner = new SQLScanner(br);
558
559 tokens = scanner.scan();
560
561 br.close();
562
563 while (hasTokens())
564 {
565 if (token == null)
566 {
567 next();
568 }
569
570 if (token.getStr().toUpperCase().equals("CREATE"))
571 {
572 create();
573 }
574 if (hasTokens())
575 {
576 next();
577 }
578 }
579 return appDataDB;
580 }
581 }