EP / schemaless

Schemaless Data Store.

Clone this repository (size: 166.6 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/EP/schemaless
commit 28: 97d34cb380f5
parent 27: 55b082e1077b
branch: default
Simplify type conversion between sql and java.
Eung-ju PARK <eungju at google dot com>
18 months ago

Changed (Δ11.9 KB):

raw changeset »

src/main/java/schemaless/storage/MySqlIndexStorage.java (17 lines added, 14 lines removed)

src/main/java/schemaless/storage/MySqlQueryBuilder.java (5 lines added, 8 lines removed)

src/main/java/schemaless/storage/jdbc/CharSqlType.java (22 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/DateSqlType.java (21 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/EnumSqlType.java (23 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/NullAwareSqlType.java (33 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/ObjectSqlType.java (19 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/SqlType.java (11 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/SqlTypeRegistry.java (37 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/StringSqlType.java (19 lines added, 0 lines removed)

src/main/java/schemaless/storage/jdbc/UuidSqlType.java (21 lines added, 0 lines removed)

src/test/java/schemaless/JsonSerializerTest.java (13 lines added, 95 lines removed)

src/test/java/schemaless/Naturalist.java (82 lines added, 0 lines removed)

src/test/java/schemaless/Scientist.java (10 lines added, 0 lines removed)

src/test/java/schemaless/gardener/IndexGardeningTest.java (1 lines added, 1 lines removed)

src/test/java/schemaless/storage/MySql.sql (26 lines added, 0 lines removed)

src/test/java/schemaless/storage/MySqlIndexStorageTest.java (12 lines added, 8 lines removed)

src/test/java/schemaless/storage/MySqlQueryBuilderTest.java (2 lines added, 1 lines removed)

Up to file-list src/main/java/schemaless/storage/MySqlIndexStorage.java:

@@ -19,11 +19,14 @@ import schemaless.IndexDefinition;
19
19
import schemaless.IndexRow;
20
20
import schemaless.IndexStorage;
21
21
import schemaless.query.Query;
22
import schemaless.storage.jdbc.SqlType;
23
import schemaless.storage.jdbc.SqlTypeRegistry;
22
24
23
25
public class MySqlIndexStorage implements IndexStorage {
24
	private final MySqlJdbcAdapter jdbcAdapter = new MySqlJdbcAdapter();
26
	private final SqlTypeRegistry sqlTypeRegistry = new SqlTypeRegistry();
25
27
	private final IndexDefinition definition;
26
28
	private final DataSource dataSource;
29
	private final SqlType entityIdSqlType;
27
30
	private final String tableName;
28
31
	private final String insertSql;
29
32
	private final String updateSql;
@@ -35,6 +38,7 @@ public class MySqlIndexStorage implement
35
38
		this.definition = definition;
36
39
		this.dataSource = dataSource;
37
40
		this.tableName = definition.entityDefinition().name() + "_index_" + definition.name();
41
		this.entityIdSqlType = sqlTypeRegistry.get(UUID.class);
38
42
		this.insertSql = insertSql();
39
43
		this.updateSql = updateSql();
40
44
		this.deleteSql = deleteSql();
@@ -107,14 +111,10 @@ public class MySqlIndexStorage implement
107
111
			for (String each : definition.properties()) {
108
112
				Class<?> type = definition.entityDefinition().getPropertyDescriptor(each).getPropertyType();
109
113
				Object value = PropertyUtils.getProperty(entity, each);
110
				if (type == UUID.class) {
111
					jdbcAdapter.setParameter(statement, parameterIndex, (UUID) value);
112
				} else {
113
					statement.setObject(parameterIndex, value);
114
				}
114
				sqlTypeRegistry.get(type).set(statement, parameterIndex, value);
115
115
				parameterIndex++;
116
116
			}
117
			jdbcAdapter.setParameter(statement, parameterIndex, id);
117
			entityIdSqlType.set(statement, parameterIndex, id);
118
118
			assertAffectedCount(1, statement.executeUpdate());
119
119
		} catch (Exception e) {
120
120
			throw new DataAccessException("Cannot insert the index of the entity " + id + " into the table " + tableName, e);
@@ -133,10 +133,12 @@ public class MySqlIndexStorage implement
133
133
			statement = connection.prepareStatement(updateSql);
134
134
			int parameterIndex = 1;
135
135
			for (String each : definition.properties()) {
136
				statement.setObject(parameterIndex, PropertyUtils.getProperty(entity, each));
136
				Class<?> type = definition.entityDefinition().getPropertyDescriptor(each).getPropertyType();
137
				Object value = PropertyUtils.getProperty(entity, each);
138
				sqlTypeRegistry.get(type).set(statement, parameterIndex, value);
137
139
				parameterIndex++;
138
140
			}
139
			jdbcAdapter.setParameter(statement, parameterIndex, id);
141
			entityIdSqlType.set(statement, parameterIndex, id);
140
142
			assertAffectedCount(1, statement.executeUpdate());
141
143
		} catch (Exception e) {
142
144
			throw new DataAccessException("Cannot update the index of the entity " + id + " on the table " + tableName, e);
@@ -152,7 +154,7 @@ public class MySqlIndexStorage implement
152
154
		try {
153
155
			connection = dataSource.getConnection();
154
156
			statement = connection.prepareStatement(deleteSql);
155
			jdbcAdapter.setParameter(statement, 1, id);
157
			entityIdSqlType.set(statement, 1, id);
156
158
			assertAffectedCount(1, statement.executeUpdate());
157
159
		} catch (SQLException e) {
158
160
			throw new DataAccessException("Cannot delete the index of the " + id + " on the table " + tableName, e);
@@ -183,13 +185,13 @@ public class MySqlIndexStorage implement
183
185
		ResultSet rs = null;
184
186
		try {
185
187
			connection = dataSource.getConnection();
186
			MySqlQueryBuilder queryBuilder = new MySqlQueryBuilder(tableName, definition.entityDefinition());
188
			MySqlQueryBuilder queryBuilder = new MySqlQueryBuilder(tableName, definition.entityDefinition(), sqlTypeRegistry);
187
189
			query.accept(queryBuilder);
188
190
			statement = queryBuilder.buildStatement(connection);
189
191
			rs = statement.executeQuery();
190
192
			List<UUID> result = new ArrayList<UUID>();
191
193
			while (rs.next()) {
192
				result.add(jdbcAdapter.getColumnAsUuid(rs, 1));
194
				result.add((UUID) entityIdSqlType.get(rs, 1, UUID.class));
193
195
			}
194
196
			return result;
195
197
		} catch (SQLException e) {
@@ -208,14 +210,15 @@ public class MySqlIndexStorage implement
208
210
		try {
209
211
			connection = dataSource.getConnection();
210
212
			statement = connection.prepareStatement(findSql);
211
			jdbcAdapter.setParameter(statement, 1, id);
213
			entityIdSqlType.set(statement, 1, id);
212
214
			rs = statement.executeQuery();
213
215
			IndexRow indexRow = null;
214
216
			if (rs.next()) {
215
217
				indexRow = new IndexRow();
216
218
				int columnIndex = 1;
217
219
				for (String each : definition.properties()) {
218
					indexRow.put(each, rs.getObject(columnIndex));
220
					Class<?> type = definition.entityDefinition().getPropertyDescriptor(each).getPropertyType();
221
					indexRow.put(each, sqlTypeRegistry.get(type).get(rs, columnIndex++, type));
219
222
				}
220
223
			}
221
224
			return indexRow;

Up to file-list src/main/java/schemaless/storage/MySqlQueryBuilder.java:

@@ -5,7 +5,6 @@ import java.sql.PreparedStatement;
5
5
import java.sql.SQLException;
6
6
import java.util.ArrayList;
7
7
import java.util.List;
8
import java.util.UUID;
9
8
10
9
import schemaless.EntityDefinition;
11
10
import schemaless.query.And;
@@ -21,18 +20,20 @@ import schemaless.query.Predicate;
21
20
import schemaless.query.Query;
22
21
import schemaless.query.QueryVisitor;
23
22
import schemaless.query.Sort;
23
import schemaless.storage.jdbc.SqlTypeRegistry;
24
24
import schemaless.support.JdbcHelper;
25
25
26
26
class MySqlQueryBuilder implements QueryVisitor {
27
	private MySqlJdbcAdapter jdbcAdapter = new MySqlJdbcAdapter(); 
28
27
	private String tableName;
29
28
	private EntityDefinition entityDefinition;
29
	private SqlTypeRegistry sqlTypeRegistry;
30
30
	private StringBuilder sql;
31
31
	private List<SqlParameter> parameters;
32
32
	
33
	public MySqlQueryBuilder(String tableName, EntityDefinition entityDefinition) {
33
	public MySqlQueryBuilder(String tableName, EntityDefinition entityDefinition, SqlTypeRegistry sqlTypeRegistry) {
34
34
		this.tableName = tableName;
35
35
		this.entityDefinition = entityDefinition;
36
		this.sqlTypeRegistry = sqlTypeRegistry;
36
37
		this.sql = new StringBuilder();
37
38
		parameters = new ArrayList<SqlParameter>();
38
39
	}
@@ -131,11 +132,7 @@ class MySqlQueryBuilder implements Query
131
132
		PreparedStatement statement = connection.prepareStatement(sql);
132
133
		int parameterIndex = 1;
133
134
		for (SqlParameter each : parameters) {
134
			if (each.type == UUID.class) {
135
				jdbcAdapter.setParameter(statement, parameterIndex++, (UUID) each.value);
136
			} else {
137
				statement.setObject(parameterIndex++, each.value);
138
			}
135
			sqlTypeRegistry.get(each.type).set(statement, parameterIndex++, each.value);
139
136
		}
140
137
		return statement;
141
138
	}

Up to file-list src/main/java/schemaless/storage/jdbc/CharSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
7
public class CharSqlType extends NullAwareSqlType {
8
	public CharSqlType(int sqlTypeCode) {
9
		super(sqlTypeCode);
10
	}
11
12
	@Override
13
	public void setNotNull(PreparedStatement statement, int index, Object value)	throws SQLException {
14
		statement.setString(index, value.toString());
15
	}
16
17
	@Override
18
	public Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
19
		String value = resultSet.getString(index);
20
		return value == null ? null : value.charAt(0);
21
	}
22
}

Up to file-list src/main/java/schemaless/storage/jdbc/DateSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
import java.util.Date;
7
8
public class DateSqlType extends NullAwareSqlType {
9
	public DateSqlType(int sqlTypeCode) {
10
		super(sqlTypeCode);
11
	}
12
13
	public void setNotNull(PreparedStatement statement, int index, Object value) throws SQLException {
14
		statement.setTimestamp(index, new java.sql.Timestamp(((Date) value).getTime()));
15
	}
16
17
	public Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
18
		Date value = resultSet.getTimestamp(index);
19
		return value == null ? null : new Date(value.getTime()); 
20
	}
21
}

Up to file-list src/main/java/schemaless/storage/jdbc/EnumSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
7
@SuppressWarnings("unchecked")
8
public class EnumSqlType extends NullAwareSqlType {
9
	public EnumSqlType(int sqlTypeCode) {
10
		super(sqlTypeCode);
11
	}
12
13
	@Override
14
	public void setNotNull(PreparedStatement statement, int index, Object value)	throws SQLException {
15
		statement.setString(index, ((Enum) value).name());
16
	}
17
18
	@Override
19
	public Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
20
		String value = resultSet.getString(index);
21
		return value == null ? null : Enum.valueOf((Class) javaType, value);
22
	}
23
}

Up to file-list src/main/java/schemaless/storage/jdbc/NullAwareSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
7
public abstract class NullAwareSqlType implements SqlType {
8
	protected int sqlTypeCode;
9
10
	public NullAwareSqlType(int sqlTypeCode) {
11
		this.sqlTypeCode = sqlTypeCode;
12
	}
13
	
14
	public void set(PreparedStatement statement, int index, Object value) throws SQLException {
15
		if (value == null) {
16
			statement.setNull(index, sqlTypeCode);
17
		} else {
18
			setNotNull(statement, index, value);
19
		}
20
	}
21
22
	public Object get(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
23
		Object value = getNullable(resultSet, index, javaType);
24
		if (resultSet.wasNull()) {
25
			return null;
26
		}
27
		return value;
28
	}
29
	
30
	public abstract void setNotNull(PreparedStatement statement, int index, Object value) throws SQLException;
31
32
	public abstract Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException;
33
}

Up to file-list src/main/java/schemaless/storage/jdbc/ObjectSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
7
public class ObjectSqlType extends NullAwareSqlType {
8
	public ObjectSqlType(int sqlTypeCode) {
9
		super(sqlTypeCode);
10
	}
11
12
	public void setNotNull(PreparedStatement statement, int index, Object value) throws SQLException {
13
		statement.setObject(index, value);
14
	}
15
16
	public Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
17
		return resultSet.getObject(index);
18
	}
19
}

Up to file-list src/main/java/schemaless/storage/jdbc/SqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
7
public interface SqlType {
8
	void set(PreparedStatement statement, int index, Object value) throws SQLException;
9
10
	Object get(ResultSet resultSet, int index, Class<?> javaType) throws SQLException;
11
}

Up to file-list src/main/java/schemaless/storage/jdbc/SqlTypeRegistry.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.Types;
4
import java.util.Date;
5
import java.util.HashMap;
6
import java.util.Map;
7
import java.util.UUID;
8
9
public class SqlTypeRegistry {
10
	private final SqlType defaultSqlType = new ObjectSqlType(Types.OTHER);
11
	private final SqlType enumSqlType = new EnumSqlType(Types.VARCHAR);
12
	private Map<Class<?>, SqlType> sqlTypes;
13
	
14
	public SqlTypeRegistry() {
15
		 sqlTypes = new HashMap<Class<?>, SqlType>();
16
		 register(char.class, new CharSqlType(Types.CHAR));
17
		 register(Character.class, new CharSqlType(Types.CHAR));
18
		 register(String.class, new StringSqlType(Types.VARCHAR));
19
		 register(Date.class, new DateSqlType(Types.TIMESTAMP));
20
		 register(UUID.class, new UuidSqlType(Types.CHAR));
21
	}
22
	
23
	public void register(Class<?> javaType, SqlType sqlType) {
24
		 sqlTypes.put(javaType, sqlType);
25
	}
26
27
	public SqlType get(Class<?> javaType) {
28
		SqlType result = sqlTypes.get(javaType);
29
		if (result != null) {
30
			return result;
31
		}
32
		if (javaType.isEnum()) {
33
			return enumSqlType;
34
		}
35
		return defaultSqlType;
36
	}
37
}

Up to file-list src/main/java/schemaless/storage/jdbc/StringSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
7
public class StringSqlType extends NullAwareSqlType {
8
	public StringSqlType(int sqlTypeCode) {
9
		super(sqlTypeCode);
10
	}
11
12
	public void setNotNull(PreparedStatement statement, int index, Object value) throws SQLException {
13
		statement.setString(index, (String) value);
14
	}
15
16
	public Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
17
		return resultSet.getString(index);
18
	}
19
}

Up to file-list src/main/java/schemaless/storage/jdbc/UuidSqlType.java:

1
package schemaless.storage.jdbc;
2
3
import java.sql.PreparedStatement;
4
import java.sql.ResultSet;
5
import java.sql.SQLException;
6
import java.util.UUID;
7
8
public class UuidSqlType extends NullAwareSqlType {
9
	public UuidSqlType(int sqlTypeCode) {
10
		super(sqlTypeCode);
11
	}
12
13
	public void setNotNull(PreparedStatement statement, int index, Object value) throws SQLException {
14
		statement.setString(index, value.toString());
15
	}
16
17
	public Object getNullable(ResultSet resultSet, int index, Class<?> javaType) throws SQLException {
18
		String value = resultSet.getString(index);
19
		return value == null ? null : UUID.fromString(value);
20
	}
21
}

Up to file-list src/test/java/schemaless/JsonSerializerTest.java:

@@ -6,8 +6,6 @@ import java.lang.annotation.ElementType;
6
6
import java.util.Date;
7
7
import java.util.UUID;
8
8
9
import org.apache.commons.lang.builder.EqualsBuilder;
10
import org.apache.commons.lang.builder.ToStringBuilder;
11
9
import org.json.JSONObject;
12
10
import org.json.JSONStringer;
13
11
import org.junit.Before;
@@ -17,7 +15,7 @@ public class JsonSerializerTest {
17
15
	private JsonSerializer dut;
18
16
19
17
	@Before public void beforeEach() {
20
		dut = new JsonSerializer(TestingObject.class);
18
		dut = new JsonSerializer(Naturalist.class);
21
19
	}
22
20
	
23
21
	@Test public void primitiveTypes() {
@@ -89,18 +87,18 @@ public class JsonSerializerTest {
89
87
	}
90
88
	
91
89
	@Test public void serialize() {
92
		TestingObject entity = new TestingObject();
93
		entity.setNull(null);
94
		entity.setBoolean(true);
95
		entity.setByte((byte) 1);
96
		entity.setShort((short) 2);
97
		entity.setInt(4);
98
		entity.setLong(8L);
99
		entity.setChar('a');
100
		entity.setString("abc");
101
		entity.setEnum(ElementType.METHOD);
102
		entity.setDate(new Date(1L));
103
		entity.setUuid(UUID.randomUUID());
90
		Naturalist entity = new Naturalist();
91
		entity.setNullType(null);
92
		entity.setBooleanType(true);
93
		entity.setByteType((byte) 1);
94
		entity.setShortType((short) 2);
95
		entity.setIntType(4);
96
		entity.setLongType(8L);
97
		entity.setCharType('a');
98
		entity.setStringType("abc");
99
		entity.setEnumType(ElementType.METHOD);
100
		entity.setDateType(new Date(1L));
101
		entity.setId(UUID.randomUUID());
104
102
		
105
103
		String serialized = dut.serializeAsString(entity);
106
104
		System.out.println(serialized);
@@ -109,84 +107,4 @@ public class JsonSerializerTest {
109
107
		System.out.println(deserialized);
110
108
		assertEquals(entity, deserialized);
111
109
	}
112
	
113
	private static class ParentObject {
114
		public String getGetterOnly() {
115
			return "hello";
116
		}
117
		
118
		public void setSetterOnly(String ignore) {
119
		}
120
	}
121
	
122
	public static class TestingObject extends ParentObject {
123
		private Object null_;
124
		private boolean boolean_;
125
		private byte byte_;
126
		private short short_;
127
		private int int_;
128
		private long long_;
129
		private char char_;
130
		private String string;
131
		private ElementType enum_;
132
		private UUID uuid;
133
		private Date date;
134
135
		public Object getNull() {
136
			return null_;
137
		}
138
		public void setNull(Object null_) {
139
			this.null_ = null;
140
		}
141
		
142
		public boolean getBoolean() { return boolean_; }
143
		public void setBoolean(boolean boolean_) { this.boolean_ = boolean_; }
144
145
		public byte getByte() { return byte_; }
146
		public void setByte(byte byte_) { this.byte_ = byte_; }
147
148
		public short getShort() { return short_; }
149
		public void setShort(short short_) { this.short_ = short_; }
150
151
		public int getInt() {
152
			return int_;
153
		}
154
		public void setInt(int int_) {
155
			this.int_ = int_;
156
		}
157
		
158
		public long getLong() { return long_; }
159
		public void setLong(long long_) { this.long_ = long_; }
160
161
		public char getChar() { return char_; }
162
		public void setChar(char char_) { this.char_ = char_; }
163
164
		public String getString() { return string; }
165
		public void setString(String string) { this.string = string; }
166
167
		public ElementType getEnum() { return enum_; }
168
		public void setEnum(ElementType enum_) { this.enum_ = enum_; }
169
170
		public Date getDate() {
171
			return date;
172
		}
173
		public void setDate(Date date) {
174
			this.date = date;
175
		}
176
177
		public UUID getUuid() {
178
			return uuid;
179
		}
180
		public void setUuid(UUID uuid) {
181
			this.uuid = uuid;
182
		}
183
		
184
		public String toString() {
185
			return ToStringBuilder.reflectionToString(this);
186
		}
187
		
188
		public boolean equals(Object that) {
189
			return EqualsBuilder.reflectionEquals(this, that);
190
		}
191
	}
192
110
}

Up to file-list src/test/java/schemaless/Naturalist.java:

1
package schemaless;
2
3
import java.lang.annotation.ElementType;
4
import java.util.Date;
5
import java.util.UUID;
6
7
import org.apache.commons.lang.builder.EqualsBuilder;
8
import org.apache.commons.lang.builder.ToStringBuilder;
9
10
public class Naturalist extends Scientist {
11
	private UUID id;
12
	private String nullType;
13
	private boolean booleanType;
14
	private byte byteType;
15
	private short shortType;
16
	private int intType;
17
	private long longType;
18
	private char charType;
19
	private String stringType;
20
	private ElementType enumType;
21
	private Date dateType;
22
23
	public Naturalist() {
24
	}
25
	
26
	public static Naturalist sample() {
27
		Naturalist x = new Naturalist();
28
		x.id = UUID.randomUUID();
29
		x.nullType = null;
30
		x.booleanType = true;
31
		x.byteType = 1;
32
		x.shortType = 2;
33
		x.intType = 4;
34
		x.longType = 8;
35
		x.charType = 'a';
36
		x.stringType = "ABC";
37
		x.enumType = ElementType.METHOD;
38
		x.dateType = new Date();
39
		return x;
40
	}
41
	
42
	public UUID getId() { return id; }
43
	public void setId(UUID uuid) { this.id = uuid; }
44
	
45
	public Object getNullType() { return nullType; }
46
	public void setNullType(Object null_) { 	this.nullType = null; }
47
	
48
	public boolean getBooleanType() { return booleanType; }
49
	public void setBooleanType(boolean boolean_) { this.booleanType = boolean_; }
50
51
	public byte getByteType() { return byteType; }
52
	public void setByteType(byte byte_) { this.byteType = byte_; }
53
54
	public short getShortType() { return shortType; }
55
	public void setShortType(short short_) { this.shortType = short_; }
56
57
	public int getIntType() { return intType; }
58
	public void setIntType(int int_) {	this.intType = int_; }
59
	
60
	public long getLongType() { return longType; }
61
	public void setLongType(long long_) { this.longType = long_; }
62
63
	public char getCharType() { return charType; }
64
	public void setCharType(char char_) { this.charType = char_; }
65
66
	public String getStringType() { return stringType; }
67
	public void setStringType(String string) { this.stringType = string; }
68
69
	public ElementType getEnumType() { return enumType; }
70
	public void setEnumType(ElementType enum_) { this.enumType = enum_; }
71
72
	public Date getDateType() { return dateType; }
73
	public void setDateType(Date date) { this.dateType = date; }
74
75
	public String toString() {
76
		return ToStringBuilder.reflectionToString(this);
77
	}
78
	
79
	public boolean equals(Object that) {
80
		return EqualsBuilder.reflectionEquals(this, that);
81
	}
82
}

Up to file-list src/test/java/schemaless/Scientist.java:

1
package schemaless;
2
3
class Scientist {
4
	public String getGetterOnly() {
5
		return "hello";
6
	}
7
	
8
	public void setSetterOnly(String ignore) {
9
	}
10
}

Up to file-list src/test/java/schemaless/gardener/IndexGardeningTest.java:

@@ -46,7 +46,7 @@ public class IndexGardeningTest {
46
46
	
47
47
	@Test public void indexInspectionFailed() {
48
48
		mockery.checking(new Expectations() {{
49
			one(indexStorage).find(entity.getId()); will(throwException(new Exception("BLAH")));
49
			one(indexStorage).find(entity.getId()); will(throwException(new RuntimeException("BLAH")));
50
50
			one(listener).failed(entityRow);
51
51
		}});
52
52
		dut.inspect(entityRow);

Up to file-list src/test/java/schemaless/storage/MySql.sql:

@@ -14,3 +14,29 @@ CREATE TABLE feed_index_user_id (
14
14
    entity_id CHAR(36) NOT NULL UNIQUE,
15
15
    PRIMARY KEY (user_id, entity_id)
16
16
) ENGINE=InnoDB;
17
18
DROP TABLE IF EXISTS naturalist;
19
CREATE TABLE naturalist (
20
    added_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
21
    id CHAR(36) NOT NULL,
22
    updated TIMESTAMP NOT NULL,
23
    body MEDIUMBLOB,
24
    UNIQUE KEY (id),
25
    KEY (updated)
26
) ENGINE=InnoDB;
27
28
DROP TABLE IF EXISTS naturalist_index_all;
29
CREATE TABLE naturalist_index_all (
30
	null_type VARCHAR(127) NULL,
31
	boolean_type BOOLEAN NOT NULL,
32
	byte_type TINYINT NOT NULL,
33
	short_type SMALLINT NOT NULL,
34
	int_type INT NOT NULL,
35
	long_type BIGINT NOT NULL,
36
	char_type CHAR(1) NOT NULL,
37
	string_type VARCHAR(255) NULL,
38
	enum_type VARCHAR(127) NULL,
39
	date_type DATETIME NULL,
40
    entity_id CHAR(36) NOT NULL UNIQUE,
41
    PRIMARY KEY (entity_id)
42
) ENGINE=InnoDB;

Up to file-list src/test/java/schemaless/storage/MySqlIndexStorageTest.java:

@@ -2,8 +2,10 @@ package schemaless.storage;
2
2
3
3
import static org.junit.Assert.*;
4
4
5
import java.lang.annotation.ElementType;
5
6
import java.sql.SQLException;
6
7
import java.util.Arrays;
8
import java.util.Date;
7
9
import java.util.List;
8
10
import java.util.UUID;
9
11
@@ -12,8 +14,8 @@ import org.junit.After;
12
14
import org.junit.Before;
13
15
import org.junit.Test;
14
16
17
import schemaless.Naturalist;
15
18
import schemaless.EntityDefinition;
16
import schemaless.Feed;
17
19
import schemaless.IndexDefinition;
18
20
import schemaless.IndexStorage;
19
21
import schemaless.query.Equal;
@@ -23,15 +25,16 @@ import schemaless.storage.MySqlIndexStor
23
25
public class MySqlIndexStorageTest {
24
26
	private BasicDataSource dataSource;
25
27
	private IndexStorage dut;
26
	private Feed entity = new Feed(UUID.randomUUID(), "someone"); 
28
	private Naturalist entity; 
27
29
28
30
	@Before public void beforeEach() {
29
31
		dataSource = JdbcTestHelper.dataSource();
30
32
31
		EntityDefinition entityDefinition = new EntityDefinition("feed", Feed.class);
32
		IndexDefinition index = new IndexDefinition(entityDefinition, "user_id", new String[] { "userId" });
33
		EntityDefinition entityDefinition = new EntityDefinition("naturalist", Naturalist.class);
34
		IndexDefinition index = new IndexDefinition(entityDefinition, "all", new String[] { "nullType", "booleanType", "byteType", "shortType", "intType", "longType", "charType", "stringType", "enumType", "dateType" });
33
35
		dut = new MySqlIndexStorage(index, dataSource);
34
36
		dut.deleteAll();
37
		entity = Naturalist.sample();
35
38
	}
36
39
	
37
40
	@After public void afterEach() throws SQLException {
@@ -45,7 +48,8 @@ public class MySqlIndexStorageTest {
45
48
46
49
	@Test public void update() {
47
50
		dut.insert(entity);
48
		dut.update(new Feed(entity.getId(), "another"));
51
		entity.setEnumType(ElementType.FIELD);
52
		dut.update(entity);
49
53
	}
50
54
51
55
	@Test public void delete() {
@@ -55,15 +59,15 @@ public class MySqlIndexStorageTest {
55
59
	
56
60
	@Test public void findAll() {
57
61
		dut.insert(entity);
58
		Feed another = new Feed(UUID.randomUUID(), entity.getUserId());
62
		Naturalist another = Naturalist.sample();
59
63
		dut.insert(another);
60
		List<UUID> actual = dut.findAll(new Query(new Equal("userId", "someone")));
64
		List<UUID> actual = dut.findAll(new Query(new Equal("charType", entity.getCharType())));
61
65
		assertTrue(actual.containsAll(Arrays.asList(another.getId(), entity.getId())));
62
66
	}
63
67
64
68
	@Test public void find() {
65
69
		assertNull(dut.find(entity.getId()));
66
70
		dut.insert(entity);
67
		assertEquals(entity.getUserId(), dut.find(entity.getId()).get("userId"));
71
		assertEquals(entity.getCharType(), dut.find(entity.getId()).get("charType"));
68
72
	}
69
73
}

Up to file-list src/test/java/schemaless/storage/MySqlQueryBuilderTest.java:

@@ -18,6 +18,7 @@ import schemaless.query.NotEqual;
18
18
import schemaless.query.Or;
19
19
import schemaless.query.Query;
20
20
import schemaless.query.Sort;
21
import schemaless.storage.jdbc.SqlTypeRegistry;
21
22
22
23
public class MySqlQueryBuilderTest {
23
24
	private MySqlQueryBuilder dut;
@@ -41,7 +42,7 @@ public class MySqlQueryBuilderTest {
41
42
	}
42
43
	
43
44
	@Before public void beforeEach() {
44
		dut = new MySqlQueryBuilder("table_name", new EntityDefinition("table_name", TestingObject.class));
45
		dut = new MySqlQueryBuilder("table_name", new EntityDefinition("table_name", TestingObject.class), new SqlTypeRegistry());
45
46
	}
46
47
47
48
	@Test public void equal() {