Commit 55debe73 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Fixed problem with uninitialized db

parent 2adb200f
......@@ -5,11 +5,13 @@ import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Collection;
import java.util.Scanner;
import tdt4140.gr1800.app.core.GeoLocation;
import tdt4140.gr1800.app.core.GeoLocations;
......@@ -18,35 +20,62 @@ import tdt4140.gr1800.app.core.Person;
public class DbAccessImpl extends AbstractDbAccessImpl {
private final DbAccessHelper helper;
private DbAccessImpl(DbAccessHelper helper) {
private DbAccessImpl(final DbAccessHelper helper) {
this.helper = helper;
}
public DbAccessImpl(Connection dbConnection) {
public DbAccessImpl(final Connection dbConnection) {
this(new DbAccessHelper(dbConnection));
}
public DbAccessImpl(String connectionUri, String user, String pass) throws SQLException {
public DbAccessImpl(final String connectionUri, final String user, final String pass) throws SQLException {
this(DriverManager.getConnection(connectionUri, user, pass));
}
public DbAccessImpl(String connectionUri) throws SQLException {
public DbAccessImpl(final String connectionUri) throws SQLException {
this(connectionUri, "SA", "");
}
//
public void executeStatements(final String path, final boolean cleanUp) throws SQLException {
final Statement dbStatement = helper.getDbConnection().createStatement();
final StringBuilder buffer = new StringBuilder();
try (Scanner scanner = new Scanner(getClass().getResourceAsStream(path))) {
while (scanner.hasNextLine()) {
final String line = scanner.nextLine();
final int pos = line.indexOf(";");
if (pos >= 0) {
buffer.append(line.substring(0, pos + 1));
final String sql = buffer.toString();
buffer.setLength(0);
if (pos < line.length()) {
buffer.append(line.substring(pos + 1));
}
if (cleanUp || (! sql.startsWith("DROP"))) {
dbStatement.execute(sql);
}
} else {
buffer.append(line);
buffer.append("\n");
}
}
}
}
//
@Override
public synchronized Person createPerson(String name, String email) {
Person person = super.createPerson(name, email);
int id = helper.executeDbInsertGettingIdentity(String.format("INSERT INTO person (name, email) VALUES ('%s', '%s')", name, email));
public synchronized Person createPerson(final String name, final String email) {
final Person person = super.createPerson(name, email);
final int id = helper.executeDbInsertGettingIdentity(String.format("INSERT INTO person (name, email) VALUES ('%s', '%s')", name, email));
personIds.set(person, id);
return person;
}
protected Person createPerson(int id, String name, String email) {
Person person = new Person();
protected Person createPerson(final int id, final String name, final String email) {
final Person person = new Person();
person.setName(name);
person.setEmail(email);
personIds.remove(id);
......@@ -55,17 +84,17 @@ public class DbAccessImpl extends AbstractDbAccessImpl {
}
@Override
public Collection<Person> getAllPersons(boolean refresh) {
public Collection<Person> getAllPersons(final boolean refresh) {
if (refresh) {
personIds.clear();
ResultSet result = helper.executeQuery("SELECT id, name, email FROM person");
final ResultSet result = helper.executeQuery("SELECT id, name, email FROM person");
try {
while (result.next()) {
int id = result.getInt(1);
String name = result.getString(2), email = result.getString(3);
final int id = result.getInt(1);
final String name = result.getString(2), email = result.getString(3);
createPerson(id, name, email);
}
} catch (SQLException e) {
} catch (final SQLException e) {
helper.throwException(e);
}
}
......@@ -73,19 +102,19 @@ public class DbAccessImpl extends AbstractDbAccessImpl {
}
@Override
public Person getPerson(int id, boolean refresh) {
public Person getPerson(final int id, final boolean refresh) {
Person person = null;
if (! refresh) {
person = super.getPerson(id, false);
}
if (person == null || refresh) {
ResultSet result = helper.executeQuery("SELECT id, name, email FROM person WHERE id = ?", id);
final ResultSet result = helper.executeQuery("SELECT id, name, email FROM person WHERE id = ?", id);
try {
if (result.next()) {
String name = result.getString(2), email = result.getString(3);
final String name = result.getString(2), email = result.getString(3);
person = createPerson(id, name, email);
}
} catch (SQLException e) {
} catch (final SQLException e) {
helper.throwException(e);
}
}
......@@ -93,20 +122,20 @@ public class DbAccessImpl extends AbstractDbAccessImpl {
}
@Override
public Person getPersonByName(String name, boolean refresh) {
public Person getPersonByName(final String name, final boolean refresh) {
Person person = null;
if (! refresh) {
person = super.getPersonByName(name, false);
}
if (person == null || refresh) {
ResultSet result = helper.executeQuery("SELECT id, name, email FROM person WHERE name = ?", name);
final ResultSet result = helper.executeQuery("SELECT id, name, email FROM person WHERE name = ?", name);
try {
if (result.next()) {
int id = result.getInt(1);
String dbName = result.getString(2), email = result.getString(3);
final int id = result.getInt(1);
final String dbName = result.getString(2), email = result.getString(3);
person = createPerson(id, dbName, email);
}
} catch (SQLException e) {
} catch (final SQLException e) {
helper.throwException(e);
}
}
......@@ -114,47 +143,47 @@ public class DbAccessImpl extends AbstractDbAccessImpl {
}
@Override
public Person getPersonByEmail(String email, boolean refresh) {
public Person getPersonByEmail(final String email, final boolean refresh) {
Person person = null;
if (! refresh) {
person = super.getPersonByEmail(email, false);
}
if (person == null || refresh) {
ResultSet result = helper.executeQuery("SELECT id, name, email FROM person WHERE email = ?", email);
final ResultSet result = helper.executeQuery("SELECT id, name, email FROM person WHERE email = ?", email);
try {
if (result.next()) {
int id = result.getInt(1);
String name = result.getString(2), dbEmail = result.getString(3);
final int id = result.getInt(1);
final String name = result.getString(2), dbEmail = result.getString(3);
person = createPerson(id, name, dbEmail);
}
} catch (SQLException e) {
} catch (final SQLException e) {
helper.throwException(e);
}
}
return person;
}
@Override
public synchronized void updatePersonData(Person person) {
public synchronized void updatePersonData(final Person person) {
helper.executeDbStatement("UPDATE person SET name = ?, email = ? WHERE id = ?", person.getName(), person.getEmail(), getId(person));
}
@Override
public synchronized void deletePerson(Person person) {
int id = getId(person);
public synchronized void deletePerson(final Person person) {
final int id = getId(person);
super.deletePerson(person);
helper.executeDbStatement("DELETE FROM person WHERE id = ?", id);
// not needed with ON DELETE CASCADE set on foreign keys
// helper.executeDbStatement("DELETE FROM geoLocations WHERE ownerId = ?", person.getId());
// helper.executeDbStatement("DELETE FROM geoLocation WHERE ownerId = ?", person.getId());
// helper.executeDbStatement("DELETE FROM geoLocations WHERE ownerId = ?", person.getId());
// helper.executeDbStatement("DELETE FROM geoLocation WHERE ownerId = ?", person.getId());
}
//
@Override
public GeoLocations createGeoLocations(Person owner) {
GeoLocations geoLocations = super.createGeoLocations(owner);
int id = helper.executeDbInsertGettingIdentity(String.format("INSERT INTO geoLocations (ownerId) VALUES ('%s')", getId(owner)));
public GeoLocations createGeoLocations(final Person owner) {
final GeoLocations geoLocations = super.createGeoLocations(owner);
final int id = helper.executeDbInsertGettingIdentity(String.format("INSERT INTO geoLocations (ownerId) VALUES ('%s')", getId(owner)));
geoLocationsIds.set(geoLocations, id);
return geoLocations;
}
......@@ -165,94 +194,94 @@ public class DbAccessImpl extends AbstractDbAccessImpl {
}
@Override
public Collection<GeoLocations> getGeoLocations(Person owner, boolean refresh) {
Collection<GeoLocations> existingGeoLocations = super.getGeoLocations(owner, false);
public Collection<GeoLocations> getGeoLocations(final Person owner, final boolean refresh) {
final Collection<GeoLocations> existingGeoLocations = super.getGeoLocations(owner, false);
if (refresh || existingGeoLocations.isEmpty()) {
owner.removeGeolocations((String[]) null);
geoLocationsIds.removeAll(existingGeoLocations);
existingGeoLocations.clear();
int ownerId = getId(owner);
ResultSet result = helper.executeQuery("SELECT id, path, name, description, date, time, zone FROM geoLocations WHERE ownerId = ?", ownerId);
final int ownerId = getId(owner);
final ResultSet result = helper.executeQuery("SELECT id, path, name, description, date, time, zone FROM geoLocations WHERE ownerId = ?", ownerId);
try {
while (result.next()) {
int id = result.getInt(1);
boolean path = result.getBoolean(2);
String name = result.getString(3), description = result.getString(4);
GeoLocations geoLocations = new GeoLocations(owner);
final int id = result.getInt(1);
final boolean path = result.getBoolean(2);
final String name = result.getString(3), description = result.getString(4);
final GeoLocations geoLocations = new GeoLocations(owner);
owner.addGeolocations(geoLocations);
geoLocations.setPath(path);
geoLocations.setName(name);
geoLocations.setDescription(description);
Date date = result.getDate(5);
Time time = result.getTime(6);
String zone = result.getString(7);
final Date date = result.getDate(5);
final Time time = result.getTime(6);
final String zone = result.getString(7);
geoLocations.setDate(date != null ? date.toLocalDate() : null);
geoLocations.setTime(time != null ? time.toLocalTime() : null);
geoLocations.setZone(zone != null ? ZoneId.of(zone) : null);
existingGeoLocations.add(geoLocations);
geoLocationsIds.set(geoLocations, id);
ResultSet tagResults = helper.executeQuery(String.format("SELECT tag FROM tag WHERE ownerId = ? AND ownerType = '%s'", TagOwnerType.GLS), id);
final ResultSet tagResults = helper.executeQuery(String.format("SELECT tag FROM tag WHERE ownerId = ? AND ownerType = '%s'", TagOwnerType.GLS), id);
while (tagResults.next()) {
geoLocations.addTags(tagResults.getString(1));
}
}
} catch (SQLException e) {
} catch (final SQLException e) {
helper.throwException(e);
}
ResultSet tagResult = helper.executeQuery(String.format("SELECT geoLocations.id, tag.tag FROM geoLocations, tag WHERE geoLocations.ownerId = ? AND tag.ownerId = geoLocations.id AND ownerType = '%s'", TagOwnerType.GLS), ownerId);
final ResultSet tagResult = helper.executeQuery(String.format("SELECT geoLocations.id, tag.tag FROM geoLocations, tag WHERE geoLocations.ownerId = ? AND tag.ownerId = geoLocations.id AND ownerType = '%s'", TagOwnerType.GLS), ownerId);
try {
while (tagResult.next()) {
int geoLocationsId = tagResult.getInt(1);
String tag = tagResult.getString(2);
GeoLocations geoLocations = geoLocationsIds.get(geoLocationsId);
final int geoLocationsId = tagResult.getInt(1);
final String tag = tagResult.getString(2);
final GeoLocations geoLocations = geoLocationsIds.get(geoLocationsId);
if (geoLocations != null) {
geoLocations.addTags(tag);
}
}
} catch (SQLException e) {
} catch (final SQLException e) {
helper.throwException(e);
}
}
return existingGeoLocations;
}
@Override
public void updateGeoLocationsData(GeoLocations geoLocations) {
boolean path = geoLocations.isPath();
String name = geoLocations.getName(), desc = geoLocations.getDescription();
LocalDate date = geoLocations.getDate();
LocalTime time = geoLocations.getTime();
String zone = (geoLocations.getZone() != null ? geoLocations.getZone().getId() : null);
int ownerId = getId(geoLocations);
public void updateGeoLocationsData(final GeoLocations geoLocations) {
final boolean path = geoLocations.isPath();
final String name = geoLocations.getName(), desc = geoLocations.getDescription();
final LocalDate date = geoLocations.getDate();
final LocalTime time = geoLocations.getTime();
final String zone = (geoLocations.getZone() != null ? geoLocations.getZone().getId() : null);
final int ownerId = getId(geoLocations);
helper.executeDbStatement("UPDATE geoLocations SET path = ?, name = ?, description = ?, date = ?, time = ?, zone = ? WHERE id = ?", path, name, desc, Date.valueOf(date), Time.valueOf(time), zone, ownerId);
deleteTags(ownerId, TagOwnerType.GLS);
String insertStatement = "INSERT INTO tag (ownerId, ownerType, tag) VALUES ";
String[] tags = geoLocations.getTags();
final String[] tags = geoLocations.getTags();
for (int i = 0; i < tags.length; i++) {
if (i > 0) {
insertStatement += ", ";
insertStatement += ", ";
}
insertStatement += String.format("(%s, '%s', '%s')", ownerId, TagOwnerType.GLS, tags[i]);
}
helper.executeDbStatement(insertStatement);
}
protected void deleteTags(int ownerId, TagOwnerType ownerType) {
protected void deleteTags(final int ownerId, final TagOwnerType ownerType) {
helper.executeDbStatement(String.format("DELETE FROM tag WHERE ownerId = ? AND ownerType = '%s'", ownerType), ownerId);
}
@Override
public void deleteGeoLocations(GeoLocations geoLocations) {
int ownerId = getId(geoLocations);
public void deleteGeoLocations(final GeoLocations geoLocations) {
final int ownerId = getId(geoLocations);
super.deleteGeoLocations(geoLocations);
helper.executeDbStatement("DELETE FROM geoLocations WHERE id = ?", ownerId);
deleteTags(ownerId, TagOwnerType.GLS);
}
//
@Override
public void updateGeoLocationData(GeoLocations geoLocations, GeoLocation geoLocation) {
public void updateGeoLocationData(final GeoLocations geoLocations, final GeoLocation geoLocation) {
throw new UnsupportedOperationException("NYI");
}
}
package tdt4140.gr1800.app.json;
import java.util.function.Consumer;
import java.util.function.Function;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ObjectNode;
public abstract class IdDeserializer<T> extends StdDeserializer<T> {
public IdDeserializer(final Class<T> clazz) {
super(clazz);
}
void deserialize(final ObjectNode objectNode, final String fieldName, final Consumer<String> setter) throws JsonProcessingException {
if (objectNode.has(fieldName)) {
final String s = objectNode.get(fieldName).asText();
setter.accept(s);
}
}
<U> void deserialize(final ObjectNode objectNode, final String fieldName, final Function<String, U> parser, final Consumer<U> setter) throws JsonProcessingException {
if (objectNode.has(fieldName)) {
final String s = objectNode.get(fieldName).asText();
final U value = parser.apply(s);
setter.accept(value);
}
}
}
......@@ -6,14 +6,13 @@ import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import tdt4140.gr1800.app.core.GeoLocations;
import tdt4140.gr1800.app.core.Person;
public class PersonDeserializer extends StdDeserializer<Person> {
public class PersonDeserializer extends IdDeserializer<Person> {
public PersonDeserializer() {
super(Person.class);
......@@ -31,10 +30,8 @@ public class PersonDeserializer extends StdDeserializer<Person> {
if (jsonNode instanceof ObjectNode) {
final ObjectNode objectNode = (ObjectNode) jsonNode;
final Person person = new Person();
if (objectNode.has(GeoLocationsSerializer.NAME_FIELD_NAME)) {
final String name = objectNode.get(GeoLocationsSerializer.NAME_FIELD_NAME).asText();
person.setName(name);
}
deserialize(objectNode, PersonSerializer.NAME_FIELD_NAME, person::setName);
deserialize(objectNode, PersonSerializer.EMAIL_FIELD_NAME, person::setEmail);
if (objectNode.has(GeoLocationsSerializer.LOCATIONS_FIELD_NAME)) {
final JsonNode locationsNode = objectNode.get(GeoLocationsSerializer.LOCATIONS_FIELD_NAME);
if (locationsNode instanceof ArrayNode) {
......
......@@ -3,11 +3,9 @@ package tdt4140.gr1800.app.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.Collection;
import java.util.Scanner;
import org.junit.After;
import org.junit.Assert;
......@@ -22,52 +20,28 @@ public class HsqldbAccessTest {
private Connection dbCon;
private AbstractDbAccessImpl dbAccess;
private static int testNum = 0;
@Before
public void setUp() throws Exception {
Class.forName("org.hsqldb.jdbc.JDBCDriver");
dbCon = DriverManager.getConnection("jdbc:hsqldb:mem:" + HsqldbAccessTest.class.getName() + testNum, "SA", "");
executeStatements("schema.sql");
dbAccess = new DbAccessImpl(dbCon);
final DbAccessImpl dbAccess = new DbAccessImpl(dbCon);
dbAccess.executeStatements("schema.sql", false);
this.dbAccess = dbAccess;
testNum++;
}
@After
public void tearDown() {
if (dbCon != null) {
try {
dbCon.close();
} catch (SQLException e) {
} catch (final SQLException e) {
}
}
}
protected void executeStatements(String path) throws SQLException {
Statement dbStatement = dbCon.createStatement();
StringBuilder buffer = new StringBuilder();
try (Scanner scanner = new Scanner(HsqldbAccessTest.class.getResourceAsStream(path))) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
int pos = line.indexOf(";");
if (pos >= 0) {
buffer.append(line.substring(0, pos + 1));
String sql = buffer.toString();
buffer.setLength(0);
if (pos < line.length()) {
buffer.append(line.substring(pos + 1));
}
if (! sql.startsWith("DROP")) {
dbStatement.execute(sql);
}
} else {
buffer.append(line);
buffer.append("\n");
}
}
}
}
protected void checkPersonData(Person hal, Person dbHal) {
protected void checkPersonData(final Person hal, final Person dbHal) {
Assert.assertNotNull(dbHal);
Assert.assertEquals(hal.getName(), dbHal.getName());
Assert.assertEquals(hal.getEmail(), dbHal.getEmail());
......@@ -75,95 +49,95 @@ public class HsqldbAccessTest {
@Test
public void testCreatePersonGetAllPersons() {
Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
Collection<Person> persons = dbAccess.getAllPersons(false);
final Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
final Collection<Person> persons = dbAccess.getAllPersons(false);
Assert.assertEquals(1, persons.size());
checkPersonData(hal, persons.iterator().next());
dbAccess.personIds.clear();
Collection<Person> dbPersons = dbAccess.getAllPersons(true);
final Collection<Person> dbPersons = dbAccess.getAllPersons(true);
Assert.assertEquals(1, dbPersons.size());
checkPersonData(hal, dbPersons.iterator().next());
}
@Test
public void testCreatePersonGetPerson() {
Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
int id = dbAccess.getId(hal);
Person dbHal = dbAccess.getPerson(id, true);
final Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
final int id = dbAccess.getId(hal);
final Person dbHal = dbAccess.getPerson(id, true);
checkPersonData(hal, dbHal);
Assert.assertSame(dbHal, dbAccess.getPerson(id, false));
}
@Test
public void testCreatePersonGetPersonByName() {
Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
Person dbHal = dbAccess.getPersonByName(hal.getName(), true);
final Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
final Person dbHal = dbAccess.getPersonByName(hal.getName(), true);
checkPersonData(hal, dbHal);
}
@Test
public void testCreatePersonGetPersonByEmail() {
Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
Person dbHal = dbAccess.getPersonByEmail(hal.getEmail(), true);
final Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
final Person dbHal = dbAccess.getPersonByEmail(hal.getEmail(), true);
checkPersonData(hal, dbHal);
}
@Test
public void testCreatePersonUpdatePerson() {
Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
int id = dbAccess.getId(hal);
final Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
final int id = dbAccess.getId(hal);
hal.setName("Hallvard");
hal.setEmail("hallvard.traetteberg@gmail.com");
dbAccess.updatePersonData(hal);
Person dbHal = dbAccess.getPerson(id, true);
final Person dbHal = dbAccess.getPerson(id, true);
checkPersonData(hal, dbHal);
}
@Test
public void testCreatePersonDeletePerson() {
Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
final Person hal = dbAccess.createPerson("hal", "hal@ntnu.no");
dbAccess.deletePerson(hal);
Collection<Person> persons = dbAccess.getAllPersons(true);
final Collection<Person> persons = dbAccess.getAllPersons(true);
Assert.assertEquals(0, persons.size());
}
<