package org.simpleflatmapper.jdbc;
import org.simpleflatmapper.util.CheckedConsumer;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
/**
*
* @param <T> the target type
* @param <K> the key type
*/
public class ConnectedCrud<T, K> {
private final TransactionTemplate transactionTemplate;
private final Crud<T, K> delegate;
public ConnectedCrud(TransactionTemplate transactionTemplate, Crud<T, K> delegate) {
this.transactionTemplate = transactionTemplate;
this.delegate = delegate;
}
/**
* insert value into the db through the specified connection.
*
* @param value the value
* @throws SQLException if an error occurs
*/
public void create(final T value) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.create(connection, value);
return null;
}
});
}
/**
* insert values into the db through the specified connection.
*
* @param values the values
* @throws SQLException if an error occurs
*/
public void create(final Collection<T> values) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.create(connection, values);
return null;
}
});
}
/**
* insert value into the db through the specified connection.
* Callback keyConsumer with the generated key if one was.
*
* @param value the value
* @param keyConsumer the key consumer
* @param <RH> the type of keyConsumer
* @return the keyConsumer
* @throws SQLException
*/
public <RH extends CheckedConsumer<? super K>> RH create(final T value, final RH keyConsumer) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.create(connection, value, keyConsumer);
return null;
}
});
return keyConsumer;
}
/**
* insert values into the db through the specified connection.
* Callback keyConsumer for the generated keys.
*
* @param values the values
* @param keyConsumer the key consumer
* @param <RH> the type of keyConsumer
* @return the keyConsumer
* @throws SQLException
*/
public <RH extends CheckedConsumer<? super K>> RH create(final Collection<T> values, final RH keyConsumer) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.create(connection, values, keyConsumer);
return null;
}
});
return keyConsumer;
}
/**
* retrieve the object with the specified key.
*
* @param key the key
* @return the object or null if not found
* @throws SQLException if an error occurs
*/
public T read(final K key) throws SQLException {
return
transactionTemplate
.doInTransaction(new SQLFunction<Connection, T>() {
@Override
public T apply(Connection connection) throws SQLException {
return delegate.read(connection, key);
}
});
}
/**
* retrieve the objects with the specified keys and pass them to the consumer.
*
* @param keys the keys
* @param consumer the handler that is callback for each row
* @throws SQLException if an error occurs
*/
public <RH extends CheckedConsumer<? super T>> RH read(final Collection<K> keys, final RH consumer) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.read(connection, keys, consumer);
return null;
}
});
return consumer;
}
/**
* update the object.
*
* @param value the object
* @throws SQLException if an error occurs
*/
public void update(final T value) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.update(connection, value);
return null;
}
});
}
/**
* update the objects.
*
* @param values the objects
* @throws SQLException if an error occurs
*/
public void update(final Collection<T> values) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.update(connection, values);
return null;
}
});
}
/**
* delete the object with the specified key.
*
* @param key the key
* @throws SQLException if an error occurs
*/
public void delete(final K key) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.delete(connection, key);
return null;
}
});
}
/**
* delete the objects with the specified keys.
*
* @param keys the keys
* @throws SQLException if an error occurs
*/
public void delete(final Collection<K> keys) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.delete(connection, keys);
return null;
}
});
}
/**
* UPSERT only supported on Mysql
* @param value the value
* @throws SQLException
* @throws UnsupportedOperationException
*/
public void createOrUpdate(final T value) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.createOrUpdate(connection, value);
return null;
}
});
}
/**
* UPSERT only supported on Mysql
* @param values the values to upsert
* @throws SQLException
* @throws UnsupportedOperationException
*/
public void createOrUpdate(final Collection<T> values) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.createOrUpdate(connection, values);
return null;
}
});
}
/**
* UPSERT only supported on Mysql and Postgres 9.5.
* Used the callback with caution has Mysql will return an incremented id event for when no insert actually occurred.
* @param value the value to upsert
* @param keyConsumer generated key consumer
* @param <RH> the keyConsumer type
* @return the keyConsumer
* @throws SQLException
*/
public <RH extends CheckedConsumer<? super K>> RH createOrUpdate(final T value, final RH keyConsumer) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.createOrUpdate(connection, value, keyConsumer);
return null;
}
});
return keyConsumer;
}
/**
* UPSERT only supported on Mysql and Postgres 9.5.
* Used the callback with caution has Mysql will return an incremented id event for when no insert actually occurred.
* @param values the values to insert
* @param keyConsumer generated key consumer
* @param <RH> the keyConsumer type
* @return the keyConsumer
* @throws SQLException
*/
public <RH extends CheckedConsumer<? super K>> RH createOrUpdate(final Collection<T> values, final RH keyConsumer) throws SQLException {
transactionTemplate
.doInTransaction(new SQLFunction<Connection, Object>() {
@Override
public Object apply(Connection connection) throws SQLException {
delegate.createOrUpdate(connection, values, keyConsumer);
return null;
}
});
return keyConsumer;
}
public Crud<T, K> crud() {
return delegate;
}
public <P> ConnectedSelectQuery<T, P> where(final String whereClause, final Type paramClass) {
SelectQuery<T, P> selectQuery = delegate.where(whereClause, paramClass);
return new ConnectedSelectQuery<T, P>(selectQuery, transactionTemplate);
}
}