From f3514d5af499b851b538af4a3ffa6f3aa46b4ecc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Barciela=20Mart=C3=ADn?= Date: Thu, 15 Mar 2018 21:02:06 +0100 Subject: [PATCH] add end point to list all pets from one owner --- db/mysql-with-inserts.sql | 13 +- db/mysql.sql | 3 +- .../java/es/uvigo/esei/daa/dao/PeopleDAO.java | 6 + .../java/es/uvigo/esei/daa/dao/PetsDAO.java | 79 ++++--- .../java/es/uvigo/esei/daa/entities/Pet.java | 22 +- .../uvigo/esei/daa/rest/PeopleResource.java | 19 ++ .../es/uvigo/esei/daa/rest/PetResource.java | 54 ++++- src/main/webapp/js/dao/Pet.js | 47 +++++ src/main/webapp/js/view/pet.js | 193 ++++++++++++++++++ .../uvigo/esei/daa/entities/PetUnitTest.java | 6 +- .../uvigo/esei/daa/rest/PetResourceTest.java | 5 + 11 files changed, 400 insertions(+), 47 deletions(-) create mode 100644 src/main/webapp/js/dao/Pet.js create mode 100644 src/main/webapp/js/view/pet.js create mode 100644 src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java diff --git a/db/mysql-with-inserts.sql b/db/mysql-with-inserts.sql index ce61228..f760489 100644 --- a/db/mysql-with-inserts.sql +++ b/db/mysql-with-inserts.sql @@ -1,3 +1,4 @@ +DROP DATABASE IF EXISTS `daaexample`; CREATE DATABASE `daaexample`; CREATE TABLE `daaexample`.`people` ( @@ -18,7 +19,7 @@ CREATE TABLE `daaexample`.`pets` ( `name` varchar(50) NOT NULL, `idOwner` int NOT NULL, PRIMARY KEY (`idPet`), - FOREING KEY (`idOwner`) REFERENCES people(id), + FOREIGN KEY (`idOwner`) REFERENCES people(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; @@ -35,11 +36,11 @@ INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Alba','Fern INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Asunción','Jiménez'); -- INSERTS IN PETS -- -INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`id`) VALUES (0,'Perro',0); -INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`id`) VALUES (0,'Gato',1); -INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`id`) VALUES (0,'Loro',2); -INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`id`) VALUES (0,'Serpiente',3); -INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`id`) VALUES (0,'Rata',0); +INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`idOwner`) VALUES (0,'Perro',4); +INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`idOwner`) VALUES (0,'Gato',1); +INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`idOwner`) VALUES (0,'Loro',2); +INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`idOwner`) VALUES (0,'Serpiente',3); +INSERT INTO `daaexample`.`pets` (`idPet`,`name`,`idOwner`) VALUES (0,'Rata',1); -- The password for each user is its login suffixed with "pass". For example, user "admin" has the password "adminpass". diff --git a/db/mysql.sql b/db/mysql.sql index caf3c32..f75b2a4 100644 --- a/db/mysql.sql +++ b/db/mysql.sql @@ -1,3 +1,4 @@ +DROP DATABASE IF EXISTS `daaexample`; CREATE DATABASE `daaexample`; CREATE TABLE `daaexample`.`people` ( @@ -18,7 +19,7 @@ CREATE TABLE `daaexample`.`pets` ( `name` varchar(50) NOT NULL, `idOwner` int NOT NULL, PRIMARY KEY (`idPet`), - FOREING KEY (`idOwner`) REFERENCES people(id), + FOREIGN KEY (`idOwner`) REFERENCES `daaexample`.`people`(id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa'; diff --git a/src/main/java/es/uvigo/esei/daa/dao/PeopleDAO.java b/src/main/java/es/uvigo/esei/daa/dao/PeopleDAO.java index 1d99edb..4529522 100644 --- a/src/main/java/es/uvigo/esei/daa/dao/PeopleDAO.java +++ b/src/main/java/es/uvigo/esei/daa/dao/PeopleDAO.java @@ -188,4 +188,10 @@ public class PeopleDAO extends DAO { row.getString("surname") ); } + + + + + + } diff --git a/src/main/java/es/uvigo/esei/daa/dao/PetsDAO.java b/src/main/java/es/uvigo/esei/daa/dao/PetsDAO.java index 3364488..7adb572 100644 --- a/src/main/java/es/uvigo/esei/daa/dao/PetsDAO.java +++ b/src/main/java/es/uvigo/esei/daa/dao/PetsDAO.java @@ -17,13 +17,13 @@ public class PetsDAO extends DAO{ private final static Logger LOG = Logger.getLogger(PetsDAO.class.getName()); - public Pet get(int id) + public Pet get(int idPet) throws DAOException, IllegalArgumentException { try (final Connection conn = this.getConnection()) { final String query = "SELECT * FROM pets WHERE idPet=?"; try (final PreparedStatement statement = conn.prepareStatement(query)) { - statement.setInt(1, id); + statement.setInt(1, idPet); try (final ResultSet result = statement.executeQuery()) { if (result.next()) { @@ -57,30 +57,30 @@ public class PetsDAO extends DAO{ } } } catch (SQLException e) { - LOG.log(Level.SEVERE, "Error listing people", e); + LOG.log(Level.SEVERE, "Error listing pet", e); throw new DAOException(e); } } - public Person add(String name, String surname) + public Pet add(String name, int idOwner) throws DAOException, IllegalArgumentException { - if (name == null || surname == null) { - throw new IllegalArgumentException("name and surname can't be null"); + if (name == null) { + throw new IllegalArgumentException("name can't be null"); } try (Connection conn = this.getConnection()) { - final String query = "INSERT INTO people VALUES(null, ?, ?)"; + final String query = "INSERT INTO pets VALUES(null, ?, ?)"; try (PreparedStatement statement = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { statement.setString(1, name); - statement.setString(2, surname); + statement.setInt(2, idOwner); if (statement.executeUpdate() == 1) { try (ResultSet resultKeys = statement.getGeneratedKeys()) { if (resultKeys.next()) { - return new Person(resultKeys.getInt(1), name, surname); + return new Pet(resultKeys.getInt(1), name, idOwner); } else { LOG.log(Level.SEVERE, "Error retrieving inserted id"); throw new SQLException("Error retrieving inserted id"); @@ -92,32 +92,32 @@ public class PetsDAO extends DAO{ } } } catch (SQLException e) { - LOG.log(Level.SEVERE, "Error adding a person", e); + LOG.log(Level.SEVERE, "Error adding a pet", e); throw new DAOException(e); } } - public void modify(Person person) + public void modify(Pet pet) throws DAOException, IllegalArgumentException { - if (person == null) { + if (pet == null) { throw new IllegalArgumentException("person can't be null"); } try (Connection conn = this.getConnection()) { - final String query = "UPDATE people SET name=?, surname=? WHERE id=?"; + final String query = "UPDATE pets SET name=?, idOwner=? WHERE idPet=?"; try (PreparedStatement statement = conn.prepareStatement(query)) { - statement.setString(1, person.getName()); - statement.setString(2, person.getSurname()); - statement.setInt(3, person.getId()); + statement.setString(1, pet.getName()); + statement.setInt(2, pet.getIdOwner()); + statement.setInt(3, pet.getIdPet()); if (statement.executeUpdate() != 1) { - throw new IllegalArgumentException("name and surname can't be null"); + throw new IllegalArgumentException("name can't be null"); } } } catch (SQLException e) { - LOG.log(Level.SEVERE, "Error modifying a person", e); + LOG.log(Level.SEVERE, "Error modifying a pet", e); throw new DAOException(); } } @@ -127,7 +127,7 @@ public class PetsDAO extends DAO{ public void delete(int id) throws DAOException, IllegalArgumentException { try (final Connection conn = this.getConnection()) { - final String query = "DELETE FROM people WHERE id=?"; + final String query = "DELETE FROM pets WHERE idPet=?"; try (final PreparedStatement statement = conn.prepareStatement(query)) { statement.setInt(1, id); @@ -137,28 +137,49 @@ public class PetsDAO extends DAO{ } } } catch (SQLException e) { - LOG.log(Level.SEVERE, "Error deleting a person", e); + LOG.log(Level.SEVERE, "Error deleting a pet", e); throw new DAOException(e); } } private Pet rowToEntity(ResultSet row) throws SQLException { return new Pet( - row.getInt("id"), + row.getInt("idPet"), row.getString("name"), row.getInt("idOwner") ); } + + public List listPetsOwner(int idOwner) throws DAOException{ + + try(final Connection connection = this.getConnection()){ + final String query = "SELECT * FROM pets WHERE idOwner=?"; + + try(final PreparedStatement statement = connection.prepareStatement(query)){ + + statement.setInt(1, idOwner); + + try(final ResultSet result = statement.executeQuery()){ + final List petsOwner = new LinkedList<>(); + + while(result.next()) { + + petsOwner.add(rowToEntity(result)); + + } + + return petsOwner; + } + } + }catch (SQLException exc) { + LOG.log(Level.SEVERE, "Fallo al listar mascotas", exc); + throw new DAOException(exc); + } + + } - - - - - - - - + } diff --git a/src/main/java/es/uvigo/esei/daa/entities/Pet.java b/src/main/java/es/uvigo/esei/daa/entities/Pet.java index 682e5ba..f927d96 100644 --- a/src/main/java/es/uvigo/esei/daa/entities/Pet.java +++ b/src/main/java/es/uvigo/esei/daa/entities/Pet.java @@ -3,21 +3,21 @@ package es.uvigo.esei.daa.entities; import static java.util.Objects.requireNonNull; public class Pet { - private int id; + private int idPet; private String name; private int idOwner; Pet() {} - public Pet(int id, String name, int idOwner) { - this.id = id; + public Pet(int idPet, String name, int idOwner) { + this.idPet = idPet; this.setName(name); this.setOwner(idOwner); } - public int getId() { - return id; + public int getIdPet() { + return idPet; } public String getName() { @@ -29,13 +29,21 @@ public class Pet { } public void setName(String name) { - this.name = name; + this.name = requireNonNull(name, "Name can't be null"); } public void setOwner(int idOwner) { this.idOwner = idOwner; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + idPet; + return result; + } + @Override public boolean equals(Object obj) { if (this == obj) @@ -45,7 +53,7 @@ public class Pet { if (!(obj instanceof Pet)) return false; Pet other = (Pet) obj; - if (id != other.id) + if (idPet != other.idPet) return false; return true; } diff --git a/src/main/java/es/uvigo/esei/daa/rest/PeopleResource.java b/src/main/java/es/uvigo/esei/daa/rest/PeopleResource.java index 09b8834..bb7ba57 100644 --- a/src/main/java/es/uvigo/esei/daa/rest/PeopleResource.java +++ b/src/main/java/es/uvigo/esei/daa/rest/PeopleResource.java @@ -16,6 +16,7 @@ import javax.ws.rs.core.Response; import es.uvigo.esei.daa.dao.DAOException; import es.uvigo.esei.daa.dao.PeopleDAO; +import es.uvigo.esei.daa.dao.PetsDAO; import es.uvigo.esei.daa.entities.Person; /** @@ -75,6 +76,24 @@ public class PeopleResource { .build(); } } + + @GET + @Path("/{id}/pets") + public Response getListPets( + @PathParam("id") int idOwner + ) { + try { + + return Response.ok((new PetsDAO()).listPetsOwner(idOwner)).build(); + + } catch (DAOException exc) { + + LOG.log(Level.SEVERE, "Error al mostrar las mascotas de la persona", exc); + + return Response.serverError().entity(exc.getMessage()).build(); + } + } + /** * Returns the complete list of people stored in the system. diff --git a/src/main/java/es/uvigo/esei/daa/rest/PetResource.java b/src/main/java/es/uvigo/esei/daa/rest/PetResource.java index 1d61fbf..de4b24b 100644 --- a/src/main/java/es/uvigo/esei/daa/rest/PetResource.java +++ b/src/main/java/es/uvigo/esei/daa/rest/PetResource.java @@ -1,8 +1,11 @@ package es.uvigo.esei.daa.rest; import java.util.logging.Level; +import java.util.logging.Logger; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -10,17 +13,31 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import es.uvigo.esei.daa.dao.DAOException; +import es.uvigo.esei.daa.dao.PeopleDAO; +import es.uvigo.esei.daa.dao.PetsDAO; +import es.uvigo.esei.daa.entities.Person; import es.uvigo.esei.daa.entities.Pet; @Path("/pets") @Produces(MediaType.APPLICATION_JSON) public class PetResource { + private final static Logger LOG = Logger.getLogger(PetResource.class.getName()); + private final PetsDAO dao; + + public PetResource() { + this(new PetsDAO()); + } + + PetResource(PetsDAO dao) { + this.dao = dao; + } + @GET @Path("/{idPet}") public Response get(@PathParam("idPet") int idPet) { try { - final Pet pet = this.dao.get(id); + final Pet pet = this.dao.get(idPet); return Response.ok(pet).build(); } catch (IllegalArgumentException iae) { @@ -37,5 +54,40 @@ public class PetResource { .build(); } } + + @GET + public Response list() { + try { + return Response.ok(this.dao.list()).build(); + } catch (DAOException e) { + LOG.log(Level.SEVERE, "Error listing pet", e); + return Response.serverError().entity(e.getMessage()).build(); + } + } + + @POST + public Response add( + @FormParam("name") String name, + @FormParam("idOwner") int idOwner + ) { + try { + final Pet newPet = this.dao.add(name, idOwner); + + return Response.ok(newPet).build(); + } catch (IllegalArgumentException iae) { + LOG.log(Level.FINE, "Invalid pet id in add method", iae); + + return Response.status(Response.Status.BAD_REQUEST) + .entity(iae.getMessage()) + .build(); + } catch (DAOException e) { + LOG.log(Level.SEVERE, "Error adding a pet", e); + + return Response.serverError() + .entity(e.getMessage()) + .build(); + } + } + } diff --git a/src/main/webapp/js/dao/Pet.js b/src/main/webapp/js/dao/Pet.js new file mode 100644 index 0000000..c8684bf --- /dev/null +++ b/src/main/webapp/js/dao/Pet.js @@ -0,0 +1,47 @@ +var PetsDAO = (function() { + var resourcePath = "rest/pets/"; + var requestByAjax = function(data, done, fail, always) { + done = typeof done !== 'undefined' ? done : function() {}; + fail = typeof fail !== 'undefined' ? fail : function() {}; + always = typeof always !== 'undefined' ? always : function() {}; + + $.ajax(data) + .done(done) + .fail(fail) + .always(always); + }; + + function PetsDAO() { + this.listPet = function(done, fail, always) { + requestByAjax({ + url: resourcePath, + type: 'GET' + }, done, fail, always); + }; + + this.addPet = function(pet, done, fail, always) { + requestByAjax({ + url: resourcePath, + type: 'POST', + data: pet + }, done, fail, always); + }; + + this.modifyPet = function(pet, done, fail, always) { + requestByAjax({ + url: resourcePath + pet.idPet, + type: 'PUT', + data: pet + }, done, fail, always); + }; + + this.deletePet = function(idPet, done, fail, always) { + requestByAjax({ + url: resourcePath + idPet, + type: 'DELETE', + }, done, fail, always); + }; + } + + return PetsDAO; +})(); \ No newline at end of file diff --git a/src/main/webapp/js/view/pet.js b/src/main/webapp/js/view/pet.js new file mode 100644 index 0000000..514a186 --- /dev/null +++ b/src/main/webapp/js/view/pet.js @@ -0,0 +1,193 @@ +var PetView = (function() { + var dao; + + // Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery. + var self; + + var formId = 'pet-form'; + var listId = 'pet-list'; + var formQuery = '#' + formId; + var listQuery = '#' + listId; + + function PetView(petsDao, formContainerId, listContainerId) { + dao = petsDao; + self = this; + + insertPetForm($('#' + formContainerId)); + insertPetList($('#' + listContainerId)); + + this.init = function() { + dao.listPet(function(pet) { + $.each(pet, function(key, pet) { + appendToTable(pet); + }); + }); + + // La acción por defecto de enviar formulario (submit) se sobreescribe + // para que el envío sea a través de AJAX + $(formQuery).submit(function(event) { + var pet = self.getPetInForm(); + + if (self.isEditing()) { + dao.modifyPet(pet, + function(pet) { + $('#pet-' + pet.idPet + ' td.name').text(pet.name); + $('#pet-' + pet.idPet + ' td.idOwner').text(pet.idOwner); + self.resetForm(); + }, + showErrorMessage, + self.enableForm + ); + } else { + dao.addPet(pet, + function(pet) { + appendToTable(pet); + self.resetForm(); + }, + showErrorMessage, + self.enableForm + ); + } + + return false; + }); + + $('#btnClear').click(this.resetForm); + }; + + this.getPetInForm = function() { + var form = $(formQuery); + return { + 'idPet': form.find('input[name="idPet"]').val(), + 'name': form.find('input[name="name"]').val(), + 'idOwner': form.find('input[name="idOwner"]').val() + }; + }; + + this.getPetInRow = function(idPet) { + var row = $('#pet-' + idPet); + + if (row !== undefined) { + return { + 'idPet': idPet, + 'name': row.find('td.name').text(), + 'idOwner': row.find('td.idOwner').text() + }; + } else { + return undefined; + } + }; + + this.editPet = function(idPet) { + var row = $('#pet-' + idPet); + + if (row !== undefined) { + var form = $(formQuery); + + form.find('input[name="idPet"]').val(idPet); + form.find('input[name="name"]').val(row.find('td.name').text()); + form.find('input[name="idOwner"]').val(row.find('td.idOwner').text()); + + $('input#btnSubmit').val('Modificar'); + } + }; + + this.deletePet = function(idPet) { + if (confirm('Está a punto de eliminar a una mascota. ¿Está seguro de que desea continuar?')) { + dao.deletePet(id, + function() { + $('tr#pet-' + idPet).remove(); + }, + showErrorMessage + ); + } + }; + + this.isEditing = function() { + return $(formQuery + ' input[name="idPet"]').val() != ""; + }; + + this.disableForm = function() { + $(formQuery + ' input').prop('disabled', true); + }; + + this.enableForm = function() { + $(formQuery + ' input').prop('disabled', false); + }; + + this.resetForm = function() { + $(formQuery)[0].reset(); + $(formQuery + ' input[name="idPet"]').val(''); + $('#btnSubmit').val('Crear'); + }; + }; + + var insertPetList = function(parent) { + parent.append( + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
NombreDueño 
' + ); + }; + + var insertPetForm = function(parent) { + parent.append( + '
\ + \ +
\ +
\ + \ +
\ +
\ + \ +
\ +
\ + \ + \ +
\ +
\ +
' + ); + }; + + var createPetRow = function(pet) { + return '\ + ' + pet.name + '\ + ' + pet.idOwner + '\ + \ + Editar\ + Eliminar\ + \ + '; + }; + + var showErrorMessage = function(jqxhr, textStatus, error) { + alert(textStatus + ": " + error); + }; + + var addRowListeners = function(pet) { + $('#pet-' + pet.idPet + ' a.edit').click(function() { + self.editPet(pet.idPet); + }); + + $('#pet-' + pet.idPet + ' a.delete').click(function() { + self.deletePet(pet.idPet); + }); + }; + + var appendToTable = function(pet) { + $(listQuery + ' > tbody:last') + .append(createPetRow(pet)); + addRowListeners(pet); + }; + + return PetView; +})(); diff --git a/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java b/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java index 6621921..661fa4e 100644 --- a/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java +++ b/src/test/java/es/uvigo/esei/daa/entities/PetUnitTest.java @@ -21,7 +21,7 @@ public class PetUnitTest { final Pet pet = new Pet(id,name,idOwner); - assertThat(pet.getId(), equalTo(id)); + assertThat(pet.getIdPet(), equalTo(id)); assertThat(pet.getName(), equalTo(name)); assertThat(pet.getIdOwner(), equalTo(idOwner)); @@ -41,7 +41,7 @@ public class PetUnitTest { final Pet pet = new Pet(id, "gato", idOwner); pet.setName("manoplas"); - assertThat(pet.getId(), is(equalTo(id))); + assertThat(pet.getIdPet(), is(equalTo(id))); assertThat(pet.getName(), is(equalTo("manoplas"))); assertThat(pet.getIdOwner(), is(equalTo(idOwner))); } @@ -61,7 +61,7 @@ public class PetUnitTest { final Pet pet = new Pet(id, name, 2); pet.setOwner(4); - assertThat(pet.getId(), is(equalTo(id))); + assertThat(pet.getIdPet(), is(equalTo(id))); assertThat(pet.getName(), is(equalTo(name))); assertThat(pet.getIdOwner(), is(equalTo(4))); } diff --git a/src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java b/src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java new file mode 100644 index 0000000..0f1c7d6 --- /dev/null +++ b/src/test/java/es/uvigo/esei/daa/rest/PetResourceTest.java @@ -0,0 +1,5 @@ +package es.uvigo.esei.daa.rest; + +public class PetResourceTest { + +} -- 2.18.1