diff --git a/backend/pom.xml b/backend/pom.xml
index 8246cb7..2b07314 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -32,7 +32,7 @@
io.dropwizard
- dropwizard-jdbi3
+ dropwizard-hibernate
${dropwizard.version}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/ObservationsApplication.java b/backend/src/main/java/uk/co/neviyn/Observations/ObservationsApplication.java
index f7efe74..3ebdeea 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/ObservationsApplication.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/ObservationsApplication.java
@@ -2,11 +2,14 @@ package uk.co.neviyn.Observations;
import io.dropwizard.Application;
import io.dropwizard.assets.AssetsBundle;
-import io.dropwizard.jdbi3.JdbiFactory;
+import io.dropwizard.db.DataSourceFactory;
+import io.dropwizard.hibernate.HibernateBundle;
import io.dropwizard.jersey.setup.JerseyEnvironment;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
-import org.jdbi.v3.core.Jdbi;
+import uk.co.neviyn.Observations.core.Observation;
+import uk.co.neviyn.Observations.core.Site;
+import uk.co.neviyn.Observations.core.Tutor;
import uk.co.neviyn.Observations.dao.ObservationDao;
import uk.co.neviyn.Observations.dao.SiteDao;
import uk.co.neviyn.Observations.dao.TutorDao;
@@ -16,6 +19,18 @@ import uk.co.neviyn.Observations.resources.SiteResource;
public class ObservationsApplication extends Application {
+ private final HibernateBundle hibernate = new HibernateBundle(
+ Observation.class,
+ Tutor.class,
+ Site.class
+ ) {
+ @Override
+ public DataSourceFactory getDataSourceFactory(ObservationsConfiguration configuration) {
+ return configuration.getDataSourceFactory();
+ }
+ };
+
+
public static void main(String[] args) throws Exception {
new ObservationsApplication().run(args);
}
@@ -23,27 +38,22 @@ public class ObservationsApplication extends Application bootstrap) {
super.initialize(bootstrap);
+ bootstrap.addBundle(hibernate);
bootstrap.addBundle(new AssetsBundle("/assets/", "/", "/index.html"));
}
@Override
public void run(ObservationsConfiguration observationsConfiguration, Environment environment) {
final JerseyEnvironment jersey = environment.jersey();
- final JdbiFactory factory = new JdbiFactory();
- final Jdbi jdbi = factory.build(environment, observationsConfiguration.getDataSourceFactory(), "database");
- TutorDao tutorDao = jdbi.onDemand(TutorDao.class);
- SiteDao siteDao = jdbi.onDemand(SiteDao.class);
- ObservationDao observationDao = jdbi.onDemand(ObservationDao.class);
+ TutorDao tutorDao = new TutorDao(hibernate.getSessionFactory());
+ SiteDao siteDao = new SiteDao(hibernate.getSessionFactory());
+ ObservationDao observationDao = new ObservationDao(hibernate.getSessionFactory());
jersey.register(tutorDao);
jersey.register(siteDao);
jersey.register(observationDao);
- siteDao.createSiteTable();
- tutorDao.createTutorTable();
- observationDao.createObservationTable();
- observationDao.createObservationTutorTable();
final TutorResource tutorResource = new TutorResource(tutorDao);
jersey.register(tutorResource);
- final ObservationResource observationResource = new ObservationResource(observationDao);
+ final ObservationResource observationResource = new ObservationResource(observationDao, tutorDao, siteDao);
jersey.register(observationResource);
final SiteResource siteResource = new SiteResource(siteDao);
jersey.register(siteResource);
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStats.java b/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStats.java
index d93042c..ed993a6 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStats.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStats.java
@@ -1,14 +1,10 @@
package uk.co.neviyn.Observations.api;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
-import org.jdbi.v3.core.mapper.RowMapper;
-import org.jdbi.v3.core.statement.StatementContext;
import org.joda.time.LocalDate;
@Data
@@ -18,16 +14,9 @@ public class AverageStats {
@NonNull
@JsonProperty
- private float monitoring, control, conservatism, teamwork, knowledge;
+ private double monitoring, control, conservatism, teamwork, knowledge;
@NonNull
@JsonProperty
private LocalDate date;
-
- public static class Mapper implements RowMapper {
- public AverageStats map(ResultSet rs, StatementContext ctx) throws SQLException {
- return new AverageStats(rs.getFloat("monitoring"), rs.getFloat("control"), rs.getFloat("conservatism"),
- rs.getFloat("teamwork"), rs.getFloat("knowledge"), new LocalDate(rs.getDate("date")));
- }
- }
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStatsChartJs.java b/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStatsChartJs.java
index 2ff320e..96d82fa 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStatsChartJs.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/api/AverageStatsChartJs.java
@@ -22,7 +22,7 @@ public class AverageStatsChartJs {
private List datasets = new ArrayList<>();
public AverageStatsChartJs(List inputData){
- List monitoring = new ArrayList<>(),
+ List monitoring = new ArrayList<>(),
control = new ArrayList<>(),
conservatism = new ArrayList<>(),
teamwork = new ArrayList<>(),
@@ -54,6 +54,6 @@ public class AverageStatsChartJs {
@NonNull
@JsonProperty
- private final List data;
+ private final List data;
}
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/api/NewObservation.java b/backend/src/main/java/uk/co/neviyn/Observations/api/NewObservation.java
index 0fc967a..5842339 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/api/NewObservation.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/api/NewObservation.java
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.*;
+import uk.co.neviyn.Observations.core.ObservationEntry;
@Data
@NoArgsConstructor
@@ -12,11 +13,11 @@ public class NewObservation {
@NonNull
@JsonProperty
- private int siteId;
+ private long siteId;
@NonNull
@JsonProperty
- private List tutorIds;
+ private List tutorIds;
@NonNull
@JsonProperty
@@ -28,6 +29,6 @@ public class NewObservation {
@NonNull
@JsonProperty
- private String rawData;
+ private List rawData;
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/BaseEntity.java b/backend/src/main/java/uk/co/neviyn/Observations/core/BaseEntity.java
new file mode 100644
index 0000000..1f34e27
--- /dev/null
+++ b/backend/src/main/java/uk/co/neviyn/Observations/core/BaseEntity.java
@@ -0,0 +1,23 @@
+package uk.co.neviyn.Observations.core;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.NonNull;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+@Data
+@MappedSuperclass
+@NoArgsConstructor
+@AllArgsConstructor
+class BaseEntity {
+ @NonNull
+ @JsonProperty
+ @Id
+ @GeneratedValue
+ private long id;
+}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java b/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java
index 4fffc4a..6898648 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/core/Observation.java
@@ -2,30 +2,30 @@ package uk.co.neviyn.Observations.core;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.List;
+import java.util.Set;
import lombok.*;
-import org.apache.commons.lang3.SerializationUtils;
-import org.jdbi.v3.core.mapper.RowMapper;
-import org.jdbi.v3.core.statement.StatementContext;
import org.joda.time.DateTime;
-import uk.co.neviyn.Observations.api.ObservationEntry;
+import javax.persistence.*;
+
+@EqualsAndHashCode(callSuper = true)
+@Entity
+@Table(name = "OBSERVATION")
@Data
@NoArgsConstructor
-@AllArgsConstructor
-public class Observation {
+@AllArgsConstructor(access = AccessLevel.PROTECTED)
+public class Observation extends BaseEntity{
- @NonNull
@JsonProperty
- private int id;
+ @ManyToOne
+ @JoinColumn(name="site_id", nullable=false)
+ private Site site;
- @NonNull
@JsonProperty
- private int siteId;
+ @ManyToMany(mappedBy = "observations")
+ private Set tutors;
@NonNull
@JsonProperty
@@ -41,49 +41,9 @@ public class Observation {
@NonNull
@JsonProperty
- private List rawData;
+ private List observations;
@NonNull
@JsonProperty
private DateTime date;
-
- public Observation(int siteId, String observed, int monitoring, int control, int conservatism, int teamwork,
- int knowledge, List rawData) {
- this.siteId = siteId;
- this.observed = observed;
- this.monitoring = monitoring;
- this.control = control;
- this.conservatism = conservatism;
- this.teamwork = teamwork;
- this.knowledge = knowledge;
- this.rawData = rawData;
- }
-
- private Observation(int id, int siteId, String observed, String type, int monitoring, int control, int conservatism,
- int teamwork, int knowledge, byte[] rawData, DateTime date) {
- this.id = id;
- this.siteId = siteId;
- this.observed = observed;
- this.type = TrainingType.valueOf(type.toUpperCase());
- this.monitoring = monitoring;
- this.control = control;
- this.conservatism = conservatism;
- this.teamwork = teamwork;
- this.knowledge = knowledge;
- this.rawData = SerializationUtils.deserialize(rawData);
- this.date = date;
- }
-
- public byte[] serializeRawData(){
- return SerializationUtils.serialize((Serializable) rawData);
- }
-
- public static class Mapper implements RowMapper {
-
- public Observation map(ResultSet rs, StatementContext ctx) throws SQLException {
- return new Observation(rs.getInt("id"), rs.getInt("siteId"), rs.getString("observed"), rs.getString("type"),
- rs.getInt("monitoring"), rs.getInt("control"), rs.getInt("conservatism"), rs.getInt("teamwork"),
- rs.getInt("knowledge"), rs.getBytes("rawData"), new DateTime(rs.getDate("date")));
- }
- }
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/api/ObservationEntry.java b/backend/src/main/java/uk/co/neviyn/Observations/core/ObservationEntry.java
similarity index 63%
rename from backend/src/main/java/uk/co/neviyn/Observations/api/ObservationEntry.java
rename to backend/src/main/java/uk/co/neviyn/Observations/core/ObservationEntry.java
index 060c1fc..7238f15 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/api/ObservationEntry.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/core/ObservationEntry.java
@@ -1,15 +1,13 @@
-package uk.co.neviyn.Observations.api;
+package uk.co.neviyn.Observations.core;
import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
+import lombok.*;
+@EqualsAndHashCode(callSuper = true)
@Data
-@AllArgsConstructor
@NoArgsConstructor
-public class ObservationEntry {
+@AllArgsConstructor
+public class ObservationEntry extends BaseEntity{
@NonNull
@JsonProperty
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java b/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java
index cc7297f..3ea673a 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/core/Site.java
@@ -1,32 +1,33 @@
package uk.co.neviyn.Observations.core;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
-import org.jdbi.v3.core.mapper.RowMapper;
-import org.jdbi.v3.core.statement.StatementContext;
+import java.util.Set;
+import lombok.*;
+
+import javax.persistence.*;
+
+@EqualsAndHashCode(callSuper = true)
+@Entity
+@Table(name = "SITE")
@Data
@NoArgsConstructor
-@AllArgsConstructor(access = AccessLevel.PROTECTED)
-public class Site {
-
- @NonNull
- @JsonProperty
- private int id;
+public class Site extends BaseEntity {
@NonNull
@JsonProperty
private String name;
- public static class Mapper implements RowMapper {
- public Site map(ResultSet rs, StatementContext ctx) throws SQLException {
- return new Site(rs.getInt("id"), rs.getString("name"));
- }
+ @JsonProperty
+ @OneToMany(mappedBy="site")
+ private Set tutors;
+
+ @JsonProperty
+ @OneToMany(mappedBy = "site")
+ private Set observations;
+
+ public Site(long id, String name) {
+ super(id);
+ this.name = name;
}
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java b/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java
index 894794b..6bf5de8 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/core/Tutor.java
@@ -1,37 +1,38 @@
package uk.co.neviyn.Observations.core;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import lombok.AccessLevel;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
-import org.jdbi.v3.core.mapper.RowMapper;
-import org.jdbi.v3.core.statement.StatementContext;
+import lombok.*;
+import javax.persistence.*;
+import java.util.Set;
+
+@EqualsAndHashCode(callSuper = true)
+@Entity
+@Table(name = "TUTOR")
@Data
@NoArgsConstructor
-@AllArgsConstructor(access = AccessLevel.PROTECTED)
-public class Tutor {
-
- @NonNull
- @JsonProperty
- private int id;
+public class Tutor extends BaseEntity {
@NonNull
@JsonProperty
private String name;
- @NonNull
@JsonProperty
- private int site;
+ @ManyToOne
+ @JoinColumn(name="site_id", nullable=false)
+ private Site site;
- public static class Mapper implements RowMapper{
+ @JsonProperty
+ @ManyToMany
+ @JoinTable(
+ name = "TUTOR_OBSERVATION",
+ joinColumns = { @JoinColumn(name = "tutor_id")},
+ inverseJoinColumns = { @JoinColumn(name = "observation_id")}
+ )
+ private Set observations;
- public Tutor map(ResultSet rs, StatementContext ctx) throws SQLException {
- return new Tutor(rs.getInt("id"), rs.getString("name"), rs.getInt("site"));
- }
+ public Tutor(long id, String name) {
+ super(id);
+ this.name = name;
}
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/dao/ObservationDao.java b/backend/src/main/java/uk/co/neviyn/Observations/dao/ObservationDao.java
index d22feee..e67ba09 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/dao/ObservationDao.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/dao/ObservationDao.java
@@ -1,59 +1,40 @@
package uk.co.neviyn.Observations.dao;
-import java.util.List;
-import org.jdbi.v3.sqlobject.config.RegisterRowMapper;
-import org.jdbi.v3.sqlobject.customizer.Bind;
-import org.jdbi.v3.sqlobject.customizer.BindBean;
-import org.jdbi.v3.sqlobject.statement.GetGeneratedKeys;
-import org.jdbi.v3.sqlobject.statement.SqlQuery;
-import org.jdbi.v3.sqlobject.statement.SqlUpdate;
-import org.joda.time.DateTime;
+import io.dropwizard.hibernate.AbstractDAO;
+import org.hibernate.SessionFactory;
import uk.co.neviyn.Observations.api.AverageStats;
-import uk.co.neviyn.Observations.api.NewObservation;
import uk.co.neviyn.Observations.core.Observation;
+import uk.co.neviyn.Observations.core.Site;
-@RegisterRowMapper(Observation.Mapper.class)
-public interface ObservationDao {
+import java.util.List;
- @SqlUpdate("CREATE TABLE IF NOT EXISTS observations (id INTEGER PRIMARY KEY, siteId INTEGER, " +
- "observed TEXT, type TEXT, monitoring INTEGER, control INTEGER, conservatism INTEGER, teamwork INTEGER, " +
- "knowledge INTEGER, rawData BLOB, date DATE)")
- void createObservationTable();
+public class ObservationDao extends AbstractDAO {
+ public ObservationDao(SessionFactory sessionFactory) {
+ super(sessionFactory);
+ }
- @SqlUpdate("CREATE TABLE IF NOT EXISTS observation_tutor (tutorId INT NOT NULL, observationId INT NOT NULL, " +
- "FOREIGN KEY (tutorID) REFERENCES tutor(id), FOREIGN KEY (observationId) REFERENCES observations(id))")
- void createObservationTutorTable();
+ public Observation get(long id){
+ return super.get(id);
+ }
- @SqlUpdate("INSERT INTO observations (siteId, observed, type, monitoring, control, conservatism, teamwork, knowledge, " +
- "rawData, date) VALUES (:siteId, :observed, :type, :monitoring, :control, :conservatism, :teamwork, :knowledge, " +
- ":serializeRawData, :date)")
- @GetGeneratedKeys
- int addObservation(@BindBean NewObservation observation, @Bind("date") DateTime date);
+ public Observation persist(Observation observation){
+ return super.persist(observation);
+ }
- @SqlUpdate("INSERT INTO observation_tutor (tutorId, observationId) VALUES (:tutorId, :observationId)")
- void addObservationTutor(@Bind("observationId")int observationId, @Bind("tutorId")int tutorId);
+ public List listAll(){
+ return list(criteriaQuery());
+ }
- @SqlQuery("SELECT * FROM observations WHERE date BETWEEN :startDate AND :endDate")
- List observationsBetweenDates(@Bind("startDate")DateTime startDate, @Bind("endDate")DateTime endDate);
+ public List averageStatsForAll(){
+ final String hql = "select avg(observation.monitoring), avg(observation.control), avg(observation.conservatism), " +
+ "avg(observation.teamwork), avg(observation.knowledge) from observation where group by observation.date";
+ return currentSession().createQuery(hql, AverageStats.class).list();
+ }
- @SqlQuery("SELECT * FROM observations LEFT JOIN observation_tutor ON observation_tutor.observationId = observations.id " +
- "LEFT JOIN tutor ON observation_tutor.tutorId = tutor.id WHERE tutor.id = :tutorId")
- List observationsByTutor(@Bind("tutorId")int tutorId);
-
- @SqlQuery("SELECT * FROM observations WHERE date BETWEEN :startDate AND :endDate " +
- "LEFT JOIN observation_tutor ON observation_tutor.observationId = observations.id " +
- "LEFT JOIN tutor ON observation_tutor.tutorId = tutor.id WHERE tutor.id = :tutorId")
- List observationsByTutorBetweenDates(@Bind("tutorId")int tutorId, @Bind("startDate")DateTime startDate,
- @Bind("endDate")DateTime endDate);
-
- @SqlQuery("SELECT AVG(monitoring) as monitoring, AVG(control) as control, AVG(conservatism) as conservatism, " +
- "AVG(teamwork) as teamwork, AVG(knowledge) as knowledge, date FROM observations GROUP BY date ORDER BY date")
- @RegisterRowMapper(AverageStats.Mapper.class)
- List averageObservationScoresByDay();
-
- @SqlQuery("SELECT MIN(date) FROM observations")
- DateTime earliestEntryDate();
-
- @SqlQuery("SELECT MAX(date) FROM observations")
- DateTime latestEntryDate();
+ public List averageStatsForSite(Site site){
+ final String hql = "select avg(observation.monitoring), avg(observation.control), avg(observation.conservatism), " +
+ "avg(observation.teamwork), avg(observation.knowledge) from observation where observation.site = :site " +
+ "group by observation.date";
+ return currentSession().createQuery(hql, AverageStats.class).setParameter("site", site).list();
+ }
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/dao/SiteDao.java b/backend/src/main/java/uk/co/neviyn/Observations/dao/SiteDao.java
index a682c4e..a0329b9 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/dao/SiteDao.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/dao/SiteDao.java
@@ -1,21 +1,21 @@
package uk.co.neviyn.Observations.dao;
-import java.util.List;
-import org.jdbi.v3.sqlobject.config.RegisterRowMapper;
-import org.jdbi.v3.sqlobject.customizer.Bind;
-import org.jdbi.v3.sqlobject.statement.SqlQuery;
-import org.jdbi.v3.sqlobject.statement.SqlUpdate;
+import io.dropwizard.hibernate.AbstractDAO;
+import org.hibernate.SessionFactory;
import uk.co.neviyn.Observations.core.Site;
-@RegisterRowMapper(Site.Mapper.class)
-public interface SiteDao {
+import java.util.List;
- @SqlUpdate("CREATE TABLE IF NOT EXISTS site (id INTEGER PRIMARY KEY, name VARCHAR(100))")
- void createSiteTable();
+public class SiteDao extends AbstractDAO {
+ public SiteDao(SessionFactory sessionFactory) {
+ super(sessionFactory);
+ }
- @SqlQuery("SELECT * FROM site")
- List allSites();
+ public List listAll(){
+ return list(criteriaQuery());
+ }
- @SqlQuery("SELECT * FROM site WHERE id = :id")
- Site getSiteById(@Bind("id") int id);
+ public Site get(long id){
+ return super.get(id);
+ }
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/dao/TutorDao.java b/backend/src/main/java/uk/co/neviyn/Observations/dao/TutorDao.java
index a9ba41f..a988dc1 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/dao/TutorDao.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/dao/TutorDao.java
@@ -1,29 +1,21 @@
package uk.co.neviyn.Observations.dao;
-import java.util.List;
-import org.jdbi.v3.sqlobject.config.RegisterRowMapper;
-import org.jdbi.v3.sqlobject.customizer.Bind;
-import org.jdbi.v3.sqlobject.customizer.BindBean;
-import org.jdbi.v3.sqlobject.statement.GetGeneratedKeys;
-import org.jdbi.v3.sqlobject.statement.SqlQuery;
-import org.jdbi.v3.sqlobject.statement.SqlUpdate;
+import io.dropwizard.hibernate.AbstractDAO;
+import org.hibernate.SessionFactory;
import uk.co.neviyn.Observations.core.Tutor;
-@RegisterRowMapper(Tutor.Mapper.class)
-public interface TutorDao {
+import java.util.List;
- @SqlUpdate("CREATE TABLE IF NOT EXISTS tutor (id INTEGER PRIMARY KEY, " +
- "name VARCHAR(100), site INT, FOREIGN KEY (site) REFERENCES site(id))")
- void createTutorTable();
+public class TutorDao extends AbstractDAO {
+ public TutorDao(SessionFactory sessionFactory) {
+ super(sessionFactory);
+ }
- @SqlUpdate("INSERT INTO tutor(name, site) VALUES (:name, :site)")
- @GetGeneratedKeys("id")
- int add(@BindBean Tutor tutor);
-
- @SqlQuery("SELECT * FROM tutor WHERE site = :siteId")
- List tutorsForSite(@Bind("siteId")int siteId);
-
- @SqlQuery("SELECT * FROM tutor")
- List allTutors();
+ public Tutor get(long id){
+ return super.get(id);
+ }
+ public List listAll(){
+ return list(criteriaQuery());
+ }
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java b/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java
index 74566ff..d75a959 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/resources/ObservationResource.java
@@ -1,6 +1,9 @@
package uk.co.neviyn.Observations.resources;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
@@ -10,6 +13,8 @@ import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+
+import io.dropwizard.hibernate.UnitOfWork;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
@@ -18,7 +23,12 @@ import uk.co.neviyn.Observations.api.AverageStats;
import uk.co.neviyn.Observations.api.AverageStatsChartJs;
import uk.co.neviyn.Observations.api.NewObservation;
import uk.co.neviyn.Observations.core.Observation;
+import uk.co.neviyn.Observations.core.Site;
+import uk.co.neviyn.Observations.core.TrainingType;
+import uk.co.neviyn.Observations.core.Tutor;
import uk.co.neviyn.Observations.dao.ObservationDao;
+import uk.co.neviyn.Observations.dao.SiteDao;
+import uk.co.neviyn.Observations.dao.TutorDao;
@RequiredArgsConstructor
@Produces(MediaType.APPLICATION_JSON)
@@ -28,32 +38,44 @@ import uk.co.neviyn.Observations.dao.ObservationDao;
public class ObservationResource {
private final ObservationDao dao;
+ private final TutorDao tutorDao;
+ private final SiteDao siteDao;
@POST
- public int add(@NotNull @Valid NewObservation observation){
- final int observationId = dao.addObservation(observation, LocalDate.now().toDateTimeAtStartOfDay());
- log.info("Created observation with ID " + observationId + " at " + DateTime.now().toString());
- for(int tutorId: observation.getTutorIds()){
- dao.addObservationTutor(observationId, tutorId);
+ @UnitOfWork
+ public long add(@NotNull @Valid NewObservation newObservation){
+ final DateTime submissionDate = LocalDate.now().toDateTimeAtStartOfDay();
+ Set tutors = new HashSet<>();
+ for(long l: newObservation.getTutorIds()){
+ tutors.add(tutorDao.get(l));
}
- return observationId;
- }
-
- @Path("/by/{tutorId}")
- @GET
- public List observationsBy(@PathParam("tutorId") int tutorId){
- return dao.observationsByTutor(tutorId);
+ final Site site = siteDao.get(newObservation.getSiteId());
+ Observation observation = new Observation();
+ observation.setSite(site);
+ observation.setTutors(tutors);
+ observation.setObserved(newObservation.getObserved());
+ observation.setType(TrainingType.valueOf(newObservation.getType()));
+ observation.setMonitoring(newObservation.getMonitoring());
+ observation.setControl(newObservation.getControl());
+ observation.setConservatism(newObservation.getConservatism());
+ observation.setTeamwork(newObservation.getTeamwork());
+ observation.setKnowledge(newObservation.getKnowledge());
+ observation.setObservations(newObservation.getRawData());
+ observation.setDate(submissionDate);
+ observation = dao.persist(observation);
+ log.info("Created observation with ID " + observation.getId() + " at " + DateTime.now().toString());
+ return observation.getId();
}
@Path("/average/all")
@GET
public List averageObservationScores(){
- return dao.averageObservationScoresByDay();
+ return dao.averageStatsForAll();
}
@Path("/average/all/chartjs")
@GET
public AverageStatsChartJs averageStatsChartJs(){
- return new AverageStatsChartJs(dao.averageObservationScoresByDay());
+ return new AverageStatsChartJs(dao.averageStatsForAll());
}
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java b/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java
index 40599d2..d03ac31 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/resources/SiteResource.java
@@ -1,7 +1,9 @@
package uk.co.neviyn.Observations.resources;
+import io.dropwizard.hibernate.UnitOfWork;
import lombok.RequiredArgsConstructor;
import uk.co.neviyn.Observations.api.SelectOption;
+import uk.co.neviyn.Observations.core.Tutor;
import uk.co.neviyn.Observations.dao.SiteDao;
import javax.ws.rs.GET;
@@ -9,6 +11,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
@RequiredArgsConstructor
@@ -20,7 +23,15 @@ public class SiteResource {
@Path("/all")
@GET
- public List> allSites() {
- return dao.allSites().stream().map(x -> new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList());
+ @UnitOfWork
+ public List> allSites() {
+ return dao.listAll().stream().map(x -> new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList());
+ }
+
+ @Path("/{id}/tutors")
+ @GET
+ @UnitOfWork
+ public Set getSiteTutors(long id){
+ return dao.get(id).getTutors();
}
}
diff --git a/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java b/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java
index 0f86590..148c268 100644
--- a/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java
+++ b/backend/src/main/java/uk/co/neviyn/Observations/resources/TutorResource.java
@@ -9,6 +9,8 @@ import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+
+import io.dropwizard.hibernate.UnitOfWork;
import lombok.RequiredArgsConstructor;
import uk.co.neviyn.Observations.api.SelectOption;
import uk.co.neviyn.Observations.core.Tutor;
@@ -23,20 +25,11 @@ public class TutorResource {
@Path("/all")
@GET
+ @UnitOfWork
public List allTutors() {
- List tutors = dao.allTutors();
+ List tutors = dao.listAll();
if (tutors != null && !tutors.isEmpty())
return tutors;
throw new WebApplicationException("No tutors found!", Response.Status.NOT_FOUND);
}
-
- @Path("/site/{id}")
- @GET
- public List> tutorsForSite(@PathParam("id") int siteId) {
- List tutors = dao.tutorsForSite(siteId);
- if (tutors != null && !tutors.isEmpty()) {
- return tutors.stream().map(x -> new SelectOption<>(x.getName(), x.getId())).collect(Collectors.toList());
- }
- throw new WebApplicationException("No tutors found!", Response.Status.NOT_FOUND);
- }
}
diff --git a/backend/src/test/java/uk/co/neviyn/Observations/api/NewObservationTest.java b/backend/src/test/java/uk/co/neviyn/Observations/api/NewObservationTest.java
index 1f3d8bf..8a3f6e2 100644
--- a/backend/src/test/java/uk/co/neviyn/Observations/api/NewObservationTest.java
+++ b/backend/src/test/java/uk/co/neviyn/Observations/api/NewObservationTest.java
@@ -3,8 +3,10 @@ package uk.co.neviyn.Observations.api;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dropwizard.jackson.Jackson;
import org.junit.Test;
+import uk.co.neviyn.Observations.core.ObservationEntry;
import java.util.Arrays;
+import java.util.Collections;
import static io.dropwizard.testing.FixtureHelpers.fixture;
import static org.junit.Assert.*;
@@ -13,8 +15,8 @@ public class NewObservationTest {
private static final ObjectMapper mapper = Jackson.newObjectMapper();
- private final NewObservation newObservation = new NewObservation(1, Arrays.asList(1, 2, 3), "A random thing made for testing.",
- "INITIAL", 1, 2, 3, 4, 5, "{\"data\":\"Looks like there's nothing here.\"}");
+ private final NewObservation newObservation = new NewObservation(1, Arrays.asList(1L, 2L, 3L), "A random thing made for testing.",
+ "INITIAL", 1, 2, 3, 4, 5, Collections.singletonList(new ObservationEntry("MONITORING", 5, "some", "another sum")));
@Test
public void serializesToJson() throws Exception {
diff --git a/backend/src/test/java/uk/co/neviyn/Observations/core/ObservationTest.java b/backend/src/test/java/uk/co/neviyn/Observations/core/ObservationTest.java
index 5490a5c..f16f873 100644
--- a/backend/src/test/java/uk/co/neviyn/Observations/core/ObservationTest.java
+++ b/backend/src/test/java/uk/co/neviyn/Observations/core/ObservationTest.java
@@ -5,7 +5,6 @@ import io.dropwizard.jackson.Jackson;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.junit.Test;
-import uk.co.neviyn.Observations.api.ObservationEntry;
import java.util.Collections;
@@ -16,7 +15,7 @@ import static org.junit.Assert.*;
public class ObservationTest {
private static final ObjectMapper mapper = Jackson.newObjectMapper();
- private final Observation observation = new Observation(1, 1, "Just a test observation", TrainingType.INITIAL, 1, 2, 3,
+ private final Observation observation = new Observation(null, null, "Just a test observation", TrainingType.INITIAL, 1, 2, 3,
4, 5, Collections.singletonList(new ObservationEntry("MONITORING", 5, "some", "another sum")), DateTime.parse("2018-09-18T00:00:00.000Z")
);
diff --git a/backend/src/test/resources/fixtures/NewObservation.json b/backend/src/test/resources/fixtures/NewObservation.json
index 237a7fa..1fe1e4e 100644
--- a/backend/src/test/resources/fixtures/NewObservation.json
+++ b/backend/src/test/resources/fixtures/NewObservation.json
@@ -8,5 +8,5 @@
"conservatism":3,
"teamwork":4,
"knowledge":5,
- "rawData":"{\"data\":\"Looks like there's nothing here.\"}"
+ "rawData":[{"type":"MONITORING","rating":5,"strengths":"some","improvements":"another sum"}]
}
\ No newline at end of file
diff --git a/backend/src/test/resources/fixtures/Observation.json b/backend/src/test/resources/fixtures/Observation.json
index 0594395..653b743 100644
--- a/backend/src/test/resources/fixtures/Observation.json
+++ b/backend/src/test/resources/fixtures/Observation.json
@@ -1,6 +1,5 @@
{
- "id":1,
- "siteId":1,
+ "id":0,
"observed":"Just a test observation",
"type":"INITIAL",
"monitoring":1,
@@ -8,7 +7,7 @@
"conservatism":3,
"teamwork":4,
"knowledge":5,
- "rawData":[{
+ "observations":[{
"type": "MONITORING",
"rating":5,
"strengths":"some",
diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue
index 5622934..950e730 100644
--- a/frontend/src/views/Home.vue
+++ b/frontend/src/views/Home.vue
@@ -76,7 +76,7 @@ export default {
...mapMutations(["setSite", "setDescription", "setType", "setTutors"]),
getTutors: function() {
if (this.site != null) {
- Vue.axios.get("/api/tutor/site/" + this.site).then(response => {
+ Vue.axios.get("/api/site/" + this.site + "/tutors").then(response => {
this.tutorOptions = response.data;
this.loadingTutors = false;
});