
com.github.gkutiel.ObjectStore Maven / Gradle / Ivy
package com.github.gkutiel;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.h2.Driver;
public class ObjectStore {
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public static @interface Index {}
private final Map objs = new HashMap<>();
private final Map keys = new HashMap<>();
private final Connection con;
private final List indexableFields;
private final String insert;
private long id = 0;
public static ObjectStore create(final Class c) {
return new ObjectStore<>(c);
}
private static List getIndexableFields(final Class> c) {
final List indexedFields = new ArrayList<>();
final Field[] declaredFields = c.getDeclaredFields();
AccessibleObject.setAccessible(declaredFields, true);
for (final Field field : declaredFields)
if (field.isAnnotationPresent(Index.class)) indexedFields.add(field);
return indexedFields;
}
private ObjectStore(final Class c) {
try {
indexableFields = getIndexableFields(c);
new Driver();
con = DriverManager.getConnection("jdbc:h2:mem:");
con.createStatement().execute(Temp.table(indexableFields));
insert = Temp.ps(indexableFields.size());
} catch (final SQLException e) {
throw new RuntimeException(e);
}
}
synchronized public List get(final String cond, final Object... args) {
try {
final List ts = new ArrayList<>();
final ResultSet rs = getSelect(cond, args).executeQuery();
while (rs.next()) {
final long id = rs.getLong(1);
ts.add(objs.get(id));
}
return ts;
} catch (final SQLException e) {
throw new RuntimeException(e);
}
}
synchronized public void remove(final T t) {
try {
final Long id = keys.get(t);
if (id == null) return;
keys.remove(t);
objs.remove(id);
con.createStatement().execute("DELETE FROM T WHERE id = " + id);
} catch (final SQLException e) {
throw new RuntimeException(e);
}
}
public synchronized void store(final T t) {
try {
getInsert(t).executeUpdate();
objs.put(id, t);
keys.put(t, id);
} catch (final SQLException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
private PreparedStatement getInsert(final T t) throws IllegalAccessException, SQLException {
final PreparedStatement s = con.prepareStatement(insert);
int i = 1;
s.setLong(i, ++id);
for (final Field field : indexableFields)
Statement.set(s, ++i, field.get(t));
return s;
}
private PreparedStatement getSelect(final String cond, final Object... args) throws SQLException {
final PreparedStatement ps = con.prepareStatement("SELECT id FROM T WHERE " + cond);
int i = 1;
for (final Object v : args)
Statement.set(ps, i++, v);
return ps;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy