Source Code Cross Referenced for BasePeer.java in  » Database-ORM » Torque » org » apache » torque » util » 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 ORM » Torque » org.apache.torque.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        package org.apache.torque.util;
0002:
0003:        /*
0004:         * Licensed to the Apache Software Foundation (ASF) under one
0005:         * or more contributor license agreements.  See the NOTICE file
0006:         * distributed with this work for additional information
0007:         * regarding copyright ownership.  The ASF licenses this file
0008:         * to you under the Apache License, Version 2.0 (the
0009:         * "License"); you may not use this file except in compliance
0010:         * with the License.  You may obtain a copy of the License at
0011:         *
0012:         *   http://www.apache.org/licenses/LICENSE-2.0
0013:         *
0014:         * Unless required by applicable law or agreed to in writing,
0015:         * software distributed under the License is distributed on an
0016:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0017:         * KIND, either express or implied.  See the License for the
0018:         * specific language governing permissions and limitations
0019:         * under the License.
0020:         */
0021:
0022:        import java.io.Serializable;
0023:        import java.sql.Connection;
0024:        import java.sql.PreparedStatement;
0025:        import java.sql.SQLException;
0026:        import java.sql.Statement;
0027:        import java.util.ArrayList;
0028:        import java.util.Collections;
0029:        import java.util.HashSet;
0030:        import java.util.Iterator;
0031:        import java.util.List;
0032:        import java.util.Map;
0033:        import java.util.Set;
0034:
0035:        import org.apache.commons.lang.StringUtils;
0036:        import org.apache.commons.logging.Log;
0037:        import org.apache.commons.logging.LogFactory;
0038:        import org.apache.torque.Database;
0039:        import org.apache.torque.Torque;
0040:        import org.apache.torque.TorqueException;
0041:        import org.apache.torque.adapter.DB;
0042:        import org.apache.torque.map.ColumnMap;
0043:        import org.apache.torque.map.DatabaseMap;
0044:        import org.apache.torque.map.MapBuilder;
0045:        import org.apache.torque.map.TableMap;
0046:        import org.apache.torque.oid.IdGenerator;
0047:        import org.apache.torque.om.NumberKey;
0048:        import org.apache.torque.om.ObjectKey;
0049:        import org.apache.torque.om.SimpleKey;
0050:        import org.apache.torque.om.StringKey;
0051:
0052:        import com.workingdogs.village.Column;
0053:        import com.workingdogs.village.DataSet;
0054:        import com.workingdogs.village.DataSetException;
0055:        import com.workingdogs.village.KeyDef;
0056:        import com.workingdogs.village.QueryDataSet;
0057:        import com.workingdogs.village.Record;
0058:        import com.workingdogs.village.Schema;
0059:        import com.workingdogs.village.TableDataSet;
0060:
0061:        /**
0062:         * This is the base class for all Peer classes in the system.  Peer
0063:         * classes are responsible for isolating all of the database access
0064:         * for a specific business object.  They execute all of the SQL
0065:         * against the database.  Over time this class has grown to include
0066:         * utility methods which ease execution of cross-database queries and
0067:         * the implementation of concrete Peers.
0068:         *
0069:         * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
0070:         * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
0071:         * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
0072:         * @author <a href="mailto:stephenh@chase3000.com">Stephen Haberman</a>
0073:         * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
0074:         * @author <a href="mailto:vido@ldh.org">Augustin Vidovic</a>
0075:         * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
0076:         * @version $Id: BasePeer.java 591648 2007-11-03 16:34:00Z tfischer $
0077:         */
0078:        public abstract class BasePeer implements  Serializable {
0079:            /** Constant criteria key to reference ORDER BY columns. */
0080:            public static final String ORDER_BY = "ORDER BY";
0081:
0082:            /**
0083:             * Constant criteria key to remove Case Information from
0084:             * search/ordering criteria.
0085:             */
0086:            public static final String IGNORE_CASE = "IgNOrE cAsE";
0087:
0088:            /** Classes that implement this class should override this value. */
0089:            public static final String TABLE_NAME = "TABLE_NAME";
0090:
0091:            /** the log */
0092:            protected static final Log log = LogFactory.getLog(BasePeer.class);
0093:
0094:            private static void throwTorqueException(Exception e)
0095:                    throws TorqueException {
0096:                if (e instanceof  TorqueException) {
0097:                    throw (TorqueException) e;
0098:                } else {
0099:                    throw new TorqueException(e);
0100:                }
0101:            }
0102:
0103:            /**
0104:             * Sets up a Schema for a table.  This schema is then normally
0105:             * used as the argument for initTableColumns().
0106:             *
0107:             * @param tableName The name of the table.
0108:             * @return A Schema.
0109:             */
0110:            public static Schema initTableSchema(String tableName) {
0111:                return initTableSchema(tableName, Torque.getDefaultDB());
0112:            }
0113:
0114:            /**
0115:             * Sets up a Schema for a table.  This schema is then normally
0116:             * used as the argument for initTableColumns
0117:             *
0118:             * @param tableName The propery name for the database in the
0119:             * configuration file.
0120:             * @param dbName The name of the database.
0121:             * @return A Schema.
0122:             */
0123:            public static Schema initTableSchema(String tableName, String dbName) {
0124:                Schema schema = null;
0125:                Connection con = null;
0126:
0127:                try {
0128:                    con = Torque.getConnection(dbName);
0129:                    schema = new Schema().schema(con, tableName);
0130:                } catch (Exception e) {
0131:                    log.error(e);
0132:                    throw new Error("Error in BasePeer.initTableSchema("
0133:                            + tableName + "): " + e.getMessage());
0134:                } finally {
0135:                    Torque.closeConnection(con);
0136:                }
0137:                return schema;
0138:            }
0139:
0140:            /**
0141:             * Creates a Column array for a table based on its Schema.
0142:             *
0143:             * @param schema A Schema object.
0144:             * @return A Column[].
0145:             */
0146:            public static Column[] initTableColumns(Schema schema) {
0147:                Column[] columns = null;
0148:                try {
0149:                    int numberOfColumns = schema.numberOfColumns();
0150:                    columns = new Column[numberOfColumns];
0151:                    for (int i = 0; i < numberOfColumns; i++) {
0152:                        columns[i] = schema.column(i + 1);
0153:                    }
0154:                } catch (Exception e) {
0155:                    log.error(e);
0156:                    throw new Error("Error in BasePeer.initTableColumns(): "
0157:                            + e.getMessage());
0158:                }
0159:                return columns;
0160:            }
0161:
0162:            /**
0163:             * Convenience method to create a String array of column names.
0164:             *
0165:             * @param columns A Column[].
0166:             * @return A String[].
0167:             */
0168:            public static String[] initColumnNames(Column[] columns) {
0169:                String[] columnNames = new String[columns.length];
0170:                for (int i = 0; i < columns.length; i++) {
0171:                    columnNames[i] = columns[i].name().toUpperCase();
0172:                }
0173:                return columnNames;
0174:            }
0175:
0176:            /**
0177:             * Convenience method to create a String array of criteria keys.
0178:             *
0179:             * @param tableName Name of table.
0180:             * @param columnNames A String[].
0181:             * @return A String[].
0182:             */
0183:            public static String[] initCriteriaKeys(String tableName,
0184:                    String[] columnNames) {
0185:                String[] keys = new String[columnNames.length];
0186:                for (int i = 0; i < columnNames.length; i++) {
0187:                    keys[i] = tableName + "." + columnNames[i].toUpperCase();
0188:                }
0189:                return keys;
0190:            }
0191:
0192:            /**
0193:             * Convenience method that uses straight JDBC to delete multiple
0194:             * rows.  Village throws an Exception when multiple rows are
0195:             * deleted.
0196:             *
0197:             * @param con A Connection.
0198:             * @param table The table to delete records from.
0199:             * @param column The column in the where clause.
0200:             * @param value The value of the column.
0201:             * @throws TorqueException Any exceptions caught during processing will be
0202:             *         rethrown wrapped into a TorqueException.
0203:             */
0204:            public static void deleteAll(Connection con, String table,
0205:                    String column, int value) throws TorqueException {
0206:                Statement statement = null;
0207:                try {
0208:                    statement = con.createStatement();
0209:
0210:                    StringBuffer query = new StringBuffer();
0211:                    query.append("DELETE FROM ").append(table)
0212:                            .append(" WHERE ").append(column).append(" = ")
0213:                            .append(value);
0214:
0215:                    statement.executeUpdate(query.toString());
0216:                } catch (SQLException e) {
0217:                    throw new TorqueException(e);
0218:                } finally {
0219:                    if (statement != null) {
0220:                        try {
0221:                            statement.close();
0222:                        } catch (SQLException e) {
0223:                            throw new TorqueException(e);
0224:                        }
0225:                    }
0226:                }
0227:            }
0228:
0229:            /**
0230:             * Convenience method that uses straight JDBC to delete multiple
0231:             * rows.  Village throws an Exception when multiple rows are
0232:             * deleted.  This method attempts to get the default database from
0233:             * the pool.
0234:             *
0235:             * @param table The table to delete records from.
0236:             * @param column The column in the where clause.
0237:             * @param value The value of the column.
0238:             * @throws TorqueException Any exceptions caught during processing will be
0239:             *         rethrown wrapped into a TorqueException.
0240:             */
0241:            public static void deleteAll(String table, String column, int value)
0242:                    throws TorqueException {
0243:                Connection con = null;
0244:                try {
0245:                    // Get a connection to the db.
0246:                    con = Torque.getConnection(Torque.getDefaultDB());
0247:                    deleteAll(con, table, column, value);
0248:                } finally {
0249:                    Torque.closeConnection(con);
0250:                }
0251:            }
0252:
0253:            /**
0254:             * Method to perform deletes based on values and keys in a
0255:             * Criteria.
0256:             *
0257:             * @param criteria The criteria to use.
0258:             * @throws TorqueException Any exceptions caught during processing will be
0259:             *         rethrown wrapped into a TorqueException.
0260:             * @deprecated This method causes unexpected results when joins are used.
0261:             *              Please use doDelete(Criteria, String).
0262:             */
0263:            public static void doDelete(Criteria criteria)
0264:                    throws TorqueException {
0265:                doDelete(criteria, (String) null);
0266:            }
0267:
0268:            /**
0269:             * Method to perform deletes based on values and keys in a
0270:             * Criteria.
0271:             * This method is protected because it may cause ambiguity between
0272:             * doDelete(Criteria,Connection) and this method. It will be made public
0273:             * once doDelete(Criteria, Connection) is removed.
0274:             *
0275:             * @param criteria The criteria to use.
0276:             * @param tableName the name of the table to delete records from.
0277:             *         If set to null, the name of the table(s) can be extracted from
0278:             *         the criteria, but this can cause unexpected results.
0279:             * @throws TorqueException Any exceptions caught during processing will be
0280:             *         rethrown wrapped into a TorqueException.
0281:             */
0282:            protected static void doDelete(Criteria criteria, String tableName)
0283:                    throws TorqueException {
0284:                Connection con = null;
0285:                try {
0286:                    con = Transaction.beginOptional(criteria.getDbName(),
0287:                            criteria.isUseTransaction());
0288:                    doDelete(criteria, tableName, con);
0289:                    Transaction.commit(con);
0290:                } catch (TorqueException e) {
0291:                    Transaction.safeRollback(con);
0292:                    throw e;
0293:                }
0294:            }
0295:
0296:            /**
0297:             * Method to perform deletes based on values and keys in a Criteria.
0298:             *
0299:             * @param criteria The criteria to use.
0300:             * @param con A Connection.
0301:             * @throws TorqueException Any exceptions caught during processing will be
0302:             *         rethrown wrapped into a TorqueException.
0303:             * @deprecated This method causes unexpected results when joins are used.
0304:             *              Please use doDelete(Criteria, String, Connection).
0305:             */
0306:            public static void doDelete(Criteria criteria, Connection con)
0307:                    throws TorqueException {
0308:                doDelete(criteria, null, con);
0309:            }
0310:
0311:            /**
0312:             * Method to perform deletes based on values and keys in a Criteria.
0313:             *
0314:             * @param criteria The criteria to use.
0315:             * @param tableName the name of the table to delete records from.
0316:             *         If set to null, the name of the table(s) can be extracted from
0317:             *         the criteria, but this can cause unexpected results.
0318:             * @param con A Connection.
0319:             * @throws TorqueException Any exceptions caught during processing will be
0320:             *         rethrown wrapped into a TorqueException.
0321:             */
0322:            public static void doDelete(Criteria criteria, String tableName,
0323:                    Connection con) throws TorqueException {
0324:                String dbName = criteria.getDbName();
0325:                final DatabaseMap dbMap = Torque.getDatabaseMap(dbName);
0326:
0327:                // This Callback adds all tables to the Table set which
0328:                // are referenced from a cascading criteria. As a result, all
0329:                // data that is referenced through foreign keys will also be
0330:                // deleted.
0331:                SQLBuilder.TableCallback tc = new SQLBuilder.TableCallback() {
0332:                    public void process(Set tables, String key, Criteria crit) {
0333:                        if (crit.isCascade()) {
0334:                            // This steps thru all the columns in the database.
0335:                            TableMap[] tableMaps = dbMap.getTables();
0336:                            for (int i = 0; i < tableMaps.length; i++) {
0337:                                ColumnMap[] columnMaps = tableMaps[i]
0338:                                        .getColumns();
0339:
0340:                                for (int j = 0; j < columnMaps.length; j++) {
0341:                                    // Only delete rows where the foreign key is
0342:                                    // also a primary key.  Other rows need
0343:                                    // updating, but that is not implemented.
0344:                                    if (columnMaps[j].isForeignKey()
0345:                                            && columnMaps[j].isPrimaryKey()
0346:                                            && key.equals(columnMaps[j]
0347:                                                    .getRelatedName())) {
0348:                                        tables.add(tableMaps[i].getName());
0349:                                        crit.add(columnMaps[j]
0350:                                                .getFullyQualifiedName(), crit
0351:                                                .getValue(key));
0352:                                    }
0353:                                }
0354:                            }
0355:                        }
0356:                    }
0357:                };
0358:
0359:                Set tables;
0360:                if (tableName == null) {
0361:                    tables = SQLBuilder.getTableSet(criteria, tc);
0362:                } else {
0363:                    tables = new HashSet(1);
0364:                    tables.add(tableName);
0365:                }
0366:
0367:                try {
0368:                    processTables(criteria, tables, con, new ProcessCallback() {
0369:                        public void process(String table, String dbName,
0370:                                Record rec) throws Exception {
0371:                            rec.markToBeDeleted();
0372:                            rec.save();
0373:                        }
0374:                    });
0375:                } catch (Exception e) {
0376:                    throwTorqueException(e);
0377:                }
0378:            }
0379:
0380:            /**
0381:             * Method to perform inserts based on values and keys in a
0382:             * Criteria.
0383:             * <p>
0384:             * If the primary key is auto incremented the data in Criteria
0385:             * will be inserted and the auto increment value will be returned.
0386:             * <p>
0387:             * If the primary key is included in Criteria then that value will
0388:             * be used to insert the row.
0389:             * <p>
0390:             * If no primary key is included in Criteria then we will try to
0391:             * figure out the primary key from the database map and insert the
0392:             * row with the next available id using util.db.IDBroker.
0393:             * <p>
0394:             * If no primary key is defined for the table the values will be
0395:             * inserted as specified in Criteria and -1 will be returned.
0396:             *
0397:             * @param criteria Object containing values to insert.
0398:             * @return An Object which is the id of the row that was inserted
0399:             * (if the table has a primary key) or null (if the table does not
0400:             * have a primary key).
0401:             * @throws TorqueException Any exceptions caught during processing will be
0402:             *         rethrown wrapped into a TorqueException.
0403:             */
0404:            public static ObjectKey doInsert(Criteria criteria)
0405:                    throws TorqueException {
0406:                Connection con = null;
0407:                ObjectKey id = null;
0408:
0409:                try {
0410:                    con = Transaction.beginOptional(criteria.getDbName(),
0411:                            criteria.isUseTransaction());
0412:                    id = doInsert(criteria, con);
0413:                    Transaction.commit(con);
0414:                } catch (TorqueException e) {
0415:                    Transaction.safeRollback(con);
0416:                    throw e;
0417:                }
0418:
0419:                return id;
0420:            }
0421:
0422:            /**
0423:             * Method to perform inserts based on values and keys in a
0424:             * Criteria.
0425:             * <p>
0426:             * If the primary key is auto incremented the data in Criteria
0427:             * will be inserted and the auto increment value will be returned.
0428:             * <p>
0429:             * If the primary key is included in Criteria then that value will
0430:             * be used to insert the row.
0431:             * <p>
0432:             * If no primary key is included in Criteria then we will try to
0433:             * figure out the primary key from the database map and insert the
0434:             * row with the next available id using util.db.IDBroker.
0435:             * <p>
0436:             * If no primary key is defined for the table the values will be
0437:             * inserted as specified in Criteria and null will be returned.
0438:             *
0439:             * @param criteria Object containing values to insert.
0440:             * @param con A Connection.
0441:             * @return An Object which is the id of the row that was inserted
0442:             * (if the table has a primary key) or null (if the table does not
0443:             * have a primary key).
0444:             * @throws TorqueException Any exceptions caught during processing will be
0445:             *         rethrown wrapped into a TorqueException.
0446:             */
0447:            public static ObjectKey doInsert(Criteria criteria, Connection con)
0448:                    throws TorqueException {
0449:                SimpleKey id = null;
0450:
0451:                // Get the table name and method for determining the primary
0452:                // key value.
0453:                String table = null;
0454:                Iterator keys = criteria.keySet().iterator();
0455:                if (keys.hasNext()) {
0456:                    table = criteria.getTableName((String) keys.next());
0457:                } else {
0458:                    throw new TorqueException(
0459:                            "Database insert attempted without "
0460:                                    + "anything specified to insert");
0461:                }
0462:
0463:                String dbName = criteria.getDbName();
0464:                Database database = Torque.getDatabase(dbName);
0465:                DatabaseMap dbMap = database.getDatabaseMap();
0466:                TableMap tableMap = dbMap.getTable(table);
0467:                Object keyInfo = tableMap.getPrimaryKeyMethodInfo();
0468:                IdGenerator keyGen = database.getIdGenerator(tableMap
0469:                        .getPrimaryKeyMethod());
0470:
0471:                ColumnMap pk = getPrimaryKey(criteria);
0472:
0473:                // If the keyMethod is SEQUENCE or IDBROKERTABLE, get the id
0474:                // before the insert.
0475:                if (keyGen != null && keyGen.isPriorToInsert()) {
0476:                    // pk will be null if there is no primary key defined for the table
0477:                    // we're inserting into.
0478:                    if (pk != null
0479:                            && !criteria
0480:                                    .containsKey(pk.getFullyQualifiedName())) {
0481:                        id = getId(pk, keyGen, con, keyInfo);
0482:                        criteria.add(pk.getFullyQualifiedName(), id);
0483:                    }
0484:                }
0485:
0486:                // Use Village to perform the insert.
0487:                TableDataSet tds = null;
0488:                try {
0489:                    String tableName = SQLBuilder.getFullTableName(table,
0490:                            dbName);
0491:                    tds = new TableDataSet(con, tableName);
0492:                    Record rec = tds.addRecord();
0493:                    // not the fully qualified name, insertOrUpdateRecord wants to use table as an index...
0494:                    BasePeer.insertOrUpdateRecord(rec, table, dbName, criteria);
0495:                } catch (DataSetException e) {
0496:                    throwTorqueException(e);
0497:                } catch (SQLException e) {
0498:                    throwTorqueException(e);
0499:                } catch (TorqueException e) {
0500:                    throwTorqueException(e);
0501:                } finally {
0502:                    VillageUtils.close(tds);
0503:                }
0504:
0505:                // If the primary key column is auto-incremented, get the id
0506:                // now.
0507:                if (keyGen != null && keyGen.isPostInsert()) {
0508:                    id = getId(pk, keyGen, con, keyInfo);
0509:                }
0510:
0511:                return id;
0512:            }
0513:
0514:            /**
0515:             * Create an Id for insertion in the Criteria
0516:             *
0517:             * @param pk ColumnMap for the Primary key
0518:             * @param keyGen The Id Generator object
0519:             * @param con The SQL Connection to run the id generation under
0520:             * @param keyInfo KeyInfo Parameter from the Table map
0521:             *
0522:             * @return A simple Key representing the new Id value
0523:             * @throws TorqueException Possible errors get wrapped in here.
0524:             */
0525:            private static SimpleKey getId(ColumnMap pk, IdGenerator keyGen,
0526:                    Connection con, Object keyInfo) throws TorqueException {
0527:                SimpleKey id = null;
0528:
0529:                try {
0530:                    if (pk != null && keyGen != null) {
0531:                        if (pk.getType() instanceof  Number) {
0532:                            id = new NumberKey(keyGen.getIdAsBigDecimal(con,
0533:                                    keyInfo));
0534:                        } else {
0535:                            id = new StringKey(keyGen.getIdAsString(con,
0536:                                    keyInfo));
0537:                        }
0538:                    }
0539:                } catch (Exception e) {
0540:                    throwTorqueException(e);
0541:                }
0542:                return id;
0543:            }
0544:
0545:            /**
0546:             * Grouping of code used in both doInsert() and doUpdate()
0547:             * methods.  Sets up a Record for saving.
0548:             *
0549:             * @param rec A Record.
0550:             * @param table Name of table.
0551:             * @param criteria A Criteria.
0552:             * @throws TorqueException Any exceptions caught during processing will be
0553:             *         rethrown wrapped into a TorqueException.
0554:             */
0555:            private static void insertOrUpdateRecord(Record rec, String table,
0556:                    String dbName, Criteria criteria) throws TorqueException {
0557:                DatabaseMap dbMap = Torque.getDatabaseMap(dbName);
0558:
0559:                ColumnMap[] columnMaps = dbMap.getTable(table).getColumns();
0560:                boolean shouldSave = false;
0561:                for (int j = 0; j < columnMaps.length; j++) {
0562:                    ColumnMap colMap = columnMaps[j];
0563:                    String colName = colMap.getColumnName();
0564:                    String key = new StringBuffer(colMap.getTableName())
0565:                            .append('.').append(colName).toString();
0566:                    if (criteria.containsKey(key)) {
0567:                        try {
0568:                            VillageUtils.setVillageValue(criteria, key, rec,
0569:                                    colName);
0570:                            shouldSave = true;
0571:                        } catch (Exception e) {
0572:                            throwTorqueException(e);
0573:                        }
0574:                    }
0575:                }
0576:
0577:                if (shouldSave) {
0578:                    try {
0579:                        rec.save();
0580:                    } catch (Exception e) {
0581:                        throwTorqueException(e);
0582:                    }
0583:                } else {
0584:                    throw new TorqueException("No changes to save");
0585:                }
0586:            }
0587:
0588:            /**
0589:             * Method to create an SQL query for display only based on values in a
0590:             * Criteria.
0591:             *
0592:             * @param criteria A Criteria.
0593:             * @return the SQL query for display
0594:             * @exception TorqueException Trouble creating the query string.
0595:             */
0596:            static String createQueryDisplayString(Criteria criteria)
0597:                    throws TorqueException {
0598:                return createQuery(criteria).toString();
0599:            }
0600:
0601:            /**
0602:             * Method to create an SQL query for actual execution based on values in a
0603:             * Criteria.
0604:             *
0605:             * @param criteria A Criteria.
0606:             * @return the SQL query for actual execution
0607:             * @exception TorqueException Trouble creating the query string.
0608:             */
0609:            public static String createQueryString(Criteria criteria)
0610:                    throws TorqueException {
0611:                Query query = createQuery(criteria);
0612:                return query.toString();
0613:            }
0614:
0615:            /**
0616:             * Method to create an SQL query based on values in a Criteria.  Note that
0617:             * final manipulation of the limit and offset are performed when the query
0618:             * is actually executed.
0619:             *
0620:             * @param criteria A Criteria.
0621:             * @return the sql query
0622:             * @exception TorqueException Trouble creating the query string.
0623:             */
0624:            static Query createQuery(Criteria criteria) throws TorqueException {
0625:                return SQLBuilder.buildQueryClause(criteria, null,
0626:                        new SQLBuilder.QueryCallback() {
0627:                            public String process(Criteria.Criterion criterion,
0628:                                    List params) {
0629:                                return criterion.toString();
0630:                            }
0631:                        });
0632:            }
0633:
0634:            /**
0635:             * Returns all results.
0636:             *
0637:             * @param criteria A Criteria.
0638:             * @return List of Record objects.
0639:             * @throws TorqueException Any exceptions caught during processing will be
0640:             *         rethrown wrapped into a TorqueException.
0641:             */
0642:            public static List doSelect(Criteria criteria)
0643:                    throws TorqueException {
0644:                Connection con = null;
0645:                List results = null;
0646:
0647:                try {
0648:                    con = Transaction.beginOptional(criteria.getDbName(),
0649:                            criteria.isUseTransaction());
0650:                    results = doSelect(criteria, con);
0651:                    Transaction.commit(con);
0652:                } catch (TorqueException e) {
0653:                    Transaction.safeRollback(con);
0654:                    throw e;
0655:                }
0656:                return results;
0657:            }
0658:
0659:            /**
0660:             * Returns all results.
0661:             *
0662:             * @param criteria A Criteria.
0663:             * @param con A Connection.
0664:             * @return List of Record objects.
0665:             * @throws TorqueException Any exceptions caught during processing will be
0666:             *         rethrown wrapped into a TorqueException.
0667:             */
0668:            public static List doSelect(Criteria criteria, Connection con)
0669:                    throws TorqueException {
0670:                Query query = createQuery(criteria);
0671:                DB dbadapter = Torque.getDB(criteria.getDbName());
0672:
0673:                // Call Village depending on the capabilities of the DB
0674:                return executeQuery(query.toString(), dbadapter
0675:                        .supportsNativeOffset() ? 0 : criteria.getOffset(),
0676:                        dbadapter.supportsNativeLimit() ? -1 : criteria
0677:                                .getLimit(), criteria.isSingleRecord(), con);
0678:            }
0679:
0680:            /**
0681:             * Utility method which executes a given sql statement.  This
0682:             * method should be used for select statements only.  Use
0683:             * executeStatement for update, insert, and delete operations.
0684:             *
0685:             * @param queryString A String with the sql statement to execute.
0686:             * @return List of Record objects.
0687:             * @throws TorqueException Any exceptions caught during processing will be
0688:             *         rethrown wrapped into a TorqueException.
0689:             */
0690:            public static List executeQuery(String queryString)
0691:                    throws TorqueException {
0692:                return executeQuery(queryString, Torque.getDefaultDB(), false);
0693:            }
0694:
0695:            /**
0696:             * Utility method which executes a given sql statement.  This
0697:             * method should be used for select statements only.  Use
0698:             * executeStatement for update, insert, and delete operations.
0699:             *
0700:             * @param queryString A String with the sql statement to execute.
0701:             * @param dbName The database to connect to.
0702:             * @return List of Record objects.
0703:             * @throws TorqueException Any exceptions caught during processing will be
0704:             *         rethrown wrapped into a TorqueException.
0705:             */
0706:            public static List executeQuery(String queryString, String dbName)
0707:                    throws TorqueException {
0708:                return executeQuery(queryString, dbName, false);
0709:            }
0710:
0711:            /**
0712:             * Method for performing a SELECT.  Returns all results.
0713:             *
0714:             * @param queryString A String with the sql statement to execute.
0715:             * @param dbName The database to connect to.
0716:             * @param singleRecord Whether or not we want to select only a
0717:             * single record.
0718:             * @return List of Record objects.
0719:             * @throws TorqueException Any exceptions caught during processing will be
0720:             *         rethrown wrapped into a TorqueException.
0721:             */
0722:            public static List executeQuery(String queryString, String dbName,
0723:                    boolean singleRecord) throws TorqueException {
0724:                return executeQuery(queryString, 0, -1, dbName, singleRecord);
0725:            }
0726:
0727:            /**
0728:             * Method for performing a SELECT.  Returns all results.
0729:             *
0730:             * @param queryString A String with the sql statement to execute.
0731:             * @param singleRecord Whether or not we want to select only a
0732:             * single record.
0733:             * @param con A Connection.
0734:             * @return List of Record objects.
0735:             * @throws TorqueException Any exceptions caught during processing will be
0736:             *         rethrown wrapped into a TorqueException.
0737:             */
0738:            public static List executeQuery(String queryString,
0739:                    boolean singleRecord, Connection con)
0740:                    throws TorqueException {
0741:                return executeQuery(queryString, 0, -1, singleRecord, con);
0742:            }
0743:
0744:            /**
0745:             * Method for performing a SELECT.
0746:             *
0747:             * @param queryString A String with the sql statement to execute.
0748:             * @param start The first row to return.
0749:             * @param numberOfResults The number of rows to return.
0750:             * @param dbName The database to connect to.
0751:             * @param singleRecord Whether or not we want to select only a
0752:             * single record.
0753:             * @return List of Record objects.
0754:             * @throws TorqueException Any exceptions caught during processing will be
0755:             *         rethrown wrapped into a TorqueException.
0756:             */
0757:            public static List executeQuery(String queryString, int start,
0758:                    int numberOfResults, String dbName, boolean singleRecord)
0759:                    throws TorqueException {
0760:                Connection con = null;
0761:                List results = null;
0762:                try {
0763:                    con = Torque.getConnection(dbName);
0764:                    // execute the query
0765:                    results = executeQuery(queryString, start, numberOfResults,
0766:                            singleRecord, con);
0767:                } finally {
0768:                    Torque.closeConnection(con);
0769:                }
0770:                return results;
0771:            }
0772:
0773:            /**
0774:             * Method for performing a SELECT.  Returns all results.
0775:             *
0776:             * @param queryString A String with the sql statement to execute.
0777:             * @param start The first row to return.
0778:             * @param numberOfResults The number of rows to return.
0779:             * @param singleRecord Whether or not we want to select only a
0780:             * single record.
0781:             * @param con A Connection.
0782:             * @return List of Record objects.
0783:             * @throws TorqueException Any exceptions caught during processing will be
0784:             *         rethrown wrapped into a TorqueException.
0785:             */
0786:            public static List executeQuery(String queryString, int start,
0787:                    int numberOfResults, boolean singleRecord, Connection con)
0788:                    throws TorqueException {
0789:                QueryDataSet qds = null;
0790:                List results = Collections.EMPTY_LIST;
0791:                try {
0792:                    // execute the query
0793:                    long startTime = System.currentTimeMillis();
0794:                    qds = new QueryDataSet(con, queryString);
0795:                    if (log.isDebugEnabled()) {
0796:                        log.debug("Elapsed time="
0797:                                + (System.currentTimeMillis() - startTime)
0798:                                + " ms");
0799:                    }
0800:                    results = getSelectResults(qds, start, numberOfResults,
0801:                            singleRecord);
0802:                } catch (DataSetException e) {
0803:                    throwTorqueException(e);
0804:                } catch (SQLException e) {
0805:                    throwTorqueException(e);
0806:                } finally {
0807:                    VillageUtils.close(qds);
0808:                }
0809:                return results;
0810:            }
0811:
0812:            /**
0813:             * Returns all records in a QueryDataSet as a List of Record
0814:             * objects.  Used for functionality like util.LargeSelect.
0815:             *
0816:             * @see #getSelectResults(QueryDataSet, int, int, boolean)
0817:             * @param qds the QueryDataSet
0818:             * @return a List of Record objects
0819:             * @throws TorqueException Any exceptions caught during processing will be
0820:             *         rethrown wrapped into a TorqueException.
0821:             */
0822:            public static List getSelectResults(QueryDataSet qds)
0823:                    throws TorqueException {
0824:                return getSelectResults(qds, 0, -1, false);
0825:            }
0826:
0827:            /**
0828:             * Returns all records in a QueryDataSet as a List of Record
0829:             * objects.  Used for functionality like util.LargeSelect.
0830:             *
0831:             * @see #getSelectResults(QueryDataSet, int, int, boolean)
0832:             * @param qds the QueryDataSet
0833:             * @param singleRecord
0834:             * @return a List of Record objects
0835:             * @throws TorqueException Any exceptions caught during processing will be
0836:             *         rethrown wrapped into a TorqueException.
0837:             */
0838:            public static List getSelectResults(QueryDataSet qds,
0839:                    boolean singleRecord) throws TorqueException {
0840:                return getSelectResults(qds, 0, -1, singleRecord);
0841:            }
0842:
0843:            /**
0844:             * Returns numberOfResults records in a QueryDataSet as a List
0845:             * of Record objects.  Starting at record 0.  Used for
0846:             * functionality like util.LargeSelect.
0847:             *
0848:             * @see #getSelectResults(QueryDataSet, int, int, boolean)
0849:             * @param qds the QueryDataSet
0850:             * @param numberOfResults
0851:             * @param singleRecord
0852:             * @return a List of Record objects
0853:             * @throws TorqueException Any exceptions caught during processing will be
0854:             *         rethrown wrapped into a TorqueException.
0855:             */
0856:            public static List getSelectResults(QueryDataSet qds,
0857:                    int numberOfResults, boolean singleRecord)
0858:                    throws TorqueException {
0859:                List results = null;
0860:                if (numberOfResults != 0) {
0861:                    results = getSelectResults(qds, 0, numberOfResults,
0862:                            singleRecord);
0863:                }
0864:                return results;
0865:            }
0866:
0867:            /**
0868:             * Returns numberOfResults records in a QueryDataSet as a List
0869:             * of Record objects.  Starting at record start.  Used for
0870:             * functionality like util.LargeSelect.
0871:             *
0872:             * @param qds The <code>QueryDataSet</code> to extract results
0873:             * from.
0874:             * @param start The index from which to start retrieving
0875:             * <code>Record</code> objects from the data set.
0876:             * @param numberOfResults The number of results to return (or
0877:             * <code> -1</code> for all results).
0878:             * @param singleRecord Whether or not we want to select only a
0879:             * single record.
0880:             * @return A <code>List</code> of <code>Record</code> objects.
0881:             * @exception TorqueException If any <code>Exception</code> occurs.
0882:             */
0883:            public static List getSelectResults(QueryDataSet qds, int start,
0884:                    int numberOfResults, boolean singleRecord)
0885:                    throws TorqueException {
0886:                List results = null;
0887:                try {
0888:                    if (numberOfResults < 0) {
0889:                        results = new ArrayList();
0890:                        qds.fetchRecords();
0891:                    } else {
0892:                        results = new ArrayList(numberOfResults);
0893:                        qds.fetchRecords(start, numberOfResults);
0894:                    }
0895:
0896:                    int startRecord = 0;
0897:
0898:                    //Offset the correct number of records
0899:                    if (start > 0 && numberOfResults <= 0) {
0900:                        startRecord = start;
0901:                    }
0902:
0903:                    // Return a List of Record objects.
0904:                    for (int i = startRecord; i < qds.size(); i++) {
0905:                        Record rec = qds.getRecord(i);
0906:                        results.add(rec);
0907:                    }
0908:
0909:                    if (results.size() > 1 && singleRecord) {
0910:                        handleMultipleRecords(qds);
0911:                    }
0912:                } catch (Exception e) {
0913:                    throwTorqueException(e);
0914:                }
0915:                return results;
0916:            }
0917:
0918:            /**
0919:             * Helper method which returns the primary key contained
0920:             * in the given Criteria object.
0921:             *
0922:             * @param criteria A Criteria.
0923:             * @return ColumnMap if the Criteria object contains a primary
0924:             *          key, or null if it doesn't.
0925:             * @throws TorqueException Any exceptions caught during processing will be
0926:             *         rethrown wrapped into a TorqueException.
0927:             */
0928:            private static ColumnMap getPrimaryKey(Criteria criteria)
0929:                    throws TorqueException {
0930:                // Assume all the keys are for the same table.
0931:                String key = (String) criteria.keys().nextElement();
0932:
0933:                String table = criteria.getTableName(key);
0934:                ColumnMap pk = null;
0935:
0936:                if (!table.equals("")) {
0937:                    DatabaseMap dbMap = Torque.getDatabaseMap(criteria
0938:                            .getDbName());
0939:                    if (dbMap == null) {
0940:                        throw new TorqueException("dbMap is null");
0941:                    }
0942:                    if (dbMap.getTable(table) == null) {
0943:                        throw new TorqueException("dbMap.getTable() is null");
0944:                    }
0945:
0946:                    ColumnMap[] columns = dbMap.getTable(table).getColumns();
0947:
0948:                    for (int i = 0; i < columns.length; i++) {
0949:                        if (columns[i].isPrimaryKey()) {
0950:                            pk = columns[i];
0951:                            break;
0952:                        }
0953:                    }
0954:                }
0955:                return pk;
0956:            }
0957:
0958:            /**
0959:             * Convenience method used to update rows in the DB.  Checks if a
0960:             * <i>single</i> int primary key is specified in the Criteria
0961:             * object and uses it to perform the udpate.  If no primary key is
0962:             * specified an Exception will be thrown.
0963:             * <p>
0964:             * Use this method for performing an update of the kind:
0965:             * <p>
0966:             * "WHERE primary_key_id = an int"
0967:             * <p>
0968:             * To perform an update with non-primary key fields in the WHERE
0969:             * clause use doUpdate(criteria, criteria).
0970:             *
0971:             * @param updateValues A Criteria object containing values used in
0972:             *        set clause.
0973:             * @throws TorqueException Any exceptions caught during processing will be
0974:             *         rethrown wrapped into a TorqueException.
0975:             */
0976:            public static void doUpdate(Criteria updateValues)
0977:                    throws TorqueException {
0978:                Connection con = null;
0979:                try {
0980:                    con = Transaction.beginOptional(updateValues.getDbName(),
0981:                            updateValues.isUseTransaction());
0982:                    doUpdate(updateValues, con);
0983:                    Transaction.commit(con);
0984:                } catch (TorqueException e) {
0985:                    Transaction.safeRollback(con);
0986:                    throw e;
0987:                }
0988:            }
0989:
0990:            /**
0991:             * Convenience method used to update rows in the DB.  Checks if a
0992:             * <i>single</i> int primary key is specified in the Criteria
0993:             * object and uses it to perform the udpate.  If no primary key is
0994:             * specified an Exception will be thrown.
0995:             * <p>
0996:             * Use this method for performing an update of the kind:
0997:             * <p>
0998:             * "WHERE primary_key_id = an int"
0999:             * <p>
1000:             * To perform an update with non-primary key fields in the WHERE
1001:             * clause use doUpdate(criteria, criteria).
1002:             *
1003:             * @param updateValues A Criteria object containing values used in
1004:             * set clause.
1005:             * @param con A Connection.
1006:             * @throws TorqueException Any exceptions caught during processing will be
1007:             *         rethrown wrapped into a TorqueException.
1008:             */
1009:            public static void doUpdate(Criteria updateValues, Connection con)
1010:                    throws TorqueException {
1011:                ColumnMap pk = getPrimaryKey(updateValues);
1012:                Criteria selectCriteria = null;
1013:
1014:                if (pk != null
1015:                        && updateValues.containsKey(pk.getFullyQualifiedName())) {
1016:                    selectCriteria = new Criteria(2);
1017:                    selectCriteria.put(pk.getFullyQualifiedName(), updateValues
1018:                            .remove(pk.getFullyQualifiedName()));
1019:                } else {
1020:                    throw new TorqueException(
1021:                            "No PK specified for database update");
1022:                }
1023:
1024:                doUpdate(selectCriteria, updateValues, con);
1025:            }
1026:
1027:            /**
1028:             * Method used to update rows in the DB.  Rows are selected based
1029:             * on selectCriteria and updated using values in updateValues.
1030:             * <p>
1031:             * Use this method for performing an update of the kind:
1032:             * <p>
1033:             * WHERE some_column = some value AND could_have_another_column =
1034:             * another value AND so on...
1035:             *
1036:             * @param selectCriteria A Criteria object containing values used in where
1037:             *        clause.
1038:             * @param updateValues A Criteria object containing values used in set
1039:             *        clause.
1040:             * @throws TorqueException Any exceptions caught during processing will be
1041:             *         rethrown wrapped into a TorqueException.
1042:             */
1043:            public static void doUpdate(Criteria selectCriteria,
1044:                    Criteria updateValues) throws TorqueException {
1045:                Connection con = null;
1046:                try {
1047:                    con = Transaction.beginOptional(selectCriteria.getDbName(),
1048:                            updateValues.isUseTransaction());
1049:                    doUpdate(selectCriteria, updateValues, con);
1050:                    Transaction.commit(con);
1051:                } catch (TorqueException e) {
1052:                    Transaction.safeRollback(con);
1053:                    throw e;
1054:                }
1055:            }
1056:
1057:            /**
1058:             * Method used to update rows in the DB.  Rows are selected based
1059:             * on criteria and updated using values in updateValues.
1060:             * <p>
1061:             * Use this method for performing an update of the kind:
1062:             * <p>
1063:             * WHERE some_column = some value AND could_have_another_column =
1064:             * another value AND so on.
1065:             *
1066:             * @param criteria A Criteria object containing values used in where
1067:             *        clause.
1068:             * @param updateValues A Criteria object containing values used in set
1069:             *        clause.
1070:             * @param con A Connection.
1071:             * @throws TorqueException Any exceptions caught during processing will be
1072:             *         rethrown wrapped into a TorqueException.
1073:             */
1074:            public static void doUpdate(Criteria criteria,
1075:                    final Criteria updateValues, Connection con)
1076:                    throws TorqueException {
1077:                Set tables = SQLBuilder.getTableSet(criteria, null);
1078:
1079:                try {
1080:                    processTables(criteria, tables, con, new ProcessCallback() {
1081:                        public void process(String table, String dbName,
1082:                                Record rec) throws Exception {
1083:                            // Callback must be called with table name without Schema!
1084:                            BasePeer.insertOrUpdateRecord(rec, table, dbName,
1085:                                    updateValues);
1086:                        }
1087:                    });
1088:                } catch (Exception e) {
1089:                    throwTorqueException(e);
1090:                }
1091:            }
1092:
1093:            /**
1094:             * Utility method which executes a given sql statement.  This
1095:             * method should be used for update, insert, and delete
1096:             * statements.  Use executeQuery() for selects.
1097:             *
1098:             * @param statementString A String with the sql statement to execute.
1099:             * @return The number of rows affected.
1100:             * @throws TorqueException Any exceptions caught during processing will be
1101:             *         rethrown wrapped into a TorqueException.
1102:             */
1103:            public static int executeStatement(String statementString)
1104:                    throws TorqueException {
1105:                return executeStatement(statementString, Torque.getDefaultDB());
1106:            }
1107:
1108:            /**
1109:             * Utility method which executes a given sql statement.  This
1110:             * method should be used for update, insert, and delete
1111:             * statements.  Use executeQuery() for selects.
1112:             *
1113:             * @param statementString A String with the sql statement to execute.
1114:             * @param dbName Name of database to connect to.
1115:             * @return The number of rows affected.
1116:             * @throws TorqueException Any exceptions caught during processing will be
1117:             *         rethrown wrapped into a TorqueException.
1118:             */
1119:            public static int executeStatement(String statementString,
1120:                    String dbName) throws TorqueException {
1121:                Connection con = null;
1122:                int rowCount = -1;
1123:                try {
1124:                    con = Torque.getConnection(dbName);
1125:                    rowCount = executeStatement(statementString, con);
1126:                } finally {
1127:                    Torque.closeConnection(con);
1128:                }
1129:                return rowCount;
1130:            }
1131:
1132:            /**
1133:             * Utility method which executes a given sql statement.  This
1134:             * method should be used for update, insert, and delete
1135:             * statements.  Use executeQuery() for selects.
1136:             *
1137:             * @param statementString A String with the sql statement to execute.
1138:             * @param con A Connection.
1139:             * @return The number of rows affected.
1140:             * @throws TorqueException Any exceptions caught during processing will be
1141:             *         rethrown wrapped into a TorqueException.
1142:             */
1143:            public static int executeStatement(String statementString,
1144:                    Connection con) throws TorqueException {
1145:                int rowCount = -1;
1146:                Statement statement = null;
1147:                try {
1148:                    statement = con.createStatement();
1149:                    rowCount = statement.executeUpdate(statementString);
1150:                } catch (SQLException e) {
1151:                    throw new TorqueException(e);
1152:                } finally {
1153:                    if (statement != null) {
1154:                        try {
1155:                            statement.close();
1156:                        } catch (SQLException e) {
1157:                            throw new TorqueException(e);
1158:                        }
1159:                    }
1160:                }
1161:                return rowCount;
1162:            }
1163:
1164:            /**
1165:             * If the user specified that (s)he only wants to retrieve a
1166:             * single record and multiple records are retrieved, this method
1167:             * is called to handle the situation.  The default behavior is to
1168:             * throw an exception, but subclasses can override this method as
1169:             * needed.
1170:             *
1171:             * @param ds The DataSet which contains multiple records.
1172:             * @exception TorqueException Couldn't handle multiple records.
1173:             */
1174:            protected static void handleMultipleRecords(DataSet ds)
1175:                    throws TorqueException {
1176:                throw new TorqueException(
1177:                        "Criteria expected single Record and "
1178:                                + "Multiple Records were selected");
1179:            }
1180:
1181:            /**
1182:             * This method returns the MapBuilder specified in the name
1183:             * parameter.  You should pass in the full path to the class, ie:
1184:             * org.apache.torque.util.db.map.TurbineMapBuilder.  The
1185:             * MapBuilder instances are cached in the TorqueInstance for speed.
1186:             *
1187:             * @param name name of the MapBuilder
1188:             * @return A MapBuilder, not null
1189:             * @throws TorqueException if the Map Builder cannot be instantiated
1190:             * @deprecated Use Torque.getMapBuilder(name) instead
1191:             */
1192:            public static MapBuilder getMapBuilder(String name)
1193:                    throws TorqueException {
1194:                return Torque.getMapBuilder(name);
1195:            }
1196:
1197:            /**
1198:             * Performs a SQL <code>select</code> using a PreparedStatement.
1199:             * Note: this method does not handle null criteria values.
1200:             *
1201:             * @param criteria
1202:             * @param con
1203:             * @return a List of Record objects.
1204:             * @throws TorqueException Error performing database query.
1205:             */
1206:            public static List doPSSelect(Criteria criteria, Connection con)
1207:                    throws TorqueException {
1208:                List v = null;
1209:
1210:                StringBuffer qry = new StringBuffer();
1211:                List params = new ArrayList(criteria.size());
1212:
1213:                createPreparedStatement(criteria, qry, params);
1214:
1215:                PreparedStatement statement = null;
1216:                try {
1217:                    statement = con.prepareStatement(qry.toString());
1218:
1219:                    for (int i = 0; i < params.size(); i++) {
1220:                        Object param = params.get(i);
1221:                        if (param instanceof  java.sql.Date) {
1222:                            statement.setDate(i + 1, (java.sql.Date) param);
1223:                        } else if (param instanceof  NumberKey) {
1224:                            statement.setBigDecimal(i + 1, ((NumberKey) param)
1225:                                    .getBigDecimal());
1226:                        } else if (param instanceof  Integer) {
1227:                            statement.setInt(i + 1, ((Integer) param)
1228:                                    .intValue());
1229:                        } else {
1230:                            statement.setString(i + 1, param.toString());
1231:                        }
1232:                    }
1233:
1234:                    QueryDataSet qds = null;
1235:                    try {
1236:                        qds = new QueryDataSet(statement.executeQuery());
1237:                        v = getSelectResults(qds);
1238:                    } finally {
1239:                        VillageUtils.close(qds);
1240:                    }
1241:                } catch (DataSetException e) {
1242:                    throwTorqueException(e);
1243:                } catch (SQLException e) {
1244:                    throwTorqueException(e);
1245:                } finally {
1246:                    if (statement != null) {
1247:                        try {
1248:                            statement.close();
1249:                        } catch (SQLException e) {
1250:                            throw new TorqueException(e);
1251:                        }
1252:                    }
1253:                }
1254:                return v;
1255:            }
1256:
1257:            /**
1258:             * Do a Prepared Statement select according to the given criteria
1259:             *
1260:             * @param criteria
1261:             * @return a List of Record objects.
1262:             * @throws TorqueException Any exceptions caught during processing will be
1263:             *         rethrown wrapped into a TorqueException.
1264:             */
1265:            public static List doPSSelect(Criteria criteria)
1266:                    throws TorqueException {
1267:                Connection con = Torque.getConnection(criteria.getDbName());
1268:                List v = null;
1269:
1270:                try {
1271:                    v = doPSSelect(criteria, con);
1272:                } finally {
1273:                    Torque.closeConnection(con);
1274:                }
1275:                return v;
1276:            }
1277:
1278:            /**
1279:             * Create a new PreparedStatement.  It builds a string representation
1280:             * of a query and a list of PreparedStatement parameters.
1281:             *
1282:             * @param criteria
1283:             * @param queryString
1284:             * @param params
1285:             * @throws TorqueException Any exceptions caught during processing will be
1286:             *         rethrown wrapped into a TorqueException.
1287:             */
1288:            public static void createPreparedStatement(Criteria criteria,
1289:                    StringBuffer queryString, List params)
1290:                    throws TorqueException {
1291:                Query query = SQLBuilder.buildQueryClause(criteria, params,
1292:                        new SQLBuilder.QueryCallback() {
1293:                            public String process(Criteria.Criterion criterion,
1294:                                    List params) {
1295:                                StringBuffer sb = new StringBuffer();
1296:                                criterion.appendPsTo(sb, params);
1297:                                return sb.toString();
1298:                            }
1299:                        });
1300:
1301:                String sql = query.toString();
1302:                log.debug(sql);
1303:
1304:                queryString.append(sql);
1305:            }
1306:
1307:            /**
1308:             * Checks all columns in the criteria to see whether
1309:             * booleanchar and booleanint columns are queried with a boolean.
1310:             * If yes, the query values are mapped onto values the database
1311:             * does understand, i.e. 0 and 1 for booleanints and N and Y for
1312:             * booleanchar columns.
1313:             *
1314:             * @param criteria The criteria to be checked for booleanint and booleanchar
1315:             *        columns.
1316:             * @param defaultTableMap the table map to be used if the table name is
1317:             *        not given in a column.
1318:             * @throws TorqueException if the database map for the criteria cannot be
1319:             *         retrieved.
1320:             */
1321:            public static void correctBooleans(Criteria criteria,
1322:                    TableMap defaultTableMap) throws TorqueException {
1323:                Iterator keyIt = criteria.keySet().iterator();
1324:                while (keyIt.hasNext()) {
1325:                    String key = (String) keyIt.next();
1326:                    String columnName;
1327:                    TableMap tableMap = null;
1328:                    int dotPosition = key.lastIndexOf(".");
1329:                    if (dotPosition == -1) {
1330:                        columnName = key;
1331:                        tableMap = defaultTableMap;
1332:                    } else {
1333:                        columnName = key.substring(dotPosition + 1);
1334:                        String tableName = key.substring(0, dotPosition);
1335:                        String databaseName = criteria.getDbName();
1336:                        if (databaseName == null) {
1337:                            databaseName = Torque.getDefaultDB();
1338:                        }
1339:                        DatabaseMap databaseMap = Torque
1340:                                .getDatabaseMap(databaseName);
1341:                        if (databaseMap != null) {
1342:                            tableMap = databaseMap.getTable(tableName);
1343:                        }
1344:                        if (tableMap == null) {
1345:                            // try aliases
1346:                            Map aliases = criteria.getAliases();
1347:                            if (aliases.get(tableName) != null) {
1348:                                tableName = (String) aliases.get(tableName);
1349:                                tableMap = databaseMap.getTable(tableName);
1350:                            }
1351:                        }
1352:                    }
1353:                    if (tableMap == null) {
1354:                        // no description of table available, do not modify anything
1355:                        continue;
1356:                    }
1357:
1358:                    ColumnMap columnMap = tableMap.getColumn(columnName);
1359:                    if (columnMap != null) {
1360:                        if ("BOOLEANINT".equals(columnMap.getTorqueType())) {
1361:                            Criteria.Criterion criterion = criteria
1362:                                    .getCriterion(key);
1363:                            replaceBooleanValues(criterion, new Integer(1),
1364:                                    new Integer(0));
1365:                        } else if ("BOOLEANCHAR".equals(columnMap
1366:                                .getTorqueType())) {
1367:                            Criteria.Criterion criterion = criteria
1368:                                    .getCriterion(key);
1369:                            replaceBooleanValues(criterion, "Y", "N");
1370:                        }
1371:                    }
1372:                }
1373:            }
1374:
1375:            /**
1376:             * Replaces any Boolean value in the criterion and its attached Criterions
1377:             * by trueValue if the Boolean equals <code>Boolean.TRUE</code>
1378:             * and falseValue if the Boolean equals <code>Boolean.FALSE</code>.
1379:             *
1380:             * @param criterion the criterion to replace Boolean values in.
1381:             * @param trueValue the value by which Boolean.TRUE should be replaced.
1382:             * @param falseValue the value by which Boolean.FALSE should be replaced.
1383:             */
1384:            private static void replaceBooleanValues(
1385:                    Criteria.Criterion criterion, Object trueValue,
1386:                    Object falseValue) {
1387:                // attachedCriterions also contains the criterion itself,
1388:                // so no additional treatment is needed for the criterion itself.
1389:                Criteria.Criterion[] attachedCriterions = criterion
1390:                        .getAttachedCriterion();
1391:                for (int i = 0; i < attachedCriterions.length; ++i) {
1392:                    Object criterionValue = attachedCriterions[i].getValue();
1393:                    if (criterionValue instanceof  Boolean) {
1394:                        Boolean booleanValue = (Boolean) criterionValue;
1395:                        attachedCriterions[i].setValue(Boolean.TRUE
1396:                                .equals(booleanValue) ? trueValue : falseValue);
1397:                    }
1398:
1399:                }
1400:
1401:            }
1402:
1403:            /**
1404:             * Process the result of a Table list generation.
1405:             * This runs the statements onto the list of tables and
1406:             * provides a callback hook to add functionality.
1407:             *
1408:             * This method should've been in SQLBuilder, but is uses the handleMultipleRecords callback thingie..
1409:             *
1410:             * @param crit The criteria
1411:             * @param tables A set of Tables to run on
1412:             * @param con The SQL Connection to run the statements on
1413:             * @param pc A ProcessCallback object
1414:             *
1415:             * @throws Exception An Error occured (should be wrapped into TorqueException)
1416:             */
1417:            private static void processTables(Criteria crit, Set tables,
1418:                    Connection con, ProcessCallback pc) throws Exception {
1419:                String dbName = crit.getDbName();
1420:                DB db = Torque.getDB(dbName);
1421:                DatabaseMap dbMap = Torque.getDatabaseMap(dbName);
1422:
1423:                // create the statements for the tables
1424:                for (Iterator it = tables.iterator(); it.hasNext();) {
1425:                    String table = (String) it.next();
1426:                    KeyDef kd = new KeyDef();
1427:                    Set whereClause = new HashSet();
1428:
1429:                    ColumnMap[] columnMaps = dbMap.getTable(table).getColumns();
1430:
1431:                    for (int j = 0; j < columnMaps.length; j++) {
1432:                        ColumnMap colMap = columnMaps[j];
1433:                        if (colMap.isPrimaryKey()) {
1434:                            kd.addAttrib(colMap.getColumnName());
1435:                        }
1436:
1437:                        String key = new StringBuffer(colMap.getTableName())
1438:                                .append('.').append(colMap.getColumnName())
1439:                                .toString();
1440:
1441:                        if (crit.containsKey(key)) {
1442:                            if (crit.getComparison(key).equals(Criteria.CUSTOM)) {
1443:                                whereClause.add(crit.getString(key));
1444:                            } else {
1445:                                whereClause.add(SqlExpression.build(colMap
1446:                                        .getColumnName(), crit.getValue(key),
1447:                                        crit.getComparison(key), crit
1448:                                                .isIgnoreCase(), db));
1449:                            }
1450:                        }
1451:                    }
1452:
1453:                    // Execute the statement for each table
1454:                    TableDataSet tds = null;
1455:                    try {
1456:                        String tableName = SQLBuilder.getFullTableName(table,
1457:                                dbName);
1458:
1459:                        // Get affected records.
1460:                        tds = new TableDataSet(con, tableName, kd);
1461:                        String sqlSnippet = StringUtils.join(whereClause
1462:                                .iterator(), " AND ");
1463:
1464:                        if (log.isDebugEnabled()) {
1465:                            log.debug("BasePeer: whereClause=" + sqlSnippet);
1466:                        }
1467:
1468:                        tds.where(sqlSnippet);
1469:                        tds.fetchRecords();
1470:
1471:                        if (tds.size() > 1 && crit.isSingleRecord()) {
1472:                            handleMultipleRecords(tds);
1473:                        }
1474:
1475:                        for (int j = 0; j < tds.size(); j++) {
1476:                            Record rec = tds.getRecord(j);
1477:
1478:                            if (pc != null) {
1479:                                // Table name _without_ schema!
1480:                                pc.process(table, dbName, rec);
1481:                            }
1482:                        }
1483:                    } finally {
1484:                        VillageUtils.close(tds);
1485:                    }
1486:                }
1487:            }
1488:
1489:            /**
1490:             * Inner Interface that defines the Callback method for
1491:             * the Record Processing
1492:             */
1493:            protected interface ProcessCallback {
1494:                void process(String table, String dbName, Record rec)
1495:                        throws Exception;
1496:            }
1497:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.