All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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