/* Copyright (c) 2001-2016, 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.rowio;
import java.math.
BigDecimal;
import java.util.
Calendar;
import java.util.
GregorianCalendar;
import org.hsqldb.
HsqlDateTime;
import org.hsqldb.
HsqlException;
import org.hsqldb.
Scanner;
import org.hsqldb.
Session;
import org.hsqldb.
Tokens;
import org.hsqldb.error.
Error;
import org.hsqldb.error.
ErrorCode;
import org.hsqldb.lib.
HsqlArrayList;
import org.hsqldb.map.
ValuePool;
import org.hsqldb.scriptio.
ScriptReaderBase;
import org.hsqldb.types.
BinaryData;
import org.hsqldb.types.
BlobData;
import org.hsqldb.types.
BlobDataID;
import org.hsqldb.types.
ClobData;
import org.hsqldb.types.
ClobDataID;
import org.hsqldb.types.
DateTimeType;
import org.hsqldb.types.
IntervalMonthData;
import org.hsqldb.types.
IntervalSecondData;
import org.hsqldb.types.
IntervalType;
import org.hsqldb.types.
JavaObjectData;
import org.hsqldb.types.
TimeData;
import org.hsqldb.types.
TimestampData;
import org.hsqldb.types.
Type;
/**
* Class for reading the data for a database row from the script file.
*
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.3.5
* @since 1.7.3
*/
public class
RowInputTextLog extends
RowInputBase
implements
RowInputInterface {
Scanner scanner;
String tableName = null;
String schemaName = null;
int
statementType;
Object value;
boolean
version18;
boolean
noSeparators;
Calendar tempCalDefault = new
GregorianCalendar();
public
RowInputTextLog() {
super(new byte[0]);
scanner = new
Scanner();
}
public
RowInputTextLog(boolean
version18) {
super(new byte[0]);
scanner = new
Scanner();
this.
version18 =
version18;
}
public void
setSource(
Session session,
String text) {
scanner.
reset(
session,
text);
statementType =
ScriptReaderBase.
ANY_STATEMENT;
scanner.
scanNext();
String s =
scanner.
getString();
if (
s.
equals(
Tokens.
T_INSERT)) {
statementType =
ScriptReaderBase.
INSERT_STATEMENT;
scanner.
scanNext();
scanner.
scanNext();
tableName =
scanner.
getString();
scanner.
scanNext();
} else if (
s.
equals(
Tokens.
T_DELETE)) {
statementType =
ScriptReaderBase.
DELETE_STATEMENT;
scanner.
scanNext();
scanner.
scanNext();
tableName =
scanner.
getString();
} else if (
s.
equals(
Tokens.
T_COMMIT)) {
statementType =
ScriptReaderBase.
COMMIT_STATEMENT;
} else if (
s.
equals(
Tokens.
T_SET)) {
scanner.
scanNext();
if (
Tokens.
T_SCHEMA.
equals(
scanner.
getString())) {
scanner.
scanNext();
schemaName =
scanner.
getString();
statementType =
ScriptReaderBase.
SET_SCHEMA_STATEMENT;
}
}
}
public int
getStatementType() {
return
statementType;
}
public
String getTableName() {
return
tableName;
}
public
String getSchemaName() {
return
schemaName;
}
protected void
readField() {
readFieldPrefix();
scanner.
scanNext();
value =
scanner.
getValue();
}
protected void
readNumberField(
Type type) {
readFieldPrefix();
scanner.
scanNext();
boolean
minus =
scanner.
getTokenType() ==
Tokens.
MINUS_OP;
if (
minus) {
scanner.
scanNext();
}
value =
scanner.
getValue();
if (
minus) {
try {
value =
scanner.
getDataType().
negate(
value);
} catch (
HsqlException e) {}
}
}
protected void
readFieldPrefix() {
if (!
noSeparators) {
scanner.
scanNext();
if (
statementType ==
ScriptReaderBase.
DELETE_STATEMENT) {
scanner.
scanNext();
scanner.
scanNext();
}
}
}
public
String readString() {
readField();
return (
String)
value;
}
public char
readChar() {
throw
Error.
runtimeError(
ErrorCode.
U_S0500, "RowInputTextLog");
}
public byte
readByte() {
throw
Error.
runtimeError(
ErrorCode.
U_S0500, "RowInputTextLog");
}
public short
readShort() {
throw
Error.
runtimeError(
ErrorCode.
U_S0500, "RowInputTextLog");
}
public int
readInt() {
throw
Error.
runtimeError(
ErrorCode.
U_S0500, "RowInputTextLog");
}
public long
readLong() {
throw
Error.
runtimeError(
ErrorCode.
U_S0500, "RowInputTextLog");
}
public int
readType() {
return 0;
}
protected boolean
readNull() {
// Return null on each column read instead.
return false;
}
protected
String readChar(
Type type) {
readField();
return (
String)
value;
}
protected
Integer readSmallint() {
readNumberField(
Type.
SQL_SMALLINT);
return (
Integer)
value;
}
protected
Integer readInteger() {
readNumberField(
Type.
SQL_INTEGER);
if (
value instanceof
Long) {
value =
Type.
SQL_INTEGER.
convertToDefaultType(null,
value);
}
return (
Integer)
value;
}
protected
Long readBigint() {
readNumberField(
Type.
SQL_BIGINT);
if (
value == null) {
return null;
}
if (
value instanceof
BigDecimal) {
return (
Long)
Type.
SQL_BIGINT.
convertToDefaultType(null,
value);
}
return
ValuePool.
getLong(((
Number)
value).
longValue());
}
protected
Double readReal() {
readNumberField(
Type.
SQL_DOUBLE);
if (
value == null) {
return null;
}
if (
scanner.
scanSpecialIdentifier(
Tokens.
T_DIVIDE_OP)) {
scanner.
scanNext();
Object divisor =
scanner.
getValue();
double
i = ((
Number)
divisor).
doubleValue();
if (
i == 0) {
if (((
Number)
value).
doubleValue() == 1E0) {
i =
Double.
NEGATIVE_INFINITY;
} else if (((
Number)
value).
doubleValue() == -1E0) {
i =
Double.
POSITIVE_INFINITY;
} else if (((
Number)
value).
doubleValue() == 0E0) {
i =
Double.
NaN;
} else {
throw
Error.
error(
ErrorCode.
X_42585);
}
} else {
throw
Error.
error(
ErrorCode.
X_42585);
}
value =
Double.
valueOf(
i);
}
return (
Double)
value;
}
protected
BigDecimal readDecimal(
Type type) {
readNumberField(
type);
if (
value == null) {
return null;
}
BigDecimal bd = (
BigDecimal)
type.
convertToDefaultType(null,
value);
return
bd;
}
protected
TimeData readTime(
Type type) {
readField();
if (
value == null) {
return null;
}
if (
version18) {
java.sql.
Time dateTime = java.sql.
Time.
valueOf((
String)
value);
long
millis =
HsqlDateTime.
convertMillisFromCalendar(
tempCalDefault,
dateTime.
getTime());
millis =
HsqlDateTime.
getNormalisedTime(
millis);
return new
TimeData((int)
millis / 1000, 0, 0);
}
return
scanner.
newTime((
String)
value);
}
protected
TimestampData readDate(
Type type) {
readField();
if (
value == null) {
return null;
}
if (
version18) {
java.sql.
Date dateTime = java.sql.
Date.
valueOf((
String)
value);
long
millis =
HsqlDateTime.
convertMillisFromCalendar(
tempCalDefault,
dateTime.
getTime());
millis =
HsqlDateTime.
getNormalisedDate(
millis);
return new
TimestampData(
millis / 1000);
}
return
scanner.
newDate((
String)
value);
}
protected
TimestampData readTimestamp(
Type type) {
readField();
if (
value == null) {
return null;
}
if (
version18) {
java.sql.
Timestamp dateTime =
java.sql.
Timestamp.
valueOf((
String)
value);
long
millis =
HsqlDateTime.
convertMillisFromCalendar(
tempCalDefault,
dateTime.
getTime());
int
nanos =
dateTime.
getNanos();
nanos =
DateTimeType.
normaliseFraction(
nanos,
type.
scale);
return new
TimestampData(
millis / 1000,
nanos, 0);
}
return
scanner.
newTimestamp((
String)
value);
}
protected
IntervalMonthData readYearMonthInterval(
Type type) {
readField();
if (
value == null) {
return null;
}
return (
IntervalMonthData)
scanner.
newInterval((
String)
value,
(
IntervalType)
type);
}
protected
IntervalSecondData readDaySecondInterval(
Type type) {
readField();
if (
value == null) {
return null;
}
return (
IntervalSecondData)
scanner.
newInterval((
String)
value,
(
IntervalType)
type);
}
protected
Boolean readBoole() {
readFieldPrefix();
scanner.
scanNext();
String token =
scanner.
getString();
value = null;
if (
token.
equalsIgnoreCase(
Tokens.
T_TRUE)) {
value =
Boolean.
TRUE;
} else if (
token.
equalsIgnoreCase(
Tokens.
T_FALSE)) {
value =
Boolean.
FALSE;
}
return (
Boolean)
value;
}
protected
Object readOther() {
readFieldPrefix();
if (
scanner.
scanNull()) {
return null;
}
scanner.
scanBinaryStringWithQuote();
if (
scanner.
getTokenType() ==
Tokens.
X_MALFORMED_BINARY_STRING) {
throw
Error.
error(
ErrorCode.
X_42587);
}
value =
scanner.
getValue();
return new
JavaObjectData(((
BinaryData)
value).
getBytes());
}
protected
BinaryData readBit() {
readFieldPrefix();
if (
scanner.
scanNull()) {
return null;
}
scanner.
scanBitStringWithQuote();
if (
scanner.
getTokenType() ==
Tokens.
X_MALFORMED_BIT_STRING) {
throw
Error.
error(
ErrorCode.
X_42587);
}
value =
scanner.
getValue();
return (
BinaryData)
value;
}
protected
BinaryData readUUID() {
readFieldPrefix();
if (
scanner.
scanNull()) {
return null;
}
scanner.
scanUUIDStringWithQuote();
if (
scanner.
getTokenType() ==
Tokens.
X_MALFORMED_BINARY_STRING) {
throw
Error.
error(
ErrorCode.
X_42587);
}
value =
scanner.
getValue();
return (
BinaryData)
value;
}
protected
BinaryData readBinary() {
readFieldPrefix();
if (
scanner.
scanNull()) {
return null;
}
scanner.
scanBinaryStringWithQuote();
if (
scanner.
getTokenType() ==
Tokens.
X_MALFORMED_BINARY_STRING) {
throw
Error.
error(
ErrorCode.
X_42587);
}
value =
scanner.
getValue();
return (
BinaryData)
value;
}
protected
ClobData readClob() {
readNumberField(
Type.
SQL_BIGINT);
if (
value == null) {
return null;
}
long
id = ((
Number)
value).
longValue();
return new
ClobDataID(
id);
}
protected
BlobData readBlob() {
readNumberField(
Type.
SQL_BIGINT);
if (
value == null) {
return null;
}
long
id = ((
Number)
value).
longValue();
return new
BlobDataID(
id);
}
protected
Object[]
readArray(
Type type) {
type =
type.
collectionBaseType();
readFieldPrefix();
scanner.
scanNext();
String token =
scanner.
getString();
value = null;
if (
token.
equalsIgnoreCase(
Tokens.
T_NULL)) {
return null;
} else if (!
token.
equalsIgnoreCase(
Tokens.
T_ARRAY)) {
throw
Error.
error(
ErrorCode.
X_42584);
}
scanner.
scanNext();
token =
scanner.
getString();
if (!
token.
equalsIgnoreCase(
Tokens.
T_LEFTBRACKET)) {
throw
Error.
error(
ErrorCode.
X_42584);
}
HsqlArrayList list = new
HsqlArrayList();
noSeparators = true;
for (int
i = 0; ;
i++) {
if (
scanner.
scanSpecialIdentifier(
Tokens.
T_RIGHTBRACKET)) {
break;
}
if (
i > 0) {
if (!
scanner.
scanSpecialIdentifier(
Tokens.
T_COMMA)) {
throw
Error.
error(
ErrorCode.
X_42584);
}
}
Object value =
readData(
type);
list.
add(
value);
}
noSeparators = false;
Object[]
data = new
Object[
list.
size()];
list.
toArray(
data);
return
data;
}
}