org.firebirdsql.gds.XSQLVAR Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jaybird Show documentation
Show all versions of jaybird Show documentation
JDBC Driver for the Firebird RDBMS
/*
* Public Firebird Java API.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*
* The Original Code is the Firebird Java GDS implementation.
*
* The Initial Developer of the Original Code is Alejandro Alberola.
* Portions created by Alejandro Alberola are Copyright (C) 2001
* Boix i Oltra, S.L. All Rights Reserved.
*
*/
package org.firebirdsql.gds;
import java.sql.Date;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.GregorianCalendar;
import org.firebirdsql.encodings.Encoding;
import org.firebirdsql.encodings.EncodingFactory;
/**
* The class XSQLDA
is a java mapping of the XSQLVAR server
* data structure used to represent one column for input and output.
*
* @author Alejandro Alberola
* @version 1.0
*/
public class XSQLVAR {
public int sqltype;
public int sqlscale;
public int sqlsubtype;
public int sqllen;
public byte[] sqldata;
// public int sqlind;
public String sqlname;
public String relname;
public String ownname;
public String aliasname;
//
protected Encoding coder;
public XSQLVAR() {
}
/**
* Get a deep copy of this object.
*
* @return deep copy of this object.
*/
public XSQLVAR deepCopy() {
XSQLVAR result = new XSQLVAR();
result.copyFrom(this);
return result;
}
/**
* Copy constructor. Initialize this instance of XSQLVAR
with
* values from another instance.
*
* @param original The other instance of XSQLVAR
to be used
* as the base for initializing this instance
*/
public void copyFrom(XSQLVAR original) {
copyFrom(original, true);
}
/**
* Copy constructor. Initialize this instance of XSQLVAR
with
* values from another instance.
*
* @param original The other instance of XSQLVAR
to be used
* as the base for initializing this instance
*/
public void copyFrom(XSQLVAR original, boolean copyData) {
this.sqltype = original.sqltype;
this.sqlscale = original.sqlscale;
this.sqlsubtype = original.sqlsubtype;
this.sqllen = original.sqllen;
if (original.sqldata != null && copyData) {
this.sqldata = new byte[original.sqldata.length];
System.arraycopy(original.sqldata, 0, this.sqldata, 0, original.sqldata.length);
} else
this.sqldata = null;
this.sqlname = original.sqlname;
this.relname = original.relname;
this.ownname = original.ownname;
this.aliasname = original.aliasname;
}
//
// numbers
//
/**
* Encode a short
value as a byte
array.
*
* @param value The value to be encoded
* @return The value of value
encoded as a
* byte
array
*/
public byte[] encodeShort(short value){
return encodeInt(value);
}
/**
* Decode a byte
array into a short
value.
*
* @param byte_int The byte
array to be decoded
* @return The short
value of the decoded
* byte
array
*/
public short decodeShort(byte[] byte_int){
return (short) decodeInt(byte_int);
}
/**
* Encode an int
value as a byte
array.
*
* @param value The value to be encoded
* @return The value of value
encoded as a
* byte
array
*/
public byte[] encodeInt(int value){
byte ret[] = new byte[4];
ret[0] = (byte) ((value >>> 24) & 0xff);
ret[1] = (byte) ((value >>> 16) & 0xff);
ret[2] = (byte) ((value >>> 8) & 0xff);
ret[3] = (byte) ((value >>> 0) & 0xff);
return ret;
}
/**
* Decode a byte
array into an int
value.
*
* @param byte_int The byte
array to be decoded
* @return The int
value of the decoded
* byte
array
*/
public int decodeInt(byte[] byte_int){
int b1 = byte_int[0]&0xFF;
int b2 = byte_int[1]&0xFF;
int b3 = byte_int[2]&0xFF;
int b4 = byte_int[3]&0xFF;
return ((b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0));
}
/**
* Encode a long
value as a byte
array.
*
* @param value The value to be encoded
* @return The value of value
encoded as a
* byte
array
*/
public byte[] encodeLong(long value){
byte[] ret = new byte[8];
ret[0] = (byte) (value >>> 56 & 0xFF);
ret[1] = (byte) (value >>> 48 & 0xFF);
ret[2] = (byte) (value >>> 40 & 0xFF);
ret[3] = (byte) (value >>> 32 & 0xFF);
ret[4] = (byte) (value >>> 24 & 0xFF);
ret[5] = (byte) (value >>> 16 & 0xFF);
ret[6] = (byte) (value >>> 8 & 0xFF);
ret[7] = (byte) (value >>> 0 & 0xFF);
return ret;
}
/**
* Decode a byte
array into a long
value.
*
* @param byte_int The byte
array to be decoded
* @return The long
value of the decoded
* byte
array
*/
public long decodeLong(byte[] byte_int){
long b1 = byte_int[0]&0xFF;
long b2 = byte_int[1]&0xFF;
long b3 = byte_int[2]&0xFF;
long b4 = byte_int[3]&0xFF;
long b5 = byte_int[4]&0xFF;
long b6 = byte_int[5]&0xFF;
long b7 = byte_int[6]&0xFF;
long b8 = byte_int[7]&0xFF;
return ((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32)
+ (b5 << 24) + (b6 << 16) + (b7 << 8) + (b8 << 0));
}
/**
* Encode a float
value as a byte
array.
*
* @param value The value to be encoded
* @return The value of value
encoded as a
* byte
array
*/
public byte[] encodeFloat(float value){
return encodeInt(Float.floatToIntBits(value));
}
/**
* Decode a byte
array into a float
value.
*
* @param byte_int The byte
array to be decoded
* @return The float
value of the decoded
* byte
array
*/
public float decodeFloat(byte[] byte_int){
return Float.intBitsToFloat(decodeInt(byte_int));
}
/**
* Encode a double
value as a byte
array.
*
* @param value The value to be encoded
* @return The value of value
encoded as a
* byte
array
*/
public byte[] encodeDouble(double value){
return encodeLong(Double.doubleToLongBits(value));
}
/**
* Decode a byte
array into a double
value.
*
* @param byte_int The byte
array to be decoded
* @return The double
value of the decoded
* byte
array
*/
public double decodeDouble(byte[] byte_int){
return Double.longBitsToDouble(decodeLong(byte_int));
}
//
// Strings
//
// public byte[] encodeString(String value, String encoding) throws SQLException {
// if (coder == null)
// coder = EncodingFactory.getEncoding(encoding);
// return coder.encodeToCharset(value);
// }
// public byte[] encodeString(byte[] value, String encoding)throws SQLException {
// if (encoding == null)
// return value;
// else {
// if (coder == null)
// coder = EncodingFactory.getEncoding(encoding);
// return coder.encodeToCharset(coder.decodeFromCharset(value));
// }
// }
//
// public String decodeString(byte[] value, String encoding){
// if (coder == null)
// coder = EncodingFactory.getEncoding(encoding);
// return coder.decodeFromCharset(value);
// }
//
// Strings with mapping
//
/**
* Encode a String
value into a byte
array using
* a given encoding.
*
* @param value The String
to be encoded
* @param encoding The encoding to use in the encoding process
* @param mappingPath The character mapping path to be used in the encoding
* @return The value of value
as a byte
array
* @throws SQLException if the given encoding cannot be found, or an error
* occurs during the encoding
*/
public byte[] encodeString(String value, String encoding, String mappingPath) throws SQLException {
if (coder == null)
coder = EncodingFactory.getEncoding(encoding, mappingPath);
return coder.encodeToCharset(value);
}
/**
* Encode a byte
array using a given encoding.
*
* @param value The byte
array to be encoded
* @param encoding The encoding to use in the encoding process
* @param mappingPath The character mapping path to be used in the encoding
* @return The value of value
encoded using the given encoding
* @throws SQLException if the given encoding cannot be found, or an error
* occurs during the encoding
*/
public byte[] encodeString(byte[] value, String encoding, String mappingPath)throws SQLException {
if (encoding == null)
return value;
else {
if (coder == null)
coder = EncodingFactory.getEncoding(encoding, mappingPath);
return coder.encodeToCharset(coder.decodeFromCharset(value));
}
}
/**
* Decode an encoded byte
array into a String
* using a given encoding.
*
* @param value The value to be decoded
* @param encoding The encoding to be used in the decoding process
* @param mappingPath The character mapping path to be used in the decoding
* @return The decoded String
* @throws SQLException if the given encoding cannot be found, or an
* error occurs during the decoding
*/
public String decodeString(byte[] value, String encoding, String mappingPath) throws SQLException{
if (coder == null)
coder = EncodingFactory.getEncoding(encoding, mappingPath);
return coder.decodeFromCharset(value);
}
//
// times,dates...
//
/**
* Encode a Timestamp
using a given Calendar
.
*
* @param value The Timestamp
to be encoded
* @param cal The Calendar
to be used for encoding,
* may be null
*/
public Timestamp encodeTimestamp(java.sql.Timestamp value, Calendar cal){
return encodeTimestamp(value, cal, false);
}
/**
* Encode a Timestamp
using a given Calendar
.
*
* @param value The Timestamp
to be encoded
* @param cal The Calendar
to be used for encoding,
* may be null
* @param invertTimeZone If true
, the timezone offset value
* will be subtracted from the encoded value, otherwise it will
* be added
* @return The encoded Timestamp
*/
public Timestamp encodeTimestamp(java.sql.Timestamp value, Calendar cal, boolean invertTimeZone){
if (cal == null) {
return value;
}
else {
long time = value.getTime() +
(invertTimeZone ? -1 : 1) * (cal.getTimeZone().getRawOffset() -
Calendar.getInstance().getTimeZone().getRawOffset());
return new Timestamp(time);
}
}
/**
* Encode a Timstamp
as a byte
array.
*
* @param value The Timstamp
to be encoded
* @return The array of byte
s that represents the given
* Timestamp
value
*/
public byte[] encodeTimestamp(Timestamp value){
// note, we cannot simply pass millis to the database, because
// Firebird stores timestamp in format (citing Ann W. Harrison):
//
// "[timestamp is] stored a two long words, one representing
// the number of days since 17 Nov 1858 and one representing number
// of 100 nano-seconds since midnight"
datetime d = new datetime(value);
byte[] date = d.toDateBytes();
byte[] time = d.toTimeBytes();
byte[] result = new byte[8];
System.arraycopy(date, 0, result, 0, 4);
System.arraycopy(time, 0, result, 4, 4);
return result;
}
/**
* Decode a Timestamp
value using a given
* Calendar
.
*
* @param value The Timestamp
to be decoded
* @param cal The Calendar
to be used in decoding,
* may be null
* @return The decoded Timestamp
*/
public java.sql.Timestamp decodeTimestamp(Timestamp value, Calendar cal) {
return decodeTimestamp(value, cal, false);
}
/**
* Decode a Timestamp
value using a given
* Calendar
.
*
* @param value The Timestamp
to be decoded
* @param cal The Calendar
to be used in decoding,
* may be null
* @param invertTimeZone If true
, the timezone offset value
* will be subtracted from the decoded value, otherwise it will
* be added
* @return The encoded Timestamp
*/
public java.sql.Timestamp decodeTimestamp(Timestamp value, Calendar cal, boolean invertTimeZone){
if (cal == null) {
return value;
}
else {
long time = value.getTime() -
(invertTimeZone ? -1 : 1) * (cal.getTimeZone().getRawOffset() -
Calendar.getInstance().getTimeZone().getRawOffset());
return new Timestamp(time);
}
}
/**
* Decode a byte
array into a Timestamp
.
*
* @param byte_int The byte
array to be decoded
* @return A Timestamp
value from the decoded
* byte
s
*/
public Timestamp decodeTimestamp(byte[] byte_int){
if (byte_int.length != 8)
throw new IllegalArgumentException("Bad parameter to decode");
// we have to extract time and date correctly
// see encodeTimestamp(...) for explanations
byte[] date = new byte[4];
byte[] time = new byte[4];
System.arraycopy(byte_int, 0, date, 0, 4);
System.arraycopy(byte_int, 4, time, 0, 4);
datetime d = new datetime(date,time);
return d.toTimestamp();
}
/**
* Encode a given Time
value using a given
* Calendar
.
*
* @param d The Time
to be encoded
* @param cal The Calendar
to be used in the encoding,
* may be null
* @return The encoded Time
*/
public java.sql.Time encodeTime(Time d, Calendar cal, boolean invertTimeZone) {
if (cal == null) {
return d;
}
else {
long time = d.getTime() +
(invertTimeZone ? -1 : 1) * (cal.getTimeZone().getRawOffset() -
Calendar.getInstance().getTimeZone().getRawOffset());
return new Time(time);
}
}
/**
* Encode a Time
value into a byte
array.
*
* @param d The Time
to be encoded
* @return The array of byte
s representing the given
* Time
*/
public byte[] encodeTime(Time d) {
datetime dt = new datetime(d);
return dt.toTimeBytes();
}
/**
* Decode a Time
value using a given Calendar
.
*
* @param d The Time
to be decoded
* @param cal The Calendar
to be used in the decoding, may
* be null
* @return The decooded Time
*/
public java.sql.Time decodeTime(java.sql.Time d, Calendar cal, boolean invertTimeZone) {
if (cal == null) {
return d;
}
else {
long time = d.getTime() -
(invertTimeZone ? -1 : 1) * (cal.getTimeZone().getRawOffset() -
Calendar.getInstance().getTimeZone().getRawOffset());
return new Time(time);
}
}
/**
* Decode a byte
array into a Time
value.
*
* @param int_byte The byte
array to be decoded
* @return The decoded Time
*/
public Time decodeTime(byte[] int_byte) {
datetime dt = new datetime(null,int_byte);
return dt.toTime();
}
/**
* Encode a given Date
value using a given
* Calendar
.
*
* @param d The Date
to be encoded
* @param cal The Calendar
to be used in the encoding,
* may be null
* @return The encoded Date
*/
public Date encodeDate(java.sql.Date d, Calendar cal) {
if (cal == null) {
return (d);
}
else {
cal.setTime(d);
return new Date(cal.getTime().getTime());
}
}
/**
* Encode a Date
value into a byte
array.
*
* @param d The Date
to be encoded
* @return The array of byte
s representing the given
* Date
*/
public byte[] encodeDate(Date d) {
datetime dt = new datetime(d);
return dt.toDateBytes();
}
/**
* Decode a Date
value using a given Calendar
.
*
* @param d The Date
to be decoded
* @param cal The Calendar
to be used in the decoding, may
* be null
* @return The decoded Date
*/
public java.sql.Date decodeDate(Date d, Calendar cal) {
if (cal == null || d == null) {
return d;
}
else {
cal.setTime(d);
return new Date(cal.getTime().getTime());
}
}
/**
* Decode a byte
array into a Date
value.
*
* @param byte_int The byte
array to be decoded
* @return The decoded Date
*/
public Date decodeDate(byte[] byte_int) {
datetime dt = new datetime(byte_int, null);
return dt.toDate();
}
//
// Helper Class to encode/decode times/dates
//
private class datetime{
int year;
int month;
int day;
int hour;
int minute;
int second;
int millisecond;
datetime(Timestamp value){
Calendar c = new GregorianCalendar();
c.setTime(value);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH)+1;
day = c.get(Calendar.DAY_OF_MONTH);
hour = c.get(Calendar.HOUR_OF_DAY);
minute = c.get(Calendar.MINUTE);
second = c.get(Calendar.SECOND);
millisecond = value.getNanos()/1000000;
}
datetime(Date value){
Calendar c = new GregorianCalendar();
c.setTime(value);
year = c.get(Calendar.YEAR);
month = c.get(Calendar.MONTH)+1;
day = c.get(Calendar.DAY_OF_MONTH);
hour = 0;
minute = 0;
second = 0;
millisecond = 0;
}
datetime(Time value){
Calendar c = new GregorianCalendar();
c.setTime(value);
year = 0;
month = 0;
day = 0;
hour = c.get(Calendar.HOUR_OF_DAY);
minute = c.get(Calendar.MINUTE);
second = c.get(Calendar.SECOND);
millisecond = c.get(Calendar.MILLISECOND);
}
datetime(byte[] date, byte[] time){
if (date != null){
int sql_date = decodeInt(date);
int century;
sql_date -= 1721119 - 2400001;
century = (4 * sql_date - 1) / 146097;
sql_date = 4 * sql_date - 1 - 146097 * century;
day = sql_date / 4;
sql_date = (4 * day + 3) / 1461;
day = 4 * day + 3 - 1461 * sql_date;
day = (day + 4) / 4;
month = (5 * day - 3) / 153;
day = 5 * day - 3 - 153 * month;
day = (day + 5) / 5;
year = 100 * century + sql_date;
if (month < 10) {
month += 3;
} else {
month -= 9;
year += 1;
}
}
if (time != null){
int millisInDay = decodeInt(time)/10;
hour = millisInDay / 3600000;
minute = (millisInDay - hour*3600000) / 60000;
second = (millisInDay - hour*3600000 - minute * 60000) / 1000;
millisecond = millisInDay - hour*3600000 - minute * 60000 - second * 1000;
}
}
byte[] toTimeBytes(){
int millisInDay = (hour * 3600000 + minute * 60000 + second * 1000 + millisecond)*10;
return encodeInt(millisInDay);
}
byte[] toDateBytes(){
int cpMonth = month;
int cpYear = year;
int c, ya;
if (cpMonth > 2) {
cpMonth -= 3;
} else {
cpMonth += 9;
cpYear -= 1;
}
c = cpYear / 100;
ya = cpYear - 100 * c;
int value = ((146097 * c) / 4 +
(1461 * ya) / 4 +
(153 * cpMonth + 2) / 5 +
day + 1721119 - 2400001);
return encodeInt(value);
}
Time toTime(){
Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR, 1970);
c.set(Calendar.MONTH, Calendar.JANUARY);
c.set(Calendar.DAY_OF_MONTH, 1);
c.set(Calendar.HOUR_OF_DAY,hour);
c.set(Calendar.MINUTE,minute);
c.set(Calendar.SECOND,second);
c.set(Calendar.MILLISECOND,millisecond);
return new Time(c.getTime().getTime());
}
Timestamp toTimestamp(){
Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR,year);
c.set(Calendar.MONTH,month-1);
c.set(Calendar.DAY_OF_MONTH,day);
c.set(Calendar.HOUR_OF_DAY,hour);
c.set(Calendar.MINUTE,minute);
c.set(Calendar.SECOND,second);
c.set(Calendar.MILLISECOND,millisecond);
return new Timestamp(c.getTime().getTime());
}
Date toDate(){
Calendar c = new GregorianCalendar();
c.set(Calendar.YEAR,year);
c.set(Calendar.MONTH,month-1);
c.set(Calendar.DAY_OF_MONTH,day);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0);
c.set(Calendar.MILLISECOND,0);
return new Date(c.getTime().getTime());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy