blob: 1bbabae856d9bd70d4243c3e258828816eba6907 [file] [log] [blame]
Michael Hanl72c7b832015-09-03 08:42:15 +02001package de.ids_mannheim.korap.handlers;
2
margaretha992178e2017-02-10 13:21:21 +01003import java.util.Collection;
4import java.util.HashMap;
5import java.util.List;
6
Michael Hanl72c7b832015-09-03 08:42:15 +02007import org.slf4j.Logger;
Michael Hanlac113e52016-01-19 15:49:20 +01008import org.slf4j.LoggerFactory;
Michael Hanl72c7b832015-09-03 08:42:15 +02009import org.springframework.dao.DataAccessException;
10import org.springframework.dao.IncorrectResultSizeDataAccessException;
11import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
12import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
13import org.springframework.jdbc.support.GeneratedKeyHolder;
14import org.springframework.jdbc.support.KeyHolder;
15
margaretha992178e2017-02-10 13:21:21 +010016import de.ids_mannheim.korap.config.Attributes;
17import de.ids_mannheim.korap.exceptions.KustvaktException;
18import de.ids_mannheim.korap.exceptions.StatusCodes;
margaretha82c061e2017-04-18 18:03:11 +020019import de.ids_mannheim.korap.exceptions.DatabaseException;
margaretha992178e2017-02-10 13:21:21 +010020import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
21import de.ids_mannheim.korap.interfaces.db.ResourceOperationIface;
22import de.ids_mannheim.korap.resources.KustvaktResource;
23import de.ids_mannheim.korap.resources.ResourceFactory;
24import de.ids_mannheim.korap.user.User;
25import de.ids_mannheim.korap.utils.SqlBuilder;
Michael Hanl72c7b832015-09-03 08:42:15 +020026
27/**
28 * Created by hanl on 7/21/14.
29 */
30//todo: auditing // testing
margaretha7e16d6f2017-04-18 18:01:59 +020031public class ResourceDao<T extends KustvaktResource>
32 implements ResourceOperationIface<T> {
Michael Hanl72c7b832015-09-03 08:42:15 +020033
Michael Hanlac113e52016-01-19 15:49:20 +010034 private static Logger log = LoggerFactory.getLogger(ResourceDao.class);
Michael Hanl72c7b832015-09-03 08:42:15 +020035 protected final NamedParameterJdbcTemplate jdbcTemplate;
36
Michael Hanl8abaf9e2016-05-23 16:46:35 +020037
38 public ResourceDao (PersistenceClient client) {
Michael Hanl72c7b832015-09-03 08:42:15 +020039 this.jdbcTemplate = (NamedParameterJdbcTemplate) client.getSource();
40 }
41
Michael Hanl8abaf9e2016-05-23 16:46:35 +020042
Michael Hanl72c7b832015-09-03 08:42:15 +020043 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +020044 public Class<T> type () {
Michael Hanl482f30d2015-09-25 12:39:46 +020045 return (Class<T>) KustvaktResource.class;
Michael Hanl72c7b832015-09-03 08:42:15 +020046 }
47
Michael Hanl8abaf9e2016-05-23 16:46:35 +020048
Michael Hanldaf86602016-05-12 14:31:52 +020049 // todo: testing
Michael Hanl72c7b832015-09-03 08:42:15 +020050 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +020051 public List<T> getResources (Collection<Object> ids, User user)
Michael Hanl72c7b832015-09-03 08:42:15 +020052 throws KustvaktException {
Michael Hanl8abaf9e2016-05-23 16:46:35 +020053 String sql = "SELECT rs.*, rt.name_path FROM resource_store as rs inner join resource_tree as rt"
54 + " on rs.id=rt.child_id WHERE rs.id IN (:ids);";
Michael Hanldaf86602016-05-12 14:31:52 +020055 MapSqlParameterSource parameters = new MapSqlParameterSource();
56 parameters.addValue("ids", ids);
57 try {
58 return (List<T>) this.jdbcTemplate.query(sql, parameters,
59 new RowMapperFactory.ResourceMapper());
Michael Hanl8abaf9e2016-05-23 16:46:35 +020060 }
61 catch (DataAccessException e) {
margaretha7e16d6f2017-04-18 18:01:59 +020062 log.error(
63 "Exception during database retrieval for ids '" + ids + "'",
64 e);
margaretha82c061e2017-04-18 18:03:11 +020065 throw new DatabaseException(user.getId(), "resource_store",
margaretha7e16d6f2017-04-18 18:01:59 +020066 StatusCodes.DB_GET_FAILED,
67 "Exception during database retrieval for ids '" + ids,
68 ids.toString());
Michael Hanldaf86602016-05-12 14:31:52 +020069 }
70
Michael Hanl72c7b832015-09-03 08:42:15 +020071 }
72
Michael Hanl8abaf9e2016-05-23 16:46:35 +020073
Michael Hanl72c7b832015-09-03 08:42:15 +020074 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +020075 public int updateResource (T resource, User user) throws KustvaktException {
Michael Hanl72c7b832015-09-03 08:42:15 +020076 MapSqlParameterSource source = new MapSqlParameterSource();
77 source.addValue("id", resource.getPersistentID());
78 source.addValue("name", resource.getName());
79 source.addValue("desc", resource.getDescription());
margaretha7e16d6f2017-04-18 18:01:59 +020080 source.addValue("data", resource.getStringData());
Michael Hanl9b84eff2016-01-27 17:11:11 +010081 final String sql = "UPDATE resource_store set name=:name, data=:data, description=:desc where persistent_id=:id;";
Michael Hanl72c7b832015-09-03 08:42:15 +020082 try {
83 return this.jdbcTemplate.update(sql, source);
Michael Hanl8abaf9e2016-05-23 16:46:35 +020084 }
85 catch (DataAccessException e) {
margaretha7e16d6f2017-04-18 18:01:59 +020086 log.error("Exception during database update for id '"
87 + resource.getPersistentID() + "'", e);
margaretha82c061e2017-04-18 18:03:11 +020088 throw new DatabaseException(user.getId(), "resource_store",
margaretha7e16d6f2017-04-18 18:01:59 +020089 StatusCodes.DB_UPDATE_FAILED, "Exception during database update for id '"
90 + resource.getPersistentID(), resource.toString());
Michael Hanl72c7b832015-09-03 08:42:15 +020091 }
92 }
93
Michael Hanl8abaf9e2016-05-23 16:46:35 +020094
Michael Hanl72c7b832015-09-03 08:42:15 +020095 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +020096 public int[] updateResources (List<T> resources, User user)
Michael Hanl72c7b832015-09-03 08:42:15 +020097 throws KustvaktException {
98 return new int[1];
99 }
100
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200101
Michael Hanl72c7b832015-09-03 08:42:15 +0200102 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200103 public <T extends KustvaktResource> T findbyId (String id, User user)
Michael Hanl72c7b832015-09-03 08:42:15 +0200104 throws KustvaktException {
105 MapSqlParameterSource source = new MapSqlParameterSource();
106 source.addValue("pid", id);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200107 String sql = "SELECT rs.*, rt.name_path FROM resource_store as rs inner join resource_tree as rt"
margaretha5af82372017-02-16 14:22:58 +0100108 + " on rs.id=rt.child_id WHERE rs.persistent_id=:pid";
109 //group by rs.id;";
Michael Hanl72c7b832015-09-03 08:42:15 +0200110 try {
111 return (T) this.jdbcTemplate.queryForObject(sql, source,
112 new RowMapperFactory.ResourceMapper());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200113 }
114 catch (DataAccessException e) {
margaretha7e16d6f2017-04-18 18:01:59 +0200115 // empty results
Michael Hanl72c7b832015-09-03 08:42:15 +0200116 return null;
117 }
118 }
119
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200120
121 public KustvaktResource findbyPath (String path, User user)
Michael Hanl72c7b832015-09-03 08:42:15 +0200122 throws KustvaktException {
123 MapSqlParameterSource source = new MapSqlParameterSource();
124 source.addValue("path", path);
125 String sql = "SELECT rs.*, rt.name_path FROM resource_store as rs inner join resource_tree as rt on rs.id=rt.child_id WHERE rt.name_path=:path;";
126 try {
127 return this.jdbcTemplate.queryForObject(sql, source,
128 new RowMapperFactory.ResourceMapper());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200129 }
130 catch (DataAccessException e) {
Michael Hanl72c7b832015-09-03 08:42:15 +0200131 if (e instanceof IncorrectResultSizeDataAccessException)
132 throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
133 "invalid request path given!", path);
134 return null;
135 }
136 }
137
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200138
Michael Hanl72c7b832015-09-03 08:42:15 +0200139 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200140 public <T extends KustvaktResource> T findbyId (Integer id, User user)
Michael Hanl72c7b832015-09-03 08:42:15 +0200141 throws KustvaktException {
142 MapSqlParameterSource source = new MapSqlParameterSource();
143 source.addValue("id", id);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200144 String sql = "SELECT rs.*, rt.name_path FROM resource_store as rs inner join resource_tree as rt on rs.id=rt.child_id "
145 + "WHERE rs.id=:id group by rs.id order by rt.depth desc;";
Michael Hanl72c7b832015-09-03 08:42:15 +0200146 try {
147 return (T) this.jdbcTemplate.queryForObject(sql, source,
148 new RowMapperFactory.ResourceMapper());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200149 }
150 catch (DataAccessException e) {
Michael Hanl7368aa42016-02-05 18:15:47 +0100151 if (e instanceof IncorrectResultSizeDataAccessException)
152 throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
153 "invalid request id given!", String.valueOf(id));
Michael Hanl72c7b832015-09-03 08:42:15 +0200154 return null;
155 }
156 }
157
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200158
Michael Hanl72c7b832015-09-03 08:42:15 +0200159 @Override
Michael Hanlcb2d3f92016-06-02 17:34:06 +0200160 public <T1 extends KustvaktResource> List<T1> findbyPartialId (String id,
161 User user) throws KustvaktException {
162 return null;
163 }
164
165
166 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200167 public int storeResource (T resource, User user) throws KustvaktException {
Michael Hanl72c7b832015-09-03 08:42:15 +0200168 MapSqlParameterSource source = new MapSqlParameterSource();
169 KeyHolder holder = new GeneratedKeyHolder();
170 // parent_id necessary so trigger can be used for tree insert!
171 final String sql, parid;
Michael Hanl19390652016-01-16 11:01:24 +0100172 SqlBuilder b = new SqlBuilder("resource_store");
173 b.insert(Attributes.NAME, Attributes.PARENT_ID,
174 Attributes.PERSISTENT_ID, Attributes.DESCRIPTION,
175 Attributes.CREATOR, Attributes.TYPE, Attributes.CREATED);
margaretha7e16d6f2017-04-18 18:01:59 +0200176 b.params(
177 ":name, :parent, :pid, :desc, :ow, :type, :created, :dtype, :data");
Michael Hanl19390652016-01-16 11:01:24 +0100178
Michael Hanl72c7b832015-09-03 08:42:15 +0200179 if (resource.getParentID() == null) {
Michael Hanl9b84eff2016-01-27 17:11:11 +0100180 sql = "INSERT INTO resource_store (name, parent_id, persistent_id, description, creator, type, created, data) "
181 + "VALUES (:name, :parent, :pid, :desc, :ow, :type, :created, :data);";
Michael Hanl72c7b832015-09-03 08:42:15 +0200182 parid = null;
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200183 }
184 else {
Michael Hanl19390652016-01-16 11:01:24 +0100185 // fixme: use trigger for consistency check!
Michael Hanl9b84eff2016-01-27 17:11:11 +0100186 sql = "INSERT INTO resource_store (name, parent_id, persistent_id, description, creator, type, created, data) "
187 + "select :name, id, :pid, :desc, :ow, :type, :created, :data from resource_store where persistent_id=:parent;";
Michael Hanl72c7b832015-09-03 08:42:15 +0200188 parid = resource.getParentID();
189 }
190
191 source.addValue("name", resource.getName());
192 source.addValue("pid", resource.getPersistentID());
193 source.addValue("parent", parid);
Michael Hanlc4446022016-02-12 18:03:17 +0100194 source.addValue("ow", user.getId());
Michael Hanl72c7b832015-09-03 08:42:15 +0200195 source.addValue("desc", resource.getDescription());
196 source.addValue("type",
197 ResourceFactory.getResourceMapping(resource.getClass()));
Michael Hanl19390652016-01-16 11:01:24 +0100198 source.addValue("created", System.currentTimeMillis());
margaretha992178e2017-02-10 13:21:21 +0100199 source.addValue("data", resource.getStringData());
Michael Hanl9b84eff2016-01-27 17:11:11 +0100200
Michael Hanl72c7b832015-09-03 08:42:15 +0200201 try {
margaretha7e16d6f2017-04-18 18:01:59 +0200202 this.jdbcTemplate.update(sql, source, holder,
203 new String[] { "id" });
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200204 }
205 catch (DataAccessException e) {
margaretha7e16d6f2017-04-18 18:01:59 +0200206 log.error("Exception during database store for id '"
207 + resource.getPersistentID() + "'", e);
margaretha82c061e2017-04-18 18:03:11 +0200208 throw new DatabaseException(user.getId(), "resource_store",
margaretha7e16d6f2017-04-18 18:01:59 +0200209 StatusCodes.DB_INSERT_FAILED,
210 "Exception during database store for id '"
211 + resource.getPersistentID(),
212 resource.toString());
Michael Hanl72c7b832015-09-03 08:42:15 +0200213 }
214 resource.setId(holder.getKey().intValue());
215 return resource.getId();
216 }
217
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200218
Michael Hanl72c7b832015-09-03 08:42:15 +0200219 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200220 public int deleteResource (String id, User user) throws KustvaktException {
Michael Hanl72c7b832015-09-03 08:42:15 +0200221 MapSqlParameterSource source = new MapSqlParameterSource();
222 source.addValue("id", id);
223 final String sql = "DELETE FROM resource_store WHERE persistent_id=:id;";
224 try {
225 return this.jdbcTemplate.update(sql, source);
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200226 }
227 catch (DataAccessException e) {
margaretha82c061e2017-04-18 18:03:11 +0200228 throw new DatabaseException(user.getId(), "resource_store",
margaretha7e16d6f2017-04-18 18:01:59 +0200229 StatusCodes.DB_DELETE_FAILED, "Operation DELETE failed.",
230 id);
Michael Hanl72c7b832015-09-03 08:42:15 +0200231 }
232 }
Michael Hanl19390652016-01-16 11:01:24 +0100233
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200234
Michael Hanl19390652016-01-16 11:01:24 +0100235 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200236 public int size () {
Michael Hanl9b84eff2016-01-27 17:11:11 +0100237 final String sql = "SELECT COUNT(*) FROM resource_store;";
238 try {
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200239 return this.jdbcTemplate.queryForObject(sql,
240 new HashMap<String, Object>(), Integer.class);
241 }
242 catch (DataAccessException e) {
Michael Hanlc4446022016-02-12 18:03:17 +0100243 return 0;
Michael Hanl9b84eff2016-01-27 17:11:11 +0100244 }
Michael Hanlf1e85e72016-01-21 16:55:45 +0100245 }
Michael Hanldaf86602016-05-12 14:31:52 +0200246
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200247
Michael Hanldaf86602016-05-12 14:31:52 +0200248 @Override
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200249 public int truncate () {
Michael Hanldaf86602016-05-12 14:31:52 +0200250 final String sql = "DELETE FROM resource_store;";
251 try {
252 return this.jdbcTemplate.update(sql, new HashMap<String, Object>());
Michael Hanl8abaf9e2016-05-23 16:46:35 +0200253 }
254 catch (DataAccessException e) {
Michael Hanldaf86602016-05-12 14:31:52 +0200255 return -1;
256 }
257 }
Michael Hanlf8fcc7a2016-06-03 17:41:07 +0200258
Michael Hanl72c7b832015-09-03 08:42:15 +0200259}