Source Code Cross Referenced for Library.java in  » Database-DBMS » hsql » org » hsqldb » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /* Copyright (c) 1995-2000, The Hypersonic SQL Group.
0002:         * All rights reserved.
0003:         *
0004:         * Redistribution and use in source and binary forms, with or without
0005:         * modification, are permitted provided that the following conditions are met:
0006:         *
0007:         * Redistributions of source code must retain the above copyright notice, this
0008:         * list of conditions and the following disclaimer.
0009:         *
0010:         * Redistributions in binary form must reproduce the above copyright notice,
0011:         * this list of conditions and the following disclaimer in the documentation
0012:         * and/or other materials provided with the distribution.
0013:         *
0014:         * Neither the name of the Hypersonic SQL Group nor the names of its
0015:         * contributors may be used to endorse or promote products derived from this
0016:         * software without specific prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP,
0022:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0025:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0026:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0028:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029:         *
0030:         * This software consists of voluntary contributions made by many individuals 
0031:         * on behalf of the Hypersonic SQL Group.
0032:         *
0033:         *
0034:         * For work added by the HSQL Development Group:
0035:         *
0036:         * Copyright (c) 2001-2005, The HSQL Development Group
0037:         * All rights reserved.
0038:         *
0039:         * Redistribution and use in source and binary forms, with or without
0040:         * modification, are permitted provided that the following conditions are met:
0041:         *
0042:         * Redistributions of source code must retain the above copyright notice, this
0043:         * list of conditions and the following disclaimer.
0044:         *
0045:         * Redistributions in binary form must reproduce the above copyright notice,
0046:         * this list of conditions and the following disclaimer in the documentation
0047:         * and/or other materials provided with the distribution.
0048:         *
0049:         * Neither the name of the HSQL Development Group nor the names of its
0050:         * contributors may be used to endorse or promote products derived from this
0051:         * software without specific prior written permission.
0052:         *
0053:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0054:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0055:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0056:         * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
0057:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0058:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0059:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0060:         * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0061:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0062:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0063:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0064:         */
0065:
0066:        package org.hsqldb;
0067:
0068:        import java.sql.Connection;
0069:        import java.sql.Date;
0070:        import java.sql.Time;
0071:        import java.sql.Timestamp;
0072:        import java.text.FieldPosition;
0073:        import java.text.SimpleDateFormat;
0074:        import java.util.Calendar;
0075:        import java.util.Locale;
0076:        import java.util.Random;
0077:
0078:        import org.hsqldb.lib.HashMap;
0079:        import org.hsqldb.lib.IntValueHashMap;
0080:        import org.hsqldb.persist.HsqlDatabaseProperties;
0081:        import org.hsqldb.store.ValuePool;
0082:
0083:        // fredt@users 20020210 - patch 513005 by sqlbob@users (RMP) - ABS function
0084:        // fredt@users 20020305 - patch 1.7.0 - change to 2D string arrays
0085:        // sqlbob@users 20020420- patch 1.7.0 - added HEXTORAW and RAWTOHEX.
0086:        // boucherb@user 20020918 - doc 1.7.2 - added JavaDoc  and code comments
0087:        // fredt@user 20021021 - doc 1.7.2 - modified JavaDoc
0088:        // boucherb@users 20030201 - patch 1.7.2 - direct calls for org.hsqldb.Library
0089:        // fredt@users - patch 1.8.0 - new functions added
0090:
0091:        /**
0092:         * fredt - todo - since the introduction of SQL built-in functions and
0093:         * evaluation of several session-dependent methods outside this class,
0094:         * several methods here are dummies. These methods are still reported in
0095:         * system tables incorrectly as corresponding to the SQL function names.
0096:         */
0097:
0098:        /**
0099:         * Provides the HSQLDB implementation of standard Open Group SQL CLI
0100:         * <em>Extended Scalar Functions</em> and other public HSQLDB SQL functions.<p>
0101:         *
0102:         * All methods here that have a Connection parameter are dummies and should
0103:         * not be called from user supplied Java procedure or trigger code. Use real
0104:         * SQL functions should be called instead in these instances.
0105:         *
0106:         * Extensively rewritten and extended in successive versions of HSQLDB.
0107:         *
0108:         * @author Thomas Mueller (Hypersonic SQL Group)
0109:         * @version 1.8.0
0110:         * @since Hypersonic SQL
0111:         */
0112:        public class Library {
0113:
0114:            static final SimpleDateFormat tocharFormat = new SimpleDateFormat();
0115:            static final SimpleDateFormat daynameFormat = new SimpleDateFormat(
0116:                    "EEEE", Locale.ENGLISH);
0117:            static final SimpleDateFormat monthnameFormat = new SimpleDateFormat(
0118:                    "MMMM", Locale.ENGLISH);
0119:            static final StringBuffer daynameBuffer = new StringBuffer();
0120:            static final StringBuffer monthnameBuffer = new StringBuffer();
0121:            static final FieldPosition monthPosition = new FieldPosition(
0122:                    SimpleDateFormat.MONTH_FIELD);
0123:            static final FieldPosition dayPosition = new FieldPosition(
0124:                    SimpleDateFormat.DAY_OF_WEEK_FIELD);
0125:            public static final String[][] sNumeric = {
0126:                    { "ABS", "org.hsqldb.Library.abs" },
0127:                    { "ACOS", "java.lang.Math.acos" },
0128:                    { "ASIN", "java.lang.Math.asin" },
0129:                    { "ATAN", "java.lang.Math.atan" },
0130:                    { "ATAN2", "java.lang.Math.atan2" },
0131:                    { "CEILING", "java.lang.Math.ceil" },
0132:                    { "COS", "java.lang.Math.cos" },
0133:                    { "COT", "org.hsqldb.Library.cot" },
0134:                    { "DEGREES", "java.lang.Math.toDegrees" },
0135:                    { "EXP", "java.lang.Math.exp" },
0136:                    { "FLOOR", "java.lang.Math.floor" },
0137:                    { "LOG", "java.lang.Math.log" },
0138:                    { "LOG10", "org.hsqldb.Library.log10" },
0139:                    { "MOD", "org.hsqldb.Library.mod" },
0140:                    { "PI", "org.hsqldb.Library.pi" },
0141:                    { "POWER", "java.lang.Math.pow" },
0142:                    { "RADIANS", "java.lang.Math.toRadians" },
0143:                    { "RAND", "java.lang.Math.random" },
0144:                    { "ROUND", "org.hsqldb.Library.round" },
0145:                    { "SIGN", "org.hsqldb.Library.sign" },
0146:                    { "SIN", "java.lang.Math.sin" },
0147:                    { "SQRT", "java.lang.Math.sqrt" },
0148:                    { "TAN", "java.lang.Math.tan" },
0149:                    { "TRUNCATE", "org.hsqldb.Library.truncate" },
0150:                    { "BITAND", "org.hsqldb.Library.bitand" },
0151:                    { "BITOR", "org.hsqldb.Library.bitor" },
0152:                    { "BITXOR", "org.hsqldb.Library.bitxor" },
0153:                    { "ROUNDMAGIC", "org.hsqldb.Library.roundMagic" } };
0154:
0155:            // fredt@users 20010701 - patch 418023 by deforest@users
0156:            // the definition for SUBSTR was added
0157:            public static final String[][] sString = {
0158:                    { "ASCII", "org.hsqldb.Library.ascii" },
0159:                    { "BIT_LENGTH", "org.hsqldb.Library.bitLength" },
0160:                    { "CHAR", "org.hsqldb.Library.character" },
0161:                    { "CHAR_LENGTH", "org.hsqldb.Library.length" },
0162:                    { "CHARACTER_LENGTH", "org.hsqldb.Library.length" },
0163:                    { "CONCAT", "org.hsqldb.Library.concat" },
0164:                    { "DIFFERENCE", "org.hsqldb.Library.difference" },
0165:                    { "HEXTORAW", "org.hsqldb.Library.hexToRaw" },
0166:                    { "INSERT", "org.hsqldb.Library.insert" },
0167:                    { "LCASE", "org.hsqldb.Library.lcase" },
0168:                    { "LEFT", "org.hsqldb.Library.left" },
0169:                    { "LENGTH", "org.hsqldb.Library.length" },
0170:                    { "LOCATE", "org.hsqldb.Library.locate" },
0171:                    { "LTRIM", "org.hsqldb.Library.ltrim" },
0172:                    { "OCTET_LENGTH", "org.hsqldb.Library.octetLength" },
0173:                    { "RAWTOHEX", "org.hsqldb.Library.rawToHex" },
0174:                    { "REPEAT", "org.hsqldb.Library.repeat" },
0175:                    { "REPLACE", "org.hsqldb.Library.replace" },
0176:                    { "RIGHT", "org.hsqldb.Library.right" },
0177:                    { "RTRIM", "org.hsqldb.Library.rtrim" },
0178:                    { "SOUNDEX", "org.hsqldb.Library.soundex" },
0179:                    { "SPACE", "org.hsqldb.Library.space" },
0180:                    { "SUBSTR", "org.hsqldb.Library.substring" },
0181:                    { "SUBSTRING", "org.hsqldb.Library.substring" },
0182:                    { "UCASE", "org.hsqldb.Library.ucase" },
0183:                    { "LOWER", "org.hsqldb.Library.lcase" },
0184:                    { "UPPER", "org.hsqldb.Library.ucase" } };
0185:            public static final String[][] sTimeDate = {
0186:                    { "CURDATE", "org.hsqldb.Library.curdate" },
0187:                    { "CURTIME", "org.hsqldb.Library.curtime" },
0188:                    { "DATEDIFF", "org.hsqldb.Library.datediff" },
0189:                    { "DAYNAME", "org.hsqldb.Library.dayname" },
0190:                    { "DAY", "org.hsqldb.Library.dayofmonth" },
0191:                    { "DAYOFMONTH", "org.hsqldb.Library.dayofmonth" },
0192:                    { "DAYOFWEEK", "org.hsqldb.Library.dayofweek" },
0193:                    { "DAYOFYEAR", "org.hsqldb.Library.dayofyear" },
0194:                    { "HOUR", "org.hsqldb.Library.hour" },
0195:                    { "MINUTE", "org.hsqldb.Library.minute" },
0196:                    { "MONTH", "org.hsqldb.Library.month" },
0197:                    { "MONTHNAME", "org.hsqldb.Library.monthname" },
0198:                    { "NOW", "org.hsqldb.Library.now" },
0199:                    { "QUARTER", "org.hsqldb.Library.quarter" },
0200:                    { "SECOND", "org.hsqldb.Library.second" },
0201:                    { "WEEK", "org.hsqldb.Library.week" },
0202:                    { "YEAR", "org.hsqldb.Library.year" },
0203:                    { "TO_CHAR", "org.hsqldb.Library.to_char" } };
0204:            public static final String[][] sSystem = {
0205:                    { "DATABASE", "org.hsqldb.Library.database" },
0206:                    { "USER", "org.hsqldb.Library.user" },
0207:                    { "IDENTITY", "org.hsqldb.Library.identity" } };
0208:
0209:            private Library() {
0210:            }
0211:
0212:            static HashMap getAliasMap() {
0213:
0214:                HashMap h = new HashMap(83, 1);
0215:
0216:                register(h, sNumeric);
0217:                register(h, sString);
0218:                register(h, sTimeDate);
0219:                register(h, sSystem);
0220:
0221:                return h;
0222:            }
0223:
0224:            private static void register(HashMap h, String[][] s) {
0225:
0226:                for (int i = 0; i < s.length; i++) {
0227:                    h.put(s[i][0], s[i][1]);
0228:                }
0229:            }
0230:
0231:            private static final Random rRandom = new Random();
0232:
0233:            // NUMERIC FUNCTIONS
0234:            // fredt@users 20020220 - patch 489184 by xclayl@users - thread safety
0235:
0236:            /**
0237:             * Returns the next pseudorandom, uniformly distributed <code>double</code> value
0238:             * between 0.0 and 1.0 from a single, system-wide random number generator's
0239:             * sequence, optionally re-seeding (and thus resetting) the generator sequence.
0240:             *
0241:             * If the seed value is <code>null</code>, then the underlying random number
0242:             * generator retrieves the next value in its current sequence, else the seed
0243:             * alters the state of the generator object so as to be in exactly the same state
0244:             * as if it had just been created with the seed value.
0245:             * @param seed an optional parameter with which to reseed the underlying
0246:             * pseudorandom number generator
0247:             * @return the next pseudorandom, uniformly distributed <code>double</code> value between
0248:             *      0.0 and 1.0
0249:             */
0250:            public static double rand(Integer seed) {
0251:
0252:                // boucherb@users 20020918
0253:                // CHECKME: perhaps rRandom should be a member of Session,
0254:                // since otherwise connections are *not* guranteed to get the
0255:                // same pseudorandom sequence, given the same set of calls to this
0256:                // SQL function.  This makes comparitive analysis difficult.
0257:                // In fact, rRandom will be shared across multiple in-process
0258:                // database instances, so it is not even guaranteed that the
0259:                // sole connection to one instance will get the same sequence given
0260:                // the same set of calls to this SQL function.
0261:                synchronized (rRandom) {
0262:                    if (seed != null) {
0263:                        rRandom.setSeed(seed.intValue());
0264:                    }
0265:
0266:                    return rRandom.nextDouble();
0267:                }
0268:            }
0269:
0270:            /**
0271:             * Returns the absolute value of the given <code>double</code> value.
0272:             * @param d the number for which to determine the absolute value
0273:             * @return the absolute value of <code>d</code>, as a <code>double</code>
0274:             */
0275:            public static double abs(double d) {
0276:                return Math.abs(d);
0277:            }
0278:
0279:            // this magic number works for 100000000000000; but not for 0.1 and 0.01
0280:            private static final double LOG10_FACTOR = 0.43429448190325183;
0281:
0282:            /**
0283:             * Returns the base 10 logarithm of the given <code>double</code> value.
0284:             * @param x the value for which to calculate the base 10 logarithm
0285:             * @return the base 10 logarithm of <code>x</code>, as a <code>double</code>
0286:             */
0287:            public static double log10(double x) {
0288:                return roundMagic(Math.log(x) * LOG10_FACTOR);
0289:            }
0290:
0291:            /**
0292:             * Retrieves a <em>magically</em> rounded </code>double</code> value produced
0293:             * from the given <code>double</code> value.  This method provides special
0294:             * handling for numbers close to zero and performs rounding only for
0295:             * numbers within a specific range, returning  precisely the given value
0296:             * if it does not lie in this range. <p>
0297:             *
0298:             * Special handling includes: <p>
0299:             *
0300:             * <UL>
0301:             * <LI> input in the interval -0.0000000000001..0.0000000000001 returns 0.0
0302:             * <LI> input outside the interval -1000000000000..1000000000000 returns
0303:             *      input unchanged
0304:             * <LI> input is converted to String form
0305:             * <LI> input with a <code>String</code> form length greater than 16 returns
0306:             *      input unchaged
0307:             * <LI> <code>String</code> form with last four characters of '...000x' where
0308:             *      x != '.' is converted to '...0000'
0309:             * <LI> <code>String</code> form with last four characters of '...9999' is
0310:             *      converted to '...999999'
0311:             * <LI> the <code>java.lang.Double.doubleValue</code> of the <code>String</code>
0312:             *      form is returned
0313:             * </UL>
0314:             * @param d the double value for which to retrieve the <em>magically</em>
0315:             *      rounded value
0316:             * @return the <em>magically</em> rounded value produced
0317:             */
0318:            public static double roundMagic(double d) {
0319:
0320:                // this function rounds numbers in a good way but slow:
0321:                // - special handling for numbers around 0
0322:                // - only numbers <= +/-1000000000000
0323:                // - convert to a string
0324:                // - check the last 4 characters:
0325:                // '000x' becomes '0000'
0326:                // '999x' becomes '999999' (this is rounded automatically)
0327:                if ((d < 0.0000000000001) && (d > -0.0000000000001)) {
0328:                    return 0.0;
0329:                }
0330:
0331:                if ((d > 1000000000000.) || (d < -1000000000000.)) {
0332:                    return d;
0333:                }
0334:
0335:                StringBuffer s = new StringBuffer();
0336:
0337:                s.append(d);
0338:
0339:                int len = s.length();
0340:
0341:                if (len < 16) {
0342:                    return d;
0343:                }
0344:
0345:                char cx = s.charAt(len - 1);
0346:                char c1 = s.charAt(len - 2);
0347:                char c2 = s.charAt(len - 3);
0348:                char c3 = s.charAt(len - 4);
0349:
0350:                if ((c1 == '0') && (c2 == '0') && (c3 == '0') && (cx != '.')) {
0351:                    s.setCharAt(len - 1, '0');
0352:                } else if ((c1 == '9') && (c2 == '9') && (c3 == '9')
0353:                        && (cx != '.')) {
0354:                    s.setCharAt(len - 1, '9');
0355:                    s.append('9');
0356:                    s.append('9');
0357:                }
0358:
0359:                return Double.valueOf(s.toString()).doubleValue();
0360:            }
0361:
0362:            /**
0363:             * Returns the cotangent of the given <code>double</code> value
0364:             *  expressed in radians.
0365:             * @param d the angle, expressed in radians
0366:             * @return the cotangent
0367:             */
0368:            public static double cot(double d) {
0369:                return 1. / Math.tan(d);
0370:            }
0371:
0372:            /**
0373:             * Returns the remainder (modulus) of the first given integer divided
0374:             * by the second. <p>
0375:             *
0376:             * @param i1 the numerator
0377:             * @param i2 the divisor
0378:             * @return <code>i1</code> % <code>i2</code>, as an <code>int</code>
0379:             */
0380:            public static int mod(int i1, int i2) {
0381:                return i1 % i2;
0382:            }
0383:
0384:            /**
0385:             * Returns the constant value, pi.
0386:             * @return pi as a <code>double</code> value
0387:             */
0388:            public static double pi() {
0389:                return Math.PI;
0390:            }
0391:
0392:            /**
0393:             * Returns the given <code>double</code> value, rounded to the given
0394:             * <code>int</code> places right of the decimal point. If
0395:             * the supplied rounding place value is negative, rounding is performed
0396:             * to the left of the decimal point, using its magnitude (absolute value).
0397:             * @param d the value to be rounded
0398:             * @param p the rounding place value
0399:             * @return <code>d</code> rounded
0400:             */
0401:            public static double round(double d, int p) {
0402:
0403:                double f = Math.pow(10., p);
0404:
0405:                return Math.round(d * f) / f;
0406:            }
0407:
0408:            /**
0409:             * Returns an indicator of the sign of the given <code>double</code>
0410:             * value. If the value is less than zero, -1 is returned. If the value
0411:             * equals zero, 0 is returned. If the value is greater than zero, 1 is
0412:             * returned.
0413:             * @param d the value
0414:             * @return the sign of <code>d</code>
0415:             */
0416:            public static int sign(double d) {
0417:
0418:                return (d < 0) ? -1 : ((d > 0) ? 1 : 0);
0419:            }
0420:
0421:            /**
0422:             * Returns the given <code>double</code> value, truncated to
0423:             * the given <code>int</code> places right of the decimal point.
0424:             * If the given place value is negative, the given <code>double</code>
0425:             * value is truncated to the left of the decimal point, using the
0426:             * magnitude (aboslute value) of the place value.
0427:             * @param d the value to truncate
0428:             * @param p the places left or right of the decimal point at which to
0429:             *          truncate
0430:             * @return <code>d</code>, truncated
0431:             */
0432:            public static double truncate(double d, int p) {
0433:
0434:                double f = Math.pow(10., p);
0435:                double g = d * f;
0436:
0437:                return ((d < 0) ? Math.ceil(g) : Math.floor(g)) / f;
0438:            }
0439:
0440:            /**
0441:             * Returns the bit-wise logical <em>and</em> of the given
0442:             * integer values.
0443:             * @param i the first value
0444:             * @param j the second value
0445:             * @return the bit-wise logical <em>and</em> of
0446:             *      <code>i</code> and <code>j</code>
0447:             */
0448:            public static int bitand(int i, int j) {
0449:                return i & j;
0450:            }
0451:
0452:            /**
0453:             * Returns the bit-wise logical <em>or</em> of the given
0454:             * integer values.
0455:             *
0456:             * @param i the first value
0457:             * @param j the second value
0458:             * @return the bit-wise logical <em>or</em> of
0459:             *      <code>i</code> and <code>j</code>
0460:             */
0461:            public static int bitor(int i, int j) {
0462:                return i | j;
0463:            }
0464:
0465:            /**
0466:             * Returns the bit-wise logical <em>xor</em> of the given
0467:             * integer values.
0468:             *
0469:             * @param i the first value
0470:             * @param j the second value
0471:             * @return the bit-wise logical <em>xor</em> of
0472:             *      <code>i</code> and <code>j</code>
0473:             *
0474:             * @since 1.8.0
0475:             */
0476:            public static int bitxor(int i, int j) {
0477:                return i ^ j;
0478:            }
0479:
0480:            // STRING FUNCTIONS
0481:
0482:            /**
0483:             * Returns the Unicode code value of the leftmost character of
0484:             * <code>s</code> as an <code>int</code>.  This is the same as the
0485:             * ASCII value if the string contains only ASCII characters.
0486:             * @param s the <code>String</code> to evaluate
0487:             * @return the integer Unicode value of the
0488:             *    leftmost character
0489:             */
0490:            public static Integer ascii(String s) {
0491:
0492:                if ((s == null) || (s.length() == 0)) {
0493:                    return null;
0494:                }
0495:
0496:                return ValuePool.getInt(s.charAt(0));
0497:            }
0498:
0499:            /**
0500:             * Returns the character string corresponding to the given ASCII
0501:             * (or Unicode) value.
0502:             *
0503:             * <b>Note:</b> <p>
0504:             *
0505:             * In some SQL CLI
0506:             * implementations, a <code>null</code> is returned if the range is outside 0..255.
0507:             * In HSQLDB, the corresponding Unicode character is returned
0508:             * unchecked.
0509:             * @param code the character code for which to return a String
0510:             *      representation
0511:             * @return the String representation of the character
0512:             */
0513:            public static String character(int code) {
0514:                return String.valueOf((char) code);
0515:            }
0516:
0517:            /**
0518:             * Returns a <code>String</code> object that is the result of an
0519:             * concatenation of the given <code>String</code> objects. <p>
0520:             *
0521:             * <b>When only one string is NULL, the result is different from that
0522:             * returned by an (string1 || string2) expression:
0523:             *
0524:             * <UL>
0525:             * <LI> if both <code>String</code> objects are <code>null</code>, return
0526:             *      <code>null</code>
0527:             * <LI> if only one string is <code>null</code>, return the other
0528:             * <LI> if both <code>String</code> objects are non-null, return as a
0529:             *      <code>String</code> object the character sequence obtained by listing,
0530:             *      in left to right order, the characters of the first string followed by
0531:             *      the characters of the second
0532:             * </UL>
0533:             * @param s1 the first <code>String</code>
0534:             * @param s2 the second <code>String</code>
0535:             * @return <code>s1</code> concatentated with <code>s2</code>
0536:             */
0537:            public static String concat(String s1, String s2) {
0538:
0539:                if (s1 == null) {
0540:                    if (s2 == null) {
0541:                        return null;
0542:                    }
0543:
0544:                    return s2;
0545:                }
0546:
0547:                if (s2 == null) {
0548:                    return s1;
0549:                }
0550:
0551:                return s1.concat(s2);
0552:            }
0553:
0554:            /**
0555:             * Returns a count of the characters that do not match when comparing
0556:             * the 4 digit numeric SOUNDEX character sequences for the
0557:             * given <code>String</code> objects.  If either <code>String</code> object is
0558:             * <code>null</code>, zero is returned.
0559:             * @param s1 the first <code>String</code>
0560:             * @param s2 the second <code>String</code>
0561:             * @return the number of differences between the <code>SOUNDEX</code> of
0562:             *      <code>s1</code> and the <code>SOUNDEX</code> of <code>s2</code>
0563:             */
0564:
0565:            // fredt@users 20020305 - patch 460907 by fredt - soundex
0566:            public static int difference(String s1, String s2) {
0567:
0568:                // todo: check if this is the standard algorithm
0569:                if ((s1 == null) || (s2 == null)) {
0570:                    return 0;
0571:                }
0572:
0573:                s1 = soundex(s1);
0574:                s2 = soundex(s2);
0575:
0576:                int e = 0;
0577:
0578:                for (int i = 0; i < 4; i++) {
0579:                    if (s1.charAt(i) != s2.charAt(i)) {
0580:                        e++;
0581:                    }
0582:                }
0583:
0584:                return e;
0585:            }
0586:
0587:            /**
0588:             * Converts a <code>String</code> of hexidecimal digit characters to a raw
0589:             * binary value, represented as a <code>String</code>.<p>
0590:             *
0591:             * The given <code>String</code> object must consist of a sequence of
0592:             * 4 digit hexidecimal character substrings.<p> If its length is not
0593:             * evenly divisible by 4, <code>null</code> is returned.  If any of
0594:             * its 4 character subsequences cannot be parsed as a
0595:             * 4 digit, base 16 value, then a NumberFormatException is thrown.
0596:             *
0597:             * This conversion has the effect of reducing the character count 4:1.
0598:             *
0599:             * @param s a <code>String</code> of hexidecimal digit characters
0600:             * @return an equivalent raw binary value, represented as a
0601:             *      <code>String</code>
0602:             */
0603:            public static String hexToRaw(String s) {
0604:
0605:                if (s == null) {
0606:                    return null;
0607:                }
0608:
0609:                char raw;
0610:                StringBuffer to = new StringBuffer();
0611:                int len = s.length();
0612:
0613:                if (len % 4 != 0) {
0614:                    return null;
0615:                }
0616:
0617:                for (int i = 0; i < len; i += 4) {
0618:                    raw = (char) Integer.parseInt(s.substring(i, i + 4), 16);
0619:
0620:                    to.append(raw);
0621:                }
0622:
0623:                return (to.toString());
0624:            }
0625:
0626:            /**
0627:             * Returns a character sequence which is the result of writing the
0628:             * first <code>length</code> number of characters from the second
0629:             * given <code>String</code> over the first string. The start position
0630:             * in the first string where the characters are overwritten is given by
0631:             * <code>start</code>.<p>
0632:             *
0633:             * <b>Note:</b> In order of precedence, boundry conditions are handled as
0634:             * follows:<p>
0635:             *
0636:             * <UL>
0637:             * <LI>if either supplied <code>String</code> is null, then the other is
0638:             *      returned; the check starts with the first given <code>String</code>.
0639:             * <LI>if <code>start</code> is less than one, <code>s1</code> is returned
0640:             * <LI>if <code>length</code> is less than or equal to zero,
0641:             *     <code>s1</code> is returned
0642:             * <LI>if the length of <code>s2</code> is zero, <code>s1</code> is returned
0643:             * <LI>if <code>start</code> is greater than the length of <code>s1</code>,
0644:             *      <code>s1</code> is returned
0645:             * <LI>if <code>length</code> is such that, taken together with
0646:             *      <code>start</code>, the indicated interval extends
0647:             *      beyond the end of <code>s1</code>, then the insertion is performed
0648:             *      precisely as if upon a copy of <code>s1</code> extended in length
0649:             *      to just include the indicated interval
0650:             * </UL>
0651:             * @param s1 the <code>String</code> into which to insert <code>s2</code>
0652:             * @param start the position, with origin one, at which to start the insertion
0653:             * @param length the number of characters in <code>s1</code> to replace
0654:             * @param s2 the <code>String</code> to insert into <code>s1</code>
0655:             * @return <code>s2</code> inserted into <code>s1</code>, as indicated
0656:             *      by <code>start</code> and <code>length</code> and adjusted for
0657:             *      boundry conditions
0658:             */
0659:            public static String insert(String s1, int start, int length,
0660:                    String s2) {
0661:
0662:                if (s1 == null) {
0663:                    return s2;
0664:                }
0665:
0666:                if (s2 == null) {
0667:                    return s1;
0668:                }
0669:
0670:                int len1 = s1.length();
0671:                int len2 = s2.length();
0672:
0673:                start--;
0674:
0675:                if (start < 0 || length <= 0 || len2 == 0 || start > len1) {
0676:                    return s1;
0677:                }
0678:
0679:                if (start + length > len1) {
0680:                    length = len1 - start;
0681:                }
0682:
0683:                return s1.substring(0, start) + s2
0684:                        + s1.substring(start + length);
0685:            }
0686:
0687:            /**
0688:             * Returns a copy of the given <code>String</code>, with all upper case
0689:             * characters converted to lower case. This uses the default Java String
0690:             * conversion.
0691:             * @param s the <code>String</code> from which to produce a lower case
0692:             *      version
0693:             * @return a lower case version of <code>s</code>
0694:             */
0695:            public static String lcase(String s) {
0696:                return (s == null) ? null : s.toLowerCase();
0697:            }
0698:
0699:            /**
0700:             * Returns the leftmost <code>count</code> characters from the given
0701:             * <code>String</code>. <p>
0702:             *
0703:             * <b>Note:</b> boundry conditions are handled in the following order of
0704:             * precedence:
0705:             *
0706:             * <UL>
0707:             *  <LI> if <code>s</code> is <code>null</code>, then <code>null</code>
0708:             *      is returned
0709:             *  <LI> if <code>count</code> is less than 1, then a zero-length
0710:             *       <code>String</code> is returned
0711:             *  <LI> if <code>count</code> is greater than the length of <code>s</code>,
0712:             *      then a copy of <code>s</code> is returned
0713:             * </UL>
0714:             * @param s the <code>String</code> from which to retrieve the leftmost
0715:             *      characters
0716:             * @param count the count of leftmost characters to retrieve
0717:             * @return the leftmost <code>count</code> characters of <code>s</code>
0718:             */
0719:            public static String left(String s, int count) {
0720:
0721:                if (s == null) {
0722:                    return null;
0723:                }
0724:
0725:                return s.substring(0, ((count < 0) ? 0
0726:                        : (count < s.length()) ? count : s.length()));
0727:            }
0728:
0729:            // fredt@users - 20020819 - patch 595854 by thomasm@users
0730:
0731:            /**
0732:             * Returns the number of characters in the given <code>String</code>.
0733:             * This includes trailing blanks.
0734:             *
0735:             * @param s the <code>String</code> for which to determine length
0736:             * @return the length of <code>s</code>, including trailing blanks
0737:             */
0738:            public static Integer length(String s) {
0739:                return s == null ? null : ValuePool.getInt(s.length());
0740:            }
0741:
0742:            /**
0743:             * Returns the number of bytes in the given <code>String</code>.
0744:             * This includes trailing blanks.
0745:             *
0746:             * @param s the <code>String</code> for which to determine the octet length
0747:             * @return the octet length of <code>s</code>, including trailing blanks
0748:             * @since 1.7.2
0749:             */
0750:            public static Integer octetLength(String s) {
0751:                return s == null ? null : ValuePool.getInt(s.length() * 2);
0752:            }
0753:
0754:            /**
0755:             * Returns the number of bits in the given <code>String</code>.
0756:             * This includes trailing blanks.
0757:             *
0758:             * @param s the <code>String</code> for which to determine the bit length
0759:             * @return the bit length of <code>s</code>, including trailing blanks
0760:             * @since 1.7.2
0761:             */
0762:            public static Integer bitLength(String s) {
0763:                return s == null ? null : ValuePool.getInt(s.length() * 16);
0764:            }
0765:
0766:            /**
0767:             * Returns the starting position of the first occurrence of
0768:             * the given <code>search</code> <code>String</code> object within
0769:             * the given <code>String</code> object, <code>s</code>.
0770:             *
0771:             * The search for the first occurrence of <code>search</code> begins with
0772:             * the first character position in <code>s</code>, unless the optional
0773:             * argument, <code>start</code>, is specified (non-null). If
0774:             * <code>start</code> is specified, the search begins with the character
0775:             * position indicated by the value of <code>start</code>, where the
0776:             * first character position in <code>s</code> is indicated by the value 1.
0777:             * If <code>search</code> is not found within <code>s</code>, the
0778:             * value 0 is returned.
0779:             * @param search the <code>String</code> occurence to find in <code>s</code>
0780:             * @param s the <code>String</code> within which to find the first
0781:             *      occurence of <code>search</code>
0782:             * @param start the optional character position from which to start
0783:             *      looking in <code>s</code>
0784:             * @return the one-based starting position of the first occurrence of
0785:             *      <code>search</code> within <code>s</code>, or 0 if not found
0786:             */
0787:            public static int locate(String search, String s, Integer start) {
0788:
0789:                if (s == null || search == null) {
0790:                    return 0;
0791:                }
0792:
0793:                int i = (start == null) ? 0 : start.intValue() - 1;
0794:
0795:                return s.indexOf(search, (i < 0) ? 0 : i) + 1;
0796:            }
0797:
0798:            /**
0799:             * As locate but from start position l. <p>
0800:             *
0801:             * @param search the <code>String</code> occurence to find in <code>s</code>
0802:             * @param s the <code>String</code> within which to find the first
0803:             *      occurence of <code>search</code>
0804:             * @return the one-based starting position of the first occurrence of
0805:             *      <code>search</code> within <code>s</code>, or 0 if not found
0806:             */
0807:            public static int position(String search, String s) {
0808:                return locate(search, s, null);
0809:            }
0810:
0811:            /**
0812:             * Returns the characters of the given <code>String</code>, with the
0813:             * leading spaces removed. Characters such as TAB are not removed.
0814:             *
0815:             * @param s the <code>String</code> from which to remove the leading blanks
0816:             * @return the characters of the given <code>String</code>, with the leading
0817:             *      spaces removed
0818:             */
0819:            public static String ltrim(String s) {
0820:
0821:                if (s == null) {
0822:                    return s;
0823:                }
0824:
0825:                int len = s.length(), i = 0;
0826:
0827:                while (i < len && s.charAt(i) <= ' ') {
0828:                    i++;
0829:                }
0830:
0831:                return (i == 0) ? s : s.substring(i);
0832:            }
0833:
0834:            /**
0835:             * Converts a raw binary value, as represented by the given
0836:             * <code>String</code>, to the equivalent <code>String</code>
0837:             * of hexidecimal digit characters. <p>
0838:             *
0839:             * This conversion has the effect of expanding the character count 1:4.
0840:             *
0841:             * @param s the raw binary value, as a <code>String</code>
0842:             * @return an equivalent <code>String</code> of hexidecimal digit characters
0843:             */
0844:            public static String rawToHex(String s) {
0845:
0846:                if (s == null) {
0847:                    return null;
0848:                }
0849:
0850:                char[] from = s.toCharArray();
0851:                String hex;
0852:                StringBuffer to = new StringBuffer(4 * s.length());
0853:
0854:                for (int i = 0; i < from.length; i++) {
0855:                    hex = Integer.toHexString(from[i] & 0xffff);
0856:
0857:                    for (int j = hex.length(); j < 4; j++) {
0858:                        to.append('0');
0859:                    }
0860:
0861:                    to.append(hex);
0862:                }
0863:
0864:                return (to.toString());
0865:            }
0866:
0867:            /**
0868:             * Returns a <code>String</code> composed of the given <code>String</code>,
0869:             * repeated  <code>count</code> times.
0870:             *
0871:             * @param s the <code>String</code> to repeat
0872:             * @param count the number of repetitions
0873:             * @return the given <code>String</code>, repeated <code>count</code> times
0874:             */
0875:            public static String repeat(String s, Integer count) {
0876:
0877:                if (s == null || count == null || count.intValue() < 0) {
0878:                    return null;
0879:                }
0880:
0881:                int i = count.intValue();
0882:                StringBuffer b = new StringBuffer(s.length() * i);
0883:
0884:                while (i-- > 0) {
0885:                    b.append(s);
0886:                }
0887:
0888:                return b.toString();
0889:            }
0890:
0891:            // fredt@users - 20020903 - patch 1.7.1 - bug fix to allow multiple replaces
0892:
0893:            /**
0894:             * Replaces all occurrences of <code>replace</code> in <code>s</code>
0895:             * with the <code>String</code> object: <code>with</code>
0896:             * @param s the target for replacement
0897:             * @param replace the substring(s), if any, in <code>s</code> to replace
0898:             * @param with the value to substitute for <code>replace</code>
0899:             * @return <code>s</code>, with all occurences of <code>replace</code>
0900:             *      replaced by <code>with</code>
0901:             */
0902:            public static String replace(String s, String replace, String with) {
0903:
0904:                if (s == null || replace == null) {
0905:                    return s;
0906:                }
0907:
0908:                if (with == null) {
0909:                    with = "";
0910:                }
0911:
0912:                StringBuffer b = new StringBuffer();
0913:                int start = 0;
0914:                int lenreplace = replace.length();
0915:
0916:                while (true) {
0917:                    int i = s.indexOf(replace, start);
0918:
0919:                    if (i == -1) {
0920:                        b.append(s.substring(start));
0921:
0922:                        break;
0923:                    }
0924:
0925:                    b.append(s.substring(start, i));
0926:                    b.append(with);
0927:
0928:                    start = i + lenreplace;
0929:                }
0930:
0931:                return b.toString();
0932:            }
0933:
0934:            /**
0935:             * Returns the rightmost <code>count</code> characters of the given
0936:             * <code>String</code>, <code>s</code>. <p>
0937:             *
0938:             * <b>Note:</b> boundry conditions are handled in the following order of
0939:             * precedence: <p>
0940:             *
0941:             * <UL>
0942:             *  <LI> if <code>s</code> is <code>null</code>, <code>null</code> is returned
0943:             *  <LI> if <code>count</code> is less than one, a zero-length
0944:             *      <code>String</code> is returned
0945:             *  <LI> if <code>count</code> is greater than the length of <code>s</code>,
0946:             *      a copy of <code>s</code> is returned
0947:             * </UL>
0948:             * @param s the <code>String</code> from which to retrieve the rightmost
0949:             *      <code>count</code> characters
0950:             * @param count the number of rightmost characters to retrieve
0951:             * @return the rightmost <code>count</code> characters of <code>s</code>
0952:             */
0953:            public static String right(String s, int count) {
0954:
0955:                if (s == null) {
0956:                    return null;
0957:                }
0958:
0959:                count = s.length() - count;
0960:
0961:                return s.substring((count < 0) ? 0
0962:                        : (count < s.length()) ? count : s.length());
0963:            }
0964:
0965:            // fredt@users 20020530 - patch 1.7.0 fredt - trim only the space character
0966:
0967:            /**
0968:             * Returns the characters of the given <code>String</code>, with trailing
0969:             * spaces removed.
0970:             * @param s the <code>String</code> from which to remove the trailing blanks
0971:             * @return the characters of the given <code>String</code>, with the
0972:             * trailing spaces removed
0973:             */
0974:            public static String rtrim(String s) {
0975:
0976:                if (s == null) {
0977:                    return s;
0978:                }
0979:
0980:                int endindex = s.length() - 1;
0981:                int i = endindex;
0982:
0983:                for (; i >= 0 && s.charAt(i) == ' '; i--) {
0984:                }
0985:
0986:                return i == endindex ? s : s.substring(0, i + 1);
0987:            }
0988:
0989:            /**
0990:             * Returns the character sequence <code>s</code>, with the leading,
0991:             * trailing or both the leading and trailing occurences of the first
0992:             * character of the character sequence <code>trimstr</code> removed. <p>
0993:             *
0994:             * This method is in support of the standard SQL String function TRIM.
0995:             * Ordinarily, the functionality of this method is accessed from SQL using
0996:             * the following syntax: <p>
0997:             *
0998:             * <pre class="SqlCodeExample">
0999:             * &lt;trim function&gt; ::= TRIM &lt;left paren&gt; &lt;trim operands&gt; &lt;right paren&gt;
1000:             * &lt;trim operands&gt; ::= [ [ &lt;trim specification&gt; ] [ &lt;trim character&gt; ] FROM ] &lt;trim source&gt;
1001:             * &lt;trim source&gt; ::= &lt;character value expression&gt;
1002:             * &lt;trim specification&gt; ::= LEADING | TRAILING | BOTH
1003:             * &lt;trim character&gt; ::= &lt;character value expression&gt;
1004:             * </pre>
1005:             *
1006:             * @param s the string to trim
1007:             * @param trimstr the character whose occurences will be removed
1008:             * @param leading if true, remove leading occurences
1009:             * @param trailing if true, remove trailing occurences
1010:             * @return s, with the leading, trailing or both the leading and trailing
1011:             *      occurences of the first character of <code>trimstr</code> removed
1012:             * @since 1.7.2
1013:             */
1014:            public static String trim(String s, String trimstr,
1015:                    boolean leading, boolean trailing) {
1016:
1017:                if (s == null) {
1018:                    return s;
1019:                }
1020:
1021:                int trim = trimstr.charAt(0);
1022:                int endindex = s.length();
1023:
1024:                if (trailing) {
1025:                    for (--endindex; endindex >= 0
1026:                            && s.charAt(endindex) == trim; endindex--) {
1027:                    }
1028:
1029:                    endindex++;
1030:                }
1031:
1032:                if (endindex == 0) {
1033:                    return "";
1034:                }
1035:
1036:                int startindex = 0;
1037:
1038:                if (leading) {
1039:                    while (startindex < endindex
1040:                            && s.charAt(startindex) == trim) {
1041:                        startindex++;
1042:                    }
1043:                }
1044:
1045:                if (startindex == 0 && endindex == s.length()) {
1046:                    return s;
1047:                } else {
1048:                    return s.substring(startindex, endindex);
1049:                }
1050:            }
1051:
1052:            // fredt@users 20011010 - patch 460907 by fredt - soundex
1053:
1054:            /**
1055:             * Returns a four character code representing the sound of the given
1056:             * <code>String</code>. Non-ASCCI characters in the
1057:             * input <code>String</code> are ignored. <p>
1058:             *
1059:             * This method was
1060:             * rewritten for HSQLDB by fredt@users to comply with the description at
1061:             * <a href="http://www.nara.gov/genealogy/coding.html">
1062:             * http://www.nara.gov/genealogy/coding.html</a>.<p>
1063:             * @param s the <code>String</code> for which to calculate the 4 character
1064:             *      <code>SOUNDEX</code> value
1065:             * @return the 4 character <code>SOUNDEX</code> value for the given
1066:             *      <code>String</code>
1067:             */
1068:            public static String soundex(String s) {
1069:
1070:                if (s == null) {
1071:                    return s;
1072:                }
1073:
1074:                s = s.toUpperCase(Locale.ENGLISH);
1075:
1076:                int len = s.length();
1077:                char[] b = new char[] { '0', '0', '0', '0' };
1078:                char lastdigit = '0';
1079:
1080:                for (int i = 0, j = 0; i < len && j < 4; i++) {
1081:                    char c = s.charAt(i);
1082:                    char newdigit;
1083:
1084:                    if ("AEIOUY".indexOf(c) != -1) {
1085:                        newdigit = '7';
1086:                    } else if (c == 'H' || c == 'W') {
1087:                        newdigit = '8';
1088:                    } else if ("BFPV".indexOf(c) != -1) {
1089:                        newdigit = '1';
1090:                    } else if ("CGJKQSXZ".indexOf(c) != -1) {
1091:                        newdigit = '2';
1092:                    } else if (c == 'D' || c == 'T') {
1093:                        newdigit = '3';
1094:                    } else if (c == 'L') {
1095:                        newdigit = '4';
1096:                    } else if (c == 'M' || c == 'N') {
1097:                        newdigit = '5';
1098:                    } else if (c == 'R') {
1099:                        newdigit = '6';
1100:                    } else {
1101:                        continue;
1102:                    }
1103:
1104:                    if (j == 0) {
1105:                        b[j++] = c;
1106:                        lastdigit = newdigit;
1107:                    } else if (newdigit <= '6') {
1108:                        if (newdigit != lastdigit) {
1109:                            b[j++] = newdigit;
1110:                            lastdigit = newdigit;
1111:                        }
1112:                    } else if (newdigit == '7') {
1113:                        lastdigit = newdigit;
1114:                    }
1115:                }
1116:
1117:                return new String(b, 0, 4);
1118:            }
1119:
1120:            /**
1121:             * Returns a <code>String</code> consisting of <code>count</code> spaces, or
1122:             * <code>null</code> if <code>count</code> is less than zero. <p>
1123:             *
1124:             * @param count the number of spaces to produce
1125:             * @return a <code>String</code> of <code>count</code> spaces
1126:             */
1127:            public static String space(int count) {
1128:
1129:                if (count < 0) {
1130:                    return null;
1131:                }
1132:
1133:                char[] c = new char[count];
1134:
1135:                while (count > 0) {
1136:                    c[--count] = ' ';
1137:                }
1138:
1139:                return new String(c);
1140:            }
1141:
1142:            /**
1143:             * Returns the characters from the given <code>String</code>, starting at
1144:             * the indicated one-based <code>start</code> position and extending the
1145:             * (optional) indicated <code>length</code>. If <code>length</code> is not
1146:             * specified (is <code>null</code>), the remainder of <code>s</code> is
1147:             * implied.
1148:             *
1149:             * The rules for boundary conditions on s, start and length are,
1150:             * in order of precedence: <p>
1151:             *
1152:             * 1.) if s is null, return null
1153:             *
1154:             * 2.) If length is less than 1, return null.
1155:             *
1156:             * 3.) If start is 0, it is treated as 1.
1157:             *
1158:             * 4.) If start is positive, count from the beginning of s to find
1159:             *     the first character postion.
1160:             *
1161:             * 5.) If start is negative, count backwards from the end of s
1162:             *     to find the first character.
1163:             *
1164:             * 6.) If, after applying 2.) or 3.), the start position lies outside s,
1165:             *     then return null
1166:             *
1167:             * 7.) if length is ommited or is greated than the number of characters
1168:             *     from the start position to the end of s, return the remaineder of s,
1169:             *     starting with the start position.
1170:             *
1171:             * @param s the <code>String</code> from which to produce the indicated
1172:             *      substring
1173:             * @param start the starting position of the desired substring
1174:             * @param length the length of the desired substring
1175:             * @return the indicted substring of <code>s</code>.
1176:             */
1177:
1178:            // fredt@users 20020210 - patch 500767 by adjbirch@users - modified
1179:            // boucherb@users 20050205 - patch to correct bug 1107477
1180:            public static String substring(final String s, int start,
1181:                    final Integer length) {
1182:
1183:                if (s == null) {
1184:                    return null;
1185:                }
1186:
1187:                int sl = s.length();
1188:                int ol = (length == null) ? sl : length.intValue();
1189:
1190:                if (ol < 1) {
1191:                    return null;
1192:                }
1193:
1194:                if (start < 0) {
1195:                    start = sl + start;
1196:                } else if (start > 0) {
1197:                    start--;
1198:                }
1199:
1200:                if (start < 0 || start >= sl) {
1201:                    return null;
1202:                } else if (start > sl - ol) {
1203:                    ol = sl - start;
1204:                }
1205:
1206:                return s.substring(start, start + ol);
1207:            }
1208:
1209:            /**
1210:             * Returns a copy of the given <code>String</code>, with all lower case
1211:             * characters converted to upper case using the default Java method.
1212:             * @param s the <code>String</code> from which to produce an upper case
1213:             *      version
1214:             * @return an upper case version of <code>s</code>
1215:             */
1216:            public static String ucase(String s) {
1217:                return (s == null) ? null : s.toUpperCase();
1218:            }
1219:
1220:            // TIME AND DATE
1221:
1222:            /**
1223:             * Returns the current date as a date value. <p>
1224:             *
1225:             * Dummy mehtod.<p>
1226:             *
1227:             * @return a date value representing the current date
1228:             */
1229:            public static Date curdate(Connection c) {
1230:                return null;
1231:            }
1232:
1233:            /**
1234:             * Returns the current local time as a time value. <p>
1235:             *
1236:             * Dummy mehtod.<p>
1237:             *
1238:             * @return a time value representing the current local time
1239:             */
1240:            public static Time curtime(Connection c) {
1241:                return null;
1242:            }
1243:
1244:            /**
1245:             * Returns a character string containing the name of the day
1246:             * (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday )
1247:             * for the day portion of the given <code>java.sql.Date</code>.
1248:             * @param d the date value from which to extract the day name
1249:             * @return the name of the day corresponding to the given
1250:             * <code>java.sql.Date</code>
1251:             */
1252:            public static String dayname(Date d) {
1253:
1254:                if (d == null) {
1255:                    return null;
1256:                }
1257:
1258:                synchronized (daynameBuffer) {
1259:                    daynameBuffer.setLength(0);
1260:
1261:                    return daynameFormat.format(d, daynameBuffer, dayPosition)
1262:                            .toString();
1263:                }
1264:            }
1265:
1266:            /**
1267:             * Returns the day of the month from the given date value, as an integer
1268:             * value in the range of 1-31.
1269:             *
1270:             * @param d the date value from which to extract the day of month
1271:             * @return the day of the month from the given date value
1272:             */
1273:            public static Integer dayofmonth(Date d) {
1274:
1275:                if (d == null) {
1276:                    return null;
1277:                }
1278:
1279:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1280:                        Calendar.DAY_OF_MONTH));
1281:            }
1282:
1283:            /**
1284:             * Returns the day of the week from the given date value, as an integer
1285:             * value in the range 1-7, where 1 represents Sunday.
1286:             *
1287:             * @param d the date value from which to extract the day of week
1288:             * @return the day of the week from the given date value
1289:             */
1290:            public static Integer dayofweek(Date d) {
1291:
1292:                if (d == null) {
1293:                    return null;
1294:                }
1295:
1296:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1297:                        Calendar.DAY_OF_WEEK));
1298:            }
1299:
1300:            /**
1301:             * Returns the day of the year from the given date value, as an integer
1302:             * value in the range 1-366.
1303:             *
1304:             * @param d the date value from which to extract the day of year
1305:             * @return the day of the year from the given date value
1306:             */
1307:            public static Integer dayofyear(Date d) {
1308:
1309:                if (d == null) {
1310:                    return null;
1311:                }
1312:
1313:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1314:                        Calendar.DAY_OF_YEAR));
1315:            }
1316:
1317:            /**
1318:             * Returns the hour from the given time value, as an integer value in
1319:             * the range of 0-23.
1320:             *
1321:             * @param t the time value from which to extract the hour of day
1322:             * @return the hour of day from the given time value
1323:             */
1324:
1325:            // fredt@users 20020210 - patch 513005 by sqlbob@users (RMP) - hour
1326:            public static Integer hour(Time t) {
1327:
1328:                if (t == null) {
1329:                    return null;
1330:                }
1331:
1332:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(t,
1333:                        Calendar.HOUR_OF_DAY));
1334:            }
1335:
1336:            /**
1337:             * Returns the minute from the given time value, as integer value in
1338:             * the range of 0-59.
1339:             *
1340:             * @param t the time value from which to extract the minute value
1341:             * @return the minute value from the given time value
1342:             */
1343:            public static Integer minute(Time t) {
1344:
1345:                if (t == null) {
1346:                    return null;
1347:                }
1348:
1349:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(t,
1350:                        Calendar.MINUTE));
1351:            }
1352:
1353:            /**
1354:             * Returns the month from the given date value, as an integer value in the
1355:             * range of 1-12. <p>
1356:             *
1357:             * The sql_month database property is now obsolete.
1358:             * The function always returns the SQL (1-12) value for month.
1359:             *
1360:             * @param d the date value from which to extract the month value
1361:             * @return the month value from the given date value
1362:             */
1363:            public static Integer month(Date d) {
1364:
1365:                if (d == null) {
1366:                    return null;
1367:                }
1368:
1369:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1370:                        Calendar.MONTH) + 1);
1371:            }
1372:
1373:            /**
1374:             * Returns a character string containing the name of month
1375:             * (January, February, March, April, May, June, July, August,
1376:             * September, October, November, December) for the month portion of
1377:             * the given date value.
1378:             *
1379:             * @param d the date value from which to extract the month name
1380:             * @return a String representing the month name from the given date value
1381:             */
1382:            public static String monthname(Date d) {
1383:
1384:                if (d == null) {
1385:                    return null;
1386:                }
1387:
1388:                synchronized (monthnameBuffer) {
1389:                    monthnameBuffer.setLength(0);
1390:
1391:                    return monthnameFormat.format(d, monthnameBuffer,
1392:                            monthPosition).toString();
1393:                }
1394:            }
1395:
1396:            /**
1397:             * Returns the current date and time as a timestamp value. <p>
1398:             *
1399:             * Dummy mehtod.<p>
1400:             *
1401:             * @return a timestamp value representing the current date and time
1402:             */
1403:            public static Timestamp now(Connection c) {
1404:                return null;
1405:            }
1406:
1407:            /**
1408:             * Returns the quarter of the year in the given date value, as an integer
1409:             * value in the range of 1-4. <p>
1410:             *
1411:             * @param d the date value from which to extract the quarter of the year
1412:             * @return an integer representing the quater of the year from the given
1413:             *      date value
1414:             */
1415:            public static Integer quarter(Date d) {
1416:
1417:                if (d == null) {
1418:                    return null;
1419:                }
1420:
1421:                return ValuePool.getInt((HsqlDateTime.getDateTimePart(d,
1422:                        Calendar.MONTH) / 3) + 1);
1423:            }
1424:
1425:            /**
1426:             * Returns the second of the given time value, as an integer value in
1427:             * the range of 0-59.
1428:             *
1429:             * @param d the date value from which to extract the second of the hour
1430:             * @return an integer representing the second of the hour from the
1431:             *      given time value
1432:             */
1433:            public static Integer second(Time d) {
1434:
1435:                if (d == null) {
1436:                    return null;
1437:                }
1438:
1439:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1440:                        Calendar.SECOND));
1441:            }
1442:
1443:            /**
1444:             * Returns the week of the year from the given date value, as an integer
1445:             * value in the range of 1-53. <p>
1446:             *
1447:             * @param d the date value from which to extract the week of the year
1448:             * @return an integer representing the week of the year from the given
1449:             *      date value
1450:             */
1451:            public static Integer week(Date d) {
1452:
1453:                if (d == null) {
1454:                    return null;
1455:                }
1456:
1457:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1458:                        Calendar.WEEK_OF_YEAR));
1459:            }
1460:
1461:            /**
1462:             * Returns the year from the given date value, as an integer value in
1463:             * the range of 1-9999. <p>
1464:             *
1465:             * @param d the date value from which to extract the year
1466:             * @return an integer value representing the year from the given
1467:             *      date value
1468:             */
1469:            public static Integer year(Date d) {
1470:
1471:                if (d == null) {
1472:                    return null;
1473:                }
1474:
1475:                return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
1476:                        Calendar.YEAR));
1477:            }
1478:
1479:            /**
1480:             * @since 1.8.0
1481:             */
1482:            public static String to_char(java.util.Date d, String format) {
1483:
1484:                if (d == null || format == null) {
1485:                    return null;
1486:                }
1487:
1488:                synchronized (tocharFormat) {
1489:                    tocharFormat.applyPattern(HsqlDateTime
1490:                            .toJavaDatePattern(format));
1491:
1492:                    return tocharFormat.format(d);
1493:                }
1494:            }
1495:
1496:            // date calculations.
1497:
1498:            /**
1499:             * Returns the number of units elapsed between two dates.<p>
1500:             * The datapart parameter indicates the part to be used for computing the
1501:             * difference. Supported types include: 'year', 'yy', 'month', 'mm'
1502:             * 'day', 'dd', 'hour', 'hh', 'minute', 'mi', 'second', 'ss', 'millisecond',
1503:             * 'ms'.
1504:             *
1505:             * Contributed by Michael Landon<p>
1506:             *
1507:             * @param datepart Specifies the unit in which the interval is to be measured.
1508:             * @param d1 The starting datetime value for the interval. This value is
1509:             *           subtracted from d2 to return the number of
1510:             *           date-parts between the two arguments.
1511:             * @param d2 The ending datetime for the interval. d1 is subtracted
1512:             *           from this value to return the number of date-parts
1513:             *           between the two arguments.
1514:             *
1515:             * since 1.7.3
1516:             */
1517:            public static Long datediff(String datepart, Timestamp d1,
1518:                    Timestamp d2) throws HsqlException {
1519:
1520:                // make sure we've got valid data
1521:                if (d1 == null || d2 == null) {
1522:                    return null;
1523:                }
1524:
1525:                if ("yy".equalsIgnoreCase(datepart)
1526:                        || "year".equalsIgnoreCase(datepart)) {
1527:                    return ValuePool.getLong(getElapsed(Calendar.YEAR, d1, d2));
1528:                } else if ("mm".equalsIgnoreCase(datepart)
1529:                        || "month".equalsIgnoreCase(datepart)) {
1530:                    return ValuePool
1531:                            .getLong(getElapsed(Calendar.MONTH, d1, d2));
1532:                } else if ("dd".equalsIgnoreCase(datepart)
1533:                        || "day".equalsIgnoreCase(datepart)) {
1534:                    return ValuePool.getLong(getElapsed(Calendar.DATE, d1, d2));
1535:                } else if ("hh".equalsIgnoreCase(datepart)
1536:                        || "hour".equalsIgnoreCase(datepart)) {
1537:                    return ValuePool.getLong(getElapsed(Calendar.HOUR, d1, d2));
1538:                } else if ("mi".equalsIgnoreCase(datepart)
1539:                        || "minute".equalsIgnoreCase(datepart)) {
1540:                    return ValuePool
1541:                            .getLong(getElapsed(Calendar.MINUTE, d1, d2));
1542:                } else if ("ss".equalsIgnoreCase(datepart)
1543:                        || "second".equalsIgnoreCase(datepart)) {
1544:                    return ValuePool
1545:                            .getLong(getElapsed(Calendar.SECOND, d1, d2));
1546:                } else if ("ms".equalsIgnoreCase(datepart)
1547:                        || "millisecond".equalsIgnoreCase(datepart)) {
1548:                    return ValuePool.getLong(getElapsed(Calendar.MILLISECOND,
1549:                            d1, d2));
1550:                } else {
1551:                    throw Trace.error(Trace.INVALID_CONVERSION);
1552:                }
1553:            }
1554:
1555:            /**
1556:             * Private method used to do actual calculation units elapsed between
1557:             * two given dates. <p>
1558:             *
1559:             * @param field Calendar field to use to calculate elapsed time
1560:             * @param d1 The starting date for the interval. This value is
1561:             *           subtracted from d2 to return the number of
1562:             *           date-parts between the two arguments.
1563:             * @param d2 The ending date for the interval. d1 is subtracted
1564:             *           from this value to return the number of date-parts
1565:             *           between the two arguments.
1566:             */
1567:            private static long getElapsed(int field, java.util.Date d1,
1568:                    java.util.Date d2) {
1569:
1570:                // can we do this very simply?
1571:                if (field == Calendar.MILLISECOND) {
1572:                    return d2.getTime() - d1.getTime();
1573:                }
1574:
1575:                // ok, let's work a little harder:
1576:                Calendar g1 = Calendar.getInstance(), g2 = Calendar
1577:                        .getInstance();
1578:
1579:                g1.setTime(d1);
1580:                g2.setTime(d2);
1581:                g1.set(Calendar.MILLISECOND, 0);
1582:                g2.set(Calendar.MILLISECOND, 0);
1583:
1584:                if (field == Calendar.SECOND) {
1585:                    return (g2.getTime().getTime() - g1.getTime().getTime()) / 1000;
1586:                }
1587:
1588:                g1.set(Calendar.SECOND, 0);
1589:                g2.set(Calendar.SECOND, 0);
1590:
1591:                if (field == Calendar.MINUTE) {
1592:                    return (g2.getTime().getTime() - g1.getTime().getTime())
1593:                            / (1000 * 60);
1594:                }
1595:
1596:                g1.set(Calendar.MINUTE, 0);
1597:                g2.set(Calendar.MINUTE, 0);
1598:
1599:                if (field == Calendar.HOUR) {
1600:                    return (g2.getTime().getTime() - g1.getTime().getTime())
1601:                            / (1000 * 60 * 60);
1602:                } // end if-else
1603:
1604:                // if we got here, then we really need to work:
1605:                long elapsed = 0;
1606:                short sign = 1;
1607:
1608:                if (g2.before(g1)) {
1609:                    sign = -1;
1610:
1611:                    Calendar tmp = g1;
1612:
1613:                    g1 = g2;
1614:                    g2 = tmp;
1615:                } // end if
1616:
1617:                g1.set(Calendar.HOUR_OF_DAY, 0);
1618:                g2.set(Calendar.HOUR_OF_DAY, 0);
1619:
1620:                if (field == Calendar.MONTH || field == Calendar.YEAR) {
1621:                    g1.set(Calendar.DATE, 1);
1622:                    g2.set(Calendar.DATE, 1);
1623:                }
1624:
1625:                if (field == Calendar.YEAR) {
1626:                    g1.set(Calendar.MONTH, 1);
1627:                    g2.set(Calendar.MONTH, 1);
1628:                } // end if-else
1629:
1630:                // then calculate elapsed units
1631:                while (g1.before(g2)) {
1632:                    g1.add(field, 1);
1633:
1634:                    elapsed++;
1635:                }
1636:
1637:                return sign * elapsed;
1638:            } // end getElapsed
1639:
1640:            // SYSTEM
1641:            /*
1642:             * All system functions that return Session dependent information are
1643:             * dummies here.
1644:             */
1645:
1646:            /**
1647:             * Returns the name of the database corresponding to this connection.
1648:             *
1649:             * @param conn the connection for which to retrieve the database name
1650:             * @return the name of the database for the given connection
1651:             * @throws HsqlException if a database access error occurs
1652:             */
1653:            public static String database(Connection conn) throws HsqlException {
1654:                return null;
1655:            }
1656:
1657:            /**
1658:             * Returns the user's authorization name (the user's name as known to this
1659:             * database).
1660:             *
1661:             * @param conn the connection for which to retrieve the user name
1662:             * @return the user's name as known to the database
1663:             * @throws HsqlException if a database access error occurs
1664:             */
1665:            public static String user(Connection conn) throws HsqlException {
1666:                return null;
1667:            }
1668:
1669:            /**
1670:             * Retrieves the last auto-generated integer indentity value
1671:             * used by this connection. <p>
1672:             *
1673:             * Dummy mehtod.<p>
1674:             *
1675:             * @return the connection's the last generated integer identity value
1676:             * @throws HsqlException if a database access error occurs
1677:             */
1678:            public static int identity() throws HsqlException {
1679:                return 0;
1680:            }
1681:
1682:            // JDBC SYSTEM
1683:
1684:            /**
1685:             * Retrieves the autocommit status of this connection. <p>
1686:             *
1687:             * @param conn the <code>Connection</code> object for which to retrieve
1688:             *      the current autocommit status
1689:             * @return a boolean value representing the connection's autocommit status
1690:             * @since 1.7.0
1691:             */
1692:            public static boolean getAutoCommit(Connection conn) {
1693:                return false;
1694:            }
1695:
1696:            /**
1697:             * Retrieves the full version number of this database product. <p>
1698:             *
1699:             * @return database version number as a <code>String</code> object
1700:             * @since 1.8.0.4
1701:             */
1702:            public static String getDatabaseFullProductVersion() {
1703:                return HsqlDatabaseProperties.THIS_FULL_VERSION;
1704:            }
1705:
1706:            /**
1707:             * Retrieves the name of this database product. <p>
1708:             *
1709:             * @return database product name as a <code>String</code> object
1710:             * @since 1.7.2
1711:             */
1712:            public static String getDatabaseProductName() {
1713:                return HsqlDatabaseProperties.PRODUCT_NAME;
1714:            }
1715:
1716:            /**
1717:             * Retrieves the version number of this database product. <p>
1718:             *
1719:             * @return database version number as a <code>String</code> object
1720:             * @since 1.7.2
1721:             */
1722:            public static String getDatabaseProductVersion() {
1723:                return HsqlDatabaseProperties.THIS_VERSION;
1724:            }
1725:
1726:            /**
1727:             * Retrieves the major version number of this database. <p>
1728:             *
1729:             * @return the database's major version as an <code>int</code> value
1730:             * @since 1.7.2
1731:             */
1732:            public static int getDatabaseMajorVersion() {
1733:                return HsqlDatabaseProperties.MAJOR;
1734:            }
1735:
1736:            /**
1737:             * Retrieves the major version number of this database. <p>
1738:             *
1739:             * @return the database's major version as an <code>int</code> value
1740:             * @since 1.7.2
1741:             */
1742:            public static int getDatabaseMinorVersion() {
1743:                return HsqlDatabaseProperties.MINOR;
1744:            }
1745:
1746:            /**
1747:             * Retrieves whether this connection is in read-only mode. <p>
1748:             *
1749:             * Dummy mehtod.<p>
1750:             *
1751:             * @param conn the <code>Connection</code> object for which to retrieve
1752:             *      the current read-only status
1753:             * @return  <code>true</code> if connection is read-only and
1754:             *      <code>false</code> otherwise
1755:             * @since 1.7.2
1756:             */
1757:            public static boolean isReadOnlyConnection(Connection conn) {
1758:                return false;
1759:            }
1760:
1761:            /**
1762:             * Dummy method. Retrieves whether this database is in read-only mode. <p>
1763:             *
1764:             * @param c the <code>Connection</code> object for which to retrieve
1765:             *      the current database read-only status
1766:             * @return <code>true</code> if so; <code>false</code> otherwise
1767:             * @since 1.7.2
1768:             */
1769:            public static boolean isReadOnlyDatabase(Connection c) {
1770:                return false;
1771:            }
1772:
1773:            /**
1774:             * Retrieves whether the files of this database are in read-only mode. <p>
1775:             *
1776:             * Dummy mehtod.<p>
1777:             *
1778:             * @param c the <code>Connection</code> object for which to retrieve
1779:             *      the current database files read-only status
1780:             * @return <code>true</code> if so; <code>false</code> otherwise
1781:             * @since 1.7.2
1782:             */
1783:            public static boolean isReadOnlyDatabaseFiles(Connection c) {
1784:                return false;
1785:            }
1786:
1787:            static final int abs = 0;
1788:            static final int ascii = 1;
1789:            static final int bitand = 2;
1790:            static final int bitLength = 3;
1791:            static final int bitor = 4;
1792:            static final int bitxor = 5;
1793:            static final int character = 6;
1794:            static final int concat = 7;
1795:            static final int cot = 8;
1796:            static final int curdate = 9;
1797:            static final int curtime = 10;
1798:            static final int database = 11;
1799:            static final int datediff = 12;
1800:            static final int day = 13;
1801:            static final int dayname = 14;
1802:            static final int dayofmonth = 15;
1803:            static final int dayofweek = 16;
1804:            static final int dayofyear = 17;
1805:            static final int difference = 18;
1806:            static final int getAutoCommit = 19;
1807:            static final int getDatabaseFullProductVersion = 20;
1808:            static final int getDatabaseMajorVersion = 21;
1809:            static final int getDatabaseMinorVersion = 22;
1810:            static final int getDatabaseProductName = 23;
1811:            static final int getDatabaseProductVersion = 24;
1812:            static final int hexToRaw = 25;
1813:            static final int hour = 26;
1814:            static final int identity = 27;
1815:            static final int insert = 28;
1816:            static final int isReadOnlyConnection = 29;
1817:            static final int isReadOnlyDatabase = 30;
1818:            static final int isReadOnlyDatabaseFiles = 31;
1819:            static final int lcase = 32;
1820:            static final int left = 33;
1821:            static final int length = 34;
1822:            static final int locate = 35;
1823:            static final int log10 = 36;
1824:            static final int ltrim = 37;
1825:            static final int minute = 38;
1826:            static final int mod = 39;
1827:            static final int month = 40;
1828:            static final int monthname = 41;
1829:            static final int now = 42;
1830:            static final int octetLength = 43;
1831:            static final int pi = 44;
1832:            static final int position = 45;
1833:            static final int quarter = 46;
1834:            static final int rand = 47;
1835:            static final int rawToHex = 48;
1836:            static final int repeat = 49;
1837:            static final int replace = 50;
1838:            static final int right = 51;
1839:            static final int round = 52;
1840:            static final int roundMagic = 53;
1841:            static final int rtrim = 54;
1842:            static final int second = 55;
1843:            static final int sign = 56;
1844:            static final int soundex = 57;
1845:            static final int space = 58;
1846:            static final int substring = 59;
1847:            static final int to_char = 60;
1848:            static final int trim = 61;
1849:            static final int truncate = 62;
1850:            static final int ucase = 63;
1851:            static final int user = 64;
1852:            static final int week = 65;
1853:            static final int year = 66;
1854:
1855:            /** @todo  see bitxor and datediff numbering */
1856:
1857:            //
1858:            private static final IntValueHashMap functionMap = new IntValueHashMap(
1859:                    67);
1860:            static final Double piValue = new Double(Library.pi());
1861:
1862:            static {
1863:                functionMap.put("abs", abs);
1864:                functionMap.put("ascii", ascii);
1865:                functionMap.put("bitand", bitand);
1866:                functionMap.put("bitlength", bitLength);
1867:                functionMap.put("bitor", bitor);
1868:                functionMap.put("bitxor", bitor);
1869:                functionMap.put("character", character);
1870:                functionMap.put("concat", concat);
1871:                functionMap.put("cot", cot);
1872:                functionMap.put("curdate", curdate);
1873:                functionMap.put("curtime", curtime);
1874:                functionMap.put("database", database);
1875:                functionMap.put("datediff", datediff);
1876:                functionMap.put("dayname", dayname);
1877:                functionMap.put("day", day);
1878:                functionMap.put("dayofmonth", dayofmonth);
1879:                functionMap.put("dayofweek", dayofweek);
1880:                functionMap.put("dayofyear", dayofyear);
1881:                functionMap.put("difference", difference);
1882:                functionMap.put("getAutoCommit", getAutoCommit);
1883:                functionMap.put("getDatabaseFullProductVersion",
1884:                        getDatabaseFullProductVersion);
1885:                functionMap.put("getDatabaseMajorVersion",
1886:                        getDatabaseMajorVersion);
1887:                functionMap.put("getDatabaseMinorVersion",
1888:                        getDatabaseMinorVersion);
1889:                functionMap.put("getDatabaseProductName",
1890:                        getDatabaseProductName);
1891:                functionMap.put("getDatabaseProductVersion",
1892:                        getDatabaseProductVersion);
1893:                functionMap.put("hexToRaw", hexToRaw);
1894:                functionMap.put("hour", hour);
1895:                functionMap.put("identity", identity);
1896:                functionMap.put("insert", insert);
1897:                functionMap.put("isReadOnlyConnection", isReadOnlyConnection);
1898:                functionMap.put("isReadOnlyDatabase", isReadOnlyDatabase);
1899:                functionMap.put("isReadOnlyDatabaseFiles",
1900:                        isReadOnlyDatabaseFiles);
1901:                functionMap.put("lcase", lcase);
1902:                functionMap.put("left", left);
1903:                functionMap.put("length", length);
1904:                functionMap.put("locate", locate);
1905:                functionMap.put("log10", log10);
1906:                functionMap.put("ltrim", ltrim);
1907:                functionMap.put("minute", minute);
1908:                functionMap.put("mod", mod);
1909:                functionMap.put("month", month);
1910:                functionMap.put("monthname", monthname);
1911:                functionMap.put("now", now);
1912:                functionMap.put("octetLength", octetLength);
1913:                functionMap.put("pi", pi);
1914:                functionMap.put("position", position);
1915:                functionMap.put("quarter", quarter);
1916:                functionMap.put("rand", rand);
1917:                functionMap.put("rawToHex", rawToHex);
1918:                functionMap.put("repeat", repeat);
1919:                functionMap.put("replace", replace);
1920:                functionMap.put("right", right);
1921:                functionMap.put("round", round);
1922:                functionMap.put("roundMagic", roundMagic);
1923:                functionMap.put("rtrim", rtrim);
1924:                functionMap.put("second", second);
1925:                functionMap.put("sign", sign);
1926:                functionMap.put("soundex", soundex);
1927:                functionMap.put("space", space);
1928:                functionMap.put("substring", substring);
1929:                functionMap.put("to_char", to_char);
1930:                functionMap.put("trim", trim);
1931:                functionMap.put("truncate", truncate);
1932:                functionMap.put("ucase", ucase);
1933:                functionMap.put("user", user);
1934:                functionMap.put("week", week);
1935:                functionMap.put("year", year);
1936:            }
1937:
1938:            static Object invoke(int fID, Object[] params) throws HsqlException {
1939:
1940:                try {
1941:                    switch (fID) {
1942:
1943:                    case abs: {
1944:                        return new Double(Library.abs(((Number) params[0])
1945:                                .doubleValue()));
1946:                    }
1947:                    case ascii: {
1948:                        return ascii((String) params[0]);
1949:                    }
1950:                    case bitand: {
1951:                        return ValuePool.getInt(bitand(((Number) params[0])
1952:                                .intValue(), ((Number) params[1]).intValue()));
1953:                    }
1954:                    case bitLength: {
1955:                        return bitLength((String) params[0]);
1956:                    }
1957:                    case bitor: {
1958:                        return ValuePool.getInt(bitor(((Number) params[0])
1959:                                .intValue(), ((Number) params[1]).intValue()));
1960:                    }
1961:                    case bitxor: {
1962:                        return ValuePool.getInt(bitxor(((Number) params[0])
1963:                                .intValue(), ((Number) params[1]).intValue()));
1964:                    }
1965:                    case character: {
1966:                        return character(((Number) params[0]).intValue());
1967:                    }
1968:                    case concat: {
1969:                        return concat((String) params[0], (String) params[1]);
1970:                    }
1971:                    case cot: {
1972:                        return new Double(cot(((Number) params[0])
1973:                                .doubleValue()));
1974:                    }
1975:                    case curdate: {
1976:                        return null;
1977:                    }
1978:                    case curtime: {
1979:                        return null;
1980:                    }
1981:                    case database: {
1982:                        return null;
1983:                    }
1984:                    case datediff: {
1985:                        return datediff((String) params[0],
1986:                                (Timestamp) params[1], (Timestamp) params[2]);
1987:                    }
1988:                    case dayname: {
1989:                        return dayname((Date) params[0]);
1990:                    }
1991:                    case dayofmonth:
1992:                    case day: {
1993:                        return dayofmonth((Date) params[0]);
1994:                    }
1995:                    case dayofweek: {
1996:                        return dayofweek((Date) params[0]);
1997:                    }
1998:                    case dayofyear: {
1999:                        return dayofyear((Date) params[0]);
2000:                    }
2001:                    case difference: {
2002:                        return ValuePool.getInt(difference((String) params[0],
2003:                                (String) params[1]));
2004:                    }
2005:                    case getAutoCommit: {
2006:                        return null;
2007:                    }
2008:                    case getDatabaseFullProductVersion: {
2009:                        return getDatabaseFullProductVersion();
2010:                    }
2011:                    case getDatabaseMajorVersion: {
2012:                        return ValuePool.getInt(getDatabaseMajorVersion());
2013:                    }
2014:                    case getDatabaseMinorVersion: {
2015:                        return ValuePool.getInt(getDatabaseMinorVersion());
2016:                    }
2017:                    case getDatabaseProductName: {
2018:                        return getDatabaseProductName();
2019:                    }
2020:                    case getDatabaseProductVersion: {
2021:                        return getDatabaseProductVersion();
2022:                    }
2023:                    case hexToRaw: {
2024:                        return hexToRaw((String) params[0]);
2025:                    }
2026:                    case hour: {
2027:                        return hour((Time) params[0]);
2028:                    }
2029:                    case identity: {
2030:                        return null;
2031:                    }
2032:                    case insert: {
2033:                        return insert((String) params[0], ((Number) params[1])
2034:                                .intValue(), ((Number) params[2]).intValue(),
2035:                                (String) params[3]);
2036:                    }
2037:                    case isReadOnlyConnection: {
2038:                        return null;
2039:                    }
2040:                    case isReadOnlyDatabase: {
2041:                        return null;
2042:                    }
2043:                    case lcase: {
2044:                        return lcase((String) params[0]);
2045:                    }
2046:                    case left: {
2047:                        return left((String) params[0], ((Number) params[1])
2048:                                .intValue());
2049:                    }
2050:                    case length: {
2051:                        return length((String) params[0]);
2052:                    }
2053:                    case locate: {
2054:                        return ValuePool.getInt(locate((String) params[0],
2055:                                (String) params[1], (Integer) params[2]));
2056:                    }
2057:                    case log10: {
2058:                        return new Double(log10(((Number) params[0])
2059:                                .doubleValue()));
2060:                    }
2061:                    case ltrim: {
2062:                        return ltrim((String) params[0]);
2063:                    }
2064:                    case minute: {
2065:                        return minute((Time) params[0]);
2066:                    }
2067:                    case mod: {
2068:                        return ValuePool.getInt(mod(((Number) params[0])
2069:                                .intValue(), ((Number) params[1]).intValue()));
2070:                    }
2071:                    case month: {
2072:                        return month((Date) params[0]);
2073:                    }
2074:                    case monthname: {
2075:                        return ValuePool.getString(monthname((Date) params[0]));
2076:                    }
2077:                    case now: {
2078:                        return null;
2079:                    }
2080:                    case octetLength: {
2081:                        return octetLength((String) params[0]);
2082:                    }
2083:                    case position: {
2084:                        return ValuePool.getInt(position((String) params[0],
2085:                                (String) params[1]));
2086:                    }
2087:                    case pi: {
2088:                        return piValue;
2089:                    }
2090:                    case quarter: {
2091:                        return quarter((Date) params[0]);
2092:                    }
2093:                    case rand: {
2094:                        return new Double(rand((Integer) params[0]));
2095:                    }
2096:                    case rawToHex: {
2097:                        return rawToHex((String) params[0]);
2098:                    }
2099:                    case repeat: {
2100:                        return repeat((String) params[0], (Integer) params[1]);
2101:                    }
2102:                    case replace: {
2103:                        return replace((String) params[0], (String) params[1],
2104:                                (String) params[2]);
2105:                    }
2106:                    case right: {
2107:                        return right((String) params[0], ((Number) params[1])
2108:                                .intValue());
2109:                    }
2110:                    case round: {
2111:                        return new Double(
2112:                                round(((Number) params[0]).doubleValue(),
2113:                                        ((Number) params[1]).intValue()));
2114:                    }
2115:                    case roundMagic: {
2116:                        return new Double(roundMagic(((Number) params[0])
2117:                                .doubleValue()));
2118:                    }
2119:                    case rtrim: {
2120:                        return rtrim((String) params[0]);
2121:                    }
2122:                    case second: {
2123:                        return second((Time) params[0]);
2124:                    }
2125:                    case sign: {
2126:                        return ValuePool.getInt(sign(((Number) params[0])
2127:                                .doubleValue()));
2128:                    }
2129:                    case soundex: {
2130:                        return soundex((String) params[0]);
2131:                    }
2132:                    case space: {
2133:                        return space(((Number) params[0]).intValue());
2134:                    }
2135:                    case substring: {
2136:                        return substring((String) params[0],
2137:                                ((Number) params[1]).intValue(),
2138:                                (Integer) params[2]);
2139:                    }
2140:                    case trim: {
2141:                        return trim((String) params[0], (String) params[1],
2142:                                ((Boolean) params[2]).booleanValue(),
2143:                                ((Boolean) params[3]).booleanValue());
2144:                    }
2145:                    case truncate: {
2146:                        return new Double(
2147:                                truncate(((Number) params[0]).doubleValue(),
2148:                                        ((Number) params[1]).intValue()));
2149:                    }
2150:                    case ucase: {
2151:                        return ucase((String) params[0]);
2152:                    }
2153:                    case user: {
2154:                        return null;
2155:                    }
2156:                    case week: {
2157:                        return week((Date) params[0]);
2158:                    }
2159:                    case year: {
2160:                        return year((Date) params[0]);
2161:                    }
2162:                    case to_char: {
2163:                        return to_char((java.util.Date) params[0],
2164:                                (String) params[1]);
2165:                    }
2166:                    case isReadOnlyDatabaseFiles: {
2167:                        return null;
2168:                    }
2169:                    default: {
2170:
2171:                        // coding error
2172:                        Trace.doAssert(false);
2173:
2174:                        return null;
2175:                    }
2176:                    }
2177:                } catch (Exception e) {
2178:                    throw Trace.error(Trace.FUNCTION_CALL_ERROR, e.toString());
2179:                }
2180:            }
2181:
2182:            static final String prefix = "org.hsqldb.Library.";
2183:            static final int prefixLength = prefix.length();
2184:
2185:            static int functionID(String fname) {
2186:
2187:                return fname.startsWith(prefix) ? functionMap.get(fname
2188:                        .substring(prefixLength), -1) : -1;
2189:            }
2190:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.