blob: 33e1465b66a9249dbd5b6bd368e56ae1e7f5ff21 [file] [log] [blame]
package org.mariadb.jdbc.client;
import java.nio.charset.StandardCharsets;
import java.sql.Date;
import java.sql.SQLDataException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import org.mariadb.jdbc.Configuration;
import org.mariadb.jdbc.client.column.UuidColumn;
import org.mariadb.jdbc.client.impl.StandardReadableByteBuf;
import org.mariadb.jdbc.util.constants.ColumnFlags;
public interface ColumnDecoder extends Column {
/**
* Returns default class name depending on server column datatype
*
* @param conf configuration
* @return default class name
*/
String defaultClassname(Configuration conf);
/**
* Returns default java.sql.Types depending on server column datatype
*
* @param conf configuration
* @return default java.sql.Types
*/
int getColumnType(Configuration conf);
/**
* Returns server column datatype
*
* @param conf configuration
* @return default server column datatype
*/
String getColumnTypeName(Configuration conf);
/**
* Return decimal precision.
*
* @return decimal precision
*/
default int getPrecision() {
return (int) getColumnLength();
}
/**
* Return default Object text encoded
*
* @param conf configuration
* @param buf row buffer
* @param length data length
* @return default Object
* @throws SQLDataException if any decoding error occurs
*/
Object getDefaultText(final Configuration conf, final ReadableByteBuf buf, final int length)
throws SQLDataException;
/**
* Return default Object binary encoded
*
* @param conf configuration
* @param buf row buffer
* @param length data length
* @return default Object
* @throws SQLDataException if any decoding error occurs
*/
Object getDefaultBinary(final Configuration conf, final ReadableByteBuf buf, final int length)
throws SQLDataException;
/**
* Return String text encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return String value
* @throws SQLDataException if any decoding error occurs
*/
String decodeStringText(final ReadableByteBuf buf, final int length, final Calendar cal)
throws SQLDataException;
/**
* Return String binary encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return String value
* @throws SQLDataException if any decoding error occurs
*/
String decodeStringBinary(final ReadableByteBuf buf, final int length, final Calendar cal)
throws SQLDataException;
/**
* Return byte text encoded value
*
* @param buf row buffer
* @param length data length
* @return byte value
* @throws SQLDataException if any decoding error occurs
*/
byte decodeByteText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Return byte binary encoded value
*
* @param buf row buffer
* @param length data length
* @return byte value
* @throws SQLDataException if any decoding error occurs
*/
byte decodeByteBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Return date text encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return date value
* @throws SQLDataException if any decoding error occurs
*/
Date decodeDateText(final ReadableByteBuf buf, final int length, Calendar cal)
throws SQLDataException;
/**
* Return date binary encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return date value
* @throws SQLDataException if any decoding error occurs
*/
Date decodeDateBinary(final ReadableByteBuf buf, final int length, Calendar cal)
throws SQLDataException;
/**
* Return time text encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return time value
* @throws SQLDataException if any decoding error occurs
*/
Time decodeTimeText(final ReadableByteBuf buf, final int length, Calendar cal)
throws SQLDataException;
/**
* Return time binary encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return time value
* @throws SQLDataException if any decoding error occurs
*/
Time decodeTimeBinary(final ReadableByteBuf buf, final int length, Calendar cal)
throws SQLDataException;
/**
* Return timestamp text encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return timestamp value
* @throws SQLDataException if any decoding error occurs
*/
Timestamp decodeTimestampText(final ReadableByteBuf buf, final int length, Calendar cal)
throws SQLDataException;
/**
* Return timestamp binary encoded value
*
* @param buf row buffer
* @param length data length
* @param cal calendar
* @return timestamp value
* @throws SQLDataException if any decoding error occurs
*/
Timestamp decodeTimestampBinary(final ReadableByteBuf buf, final int length, Calendar cal)
throws SQLDataException;
/**
* Return boolean text encoded value
*
* @param buf row buffer
* @param length data length
* @return boolean value
* @throws SQLDataException if any decoding error occurs
*/
boolean decodeBooleanText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse boolean binary encoded value
*
* @param buf row buffer
* @param length data length
* @return boolean value
* @throws SQLDataException if any decoding error occurs
*/
boolean decodeBooleanBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse short text encoded value
*
* @param buf row buffer
* @param length data length
* @return short value
* @throws SQLDataException if any decoding error occurs
*/
short decodeShortText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse short binary encoded value
*
* @param buf row buffer
* @param length data length
* @return short value
* @throws SQLDataException if any decoding error occurs
*/
short decodeShortBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse int text encoded value
*
* @param buf row buffer
* @param length data length
* @return int value
* @throws SQLDataException if any decoding error occurs
*/
int decodeIntText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse int binary encoded value
*
* @param buf row buffer
* @param length data length
* @return int value
* @throws SQLDataException if any decoding error occurs
*/
int decodeIntBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse long text encoded value
*
* @param buf row buffer
* @param length data length
* @return long value
* @throws SQLDataException if any decoding error occurs
*/
long decodeLongText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse long binary encoded value
*
* @param buf row buffer
* @param length data length
* @return long value
* @throws SQLDataException if any decoding error occurs
*/
long decodeLongBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse float text encoded value
*
* @param buf row buffer
* @param length data length
* @return float value
* @throws SQLDataException if any decoding error occurs
*/
float decodeFloatText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse float binary encoded value
*
* @param buf row buffer
* @param length data length
* @return float value
* @throws SQLDataException if any decoding error occurs
*/
float decodeFloatBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse double text encoded value
*
* @param buf row buffer
* @param length data length
* @return double value
* @throws SQLDataException if any decoding error occurs
*/
double decodeDoubleText(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Parse double binary encoded value
*
* @param buf row buffer
* @param length data length
* @return double value
* @throws SQLDataException if any decoding error occurs
*/
double decodeDoubleBinary(final ReadableByteBuf buf, final int length) throws SQLDataException;
/**
* Decode Column from mysql packet
*
* @param buf packet
* @param extendedInfo is extended datatype information capability enable
* @return column
*/
static ColumnDecoder decode(ReadableByteBuf buf, boolean extendedInfo) {
// skip first strings
int[] stringPos = new int[5];
stringPos[0] = buf.skipIdentifier(); // schema pos
stringPos[1] = buf.skipIdentifier(); // table alias pos
stringPos[2] = buf.skipIdentifier(); // table pos
stringPos[3] = buf.skipIdentifier(); // column alias pos
stringPos[4] = buf.skipIdentifier(); // column pos
buf.skipIdentifier();
String extTypeName = null;
String extTypeFormat = null;
if (extendedInfo) {
// fast skipping extended info (usually not set)
if (buf.readByte() != 0) {
// revert position, because has extended info.
buf.pos(buf.pos() - 1);
ReadableByteBuf subPacket = buf.readLengthBuffer();
while (subPacket.readableBytes() > 0) {
switch (subPacket.readByte()) {
case 0:
extTypeName = subPacket.readAscii(subPacket.readLength());
break;
case 1:
extTypeFormat = subPacket.readAscii(subPacket.readLength());
break;
default: // skip data
subPacket.skip(subPacket.readLength());
break;
}
}
}
}
buf.skip(); // skip length always 0x0c
short charset = buf.readShort();
int length = buf.readInt();
DataType dataType = DataType.of(buf.readUnsignedByte());
int flags = buf.readUnsignedShort();
byte decimals = buf.readByte();
DataType.ColumnConstructor constructor =
(extTypeName != null && extTypeName.equals("uuid"))
? UuidColumn::new
: (flags & ColumnFlags.UNSIGNED) == 0
? dataType.getColumnConstructor()
: dataType.getUnsignedColumnConstructor();
return constructor.create(
buf, charset, length, dataType, decimals, flags, stringPos, extTypeName, extTypeFormat);
}
/**
* Create fake MySQL column definition packet with indicated datatype
*
* @param name column name
* @param type data type
* @param flags column flags
* @return Column
*/
static ColumnDecoder create(String name, DataType type, int flags) {
byte[] nameBytes = name.getBytes(StandardCharsets.UTF_8);
byte[] arr = new byte[9 + 2 * nameBytes.length];
arr[0] = 3;
arr[1] = 'D';
arr[2] = 'E';
arr[3] = 'F';
int[] stringPos = new int[5];
stringPos[0] = 4; // schema pos
stringPos[1] = 5; // table alias pos
stringPos[2] = 6; // table pos
// lenenc_str name
// lenenc_str org_name
int pos = 7;
for (int i = 0; i < 2; i++) {
stringPos[i + 3] = pos;
arr[pos++] = (byte) nameBytes.length;
System.arraycopy(nameBytes, 0, arr, pos, nameBytes.length);
pos += nameBytes.length;
}
int len;
/* Sensible predefined length - since we're dealing with I_S here, most char fields are 64 char long */
switch (type) {
case VARCHAR:
case VARSTRING:
len = 64 * 3; /* 3 bytes per UTF8 char */
break;
case SMALLINT:
len = 5;
break;
case NULL:
len = 0;
break;
default:
len = 1;
break;
}
DataType.ColumnConstructor constructor =
(flags & ColumnFlags.UNSIGNED) == 0
? type.getColumnConstructor()
: type.getUnsignedColumnConstructor();
return constructor.create(
new StandardReadableByteBuf(arr, arr.length),
33,
len,
type,
(byte) 0,
flags,
stringPos,
null,
null);
}
}