package org.springframework.data.jdbc.test.adt;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Struct;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import oracle.jdbc.OracleTypes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.jdbc.support.oracle.SqlReturnStructArray;
import org.springframework.data.jdbc.support.oracle.SqlStructArrayValue;
import org.springframework.data.jdbc.support.oracle.StructMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.object.StoredProcedure;
import org.springframework.stereotype.Repository;
import org.springframework.data.jdbc.support.oracle.SqlArrayValue;
import org.springframework.data.jdbc.support.oracle.SqlReturnArray;
import org.springframework.data.jdbc.support.oracle.SqlReturnSqlData;
import org.springframework.data.jdbc.support.oracle.SqlReturnStruct;
import org.springframework.data.jdbc.support.oracle.SqlStructValue;
/**
* @author trisberg
*/
@Repository
@SuppressWarnings("unused")
public class ClassicAdvancedDataTypesDao implements AdvancedDataTypesDao {
private AddSqlActorProc addSqlActorProc;
private GetSqlActorProc getSqlActorProc;
private AddActorProc addActorProc;
private GetActorProc getActorProc;
private GetActorNamesProc getActorNamesProc;
private DeleteActorsProc deleteActorsProc;
private ReadActorsProc readActorsProc;
private GetActorArrayProc getActorArrayProc;
private SaveActorArrayProc saveActorArrayProc;
@Autowired
public void init(DataSource dataSource) {
this.addSqlActorProc =
new AddSqlActorProc(dataSource);
this.getSqlActorProc =
new GetSqlActorProc(dataSource);
this.addActorProc =
new AddActorProc(dataSource);
this.getActorProc =
new GetActorProc(dataSource);
this.getActorNamesProc =
new GetActorNamesProc(dataSource);
this.deleteActorsProc =
new DeleteActorsProc(dataSource);
this.readActorsProc =
new ReadActorsProc(dataSource);
this.getActorArrayProc =
new GetActorArrayProc(dataSource);
this.saveActorArrayProc =
new SaveActorArrayProc(dataSource);
}
public void addSqlActor(final SqlActor actor) {
addSqlActorProc.execute(actor);
}
public SqlActor getSqlActor(Long id) {
return getSqlActorProc.execute(id);
}
public void addActor(final Actor actor) {
addActorProc.execute(actor);
}
public Actor getActor(Long id) {
return getActorProc.execute(id);
}
public String[] getActorNames() {
return getActorNamesProc.execute();
}
public void deleteActors(final Long[] ids) {
deleteActorsProc.execute(ids);
}
@SuppressWarnings("unchecked")
public List<Actor> getActors() {
return readActorsProc.execute();
}
public List<Actor> getAllActors() {
Object[] actors = getActorArrayProc.execute();
List<Actor> result = new ArrayList<Actor>();
for (Object actor : actors) {
if (actor instanceof Actor) {
result.add((Actor) actor);
}
}
return result;
}
public void saveActors(List<Actor> actors) {
saveActorArrayProc.execute(actors);
}
private class AddSqlActorProc extends StoredProcedure {
public AddSqlActorProc(DataSource dataSource) {
super(dataSource, "add_actor");
declareParameter(new SqlParameter("in_actor", Types.STRUCT, "ACTOR_TYPE"));
}
@SuppressWarnings("unchecked")
public void execute(Actor actor) {
Map in = Collections.singletonMap("in_actor", actor);
this.execute(in);
}
}
private class GetSqlActorProc extends StoredProcedure {
public GetSqlActorProc(DataSource dataSource) {
super(dataSource, "get_actor");
declareParameter(new SqlParameter("in_actor_id", Types.NUMERIC));
declareParameter(
new SqlOutParameter("out_actor", Types.STRUCT, "ACTOR_TYPE",
new SqlReturnSqlData(SqlActor.class))
);
}
@SuppressWarnings("unchecked")
public SqlActor execute(Long id) {
Map in = Collections.singletonMap("in_actor_id", id);
Map out = this.execute(in);
return (SqlActor) out.get("out_actor");
}
}
private class AddActorProc extends StoredProcedure {
public AddActorProc(DataSource dataSource) {
super(dataSource, "add_actor");
declareParameter(new SqlParameter("in_actor", Types.STRUCT, "ACTOR_TYPE"));
}
@SuppressWarnings("unchecked")
public void execute(Actor actor) {
Map in = Collections.singletonMap("in_actor", new SqlStructValue(actor));
this.execute(in);
}
}
private class GetActorProc extends StoredProcedure {
public GetActorProc(DataSource dataSource) {
super(dataSource, "get_actor");
declareParameter(new SqlParameter("in_actor_id", Types.NUMERIC));
declareParameter(
new SqlOutParameter("out_actor", Types.STRUCT, "ACTOR_TYPE",
new SqlReturnStruct(Actor.class))
);
}
@SuppressWarnings("unchecked")
public Actor execute(Long id) {
Map in = Collections.singletonMap("in_actor_id", id);
Map out = this.execute(in);
return (Actor) out.get("out_actor");
}
}
private class GetActorNamesProc extends StoredProcedure {
public GetActorNamesProc(DataSource dataSource) {
super(dataSource, "get_actor_names");
setFunction(true);
declareParameter(new SqlOutParameter("return", Types.ARRAY, "ACTOR_NAME_ARRAY",
new SqlReturnArray()));
}
@SuppressWarnings("unchecked")
public String[] execute() {
Map in = Collections.emptyMap();
Map out = this.execute(in);
return (String[]) out.get("return");
}
}
private class DeleteActorsProc extends StoredProcedure {
public DeleteActorsProc(DataSource dataSource) {
super(dataSource, "delete_actors");
declareParameter(new SqlParameter("in_actor_ids", Types.ARRAY, "ACTOR_ID_ARRAY"));
}
@SuppressWarnings("unchecked")
public void execute(Long[] ids) {
Map in = Collections.singletonMap("in_actor_ids", new SqlArrayValue(ids));
this.execute(in);
}
}
private class ReadActorsProc extends StoredProcedure {
public ReadActorsProc(DataSource dataSource) {
super(dataSource, "read_actors");
declareParameter(
new SqlOutParameter("out_actors_cur", OracleTypes.CURSOR,
ParameterizedBeanPropertyRowMapper.newInstance(Actor.class))
);
}
@SuppressWarnings("unchecked")
public List execute() {
Map in = Collections.emptyMap();
Map out = this.execute(in);
return (List) out.get("out_actors_cur");
}
}
private class GetActorArrayProc extends StoredProcedure {
public GetActorArrayProc(DataSource dataSource) {
super(dataSource, "get_all_actor_types");
setFunction(true);
declareParameter(new SqlOutParameter("return", Types.ARRAY, "ACTOR_ARRAY_TYPE",
new SqlReturnStructArray<Actor>(
new StructMapper<Actor>() {
public Struct toStruct(Actor source, Connection conn, String typeName) throws SQLException {
throw new InvalidDataAccessApiUsageException("Not implemented");
}
public Actor fromStruct(Struct struct) throws SQLException {
Actor a = new Actor();
Object[] attributes = struct.getAttributes();
a.setId(Long.valueOf(((Number) attributes[0]).longValue()));
a.setName(String.valueOf(attributes[1]));
a.setAge(Integer.valueOf(((Number) attributes[2]).intValue()));
return a;
}
}
)));
}
@SuppressWarnings("unchecked")
public Object[] execute() {
Map in = Collections.emptyMap();
Map out = this.execute(in);
return (Object[]) out.get("return");
}
}
private class SaveActorArrayProc extends StoredProcedure {
public SaveActorArrayProc(DataSource dataSource) {
super(dataSource, "save_actors");
declareParameter(new SqlParameter("in_actors", Types.ARRAY, "ACTOR_ARRAY_TYPE"));
}
@SuppressWarnings("unchecked")
public void execute(List<Actor> actors) {
Map in = Collections.singletonMap("in_actors",
new SqlStructArrayValue<Actor>(actors.toArray(new Actor[0]), new ActorMapper(), "ACTOR_TYPE"));
this.execute(in);
}
}
}