Commit 4225df4a authored by Imanol's avatar Imanol

Añade toda la funcionalidad para mascotas

parent 6bbdf414
......@@ -14,6 +14,14 @@ CREATE TABLE `daaexample`.`users` (
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`pets` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`peopleID` int NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`peopleID`) REFERENCES people(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Antón','Pérez');
......@@ -30,3 +38,6 @@ INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('admin', '713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca','ADMIN');
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('normal', '7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83','USER');
INSERT INTO `daaexample`.`pets` (`id`,`name`,`peopleID`) VALUES (0,'Greta',1);
INSERT INTO `daaexample`.`pets` (`id`,`name`,`peopleID`) VALUES (0,'Toby',2);
......@@ -14,4 +14,12 @@ CREATE TABLE `daaexample`.`users` (
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `daaexample`.`pets` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`peopleID` int NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`peopleID`) REFERENCES people(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost' IDENTIFIED BY 'daa';
......@@ -11,6 +11,7 @@ import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import es.uvigo.esei.daa.rest.PeopleResource;
import es.uvigo.esei.daa.rest.PetResource;
import es.uvigo.esei.daa.rest.UsersResource;
/**
......@@ -26,7 +27,8 @@ public class DAAExampleApplication extends Application {
public Set<Class<?>> getClasses() {
return Stream.of(
PeopleResource.class,
UsersResource.class
UsersResource.class,
PetResource.class
).collect(toSet());
}
......
package es.uvigo.esei.daa.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import es.uvigo.esei.daa.entities.Pet;
/**
* DAO class for the {@link Pet} entities.
*
* @author Imanol Cobian Martinez
*
*/
public class PetDAO extends DAO {
private final static Logger LOG = Logger.getLogger(PetDAO.class.getName());
public Pet get(int id) throws DAOException, IllegalArgumentException {
try (final Connection conn = this.getConnection()) {
final String query = "SELECT * FROM pets WHERE id=?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, id);
try (final ResultSet result = statement.executeQuery()) {
if (result.next()) {
return rowToEntity(result);
} else {
throw new IllegalArgumentException("Invalid id");
}
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error getting a pet", e);
throw new DAOException(e);
}
}
public List<Pet> listAll() throws DAOException {
try (final Connection conn = this.getConnection()) {
final String query = "SELECT * FROM pets";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
try (final ResultSet result = statement.executeQuery()) {
final List<Pet> pets = new LinkedList<>();
while (result.next()) {
pets.add(rowToEntity(result));
}
return pets;
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
throw new DAOException(e);
}
}
public List<Pet> listByPeopleID(int peopleID) throws DAOException {
try (final Connection conn = this.getConnection()) {
final String query = "SELECT * FROM pets where peopleID=?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, peopleID);
try (final ResultSet result = statement.executeQuery()) {
final List<Pet> pets = new LinkedList<>();
while (result.next()) {
pets.add(rowToEntity(result));
}
return pets;
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
throw new DAOException(e);
}
}
public Pet add(String name, int peopleID) throws DAOException, IllegalArgumentException {
if (name == null) {
throw new IllegalArgumentException("name can't be null");
}
try (Connection conn = this.getConnection()) {
final String query = "INSERT INTO pets VALUES(null, ?, ?)";
try (PreparedStatement statement = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, name);
statement.setInt(2, peopleID);
if (statement.executeUpdate() == 1) {
try (ResultSet resultKeys = statement.getGeneratedKeys()) {
if (resultKeys.next()) {
return new Pet(resultKeys.getInt(1), name, peopleID);
} else {
LOG.log(Level.SEVERE, "Error retrieving inserted id");
throw new SQLException("Error retrieving inserted id");
}
}
} else {
LOG.log(Level.SEVERE, "Error inserting value");
throw new SQLException("Error inserting value");
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error adding a pet", e);
throw new DAOException(e);
}
}
public void modify(Pet pet) throws DAOException, IllegalArgumentException {
if (pet == null) {
throw new IllegalArgumentException("pet can't be null");
}
try (Connection conn = this.getConnection()) {
final String query = "UPDATE pets SET name=?, peopleID=? WHERE id=?";
try (PreparedStatement statement = conn.prepareStatement(query)) {
statement.setString(1, pet.getName());
statement.setInt(2, pet.getPeopleID());
statement.setInt(3, pet.getId());
if (statement.executeUpdate() != 1) {
throw new IllegalArgumentException("name and peopleID can't be null");
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error modifying a pet", e);
throw new DAOException();
}
}
public void delete(int id) throws DAOException, IllegalArgumentException {
try (final Connection conn = this.getConnection()) {
final String query = "DELETE FROM pets WHERE id=?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, id);
if (statement.executeUpdate() != 1) {
throw new IllegalArgumentException("Invalid id");
}
}
} catch (SQLException 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.getString("name"),
row.getInt("peopleID")
);
}
}
package es.uvigo.esei.daa.entities;
import static java.util.Objects.requireNonNull;
/**
* An entity that represents a pet.
*
* @author Imanol Cobian Martinez
*/
public class Pet {
private int id;
private String name;
private int peopleID;
Pet() {}
public Pet(int id, String name, int peopleID) {
this.id = id;
this.setName(name);
this.setPeopleID(peopleID);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = requireNonNull(name, "Name can't be null");
}
public int getPeopleID() {
return peopleID;
}
public void setPeopleID(int peopleID) {
this.peopleID = requireNonNull(peopleID, "PeopleID can't be null");
}
}
package es.uvigo.esei.daa.rest;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
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.PetDAO;
import es.uvigo.esei.daa.entities.Pet;
/**
* REST resource for managing people.
*
* @author Imanol Cobian Martinez
*/
@Path("/pets")
@Produces(MediaType.APPLICATION_JSON)
public class PetResource {
private final static Logger LOG = Logger.getLogger(PeopleResource.class.getName());
private final PetDAO dao;
public PetResource() {
this(new PetDAO());
}
PetResource(PetDAO dao) {
this.dao = dao;
}
@GET
@Path("/{id}")
public Response get(
@PathParam("id") int id
) {
try {
final Pet pet = this.dao.get(id);
return Response.ok(pet).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in get method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error getting a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
@GET
public Response listAll() {
try {
return Response.ok(this.dao.listAll()).build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
return Response.serverError().entity(e.getMessage()).build();
}
}
@GET
@Path("/people{peopleID}")
public Response listByPeopleID(
@PathParam("peopleID") int peopleID
) {
try {
return Response.ok(this.dao.listByPeopleID(peopleID)).build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
return Response.serverError().entity(e.getMessage()).build();
}
}
@POST
public Response add(
@FormParam("name") String name,
@FormParam("peopleID") int peopleID
) {
try {
final Pet newPet = this.dao.add(name, peopleID);
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();
}
}
@PUT
@Path("/{id}")
public Response modify(
@PathParam("id") int id,
@FormParam("name") String name,
@FormParam("peopleID") int peopleID
) {
try {
final Pet modifiedPet = new Pet(id, name, peopleID);
this.dao.modify(modifiedPet);
return Response.ok(modifiedPet).build();
} catch (NullPointerException npe) {
final String message = String.format("Invalid data for person (name: %s, peopleID: %s)", name, peopleID);
LOG.log(Level.FINE, message);
return Response.status(Response.Status.BAD_REQUEST)
.entity(message)
.build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in modify method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error modifying a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
@DELETE
@Path("/{id}")
public Response delete(
@PathParam("id") int id
) {
try {
this.dao.delete(id);
return Response.ok(id).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in delete method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error deleting a pet", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
}
var PeopleDAO = (function() {
var resourcePath = "rest/people/";
var petsPath = "rest/pets/";
var requestByAjax = function(data, done, fail, always) {
done = typeof done !== 'undefined' ? done : function() {};
fail = typeof fail !== 'undefined' ? fail : function() {};
......@@ -23,6 +24,17 @@ var PeopleDAO = (function() {
}, done, fail, always);
};
this.listPetsByPeopleID = function(id, name, done, fail, always) {
$.ajax({
url : petsPath + "people" + id,
type : 'GET'
}).done(function() {
localStorage.setItem('peopleID', btoa(id));
localStorage.setItem('peopleName', name);
window.location = 'pets.html';
});
};
this.addPerson = function(person, done, fail, always) {
requestByAjax({
url : resourcePath,
......
var PetDAO = (function() {
var resourcePath = "rest/pets/";
var peopleID = atob(localStorage.getItem('peopleID'));
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() {};
let authToken = localStorage.getItem('authorization-token');
if (authToken !== null) {
data.beforeSend = function(xhr) {
xhr.setRequestHeader('Authorization', 'Basic ' + authToken);
};
}
$.ajax(data).done(done).fail(fail).always(always);
};
function PetDAO() {
this.listPetsByPeopleID = function(done, fail, always) {
requestByAjax({
url : resourcePath + 'people' + peopleID,
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.id,
type : 'PUT',
data : pet
}, done, fail, always);
};
this.deletePet = function(id, done, fail, always) {
requestByAjax({
url : resourcePath + id,
type : 'DELETE',
}, done, fail, always);
};
}
return PetDAO;
})();
\ No newline at end of file
......@@ -106,6 +106,10 @@ var PeopleView = (function() {
}
};
this.listPetsByPeopleID = function(id, name) {
dao.listPetsByPeopleID(id, name, showErrorMessage);
};
this.isEditing = function() {
return $(formQuery + ' input[name="id"]').val() != "";
};
......@@ -132,7 +136,7 @@ var PeopleView = (function() {
<tr class="row">\
<th class="col-sm-4">Nombre</th>\
<th class="col-sm-5">Apellido</th>\
<th class="col-sm-3">&nbsp;</th>\
<th class="col-sm-3">Acciones</th>\
</tr>\
</thead>\
<tbody>\
......@@ -166,6 +170,7 @@ var PeopleView = (function() {
<td class="name col-sm-4">' + person.name + '</td>\
<td class="surname col-sm-5">' + person.surname + '</td>\
<td class="col-sm-3">\
<a class="pets btn btn-secondary" href="#">Mascotas</a>\
<a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\
</td>\
......@@ -184,6 +189,10 @@ var PeopleView = (function() {
$('#person-' + person.id + ' a.delete').click(function() {
self.deletePerson(person.id);
});
$('#person-' + person.id + ' a.pets').click(function() {
self.listPetsByPeopleID(person.id, person.name);
});
};
var appendToTable = function(person) {
......
var PetView = (function() {
var dao;
// Referencia a this que permite acceder a las funciones públicas desde las funciones de jQuery.
var self;
var peopleID;
var peopleName;
var formId = 'pets-form';
var listId = 'pets-list';
var formQuery = '#' + formId;
var listQuery = '#' + listId;
function PetView(petDao, formContainerId, listContainerId) {
dao = petDao;
self = this;
peopleID = atob(localStorage.getItem('peopleID'));
peopleName = localStorage.getItem('peopleName');
document.getElementById('name').innerHTML = peopleName;
insertPetForm($('#' + formContainerId));
insertPetList($('#' + listContainerId));
this.init = function() {
dao.listPetsByPeopleID(function(pets) {
$.each(pets, function(key, pet) {
appendToTable(pet);
});
},
function() {
alert('No has sido posible acceder al listado de mascotas.');
});
// 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.id + ' td.name').text(pet.name);
$('#pet-' + pet.id + ' td.peopleID').text(peopleID);
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 {
'id': form.find('input[name="id"]').val(),
'name': form.find('input[name="name"]').val(),
'peopleID': peopleID
};
};
this.getPetInRow = function(id) {
var row = $('#pet-' + id);
if (row !== undefined) {
return {
'id': id,
'name': row.find('td.name').text(),
'peopleID': peopleID
};
} else {
return undefined;
}
};
this.editPet = function(id) {
var row = $('#pet-' + id);
if (row !== undefined) {
var form = $(formQuery);
form.find('input[name="id"]').val(id);
form.find('input[name="name"]').val(row.find('td.name').text());
form.find('input[name="peopleID"]').val(peopleID);
$('input#btnSubmit').val('Modificar');
}
};
this.deletePet = function(id) {
if (confirm('Está a punto de eliminar a una pet. ¿Está seguro de que desea continuar?')) {
dao.deletePet(id,
function() {
$('tr#pet-' + id).remove();
},
showErrorMessage
);
}
};
this.isEditing = function() {
return $(formQuery + ' input[name="id"]').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="id"]').val('');
$('#btnSubmit').val('Crear');
};
};
var insertPetList = function(parent) {
parent.append(
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-9">Nombre</th>\
<th class="col-sm-3">Acciones</th>\
</tr>\
</thead>\
<tbody>\
</tbody>\
</table>'
);
};
var insertPetForm = function(parent) {
parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\
<input name="id" type="hidden" value=""/>\
<input name="peopleID" type="hidden" value=""/>\
<div class="row">\
<div class="col-sm-9">\
<input name="name" type="text" value="" placeholder="Nombre" class="form-control" required/>\
</div>\
<div class="col-sm-3">\
<input id="btnSubmit" type="submit" value="Crear" class="btn btn-primary" />\
<input id="btnClear" type="reset" value="Limpiar" class="btn" />\
</div>\
</div>\
</form>'
);
};
var createPetRow = function(pet) {
return '<tr id="pet-'+ pet.id +'" class="row">\
<td class="name col-sm-9">' + pet.name + '</td>\
<td class="col-sm-3">\
<a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\
</td>\
</tr>';
};
var showErrorMessage = function(jqxhr, textStatus, error) {
alert(textStatus + ": " + error);
};
var addRowListeners = function(pet) {
$('#pet-' + pet.id + ' a.edit').click(function() {
self.editPet(pet.id);
});
$('#pet-' + pet.id + ' a.delete').click(function() {
self.deletePet(pet.id);
});
};
var appendToTable = function(pet) {
$(listQuery + ' > tbody:last')
.append(createPetRow(pet));
addRowListeners(pet);
};
return PetView;
})();
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DAA Example</title>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
</head>
<body>
<header>
<div class="navbar navbar-dark bg-dark box-shadow">
<div class="container d-flex justify-content-between">
<a href="main.html" class="navbar-brand d-flex align-items-center">
<strong>DAA Example</strong>
</a>
<button id="logout" class="btn btn-dark">Cerrar sesión</button>
</div>
</div>
</header>
<div class="container">
<div id="pet-container">
<h1 class="display-5 mt-3 mb-3">Mascotas de <span id="name"></span></h1>
</div>
</div>
<script type="text/javascript"
src="http://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="js/dao/pets.js"></script>
<script type="text/javascript" src="js/view/pets.js"></script>
<script type="text/javascript" src="js/login.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
$('#logout').click(function(event) {
event.preventDefault();
doLogout();
});
var view = new PetView(new PetDAO(),
'pet-container', 'pet-container'
);
view.init();
});
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment