Skip to content

Commit 47e7ae3

Browse files
committed
Improved row performance for primitive types.
1 parent 5c7f0fa commit 47e7ae3

File tree

8 files changed

+205
-74
lines changed

8 files changed

+205
-74
lines changed

src/main/java/com/softwareverde/database/query/Query.java

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,14 @@
33
import com.softwareverde.constable.bytearray.ByteArray;
44
import com.softwareverde.constable.list.List;
55
import com.softwareverde.constable.list.mutable.MutableList;
6-
import com.softwareverde.database.query.parameter.ParameterType;
76
import com.softwareverde.database.query.parameter.TypedParameter;
87

98
public class Query {
109
protected final String _query;
1110
protected final MutableList<TypedParameter> _parameters = new MutableList<TypedParameter>();
1211

13-
protected void _setBoolean(final boolean booleanValue) {
14-
_parameters.add(new TypedParameter(booleanValue, ParameterType.BOOLEAN));
15-
}
16-
1712
protected void _setByteArray(final byte[] bytes) {
18-
_parameters.add(new TypedParameter(bytes, ParameterType.BYTE_ARRAY));
13+
_parameters.add(new TypedParameter(bytes));
1914
}
2015

2116
public Query(final String query) {
@@ -24,36 +19,44 @@ public Query(final String query) {
2419

2520
public Query setParameter(final Object value) {
2621
if (value == null) {
27-
_parameters.add(new TypedParameter(null, ParameterType.STRING));
22+
_parameters.add(TypedParameter.NULL);
23+
return this;
24+
}
25+
26+
if (value instanceof Boolean) {
27+
_parameters.add(new TypedParameter((Boolean) value));
28+
}
29+
else if (value instanceof Long) {
30+
_parameters.add(new TypedParameter((Long) value));
31+
}
32+
else if (value instanceof Integer) {
33+
_parameters.add(new TypedParameter((Integer) value));
34+
}
35+
else if (value instanceof Short) {
36+
_parameters.add(new TypedParameter((Short) value));
37+
}
38+
else if (value instanceof Double) {
39+
_parameters.add(new TypedParameter((Double) value));
40+
}
41+
else if (value instanceof Float) {
42+
_parameters.add(new TypedParameter((Float) value));
43+
}
44+
else if (value instanceof byte[]) {
45+
_setByteArray((byte[]) value);
46+
}
47+
else if (value instanceof ByteArray) {
48+
_setByteArray(((ByteArray) value).getBytes());
49+
}
50+
else if (value instanceof TypedParameter) {
51+
_parameters.add((TypedParameter) value);
2852
}
2953
else {
30-
if (value instanceof Boolean) {
31-
_setBoolean((Boolean) value);
32-
}
33-
else if (value instanceof byte[]) {
34-
_setByteArray((byte[]) value);
35-
}
36-
else if (value instanceof ByteArray) {
37-
_setByteArray(((ByteArray) value).getBytes());
38-
}
39-
else {
40-
_parameters.add(new TypedParameter(value.toString(), ParameterType.STRING));
41-
}
54+
_parameters.add(new TypedParameter(value.toString()));
4255
}
4356

4457
return this;
4558
}
4659

47-
public Query setParameter(final boolean value) {
48-
_setBoolean(value);
49-
return this;
50-
}
51-
52-
public Query setParameter(final byte[] bytes) {
53-
_setByteArray(bytes);
54-
return this;
55-
}
56-
5760
public List<TypedParameter> getParameters() {
5861
return _parameters;
5962
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.softwareverde.database.query.parameter;
22

33
public enum ParameterType {
4-
BYTE_ARRAY, STRING, BOOLEAN
4+
BYTE_ARRAY, STRING, WHOLE_NUMBER, FLOATING_POINT_NUMBER
55
}
Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,63 @@
11
package com.softwareverde.database.query.parameter;
22

3+
import com.softwareverde.constable.bytearray.ByteArray;
4+
35
public class TypedParameter {
6+
public static final TypedParameter NULL = new TypedParameter();
7+
8+
protected static final Long TRUE = 1L;
9+
protected static final Long FALSE = 0L;
10+
411
public final ParameterType type;
512
public final Object value;
613

7-
public TypedParameter(final Object value, final ParameterType type) {
8-
this.type = type;
14+
protected TypedParameter() {
15+
this.type = ParameterType.STRING;
16+
this.value = null;
17+
}
18+
19+
public TypedParameter(final Boolean value) {
20+
this.type = ParameterType.WHOLE_NUMBER;
21+
this.value = (value ? TRUE : FALSE);
22+
}
23+
24+
public TypedParameter(final String value) {
25+
this.type = ParameterType.STRING;
26+
this.value = value;
27+
}
28+
29+
public TypedParameter(final Long value) {
30+
this.type = ParameterType.WHOLE_NUMBER;
31+
this.value = value;
32+
}
33+
34+
public TypedParameter(final Integer value) {
35+
this.type = ParameterType.WHOLE_NUMBER;
36+
this.value = (value != null ? value.longValue() : null);
37+
}
38+
39+
public TypedParameter(final Short value) {
40+
this.type = ParameterType.WHOLE_NUMBER;
41+
this.value = (value != null ? value.longValue() : null);
42+
}
43+
44+
public TypedParameter(final Double value) {
45+
this.type = ParameterType.FLOATING_POINT_NUMBER;
46+
this.value = value;
47+
}
48+
49+
public TypedParameter(final Float value) {
50+
this.type = ParameterType.FLOATING_POINT_NUMBER;
51+
this.value = (value != null ? value.doubleValue() : null);
52+
}
53+
54+
public TypedParameter(final byte[] value) {
55+
this.type = ParameterType.BYTE_ARRAY;
956
this.value = value;
1057
}
58+
59+
public TypedParameter(final ByteArray value) {
60+
this.type = ParameterType.BYTE_ARRAY;
61+
this.value = (value != null ? value.getBytes() : null);
62+
}
1163
}

src/main/java/com/softwareverde/database/row/JdbcRow.java

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,38 @@ else if (value.type != ParameterType.STRING) {
5252
return (String) value.value;
5353
}
5454

55+
protected Long _getWholeNumber(final String columnName) {
56+
final TypedParameter value = _getValue(columnName);
57+
if (value.value == null) { return null; }
58+
59+
if (value.type == ParameterType.WHOLE_NUMBER) {
60+
return ((Long) value.value);
61+
}
62+
else if (value.type == ParameterType.FLOATING_POINT_NUMBER) {
63+
return ((Double) value.value).longValue();
64+
}
65+
else {
66+
final String stringValue = _getString(columnName);
67+
return Util.parseLong(stringValue);
68+
}
69+
}
70+
71+
protected Double _getFloatingPointNumber(final String columnName) {
72+
final TypedParameter value = _getValue(columnName);
73+
if (value.value == null) { return null; }
74+
75+
if (value.type == ParameterType.FLOATING_POINT_NUMBER) {
76+
return ((Double) value.value);
77+
}
78+
else if (value.type == ParameterType.WHOLE_NUMBER) {
79+
return ((Long) value.value).doubleValue();
80+
}
81+
else {
82+
final String stringValue = _getString(columnName);
83+
return Util.parseDouble(stringValue);
84+
}
85+
}
86+
5587
/**
5688
* Returns the column names in order.
5789
*/
@@ -67,38 +99,36 @@ public String getString(final String columnName) {
6799

68100
@Override
69101
public Integer getInteger(final String columnName) {
70-
final String stringValue = _getString(columnName);
71-
return Util.parseInt(stringValue);
102+
final Long value = _getWholeNumber(columnName);
103+
if (value == null) { return null; }
104+
105+
return value.intValue();
72106
}
73107

74108
@Override
75109
public Long getLong(final String columnName) {
76-
final String stringValue = _getString(columnName);
77-
return Util.parseLong(stringValue);
110+
return _getWholeNumber(columnName);
78111
}
79112

80113
@Override
81114
public Float getFloat(final String columnName) {
82-
final String stringValue = _getString(columnName);
83-
return Util.parseFloat(stringValue);
115+
final Double value = _getFloatingPointNumber(columnName);
116+
if (value == null) { return null; }
117+
118+
return value.floatValue();
84119
}
85120

86121
@Override
87122
public Double getDouble(final String columnName) {
88-
final String stringValue = _getString(columnName);
89-
return Util.parseDouble(stringValue);
123+
return _getFloatingPointNumber(columnName);
90124
}
91125

92126
@Override
93127
public Boolean getBoolean(final String columnName) {
94-
final TypedParameter value = _getValue(columnName);
95-
96-
if (value.type != ParameterType.BOOLEAN) {
97-
final String stringValue = _getString(columnName);
98-
return Util.parseBool(stringValue);
99-
}
128+
final Long value = _getWholeNumber(columnName);
129+
if (value == null) { return null; }
100130

101-
return (boolean) value.value;
131+
return (value > 0L);
102132
}
103133

104134
@Override

src/main/java/com/softwareverde/database/row/JdbcRowFactory.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.softwareverde.database.row;
22

33
import com.softwareverde.database.DatabaseException;
4-
import com.softwareverde.database.query.parameter.ParameterType;
54
import com.softwareverde.database.query.parameter.TypedParameter;
65

76
import java.sql.ResultSet;
@@ -23,6 +22,33 @@ protected static Boolean isBinaryType(final Integer sqlDataType) {
2322
}
2423
}
2524

25+
// NOTE: Types.ROWID is intentionally treated as a String...
26+
protected static Boolean isWholeNumberType(final Integer sqlDataType) {
27+
switch (sqlDataType) {
28+
case Types.BIGINT:
29+
case Types.INTEGER:
30+
case Types.SMALLINT:
31+
case Types.TINYINT:
32+
case Types.BOOLEAN:
33+
case Types.BIT: {
34+
return true;
35+
}
36+
default: { return false; }
37+
}
38+
}
39+
40+
// NOTE: Types.NUMERIC and Types.DECIMAL are fixed-precision types, and are therefore stored internally as strings in order to maintain the precision...
41+
protected static Boolean isFloatingPointNumberType(final Integer sqlDataType) {
42+
switch (sqlDataType) {
43+
case Types.FLOAT:
44+
case Types.DOUBLE:
45+
case Types.REAL: {
46+
return true;
47+
}
48+
default: { return false; }
49+
}
50+
}
51+
2652
public JdbcRow fromResultSet(final ResultSet resultSet) throws DatabaseException {
2753
final JdbcRow jdbcRow = new JdbcRow();
2854

@@ -31,18 +57,25 @@ public JdbcRow fromResultSet(final ResultSet resultSet) throws DatabaseException
3157
for (int i = 0; i < metaData.getColumnCount(); ++i) {
3258
final int columnIndex = (i + 1);
3359
final Integer sqlDataType = metaData.getColumnType(columnIndex);
34-
final Boolean isBinaryType = JdbcRowFactory.isBinaryType(sqlDataType);
3560

3661
final String columnName = metaData.getColumnLabel(columnIndex).toLowerCase();
3762
final TypedParameter typedValue;
3863
{
39-
if (isBinaryType) {
64+
if (JdbcRowFactory.isWholeNumberType(sqlDataType)) {
65+
final Long longValue = resultSet.getLong(columnIndex);
66+
typedValue = new TypedParameter(longValue);
67+
}
68+
else if (JdbcRowFactory.isBinaryType(sqlDataType)) {
4069
final byte[] bytes = resultSet.getBytes(columnIndex);
41-
typedValue = new TypedParameter(bytes, ParameterType.BYTE_ARRAY);
70+
typedValue = new TypedParameter(bytes);
71+
}
72+
else if (JdbcRowFactory.isFloatingPointNumberType(sqlDataType)) {
73+
final Double doubleValue = resultSet.getDouble(columnIndex);
74+
typedValue = new TypedParameter(doubleValue);
4275
}
4376
else {
4477
final String stringValue = resultSet.getString(columnIndex);
45-
typedValue = new TypedParameter(stringValue, ParameterType.STRING);
78+
typedValue = new TypedParameter(stringValue);
4679
}
4780
}
4881

src/test/java/com/softwareverde/database/QueryTests.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,45 @@ public void should_add_multiple_parameter_types_to_query() {
1515
final Query query = new Query("SELECT ?, ?, ?, ?, ?, ?");
1616
final Boolean booleanObject = true;
1717
final Integer integerObject = -2;
18+
final Float floatObject = 7.777F;
1819

1920
// Action
20-
query.setParameter(true);
21-
query.setParameter(booleanObject);
22-
query.setParameter("String");
23-
query.setParameter(2);
24-
query.setParameter(integerObject);
25-
query.setParameter(new byte[] { 0x00, 0x01 });
21+
query.setParameter(true); // 0
22+
query.setParameter(booleanObject); // 1
23+
query.setParameter("String"); // 2
24+
query.setParameter(2); // 3
25+
query.setParameter(integerObject); // 4
26+
query.setParameter(new byte[] { 0x00, 0x01 }); // 5
27+
query.setParameter(floatObject); // 6
28+
query.setParameter(7F); // 7
2629

2730
// Assert
2831
final List<TypedParameter> parameterValues = query.getParameters();
2932

30-
Assert.assertEquals(true, parameterValues.get(0).value);
31-
Assert.assertEquals(ParameterType.BOOLEAN, parameterValues.get(0).type);
33+
Assert.assertEquals(1L, parameterValues.get(0).value);
34+
Assert.assertEquals(ParameterType.WHOLE_NUMBER, parameterValues.get(0).type);
3235

33-
Assert.assertEquals(true, parameterValues.get(1).value);
34-
Assert.assertEquals(ParameterType.BOOLEAN, parameterValues.get(1).type);
36+
Assert.assertEquals(1L, parameterValues.get(1).value);
37+
Assert.assertEquals(ParameterType.WHOLE_NUMBER, parameterValues.get(1).type);
3538

3639
Assert.assertEquals("String", parameterValues.get(2).value);
3740
Assert.assertEquals(ParameterType.STRING, parameterValues.get(2).type);
3841

39-
Assert.assertEquals("2", parameterValues.get(3).value);
40-
Assert.assertEquals(ParameterType.STRING, parameterValues.get(3).type);
42+
Assert.assertEquals(2L, parameterValues.get(3).value);
43+
Assert.assertEquals(ParameterType.WHOLE_NUMBER, parameterValues.get(3).type);
4144

42-
Assert.assertEquals("-2", parameterValues.get(4).value);
43-
Assert.assertEquals(ParameterType.STRING, parameterValues.get(4).type);
45+
Assert.assertEquals(-2L, parameterValues.get(4).value);
46+
Assert.assertEquals(ParameterType.WHOLE_NUMBER, parameterValues.get(4).type);
4447

4548
Assert.assertEquals(2, ((byte[]) parameterValues.get(5).value).length);
4649
Assert.assertEquals(ParameterType.BYTE_ARRAY, parameterValues.get(5).type);
4750
Assert.assertEquals((byte) 0x00, ((byte[]) parameterValues.get(5).value)[0]);
4851
Assert.assertEquals((byte) 0x01, ((byte[]) parameterValues.get(5).value)[1]);
52+
53+
Assert.assertEquals(7.777D, ((Double) parameterValues.get(6).value), 0.0001F);
54+
Assert.assertEquals(ParameterType.FLOATING_POINT_NUMBER, parameterValues.get(6).type);
55+
56+
Assert.assertEquals(7D, parameterValues.get(7).value);
57+
Assert.assertEquals(ParameterType.FLOATING_POINT_NUMBER, parameterValues.get(7).type);
4958
}
5059
}

0 commit comments

Comments
 (0)