Source Code Cross Referenced for JDBCDataObject.java in  » J2EE » Expresso » com » jcorporate » expresso » core » dataobjects » jdbc » 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 » J2EE » Expresso » com.jcorporate.expresso.core.dataobjects.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003:         *
0004:         * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         *
0010:         * 1. Redistributions of source code must retain the above copyright
0011:         *    notice, this list of conditions and the following disclaimer.
0012:         *
0013:         * 2. Redistributions in binary form must reproduce the above copyright
0014:         *    notice, this list of conditions and the following disclaimer in
0015:         *    the documentation and/or other materials provided with the
0016:         *    distribution.
0017:         *
0018:         * 3. The end-user documentation included with the redistribution,
0019:         *    if any, must include the following acknowledgment:
0020:         *       "This product includes software developed by Jcorporate Ltd.
0021:         *        (http://www.jcorporate.com/)."
0022:         *    Alternately, this acknowledgment may appear in the software itself,
0023:         *    if and wherever such third-party acknowledgments normally appear.
0024:         *
0025:         * 4. "Jcorporate" and product names such as "Expresso" must
0026:         *    not be used to endorse or promote products derived from this
0027:         *    software without prior written permission. For written permission,
0028:         *    please contact info@jcorporate.com.
0029:         *
0030:         * 5. Products derived from this software may not be called "Expresso",
0031:         *    or other Jcorporate product names; nor may "Expresso" or other
0032:         *    Jcorporate product names appear in their name, without prior
0033:         *    written permission of Jcorporate Ltd.
0034:         *
0035:         * 6. No product derived from this software may compete in the same
0036:         *    market space, i.e. framework, without prior written permission
0037:         *    of Jcorporate Ltd. For written permission, please contact
0038:         *    partners@jcorporate.com.
0039:         *
0040:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043:         * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044:         * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046:         * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051:         * SUCH DAMAGE.
0052:         * ====================================================================
0053:         *
0054:         * This software consists of voluntary contributions made by many
0055:         * individuals on behalf of the Jcorporate Ltd. Contributions back
0056:         * to the project(s) are encouraged when you make modifications.
0057:         * Please send them to support@jcorporate.com. For more information
0058:         * on Jcorporate Ltd. and its products, please see
0059:         * <http://www.jcorporate.com/>.
0060:         *
0061:         * Portions of this software are based upon other open source
0062:         * products and are subject to their respective licenses.
0063:         */
0064:        package com.jcorporate.expresso.core.dataobjects.jdbc;
0065:
0066:        import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
0067:        import com.jcorporate.expresso.core.dataobjects.BaseDataObject;
0068:        import com.jcorporate.expresso.core.dataobjects.DataException;
0069:        import com.jcorporate.expresso.core.dataobjects.DataExecutorInterface;
0070:        import com.jcorporate.expresso.core.dataobjects.DataFieldMetaData;
0071:        import com.jcorporate.expresso.core.dataobjects.DataObjectMetaData;
0072:        import com.jcorporate.expresso.core.dataobjects.DataQueryInterface;
0073:        import com.jcorporate.expresso.core.db.DBConnection;
0074:        import com.jcorporate.expresso.core.db.DBConnectionPool;
0075:        import com.jcorporate.expresso.core.db.DBException;
0076:        import com.jcorporate.expresso.core.db.config.JDBCConfig;
0077:        import com.jcorporate.expresso.core.dbobj.DBField;
0078:        import com.jcorporate.expresso.core.dbobj.DBObjectDef;
0079:        import com.jcorporate.expresso.core.misc.Base64;
0080:        import com.jcorporate.expresso.core.misc.ConfigJdbc;
0081:        import com.jcorporate.expresso.core.misc.ConfigManager;
0082:        import com.jcorporate.expresso.core.misc.ConfigurationException;
0083:        import com.jcorporate.expresso.core.misc.DateTime;
0084:        import com.jcorporate.expresso.core.misc.StringUtil;
0085:        import com.jcorporate.expresso.core.registry.RequestRegistry;
0086:        import com.jcorporate.expresso.core.security.CryptoManager;
0087:        import com.jcorporate.expresso.kernel.exception.ChainedException;
0088:        import com.jcorporate.expresso.kernel.util.FastStringBuffer;
0089:        import org.apache.log4j.Logger;
0090:
0091:        import java.io.InputStream;
0092:        import java.sql.CallableStatement;
0093:        import java.util.ArrayList;
0094:        import java.util.HashMap;
0095:        import java.util.Iterator;
0096:
0097:        /**
0098:         * Base class for JDBC-based data objects.
0099:         *
0100:         * @author Michael Rimov
0101:         * @since Expresso 5.1
0102:         *        <p/>
0103:         *        Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0104:         */
0105:
0106:        abstract public class JDBCDataObject extends BaseDataObject {
0107:
0108:            private static transient final Logger log = Logger
0109:                    .getLogger(JDBCDataObject.class);
0110:
0111:            public static int LONGBINARY_READ_DEFAULT_SIZE = 262144;
0112:
0113:            /**
0114:             * a local connection pool.  Often used to save on going back and forth
0115:             * to the connection pool, or if you want JDBC transactions.
0116:             */
0117:            transient private DBConnectionPool myPool = null;
0118:
0119:            /**
0120:             * Normally originalDBKey is the same as DB key, except where the DB object is mapped
0121:             * to another database specifically, in which case originalDBKey can be used
0122:             * to determine the database to be used to find Expresso's own tables
0123:             */
0124:            private String mappedDataContext = null;
0125:
0126:            /**
0127:             * If we are using a custom where clause for this query, it's stored here.
0128:             * If null, then build the where clause
0129:             */
0130:            protected String customWhereClause = null;
0131:
0132:            /**
0133:             * Flag to indicate whether we append any custom WHERE clause to
0134:             * the one generated, or just use the supplied custom WHERE clause
0135:             */
0136:            protected boolean appendCustomWhere = false;
0137:
0138:            /**
0139:             * dbKey is used to indicate that this object is actually stored in
0140:             * other than the default database. Null indicates it's in the default
0141:             * database
0142:             */
0143:            protected String dbKey = null;
0144:
0145:            /**
0146:             * The ArrayList of DB objects retrieved by the last searchAndRetrieve method
0147:             */
0148:            protected ArrayList recordSet = null;
0149:
0150:            /**
0151:             * We use getClass().getName() a lot in this class, however, it takes
0152:             * actually significant time to use this over the time it takes to do, say,
0153:             * a concurrentReaderHashMap lookup.  So we precalculate this value at
0154:             * instantiation and go from there.
0155:             */
0156:            transient protected String myClassName = getClass().getName();
0157:
0158:            /**
0159:             * Map of any distinct fields for retrieval.
0160:             */
0161:            protected HashMap distinctFields = null;
0162:
0163:            /**
0164:             * The actual fields retrieved
0165:             */
0166:            public HashMap retrieveFields = null;
0167:
0168:            /**
0169:             * DBObjects themselves do not contain the "meta data" or the definition of
0170:             * what fields they contain and other information. Instead, a DBObjectRef object
0171:             * (one per TYPE of DBObject) contains this info and is looked up as needed.
0172:             * This HashMap contains the DBObjectRef objects for all initialized DBObjects
0173:             *
0174:             * @todo move this static variable outside DBObject so we can wrap it for
0175:             * EJBs
0176:             */
0177:            volatile transient protected static ConcurrentReaderHashMap sMetadataMap = new ConcurrentReaderHashMap();
0178:
0179:            /**
0180:             * If setFieldsToRetrieve has been used to specify fields which will be
0181:             * retrieve by the next query.
0182:             */
0183:            protected boolean anyFieldsToRetrieve = false;
0184:
0185:            /**
0186:             * Local connection that we use if it's initialized, but
0187:             * if it's null we generate our own connection
0188:             */
0189:            transient protected DBConnection localConnection = null;
0190:
0191:            /**
0192:             * The number of records we must skip over before we start reading
0193:             * the <code>ResultSet</code> proper in a searchAndRetrieve.
0194:             * 0 means no limit
0195:             * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
0196:             */
0197:            transient protected int offsetRecord = 0;
0198:
0199:            /* The max number of records we retrieve in a searchAndRetrieve.
0200:             * 0 means no limit
0201:             */
0202:            transient protected int maxRecords = 0;
0203:
0204:            /**
0205:             * The list of fields by which this object should be sorted when
0206:             * records are retrieved
0207:             */
0208:            transient protected ArrayList sortKeys = null;
0209:
0210:            /**
0211:             * Holds the FieldUpdate objects representing any changes made to this
0212:             * object since it was retrieved
0213:             */
0214:            transient protected ArrayList myUpdates = null;
0215:
0216:            /**
0217:             * If setFieldDistinct has been used to specify distinct/unique fields for
0218:             * the next query.
0219:             */
0220:            public boolean anyFieldsDistinct = false;
0221:
0222:            /**
0223:             * This flag tells the buildWhereClause method(s) to either be case
0224:             * sensitive (normal queries) or to be case insensitive. The case
0225:             * insensitive query is useful when you want to do a search and retreive
0226:             * and want case insensitive matching.
0227:             */
0228:            protected boolean caseSensitiveQuery = true;
0229:
0230:            /**
0231:             * Utility class that currently provides help for getFieldDate() function.
0232:             */
0233:            transient static private JDBCUtil sJdbcUtil = JDBCUtil
0234:                    .getInstance();
0235:
0236:            /**
0237:             * Helper component that provides the specific interactions between the
0238:             * DBObject and the underlying datasource, JDBC or later on, otherwise
0239:             *
0240:             * @since Expresso 5.0
0241:             */
0242:            transient private static DataExecutorInterface sDataExecutor = new JDBCExecutor();
0243:
0244:            /**
0245:             * Helper component that provides the specific querying capabilities
0246:             * against any particular datasrouce, JDBC, or later on, others.
0247:             *
0248:             * @since Expresso 5.0
0249:             */
0250:            transient private static DataQueryInterface sDataQueryObject = new JDBCQuery();
0251:
0252:            /**
0253:             * Default constructor
0254:             */
0255:            public JDBCDataObject() {
0256:            }
0257:
0258:            /**
0259:             * Returns the name of the physical database that we're talking with.  This
0260:             * is opposed to getDataContext() which returns the security context as well.
0261:             * getMappedDataContext() is strictly used to get at the low level database
0262:             * connection.
0263:             *
0264:             * @return java.lang.String... the underlying data context that is mapped
0265:             *         to the physical database
0266:             */
0267:            public String getMappedDataContext() {
0268:
0269:                if (mappedDataContext == null) {
0270:                    this .setDataContext(RequestRegistry.getDataContext());
0271:                    if (log.isDebugEnabled()) {
0272:                        log
0273:                                .debug("Setting Database Context from Request Registry ");
0274:                    }
0275:                }
0276:                return mappedDataContext;
0277:            }
0278:
0279:            /**
0280:             * Retrieve the connection pool associated with this DBObject.
0281:             *
0282:             * @return DBConnectionPool instance for the current mapped context.
0283:             * @throws DataException upon error getting the connection pool instance
0284:             */
0285:            public DBConnectionPool getConnectionPool() throws DataException {
0286:                try {
0287:                    if (myPool == null) {
0288:                        if (this .getMappedDataContext() == null) {
0289:                            this .setDataContext("default");
0290:                        }
0291:                        String myDataContext = this .getMappedDataContext();
0292:                        myPool = DBConnectionPool.getInstance(myDataContext);
0293:                    }
0294:                } catch (DBException ex) {
0295:                    throw new DataException("Error getting Connection Pool", ex);
0296:                }
0297:
0298:                return myPool;
0299:            }
0300:
0301:            /**
0302:             * Sets the connection pool associated with this dbobject.  Is only settable
0303:             * from derived classes as we normally create our own as needed.
0304:             *
0305:             * @param newPool the new DBConnectionPool to set
0306:             */
0307:            protected void setDBConnectionPool(DBConnectionPool newPool) {
0308:                myPool = newPool;
0309:            }
0310:
0311:            /**
0312:             * This function is called whenever the DBField is about to be written to
0313:             * the database.  It may do additional processing such as encryption depending
0314:             * on the field attributes.
0315:             *
0316:             * @param theField A DBField object
0317:             * @return the value to write to the data source.
0318:             * @throws DataException upon error
0319:             * @todo This is not completely implemented yet, and this responsibility for
0320:             * formating a field should probably be
0321:             * put into DBField for better object orientation.
0322:             */
0323:            public String getSerialForm(DataFieldMetaData theField)
0324:                    throws DataException {
0325:                try {
0326:                    if (theField.isEncrypted()) {
0327:                        return Base64.encodeNoPadding(CryptoManager
0328:                                .getInstance().getStringEncryption()
0329:                                .encryptString(
0330:                                        this .getDataField(theField.getName())
0331:                                                .asString()));
0332:                    } else {
0333:                        String result = getDataField(theField.getName())
0334:                                .asString();
0335:                        if (theField.isBooleanType()) {
0336:                            // do we have to convert from true/false to 'Y'/'N' ??
0337:                            try {
0338:                                boolean nativeBoolean = ConfigManager
0339:                                        .getContext(getMappedDataContext())
0340:                                        .getJdbc().isNativeBool();
0341:                                if (!nativeBoolean) {
0342:                                    // fix up a true/false into what we expect to serialize
0343:                                    if ("true".equalsIgnoreCase(result)) {
0344:                                        result = "Y";
0345:                                    }
0346:                                    if ("false".equalsIgnoreCase(result)) {
0347:                                        result = "N";
0348:                                    }
0349:                                }
0350:                            } catch (ConfigurationException ce) {
0351:                                throw new DataException(ce);
0352:                            }
0353:                        }
0354:                        return result;
0355:                    }
0356:                } catch (ChainedException e) {
0357:                    throw new DataException(
0358:                            "Error getting Serialized Form for field: "
0359:                                    + theField.getName(), e);
0360:                }
0361:            } /* getSerializedForm() */
0362:
0363:            /**
0364:             * Set the database name/context for this db object. If setDBName is not called,
0365:             * the "default" db name and context is used.
0366:             * See com.jcorporate.expresso.core.misc.ConfigManager for information about
0367:             * multiple contexts. Note that setting a db/context name only affects the
0368:             * object when it allocates it's own db connections - if a specific connection
0369:             * is used (via the setConnection(DBConnection) method) then that connection must
0370:             * be already associated with the correct db/context.
0371:             * If there is an entry in the DBOtherMap table for this object, it is forced to
0372:             * that database, and a warning is logged if any other database is specified.
0373:             *
0374:             * @param newOther The name of the context or database to use
0375:             */
0376:            public synchronized void setDBName(String newOther)
0377:                    throws DBException {
0378:
0379:                /* Blank or null gets interpreted as "default" */
0380:                if (StringUtil.notNull(newOther).equals("")) {
0381:                    newOther = "default";
0382:                }
0383:
0384:                if (log.isDebugEnabled()) {
0385:                    log.debug("Object '" + myClassName + "' requesting db '"
0386:                            + newOther + "'");
0387:                }
0388:                String mappedContext = newOther;
0389:                dbKey = newOther;
0390:                /* We don't allow an alternate database name to be specified for DBOtherMap itself! */
0391:                if (!"com.jcorporate.expresso.services.dbobj.DBOtherMap"
0392:                        .equals(myClassName)) {
0393:                    String otherdbname = StringUtil.notNull(ConfigManager
0394:                            .getOtherDbLocation(newOther, myClassName));
0395:
0396:                    if (!otherdbname.equals("")) {
0397:                        mappedContext = otherdbname;
0398:
0399:                        if (log.isDebugEnabled()) {
0400:                            log.debug("Object '" + myClassName
0401:                                    + "' mapped to database '" + dbKey + "'");
0402:                        }
0403:                    }
0404:                } /* if we are not DBOtherMap */
0405:
0406:                //Clear the connectionPool if it doesn't exist.
0407:                myPool = null;
0408:
0409:                this .setMappedDataContext(mappedContext);
0410:            } /* setDBName(String) */
0411:
0412:            /**
0413:             * Retrieve the database object's metadata
0414:             *
0415:             * @return a built DataObjectMetaData
0416:             */
0417:            public final DataObjectMetaData getMetaData() {
0418:                return getDef();
0419:            }
0420:
0421:            /**
0422:             * Retrieve the JDBCObjectMetaData
0423:             *
0424:             * @return the JDBCObjectMetadata.  [Actually an instance of DataObjectMetaData,
0425:             *         but this way it's type correct]
0426:             */
0427:            public final JDBCObjectMetaData getJDBCMetaData() {
0428:                return (JDBCObjectMetaData) getMetaData();
0429:            }
0430:
0431:            /**
0432:             * Return the DBObjectRef object that contains the definition of the current
0433:             * DBObject. If there isn't one in the dbobjMetadata hashmap, initialize a new one
0434:             * as required
0435:             *
0436:             * @return static the DBObject Definition
0437:             */
0438:            protected final DBObjectDef getDef() {
0439:                DBObjectDef myDef = (DBObjectDef) sMetadataMap
0440:                        .get(this .myClassName);
0441:
0442:                return myDef;
0443:            } /* getRef() */
0444:
0445:            /**
0446:             * Construction method to allow for specialized metadata with specialized
0447:             * fields other than DBObjectDef.  Override in classes that need custom
0448:             * derived from DBObjectDef classes.
0449:             *
0450:             * @return DBOBjectDef derived instance
0451:             * @throws DBException upon construction error
0452:             */
0453:            protected DBObjectDef constructNewMetaData() throws DBException {
0454:                return new DBObjectDef();
0455:            }
0456:
0457:            /**
0458:             * Returns the checkzero update as defined by the object's metadata.
0459:             *
0460:             * @return true if checkZeroUpdate is unabled
0461:             */
0462:            public boolean checkZeroUpdate() {
0463:                return getDef().checkZeroUpdate();
0464:            }
0465:
0466:            /**
0467:             * Set the name of the db context that was the "original" context
0468:             * for this object - e.g. before any database mapping took place.
0469:             *
0470:             * @param newOriginalName new value to set
0471:             */
0472:            protected void setOriginalDBName(String newOriginalName) {
0473:                mappedDataContext = newOriginalName;
0474:            }
0475:
0476:            protected void setMappedDataContext(String newMappedName) {
0477:                mappedDataContext = newMappedName;
0478:            }
0479:
0480:            /**
0481:             * This tells the buildWhereClause to either respect case (true) or
0482:             * ignore case (false). You can call this method before doing a search and
0483:             * retrieve if you want to match without worrying about case. For example
0484:             * if you were to call this method with isCaseSensitiveQuery = FALSE
0485:             * then this comparison would match in the search:
0486:             * <p/>
0487:             * vendor_name actual value = "My Name"
0488:             * <p/>
0489:             * query value = "my name"
0490:             * <p/>
0491:             * This would match in a search and retrieve.
0492:             * <p/>
0493:             * author Adam Rossi, PlatinumSolutions
0494:             *
0495:             * @param caseSensitiveQuery boolean
0496:             */
0497:            public void setCaseSensitiveQuery(boolean caseSensitiveQuery) {
0498:
0499:                this .caseSensitiveQuery = caseSensitiveQuery;
0500:            }
0501:
0502:            /**
0503:             * Build an appropriate String for use in the select part of an SQL statement
0504:             * by doing the
0505:             *
0506:             * @param fieldName The name of the field to be handled
0507:             * @return The portion of the select clause with the appropriate function
0508:             *         wrapped around it
0509:             */
0510:            public String selectFieldString(String fieldName)
0511:                    throws DBException {
0512:                DataFieldMetaData oneField = getFieldMetaData(fieldName);
0513:
0514:                try {
0515:                    JDBCConfig myConfig = null;
0516:                    //            String fieldType = oneField.getTypeString();
0517:
0518:                    if (oneField.isDateOnlyType()) {
0519:                        myConfig = ConfigManager
0520:                                .getJdbcRequired(getDataContext());
0521:
0522:                        if (!StringUtil.notNull(
0523:                                myConfig.getDateSelectFunction()).equals("")) {
0524:                            return StringUtil.replace(myConfig
0525:                                    .getDateSelectFunction(), "%s", fieldName);
0526:                        }
0527:                    }
0528:                    if (oneField.isTimeType()) {
0529:                        myConfig = ConfigManager
0530:                                .getJdbcRequired(getDataContext());
0531:
0532:                        if (!StringUtil.notNull(
0533:                                myConfig.getTimeSelectFunction()).equals("")) {
0534:                            return StringUtil.replace(myConfig
0535:                                    .getTimeSelectFunction(), "%s", fieldName);
0536:                        }
0537:                    }
0538:                    if (oneField.isDateTimeType()) {
0539:                        myConfig = ConfigManager
0540:                                .getJdbcRequired(getDataContext());
0541:
0542:                        if (!StringUtil.notNull(
0543:                                myConfig.getDateTimeSelectFunction())
0544:                                .equals("")) {
0545:                            return StringUtil.replace(myConfig
0546:                                    .getDateTimeSelectFunction(), "%s",
0547:                                    fieldName);
0548:                        }
0549:                    }
0550:                } catch (ConfigurationException ce) {
0551:                    throw new DBException(ce);
0552:                }
0553:
0554:                return fieldName;
0555:            } /* selectFieldString(String) */
0556:
0557:            /**
0558:             * Return the value of this field, placing double quotes around it if the
0559:             * field's datatype requires it.
0560:             *
0561:             * @param fieldName   The name of the field to be used
0562:             * @param rangeString the appropriately formatted string
0563:             * @return A string, quoted if necessary, to be used in building an SQL statement
0564:             * @throws DBException If there is no such field or it's value cannot be
0565:             *                     determined
0566:             */
0567:            public String quoteIfNeeded(String fieldName, String rangeString)
0568:                    throws DBException {
0569:                DataFieldMetaData oneField = getFieldMetaData(fieldName);
0570:                if (oneField == null) {
0571:                    throw new DBException("(" + this .myClassName
0572:                            + ") No such field as " + fieldName);
0573:                }
0574:
0575:                boolean noTrim = false;
0576:                if (!oneField.isMasked() && !isGlobalMasked()) {
0577:                    try {
0578:                        noTrim = ConfigManager.getJdbcRequired(
0579:                                this .getMappedDataContext()).isStringNotTrim();
0580:                    } catch (ConfigurationException ce) {
0581:                        throw new DataException(ce);
0582:                    }
0583:                }
0584:
0585:                String fieldValue = getSerialForm(oneField);
0586:
0587:                /* if the field is null, we don't need to worry about quotes */
0588:                if (fieldValue == null) {
0589:                    return null;
0590:                }
0591:
0592:                if (rangeString != null) {
0593:                    fieldValue = fieldValue.substring(rangeString.length());
0594:                }
0595:
0596:                /* if the field is null, we don't need to worry about quotes */
0597:                if (fieldValue == null) {
0598:                    return null;
0599:                }
0600:
0601:                if ((oneField.isBooleanType() || "bit"
0602:                        .equalsIgnoreCase(oneField.getTypeString()))
0603:                        && fieldValue.length() == 0) {
0604:                    return null;
0605:                }
0606:
0607:                if (oneField.isNumericType()) {
0608:                    if (fieldValue.length() == 0) {
0609:                        return null;
0610:                    }
0611:
0612:                    return fieldValue.trim();
0613:                } /* if a numeric type */
0614:
0615:                if (oneField.isQuotedTextType()) {
0616:                    if (rangeString != null) {
0617:                        return fieldValue;
0618:                    }
0619:
0620:                    //
0621:                    //Fix so we don't get escaped double-single quotes accidentally
0622:                    //
0623:                    if (fieldValue.length() == 0) {
0624:                        return "''";
0625:                    }
0626:
0627:                    FastStringBuffer returnValue = FastStringBuffer
0628:                            .getInstance();
0629:                    String returnString = null;
0630:                    try {
0631:                        String value = "";
0632:                        if (noTrim) {
0633:                            value = fieldValue;
0634:                        } else {
0635:                            value = fieldValue.trim();
0636:                        }
0637:                        returnValue.append("\'");
0638:                        //                returnValue.append(this.getConnectionPool().getEscapeHandler().escapeString(fieldValue.trim()));
0639:                        returnValue.append(this .getConnectionPool()
0640:                                .getEscapeHandler().escapeString(value));
0641:                        returnValue.append("\'");
0642:                        returnString = returnValue.toString();
0643:                    } finally {
0644:                        returnValue.release();
0645:                        returnValue = null;
0646:                    }
0647:                    return returnString;
0648:                } /* if a quoted type */
0649:
0650:                if (oneField.isDateType()) {
0651:                    if (rangeString != null) {
0652:                        return fieldValue;
0653:                    }
0654:                    FastStringBuffer returnValue = FastStringBuffer
0655:                            .getInstance();
0656:                    String returnString = null;
0657:                    try {
0658:                        returnValue.append("\'");
0659:                        returnValue.append(fieldValue);
0660:                        returnValue.append("\'");
0661:                        returnString = returnValue.toString();
0662:                    } finally {
0663:                        returnValue.release();
0664:                        returnValue = null;
0665:                    }
0666:                    return returnString;
0667:                }
0668:
0669:                //
0670:                //We don't care about rangestrings in boolean types.... they don't
0671:                //exactly make sense.
0672:                //
0673:                if (oneField.isBooleanType()) {
0674:                    try {
0675:                        boolean nativeBoolean = ConfigManager.getContext(
0676:                                this .getDataContext()).getJdbc().isNativeBool();
0677:
0678:                        if (!nativeBoolean) {
0679:                            FastStringBuffer returnValue = FastStringBuffer
0680:                                    .getInstance();
0681:                            String returnString = null;
0682:                            try {
0683:                                returnValue.append("\'");
0684:                                returnValue.append(fieldValue.trim());
0685:                                returnValue.append("\'");
0686:                                returnString = returnValue.toString();
0687:                            } finally {
0688:                                returnValue.release();
0689:                                returnValue = null;
0690:                            }
0691:                            return returnString;
0692:                        }
0693:                    } catch (ConfigurationException ce) {
0694:                        throw new DBException(ce);
0695:                    }
0696:                }
0697:
0698:                if (noTrim) {
0699:                    return fieldValue;
0700:                } else {
0701:                    return fieldValue.trim();
0702:                }
0703:            } /* quoteIfNeeded(String) */
0704:
0705:            /**
0706:             * Set a specific DB connection for use with this db object. If you do not set
0707:             * a connection, the db object will request it's own connection from the
0708:             * appropriate connection pool & release it again after every operation (e.g.
0709:             * add, update, etc). It is important to use your own explicit connection when
0710:             * dealing with a database transactional environment (e.g. commit(), rollback()).
0711:             *
0712:             * @param newConnection The new DBConnection object to be used by this DB Object
0713:             */
0714:            public synchronized void setConnection(DBConnection newConnection)
0715:                    throws DBException {
0716:                setConnection(newConnection, newConnection.getDataContext());
0717:            } /* setConnection(DBConnection) */
0718:
0719:            /**
0720:             * <p/>
0721:             * Set a specific DB connection for use with this db object. If you do not set
0722:             * a connection, the db object will request it's own connection from the
0723:             * appropriate connection pool & release it again after every operation (e.g.
0724:             * add, update, etc). It is important to use your own explicit connection when
0725:             * dealing with a database transactional environment (e.g. commit(), rollback()).
0726:             * </p>
0727:             * <p>The difference between this and setConnection(DBConnection) is that this
0728:             * is used for using otherDB capabilities within a transaction.  So you use
0729:             * a dbconnection from your other pool, but the setup tables are in a different
0730:             * context</p>
0731:             *
0732:             * @param newConnection      The new DBConnection object to be used by this DB Object
0733:             * @param setupTablesContext the data context that is used for the expresso setup tables.
0734:             * @see #setConnection(DBConnection)
0735:             */
0736:            public synchronized void setConnection(DBConnection newConnection,
0737:                    String setupTablesContext) throws DBException {
0738:                localConnection = newConnection;
0739:                this .setDataContext(setupTablesContext);
0740:            }
0741:
0742:            /**
0743:             * Refactoring to split the execution of a query statement into the query
0744:             * part and the load part.  The DBConnection returned will have the query
0745:             * already executed.
0746:             * <p/>
0747:             * SIDE-EFFECT: custom 'where' clause is set to null.
0748:             *
0749:             * @param retrievedFieldList instantiate an ArrayList and the function will
0750:             *                           fill out the field order that the SQL statement will have it's fields in.
0751:             * @return connection that has already executed the search statement.
0752:             *         <p/>
0753:             *         Modify by Yves Henri AMAIZO <amy_amaizo@compuserve.com>
0754:             * @throws DBException upon database communication error
0755:             * @since $DatabaseSchema  $Date: 2004/11/18 02:03:27 $
0756:             */
0757:            public DBConnection createAndExecuteSearch(
0758:                    java.util.ArrayList retrievedFieldList) throws DBException {
0759:                boolean needComma = false;
0760:
0761:                if (recordSet == null) {
0762:                    recordSet = new ArrayList();
0763:                } else {
0764:                    recordSet.clear();
0765:                }
0766:
0767:                myUpdates = null;
0768:
0769:                DBConnection myConnection = null;
0770:                JDBCObjectMetaData myMetadata = this .getJDBCMetaData();
0771:                FastStringBuffer myStatement = FastStringBuffer.getInstance();
0772:                try {
0773:                    if (localConnection != null) {
0774:                        myConnection = localConnection;
0775:                    } else {
0776:                        myConnection = this .getConnectionPool().getConnection(
0777:                                this .myClassName);
0778:                    }
0779:
0780:                    myStatement.append("SELECT ");
0781:
0782:                    if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_SELECT
0783:                            && (offsetRecord > 0 || maxRecords > 0)) {
0784:
0785:                        // Insert limitation stub after table nomination
0786:                        String limitStub = makeLimitationStub(myConnection);
0787:
0788:                        myStatement.append(" ");
0789:                        myStatement.append(limitStub);
0790:                        myStatement.append(" ");
0791:                    }
0792:
0793:                    if (anyFieldsDistinct) {
0794:                        String oneFieldName = null;
0795:                        myStatement.append(" ");
0796:                        myStatement.append(getConnectionPool()
0797:                                .getDistinctRowsetKeyword());
0798:                        myStatement.append(" ");
0799:
0800:                        for (Iterator i = getDistinctFieldArrayList()
0801:                                .iterator(); i.hasNext();) {
0802:                            oneFieldName = (String) i.next();
0803:                            retrievedFieldList.add(oneFieldName);
0804:
0805:                            if (needComma) {
0806:                                myStatement.append(", ");
0807:                            }
0808:
0809:                            myStatement.append(selectFieldString(oneFieldName));
0810:                            needComma = true;
0811:                        }
0812:                    } else if (anyFieldsToRetrieve) { /* for each distinct field */
0813:                        String oneFieldName = null;
0814:
0815:                        for (Iterator i = getFieldsToRetrieveIterator(); i
0816:                                .hasNext();) {
0817:                            oneFieldName = (String) i.next();
0818:
0819:                            if (needComma) {
0820:                                myStatement.append(", ");
0821:                            }
0822:
0823:                            retrievedFieldList.add(oneFieldName);
0824:                            myStatement.append(selectFieldString(oneFieldName));
0825:                            needComma = true;
0826:                        }
0827:                    } else { /* for each field */
0828:                        for (Iterator i = myMetadata.getAllFieldsMap().values()
0829:                                .iterator(); i.hasNext();) {
0830:                            DBField oneField = (DBField) i.next();
0831:
0832:                            if (!oneField.isVirtual()
0833:                                    && !oneField.isBinaryObjectType()) {
0834:                                if (needComma) {
0835:                                    myStatement.append(", ");
0836:                                }
0837:
0838:                                retrievedFieldList.add(oneField.getName());
0839:                                myStatement.append(selectFieldString(oneField
0840:                                        .getName()));
0841:                                needComma = true;
0842:                            } /* if field is not virtual */
0843:
0844:                        } /* for each field */
0845:
0846:                    } /* else this is a regular (non-distinct) search */
0847:
0848:                    myStatement.append(" FROM ");
0849:                    myStatement.append(myMetadata.getTargetSQLTable(this 
0850:                            .getDataContext()));
0851:                    if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_TABLE
0852:                            && (offsetRecord > 0 || maxRecords > 0)) {
0853:
0854:                        // Insert limitation stub after table nomination
0855:                        String limitStub = makeLimitationStub(myConnection);
0856:                        myStatement.append(" ");
0857:                        myStatement.append(limitStub);
0858:                        myStatement.append(" ");
0859:                    }
0860:
0861:                    String whereClause;
0862:
0863:                    if (customWhereClause != null) {
0864:                        if (appendCustomWhere) {
0865:                            whereClause = buildWhereClause(true)
0866:                                    + customWhereClause;
0867:                            appendCustomWhere = false;
0868:                        } else {
0869:                            whereClause = customWhereClause;
0870:                        }
0871:                        myStatement.append(whereClause);
0872:                        customWhereClause = null;
0873:                    } else {
0874:                        whereClause = buildWhereClause(true);
0875:                        myStatement.append(whereClause);
0876:                    }
0877:                    if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_WHERE
0878:                            && (offsetRecord > 0 || maxRecords > 0)) {
0879:
0880:                        // Insert limitation stub after table nomination
0881:                        String limitStub = makeLimitationStub(myConnection);
0882:
0883:                        if (whereClause.length() > 0) {
0884:                            myStatement.append(" AND");
0885:                        }
0886:
0887:                        myStatement.append(" ");
0888:                        myStatement.append(limitStub);
0889:                        myStatement.append(" ");
0890:                    }
0891:                    /* Add the ORDER BY clause if any sortKeys are specified */
0892:                    if (sortKeys != null && sortKeys.size() > 0) {
0893:                        myStatement.append(" ORDER BY ");
0894:
0895:                        boolean needComma2 = false;
0896:
0897:                        for (Iterator i = sortKeys.iterator(); i.hasNext();) {
0898:                            if (needComma2) {
0899:                                myStatement.append(", ");
0900:                            }
0901:
0902:                            myStatement.append((String) i.next());
0903:                            needComma2 = true;
0904:                        }
0905:                        if (myConnection.getLimitationPosition() == DBConnection.LIMITATION_AFTER_ORDER_BY
0906:                                && (offsetRecord > 0 || maxRecords > 0)) {
0907:                            myStatement.append(" ");
0908:                            myStatement
0909:                                    .append(makeLimitationStub(myConnection));
0910:                        }
0911:                    }
0912:
0913:                    myConnection.execute(myStatement.toString());
0914:                    return myConnection;
0915:                } catch (DBException ex) {
0916:                    if (myConnection != null && localConnection == null) {
0917:                        myConnection.release();
0918:                    }
0919:                    log.error("Error building and executing search statement",
0920:                            ex);
0921:                    throw ex;
0922:                } finally {
0923:                    myStatement.release();
0924:                }
0925:            }
0926:
0927:            /**
0928:             * Fills the given constructed data object with data from the connection
0929:             * given the field order specified in retrievedFieldList.  Similar to
0930:             * loadFromConnection but much faster because the connection fields are
0931:             * retrieved via number instead of name.
0932:             *
0933:             * @param myObj              the Object to have the values filled out. [in/out parameter]
0934:             * @param myConnection       [in] the connection to retrieve the fields from
0935:             * @param retrievedFieldList [in] An array of Strings representing the field
0936:             *                           names to retrieve in the order they exist in the connection.
0937:             * @throws DBException upon error
0938:             */
0939:            public void loadFromConnection(JDBCDataObject myObj,
0940:                    DBConnection myConnection, ArrayList retrievedFieldList)
0941:                    throws DBException {
0942:                int i = 1;
0943:                String oneFieldName = null;
0944:                Object tmpData = null;
0945:
0946:                for (Iterator it = retrievedFieldList.iterator(); it.hasNext();) {
0947:                    oneFieldName = (String) it.next();
0948:                    DataFieldMetaData oneDBField = getFieldMetaData(oneFieldName);
0949:
0950:                    try {
0951:                        //   * @author	  Yves Henri AMAIZO
0952:                        //   Handle correctly date from resultSet data retrieve from Database
0953:                        if (oneDBField.isDateType()) {
0954:                            tmpData = getCustomStringFieldValue(myConnection,
0955:                                    oneDBField.getName());
0956:                        } else {
0957:                            if (!oneDBField.isLongBinaryType()
0958:                                    && !oneDBField.isLongCharacterType()) {
0959:                                if (myConnection.isStringNotTrim()) {
0960:                                    tmpData = myConnection.getStringNoTrim(i);
0961:                                } else {
0962:                                    tmpData = myConnection.getString(i);
0963:                                }
0964:                            } else {
0965:                                if (oneDBField.isLongBinaryType()) {
0966:                                    tmpData = null;
0967:                                    InputStream is = myConnection
0968:                                            .getBinaryStream(i);
0969:                                    if (is != null) {
0970:                                        byte[] bstr = new byte[LONGBINARY_READ_DEFAULT_SIZE];
0971:                                        int j = is.read(bstr);
0972:                                        if (j > 0) {
0973:                                            byte[] content = new byte[j];
0974:                                            System.arraycopy(bstr, 0, content,
0975:                                                    0, j);
0976:                                            tmpData = content;
0977:                                        }
0978:                                    }
0979:                                } else {
0980:                                    tmpData = myConnection.getStringNoTrim(i);
0981:                                }
0982:                            }
0983:
0984:                        }
0985:                    } catch (DBException de) {
0986:                        throw new DBException("Error retrieving field '"
0987:                                + oneFieldName, de);
0988:                    } catch (Exception de) {
0989:                        throw new DBException(
0990:                                "Not DBException Error retrieving field '"
0991:                                        + oneFieldName, de);
0992:                    }
0993:
0994:                    i++;
0995:                    myObj.set(oneFieldName, tmpData);
0996:                } /* for each retrieved field name */
0997:
0998:                myObj.setDataContext(this .getDataContext());
0999:                myObj.setStatus(BaseDataObject.STATUS_CURRENT);
1000:            }
1001:
1002:            /**
1003:             * Creates the limitation syntax optimisation stub
1004:             * to embed inside the SQL command that performs
1005:             * search and retrieve.
1006:             * <p/>
1007:             * <p>This method takes the limitation syntax string
1008:             * and performs a string replacement on the following
1009:             * tokens
1010:             * <p/>
1011:             * <ul>
1012:             * <p/>
1013:             * <li><b>%offset%</b><li><br>
1014:             * the number of rows in the <code>ResultSet</code> to skip
1015:             * before reading the data.
1016:             * <p/>
1017:             * <li><b>%maxrecord%</b><li><br>
1018:             * the maximum number of rows to read from  the <code>ResultSet</code>.
1019:             * Also known as the <i>rowlength</i>.
1020:             * <p/>
1021:             * <li><b>%endrecord%</b><li><br>
1022:             * the last record of in the <code>ResultSet</code> that the
1023:             * search and retrieved should retrieve. The end record number
1024:             * is equal to <code>( %offset% + %maxrecord% - 1 )</code>
1025:             * <p/>
1026:             * </ul>
1027:             * <p/>
1028:             * </p>
1029:             * <p/>
1030:             * <p/>
1031:             * author Peter Pilgrim, Thu Jun 21 10:30:59 BST 2001
1032:             *
1033:             * @param theConnection the db connection to make this stub from
1034:             * @return the limitation syntax stub string
1035:             * @see #searchAndRetrieveList()
1036:             * @see #setOffsetRecord( int )
1037:             * @see #setMaxRecords( int )
1038:             */
1039:            protected String makeLimitationStub(DBConnection theConnection) {
1040:                String limit = theConnection.getLimitationSyntax();
1041:                int offset = this .getOffsetRecord();
1042:                int maxrec = this .getMaxRecords();
1043:                int endrec = offset + maxrec - 1;
1044:                limit = StringUtil.replace(limit, "%offset%", Integer
1045:                        .toString(offset));
1046:                limit = StringUtil.replace(limit, "%maxrecords%", Integer
1047:                        .toString(maxrec));
1048:
1049:                // limit = StringUtil.replace( limit, "%length%",    Integer.toString( maxrec ) );
1050:                limit = StringUtil.replace(limit, "%endrecord%", Integer
1051:                        .toString(endrec));
1052:
1053:                return limit;
1054:            } /* makeLimitationStub(DBConnection) */
1055:
1056:            /**
1057:             * Get a special <code>ArrayList</code> object list of all
1058:             * of the fields in this object that are set to <b>distinct</b>
1059:             *
1060:             * @return An Iterator of all the
1061:             *         <b>distinct</b> fieldNames in this object
1062:             * @throws DBException If the list cannot be retrieved
1063:             *                     <p/>
1064:             *                     author Peter Pilgrim <peter.pilgrim@db.com>
1065:             */
1066:            public ArrayList getDistinctFieldArrayList() throws DBException {
1067:                ArrayList arl = new ArrayList();
1068:
1069:                if (distinctFields == null) {
1070:                    return arl;
1071:                }
1072:                for (Iterator i = this .getMetaData().getFieldListArray()
1073:                        .iterator(); i.hasNext();) {
1074:                    String fieldName = (String) i.next();
1075:
1076:                    if (distinctFields.containsKey(fieldName)) {
1077:                        arl.add(fieldName);
1078:                    }
1079:                }
1080:
1081:                return arl;
1082:            }
1083:
1084:            /**
1085:             * Get a special <code>Iterator</code> object list of all
1086:             * of the fields in this object that are set to <b>retrieve</b>
1087:             * <p>Author Yves henri Amaizo <amy_amaizo@compuserve.com></p>
1088:             *
1089:             * @return An Iterator of all the
1090:             *         <b>retrieve</b> fieldNames in this object
1091:             * @throws DBException If the list cannot be retrieved
1092:             */
1093:            public Iterator getFieldsToRetrieveIterator() throws DBException {
1094:
1095:                //Do a dummy so we don't throw null pointer exceptions
1096:                if (retrieveFields == null) {
1097:                    return new HashMap().keySet().iterator();
1098:                }
1099:
1100:                return retrieveFields.keySet().iterator();
1101:            }
1102:
1103:            /**
1104:             * Build and return a string consisting of an SQL 'where' clause
1105:             * using the current field values as criteria for the search. See
1106:             * setCustomWhereClause for information on specifying a more complex where clause.
1107:             *
1108:             * @param useAllFields True if all fields are to be used,
1109:             *                     false for only key fields
1110:             * @return The where clause to use in a query.
1111:             */
1112:            public String buildWhereClause(boolean useAllFields)
1113:                    throws DBException {
1114:
1115:                return sJdbcUtil.buildWhereClause(this , useAllFields);
1116:            } /* buildWhereClause(boolean) */
1117:
1118:            /**
1119:             * Build and return a FastStringBuffer ring consisting of an SQL 'where' clause
1120:             * using the current field values as criteria for the search. See
1121:             * setCustomWhereClause for information on specifying a more complex where clause.
1122:             *
1123:             * @param useAllFields    True if all fields are to be used,
1124:             *                        false for only key fields
1125:             * @param allocatedBuffer - An already allocated FastStringBuffer to fill out.
1126:             *                        This allows for compatability with, for example, object pools.
1127:             * @return A FastStringBuffer containing the "where" clause for the SQL statement
1128:             */
1129:            protected FastStringBuffer buildWhereClauseBuffer(
1130:                    boolean useAllFields, FastStringBuffer allocatedBuffer)
1131:                    throws DBException {
1132:
1133:                try {
1134:                    return sJdbcUtil.buildWhereClauseBuffer(this , useAllFields,
1135:                            allocatedBuffer);
1136:                } catch (DataException ex) {
1137:                    throw new DBException(ex.getMessage());
1138:                }
1139:            }
1140:
1141:            /**
1142:             * Get the JDBC Util functions
1143:             *
1144:             * @return JDBCUtil class.
1145:             */
1146:            protected JDBCUtil getJDBCUtil() {
1147:                return sJdbcUtil;
1148:            }
1149:
1150:            /**
1151:             * Use this function to acquire the Executor interface that is associated
1152:             * with this data object
1153:             *
1154:             * @return DataExecutorInterface or null if no Executor has been associated
1155:             *         with this object
1156:             */
1157:            public DataExecutorInterface getExecutor() {
1158:                return sDataExecutor;
1159:            }
1160:
1161:            /**
1162:             * Use this function to acquire the DataQueryInterface that is associated
1163:             * with this data object
1164:             *
1165:             * @return DataQueryInterface or null if no QueryInterface has been
1166:             *         associated with this object
1167:             */
1168:            public DataQueryInterface getQueryInterface() {
1169:                return sDataQueryObject;
1170:            }
1171:
1172:            /**
1173:             * <p>This convenience method retrieve through the resultSet.MetaData
1174:             * the date value of field define as date or time <code>DBObject</code>
1175:             *
1176:             * @param connection   The DBConnection
1177:             * @param oneFieldName the field name to get the custom field value from
1178:             * @return Custom String value retrieve from resultSet according to metaData.
1179:             * @throws DBException author Yves Henri AMAIZO <amy_amaizo@compuserve.com>
1180:             */
1181:            public String getCustomStringFieldValue(DBConnection connection,
1182:                    String oneFieldName) throws DBException {
1183:                ConfigJdbc myConfig = null;
1184:                String oneFieldValue = null;
1185:                DataFieldMetaData fieldMetadata = this 
1186:                        .getFieldMetaData(oneFieldName);
1187:                try {
1188:                    myConfig = ConfigManager.getJdbcRequired(getDataContext());
1189:                } catch (ConfigurationException ce) {
1190:                    throw new DBException(ce);
1191:                }
1192:                if (fieldMetadata.isDateTimeType()) {
1193:                    if (StringUtil.notNull(myConfig.getDateTimeSelectFormat())
1194:                            .length() > 0) {
1195:                        oneFieldValue = DateTime.getDateTimeForDB(connection
1196:                                .getTimestamp(oneFieldName), dbKey);
1197:                    } else {
1198:                        oneFieldValue = connection.getString(oneFieldName);
1199:                    }
1200:                }
1201:                if (fieldMetadata.isTimeType()) {
1202:                    if (!StringUtil.notNull(myConfig.getTimeSelectFormat())
1203:                            .equals("")) {
1204:                        oneFieldValue = DateTime.getTimeForDB(connection
1205:                                .getTime(oneFieldName), dbKey);
1206:                    } else {
1207:                        oneFieldValue = connection.getString(oneFieldName);
1208:                    }
1209:                }
1210:                if (fieldMetadata.isDateOnlyType()) {
1211:                    if (!StringUtil.notNull(myConfig.getDateSelectFormat())
1212:                            .equals("")) {
1213:                        oneFieldValue = DateTime.getDateForDB(connection
1214:                                .getDate(oneFieldName), dbKey);
1215:                    } else {
1216:                        oneFieldValue = connection.getString(oneFieldName);
1217:                    }
1218:                }
1219:                return oneFieldValue;
1220:            } /* getCustomStringFieldValue() */
1221:
1222:            /**
1223:             * <p>Return local DBConnection value
1224:             * <p/>
1225:             * author Yves Henri AMAIZO &lt;amy_amaizo@compuserve.com&gt;
1226:             *
1227:             * @return DBConnection
1228:             */
1229:            public DBConnection getLocalConnection() {
1230:                return localConnection;
1231:            }
1232:
1233:            /**
1234:             * Refactoring to split the execution of a query statement into the query
1235:             * part and the load part.  The DBConnection returned will have the query
1236:             * already executed, it is ready to
1237:             *
1238:             * @param retrievedFieldList instantiate an ArrayList and the function will
1239:             *                           fill out the field order that the SQL statement will have it's fields in.
1240:             * @return connection that has already executed the search statement.
1241:             * @throws DBException upon database communication error
1242:             */
1243:            public DBConnection createAndRunStoreProcedure(
1244:                    java.util.ArrayList retrievedFieldList) throws DBException {
1245:                if (recordSet == null) {
1246:                    recordSet = new ArrayList();
1247:                } else {
1248:                    recordSet.clear();
1249:                }
1250:
1251:                myUpdates = null;
1252:
1253:                DBConnection myConnection = null;
1254:                FastStringBuffer myStatement = FastStringBuffer.getInstance();
1255:                try {
1256:                    if (localConnection != null) {
1257:                        myConnection = localConnection;
1258:                    } else {
1259:                        myConnection = this .getConnectionPool().getConnection(
1260:                                this .myClassName);
1261:                    }
1262:
1263:                    int nbParams = this .getDef().getFieldListArray().size();
1264:                    if (this .getDef().isReturningValue()) {
1265:                        myStatement.append("{? = call ");
1266:                        nbParams--;
1267:                    } else {
1268:                        myStatement.append("{call ");
1269:                    }
1270:                    myStatement.append(this .getJDBCMetaData().getTargetTable());
1271:
1272:                    if (nbParams > 0) {
1273:                        myStatement.append("(?");
1274:                        for (int i = 1; i < nbParams; i++) {
1275:                            myStatement.append(", ?");
1276:                        }
1277:                        myStatement.append(")");
1278:                    }
1279:                    myStatement.append("}");
1280:
1281:                    CallableStatement theStroreProcedureStatement = myConnection
1282:                            .createCallableStatement(myStatement.toString());
1283:                    sJdbcUtil.buildStoreProcedureCallableStatement(this ,
1284:                            theStroreProcedureStatement);
1285:                    myConnection.executeProcedure();
1286:
1287:                    return myConnection;
1288:                } catch (DBException ex) {
1289:                    if (myConnection != null && localConnection == null) {
1290:                        myConnection.release();
1291:                    }
1292:                    log
1293:                            .error(
1294:                                    "Error building and running store procedure statement",
1295:                                    ex);
1296:                    throw ex;
1297:                } finally {
1298:                    myStatement.release();
1299:                }
1300:            } /* createAndRunStoreProcedure(java.util.ArrayList) */
1301:
1302:            /**
1303:             * Add a new field to the list of fields that are part of this
1304:             * object's list of input parameters. Called after all of the "addField" calls in the setupFields()
1305:             * method to specify which fields make up the primary key of this object.
1306:             *
1307:             * @param inFieldName The name of the field to add as part of the key
1308:             * @throws DBException if the field name is not valid or the field
1309:             *                     allows nulls
1310:             */
1311:            protected synchronized void addInParam(String inFieldName)
1312:                    throws DBException {
1313:                getDef().addInParam(inFieldName);
1314:            } /* addInParam(String) */
1315:
1316:            /**
1317:             * Add a new field to the list of fields that are part of this
1318:             * object's list of output parameter. Called after all of the "addField" calls in the setupFields()
1319:             * method to specify which fields make up the primary key of this object.
1320:             *
1321:             * @param outFieldName The name of the field to add as part of the key
1322:             * @throws DBException if the field name is not valid or the field
1323:             *                     allows nulls
1324:             */
1325:            protected synchronized void addOutParam(String outFieldName)
1326:                    throws DBException {
1327:                getDef().addOutParam(outFieldName);
1328:            } /* addOutParam(String) */
1329:
1330:            /**
1331:             * Set the target store procedure for this DBObject.
1332:             *
1333:             * @param theStoreProcedure Table for this object
1334:             * @throws DBException upon execution error.
1335:             */
1336:            public synchronized void setTargetStoreProcedure(
1337:                    String theStoreProcedure) throws DBException {
1338:                getDef().setTargetStoreProcedure(theStoreProcedure);
1339:            } /* setTargetStoreProcedure(String) */
1340:
1341:            /**
1342:             * Run a particular store procedure in the database into this object's fields
1343:             *
1344:             * @throws DBException If the record could not be retrieved.
1345:             */
1346:            public void runStoredProcedure() throws DBException {
1347:
1348:                this .getExecutor().runStoreProcedure(this );
1349:
1350:                if (getDef().isLoggingEnabled()) {
1351:                    myUpdates = null;
1352:                }
1353:
1354:                this .setStatus(BaseDataObject.STATUS_CURRENT);
1355:            }
1356:
1357:            /**
1358:             * Run a particular store procedure in the database into this object's fields
1359:             *
1360:             * @return Vector A vector of new database objects containing the results
1361:             *         of the search
1362:             * @throws DBException If the record could not be retrieved.
1363:             * @todo one line below was adapted during move from dbobject.java, and is probably wrong.; after correction, make method public  10/04 Larry
1364:             */
1365:            protected synchronized ArrayList runStoredProcedureAndRetrieveList()
1366:                    throws DBException {
1367:
1368:                ArrayList retrievedFieldList = new ArrayList();
1369:
1370:                DBConnection myConnection = null;
1371:                try {
1372:                    myConnection = this 
1373:                            .createAndRunStoreProcedure(retrievedFieldList);
1374:
1375:                    int recordCount = 0;
1376:                    int retrieveCount = 0;
1377:
1378:                    while (myConnection.next()) {
1379:                        recordCount++;
1380:                        retrieveCount++;
1381:
1382:                        //If there's limitation syntax on, then the first record will be the
1383:                        //maximum record.
1384:                        if (retrieveCount < offsetRecord
1385:                                && offsetRecord > 0
1386:                                && myConnection.getLimitationPosition() == DBConnection.LIMITATION_DISABLED) {
1387:                            continue;
1388:                        } else if (retrieveCount == offsetRecord
1389:                                && offsetRecord > 0
1390:                                && myConnection.getLimitationPosition() == DBConnection.LIMITATION_DISABLED) {
1391:                            recordCount = 0; //Reset count for counting for max records.
1392:                            continue; //Skip this record... next one, we will start loading.
1393:                        }
1394:                        if ((recordCount > maxRecords) && (maxRecords > 0)) {
1395:                            this .setAttribute("More Records", "Y");
1396:                            break;
1397:                        }
1398:
1399:                        //Only allocate if we're gonna load this record
1400:                        JDBCDataObject myObj = (JDBCDataObject) this .getClass()
1401:                                .newInstance(); // @todo Henri, change as necessary; larry 10/04
1402:                        this .loadFromConnection(myObj, myConnection,
1403:                                retrievedFieldList);
1404:                        recordSet.add(myObj);
1405:                    }
1406:                } catch (DBException de) {
1407:                    log
1408:                            .error(
1409:                                    "Error performing runStoreProcedureAndRetrieveList",
1410:                                    de);
1411:                    throw new DBException(de);
1412:                } catch (Throwable t) {
1413:                    log
1414:                            .error(
1415:                                    "Error performing runStoreProcedureAndRetrieveList",
1416:                                    t);
1417:                    throw new DBException(
1418:                            "Error performing runStoreProcedureAndRetrieveList",
1419:                            t);
1420:                } finally {
1421:                    if (localConnection == null) {
1422:                        if (myConnection != null) {
1423:                            this .getConnectionPool().release(myConnection);
1424:                        }
1425:                    }
1426:                }
1427:
1428:                return recordSet;
1429:            } /* runStoreProcedureAndRetrieveList() */
1430:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.