Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/hsqldb/Library.java


1   /* Copyrights and Licenses
2    *
3    * This product includes Hypersonic SQL.
4    * Originally developed by Thomas Mueller and the Hypersonic SQL Group. 
5    *
6    * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved. 
7    * Redistribution and use in source and binary forms, with or without modification, are permitted
8    * provided that the following conditions are met: 
9    *     -  Redistributions of source code must retain the above copyright notice, this list of conditions
10   *         and the following disclaimer. 
11   *     -  Redistributions in binary form must reproduce the above copyright notice, this list of
12   *         conditions and the following disclaimer in the documentation and/or other materials
13   *         provided with the distribution. 
14   *     -  All advertising materials mentioning features or use of this software must display the
15   *        following acknowledgment: "This product includes Hypersonic SQL." 
16   *     -  Products derived from this software may not be called "Hypersonic SQL" nor may
17   *        "Hypersonic SQL" appear in their names without prior written permission of the
18   *         Hypersonic SQL Group. 
19   *     -  Redistributions of any form whatsoever must retain the following acknowledgment: "This
20   *          product includes Hypersonic SQL." 
21   * This software is provided "as is" and any expressed or implied warranties, including, but
22   * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
23   * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
24   * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
25   * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
26   * or business interruption). However caused any on any theory of liability, whether in contract,
27   * strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this
28   * software, even if advised of the possibility of such damage. 
29   * This software consists of voluntary contributions made by many individuals on behalf of the
30   * Hypersonic SQL Group.
31   *
32   *
33   * For work added by the HSQL Development Group:
34   *
35   * Copyright (c) 2001-2002, The HSQL Development Group
36   * All rights reserved.
37   *
38   * Redistribution and use in source and binary forms, with or without
39   * modification, are permitted provided that the following conditions are met:
40   *
41   * Redistributions of source code must retain the above copyright notice, this
42   * list of conditions and the following disclaimer, including earlier
43   * license statements (above) and comply with all above license conditions.
44   *
45   * Redistributions in binary form must reproduce the above copyright notice,
46   * this list of conditions and the following disclaimer in the documentation
47   * and/or other materials provided with the distribution, including earlier
48   * license statements (above) and comply with all above license conditions.
49   *
50   * Neither the name of the HSQL Development Group nor the names of its
51   * contributors may be used to endorse or promote products derived from this
52   * software without specific prior written permission.
53   *
54   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57   * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 
58   * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
59   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
60   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65   */
66  
67  
68  package org.hsqldb;
69  
70  import java.sql.SQLException;
71  import java.sql.Timestamp;
72  import java.sql.Connection;
73  import java.sql.ResultSet;
74  import java.sql.Statement;
75  import java.util.Calendar;
76  import java.util.GregorianCalendar;
77  import java.util.Hashtable;
78  import java.util.Random;
79  import java.text.SimpleDateFormat;
80  
81  /**
82   * Class declaration
83   *
84   *
85   * @version 1.7.0
86   */
87  
88  // fredt@users 20020210 - patch 513005 by sqlbob@users (RMP) - ABS function
89  // fredt@users 20020305 - patch 1.7.0 - change to 2D string arrays
90  // sqlbob@users 20020420- patch 1.7.0 - added HEXTORAW and RAWTOHEX.
91  class Library {
92  
93      static final String sNumeric[][] = {
94          {
95              "ABS", "org.hsqldb.Library.abs"
96          }, {
97              "ACOS", "java.lang.Math.acos"
98          }, {
99              "ASIN", "java.lang.Math.asin"
100         }, {
101             "ATAN", "java.lang.Math.atan"
102         }, {
103             "ATAN2", "java.lang.Math.atan2"
104         }, {
105             "CEILING", "java.lang.Math.ceil"
106         }, {
107             "COS", "java.lang.Math.cos"
108         }, {
109             "COT", "org.hsqldb.Library.cot"
110         }, {
111             "DEGREES", "java.lang.Math.toDegrees"
112         }, {
113             "EXP", "java.lang.Math.exp"
114         }, {
115             "FLOOR", "java.lang.Math.floor"
116         }, {
117             "LOG", "java.lang.Math.log"
118         }, {
119             "LOG10", "org.hsqldb.Library.log10"
120         }, {
121             "MOD", "org.hsqldb.Library.mod"
122         }, {
123             "PI", "org.hsqldb.Library.pi"
124         }, {
125             "POWER", "java.lang.Math.pow"
126         }, {
127             "RADIANS", "java.lang.Math.toRadians"
128         }, {
129             "RAND", "java.lang.Math.random"
130         }, {
131             "ROUND", "org.hsqldb.Library.round"
132         }, {
133             "SIGN", "org.hsqldb.Library.sign"
134         }, {
135             "SIN", "java.lang.Math.sin"
136         }, {
137             "SQRT", "java.lang.Math.sqrt"
138         }, {
139             "TAN", "java.lang.Math.tan"
140         }, {
141             "TRUNCATE", "org.hsqldb.Library.truncate"
142         }, {
143             "BITAND", "org.hsqldb.Library.bitand"
144         }, {
145             "BITOR", "org.hsqldb.Library.bitor"
146         }, {
147             "ROUNDMAGIC", "org.hsqldb.Library.roundMagic"
148         }
149     };
150 
151 // fredt@users 20010701 - patch 418023 by deforest@users
152 // the definition for SUBSTR was added
153     static final String sString[][]   = {
154         {
155             "ASCII", "org.hsqldb.Library.ascii"
156         }, {
157             "CHAR", "org.hsqldb.Library.character"
158         }, {
159             "CONCAT", "org.hsqldb.Library.concat"
160         }, {
161             "DIFFERENCE", "org.hsqldb.Library.difference"
162         }, {
163             "HEXTORAW", "org.hsqldb.Library.hexToRaw"
164         }, {
165             "INSERT", "org.hsqldb.Library.insert"
166         }, {
167             "LCASE", "org.hsqldb.Library.lcase"
168         }, {
169             "LEFT", "org.hsqldb.Library.left"
170         }, {
171             "LENGTH", "org.hsqldb.Library.length"
172         }, {
173             "LOCATE", "org.hsqldb.Library.locate"
174         }, {
175             "LTRIM", "org.hsqldb.Library.ltrim"
176         }, {
177             "RAWTOHEX", "org.hsqldb.Library.rawToHex"
178         }, {
179             "REPEAT", "org.hsqldb.Library.repeat"
180         }, {
181             "REPLACE", "org.hsqldb.Library.replace"
182         }, {
183             "RIGHT", "org.hsqldb.Library.right"
184         }, {
185             "RTRIM", "org.hsqldb.Library.rtrim"
186         }, {
187             "SOUNDEX", "org.hsqldb.Library.soundex"
188         }, {
189             "SPACE", "org.hsqldb.Library.space"
190         }, {
191             "SUBSTR", "org.hsqldb.Library.substring"
192         }, {
193             "SUBSTRING", "org.hsqldb.Library.substring"
194         }, {
195             "UCASE", "org.hsqldb.Library.ucase"
196         }, {
197             "LOWER", "org.hsqldb.Library.lcase"
198         }, {
199             "UPPER", "org.hsqldb.Library.ucase"
200         }
201     };
202     static final String sTimeDate[][] = {
203         {
204             "CURDATE", "org.hsqldb.Library.curdate"
205         }, {
206             "CURTIME", "org.hsqldb.Library.curtime"
207         }, {
208             "DAYNAME", "org.hsqldb.Library.dayname"
209         }, {
210             "DAYOFMONTH", "org.hsqldb.Library.dayofmonth"
211         }, {
212             "DAYOFWEEK", "org.hsqldb.Library.dayofweek"
213         }, {
214             "DAYOFYEAR", "org.hsqldb.Library.dayofyear"
215         }, {
216             "HOUR", "org.hsqldb.Library.hour"
217         }, {
218             "MINUTE", "org.hsqldb.Library.minute"
219         }, {
220             "MONTH", "org.hsqldb.Library.month"
221         }, {
222             "MONTHNAME", "org.hsqldb.Library.monthname"
223         }, {
224             "NOW", "org.hsqldb.Library.now"
225         }, {
226             "QUARTER", "org.hsqldb.Library.quarter"
227         }, {
228             "SECOND", "org.hsqldb.Library.second"
229         }, {
230             "WEEK", "org.hsqldb.Library.week"
231         }, {
232             "YEAR", "org.hsqldb.Library.year"
233         }
234     };
235     static final String sSystem[][]   = {
236         {
237             "DATABASE", "org.hsqldb.Library.database"
238         }, {
239             "USER", "org.hsqldb.Library.user"
240         }, {
241             "IDENTITY", "org.hsqldb.Library.identity"
242         }
243     };
244 
245     /**
246      * Method declaration
247      *
248      *
249      * @param h
250      */
251     static void register(Hashtable h) {
252 
253         register(h, sNumeric);
254         register(h, sString);
255         register(h, sTimeDate);
256         register(h, sSystem);
257     }
258 
259     /**
260      * Method declaration
261      *
262      *
263      * @param h
264      * @param s
265      */
266     private static void register(Hashtable h, String s[][]) {
267 
268         for (int i = 0; i < s.length; i++) {
269             h.put(s[i][0], s[i][1]);
270         }
271     }
272 
273     private static final Random rRandom = new Random();
274 
275     // NUMERIC
276 
277     /**
278      * Method declaration
279      *
280      *
281      * @param i
282      *
283      * @return
284      */
285 // fredt@users 20020220 - patch 489184 by xclayl@users - thread safety
286     public static synchronized double rand(Integer i) {
287 
288         if (i != null) {
289             rRandom.setSeed(i.intValue());
290         }
291 
292         return rRandom.nextDouble();
293     }
294 
295     /**
296      * Method declaration
297      *
298      *
299      * @param d
300      * @param p
301      *
302      * @return
303      */
304     public static double abs(double d) {
305         return Math.abs(d);
306     }
307 
308     // this magic number works for 100000000000000; but not for 0.1 and 0.01
309     private static final double LOG10_FACTOR = 0.43429448190325183;
310 
311     /**
312      * Method declaration
313      *
314      *
315      * @param x
316      *
317      * @return
318      */
319     public static double log10(double x) {
320         return roundMagic(Math.log(x) * LOG10_FACTOR);
321     }
322 
323     /**
324      * Method declaration
325      *
326      *
327      * @param d
328      *
329      * @return
330      */
331     public static double roundMagic(double d) {
332 
333         // this function rounds numbers in a good way but slow:
334         // - special handling for numbers around 0
335         // - only numbers <= +/-1000000000000
336         // - convert to a string
337         // - check the last 4 characters:
338         // '000x' becomes '0000'
339         // '999x' becomes '999999' (this is rounded automatically)
340         if ((d < 0.0000000000001) && (d > -0.0000000000001)) {
341             return 0.0;
342         }
343 
344         if ((d > 1000000000000.) || (d < -1000000000000.)) {
345             return d;
346         }
347 
348         StringBuffer s = new StringBuffer();
349 
350         s.append(d);
351 
352         int len = s.length();
353 
354         if (len < 16) {
355             return d;
356         }
357 
358         char cx = s.charAt(len - 1);
359         char c1 = s.charAt(len - 2);
360         char c2 = s.charAt(len - 3);
361         char c3 = s.charAt(len - 4);
362 
363         if ((c1 == '0') && (c2 == '0') && (c3 == '0') && (cx != '.')) {
364             s.setCharAt(len - 1, '0');
365         } else if ((c1 == '9') && (c2 == '9') && (c3 == '9') && (cx != '.')) {
366             s.setCharAt(len - 1, '9');
367             s.append('9');
368             s.append('9');
369         }
370 
371         return Double.valueOf(s.toString()).doubleValue();
372     }
373 
374     /**
375      * Method declaration
376      *
377      *
378      * @param d
379      *
380      * @return
381      */
382     public static double cot(double d) {
383         return 1. / Math.tan(d);
384     }
385 
386     /**
387      * Method declaration
388      *
389      *
390      * @param i1
391      * @param i2
392      *
393      * @return
394      */
395     public static int mod(int i1, int i2) {
396         return i1 % i2;
397     }
398 
399     /**
400      * Method declaration
401      *
402      *
403      * @return
404      */
405     public static double pi() {
406         return Math.PI;
407     }
408 
409     /**
410      * Method declaration
411      *
412      *
413      * @param d
414      * @param p
415      *
416      * @return
417      */
418     public static double round(double d, int p) {
419 
420         double f = Math.pow(10., p);
421 
422         return Math.round(d * f) / f;
423     }
424 
425     /**
426      * Method declaration
427      *
428      *
429      * @param d
430      *
431      * @return
432      */
433     public static int sign(double d) {
434 
435         return (d < 0) ? -1
436                        : ((d > 0) ? 1
437                                   : 0);
438     }
439 
440     /**
441      * Method declaration
442      *
443      *
444      * @param d
445      * @param p
446      *
447      * @return
448      */
449     public static double truncate(double d, int p) {
450 
451         double f = Math.pow(10., p);
452         double g = d * f;
453 
454         return ((d < 0) ? Math.ceil(g)
455                         : Math.floor(g)) / f;
456     }
457 
458     /**
459      * Method declaration
460      *
461      *
462      * @param i
463      * @param j
464      *
465      * @return
466      */
467     public static int bitand(int i, int j) {
468         return i & j;
469     }
470 
471     /**
472      * Method declaration
473      *
474      *
475      * @param i
476      * @param j
477      *
478      * @return
479      */
480     public static int bitor(int i, int j) {
481         return i | j;
482     }
483 
484     // STRING
485 
486     /**
487      * Method declaration
488      *
489      *
490      * @param s
491      *
492      * @return
493      */
494     public static Integer ascii(String s) {
495 
496         if ((s == null) || (s.length() == 0)) {
497             return null;
498         }
499 
500         return new Integer(s.charAt(0));
501     }
502 
503     /**
504      * Method declaration
505      *
506      *
507      * @param code
508      *
509      * @return
510      */
511     public static String character(int code) {
512         return String.valueOf((char) code);
513     }
514 
515     /**
516      * Method declaration
517      *
518      *
519      * @param s1
520      * @param s2
521      *
522      * @return
523      */
524     public static String concat(String s1, String s2) {
525 
526         if (s1 == null) {
527             if (s2 == null) {
528                 return null;
529             }
530 
531             return s2;
532         }
533 
534         if (s2 == null) {
535             return s1;
536         }
537 
538         return s1 + s2;
539     }
540 
541     /**
542      * Method declaration
543      *
544      *
545      * @param s1
546      * @param s2
547      *
548      * @return
549      */
550 
551 // fredt@users 20020305 - patch 460907 by fredt - soundex
552     public static int difference(String s1, String s2) {
553 
554         // todo: check if this is the standard algorithm
555         if ((s1 == null) || (s2 == null)) {
556             return 0;
557         }
558 
559         s1 = soundex(s1);
560         s2 = soundex(s2);
561 
562         int e = 0;
563 
564         for (int i = 0; i < 4; i++) {
565             if (s1.charAt(i) != s2.charAt(i)) {
566                 e++;
567             }
568         }
569 
570         return e;
571     }
572 
573     /**
574      * Method declaration
575      *
576      *
577      * @param s
578      *
579      * @return
580      */
581     public static String hexToRaw(String s) {
582 
583         char         raw;
584         StringBuffer to  = new StringBuffer();
585         int          len = s.length();
586 
587         if (len % 4 != 0) {
588             return null;
589         }
590 
591         for (int i = 0; i < len; i += 4) {
592             raw = (char) Integer.parseInt(s.substring(i, i + 4), 16);
593 
594             to.append(raw);
595         }
596 
597         return (to.toString());
598     }
599 
600     /**
601      * Method declaration
602      *
603      *
604      * @param s1
605      * @param start
606      * @param length
607      * @param s2
608      *
609      * @return
610      */
611     public static String insert(String s1, int start, int length, String s2) {
612 
613         if (s1 == null) {
614             return s2;
615         }
616 
617         if (s2 == null) {
618             return s1;
619         }
620 
621         int len1 = s1.length();
622         int len2 = s2.length();
623 
624         start--;
625 
626         if (start < 0 || length <= 0 || len2 == 0 || start > len1) {
627             return s1;
628         }
629 
630         if (start + length > len1) {
631             length = len1 - start;
632         }
633 
634         return s1.substring(0, start) + s2 + s1.substring(start + length);
635     }
636 
637     /**
638      * Method declaration
639      *
640      *
641      * @param s
642      *
643      * @return
644      */
645     public static String lcase(String s) {
646         return (s == null) ? null
647                            : s.toLowerCase();
648     }
649 
650     /**
651      * Method declaration
652      *
653      *
654      * @param s
655      * @param i
656      *
657      * @return
658      */
659     public static String left(String s, int i) {
660 
661         if (s == null) {
662             return null;
663         }
664 
665         return s.substring(0, ((i < 0) ? 0
666                                        : (i < s.length()) ? i
667                                                           : s.length()));
668     }
669 
670 // fredt@users - 20020819 - patch 595854 by thomasm@users
671 
672     /**
673      *  Method declaration
674      *
675      *
676      *  @param s
677      *
678      *  @return
679      */
680     public static Integer length(String s) {
681         return s == null ? null
682                          : new Integer(s.length());
683     }
684 
685     /**
686      * Method declaration
687      *
688      *
689      * @param search
690      * @param s
691      * @param start
692      *
693      * @return
694      */
695     public static int locate(String search, String s, Integer start) {
696 
697         if (s == null || search == null) {
698             return 0;
699         }
700 
701         int i = (start == null) ? 0
702                                 : start.intValue() - 1;
703 
704         return s.indexOf(search, (i < 0) ? 0
705                                          : i) + 1;
706     }
707 
708     /**
709      * Method declaration
710      *
711      *
712      * @param s
713      *
714      * @return
715      */
716     public static String ltrim(String s) {
717 
718         if (s == null) {
719             return s;
720         }
721 
722         int len = s.length(),
723             i   = 0;
724 
725         while (i < len && s.charAt(i) <= ' ') {
726             i++;
727         }
728 
729         return (i == 0) ? s
730                         : s.substring(i);
731     }
732 
733     /**
734      * Method declaration
735      *
736      *
737      * @param s
738      *
739      * @return
740      */
741     public static String rawToHex(String s) {
742 
743         char         from[] = s.toCharArray();
744         String       hex;
745         StringBuffer to = new StringBuffer();
746 
747         for (int i = 0; i < from.length; i++) {
748             hex = Integer.toHexString(from[i] & 0xffff);
749 
750             for (int j = hex.length(); j < 4; j++) {
751                 to.append('0');
752             }
753 
754             to.append(hex);
755         }
756 
757         return (to.toString());
758     }
759 
760     /**
761      * Method declaration
762      *
763      *
764      * @param s
765      * @param i
766      *
767      * @return
768      */
769     public static String repeat(String s, Integer count) {
770 
771         if (s == null || count == null || count.intValue() < 0) {
772             return null;
773         }
774 
775         int          i = count.intValue();
776         StringBuffer b = new StringBuffer(s.length() * i);
777 
778         while (i-- > 0) {
779             b.append(s);
780         }
781 
782         return b.toString();
783     }
784 
785 // fredt@users - 20020903 - patch 1.7.1 - bug fix to allow multiple replaces
786 
787     /**
788      * Method declaration
789      *
790      *
791      * @param s
792      * @param replace
793      * @param with
794      *
795      * @return
796      */
797     public static String replace(String s, String replace, String with) {
798 
799         if (s == null || replace == null) {
800             return s;
801         }
802 
803         if (with == null) {
804             with = "";
805         }
806 
807         StringBuffer b          = new StringBuffer();
808         int          start      = 0;
809         int          lenreplace = replace.length();
810 
811         while (true) {
812             int i = s.indexOf(replace, start);
813 
814             if (i == -1) {
815                 b.append(s.substring(start));
816 
817                 break;
818             }
819 
820             b.append(s.substring(start, i));
821             b.append(with);
822 
823             start = i + lenreplace;
824         }
825 
826         return b.toString();
827     }
828 
829     /**
830      * Method declaration
831      *
832      *
833      * @param s
834      * @param i
835      *
836      * @return
837      */
838     public static String right(String s, int i) {
839 
840         if (s == null) {
841             return null;
842         }
843 
844         i = s.length() - i;
845 
846         return s.substring((i < 0) ? 0
847                                    : (i < s.length()) ? i
848                                                       : s.length());
849     }
850 
851 // fredt@users 20020530 - patch 1.7.0 fredt - trim only the space character
852 
853     /**
854      * Method declaration
855      *
856      *
857      * @param s
858      *
859      * @return
860      */
861     public static String rtrim(String s) {
862 
863         if (s == null) {
864             return s;
865         }
866 
867         int endindex = s.length() - 1;
868         int i        = endindex;
869 
870         for (; i >= 0 && s.charAt(i) == ' '; i--) {}
871 
872         return i == endindex ? s
873                              : s.substring(0, i + 1);
874     }
875 
876 // fredt@users 20011010 - patch 460907 by fredt - soundex
877 
878     /**
879      * code was rewritten by fredt@users to comply with description at
880      * http://www.nara.gov/genealogy/coding.html
881      * non ASCCI characters in string are ignored
882      *
883      * @param s
884      *
885      * @return
886      */
887     public static String soundex(String s) {
888 
889         if (s == null) {
890             return s;
891         }
892 
893         s = s.toUpperCase();
894 
895         int  len       = s.length();
896         char b[]       = new char[] {
897             '0', '0', '0', '0'
898         };
899         char lastdigit = '0';
900 
901         for (int i = 0, j = 0; i < len && j < 4; i++) {
902             char c = s.charAt(i);
903             char newdigit;
904 
905             if ("AEIOUY".indexOf(c) != -1) {
906                 newdigit = '7';
907             } else if (c == 'H' || c == 'W') {
908                 newdigit = '8';
909             } else if ("BFPV".indexOf(c) != -1) {
910                 newdigit = '1';
911             } else if ("CGJKQSXZ".indexOf(c) != -1) {
912                 newdigit = '2';
913             } else if (c == 'D' || c == 'T') {
914                 newdigit = '3';
915             } else if (c == 'L') {
916                 newdigit = '4';
917             } else if (c == 'M' || c == 'N') {
918                 newdigit = '5';
919             } else if (c == 'R') {
920                 newdigit = '6';
921             } else {
922                 continue;
923             }
924 
925             if (j == 0) {
926                 b[j++]    = c;
927                 lastdigit = newdigit;
928             } else if (newdigit <= '6') {
929                 if (newdigit != lastdigit) {
930                     b[j++]    = newdigit;
931                     lastdigit = newdigit;
932                 }
933             } else if (newdigit == '7') {
934                 lastdigit = newdigit;
935             }
936         }
937 
938         return new String(b, 0, 4);
939     }
940 
941     /**
942      * Method declaration
943      *
944      *
945      * @param i
946      *
947      * @return
948      */
949     public static String space(int i) {
950 
951         if (i < 0) {
952             return null;
953         }
954 
955         char c[] = new char[i];
956 
957         while (i > 0) {
958             c[--i] = ' ';
959         }
960 
961         return new String(c);
962     }
963 
964     /**
965      * Method declaration
966      *
967      *
968      * @param s
969      * @param start
970      * @param length
971      *
972      * @return
973      */
974 
975 // fredt@users 20020210 - patch 500767 by adjbirch@users - modified
976     public static String substring(String s, int start, Integer length) {
977 
978         if (s == null) {
979             return null;
980         }
981 
982         int len = s.length();
983 
984         start--;
985 
986         start = (start > len) ? len
987                               : start;
988 
989         int l = len;
990 
991         if (length != null) {
992             l = length.intValue();
993         }
994 
995         if (start + l > len) {
996             l = len - start;
997         }
998 
999         return s.substring(start, start + l);
1000    }
1001
1002    /**
1003     * Method declaration
1004     *
1005     *
1006     * @param s
1007     *
1008     * @return
1009     */
1010    public static String ucase(String s) {
1011        return (s == null) ? null
1012                           : s.toUpperCase();
1013    }
1014
1015    // TIME AND DATE
1016
1017    /**
1018     * Method declaration
1019     *
1020     *
1021     * @return
1022     */
1023    public static java.sql.Date curdate() {
1024        return new java.sql.Date(System.currentTimeMillis());
1025    }
1026
1027    /**
1028     * Method declaration
1029     *
1030     *
1031     * @return
1032     */
1033    public static java.sql.Time curtime() {
1034        return new java.sql.Time(System.currentTimeMillis());
1035    }
1036
1037    /**
1038     * Method declaration
1039     *
1040     *
1041     * @param d
1042     *
1043     * @return
1044     */
1045    public static String dayname(java.sql.Date d) {
1046
1047        SimpleDateFormat f = new SimpleDateFormat("EEEE");
1048
1049        return f.format(d).toString();
1050    }
1051
1052    /**
1053     * Method declaration
1054     *
1055     *
1056     * @param d
1057     * @param part
1058     *
1059     * @return
1060     */
1061    private static int getDateTimePart(java.util.Date d, int part) {
1062
1063        Calendar c = new GregorianCalendar();
1064
1065        c.setTime(d);
1066
1067        return c.get(part);
1068    }
1069
1070    /**
1071     * Method declaration
1072     *
1073     *
1074     * @param t
1075     * @param part
1076     *
1077     * @return
1078     */
1079    private static int getTimePart(java.sql.Time t, int part) {
1080
1081        Calendar c = new GregorianCalendar();
1082
1083        c.setTime(t);
1084
1085        return c.get(part);
1086    }
1087
1088    /**
1089     * Method declaration
1090     *
1091     *
1092     * @param d
1093     *
1094     * @return
1095     */
1096    public static int dayofmonth(java.sql.Date d) {
1097        return getDateTimePart(d, Calendar.DAY_OF_MONTH);
1098    }
1099
1100    /**
1101     * Method declaration
1102     *
1103     *
1104     * @param d
1105     *
1106     * @return
1107     */
1108    public static int dayofweek(java.sql.Date d) {
1109        return getDateTimePart(d, Calendar.DAY_OF_WEEK);
1110    }
1111
1112    /**
1113     * Method declaration
1114     *
1115     *
1116     * @param d
1117     *
1118     * @return
1119     */
1120    public static int dayofyear(java.sql.Date d) {
1121        return getDateTimePart(d, Calendar.DAY_OF_YEAR);
1122    }
1123
1124    /**
1125     * Method declaration
1126     *
1127     *
1128     * @param t
1129     *
1130     * @return
1131     */
1132
1133// fredt@users 20020210 - patch 513005 by sqlbob@users (RMP) - hour
1134    public static int hour(java.sql.Time t) {
1135        return getDateTimePart(t, Calendar.HOUR_OF_DAY);
1136    }
1137
1138    /**
1139     * Method declaration
1140     *
1141     *
1142     * @param t
1143     *
1144     * @return
1145     */
1146    public static int minute(java.sql.Time t) {
1147        return getDateTimePart(t, Calendar.MINUTE);
1148    }
1149
1150// fredt@users 20020130 - patch 418017 by deforest@users - made optional
1151    private static int     sql_month     = 0;
1152    private static boolean sql_month_set = false;
1153
1154    static void setSqlMonth(boolean value) {
1155
1156        if (sql_month_set == false) {
1157            sql_month     = value ? 1
1158                                  : 0;
1159            sql_month_set = true;
1160        }
1161    }
1162
1163    /**
1164     * Method declaration
1165     *
1166     *
1167     * @param d
1168     *
1169     * @return
1170     */
1171    public static int month(java.sql.Date d) {
1172        return getDateTimePart(d, Calendar.MONTH) + sql_month;
1173    }
1174
1175    /**
1176     * Method declaration
1177     *
1178     *
1179     * @param d
1180     *
1181     * @return
1182     */
1183    public static String monthname(java.sql.Date d) {
1184
1185        SimpleDateFormat f = new SimpleDateFormat("MMMM");
1186
1187        return f.format(d).toString();
1188    }
1189
1190    /**
1191     * Method declaration
1192     *
1193     *
1194     * @return
1195     */
1196    public static Timestamp now() {
1197        return new Timestamp(System.currentTimeMillis());
1198    }
1199
1200    /**
1201     * Method declaration
1202     *
1203     *
1204     * @param d
1205     *
1206     * @return
1207     */
1208    public static int quarter(java.sql.Date d) {
1209        return (getDateTimePart(d, Calendar.MONTH) / 3) + 1;
1210    }
1211
1212    /**
1213     * Method declaration
1214     *
1215     *
1216     * @param d
1217     *
1218     * @return
1219     */
1220    public static int second(java.sql.Time d) {
1221        return getDateTimePart(d, Calendar.SECOND);
1222    }
1223
1224    /**
1225     * Method declaration
1226     *
1227     *
1228     * @param d
1229     *
1230     * @return
1231     */
1232    public static int week(java.sql.Date d) {
1233        return getDateTimePart(d, Calendar.WEEK_OF_YEAR);
1234    }
1235
1236    /**
1237     * Method declaration
1238     *
1239     *
1240     * @param d
1241     *
1242     * @return
1243     */
1244    public static int year(java.sql.Date d) {
1245        return getDateTimePart(d, Calendar.YEAR);
1246    }
1247
1248    // SYSTEM
1249
1250    /**
1251     * Method declaration
1252     *
1253     *
1254     * @param conn
1255     *
1256     * @return
1257     *
1258     * @throws SQLException
1259     */
1260    public static String database(Connection conn) throws SQLException {
1261
1262        Statement stat = conn.createStatement();
1263        String s =
1264            "SELECT Value FROM SYSTEM_CONNECTIONINFO WHERE KEY='DATABASE'";
1265        ResultSet r = stat.executeQuery(s);
1266
1267        r.next();
1268
1269        return r.getString(1);
1270    }
1271
1272    /**
1273     * Method declaration
1274     *
1275     *
1276     * @param conn
1277     *
1278     * @return
1279     *
1280     * @throws SQLException
1281     */
1282    public static String user(Connection conn) throws SQLException {
1283
1284        Statement stat = conn.createStatement();
1285        String s = "SELECT Value FROM SYSTEM_CONNECTIONINFO WHERE KEY='USER'";
1286        ResultSet r    = stat.executeQuery(s);
1287
1288        r.next();
1289
1290        return r.getString(1);
1291    }
1292
1293    /**
1294     * As of 1.7.1 this is a dummy function. The return value is supplied
1295     * by Function.java
1296     *
1297     * @return 0
1298     *
1299     * @throws SQLException
1300     */
1301    public static int identity() throws SQLException {
1302        return 0;
1303    }
1304
1305    public static boolean getAutoCommit(Connection c) {
1306
1307        // hsql always creates an INTERNAL connection for
1308        // such calls to Library, so this is garanteed
1309        // to return the value contained by the
1310        // connection's Session, for local or remote connections
1311        try {
1312            return c.getAutoCommit();
1313        } catch (SQLException e) {
1314            return false;
1315        }
1316    }
1317/*
1318// test for soundex
1319    public static void main (String argv[]){
1320        String [] names = {"Yyhiokkk","Washington","Lee","Gutierrez","Pfister","Jackson","Tymczak","Ashcraft","VanDeusen","Deusen","Van Deusen"};
1321        for (int i = 0 ; i < names.length; i++ ){
1322            System.out.print( names[i] + " : " + soundex(names[i] + "\n"));
1323        }
1324    }
1325*/
1326}