/* Copyright (c) 1995-2000, The Hypersonic SQL Group. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the Hypersonic SQL Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE HYPERSONIC SQL GROUP, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * on behalf of the Hypersonic SQL Group. * * * For work added by the HSQL Development Group: * * Copyright (c) 2001-2008, The HSQL Development Group * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the HSQL Development Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.hsqldb; import j2me.sql.Date; import j2me.sql.Time; import j2me.sql.Timestamp; import j2me.math.Number; import java.util.Calendar; import java.util.Random; import javax.microedition.io.Connection; import org.hsqldb.lib.HashMap; import org.hsqldb.lib.IntValueHashMap; import org.hsqldb.persist.HsqlDatabaseProperties; import org.hsqldb.store.ValuePool; // fredt@users 20020210 - patch 513005 by sqlbob@users (RMP) - ABS function // fredt@users 20020305 - patch 1.7.0 - change to 2D string arrays // sqlbob@users 20020420- patch 1.7.0 - added HEXTORAW and RAWTOHEX. // boucherb@user 20020918 - doc 1.7.2 - added JavaDoc and code comments // fredt@user 20021021 - doc 1.7.2 - modified JavaDoc // boucherb@users 20030201 - patch 1.7.2 - direct calls for org.hsqldb.Library // fredt@users - patch 1.8.0 - new functions added /** * fredt - todo - since the introduction of SQL built-in functions and * evaluation of several session-dependent methods outside this class, * several methods here are dummies. These methods are still reported in * system tables incorrectly as corresponding to the SQL function names. */ /** * Provides the HSQLDB implementation of standard Open Group SQL CLI * Extended Scalar Functions and other public HSQLDB SQL functions.
*
* All methods here that have a Connection parameter are dummies and should
* not be called from user supplied Java procedure or trigger code. Use real
* SQL functions should be called instead in these instances.
*
* Extensively rewritten and extended in successive versions of HSQLDB.
*
* @author Thomas Mueller (Hypersonic SQL Group)
* @version 1.8.0
* @since Hypersonic SQL
*/
public class Library {
/*static final SimpleDateFormat tocharFormat = new SimpleDateFormat();
static final SimpleDateFormat daynameFormat = new SimpleDateFormat("EEEE",
Locale.ENGLISH);
static final SimpleDateFormat monthnameFormat =
new SimpleDateFormat("MMMM", Locale.ENGLISH);
static final StringBuffer daynameBuffer = new StringBuffer();
static final StringBuffer monthnameBuffer = new StringBuffer();
static final FieldPosition monthPosition =
new FieldPosition(SimpleDateFormat.MONTH_FIELD);
static final FieldPosition dayPosition =
new FieldPosition(SimpleDateFormat.DAY_OF_WEEK_FIELD);*/
public static final String[][] sNumeric = {
{
"ABS", "org.hsqldb.Library.abs"
}, {
"ACOS", "javolution.lang.MathLib.acos"
}, {
"ASIN", "javolution.lang.MathLib.asin"
}, {
"ATAN", "javolution.lang.MathLib.atan"
}, {
"ATAN2", "javolution.lang.MathLib.atan2"
}, {
"CEILING", "java.lang.Math.ceil"
}, {
"COS", "java.lang.Math.cos"
}, {
"COT", "org.hsqldb.Library.cot"
}, {
"DEGREES", "java.lang.Math.toDegrees"
}, {
"EXP", "javolution.lang.MathLib.exp"
}, {
"FLOOR", "java.lang.Math.floor"
}, {
"LOG", "javolution.lang.MathLib.log"
}, {
"LOG10", "javolution.lang.MathLib.log10"
}, {
"MOD", "org.hsqldb.Library.mod"
}, {
"PI", "org.hsqldb.Library.pi"
}, {
"POWER", "javolution.lang.MathLib.pow"
}, {
"RADIANS", "java.lang.Math.toRadians"
}, {
"RAND", "java.lang.Math.random"
}, {
"ROUND", "org.hsqldb.Library.round"
}, {
"SIGN", "org.hsqldb.Library.sign"
}, {
"SIN", "java.lang.Math.sin"
}, {
"SQRT", "java.lang.Math.sqrt"
}, {
"TAN", "java.lang.Math.tan"
}, {
"TRUNCATE", "org.hsqldb.Library.truncate"
}, {
"BITAND", "org.hsqldb.Library.bitand"
}, {
"BITOR", "org.hsqldb.Library.bitor"
}, {
"BITXOR", "org.hsqldb.Library.bitxor"
}, {
"ROUNDMAGIC", "org.hsqldb.Library.roundMagic"
}
};
// fredt@users 20010701 - patch 418023 by deforest@users
// the definition for SUBSTR was added
public static final String[][] sString = {
{
"ASCII", "org.hsqldb.Library.ascii"
}, {
"BIT_LENGTH", "org.hsqldb.Library.bitLength"
}, {
"CHAR", "org.hsqldb.Library.character"
}, {
"CHAR_LENGTH", "org.hsqldb.Library.length"
}, {
"CHARACTER_LENGTH", "org.hsqldb.Library.length"
}, {
"CONCAT", "org.hsqldb.Library.concat"
}, {
"DIFFERENCE", "org.hsqldb.Library.difference"
}, {
"HEXTORAW", "org.hsqldb.Library.hexToRaw"
}, {
"INSERT", "org.hsqldb.Library.insert"
}, {
"LCASE", "org.hsqldb.Library.lcase"
}, {
"LEFT", "org.hsqldb.Library.left"
}, {
"LENGTH", "org.hsqldb.Library.length"
}, {
"LOCATE", "org.hsqldb.Library.locate"
}, {
"LTRIM", "org.hsqldb.Library.ltrim"
}, {
"OCTET_LENGTH", "org.hsqldb.Library.octetLength"
}, {
"RAWTOHEX", "org.hsqldb.Library.rawToHex"
}, {
"REPEAT", "org.hsqldb.Library.repeat"
}, {
"REPLACE", "org.hsqldb.Library.replace"
}, {
"RIGHT", "org.hsqldb.Library.right"
}, {
"RTRIM", "org.hsqldb.Library.rtrim"
}, {
"SOUNDEX", "org.hsqldb.Library.soundex"
}, {
"SPACE", "org.hsqldb.Library.space"
}, {
"SUBSTR", "org.hsqldb.Library.substring"
}, {
"SUBSTRING", "org.hsqldb.Library.substring"
}, {
"UCASE", "org.hsqldb.Library.ucase"
}, {
"LOWER", "org.hsqldb.Library.lcase"
}, {
"UPPER", "org.hsqldb.Library.ucase"
}
};
public static final String[][] sTimeDate = {
{
"CURDATE", "org.hsqldb.Library.curdate"
}, {
"CURTIME", "org.hsqldb.Library.curtime"
}, {
"DATEDIFF", "org.hsqldb.Library.datediff"
}, {
"DAYNAME", "org.hsqldb.Library.dayname"
}, {
"DAY", "org.hsqldb.Library.dayofmonth"
}, {
"DAYOFMONTH", "org.hsqldb.Library.dayofmonth"
}, {
"DAYOFWEEK", "org.hsqldb.Library.dayofweek"
}, {
"DAYOFYEAR", "org.hsqldb.Library.dayofyear"
}, {
"HOUR", "org.hsqldb.Library.hour"
}, {
"MINUTE", "org.hsqldb.Library.minute"
}, {
"MONTH", "org.hsqldb.Library.month"
}, {
"MONTHNAME", "org.hsqldb.Library.monthname"
}, {
"NOW", "org.hsqldb.Library.now"
}, {
"QUARTER", "org.hsqldb.Library.quarter"
}, {
"SECOND", "org.hsqldb.Library.second"
}, {
"WEEK", "org.hsqldb.Library.week"
}, {
"YEAR", "org.hsqldb.Library.year"
}, {
"TO_CHAR", "org.hsqldb.Library.to_char"
}
};
public static final String[][] sSystem = {
{
"DATABASE", "org.hsqldb.Library.database"
}, {
"USER", "org.hsqldb.Library.user"
}, {
"IDENTITY", "org.hsqldb.Library.identity"
}
};
private Library() {}
static HashMap getAliasMap() {
HashMap h = new HashMap(83, 1);
register(h, sNumeric);
register(h, sString);
register(h, sTimeDate);
register(h, sSystem);
return h;
}
private static void register(HashMap h, String[][] s) {
for (int i = 0; i < s.length; i++) {
h.put(s[i][0], s[i][1]);
}
}
private static final Random rRandom = new Random();
// NUMERIC FUNCTIONS
// fredt@users 20020220 - patch 489184 by xclayl@users - thread safety
/**
* Returns the next pseudorandom, uniformly distributed double
value
* between 0.0 and 1.0 from a single, system-wide random number generator's
* sequence, optionally re-seeding (and thus resetting) the generator sequence.
*
* If the seed value is null
, then the underlying random number
* generator retrieves the next value in its current sequence, else the seed
* alters the state of the generator object so as to be in exactly the same state
* as if it had just been created with the seed value.
* @param seed an optional parameter with which to reseed the underlying
* pseudorandom number generator
* @return the next pseudorandom, uniformly distributed double
value between
* 0.0 and 1.0
*/
public static double rand(Integer seed) {
// boucherb@users 20020918
// CHECKME: perhaps rRandom should be a member of Session,
// since otherwise connections are *not* guranteed to get the
// same pseudorandom sequence, given the same set of calls to this
// SQL function. This makes comparitive analysis difficult.
// In fact, rRandom will be shared across multiple in-process
// database instances, so it is not even guaranteed that the
// sole connection to one instance will get the same sequence given
// the same set of calls to this SQL function.
synchronized (rRandom) {
if (seed != null) {
rRandom.setSeed(seed.intValue());
}
return rRandom.nextDouble();
}
}
/**
* Returns the absolute value of the given double
value.
* @param d the number for which to determine the absolute value
* @return the absolute value of d
, as a double
*/
public static double abs(double d) {
return Math.abs(d);
}
// this magic number works for 100000000000000; but not for 0.1 and 0.01
//private static final double LOG10_FACTOR = 0.43429448190325183;
/**
* Returns the base 10 logarithm of the given double
value.
* @param x the value for which to calculate the base 10 logarithm
* @return the base 10 logarithm of x
, as a double
*/
public static double log10(double x) {
throw new java.lang.RuntimeException("NotImplemented");
//return roundMagic(Math.log(x) * LOG10_FACTOR);
}
/**
* Retrieves a magically rounded double value produced
* from the given double
value. This method provides special
* handling for numbers close to zero and performs rounding only for
* numbers within a specific range, returning precisely the given value
* if it does not lie in this range.
* * Special handling includes:
* *
String
form length greater than 16 returns
* input unchaged
* String
form with last four characters of '...000x' where
* x != '.' is converted to '...0000'
* String
form with last four characters of '...9999' is
* converted to '...999999'
* java.lang.Double.doubleValue
of the String
* form is returned
* double
value
* expressed in radians.
* @param d the angle, expressed in radians
* @return the cotangent
*/
public static double cot(double d) {
return 1. / Math.tan(d);
}
/**
* Returns the remainder (modulus) of the first given integer divided
* by the second.
*
* @param i1 the numerator
* @param i2 the divisor
* @return i1
% i2
, as an int
*/
public static int mod(int i1, int i2) {
return i1 % i2;
}
/**
* Returns the constant value, pi.
* @return pi as a double
value
*/
public static double pi() {
return Math.PI;
}
/**
* Returns the given double
value, rounded to the given
* int
places right of the decimal point. If
* the supplied rounding place value is negative, rounding is performed
* to the left of the decimal point, using its magnitude (absolute value).
* @param d the value to be rounded
* @param p the rounding place value
* @return d
rounded
*/
public static double round(double d, int p) {
/*double f = Math.pow(10., p);
return Math.round(d * f) / f;*/
throw new java.lang.RuntimeException("NotImplemented");
}
/**
* Returns an indicator of the sign of the given double
* value. If the value is less than zero, -1 is returned. If the value
* equals zero, 0 is returned. If the value is greater than zero, 1 is
* returned.
* @param d the value
* @return the sign of d
*/
public static int sign(double d) {
return (d < 0) ? -1
: ((d > 0) ? 1
: 0);
}
/**
* Returns the given double
value, truncated to
* the given int
places right of the decimal point.
* If the given place value is negative, the given double
* value is truncated to the left of the decimal point, using the
* magnitude (aboslute value) of the place value.
* @param d the value to truncate
* @param p the places left or right of the decimal point at which to
* truncate
* @return d
, truncated
*/
public static double truncate(double d, int p) {
/*
double f = Math.pow(10., p);
double g = d * f;
return ((d < 0) ? Math.ceil(g)
: Math.floor(g)) / f;*/
throw new java.lang.RuntimeException("NotImplemented");
}
/**
* Returns the bit-wise logical and of the given
* integer values.
* @param i the first value
* @param j the second value
* @return the bit-wise logical and of
* i
and j
*/
public static int bitand(int i, int j) {
return i & j;
}
/**
* Returns the bit-wise logical or of the given
* integer values.
*
* @param i the first value
* @param j the second value
* @return the bit-wise logical or of
* i
and j
*/
public static int bitor(int i, int j) {
return i | j;
}
/**
* Returns the bit-wise logical xor of the given
* integer values.
*
* @param i the first value
* @param j the second value
* @return the bit-wise logical xor of
* i
and j
*
* @since 1.8.0
*/
public static int bitxor(int i, int j) {
return i ^ j;
}
// STRING FUNCTIONS
/**
* Returns the Unicode code value of the leftmost character of
* s
as an int
. This is the same as the
* ASCII value if the string contains only ASCII characters.
* @param s the String
to evaluate
* @return the integer Unicode value of the
* leftmost character
*/
public static Integer ascii(String s) {
if ((s == null) || (s.length() == 0)) {
return null;
}
return ValuePool.getInt(s.charAt(0));
}
/**
* Returns the character string corresponding to the given ASCII
* (or Unicode) value.
*
* Note:
*
* In some SQL CLI
* implementations, a null
is returned if the range is outside 0..255.
* In HSQLDB, the corresponding Unicode character is returned
* unchecked.
* @param code the character code for which to return a String
* representation
* @return the String representation of the character
*/
public static String character(int code) {
return String.valueOf((char) code);
}
/**
* Returns a String
object that is the result of an
* concatenation of the given String
objects.
*
* When only one string is NULL, the result is different from that
* returned by an (string1 || string2) expression:
*
*
*
* @param s1 the first String
objects are null
, return
* null
* null
, return the other
* String
objects are non-null, return as a
* String
object the character sequence obtained by listing,
* in left to right order, the characters of the first string followed by
* the characters of the second
* String
* @param s2 the second String
* @return s1
concatentated with s2
*/
public static String concat(String s1, String s2) {
if (s1 == null) {
if (s2 == null) {
return null;
}
return s2;
}
if (s2 == null) {
return s1;
}
return s1.concat(s2);
}
/**
* Returns a count of the characters that do not match when comparing
* the 4 digit numeric SOUNDEX character sequences for the
* given String
objects. If either String
object is
* null
, zero is returned.
* @param s1 the first String
* @param s2 the second String
* @return the number of differences between the SOUNDEX
of
* s1
and the SOUNDEX
of s2
*/
// fredt@users 20020305 - patch 460907 by fredt - soundex
public static int difference(String s1, String s2) {
// todo: check if this is the standard algorithm
if ((s1 == null) || (s2 == null)) {
return 0;
}
s1 = soundex(s1);
s2 = soundex(s2);
int e = 0;
for (int i = 0; i < 4; i++) {
if (s1.charAt(i) != s2.charAt(i)) {
e++;
}
}
return e;
}
/**
* Converts a String
of hexidecimal digit characters to a raw
* binary value, represented as a String
.
*
* The given String
object must consist of a sequence of
* 4 digit hexidecimal character substrings.
If its length is not
* evenly divisible by 4, null
is returned. If any of
* its 4 character subsequences cannot be parsed as a
* 4 digit, base 16 value, then a NumberFormatException is thrown.
*
* This conversion has the effect of reducing the character count 4:1.
*
* @param s a String
of hexidecimal digit characters
* @return an equivalent raw binary value, represented as a
* String
*/
public static String hexToRaw(String s) {
if (s == null) {
return null;
}
char raw;
StringBuffer to = new StringBuffer();
int len = s.length();
if (len % 4 != 0) {
return null;
}
for (int i = 0; i < len; i += 4) {
raw = (char) Integer.parseInt(s.substring(i, i + 4), 16);
to.append(raw);
}
return (to.toString());
}
/**
* Returns a character sequence which is the result of writing the
* first length
number of characters from the second
* given String
over the first string. The start position
* in the first string where the characters are overwritten is given by
* start
.
* * Note: In order of precedence, boundry conditions are handled as * follows:
* *
String
is null, then the other is
* returned; the check starts with the first given String
.
* start
is less than one, s1
is returned
* length
is less than or equal to zero,
* s1
is returned
* s2
is zero, s1
is returned
* start
is greater than the length of s1
,
* s1
is returned
* length
is such that, taken together with
* start
, the indicated interval extends
* beyond the end of s1
, then the insertion is performed
* precisely as if upon a copy of s1
extended in length
* to just include the indicated interval
* String
into which to insert s2
* @param start the position, with origin one, at which to start the insertion
* @param length the number of characters in s1
to replace
* @param s2 the String
to insert into s1
* @return s2
inserted into s1
, as indicated
* by start
and length
and adjusted for
* boundry conditions
*/
public static String insert(String s1, int start, int length, String s2) {
if (s1 == null) {
return s2;
}
if (s2 == null) {
return s1;
}
int len1 = s1.length();
int len2 = s2.length();
start--;
if (start < 0 || length <= 0 || len2 == 0 || start > len1) {
return s1;
}
if (start + length > len1) {
length = len1 - start;
}
return s1.substring(0, start) + s2 + s1.substring(start + length);
}
/**
* Returns a copy of the given String
, with all upper case
* characters converted to lower case. This uses the default Java String
* conversion.
* @param s the String
from which to produce a lower case
* version
* @return a lower case version of s
*/
public static String lcase(String s) {
return (s == null) ? null
: s.toLowerCase();
}
/**
* Returns the leftmost count
characters from the given
* String
. * * Note: boundry conditions are handled in the following order of * precedence: * *
s
is null
, then null
* is returned
* count
is less than 1, then a zero-length
* String
is returned
* count
is greater than the length of s
,
* then a copy of s
is returned
* String
from which to retrieve the leftmost
* characters
* @param count the count of leftmost characters to retrieve
* @return the leftmost count
characters of s
*/
public static String left(String s, int count) {
if (s == null) {
return null;
}
return s.substring(0, ((count < 0) ? 0
: (count < s.length()) ? count
: s.length()));
}
// fredt@users - 20020819 - patch 595854 by thomasm@users
/**
* Returns the number of characters in the given String
.
* This includes trailing blanks.
*
* @param s the String
for which to determine length
* @return the length of s
, including trailing blanks
*/
public static Integer length(String s) {
return s == null ? null
: ValuePool.getInt(s.length());
}
/**
* Returns the number of bytes in the given String
.
* This includes trailing blanks.
*
* @param s the String
for which to determine the octet length
* @return the octet length of s
, including trailing blanks
* @since 1.7.2
*/
public static Integer octetLength(String s) {
return s == null ? null
: ValuePool.getInt(s.length() * 2);
}
/**
* Returns the number of bits in the given String
.
* This includes trailing blanks.
*
* @param s the String
for which to determine the bit length
* @return the bit length of s
, including trailing blanks
* @since 1.7.2
*/
public static Integer bitLength(String s) {
return s == null ? null
: ValuePool.getInt(s.length() * 16);
}
/**
* Returns the starting position of the first occurrence of
* the given search
String
object within
* the given String
object, s
.
*
* The search for the first occurrence of search
begins with
* the first character position in s
, unless the optional
* argument, start
, is specified (non-null). If
* start
is specified, the search begins with the character
* position indicated by the value of start
, where the
* first character position in s
is indicated by the value 1.
* If search
is not found within s
, the
* value 0 is returned.
* @param search the String
occurence to find in s
* @param s the String
within which to find the first
* occurence of search
* @param start the optional character position from which to start
* looking in s
* @return the one-based starting position of the first occurrence of
* search
within s
, or 0 if not found
*/
public static int locate(String search, String s, Integer start) {
if (s == null || search == null) {
return 0;
}
int i = (start == null) ? 0
: start.intValue() - 1;
return s.indexOf(search, (i < 0) ? 0
: i) + 1;
}
/**
* As locate but from start position l.
*
* @param search the String
occurence to find in s
* @param s the String
within which to find the first
* occurence of search
* @return the one-based starting position of the first occurrence of
* search
within s
, or 0 if not found
*/
public static int position(String search, String s) {
return locate(search, s, null);
}
/**
* Returns the characters of the given String
, with the
* leading spaces removed. Characters such as TAB are not removed.
*
* @param s the String
from which to remove the leading blanks
* @return the characters of the given String
, with the leading
* spaces removed
*/
public static String ltrim(String s) {
if (s == null) {
return s;
}
int len = s.length(),
i = 0;
while (i < len && s.charAt(i) <= ' ') {
i++;
}
return (i == 0) ? s
: s.substring(i);
}
/**
* Converts a raw binary value, as represented by the given
* String
, to the equivalent String
* of hexidecimal digit characters.
*
* This conversion has the effect of expanding the character count 1:4.
*
* @param s the raw binary value, as a String
* @return an equivalent String
of hexidecimal digit characters
*/
public static String rawToHex(String s) {
if (s == null) {
return null;
}
char[] from = s.toCharArray();
String hex;
StringBuffer to = new StringBuffer(4 * s.length());
for (int i = 0; i < from.length; i++) {
hex = Integer.toHexString(from[i] & 0xffff);
for (int j = hex.length(); j < 4; j++) {
to.append('0');
}
to.append(hex);
}
return (to.toString());
}
/**
* Returns a String
composed of the given String
,
* repeated count
times.
*
* @param s the String
to repeat
* @param count the number of repetitions
* @return the given String
, repeated count
times
*/
public static String repeat(String s, Integer count) {
if (s == null || count == null || count.intValue() < 0) {
return null;
}
int i = count.intValue();
StringBuffer b = new StringBuffer(s.length() * i);
while (i-- > 0) {
b.append(s);
}
return b.toString();
}
// fredt@users - 20020903 - patch 1.7.1 - bug fix to allow multiple replaces
/**
* Replaces all occurrences of replace
in s
* with the String
object: with
* @param s the target for replacement
* @param replace the substring(s), if any, in s
to replace
* @param with the value to substitute for replace
* @return s
, with all occurences of replace
* replaced by with
*/
public static String replace(String s, String replace, String with) {
if (s == null || replace == null) {
return s;
}
if (with == null) {
with = "";
}
StringBuffer b = new StringBuffer();
int start = 0;
int lenreplace = replace.length();
while (true) {
int i = s.indexOf(replace, start);
if (i == -1) {
b.append(s.substring(start));
break;
}
b.append(s.substring(start, i));
b.append(with);
start = i + lenreplace;
}
return b.toString();
}
/**
* Returns the rightmost count
characters of the given
* String
, s
.
* * Note: boundry conditions are handled in the following order of * precedence:
* *
s
is null
, null
is returned
* count
is less than one, a zero-length
* String
is returned
* count
is greater than the length of s
,
* a copy of s
is returned
* String
from which to retrieve the rightmost
* count
characters
* @param count the number of rightmost characters to retrieve
* @return the rightmost count
characters of s
*/
public static String right(String s, int count) {
if (s == null) {
return null;
}
count = s.length() - count;
return s.substring((count < 0) ? 0
: (count < s.length()) ? count
: s.length());
}
// fredt@users 20020530 - patch 1.7.0 fredt - trim only the space character
/**
* Returns the characters of the given String
, with trailing
* spaces removed.
* @param s the String
from which to remove the trailing blanks
* @return the characters of the given String
, with the
* trailing spaces removed
*/
public static String rtrim(String s) {
if (s == null) {
return s;
}
int endindex = s.length() - 1;
int i = endindex;
for (; i >= 0 && s.charAt(i) == ' '; i--) {}
return i == endindex ? s
: s.substring(0, i + 1);
}
/**
* Returns the character sequence s
, with the leading,
* trailing or both the leading and trailing occurences of the first
* character of the character sequence trimstr
removed. * * This method is in support of the standard SQL String function TRIM. * Ordinarily, the functionality of this method is accessed from SQL using * the following syntax:
* *
* <trim function> ::= TRIM <left paren> <trim operands> <right paren> * <trim operands> ::= [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source> * <trim source> ::= <character value expression> * <trim specification> ::= LEADING | TRAILING | BOTH * <trim character> ::= <character value expression> ** * @param s the string to trim * @param trimstr the character whose occurences will be removed * @param leading if true, remove leading occurences * @param trailing if true, remove trailing occurences * @return s, with the leading, trailing or both the leading and trailing * occurences of the first character of
trimstr
removed
* @since 1.7.2
*/
public static String trim(String s, String trimstr, boolean leading,
boolean trailing) {
if (s == null) {
return s;
}
int trim = trimstr.charAt(0);
int endindex = s.length();
if (trailing) {
for (--endindex; endindex >= 0 && s.charAt(endindex) == trim;
endindex--) {}
endindex++;
}
if (endindex == 0) {
return "";
}
int startindex = 0;
if (leading) {
while (startindex < endindex && s.charAt(startindex) == trim) {
startindex++;
}
}
if (startindex == 0 && endindex == s.length()) {
return s;
} else {
return s.substring(startindex, endindex);
}
}
// fredt@users 20011010 - patch 460907 by fredt - soundex
/**
* Returns a four character code representing the sound of the given
* String
. Non-ASCCI characters in the
* input String
are ignored. * * This method was * rewritten for HSQLDB by fredt@users to comply with the description at * * http://www.nara.gov/genealogy/coding.html.
* @param s the String
for which to calculate the 4 character
* SOUNDEX
value
* @return the 4 character SOUNDEX
value for the given
* String
*/
public static String soundex(String s) {
if (s == null) {
return s;
}
s = s.toUpperCase();//Locale.ENGLISH);
int len = s.length();
char[] b = new char[] {
'0', '0', '0', '0'
};
char lastdigit = '0';
for (int i = 0, j = 0; i < len && j < 4; i++) {
char c = s.charAt(i);
char newdigit;
if ("AEIOUY".indexOf(c) != -1) {
newdigit = '7';
} else if (c == 'H' || c == 'W') {
newdigit = '8';
} else if ("BFPV".indexOf(c) != -1) {
newdigit = '1';
} else if ("CGJKQSXZ".indexOf(c) != -1) {
newdigit = '2';
} else if (c == 'D' || c == 'T') {
newdigit = '3';
} else if (c == 'L') {
newdigit = '4';
} else if (c == 'M' || c == 'N') {
newdigit = '5';
} else if (c == 'R') {
newdigit = '6';
} else {
continue;
}
if (j == 0) {
b[j++] = c;
lastdigit = newdigit;
} else if (newdigit <= '6') {
if (newdigit != lastdigit) {
b[j++] = newdigit;
lastdigit = newdigit;
}
} else if (newdigit == '7') {
lastdigit = newdigit;
}
}
return new String(b, 0, 4);
}
/**
* Returns a String
consisting of count
spaces, or
* null
if count
is less than zero.
*
* @param count the number of spaces to produce
* @return a String
of count
spaces
*/
public static String space(int count) {
if (count < 0) {
return null;
}
char[] c = new char[count];
while (count > 0) {
c[--count] = ' ';
}
return new String(c);
}
/**
* Returns the characters from the given String
, starting at
* the indicated one-based start
position and extending the
* (optional) indicated length
. If length
is not
* specified (is null
), the remainder of s
is
* implied.
*
* The rules for boundary conditions on s, start and length are,
* in order of precedence:
*
* 1.) if s is null, return null
*
* 2.) If length is less than 1, return null.
*
* 3.) If start is 0, it is treated as 1.
*
* 4.) If start is positive, count from the beginning of s to find
* the first character postion.
*
* 5.) If start is negative, count backwards from the end of s
* to find the first character.
*
* 6.) If, after applying 2.) or 3.), the start position lies outside s,
* then return null
*
* 7.) if length is ommited or is greated than the number of characters
* from the start position to the end of s, return the remaineder of s,
* starting with the start position.
*
* @param s the String
from which to produce the indicated
* substring
* @param start the starting position of the desired substring
* @param length the length of the desired substring
* @return the indicted substring of s
.
*/
// fredt@users 20020210 - patch 500767 by adjbirch@users - modified
// boucherb@users 20050205 - patch to correct bug 1107477
public static String substring(final String s, int start,
final Integer length) {
if (s == null) {
return null;
}
int sl = s.length();
int ol = (length == null) ? sl
: length.intValue();
if (ol < 1) {
return null;
}
if (start < 0) {
start = sl + start;
} else if (start > 0) {
start--;
}
if (start < 0 || start >= sl) {
return null;
} else if (start > sl - ol) {
ol = sl - start;
}
return s.substring(start, start + ol);
}
/**
* Returns a copy of the given String
, with all lower case
* characters converted to upper case using the default Java method.
* @param s the String
from which to produce an upper case
* version
* @return an upper case version of s
*/
public static String ucase(String s) {
return (s == null) ? null
: s.toUpperCase();
}
// TIME AND DATE
/**
* Returns the current date as a date value.
* * Dummy mehtod.
* * @return a date value representing the current date */ public static Date curdate(Connection c) { return null; } /** * Returns the current local time as a time value.
* * Dummy mehtod.
*
* @return a time value representing the current local time
*/
public static Time curtime(Connection c) {
return null;
}
/**
* Returns a character string containing the name of the day
* (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday )
* for the day portion of the given java.sql.Date
.
* @param d the date value from which to extract the day name
* @return the name of the day corresponding to the given
* java.sql.Date
*/
public static String dayname(Date d) {
/* if (d == null) {
return null;
}
synchronized (daynameBuffer) {
daynameBuffer.setLength(0);
return daynameFormat.format(d, daynameBuffer,
dayPosition).toString();
}*/
throw new java.lang.RuntimeException("NotImplemented");
}
/**
* Returns the day of the month from the given date value, as an integer
* value in the range of 1-31.
*
* @param d the date value from which to extract the day of month
* @return the day of the month from the given date value
*/
public static Integer dayofmonth(Date d) {
if (d == null) {
return null;
}
return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
Calendar.DAY_OF_MONTH));
}
/**
* Returns the day of the week from the given date value, as an integer
* value in the range 1-7, where 1 represents Sunday.
*
* @param d the date value from which to extract the day of week
* @return the day of the week from the given date value
*/
public static Integer dayofweek(Date d) {
if (d == null) {
return null;
}
return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
Calendar.DAY_OF_WEEK));
}
/**
* Returns the day of the year from the given date value, as an integer
* value in the range 1-366.
*
* @param d the date value from which to extract the day of year
* @return the day of the year from the given date value
*/
public static Integer dayofyear(Date d) {
/*
if (d == null) {
return null;
}
return ValuePool.getInt(HsqlDateTime.getDateTimePart(d,
Calendar.DAY_OF_YEAR));*/
throw new java.lang.RuntimeException("NotImplemented");
}
/**
* Returns the hour from the given time value, as an integer value in
* the range of 0-23.
*
* @param t the time value from which to extract the hour of day
* @return the hour of day from the given time value
*/
// fredt@users 20020210 - patch 513005 by sqlbob@users (RMP) - hour
public static Integer hour(Time t) {
if (t == null) {
return null;
}
return ValuePool.getInt(HsqlDateTime.getDateTimePart(t,
Calendar.HOUR_OF_DAY));
}
/**
* Returns the minute from the given time value, as integer value in
* the range of 0-59.
*
* @param t the time value from which to extract the minute value
* @return the minute value from the given time value
*/
public static Integer minute(Time t) {
if (t == null) {
return null;
}
return ValuePool.getInt(HsqlDateTime.getDateTimePart(t,
Calendar.MINUTE));
}
/**
* Returns the month from the given date value, as an integer value in the
* range of 1-12.
* * The sql_month database property is now obsolete. * The function always returns the SQL (1-12) value for month. * * @param d the date value from which to extract the month value * @return the month value from the given date value */ public static Integer month(Date d) { if (d == null) { return null; } return ValuePool.getInt( HsqlDateTime.getDateTimePart(d, Calendar.MONTH) + 1); } /** * Returns a character string containing the name of month * (January, February, March, April, May, June, July, August, * September, October, November, December) for the month portion of * the given date value. * * @param d the date value from which to extract the month name * @return a String representing the month name from the given date value */ public static String monthname(Date d) { /* if (d == null) { return null; } synchronized (monthnameBuffer) { monthnameBuffer.setLength(0); return monthnameFormat.format(d, monthnameBuffer, monthPosition).toString(); }*/ throw new java.lang.RuntimeException("NotImplemented"); } /** * Returns the current date and time as a timestamp value.
* * Dummy mehtod.
* * @return a timestamp value representing the current date and time */ public static Timestamp now(Connection c) { return null; } /** * Returns the quarter of the year in the given date value, as an integer * value in the range of 1-4.
* * @param d the date value from which to extract the quarter of the year * @return an integer representing the quater of the year from the given * date value */ public static Integer quarter(Date d) { if (d == null) { return null; } return ValuePool.getInt( (HsqlDateTime.getDateTimePart(d, Calendar.MONTH) / 3) + 1); } /** * Returns the second of the given time value, as an integer value in * the range of 0-59. * * @param d the date value from which to extract the second of the hour * @return an integer representing the second of the hour from the * given time value */ public static Integer second(Time d) { if (d == null) { return null; } return ValuePool.getInt(HsqlDateTime.getDateTimePart(d, Calendar.SECOND)); } /** * Returns the week of the year from the given date value, as an integer * value in the range of 1-53.
* * @param d the date value from which to extract the week of the year * @return an integer representing the week of the year from the given * date value */ public static Integer week(Date d) { /* if (d == null) { return null; } return ValuePool.getInt(HsqlDateTime.getDateTimePart(d, Calendar.WEEK_OF_YEAR));*/ throw new java.lang.RuntimeException("NotImplemented"); } /** * Returns the year from the given date value, as an integer value in * the range of 1-9999.
* * @param d the date value from which to extract the year * @return an integer value representing the year from the given * date value */ public static Integer year(Date d) { if (d == null) { return null; } return ValuePool.getInt(HsqlDateTime.getDateTimePart(d, Calendar.YEAR)); } /** * @since 1.8.0 */ public static String to_char(java.util.Date d, String format) { /* if (d == null || format == null) { return null; } synchronized (tocharFormat) { tocharFormat.applyPattern(HsqlDateTime.toJavaDatePattern(format)); return tocharFormat.format(d); }*/ throw new java.lang.RuntimeException("NotImplemented"); } // date calculations. /** * Returns the number of units elapsed between two dates.
* The datapart parameter indicates the part to be used for computing the * difference. Supported types include: 'year', 'yy', 'month', 'mm' * 'day', 'dd', 'hour', 'hh', 'minute', 'mi', 'second', 'ss', 'millisecond', * 'ms'. * * Contributed by Michael Landon
* * @param datepart Specifies the unit in which the interval is to be measured. * @param d1 The starting datetime value for the interval. This value is * subtracted from d2 to return the number of * date-parts between the two arguments. * @param d2 The ending datetime for the interval. d1 is subtracted * from this value to return the number of date-parts * between the two arguments. * * since 1.7.3 */ public static Long datediff(String datepart, Timestamp d1, Timestamp d2) throws HsqlException { // make sure we've got valid data if (d1 == null || d2 == null) { return null; } if ("yy".equalsIgnoreCase(datepart) || "year".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.YEAR, d1, d2)); } else if ("mm".equalsIgnoreCase(datepart) || "month".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.MONTH, d1, d2)); } else if ("dd".equalsIgnoreCase(datepart) || "day".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.DATE, d1, d2)); } else if ("hh".equalsIgnoreCase(datepart) || "hour".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.HOUR, d1, d2)); } else if ("mi".equalsIgnoreCase(datepart) || "minute".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.MINUTE, d1, d2)); } else if ("ss".equalsIgnoreCase(datepart) || "second".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.SECOND, d1, d2)); } else if ("ms".equalsIgnoreCase(datepart) || "millisecond".equalsIgnoreCase(datepart)) { return ValuePool.getLong(getElapsed(Calendar.MILLISECOND, d1, d2)); } else { throw Trace.error(Trace.INVALID_CONVERSION); } } /** * Private method used to do actual calculation units elapsed between * two given dates.
* * @param field Calendar field to use to calculate elapsed time * @param d1 The starting date for the interval. This value is * subtracted from d2 to return the number of * date-parts between the two arguments. * @param d2 The ending date for the interval. d1 is subtracted * from this value to return the number of date-parts * between the two arguments. */ private static long getElapsed(int field, java.util.Date d1, java.util.Date d2) { // can we do this very simply? if (field == Calendar.MILLISECOND) { return d2.getTime() - d1.getTime(); } // ok, let's work a little harder: Calendar g1 = Calendar.getInstance(), g2 = Calendar.getInstance(); g1.setTime(d1); g2.setTime(d2); g1.set(Calendar.MILLISECOND, 0); g2.set(Calendar.MILLISECOND, 0); if (field == Calendar.SECOND) { return (g2.getTime().getTime() - g1.getTime().getTime()) / 1000; } g1.set(Calendar.SECOND, 0); g2.set(Calendar.SECOND, 0); if (field == Calendar.MINUTE) { return (g2.getTime().getTime() - g1.getTime().getTime()) / (1000 * 60); } g1.set(Calendar.MINUTE, 0); g2.set(Calendar.MINUTE, 0); if (field == Calendar.HOUR) { return (g2.getTime().getTime() - g1.getTime().getTime()) / (1000 * 60 * 60); } // end if-else throw new java.lang.RuntimeException("NotImplemented"); /* // if we got here, then we really need to work: long elapsed = 0; short sign = 1; if (g2.before(g1)) { sign = -1; Calendar tmp = g1; g1 = g2; g2 = tmp; } // end if g1.set(Calendar.HOUR_OF_DAY, 0); g2.set(Calendar.HOUR_OF_DAY, 0); if (field == Calendar.MONTH || field == Calendar.YEAR) { g1.set(Calendar.DATE, 1); g2.set(Calendar.DATE, 1); } if (field == Calendar.YEAR) { g1.set(Calendar.MONTH, 1); g2.set(Calendar.MONTH, 1); } // end if-else // then calculate elapsed units while (g1.before(g2)) { g1.add(field, 1); elapsed++; } return sign * elapsed;*/ } // end getElapsed // SYSTEM /* * All system functions that return Session dependent information are * dummies here. */ /** * Returns the name of the database corresponding to this connection. * * @param conn the connection for which to retrieve the database name * @return the name of the database for the given connection * @throws HsqlException if a database access error occurs */ public static String database(Connection conn) throws HsqlException { return null; } /** * Returns the user's authorization name (the user's name as known to this * database). * * @param conn the connection for which to retrieve the user name * @return the user's name as known to the database * @throws HsqlException if a database access error occurs */ public static String user(Connection conn) throws HsqlException { return null; } /** * Retrieves the last auto-generated integer indentity value * used by this connection.
* * Dummy mehtod.
* * @return the connection's the last generated integer identity value * @throws HsqlException if a database access error occurs */ public static int identity() throws HsqlException { return 0; } // JDBC SYSTEM /** * Retrieves the autocommit status of this connection.
*
* @param conn the Connection
object for which to retrieve
* the current autocommit status
* @return a boolean value representing the connection's autocommit status
* @since 1.7.0
*/
public static boolean getAutoCommit(Connection conn) {
return false;
}
/**
* Retrieves the full version number of this database product.
*
* @return database version number as a String
object
* @since 1.8.0.4
*/
public static String getDatabaseFullProductVersion() {
return HsqlDatabaseProperties.THIS_FULL_VERSION;
}
/**
* Retrieves the name of this database product.
*
* @return database product name as a String
object
* @since 1.7.2
*/
public static String getDatabaseProductName() {
return HsqlDatabaseProperties.PRODUCT_NAME;
}
/**
* Retrieves the version number of this database product.
*
* @return database version number as a String
object
* @since 1.7.2
*/
public static String getDatabaseProductVersion() {
return HsqlDatabaseProperties.THIS_VERSION;
}
/**
* Retrieves the major version number of this database.
*
* @return the database's major version as an int
value
* @since 1.7.2
*/
public static int getDatabaseMajorVersion() {
return HsqlDatabaseProperties.MAJOR;
}
/**
* Retrieves the major version number of this database.
*
* @return the database's major version as an int
value
* @since 1.7.2
*/
public static int getDatabaseMinorVersion() {
return HsqlDatabaseProperties.MINOR;
}
/**
* Retrieves whether this connection is in read-only mode.
* * Dummy mehtod.
*
* @param conn the Connection
object for which to retrieve
* the current read-only status
* @return true
if connection is read-only and
* false
otherwise
* @since 1.7.2
*/
public static boolean isReadOnlyConnection(Connection conn) {
return false;
}
/**
* Dummy method. Retrieves whether this database is in read-only mode.
*
* @param c the Connection
object for which to retrieve
* the current database read-only status
* @return true
if so; false
otherwise
* @since 1.7.2
*/
public static boolean isReadOnlyDatabase(Connection c) {
return false;
}
/**
* Retrieves whether the files of this database are in read-only mode.
* * Dummy mehtod.
*
* @param c the Connection
object for which to retrieve
* the current database files read-only status
* @return true
if so; false
otherwise
* @since 1.7.2
*/
public static boolean isReadOnlyDatabaseFiles(Connection c) {
return false;
}
static final int abs = 0;
static final int ascii = 1;
static final int bitand = 2;
static final int bitLength = 3;
static final int bitor = 4;
static final int bitxor = 5;
static final int character = 6;
static final int concat = 7;
static final int cot = 8;
static final int curdate = 9;
static final int curtime = 10;
static final int database = 11;
static final int datediff = 12;
static final int day = 13;
static final int dayname = 14;
static final int dayofmonth = 15;
static final int dayofweek = 16;
static final int dayofyear = 17;
static final int difference = 18;
static final int getAutoCommit = 19;
static final int getDatabaseFullProductVersion = 20;
static final int getDatabaseMajorVersion = 21;
static final int getDatabaseMinorVersion = 22;
static final int getDatabaseProductName = 23;
static final int getDatabaseProductVersion = 24;
static final int hexToRaw = 25;
static final int hour = 26;
static final int identity = 27;
static final int insert = 28;
static final int isReadOnlyConnection = 29;
static final int isReadOnlyDatabase = 30;
static final int isReadOnlyDatabaseFiles = 31;
static final int lcase = 32;
static final int left = 33;
static final int length = 34;
static final int locate = 35;
static final int log10 = 36;
static final int ltrim = 37;
static final int minute = 38;
static final int mod = 39;
static final int month = 40;
static final int monthname = 41;
static final int now = 42;
static final int octetLength = 43;
static final int pi = 44;
static final int position = 45;
static final int quarter = 46;
static final int rand = 47;
static final int rawToHex = 48;
static final int repeat = 49;
static final int replace = 50;
static final int right = 51;
static final int round = 52;
static final int roundMagic = 53;
static final int rtrim = 54;
static final int second = 55;
static final int sign = 56;
static final int soundex = 57;
static final int space = 58;
static final int substring = 59;
static final int to_char = 60;
static final int trim = 61;
static final int truncate = 62;
static final int ucase = 63;
static final int user = 64;
static final int week = 65;
static final int year = 66;
/** @todo see bitxor and datediff numbering */
//
private static final IntValueHashMap functionMap =
new IntValueHashMap(67);
static final Double piValue = new Double(Library.pi());
static {
functionMap.put("abs", abs);
functionMap.put("ascii", ascii);
functionMap.put("bitand", bitand);
functionMap.put("bitlength", bitLength);
functionMap.put("bitor", bitor);
functionMap.put("bitxor", bitor);
functionMap.put("character", character);
functionMap.put("concat", concat);
functionMap.put("cot", cot);
functionMap.put("curdate", curdate);
functionMap.put("curtime", curtime);
functionMap.put("database", database);
functionMap.put("datediff", datediff);
functionMap.put("dayname", dayname);
functionMap.put("day", day);
functionMap.put("dayofmonth", dayofmonth);
functionMap.put("dayofweek", dayofweek);
functionMap.put("dayofyear", dayofyear);
functionMap.put("difference", difference);
functionMap.put("getAutoCommit", getAutoCommit);
functionMap.put("getDatabaseFullProductVersion",
getDatabaseFullProductVersion);
functionMap.put("getDatabaseMajorVersion", getDatabaseMajorVersion);
functionMap.put("getDatabaseMinorVersion", getDatabaseMinorVersion);
functionMap.put("getDatabaseProductName", getDatabaseProductName);
functionMap.put("getDatabaseProductVersion",
getDatabaseProductVersion);
functionMap.put("hexToRaw", hexToRaw);
functionMap.put("hour", hour);
functionMap.put("identity", identity);
functionMap.put("insert", insert);
functionMap.put("isReadOnlyConnection", isReadOnlyConnection);
functionMap.put("isReadOnlyDatabase", isReadOnlyDatabase);
functionMap.put("isReadOnlyDatabaseFiles", isReadOnlyDatabaseFiles);
functionMap.put("lcase", lcase);
functionMap.put("left", left);
functionMap.put("length", length);
functionMap.put("locate", locate);
functionMap.put("log10", log10);
functionMap.put("ltrim", ltrim);
functionMap.put("minute", minute);
functionMap.put("mod", mod);
functionMap.put("month", month);
functionMap.put("monthname", monthname);
functionMap.put("now", now);
functionMap.put("octetLength", octetLength);
functionMap.put("pi", pi);
functionMap.put("position", position);
functionMap.put("quarter", quarter);
functionMap.put("rand", rand);
functionMap.put("rawToHex", rawToHex);
functionMap.put("repeat", repeat);
functionMap.put("replace", replace);
functionMap.put("right", right);
functionMap.put("round", round);
functionMap.put("roundMagic", roundMagic);
functionMap.put("rtrim", rtrim);
functionMap.put("second", second);
functionMap.put("sign", sign);
functionMap.put("soundex", soundex);
functionMap.put("space", space);
functionMap.put("substring", substring);
functionMap.put("to_char", to_char);
functionMap.put("trim", trim);
functionMap.put("truncate", truncate);
functionMap.put("ucase", ucase);
functionMap.put("user", user);
functionMap.put("week", week);
functionMap.put("year", year);
}
static Object invoke(int fID, Object[] params) throws HsqlException {
try {
switch (fID) {
case abs : {
return new Double(
Library.abs( Number.doubleValue(params[0]) ) );
}
case ascii : {
return ascii((String) params[0]);
}
case bitand : {
return ValuePool.getInt(
bitand( Number.intValue(params[0]),
Number.intValue(params[1]) ) );
}
case bitLength : {
return bitLength((String) params[0]);
}
case bitor : {
return ValuePool.getInt(
bitor( Number.intValue(params[0]),
Number.intValue(params[1]) ) );
}
case bitxor : {
return ValuePool.getInt(
bitxor(Number.intValue(params[0]),
Number.intValue(params[1])));
}
case character : {
return character(Number.intValue(params[0]));
}
case concat : {
return concat((String) params[0], (String) params[1]);
}
case cot : {
return new Double(
cot(Number.doubleValue(params[0])));
}
case curdate : {
return null;
}
case curtime : {
return null;
}
case database : {
return null;
}
case datediff : {
return datediff((String) params[0],
(Timestamp) params[1],
(Timestamp) params[2]);
}
case dayname : {
return dayname((Date) params[0]);
}
case dayofmonth :
case day : {
return dayofmonth((Date) params[0]);
}
case dayofweek : {
return dayofweek((Date) params[0]);
}
case dayofyear : {
return dayofyear((Date) params[0]);
}
case difference : {
return ValuePool.getInt(difference((String) params[0],
(String) params[1]));
}
case getAutoCommit : {
return null;
}
case getDatabaseFullProductVersion : {
return getDatabaseFullProductVersion();
}
case getDatabaseMajorVersion : {
return ValuePool.getInt(getDatabaseMajorVersion());
}
case getDatabaseMinorVersion : {
return ValuePool.getInt(getDatabaseMinorVersion());
}
case getDatabaseProductName : {
return getDatabaseProductName();
}
case getDatabaseProductVersion : {
return getDatabaseProductVersion();
}
case hexToRaw : {
return hexToRaw((String) params[0]);
}
case hour : {
return hour((Time) params[0]);
}
case identity : {
return null;
}
case insert : {
return insert((String) params[0],
Number.intValue(params[1]),
Number.intValue(params[2]),
(String) params[3]);
}
case isReadOnlyConnection : {
return null;
}
case isReadOnlyDatabase : {
return null;
}
case lcase : {
return lcase((String) params[0]);
}
case left : {
return left((String) params[0],
Number.intValue(params[1]));
}
case length : {
return length((String) params[0]);
}
case locate : {
return ValuePool.getInt(locate((String) params[0],
(String) params[1],
(Integer) params[2]));
}
case log10 : {
return new Double(
log10(Number.doubleValue(params[0])));
}
case ltrim : {
return ltrim((String) params[0]);
}
case minute : {
return minute((Time) params[0]);
}
case mod : {
return ValuePool.getInt(
mod(
Number.intValue(params[0]),
Number.intValue(params[1])));
}
case month : {
return month((Date) params[0]);
}
case monthname : {
return ValuePool.getString(monthname((Date) params[0]));
}
case now : {
return null;
}
case octetLength : {
return octetLength((String) params[0]);
}
case position : {
return ValuePool.getInt(position((String) params[0],
(String) params[1]));
}
case pi : {
return piValue;
}
case quarter : {
return quarter((Date) params[0]);
}
case rand : {
return new Double(rand((Integer) params[0]));
}
case rawToHex : {
return rawToHex((String) params[0]);
}
case repeat : {
return repeat((String) params[0], (Integer) params[1]);
}
case replace : {
return replace((String) params[0], (String) params[1],
(String) params[2]);
}
case right : {
return right((String) params[0],
Number.intValue(params[1]));
}
case round : {
return new Double(
round(Number.doubleValue(params[0]),
Number.intValue(params[1])));
}
case roundMagic : {
return new Double(
roundMagic(Number.doubleValue(params[0])));
}
case rtrim : {
return rtrim((String) params[0]);
}
case second : {
return second((Time) params[0]);
}
case sign : {
return ValuePool.getInt(
sign(Number.doubleValue(params[0])));
}
case soundex : {
return soundex((String) params[0]);
}
case space : {
return space(Number.intValue(params[0]));
}
case substring : {
return substring((String) params[0],
Number.intValue(params[1]),
(Integer) params[2]);
}
case trim : {
return trim((String) params[0], (String) params[1],
((Boolean) params[2]).booleanValue(),
((Boolean) params[3]).booleanValue());
}
case truncate : {
return new Double(
truncate(
Number.doubleValue(params[0]),
Number.intValue(params[1])));
}
case ucase : {
return ucase((String) params[0]);
}
case user : {
return null;
}
case week : {
return week((Date) params[0]);
}
case year : {
return year((Date) params[0]);
}
case to_char : {
return to_char((java.util.Date) params[0],
(String) params[1]);
}
case isReadOnlyDatabaseFiles : {
return null;
}
default : {
// coding error
Trace.doAssert(false);
return null;
}
}
} catch (Exception e) {
throw Trace.error(Trace.FUNCTION_CALL_ERROR, e.toString());
}
}
static final String prefix = "org.hsqldb.Library.";
static final int prefixLength = prefix.length();
static int functionID(String fname) {
return fname.startsWith(prefix)
? functionMap.get(fname.substring(prefixLength), -1)
: -1;
}
static public class Method
{
Class m_retType;
Class[] m_aArgClasses;
public Method( Class retType , Class[] aArgClasses )
{
m_retType = retType;
m_aArgClasses = aArgClasses;
}
public Class getReturnType()
{
return m_retType;
}
Class[] getParameterTypes()
{
return m_aArgClasses;
}
};
static public Method find_method(String strFullName)
{
if ( strFullName.equals("org.hsqldb.Library.ucase") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.lcase") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.substring") )
{
Class[] args = {String.class, Integer.class, Integer.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.space") )
{
Class[] args = {Integer.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.soundex") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.rtrim") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.right") )
{
Class[] args = {String.class, Integer.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.replace") )
{
Class[] args = {String.class, String.class, String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.repeat") )
{
Class[] args = {String.class, Integer.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.rawToHex") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.octetLength") )
{
Class[] args = {String.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.ltrim") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.locate") )
{
Class[] args = {String.class, String.class, Integer.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.length") )
{
Class[] args = {String.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.left") )
{
Class[] args = {String.class, Integer.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.insert") )
{
Class[] args = {String.class, Integer.class, Integer.class, String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.hexToRaw") )
{
Class[] args = {String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.difference") )
{
Class[] args = {String.class, String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.concat") )
{
Class[] args = {String.class, String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.length") )
{
Class[] args = {String.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.character") )
{
Class[] args = {Integer.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.bitLength") )
{
Class[] args = {String.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.ascii") )
{
Class[] args = {String.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.datediff") )
{
Class[] args = {String.class, Timestamp.class, Timestamp.class};
return new Method( Long.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.dayofmonth") )
{
Class[] args = {Date.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.dayofweek") )
{
Class[] args = {Date.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.hour") )
{
Class[] args = {Time.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.minute") )
{
Class[] args = {Time.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.month") )
{
Class[] args = {Date.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.monthname") )
{
Class[] args = {Date.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.quarter") )
{
Class[] args = {Date.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.second") )
{
Class[] args = {Time.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.week") )
{
Class[] args = {Date.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.year") )
{
Class[] args = {Date.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.to_char") )
{
Class[] args = {Date.class, String.class};
return new Method( String.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.abs") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.acos") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.asin") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.atan") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.ceil") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.cos") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.cot") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.toDegrees") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.exp") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.floor") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.log") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.log10") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.log10") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.mod") )
{
Class[] args = {Integer.class, Integer.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.pi") )
{
Class[] args = {};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.pow") )
{
Class[] args = {Double.class, Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.toRadians") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("javolution.lang.MathLib.random") )
{
Class[] args = {Integer.class, Integer.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.round") )
{
Class[] args = {Double.class, Integer.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.sign") )
{
Class[] args = {Double.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("java.lang.Math.sin") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.sqrt") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("java.lang.Math.tan") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.truncate") )
{
Class[] args = {Double.class, Integer.class};
return new Method( Double.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.bitand") )
{
Class[] args = {Integer.class, Integer.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.bitor") )
{
Class[] args = {Integer.class, Integer.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.bitxor") )
{
Class[] args = {Integer.class, Integer.class};
return new Method( Integer.class, args );
}else if ( strFullName.equals("org.hsqldb.Library.roundMagic") )
{
Class[] args = {Double.class};
return new Method( Double.class, args );
}
return null;
}
}