Source Code Cross Referenced for tinySQL.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:         * tinySQL.java 
003:         *
004:         * A trivial implementation of SQL in an abstract class.
005:         * Plug it in to your favorite non-SQL data source, and
006:         * QUERY AWAY!
007:         *
008:         * Copyright 1996, Brian C. Jepson
009:         *                 (bjepson@ids.net)
010:         *
011:         * $Author: davis $
012:         * $Date: 2004/12/18 21:23:50 $
013:         * $Revision: 1.1 $
014:         *
015:         * This library is free software; you can redistribute it and/or
016:         * modify it under the terms of the GNU Lesser General Public
017:         * License as published by the Free Software Foundation; either
018:         * version 2.1 of the License, or (at your option) any later version.
019:         *
020:         * This library is distributed in the hope that it will be useful,
021:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
022:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
023:         * Lesser General Public License for more details.
024:         *
025:         * You should have received a copy of the GNU Lesser General Public
026:         * License along with this library; if not, write to the Free Software
027:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
028:         *
029:         * Revision History:
030:         *
031:         * Major rewrite in 2003/4 by Davis Swan SQL*Magic Ltd.
032:         */
033:
034:        package com.sqlmagic.tinysql;
035:
036:        import java.util.*;
037:        import java.lang.*;
038:        import java.io.*;
039:        import java.sql.SQLException;
040:        import java.sql.Types;
041:
042:        /**
043:         * @author Thomas Morger <mgs@sherito.org> Changed tinySQL to reflect changes
044:         * in tinySQLResultSet - an instance of the connection is passed to a new 
045:         * resultset at construction time.
046:         *
047:         * When fetching a resultset, the number of rows to fetch can be set in the
048:         * statement. The builder will return when the given number of rows has been 
049:         * reached and will be restarted by tsResultSet when more rows are needed.
050:         */
051:        public abstract class tinySQL {
052:
053:            boolean debug = false, groupBreak = false, keepRecord = true;
054:            boolean exDebug = false, performDebug = false;
055:            Hashtable groupFunctions;
056:            String newLine = System.getProperty("line.separator");
057:            static tinySQLTable insertTable = (tinySQLTable) null;
058:            tinySQLWhere wc;
059:            // This is the InputStream from which the parser reads.
060:            // 
061:            private InputStream SQLStream;
062:
063:            // This is the last SQL Statement processed by sqlexec(String s).
064:            // Note that sqlexec() does *not* support this.
065:            //
066:            private tinySQLStatement sqlstatement = null;
067:
068:            /*
069:             *
070:             * Constructs a new tinySQL object.
071:             *
072:             */
073:            public tinySQL() {
074:
075:            }
076:
077:            /*
078:             * Reads SQL statements from System.in() and returns a
079:             * tsResultSet for the last statement executed. This is
080:             * really only good for testing.
081:             * 
082:             * @exception tinySQLException
083:             */
084:            public tsResultSet sqlexec() throws tinySQLException {
085:
086:                SQLStream = (InputStream) System.in;
087:                System.err.println("Reading SQL Statements from STDIN...");
088:                System.err.println("CRASHING AFTER THIS POINT IS SURE...");
089:                System.err
090:                        .println("Have no Statement, no connection and no clue how to continue ...");
091:                return sql(null);
092:
093:            }
094:
095:            /*
096:             * Processes the SQL Statement s and returns
097:             * a tsResultSet.
098:             *
099:             * @param s SQL Statement to execute
100:             * @exception tinySQLException
101:             */
102:            public tsResultSet sqlexec(tinySQLStatement s)
103:                    throws tinySQLException {
104:                return sql(s);
105:            }
106:
107:            public tsResultSet sqlexec(tinySQLPreparedStatement s)
108:                    throws tinySQLException {
109:                return sql(s);
110:            }
111:
112:            /*
113:             *
114:             * Read SQL Statements from the SQLStream, and
115:             * return a result set for the last SQL Statement
116:             * executed.
117:             *
118:             * @returns the ResultSet or null, if no result set was created
119:             * @exception tinySQLException
120:             *
121:             */
122:            protected tsResultSet sql(Object s) throws tinySQLException {
123:                /*
124:                 *    Build the ResultSet
125:                 */
126:                tsResultSet rs = null;
127:                tinySQLTable jtbl;
128:                tinySQLPreparedStatement pstmt = (tinySQLPreparedStatement) null;
129:                boolean useTinyParser = true, distinct = false;
130:                Vector actions, columns, columnDefs, values, columnContexts, columnAliases;
131:                String actionType, orderType, tableName, statementType, byteString;
132:                Hashtable h, selectTables;
133:                byte[] bStream;
134:                ByteArrayInputStream st;
135:                int i;
136:                String actionString;
137:                groupBreak = false;
138:                keepRecord = true;
139:                statementType = s.getClass().getName();
140:                try {
141:                    /*
142:                     *       Instantiate a new parser object which reads from the SQLStream.  This
143:                     *       should probably be changed to a String at some point.  Note that 
144:                     *       parsing is only done once for a PreparedStatement.
145:                     */
146:                    actions = (Vector) null;
147:                    if (statementType.endsWith("tinySQLPreparedStatement")) {
148:                        pstmt = (tinySQLPreparedStatement) s;
149:                        pstmt.updateActions(actions);
150:                        actions = pstmt.getActions();
151:                        byteString = pstmt.getSQLString();
152:                        bStream = (byte[]) null;
153:                        if (pstmt.getSQLString() != (String) null)
154:                            bStream = pstmt.getSQLString().getBytes();
155:                    } else if (statementType.endsWith("tinySQLStatement")) {
156:                        bStream = ((tinySQLStatement) s).getSQLString()
157:                                .getBytes();
158:                    } else {
159:                        throw new tinySQLException("Unknown statement type"
160:                                + statementType);
161:                    }
162:                    if (actions == (Vector) null) {
163:                        st = new ByteArrayInputStream(bStream);
164:                        SQLStream = (InputStream) st;
165:                        tinySQLParser tinyp = new tinySQLParser(SQLStream, this );
166:                        tinySQLGlobals.writeLongNames();
167:                        actions = tinyp.getActions();
168:                        if (statementType.endsWith("tinySQLPreparedStatement"))
169:                            pstmt.updateActions(actions);
170:                    }
171:                    /*
172:                     *       The actions Vector consists of a list of Hashtables.  Each of these
173:                     *       action Hashtables contains elements required for a particular SQL
174:                     *       statement. The following elements are used for various actions;
175:                     *
176:                     *       Type          Name           Description          
177:                     *
178:                     *       String        tableName      The name of the affected table for 
179:                     *                                    CREATE,INSERT,UPDATE,DELETE actions.
180:                     *
181:                     *       Hashtable     selectTables   Hashtable of tables in a SELECT action. 
182:                     *
183:                     *       Vector        columns        A list of column names used by the
184:                     *                                    the action.
185:                     *
186:                     *       Vector        columnContexts A list of Strings indicating the context
187:                     *                                    for the elements in the columns Vector.
188:                     *                                    Values can be SELECT,ORDER,GROUP.
189:                     *      
190:                     *       Vector        columnDefs     A list of column objects used by the 
191:                     *                                    CREATE TABLE and ALTER TABLE ADD actions.
192:                     *            
193:                     *       Vector        values         A list of String values used in INSERT
194:                     *                                    and UPDATE actions.
195:                     *
196:                     *       String        oldColumnName  Old column name for the 
197:                     *                                    ALTER TABLE RENAME action.
198:                     *
199:                     *       String        newColumnName  New column name for the
200:                     *                                    ALTER TABLE RENAME action.
201:                     *            
202:                     *       String        orderType      Type or ORDER BY - ASC or DESC.
203:                     *
204:                     *       String        distinct       Distinct rows only - TRUE or NULL
205:                     *            
206:                     *       tinySQLWhere  whereClause    An object containing the where clause
207:                     *                                    which can be updated and queried.
208:                     */
209:                    for (i = 0; i < actions.size(); i++) {
210:                        h = (Hashtable) actions.elementAt(i);
211:                        actionType = (String) h.get("TYPE");
212:                        if (tinySQLGlobals.DEBUG)
213:                            System.out.println("Action: " + actionType);
214:                        /*
215:                         *          Many actions have a table specification.  If this one, build
216:                         *          a table object to update the where clause if there is one.
217:                         */
218:                        tableName = (String) h.get("TABLE");
219:                        wc = (tinySQLWhere) h.get("WHERE");
220:                        if (tableName != (String) null
221:                                & !actionType.equals("DROP_TABLE")
222:                                & !actionType.equals("CREATE_TABLE")
223:                                & !actionType.equals("INSERT")
224:                                & !actionType.startsWith("ALTER")) {
225:                            jtbl = getTable(tableName);
226:                            /*
227:                             *             For prepared statements, store any table objects that 
228:                             *             are created so that they can be explicitly closed when
229:                             *             the statement processing is complete.
230:                             */
231:                            if (statementType
232:                                    .endsWith("tinySQLPreparedStatement"))
233:                                pstmt.addTable(jtbl);
234:                        }
235:                        actionString = UtilString.actionToString(h);
236:                        if (debug)
237:                            System.out.println("ACTION: " + actionString);
238:                        if (actionType.equals("UPDATE")) {
239:                            /*     
240:                             *             SQL UPDATE
241:                             */
242:                            columns = (Vector) h.get("COLUMNS");
243:                            values = (Vector) h.get("VALUES");
244:                            UpdateStatement(tableName, columns, values, wc);
245:                        } else if (actionType.equals("DELETE")) {
246:                            /*       
247:                             *             SQL DELETE
248:                             */
249:                            DeleteStatement(tableName, wc);
250:                        } else if (actionType.equals("SELECT")) {
251:                            /*         
252:                             *             SQL SELECT
253:                             */
254:                            selectTables = (Hashtable) h.get("TABLES");
255:                            columns = (Vector) h.get("COLUMNS");
256:                            orderType = (String) h.get("ORDER_TYPE");
257:                            if ((String) h.get("DISTINCT") != (String) null)
258:                                distinct = true;
259:                            rs = SelectStatement(selectTables, columns, wc,
260:                                    orderType, distinct, s);
261:                        } else if (actionType.equals("INSERT")) {
262:                            /*        
263:                             *             SQL INSERT
264:                             */
265:                            columns = (Vector) h.get("COLUMNS");
266:                            values = (Vector) h.get("VALUES");
267:                            InsertStatement(statementType, tableName, columns,
268:                                    values);
269:                        } else if (actionType.equals("CREATE_TABLE")) {
270:                            /*
271:                             *             SQL CREATE TABLE
272:                             *
273:                             *             CREATE TABLE User(user_oid  NUMBER(8)    NOT NULL,
274:                             *                               userType  VARCHAR(80)  DEFAULT '-' NOT NULL,
275:                             *                               PRIMARY KEY (user_oid))
276:                             *
277:                             *             -> DEFAULT / NOT NULL / PRIMARY KEY is not supported
278:                             *
279:                             */
280:                            columnDefs = (Vector) h.get("COLUMN_DEF");
281:                            CreateTable(tableName, columnDefs);
282:                        } else if (actionType.equals("ALTER_ADD")) {
283:                            /*        
284:                             *             SQL ALTER TABLE ADD
285:                             */
286:                            columnDefs = (Vector) h.get("COLUMN_DEF");
287:                            AlterTableAddCol(tableName, columnDefs);
288:                        } else if (actionType.equals("ALTER_DROP")) {
289:                            /*         
290:                             *             SQL ALTER TABLE DROP
291:                             */
292:                            columns = (Vector) h.get("COLUMNS");
293:                            AlterTableDropCol(tableName, columns);
294:                        } else if (actionType.equals("ALTER_RENAME")) {
295:                            /*          
296:                             *             SQL ALTER TABLE RENAME
297:                             */
298:                            String oldColumnName = (String) h.get("OLD_COLUMN");
299:                            String newColumnName = (String) h.get("NEW_COLUMN");
300:                            AlterTableRenameCol(tableName, oldColumnName,
301:                                    newColumnName);
302:                        } else if (actionType.equals("DROP_TABLE")) {
303:                            /*           
304:                             *             SQL DROP TABLE
305:                             */
306:                            DropTable(tableName);
307:                        } else {
308:                            System.out.println("Unrecognized action "
309:                                    + actionType);
310:                        }
311:                    }
312:                } catch (Exception e) {
313:                    if (tinySQLGlobals.EX_DEBUG)
314:                        e.printStackTrace(System.out);
315:                    throw new tinySQLException(e.getMessage());
316:                }
317:                return rs;
318:            }
319:
320:            /*
321:             * Execute an SQL Select Statement
322:             */
323:            protected tsResultSet SelectStatement(Hashtable t, Vector c,
324:                    tinySQLWhere w, String ot, boolean distinct, Object stmt)
325:                    throws tinySQLException {
326:                Hashtable tables;
327:                Vector tableList;
328:                tsResultSet jrs;
329:                tsColumn columnObject;
330:                int i;
331:                /*
332:                 *    Instantiate a new, empty tsResultSet
333:                 */
334:                jrs = new tsResultSet(w, this );
335:                groupFunctions = new Hashtable();
336:                try {
337:                    jrs.setFetchSize(((tinySQLStatement) stmt).getFetchSize());
338:                    jrs.setType(((tinySQLStatement) stmt).getResultSetType());
339:                } catch (SQLException sqle) {
340:                    Utils
341:                            .log("Caught SQLException while setting Fetchsize and ResultSetType");
342:                    Utils.log("   This event is (should be) impossible!");
343:                }
344:                tables = t;
345:                tableList = (Vector) tables.get("TABLE_SELECT_ORDER");
346:                /*
347:                 *    Add the column objects to the ResultSet.
348:                 */
349:                for (i = 0; i < c.size(); i++) {
350:                    columnObject = (tsColumn) c.elementAt(i);
351:                    /*
352:                     *       The column object is now added to the ResultSet
353:                     */
354:                    jrs.addColumn(columnObject);
355:                    if (debug)
356:                        System.out.println("Adding "
357:                                + columnObject.contextToString() + " column "
358:                                + newLine + columnObject.toString() + newLine);
359:                }
360:                jrs.setState(1, tables, ot, distinct);
361:                contSelectStatement(jrs);
362:                return jrs;
363:            }
364:
365:            /*
366:             * Support function for restartable queries. Continue to
367:             * read the query result. The current state is taken from
368:             * tsResultSet. Proceed until maxFetchSize has reached.
369:             */
370:            protected void contSelectStatement(tsResultSet jrs)
371:                    throws tinySQLException {
372:                /*
373:                 *    The table scan here is an iterative tree expansion, similar to
374:                 *    the algorithm shown in the outline example in Chapter 5.
375:                 */
376:                String columnName, columnString, whereStatus, tableAndAlias;
377:                boolean addOK;
378:                int i, rowCount;
379:                int level = jrs.getLevel();
380:                tinySQLTable jtbl;
381:                tsColumn updateColumn;
382:                Hashtable tables = jrs.getTableState();
383:                tinySQLWhere wc = jrs.getWhereClause();
384:                /*
385:                 *    Create a hashtable to enumerate the tables to be scanned and initialize
386:                 *    with the first table name.
387:                 */
388:                Hashtable tbl_list = new Hashtable();
389:                Vector groupFunction;
390:                Vector t = (Vector) tables.get("TABLE_SELECT_ORDER");
391:                String current = (String) t.elementAt(0);
392:                String firstColumn = "*";
393:                tbl_list.put(current, new Integer(1));
394:                /*
395:                 *    Create a row object; this is added to the ResultSet.
396:                 */
397:                tsRow record = new tsRow();
398:                Vector resultSet = new Vector();
399:                /*
400:                 *    Keep retrieving rows until we run out of rows to process.
401:                 */
402:                while (level > 0) {
403:                    boolean levelFound = false;
404:                    /*
405:                     *       Find an item within the tbl_list which has the same level as the
406:                     *       one we're on.
407:                     */
408:                    Enumeration keys = tbl_list.keys();
409:                    while (keys.hasMoreElements()) {
410:                        /*
411:                         *          Get the next element in the "to be processed"
412:                         *          Hashtable, and find out its level, storing this
413:                         *          value in currLevel.
414:                         */
415:                        String hashkey = (String) keys.nextElement();
416:                        int currLevel = ((Integer) tbl_list.get(hashkey))
417:                                .intValue();
418:                        /*
419:                         *          As soon as an element is found whose level is equal to the 
420:                         *          one currently being processed, grab it's primary key (the hashkey),
421:                         *          flag levelfound, and break!
422:                         */
423:                        if (currLevel == level) {
424:                            current = hashkey;
425:                            levelFound = true;
426:                            break;
427:                        }
428:                    }
429:                    boolean eof = false; // did we hit eof?
430:                    boolean haveRecord = false; // did we get a record or not?
431:                    /*
432:                     *       If a table was found at the current level, then we should
433:                     *       try to get another row from it.
434:                     */
435:
436:                    if (levelFound) {
437:                        /*
438:                         *          Get the current table
439:                         */
440:                        jtbl = (tinySQLTable) tables.get(current);
441:                        tableAndAlias = jtbl.table + "->" + jtbl.tableAlias;
442:                        if (tinySQLGlobals.WHERE_DEBUG)
443:                            System.out.println("Processing level " + level
444:                                    + " table " + tableAndAlias + "\n");
445:                        /*
446:                         *          The following code is the start of setting up simple indexes
447:                         *          for tinySQL.  The concept involves creating a new tinySQLCondition
448:                         *          class, instances of which will be created by tinySQLWhere.  At least
449:                         *          initially only conditions that are equal to a constant will be
450:                         *          considered.  One of these conditions will be stored inside the
451:                         *          dbfFileTable object. Calls to NextRecord would then have to add
452:                         *          logic to check to see if an index exists.  The presence of a
453:                         *          complete index would be indicated by a counter that was equal
454:                         *          to the number of rows in the table.  In that case a single get
455:                         *          would deliver the record numbers required for the where condition.
456:                         *          The NextRecord function would return these record numbers in
457:                         *          sequence.  If the index did not exist then new values in the 
458:                         *          index Hashtable would be created.  None of this code has been 
459:                         *          developed or implemented, let alone tested.
460:                         *         
461:                         *
462:                         *          if ( wc != (tinySQLWhere)null )
463:                         *             jtbl.setIndexCondition(wc.getIndexCondition(tableAndAlias));
464:                         */
465:                        if (performDebug)
466:                            System.out.println("Selecting records from "
467:                                    + jtbl.table);
468:                        /*
469:                         *          Skip to the next undeleted record; at some point,
470:                         *          this will run out of records, and found will be false.
471:                         */
472:                        boolean found = false;
473:                        while (jtbl.NextRecord()) {
474:                            /*
475:                             *             Clear the column values for this table before starting 
476:                             *             to process the next row.
477:                             */
478:                            for (i = 0; i < jrs.numcols(); i++) {
479:                                updateColumn = jrs.columnAtIndex(i, true);
480:                                updateColumn.clear(tableAndAlias);
481:                            }
482:                            if (wc != (tinySQLWhere) null)
483:                                wc.clearValues(tableAndAlias);
484:                            if (!jtbl.isDeleted()) {
485:                                /*
486:                                 *                Evaluate the where clause for each column in the table.  If
487:                                 *                it is false, skip to the next row.  Otherwise, add the
488:                                 *                column value to the output record.
489:                                 */
490:                                Enumeration cols = jtbl.column_info.keys();
491:                                found = true;
492:                                whereStatus = "TRUE";
493:                                while (cols.hasMoreElements()) {
494:                                    columnName = tableAndAlias + "."
495:                                            + (String) cols.nextElement();
496:                                    columnString = jtbl.GetCol(columnName);
497:                                    if (wc != (tinySQLWhere) null) {
498:                                        whereStatus = wc.evaluate(columnName,
499:                                                columnString);
500:                                        if (whereStatus.equals("FALSE")) {
501:                                            /*
502:                                             *                         This column value caused the where clause to 
503:                                             *                         be FALSE.  Go to the next row in the table.
504:                                             */
505:                                            found = false;
506:                                            break;
507:                                        }
508:                                    }
509:                                    /*
510:                                     *                   Update the ResultSet tsColumn values 
511:                                     */
512:                                    jrs.updateColumns(columnName, columnString);
513:                                }
514:                                /*
515:                                 *                If no where condition has evaluated to false then this
516:                                 *                record is a candidate for output.  Break to the next table
517:                                 *                in this case for further WHERE processing.
518:                                 */
519:                                if (found)
520:                                    break;
521:                            }
522:                        }
523:                        if (found) {
524:                            if (tinySQLGlobals.DEBUG)
525:                                System.out.println("Build candidate record.");
526:                            for (i = 0; i < jrs.numcols(); i++) {
527:                                updateColumn = jrs.columnAtIndex(i, true);
528:                                /*
529:                                 *                Evaluate all functions before adding the
530:                                 *                column to the output record.
531:                                 */
532:                                updateColumn.updateFunctions();
533:                                columnString = updateColumn.getString();
534:                                if (updateColumn.isNotNull()) {
535:                                    record.put(updateColumn.name, columnString);
536:                                } else {
537:                                    record.remove(updateColumn.name);
538:                                }
539:                            }
540:                            if (performDebug)
541:                                System.out.println("Record is "
542:                                        + record.toString());
543:                            /*
544:                             *             Since we were just able to get a row, then
545:                             *             we are not at the end of file
546:                             */
547:                            eof = false;
548:                            /*
549:                             *             If the table we are processing is not the last in
550:                             *             the list, then we should increment level and loop to the top.
551:                             */
552:                            if (level < t.size()) {
553:                                /*
554:                                 *                Increment level
555:                                 */
556:                                level++;
557:                                /*
558:                                 *                Add the next table in the list of tables to
559:                                 *                the tbl_list, the Hashtable of "to be processed" tables.
560:                                 */
561:                                String next_tbl = (String) t
562:                                        .elementAt(level - 1);
563:                                tbl_list.put(next_tbl, new Integer(level));
564:                            } else {
565:                                /*
566:                                 *                If the table that was just processed is the last in
567:                                 *                the list, then we have drilled down to the bottom;
568:                                 *                all columns have values, and we can add it to the
569:                                 *                result set. The next time through, the program
570:                                 *                will try to read another row at this level; if it's
571:                                 *                found, only columns for the table being read will
572:                                 *                be overwritten in the tsRow.
573:                                 *                 
574:                                 *                Columns for the other table will be left alone, and 
575:                                 *                another row will be added to the result set. Here
576:                                 *                is the essence of the Cartesian Product which is
577:                                 *                being built here.
578:                                 */
579:                                haveRecord = true;
580:                            }
581:                        } else {
582:                            /*
583:                             *             We didn't find any more records at this level.
584:                             *             Reset the record pointer to the top of the table,
585:                             *             and decrement level. We have hit end of file here.
586:                             */
587:                            if (wc != (tinySQLWhere) null)
588:                                wc.clearValues(tableAndAlias);
589:                            level--;
590:                            eof = true;
591:                            jtbl.GoTop();
592:                        }
593:                    } else {
594:                        /*
595:                         *          No tables were found at this level; back up a level
596:                         *          and see if there's any up there.
597:                         */
598:                        level--;
599:                    }
600:                    /*
601:                     *       If we got a record, then add it to the result set.
602:                     */
603:                    if (haveRecord) {
604:                        /*
605:                         *          If group functions are involved, add records only after a break,
606:                         *          which is defined as a change in all of the group columns.  
607:                         *          Otherwise, update the current record.
608:                         */
609:                        if (jrs.isGrouped()) {
610:                            if (groupBreak) {
611:                                addOK = jrs.addRow((tsRow) record.clone());
612:                                if (addOK == false) {
613:                                    jrs.setLevel(level);
614:                                    return;
615:                                }
616:                                groupBreak = false;
617:                            } else {
618:                                jrs.updateRow((tsRow) record.clone());
619:                            }
620:                        } else {
621:                            /*
622:                             *             No group functions are involved.  Just add the record.
623:                             */
624:                            addOK = jrs.addRow((tsRow) record.clone());
625:                            if (addOK == false) {
626:                                jrs.setLevel(level);
627:                                return;
628:                            }
629:                        }
630:                        firstColumn = "*";
631:                    }
632:                }
633:                /*
634:                 *    Close all the tables
635:                 */
636:                for (i = 0; i < t.size(); i++) {
637:                    jtbl = (tinySQLTable) tables.get((String) t.elementAt(i));
638:                    jtbl.close();
639:                }
640:                /*
641:                 *    return a result set
642:                 */
643:                jrs.setLevel(0);
644:            }
645:
646:            /*
647:             * Delete rows which match a where clause.
648:             */
649:            private void DeleteStatement(String tableName, tinySQLWhere wc)
650:                    throws tinySQLException {
651:                tinySQLTable jtbl;
652:                Hashtable tables;
653:                String columnName, columnString, whereStatus;
654:                Enumeration cols;
655:                /* 
656:                 *    Create a table object and put it in the Hashtable.
657:                 */
658:                jtbl = getTable(tableName);
659:                tables = new Hashtable();
660:                tables.put(tableName, jtbl);
661:                /*
662:                 *    Process each row in the table ignoring deleted rows.
663:                 */
664:                jtbl.GoTop();
665:                while (jtbl.NextRecord()) {
666:                    if (!jtbl.isDeleted()) {
667:                        cols = jtbl.column_info.keys();
668:                        whereStatus = "TRUE";
669:                        while (cols.hasMoreElements()) {
670:                            columnName = jtbl.table + "->" + jtbl.tableAlias
671:                                    + "." + (String) cols.nextElement();
672:                            columnString = jtbl.GetCol(columnName);
673:                            /*
674:                             *             Check the status of the where clause for each column value.
675:                             */
676:                            if (wc != (tinySQLWhere) null)
677:                                whereStatus = wc.evaluate(columnName,
678:                                        columnString);
679:                            if (whereStatus.equals("FALSE"))
680:                                break;
681:                        }
682:                        if (whereStatus.equals("TRUE"))
683:                            jtbl.DeleteRow();
684:                        if (wc != (tinySQLWhere) null)
685:                            wc.clearValues(jtbl.table + "->" + jtbl.tableAlias);
686:                    }
687:                }
688:                jtbl.close();
689:            }
690:
691:            /*
692:             * Update rows which match a WHERE clause
693:             */
694:            private void UpdateStatement(String tableName, Vector c, Vector v,
695:                    tinySQLWhere wc) throws tinySQLException {
696:                /*
697:                 *    Create a table object and put it in the Hashtable.
698:                 */
699:                tinySQLTable jtbl = getTable(tableName);
700:                Hashtable tables = new Hashtable();
701:                tables.put(tableName, jtbl);
702:                String columnName, columnString, whereStatus;
703:                /*
704:                 *    Process each row in the table ignoring deleted rows.
705:                 */
706:                jtbl.GoTop();
707:                while (jtbl.NextRecord()) {
708:                    if (!jtbl.isDeleted()) {
709:                        Enumeration cols = jtbl.column_info.keys();
710:                        whereStatus = "TRUE";
711:                        while (cols.hasMoreElements()) {
712:                            /*
713:                             *             Use the table name for the table alias for updates.
714:                             */
715:                            columnName = jtbl.table + "->" + jtbl.table + "."
716:                                    + (String) cols.nextElement();
717:                            columnString = jtbl.GetCol(columnName);
718:                            /*
719:                             *             Check the status of the where clause for each column value.
720:                             */
721:                            if (wc != (tinySQLWhere) null)
722:                                whereStatus = wc.evaluate(columnName,
723:                                        columnString);
724:                            if (whereStatus.equals("FALSE"))
725:                                break;
726:                        }
727:                        if (whereStatus.equals("TRUE"))
728:                            jtbl.UpdateCurrentRow(c, v);
729:                        if (wc != (tinySQLWhere) null)
730:                            wc.clearValues(jtbl.table + "->" + jtbl.tableAlias);
731:                    }
732:                }
733:                jtbl.close();
734:            }
735:
736:            /*
737:             * Create the tinySQLTable object, then insert a row, and update
738:             * it with the c and v Vectors
739:             */
740:            private void InsertStatement(String statementType,
741:                    String tableName, Vector c, Vector v)
742:                    throws tinySQLException {
743:                String columnName, valueString;
744:                int i, columnType, columnSize;
745:                tinySQLTable jtbl = (tinySQLTable) null;
746:                double value;
747:                insertTable = getTable(tableName);
748:                /*
749:                 *    Check that the values supplied are the correct type and length.
750:                 */
751:                for (i = 0; i < c.size(); i++) {
752:                    columnName = (String) c.elementAt(i);
753:                    valueString = (String) v.elementAt(i);
754:                    if (valueString == (String) null)
755:                        continue;
756:                    valueString = UtilString.removeQuotes(valueString);
757:                    valueString = UtilString.replaceAll(valueString, "''", "'");
758:                    columnType = insertTable.ColType(columnName);
759:                    if (Utils.isNumberColumn(columnType)) {
760:                        try {
761:                            value = Double.parseDouble(valueString);
762:                        } catch (Exception e) {
763:                            throw new tinySQLException("Insert failed: column "
764:                                    + columnName + " is numeric - found "
765:                                    + valueString);
766:                        }
767:                    } else if (Utils.isDateColumn(columnType)) {
768:                        try {
769:                            /*
770:                             *             Modify the input to be the standard YYYYMMDD format
771:                             */
772:                            if (valueString.trim().length() > 0)
773:                                v.setElementAt(UtilString
774:                                        .dateValue(valueString), i);
775:                        } catch (Exception e) {
776:                            throw new tinySQLException("Insert failed: "
777:                                    + e.getMessage());
778:                        }
779:                    }
780:                    columnSize = insertTable.ColSize(columnName);
781:                    if (valueString.length() > columnSize) {
782:                        throw new tinySQLException(
783:                                "Insert failed: string too long for "
784:                                        + " column "
785:                                        + columnName
786:                                        + " "
787:                                        + Integer
788:                                                .toString(valueString.length())
789:                                        + " > " + Integer.toString(columnSize)
790:                                        + "<" + valueString + ">");
791:                    }
792:                }
793:                insertTable.InsertRow(c, v);
794:                /*
795:                 *    Close the table file that has just been updated unless this is a 
796:                 *    PreparedStatement.  In that case an explicit close must be done
797:                 *    on the statement object to close any open files.
798:                 */
799:                if (!statementType.endsWith("tinySQLPreparedStatement"))
800:                    insertTable.close();
801:            }
802:
803:            /*
804:             * Creates a table given a tableName, and a Vector of column
805:             * definitions.
806:             *
807:             * The column definitions are an array of tsColumn
808:             */
809:            abstract void CreateTable(String tableName, Vector v)
810:                    throws IOException, tinySQLException;
811:
812:            /*
813:             * Creates new Columns given a tableName, and a Vector of
814:             * column definition (tsColumn) arrays.<br>
815:             *
816:             * ALTER TABLE table [ * ] ADD [ COLUMN ] column type 
817:             */
818:            abstract void AlterTableAddCol(String tableName, Vector v)
819:                    throws IOException, tinySQLException;
820:
821:            /*
822:             * Deletes Columns given a tableName, and a Vector of
823:             * column definition (tsColumn) arrays.<br>
824:             *
825:             * ALTER TABLE table DROP [ COLUMN ] column { RESTRICT | CASCADE }
826:             */
827:            abstract void AlterTableDropCol(String tableName, Vector v)
828:                    throws IOException, tinySQLException;
829:
830:            /*
831:             * Rename columns
832:             *
833:             * ALTER TABLE table RENAME war TO peace
834:             */
835:            abstract void AlterTableRenameCol(String tableName,
836:                    String oldColumnName, String newColumnName)
837:                    throws tinySQLException;
838:
839:            /*
840:             * Drops a table by name
841:             */
842:            abstract void DropTable(String tableName) throws tinySQLException;
843:
844:            /*
845:             * Create a tinySQLTable object by table name
846:             */
847:            abstract tinySQLTable getTable(String tableName)
848:                    throws tinySQLException;
849:
850:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.