Source Code Cross Referenced for tinySQLParser.java in  » Database-DBMS » TinySQL » com » sqlmagic » tinysql » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » TinySQL » com.sqlmagic.tinysql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * tinySQLParser
003:         * 
004:         * $Author: davis $
005:         * $Date: 2004/12/18 21:28:17 $
006:         * $Revision: 1.1 $
007:         *
008:         * This simple token based parser replaces the CUP generated parser
009:         * simplifying extensions and reducing the total amount of code in 
010:         * tinySQL considerably.
011:         *
012:         * This library is free software; you can redistribute it and/or
013:         * modify it under the terms of the GNU Lesser General Public
014:         * License as published by the Free Software Foundation; either
015:         * version 2.1 of the License, or (at your option) any later version.
016:         *
017:         * This library is distributed in the hope that it will be useful,
018:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
019:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
020:         * Lesser General Public License for more details.
021:         *
022:         * You should have received a copy of the GNU Lesser General Public
023:         * License along with this library; if not, write to the Free Software
024:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
025:         *
026:         * Revision History;
027:         *
028:         * Written by Davis Swan in April, 2004.
029:         */
030:
031:        package com.sqlmagic.tinysql;
032:
033:        import java.io.*;
034:        import java.util.*;
035:        import java.text.*;
036:        import java.sql.Types;
037:
038:        public class tinySQLParser {
039:            Vector columnList, tableList, actionList, valueList, contextList,
040:                    columnAliasList, columns;
041:            Hashtable tables;
042:            tinySQL dbEngine;
043:            tinySQLWhere whereClause;
044:            String tableName, tableAlias, dataDir;
045:            String statementType = (String) null;
046:            String lastKeyWord = (String) null, orderType = (String) null;
047:            String oldColumnName = (String) null,
048:                    newColumnName = (String) null;
049:            String[] colTypeNames = { "INT", "FLOAT", "CHAR", "DATE" };
050:            int[] colTypes = { Types.INTEGER, Types.FLOAT, Types.CHAR,
051:                    Types.DATE };
052:            boolean distinct = false, defaultOrderBy = true;
053:
054:            public tinySQLParser(InputStream sqlInput, tinySQL inputEngine)
055:                    throws tinySQLException {
056:                StreamTokenizer st;
057:                FieldTokenizer ft;
058:                Reader r;
059:                String nextToken, upperField, nextField, keyWord = (String) null;
060:                StringBuffer cmdBuffer, inputSQLBuffer;
061:                int lastIndex, keyIndex;
062:                r = new BufferedReader(new InputStreamReader(sqlInput));
063:                dbEngine = inputEngine;
064:                actionList = new Vector();
065:                columnList = new Vector();
066:                columns = new Vector();
067:                columnAliasList = new Vector();
068:                contextList = new Vector();
069:                valueList = new Vector();
070:                tableName = (String) null;
071:                whereClause = (tinySQLWhere) null;
072:                /*
073:                 *    The tableList is a list of table names, in the optimal order 
074:                 *    in which they should be scanned for the SELECT phrase.
075:                 *    The Hashtable tables contains table objects keyed by table
076:                 *    alias and name.
077:                 */
078:                tableList = new Vector();
079:                tables = new Hashtable();
080:                tables.put("TABLE_SELECT_ORDER", tableList);
081:                try {
082:                    st = new StreamTokenizer(r);
083:                    st.eolIsSignificant(false);
084:                    st.wordChars('\'', '}');
085:                    st.wordChars('?', '?');
086:                    st.wordChars('"', '.');
087:                    st.ordinaryChars('0', '9');
088:                    st.wordChars('0', '9');
089:                    cmdBuffer = new StringBuffer();
090:                    inputSQLBuffer = new StringBuffer();
091:                    while (st.nextToken() != StreamTokenizer.TT_EOF) {
092:                        if (st.ttype == StreamTokenizer.TT_WORD)
093:                            nextToken = st.sval.trim();
094:                        else
095:                            continue;
096:                        if (inputSQLBuffer.length() > 0)
097:                            inputSQLBuffer.append(" ");
098:                        inputSQLBuffer.append(nextToken);
099:                    }
100:                    ft = new FieldTokenizer(inputSQLBuffer.toString(), ' ',
101:                            false);
102:                    while (ft.hasMoreFields()) {
103:                        nextField = ft.nextField();
104:                        upperField = nextField.toUpperCase();
105:                        if (statementType == (String) null) {
106:                            statementType = upperField;
107:                            lastIndex = getKeywordIndex(statementType,
108:                                    statementType);
109:                            if (lastIndex != 0)
110:                                throwException(9);
111:                            keyWord = statementType;
112:                        } else {
113:                            keyIndex = getKeywordIndex(statementType,
114:                                    upperField);
115:                            if (keyIndex < 0) {
116:                                if (cmdBuffer.length() > 0)
117:                                    cmdBuffer.append(" ");
118:                                cmdBuffer.append(nextField);
119:                            } else {
120:                                setPhrase(keyWord, cmdBuffer.toString());
121:                                cmdBuffer = new StringBuffer();
122:                                keyWord = upperField;
123:                                if (tinySQLGlobals.PARSER_DEBUG)
124:                                    System.out.println("Found keyword "
125:                                            + keyWord);
126:                            }
127:                        }
128:                    }
129:                    if (keyWord != (String) null)
130:                        setPhrase(keyWord, cmdBuffer.toString());
131:                    addAction();
132:                    if (tinySQLGlobals.PARSER_DEBUG)
133:                        System.out.println("SQL:" + inputSQLBuffer.toString());
134:                } catch (Exception ex) {
135:                    if (tinySQLGlobals.DEBUG)
136:                        ex.printStackTrace(System.out);
137:                    throw new tinySQLException(ex.getMessage());
138:                }
139:            }
140:
141:            /*
142:             * This method sets up particular phrase elements for the SQL command.
143:             * Examples would be a list of selected columns and tables for a SELECT
144:             * statement, or a list of column definitions for a CREATE TABLE
145:             * statement.  These phrase elements will be added to the action list
146:             * once the entire statement has been parsed.
147:             */
148:            public void setPhrase(String inputKeyWord, String inputString)
149:                    throws tinySQLException {
150:                String nextField, upperField, colTypeStr, colTypeSpec, fieldString, syntaxErr, tempString, columnName, columnAlias;
151:                StringBuffer colTypeBuffer, concatBuffer;
152:                FieldTokenizer ft1, ft2, ft3;
153:                tsColumn createColumn;
154:                int i, j, k, lenc, colType, countFields;
155:                /*
156:                 *    Handle compound keywords.
157:                 */
158:                if (inputString == (String) null) {
159:                    lastKeyWord = inputKeyWord;
160:                    return;
161:                } else if (inputString.trim().length() == 0) {
162:                    lastKeyWord = inputKeyWord;
163:                    return;
164:                }
165:                if (tinySQLGlobals.PARSER_DEBUG)
166:                    System.out.println("setPhrase " + inputString);
167:                ft1 = new FieldTokenizer(inputString, ',', false);
168:                while (ft1.hasMoreFields()) {
169:                    nextField = ft1.nextField().trim();
170:                    if (tinySQLGlobals.PARSER_DEBUG)
171:                        System.out.println(inputKeyWord + " field is "
172:                                + nextField);
173:                    upperField = nextField.toUpperCase();
174:                    if (inputKeyWord.equals("SELECT")) {
175:                        /*
176:                         *          Check for the keyword DISTINCT
177:                         */
178:                        if (nextField.toUpperCase().startsWith("DISTINCT")) {
179:                            distinct = true;
180:                            nextField = nextField.substring(9).trim();
181:                        }
182:                        /*
183:                         *          Check for and set column alias.
184:                         */
185:                        ft2 = new FieldTokenizer(nextField, ' ', false);
186:                        columnName = ft2.getField(0);
187:                        columnAlias = (String) null;
188:                        /*
189:                         *          A column alias can be preceded by the keyword AS which will
190:                         *          be ignored by tinySQL.
191:                         */
192:                        if (ft2.countFields() == 2)
193:                            columnAlias = ft2.getField(1);
194:                        else if (ft2.countFields() == 3)
195:                            columnAlias = ft2.getField(2);
196:                        /*
197:                         *          Check for column concatenation using the | symbol
198:                         */
199:                        ft2 = new FieldTokenizer(columnName, '|', false);
200:                        if (ft2.countFields() > 1) {
201:                            concatBuffer = new StringBuffer("CONCAT(");
202:                            while (ft2.hasMoreFields()) {
203:                                if (concatBuffer.length() > 7)
204:                                    concatBuffer.append(",");
205:                                concatBuffer.append(ft2.nextField());
206:                            }
207:                            columnName = concatBuffer.toString() + ")";
208:                        }
209:                        columnList.addElement(columnName);
210:                        columnAliasList.addElement(columnAlias);
211:                        contextList.addElement(inputKeyWord);
212:                    } else if (inputKeyWord.equals("TABLE")) {
213:                        /*
214:                         *          If the input keyword is TABLE, update the statement type to be a 
215:                         *          compound type such as CREATE_TABLE, DROP_TABLE, or ALTER_TABLE.
216:                         */
217:                        if (!statementType.equals("INSERT"))
218:                            statementType = statementType + "_TABLE";
219:                        if (statementType.equals("CREATE_TABLE")) {
220:                            /*
221:                             *             Parse out the column definition.
222:                             */
223:                            ft2 = new FieldTokenizer(nextField, '(', false);
224:                            if (ft2.countFields() != 2)
225:                                throwException(1);
226:                            tableName = ft2.getField(0);
227:                            fieldString = ft2.getField(1);
228:                            ft2 = new FieldTokenizer(fieldString, ',', false);
229:                            while (ft2.hasMoreFields()) {
230:                                tempString = ft2.nextField();
231:                                createColumn = parseColumnDefn(tempString);
232:                                if (createColumn != (tsColumn) null)
233:                                    columnList.addElement(createColumn);
234:                            }
235:                        } else if (statementType.equals("DROP_TABLE")) {
236:                            /*
237:                             *             Handle dropping of non-existent tables
238:                             */
239:                            tableName = upperField;
240:                            try {
241:                                validateTable(upperField, true);
242:                            } catch (Exception dropEx) {
243:                                throw new tinySQLException("Table " + tableName
244:                                        + " does not exist.");
245:                            }
246:                        } else {
247:                            tableName = upperField;
248:                            validateTable(upperField, true);
249:                        }
250:                    } else if (inputKeyWord.equals("BY")) {
251:                        /*
252:                         *          Set up Group by and Order by columns.
253:                         */
254:                        if (lastKeyWord == (String) null) {
255:                            throwException(6);
256:                        } else {
257:                            ft3 = new FieldTokenizer(upperField, ' ', false);
258:                            columnList.addElement(ft3.getField(0));
259:                            if (ft3.countFields() == 2) {
260:                                /*
261:                                 *                ASC or DESC are the only allowable directives after GROUP BY
262:                                 */
263:                                if (ft3.getField(1).startsWith("ASC")
264:                                        | ft3.getField(1).startsWith("DESC"))
265:                                    orderType = ft3.getField(1);
266:                                else
267:                                    throwException(7);
268:                            }
269:                            if (lastKeyWord.equals("ORDER"))
270:                                defaultOrderBy = false;
271:                            contextList.addElement(lastKeyWord);
272:                        }
273:                    } else if (inputKeyWord.equals("DROP")) {
274:                        /*
275:                         *          Parse list of columns to be dropped.
276:                         */
277:                        statementType = "ALTER_DROP";
278:                        ft2 = new FieldTokenizer(upperField, ' ', false);
279:                        while (ft2.hasMoreFields()) {
280:                            columnList.addElement(UtilString.removeQuotes(ft2
281:                                    .nextField()));
282:                        }
283:                    } else if (inputKeyWord.equals("RENAME")) {
284:                        /*
285:                         *          Parse old and new column name.
286:                         */
287:                        statementType = "ALTER_RENAME";
288:                        ft2 = new FieldTokenizer(upperField, ' ', false);
289:                        oldColumnName = ft2.getField(0);
290:                        newColumnName = ft2.getField(1);
291:                        if (newColumnName.equals("TO") & ft2.countFields() == 3)
292:                            newColumnName = ft2.getField(2);
293:                        if (newColumnName.length() > 11)
294:                            newColumnName = tinySQLGlobals
295:                                    .getShortName(newColumnName);
296:                    } else if (inputKeyWord.equals("ADD")) {
297:                        /*
298:                         *          Parse definition of columns to be added.
299:                         */
300:                        statementType = "ALTER_ADD";
301:                        createColumn = parseColumnDefn(nextField);
302:                        if (createColumn != (tsColumn) null)
303:                            columnList.addElement(createColumn);
304:                    } else if (inputKeyWord.equals("FROM")) {
305:                        /*
306:                         *          Check for valid table 
307:                         */
308:                        tableName = upperField;
309:                        validateTable(tableName);
310:                    } else if (inputKeyWord.equals("INTO")) {
311:                        ft2 = new FieldTokenizer(nextField, '(', false);
312:                        if (ft2.countFields() != 2)
313:                            throwException(3);
314:                        tableName = ft2.getField(0).toUpperCase();
315:                        validateTable(tableName);
316:                        fieldString = ft2.getField(1).toUpperCase();
317:                        ft2 = new FieldTokenizer(fieldString, ',', false);
318:                        while (ft2.hasMoreFields()) {
319:                            tempString = UtilString.removeQuotes(ft2
320:                                    .nextField());
321:                            columnList.addElement(tempString);
322:                            contextList.addElement(inputKeyWord);
323:                        }
324:                    } else if (inputKeyWord.equals("VALUES")) {
325:                        ft2 = new FieldTokenizer(nextField, '(', false);
326:                        fieldString = ft2.getField(0);
327:                        ft2 = new FieldTokenizer(fieldString, ',', false);
328:                        while (ft2.hasMoreFields()) {
329:                            tempString = UtilString.removeQuotes(ft2
330:                                    .nextField());
331:                            tempString = UtilString.replaceAll(tempString,
332:                                    "''", "'");
333:                            valueList.addElement(tempString);
334:                        }
335:                    } else if (inputKeyWord.equals("UPDATE")) {
336:                        tableName = nextField.toUpperCase();
337:                        validateTable(tableName);
338:                    } else if (inputKeyWord.equals("SET")) {
339:                        /*
340:                         *          Parse the update column name/value pairs
341:                         */
342:                        ft2 = new FieldTokenizer(nextField, '=', false);
343:                        if (ft2.countFields() != 2)
344:                            throwException(4);
345:                        columnList.addElement(ft2.getField(0));
346:                        contextList.addElement(inputKeyWord);
347:                        valueList.addElement(UtilString.removeQuotes(ft2
348:                                .getField(1)));
349:                    } else if (inputKeyWord.equals("WHERE")) {
350:                        whereClause = new tinySQLWhere(nextField, tables);
351:                    } else if (!inputKeyWord.equals("TABLE")) {
352:                        throwException(10);
353:                    }
354:                }
355:                lastKeyWord = inputKeyWord;
356:            }
357:
358:            public void validateTable(String tableSpec) throws tinySQLException {
359:                validateTable(tableSpec, false);
360:            }
361:
362:            public void validateTable(String tableSpec, boolean closeTable)
363:                    throws tinySQLException {
364:                /*
365:                 *    Create a table object for each table used in the SELECT statement
366:                 *    and store these objects in the tables Hashtable.  Save the original
367:                 *    list of table names to set the default selection order.
368:                 *
369:                 *    If closeTable is true the table object will be closed after it is
370:                 *    validated (for DROP TABLE and ALTER TABLE commands).
371:                 */
372:                String tableName, tableAlias, tableNameAndAlias, sortName;
373:                tinySQLTable addTable, sortTable;
374:                boolean tableAdded;
375:                FieldTokenizer ftTable;
376:                int i, addRowCount, sortRowCount;
377:                ftTable = new FieldTokenizer(tableSpec, ' ', false);
378:                tableName = ftTable.getField(0);
379:                tableAlias = (ftTable.getField(1, tableName)).toUpperCase();
380:                tableNameAndAlias = tableName + "->" + tableAlias;
381:                addTable = dbEngine.getTable(tableNameAndAlias);
382:                addTable.GoTop();
383:                addRowCount = addTable.GetRowCount();
384:                if (closeTable)
385:                    addTable.close();
386:                if (tinySQLGlobals.PARSER_DEBUG)
387:                    System.out.println("Add table " + tableNameAndAlias
388:                            + " to tables");
389:                tables.put(tableNameAndAlias, addTable);
390:                tableAdded = false;
391:                for (i = 0; i < tableList.size(); i++) {
392:                    sortName = (String) tableList.elementAt(i);
393:                    sortTable = (tinySQLTable) tables.get(sortName);
394:                    sortRowCount = sortTable.GetRowCount();
395:                    /*
396:                     *       Sort the table selections from smallest to largest table to 
397:                     *       enhance the query performance.
398:                     */
399:                    if (addRowCount > sortRowCount)
400:                        continue;
401:                    tableList.insertElementAt(tableNameAndAlias, i);
402:                    tableAdded = true;
403:                    break;
404:                }
405:                if (!tableAdded)
406:                    tableList.addElement(tableNameAndAlias);
407:                if (tinySQLGlobals.PARSER_DEBUG) {
408:                    System.out.println("Table selection order");
409:                    for (i = 0; i < tableList.size(); i++) {
410:                        sortName = (String) tableList.elementAt(i);
411:                        sortTable = (tinySQLTable) tables.get(sortName);
412:                        sortRowCount = sortTable.GetRowCount();
413:                        System.out.println(sortName + " " + sortRowCount);
414:                    }
415:                }
416:            }
417:
418:            /*
419:             * Validate the column specifications by checking against the tables.
420:             */
421:            public void validateColumns() throws tinySQLException {
422:                String columnName, columnAlias, columnContext;
423:                tsColumn columnObject;
424:                boolean selectStar;
425:                tinySQLTable jtbl;
426:                int i, j;
427:                /*
428:                 *    Check for a column named *
429:                 */
430:                selectStar = false;
431:                for (i = 0; i < columnList.size(); i++) {
432:                    columnName = (String) columnList.elementAt(i);
433:                    columnContext = (String) contextList.elementAt(i);
434:                    if (columnName.equals("*")) {
435:                        if (!columnContext.equals("SELECT"))
436:                            throw new tinySQLException(
437:                                    "* must be a SELECT column.");
438:                        selectStar = true;
439:                        break;
440:                    }
441:                }
442:                if (selectStar) {
443:                    /*
444:                     *       A column * has been found.  Delete the existing list of SELECT
445:                     *       columns and replace by using an enumeration variable to cycle through 
446:                     *       the columns in the tables Hashtable.
447:                     */
448:                    for (i = 0; i < columnList.size(); i++) {
449:                        columnContext = (String) contextList.elementAt(i);
450:                        if (columnContext.equals("SELECT")) {
451:                            columnList.removeElementAt(i);
452:                            contextList.removeElementAt(i);
453:                            columnAliasList.removeElementAt(i);
454:                        }
455:                    }
456:                    for (i = 0; i < tableList.size(); i++) {
457:                        jtbl = (tinySQLTable) tables.get((String) tableList
458:                                .elementAt(i));
459:                        /*
460:                         *          Expand to all columns.
461:                         */
462:                        for (j = 0; j < jtbl.columnNameKeys.size(); j++) {
463:                            columnName = (String) jtbl.columnNameKeys
464:                                    .elementAt(j);
465:                            columnList.addElement(jtbl.table + "->"
466:                                    + jtbl.tableAlias + "." + columnName);
467:                            columnAliasList.addElement(columnName);
468:                            contextList.addElement("SELECT");
469:                        }
470:                    }
471:                }
472:                /*
473:                 *    Build a column object for each selected column.
474:                 */
475:                if (tables == (Hashtable) null)
476:                    System.out
477:                            .println("*****Column validation - no tables defined.");
478:                for (i = 0; i < columnList.size(); i++) {
479:                    columnName = (String) columnList.elementAt(i);
480:                    columnContext = (String) contextList.elementAt(i);
481:                    columnAlias = (String) null;
482:                    if (i < columnAliasList.size())
483:                        columnAlias = (String) columnAliasList.elementAt(i);
484:                    columnObject = new tsColumn(columnName, tables,
485:                            columnContext);
486:                    columnObject.alias = UtilString.removeQuotes(columnAlias);
487:                    columns.addElement(columnObject);
488:                }
489:            }
490:
491:            /*
492:             * Parse out the column definition for a CREATE statement.
493:             */
494:            public tsColumn parseColumnDefn(String columnDefn)
495:                    throws tinySQLException {
496:                tsColumn createColumn;
497:                int i;
498:                FieldTokenizer ft;
499:                String columnName, fieldString, tempString, colTypeStr, colTypeSpec;
500:                ft = new FieldTokenizer(columnDefn.toUpperCase(), ' ', false);
501:                /*
502:                 *    A column definition must consist of a column name followed by a 
503:                 *    column specification.
504:                 */
505:                if (ft.countFields() < 2)
506:                    throwException(2);
507:                columnName = ft.getField(0);
508:                /*
509:                 *    Check for quotes around a column name that may contain blanks.
510:                 */
511:                if (columnName.charAt(0) == '"'
512:                        & columnName.charAt(columnName.length() - 1) == '"')
513:                    columnName = columnName.substring(1,
514:                            columnName.length() - 1);
515:                if (columnName.length() > 11) {
516:                    columnName = tinySQLGlobals.getShortName(columnName);
517:                }
518:                createColumn = new tsColumn(columnName);
519:                colTypeStr = "";
520:                for (i = 1; i < ft.countFields(); i++)
521:                    colTypeStr += ft.getField(1);
522:                ft = new FieldTokenizer(colTypeStr, '(', false);
523:                colTypeStr = ft.getField(0);
524:                createColumn.size = 10;
525:                createColumn.decimalPlaces = 0;
526:                if (colTypeStr.equals("FLOAT")) {
527:                    createColumn.size = 12;
528:                    createColumn.decimalPlaces = 2;
529:                }
530:                colTypeSpec = ft.getField(1);
531:                if (!colTypeSpec.equals("NULL")) {
532:                    /*
533:                     *       Parse out the scale and precision if supplied.
534:                     */
535:                    ft = new FieldTokenizer(colTypeSpec, ',', false);
536:                    createColumn.size = ft.getInt(0, 8);
537:                    createColumn.decimalPlaces = ft.getInt(1, 0);
538:                }
539:                createColumn.type = Integer.MIN_VALUE;
540:                for (i = 0; i < colTypeNames.length; i++)
541:                    if (colTypeStr.equals(colTypeNames[i]))
542:                        createColumn.type = colTypes[i];
543:                if (createColumn.type == Integer.MIN_VALUE)
544:                    throwException(8);
545:                if (tinySQLGlobals.PARSER_DEBUG)
546:                    System.out.println("Column " + createColumn.name
547:                            + ", type is " + createColumn.type + ",size is "
548:                            + createColumn.size + ",precision is "
549:                            + createColumn.decimalPlaces);
550:                return createColumn;
551:            }
552:
553:            /*
554:             * This method is used to identify SQL key words, and the order in which they
555:             * should appear in the SQL statement.
556:             */
557:            public int getKeywordIndex(String inputContext, String inputWord) {
558:                String[][] sqlSyntax = {
559:                        { "SELECT", "FROM", "WHERE", "GROUP", "ORDER", "BY" },
560:                        { "INSERT", "INTO", "VALUES" }, { "DROP", "TABLE" },
561:                        { "DELETE", "FROM", "WHERE" }, { "CREATE", "TABLE" },
562:                        { "UPDATE", "SET", "WHERE" },
563:                        { "ALTER", "TABLE", "DROP", "MODIFY", "ADD", "RENAME" } };
564:                int i, j;
565:                for (i = 0; i < sqlSyntax.length; i++) {
566:                    for (j = 0; j < sqlSyntax[i].length; j++) {
567:                        if (sqlSyntax[i][0].equals(inputContext)
568:                                & sqlSyntax[i][j].equals(inputWord))
569:                            return j;
570:                    }
571:                }
572:                return Integer.MIN_VALUE;
573:            }
574:
575:            /*
576:             * Add an action Hashtable to the list of actions
577:             */
578:            public void addAction() throws tinySQLException,
579:                    CloneNotSupportedException {
580:                int i, columnCount;
581:                tsColumn checkColumn, orderColumn;
582:                Hashtable newAction = new Hashtable();
583:                newAction.put("TYPE", statementType);
584:                if (statementType.equals("SELECT")) {
585:                    newAction.put("TABLES", tables);
586:                    if (whereClause != (tinySQLWhere) null)
587:                        newAction.put("WHERE", whereClause);
588:                    /*
589:                     *       Validate the column specifications and expand * if present
590:                     */
591:                    validateColumns();
592:                    /*
593:                     *       If no ORDER BY clause was specified, default to the list of
594:                     *       SELECT columns.
595:                     */
596:                    if (defaultOrderBy) {
597:                        columnCount = columns.size();
598:                        for (i = 0; i < columnCount; i++) {
599:                            orderColumn = (tsColumn) (columns.elementAt(i));
600:                            if (orderColumn.getContext("SELECT")) {
601:                                orderColumn.addContext("ORDER");
602:                            }
603:                        }
604:                    }
605:                    newAction.put("COLUMNS", columns);
606:                    if (orderType != (String) null)
607:                        newAction.put("ORDER_TYPE", orderType);
608:                    if (distinct)
609:                        newAction.put("DISTINCT", "TRUE");
610:                } else if (statementType.equals("DROP_TABLE")) {
611:                    newAction.put("TABLE", tableName);
612:                } else if (statementType.equals("CREATE_TABLE")) {
613:                    newAction.put("TABLE", tableName);
614:                    newAction.put("COLUMN_DEF", columnList);
615:                } else if (statementType.equals("ALTER_RENAME")) {
616:                    newAction.put("TABLE", tableName);
617:                    newAction.put("OLD_COLUMN", oldColumnName);
618:                    newAction.put("NEW_COLUMN", newColumnName);
619:                } else if (statementType.equals("ALTER_ADD")) {
620:                    newAction.put("TABLE", tableName);
621:                    newAction.put("COLUMN_DEF", columnList);
622:                } else if (statementType.equals("ALTER_DROP")) {
623:                    newAction.put("TABLE", tableName);
624:                    newAction.put("COLUMNS", columnList);
625:                } else if (statementType.equals("DELETE")) {
626:                    newAction.put("TABLE", tableName);
627:                    if (whereClause != (tinySQLWhere) null)
628:                        newAction.put("WHERE", whereClause);
629:                } else if (statementType.equals("INSERT")
630:                        | statementType.equals("UPDATE")) {
631:                    newAction.put("TABLE", tableName);
632:                    if (columnList.size() != valueList.size())
633:                        throwException(5);
634:                    newAction.put("COLUMNS", columnList);
635:                    newAction.put("VALUES", valueList);
636:                    if (whereClause != (tinySQLWhere) null)
637:                        newAction.put("WHERE", whereClause);
638:                }
639:                actionList.addElement(newAction);
640:            }
641:
642:            public void throwException(int exceptionNumber)
643:                    throws tinySQLException {
644:                throwException(exceptionNumber, (String) null);
645:            }
646:
647:            public void throwException(int exceptionNumber, String parameter)
648:                    throws tinySQLException {
649:                String exMsg = (String) null;
650:                if (exceptionNumber == 1)
651:                    exMsg = "CREATE TABLE must be followed by a table name and a list"
652:                            + " of column specifications enclosed in brackets.";
653:                else if (exceptionNumber == 2)
654:                    exMsg = "A column specification must consist of a column name"
655:                            + " followed by a column type specification.";
656:                else if (exceptionNumber == 3)
657:                    exMsg = "INTO should be followed by a table name and "
658:                            + "a list of columns enclosed in backets.";
659:                else if (exceptionNumber == 4)
660:                    exMsg = "SET must be followed by assignments in the form"
661:                            + " <columnName>=<value>.";
662:                else if (exceptionNumber == 5)
663:                    exMsg = "INSERT statement number of columns and values provided"
664:                            + " do not match.";
665:                else if (exceptionNumber == 6)
666:                    exMsg = "BY cannot be the first keyword.";
667:                else if (exceptionNumber == 7)
668:                    exMsg = "ORDER BY can only be followed by the ASC or DESC directives";
669:                else if (exceptionNumber == 8)
670:                    exMsg = "Supported column types are INT,CHAR,FLOAT,DATE";
671:                else if (exceptionNumber == 9)
672:                    exMsg = "Expecting SELECT, INSERT, ALTER, etc. in "
673:                            + statementType;
674:                else if (exceptionNumber == 10)
675:                    exMsg = "Unrecognized keyword ";
676:                throw new tinySQLException(exMsg);
677:            }
678:
679:            public Vector getActions() {
680:                return actionList;
681:            }
682:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.