Commit f492e60c authored by Aitor Gómez Taboada's avatar Aitor Gómez Taboada

Ejercicio previo para el 04/04

parent 3148c108
......@@ -15,6 +15,14 @@ CREATE TABLE `daaexample`.`users` (
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `daaexample`.`pets` (
`id` int NOT NULL AUTO_INCREMENT,
`pet_name` varchar(20) NOT NULL,
`owner_id` int NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `people`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE USER IF NOT EXISTS 'daa'@'localhost' IDENTIFIED WITH mysql_native_password BY 'daa';
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost';
......@@ -26,6 +34,11 @@ INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Ana','Marí
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'María','Nuevo');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Alba','Fernández');
INSERT INTO `daaexample`.`people` (`id`,`name`,`surname`) VALUES (0,'Asunción','Jiménez');
INSERT INTO `daaexample`.`pets` (`id`,`pet_name`,`owner_id`) VALUES (0,'Tofe',1);
INSERT INTO `daaexample`.`pets` (`id`,`pet_name`,`owner_id`) VALUES (0,'Pipo',4);
INSERT INTO `daaexample`.`pets` (`id`,`pet_name`,`owner_id`) VALUES (0,'Niki',2);
INSERT INTO `daaexample`.`pets` (`id`,`pet_name`,`owner_id`) VALUES (0,'Tim',3);
INSERT INTO `daaexample`.`pets` (`id`,`pet_name`,`owner_id`) VALUES (0,'Yeke',6);
-- The password for each user is its login suffixed with "pass". For example, user "admin" has the password "adminpass".
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
......
......@@ -15,5 +15,19 @@ CREATE TABLE `daaexample`.`users` (
PRIMARY KEY (`login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE USER IF NOT EXISTS 'daa'@'localhost' IDENTIFIED WITH mysql_native_password BY 'daa';
CREATE TABLE `daaexample`.`pets` (
`id` int NOT NULL AUTO_INCREMENT,
`pet_name` varchar(20) NOT NULL,
`owner_id` int NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (owner_id) REFERENCES `daaexample`.`people`(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE USER IF NOT EXISTS 'daa'@'localhost';
UPDATE mysql.user SET plugin = 'mysql_native_password' WHERE user = 'root';
GRANT ALL ON `daaexample`.* TO 'daa'@'localhost';
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('admin', 'admin','ADMIN');
INSERT INTO `daaexample`.`users` (`login`,`password`,`role`)
VALUES ('user', 'user','ADMIN');
cmd /k mysql -u root -p < db/mysql-with-inserts.sql
cmd /k mvn -Prun -DskipTests=true package cargo:start fizzed-watcher:run
......@@ -11,6 +11,8 @@ import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import es.uvigo.esei.daa.rest.PeopleResource;
import es.uvigo.esei.daa.rest.PetsResource;
import es.uvigo.esei.daa.rest.UsersResource;
import es.uvigo.esei.daa.rest.UsersResource;
/**
......@@ -26,7 +28,8 @@ public class DAAExampleApplication extends Application {
public Set<Class<?>> getClasses() {
return Stream.of(
PeopleResource.class,
UsersResource.class
UsersResource.class,
PetsResource.class
).collect(toSet());
}
......
......@@ -52,6 +52,32 @@ public class PeopleDAO extends DAO {
}
}
public String getFullName(int id)
throws DAOException, IllegalArgumentException {
StringBuilder toret = new StringBuilder();
try (final Connection conn = this.getConnection()) {
final String query = "SELECT name, surname FROM people WHERE id=?";
try (final PreparedStatement statement = conn.prepareStatement(query)) {
statement.setInt(1, id);
try (final ResultSet result = statement.executeQuery()) {
if (result.next()) {
toret.append(result.getString("name")).append(" ").append(result.getString("surname"));
return toret.toString();
} else {
throw new IllegalArgumentException("Invalid id");
}
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error getting a person", e);
throw new DAOException(e);
}
}
/**
* Returns a list with all the people persisted in the system.
*
......
package es.uvigo.esei.daa.dao;
import java.sql.Connection;
import es.uvigo.esei.daa.dao.PeopleDAO;
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 es.uvigo.esei.daa.entities.Person;
import es.uvigo.esei.daa.entities.Pet;
public class PetsDAO extends DAO{
private final static java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(PetsDAO.class.getName());
PeopleDAO pdao = new PeopleDAO();
//retorna una mascota a partir de un id
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);
}
}
//devuelve una lista con todas las mascotas registradas
public List<Pet> list() 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);
}
}
//registra una mascota
public Pet add(String pet_name, int owner_id)
throws DAOException, IllegalArgumentException {
boolean esPersona = false;
PeopleDAO peopleDao = new PeopleDAO();
List<Person> listaPeople = peopleDao.list();
for(Person p : listaPeople) {
//LOG.log(Level.INFO, ""+p.getId()+" "+owner_id);
if(p.getId() == owner_id || owner_id == 0) {
esPersona = true;
}
}
if(!esPersona) {
throw new IllegalArgumentException("owner_id doesn´t exist");
}
if (pet_name == null || owner_id < 0) {
throw new IllegalArgumentException("pet name and owner_id can't be null");
}
try (Connection conn = this.getConnection()) {
LOG.log(Level.INFO, "ID: "+owner_id);
final String query = "INSERT INTO pets VALUES(null, ?, ?)";
try (PreparedStatement statement = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, pet_name);
statement.setInt(2, owner_id);
if (statement.executeUpdate() == 1) {
try (ResultSet resultKeys = statement.getGeneratedKeys()) {
if (resultKeys.next()) {
Pet p = new Pet(resultKeys.getInt(1), pet_name, owner_id);
//LOG.log(Level.INFO, p.toString());
return p;
} 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);
}
}
//modifica los datos de una persona
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 pet_name=?, owner_id=? WHERE id=?";
try (PreparedStatement statement = conn.prepareStatement(query)) {
statement.setString(1, pet.getpet_name());
statement.setInt(2, pet.getowner_id());
statement.setInt(3, pet.getId());
if (statement.executeUpdate() != 1) {
throw new IllegalArgumentException("name and owner can't be null");
}
}
} catch (SQLException e) {
LOG.log(Level.SEVERE, "Error modifying a pet", e);
throw new DAOException();
}
}
//elimina una mascota a partir de su id
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("pet_name"),
row.getInt("owner_id")
);
}
}
package es.uvigo.esei.daa.entities;
import static java.util.Objects.requireNonNull;
public class Pet {
private int id;
private String pet_name;
private int owner_id;
public Pet() {} //Constructor para la conversion JSON
public Pet(int id, String pet_name, int owner_id){
this.id = id;
this.setPetName(pet_name);
this.setOwnerId(owner_id);
}
public int getId() {
return this.id;
}
public String getpet_name(){
return this.pet_name;
}
public int getowner_id() {
return this.owner_id;
}
public void setPetName(String pet_name) {
this.pet_name = requireNonNull(pet_name, "Pet name can't be null");
}
public void setOwnerId(int owner_id) {
this.owner_id = requireNonNull(owner_id, "Owner id can´t be null");
}
public void setPetId(int id) {
this.id = id;
}
@Override
public String toString() {
StringBuilder toret = new StringBuilder();
toret.append("Id: ").append(getId()).append("\n");
toret.append("Nombre: ").append(getpet_name()).append("\n");
toret.append("Owner id: ").append(getowner_id()).append("\n");
return toret.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Pet))
return false;
Pet other = (Pet) obj;
if (id != other.id)
return false;
return true;
}
}
......@@ -75,6 +75,30 @@ public class PeopleResource {
.build();
}
}
@GET
@Path("/name/{id}")
public Response getFullName(
@PathParam("id") int id
) {
try {
final String name = this.dao.getFullName(id);
return Response.ok(name).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid person id in get full name method", iae);
return Response.status(Response.Status.BAD_REQUEST)
.entity(iae.getMessage())
.build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error getting a person", e);
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
/**
* Returns the complete list of people stored in the system.
......
package es.uvigo.esei.daa.rest;
import java.util.logging.Level;
import java.util.logging.Logger;
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 javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import es.uvigo.esei.daa.dao.DAOException;
import es.uvigo.esei.daa.dao.PetsDAO;
import es.uvigo.esei.daa.entities.Pet;
//necesario registrar cada resource en DAAExampleApplication
@Path("/pets")
@Produces(MediaType.APPLICATION_JSON)
public class PetsResource {
private final static Logger LOG = Logger.getLogger(PetsResource.class.getName());
private final PetsDAO dao;
public PetsResource() {
this(new PetsDAO());
}
PetsResource(PetsDAO 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 ie) {
LOG.log(Level.FINE, "Invalid pet id in get method", ie);
return Response.status(Response.Status.BAD_REQUEST)
.entity(ie.getMessage())
.build();
} catch (DAOException e) {
return Response.serverError()
.entity(e.getMessage())
.build();
}
}
@GET
public Response list() {
try {
return Response.ok(this.dao.list()).build();
} catch (DAOException e) {
LOG.log(Level.SEVERE, "Error listing pets", e);
return Response.serverError().entity(e.getMessage()).build();
}
}
@POST
public Response add(
@FormParam("pet_name") String name,
@FormParam("owner_id") int owner_id
) {
if(name == null || owner_id <= 0) {
return Response.status(Response.Status.BAD_REQUEST).entity("Mal formada").build();
}
else {
try {
//LOG.log(Level.INFO, "ID REST: "+owner_id);
final Pet newPet = this.dao.add(name, owner_id);
return Response.ok(newPet).build();
} catch (IllegalArgumentException iae) {
LOG.log(Level.FINE, "Invalid pet id in add", 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("pet_name") String name,
@FormParam("owner_id") int owner
) {
if(id < 0 || name == null || owner <= 0) {
return Response.status(Response.Status.BAD_REQUEST).entity("Mal formada").build();
}
else {
try {
final Pet modifiedPet = new Pet(id, name, owner);
//LOG.log(Level.INFO,modifiedPet.toString());
this.dao.modify(modifiedPet);
return Response.ok(modifiedPet).build();
} catch (NullPointerException npe) {
final String message = String.format("Invalid data for pet (name: %s, owner: %i)", name, owner);
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
) {
if(id <= 0) {
return Response.status(Response.Status.BAD_REQUEST).entity("Mal formada").build();
}
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();
}
}
}
......@@ -59,6 +59,21 @@
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<security-constraint>
<web-resource-collection>
<web-resource-name>Pet Admin Area</web-resource-name>
<url-pattern>/rest/pets/*</url-pattern>
<http-method>GET</http-method>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>ADMIN</role-name>
</auth-constraint>
</security-constraint>
<!-- Security roles referenced by this web application -->
<security-role>
......
......@@ -45,6 +45,13 @@ var PeopleDAO = (function() {
type : 'DELETE',
}, done, fail, always);
};
this.getFullName = function(id, done, fail, always) {
requestByAjax({
url : resourcePath + "name/" + id,
type : 'GET'
}, done, fail, always);
};
}
return PeopleDAO;
......
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() {};
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 PetsDAO() {
this.listPets = 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.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 PetsDAO;
})();
\ No newline at end of file
......@@ -130,8 +130,9 @@ var PeopleView = (function() {
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-4">Nombre</th>\
<th class="col-sm-5">Apellido</th>\
<th class="col-sm-2">Id</th>\
<th class="col-sm-3">Nombre</th>\
<th class="col-sm-3">Apellido</th>\
<th class="col-sm-3">&nbsp;</th>\
</tr>\
</thead>\
......@@ -163,8 +164,9 @@ var PeopleView = (function() {
var createPersonRow = function(person) {
return '<tr id="person-'+ person.id +'" class="row">\
<td class="name col-sm-4">' + person.name + '</td>\
<td class="surname col-sm-5">' + person.surname + '</td>\
<td class="id col-sm-1">' + person.id + '</td>\
<td class="name col-sm-3">' + person.name + '</td>\
<td class="surname col-sm-3">' + person.surname + '</td>\
<td class="col-sm-3">\
<a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\
......
var PetsView = (function() {
var dao;
var peopleDAO;
// 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 PetsView(peopleDao, petsDao, formContainerId, listContainerId) {
peopleDAO = peopleDao;
dao = petsDao;
var dict = {}
self = this;
insertPetsForm($('#' + formContainerId));
insertPetsList($('#' + listContainerId));
this.init = function() {
dao.listPets(function(pet) {
$.each(pet, function(key, pet) {
appendToTable(pet);
});
},
function() {
alert('No has sido posible acceder al listado de mascotas.');
});
peopleDAO.listPeople(function(people) {
$.each(people, function(key, people) {
$('#pet_owner_select').append($("<option></option>").attr("value", people.id).text(people.name + ' ' +people.surname));
});
},
function() {
});
// 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();
console.log(pet);
if (self.isEditing()) {
dao.modifyPet(pet,
function(pet) {
console.log(pet);
$('#pet-' + pet.id + ' td.pet_name').text(pet.pet_name);
$('#pet-' + pet.id + ' td.owner_id').text(pet.owner_id);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
} else {
dao.addPet(pet,
function(pet) {
console.log(pet);
appendToTable(pet);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
}
return false;
});
$('#btnClear').click(this.resetForm);
};
this.reloadSelect = function(){
$('#pet_owner_select').find('option').remove().end();
peopleDAO.listPeople(function(people) {
$.each(people, function(key, people) {
$('#pet_owner_select').append($("<option></option>").attr("value", people.id).text(people.name + ' ' +people.surname));
});
},
function() {
});
}
this.getPetInForm = function() {
var form = $(formQuery);
return {
'id': form.find('input[name="id"]').val(),
'pet_name': form.find('input[name="pet_name"]').val(),
'owner_id': $('#pet_owner_select option:selected').val()
};
};
this.getPetInRow = function(id) {
var row = $('#pet-' + id);
if (row !== undefined) {
return {
'id': id,
'pet_name': row.find('td.pet_name').text(),
'owner_id': row.find('td.owner_id').text()
};
} 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="pet_name"]').val(row.find('td.pet_name').text());
form.find('input[name="owner_id"]').val(row.find('td.owner_id').text());
$('input#btnSubmit').val('Modificar');
}
};
this.deletePet = function(id) {
if (confirm('Está a punto de eliminar a una mascota. ¿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 insertPetsList = function(parent) {
parent.append(
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-4">Nombre</th>\
<th class="col-sm-5">Propietario</th>\
<th class="col-sm-3">&nbsp;</th>\
</tr>\
</thead>\
<tbody>\
</tbody>\
</table>'
);
};
var insertPetsForm = function(parent) {
parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\
<input name="id" type="hidden" value=""/>\
<div class="row">\
<div class="col-sm-4">\
<input name="pet_name" type="text" value="" placeholder="Nombre" class="form-control" required/>\
</div>\
<div class="col-sm-5">\
<select id="pet_owner_select" name="pet_owner" class="form-control">\
</select>\
</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="pet_name col-sm-4">' + pet.pet_name + '</td>\
<td class="owner_id col-sm-5">' + pet.owner_id + '</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 PetsView;
})();
......@@ -15,35 +15,68 @@
<a href="#" class="navbar-brand d-flex align-items-center">
<strong>DAA Example</strong>
</a>
<button id="logout" class="btn btn-dark">Cerrar sesión</button>
<button id="cambio" class="btn btn-dark">Gestionar mascotas</button>
<button id="logout" class="btn btn-dark">Cerrar sesión</button>
</div>
</div>
</header>
<div class="container">
<div id="people-container">
<!--<div id="people-container">
<h1 class="display-5 mt-3 mb-3">Personas</h1>
</div>-->
<div id ="people-container">
<h1 class="display-5 mt-3 mb-3"> Personas </h1>
</div>
<div id="pet-container">
<h1 class="display-5 mt-3 mb-3"> Mascotas </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/dao/people.js"></script>
<script type="text/javascript" src="js/view/pets.js"></script>
<script type="text/javascript" src="js/view/people.js"></script>
<script type="text/javascript" src="js/login.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
var petView;
var peopleView;
var select;
$('#logout').click(function(event) {
event.preventDefault();
doLogout();
});
var view = new PeopleView(new PeopleDAO(),
'people-container', 'people-container'
);
view.init();
$('#cambio').click(function(event){
if($('#people-container').is(':visible')){
petView.reloadSelect();
$('#people-container').hide();
$('#pet-container').show();
$("#cambio").html('Gestionar personas');
}
else{
$('#people-container').show();
$('#pet-container').hide();
$("#cambio").html('Gestionar mascotas');
}
});
peopleView = new PeopleView(new PeopleDAO(), 'people-container', 'people-container');
peopleView.init();
petView = new PetsView(new PeopleDAO(), new PetsDAO(),
'pet-container', 'pet-container'
);
petView.init();
$('#pet-container').hide();
});
</script>
</body>
......
package es.uvigo.esei.daa.dataset;
import static java.util.Arrays.binarySearch;
import static java.util.Arrays.stream;
import java.util.Arrays;
import java.util.function.Predicate;
import es.uvigo.esei.daa.entities.Pet;
public final class PetsDataset {
private PetsDataset() {}
public static Pet[] pets() {
return new Pet[] {
new Pet(1, "Tofe", 2),
new Pet(2, "Niki", 3),
new Pet(3, "Tobi", 1),
new Pet(4, "Tara", 2),
new Pet(5, "Tim", 5),
new Pet(6, "Trosky", 6),
};
}
public static Pet[] petsWithout(int ... ids) {
Arrays.sort(ids);
final Predicate<Pet> hasValidId = pet ->
binarySearch(ids, pet.getId()) < 0;
return stream(pets())
.filter(hasValidId)
.toArray(Pet[]::new);
}
public static Pet pet(int id) {
return stream(pets())
.filter(pet -> pet.getId() == id)
.findAny()
.orElseThrow(IllegalArgumentException::new);
}
public static Integer existentId() {
return 5;
}
public static Integer nonExistentId() {
return 1234;
}
public static Pet existentPet() {
return pet(existentId());
}
public static Pet nonExistentPet() {
return new Pet(nonExistentId(), "Baddy", 4);
}
public static String newPetName() {
return "Miku";
}
public static Integer newOwnerId() {
return 4;
}
public static Pet newPet() {
return new Pet(pets().length + 1, newPetName(), newOwnerId());
}
}
\ No newline at end of file
package es.uvigo.esei.daa.entities;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
public class PetsUnitTest {
@Test
public void testPetIntStringInt() {
final int id = 1;
final String name = "Laia";
final int ownerId = 4;
final Pet pet = new Pet(id, name, ownerId);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getpet_name(), is(equalTo(name)));
assertThat(pet.getowner_id(), is(equalTo(ownerId)));
}
@Test(expected = NullPointerException.class)
public void testPetIntStringIntNullName() {
new Pet(1, null, 2);
}
@Test
public void testSetName() {
final int id = 1;
final int ownerId = 2;
final Pet pet = new Pet(id, "Laia", 2);
pet.setPetName("Beethoven");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getpet_name(), is(equalTo("Beethoven")));
assertThat(pet.getowner_id(), is(equalTo(ownerId)));
}
@Test(expected = NullPointerException.class)
public void testSetNullName() {
final Pet pet= new Pet(1, "Beethoven", 2);
pet.setPetName(null);
}
@Test
public void testSetOwnerId() {
final int id = 1;
final String name = "Beethoven";
final Pet pet= new Pet(id, name, 2);
pet.setOwnerId(6);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getpet_name(), is(equalTo(name)));
assertThat(pet.getowner_id(), is(equalTo(6)));
}
@Test
public void testEqualsObject() {
final Pet petA = new Pet(1, "Name A", 2);
final Pet petB = new Pet(1, "Name B", 2);
assertTrue(petB.equals(petA));
}
//Error: cannot define class using reflection, downgradear java
@Test
public void testEqualsHashcode() {
EqualsVerifier.forClass(Pet.class)
.withIgnoredFields("pet_name", "owner_id")
.suppress(Warning.STRICT_INHERITANCE)
.suppress(Warning.NONFINAL_FIELDS)
.verify();
}
}
package es.uvigo.esei.daa.matchers;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import es.uvigo.esei.daa.entities.Pet;
public class IsEqualToPet extends IsEqualToEntity<Pet> {
public IsEqualToPet(Pet entity) {
super(entity);
}
@Override
protected boolean matchesSafely(Pet actual) {
this.clearDescribeTo();
if (actual == null) {
this.addTemplatedDescription("actual", expected.toString());
return false;
} else {
return checkAttribute("id", Pet::getId, actual)
&& checkAttribute("pet_name", Pet::getpet_name, actual)
&& checkAttribute("owner_id", Pet::getowner_id, actual);
}
}
/**
* Factory method that creates a new {@link IsEqualToEntity} matcher with
* the provided {@link Pet} as the expected value.
*
* @param pet the expected pet
* @return a new {@link IsEqualToEntity} matcher with the provided
* {@link Pet} as the expected value.
*/
@Factory
public static IsEqualToPet equalsToPet(Pet pet) {
return new IsEqualToPet(pet);
}
/**
* Factory method that returns a new {@link Matcher} that includes several
* {@link IsEqualToPet} matchers, each one using an {@link Pet} of the
* provided ones as the expected value.
*
* @param pets the pets to be used as the expected values.
* @return a new {@link Matcher} that includes several
* {@link IsEqualToPet} matchers, each one using an {@link Pet} of the
* provided ones as the expected value.
* @see IsEqualToEntity#containsEntityInAnyOrder(java.util.function.Function, Object...)
*/
@Factory
public static Matcher<Iterable<? extends Pet>> containsPetsInAnyOrder(Pet ... pets) {
return containsEntityInAnyOrder(IsEqualToPet::equalsToPet, pets);
}
}
package es.uvigo.esei.daa.rest;
import static es.uvigo.esei.daa.dataset.PeopleDataset.existentId;
import static es.uvigo.esei.daa.dataset.PeopleDataset.existentPerson;
import static es.uvigo.esei.daa.dataset.PeopleDataset.newName;
import static es.uvigo.esei.daa.dataset.PeopleDataset.newPerson;
import static es.uvigo.esei.daa.dataset.PeopleDataset.newSurname;
import static es.uvigo.esei.daa.dataset.PeopleDataset.nonExistentId;
import static es.uvigo.esei.daa.dataset.PeopleDataset.people;
import static es.uvigo.esei.daa.dataset.PetsDataset.*;
import static es.uvigo.esei.daa.dataset.UsersDataset.adminLogin;
import static es.uvigo.esei.daa.dataset.UsersDataset.normalLogin;
import static es.uvigo.esei.daa.dataset.UsersDataset.userToken;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasBadRequestStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasOkStatus;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasUnauthorized;
import static es.uvigo.esei.daa.matchers.IsEqualToPerson.containsPeopleInAnyOrder;
import static es.uvigo.esei.daa.matchers.HasHttpStatus.hasForbidden;
import static es.uvigo.esei.daa.matchers.IsEqualToPerson.equalsToPerson;
import static es.uvigo.esei.daa.matchers.IsEqualToPet.*;
import static javax.ws.rs.client.Entity.entity;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import javax.sql.DataSource;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.MethodMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import es.uvigo.esei.daa.DAAExampleTestApplication;
import es.uvigo.esei.daa.entities.Person;
import es.uvigo.esei.daa.entities.Pet;
import es.uvigo.esei.daa.listeners.ApplicationContextBinding;
import es.uvigo.esei.daa.listeners.ApplicationContextJndiBindingTestExecutionListener;
import es.uvigo.esei.daa.listeners.DbManagement;
import es.uvigo.esei.daa.listeners.DbManagementTestExecutionListener;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:contexts/mem-context.xml")
@TestExecutionListeners({
DbUnitTestExecutionListener.class,
DbManagementTestExecutionListener.class,
ApplicationContextJndiBindingTestExecutionListener.class
})
@ApplicationContextBinding(
jndiUrl = "java:/comp/env/jdbc/daaexample",
type = DataSource.class
)
@DbManagement(
create = "classpath:db/hsqldb.sql",
drop = "classpath:db/hsqldb-drop.sql"
)
@DatabaseSetup("/datasets/dataset.xml")
@ExpectedDatabase("/datasets/dataset.xml")
public class PetsResourceTest extends JerseyTest {
@Override
protected Application configure() {
return new DAAExampleTestApplication();
}
@Override
protected void configureClient(ClientConfig config) {
super.configureClient(config);
// Enables JSON transformation in client
config.register(JacksonJsonProvider.class);
config.property("com.sun.jersey.api.json.POJOMappingFeature", Boolean.TRUE);
}
@Test
public void testPetList() throws IOException {
final Response response = target("pets").request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasOkStatus());
final List<Pet> pets = response.readEntity(new GenericType<List<Pet>>(){});
assertThat(pets, containsPetsInAnyOrder(pets()));
}
@Test
public void testPetListUnauthorized() throws IOException {
final Response response = target("pets").request()
.get();
assertThat(response, hasUnauthorized());
}
@Test
public void testPetGet() throws IOException {
final Response response = target("pets/" + existentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasOkStatus());
final Pet pet = response.readEntity(Pet.class);
assertThat(pet, is(equalsToPet(existentPet())));
}
@Test
public void testPetGetUnauthorized() throws IOException {
final Response response = target("pets/" + existentId()).request()
.get();
assertThat(response, hasUnauthorized());
}
@Test
public void testPetGetInvalidId() throws IOException {
final Response response = target("pets/" + nonExistentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasBadRequestStatus());
}
@Test
@ExpectedDatabase("/datasets/dataset-pets-add.xml")
public void testPetAdd() throws IOException {
final Form form = new Form();
form.param("pet_name", newPetName());
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasOkStatus());
final Pet pet = response.readEntity(Pet.class);
assertThat(pet, is(equalsToPet(newPet())));
}
@Test
public void testPetAddUnauthorized() throws IOException {
final Form form = new Form();
form.param("pet_name", newPetName());
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE)
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasUnauthorized());
}
@Test
public void testPetAddMissingName() throws IOException {
final Form form = new Form();
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testPetAddMissingSurname() throws IOException {
final Form form = new Form();
form.param("pet_name", newName());
final Response response = target("pets/").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
/* TODO: Arreglar fallo id. Posiblemente campo autoincrement, dataset esta bien
@Test
@ExpectedDatabase("/datasets/dataset-pets-modify.xml")
public void testPetModify() throws IOException {
final Form form = new Form();
form.param("pet_name", newPetName());
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasOkStatus());
System.out.println(response.getStatus());
Pet pet = newPet();
pet.setPetId(5);
Pet modifiedPet = response.readEntity(Pet.class);
System.out.println("PET MODIFICADA "+modifiedPet.toString());
System.out.println("PET EXISTENTE "+pet.toString());
assertEquals(pet.getowner_id(), modifiedPet.getowner_id());
assertEquals(pet.getpet_name(), modifiedPet.getpet_name());
}*/
@Test
public void testPetModifyUnauthorized() throws IOException {
final Form form = new Form();
form.param("pet_name", newPetName());
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasUnauthorized());
}
@Test
public void testPetModifyName() throws IOException {
final Form form = new Form();
form.param("pet_name", newPetName());
final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testPetModifyOwnerId() throws IOException {
final Form form = new Form();
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
public void testPetModifyInvalidId() throws IOException {
final Form form = new Form();
form.param("pet_name", newPetName());
form.param("owner_id", String.valueOf(newOwnerId()));
final Response response = target("pets/" + nonExistentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(adminLogin()))
.put(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasBadRequestStatus());
}
@Test
@ExpectedDatabase("/datasets/dataset-pets-delete.xml")
public void testPetDelete() throws IOException {
final Response response = target("pets/" + existentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.delete();
assertThat(response, hasOkStatus());
final Integer deletedId = response.readEntity(Integer.class);
assertThat(deletedId, is(equalTo(existentId())));
}
@Test
public void testPetDeleteUnauthorized() throws IOException {
final Response response = target("pets/" + existentId()).request()
.delete();
assertThat(response, hasUnauthorized());
}
@Test
public void testPetDeleteInvalidId() throws IOException {
final Response response = target("pets/" + nonExistentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.delete();
assertThat(response, hasBadRequestStatus());
}
}
......@@ -5,11 +5,13 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import es.uvigo.esei.daa.rest.PeopleResourceTest;
import es.uvigo.esei.daa.rest.PetsResourceTest;
import es.uvigo.esei.daa.rest.UsersResourceTest;
@SuiteClasses({
PeopleResourceTest.class,
UsersResourceTest.class
UsersResourceTest.class,
PetsResourceTest.class
})
@RunWith(Suite.class)
public class IntegrationTestSuite {
......
......@@ -5,9 +5,11 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import es.uvigo.esei.daa.entities.PersonUnitTest;
import es.uvigo.esei.daa.entities.PetsUnitTest;
@SuiteClasses({
PersonUnitTest.class
PersonUnitTest.class,
PetsUnitTest.class
})
@RunWith(Suite.class)
public class UnitTestSuite {
......
......@@ -16,4 +16,12 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="5" pet_name="Tim" owner_id="5"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
</dataset>
\ No newline at end of file
......@@ -14,4 +14,12 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="5" pet_name="Tim" owner_id="5"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
</dataset>
\ No newline at end of file
......@@ -15,4 +15,11 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="5" pet_name="Tim" owner_id="5"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
</dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dataset SYSTEM "dataset.dtd">
<dataset>
<people id="1" name="Antón" surname="Álvarez" />
<people id="2" name="Ana" surname="Amargo" />
<people id="3" name="Manuel" surname="Martínez" />
<people id="4" name="María" surname="Márquez" />
<people id="5" name="Lorenzo" surname="López" />
<people id="6" name="Laura" surname="Laredo" />
<people id="7" name="Perico" surname="Palotes" />
<people id="8" name="Patricia" surname="Pérez" />
<people id="9" name="Julia" surname="Justa" />
<people id="10" name="Juan" surname="Jiménez" />
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="5" pet_name="Tim" owner_id="5"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
<pets id="7" pet_name="Miku" owner_id="4"/>
</dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dataset SYSTEM "dataset.dtd">
<dataset>
<people id="1" name="Antón" surname="Álvarez" />
<people id="2" name="Ana" surname="Amargo" />
<people id="3" name="Manuel" surname="Martínez" />
<people id="4" name="María" surname="Márquez" />
<people id="5" name="Lorenzo" surname="López" />
<people id="6" name="Laura" surname="Laredo" />
<people id="7" name="Perico" surname="Palotes" />
<people id="8" name="Patricia" surname="Pérez" />
<people id="9" name="Julia" surname="Justa" />
<people id="10" name="Juan" surname="Jiménez" />
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
</dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dataset SYSTEM "dataset.dtd">
<dataset>
<people id="1" name="Antón" surname="Álvarez" />
<people id="2" name="Ana" surname="Amargo" />
<people id="3" name="Manuel" surname="Martínez" />
<people id="4" name="María" surname="Márquez" />
<people id="5" name="Lorenzo" surname="López" />
<people id="6" name="Laura" surname="Laredo" />
<people id="7" name="Perico" surname="Palotes" />
<people id="8" name="Patricia" surname="Pérez" />
<people id="9" name="Julia" surname="Justa" />
<people id="10" name="Juan" surname="Jiménez" />
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="5" pet_name="Miku" owner_id="4"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
</dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT dataset (people*, users*)>
<!ELEMENT dataset (people*, users*, pets*)>
<!ELEMENT people EMPTY>
<!ELEMENT users EMPTY>
<!ELEMENT pets EMPTY>
<!ATTLIST people
id CDATA #IMPLIED
name CDATA #IMPLIED
......@@ -12,3 +13,8 @@
password CDATA #IMPLIED
role CDATA #IMPLIED
>
<!ATTLIST pets
id CDATA #IMPLIED
pet_name CDATA #IMPLIED
owner_id CDATA #IMPLIED
>
\ No newline at end of file
......@@ -15,4 +15,12 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" pet_name="Tofe" owner_id="2"/>
<pets id="2" pet_name="Niki" owner_id="3"/>
<pets id="3" pet_name="Tobi" owner_id="1"/>
<pets id="4" pet_name="Tara" owner_id="2"/>
<pets id="5" pet_name="Tim" owner_id="5"/>
<pets id="6" pet_name="Trosky" owner_id="6"/>
</dataset>
\ No newline at end of file
DROP TABLE People IF EXISTS;
DROP TABLE Users IF EXISTS;
DROP TABLE Pets IF EXISTS;
......@@ -10,4 +10,10 @@ CREATE TABLE users (
password VARCHAR(64) NOT NULL,
role VARCHAR(5) NOT NULL,
PRIMARY KEY (login)
);
\ No newline at end of file
);
CREATE TABLE pets (
id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL,
pet_name VARCHAR(50) NOT NULL,
owner_id INT NOT NULL
);
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