Commit 21785083 authored by alexgomezg's avatar alexgomezg

Se añade Pets a la aplicación

Se añade todo lo necesario para la gestion de Mascotas en la aplicación
parent 3148c108
...@@ -12,6 +12,7 @@ import javax.ws.rs.core.Application; ...@@ -12,6 +12,7 @@ import javax.ws.rs.core.Application;
import es.uvigo.esei.daa.rest.PeopleResource; import es.uvigo.esei.daa.rest.PeopleResource;
import es.uvigo.esei.daa.rest.UsersResource; import es.uvigo.esei.daa.rest.UsersResource;
import es.uvigo.esei.daa.rest.PetResource;
/** /**
* Configuration of the REST application. This class includes the resources and * Configuration of the REST application. This class includes the resources and
...@@ -26,6 +27,7 @@ public class DAAExampleApplication extends Application { ...@@ -26,6 +27,7 @@ public class DAAExampleApplication extends Application {
public Set<Class<?>> getClasses() { public Set<Class<?>> getClasses() {
return Stream.of( return Stream.of(
PeopleResource.class, PeopleResource.class,
PetResource.class,
UsersResource.class UsersResource.class
).collect(toSet()); ).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 Alex
*
*/
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, String type, int peopleID) throws DAOException, IllegalArgumentException {
if (name == null || type==null) {
throw new IllegalArgumentException("name and type 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.setString(2, type);
statement.setInt(3, peopleID);
System.out.println(statement.toString());
if (statement.executeUpdate() == 1) {
try (ResultSet resultKeys = statement.getGeneratedKeys()) {
if (resultKeys.next()) {
return new Pet(resultKeys.getInt(1), name, type, 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=?,type=?,peopleID=? WHERE id=?";
try (PreparedStatement statement = conn.prepareStatement(query)) {
statement.setString(1, pet.getName());
statement.setString(2, pet.getType());
statement.setInt(3, pet.getPeopleID());
statement.setInt(4, 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.getString("type"),
row.getInt("peopleID")
);
}
}
package es.uvigo.esei.daa.entities;
import static java.util.Objects.requireNonNull;
/**
* An entity that represents a pet.
*
* @author Alex
*/
public class Pet {
private int id;
private String name;
private String type;
private int peopleID;
Pet() {
}
public Pet(int id, String name, String type, int peopleID) {
this.id = id;
this.setName(name);
this.setType(type);
this.setPeopleID(peopleID);
}
public int getId() {
return id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = requireNonNull(type, "Name can't be null");
}
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");
}
@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;
}
}
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("type") String type,
@FormParam("peopleID") int peopleID
) {
try {
final Pet newPet = this.dao.add(name,type,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("type") String type,
@FormParam("peopleID") int peopleID
) {
try {
final Pet modifiedPet = new Pet(id, name,type,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 PetDAO = (function () {
var resourcePath = "rest/pets/";
//var peopleID = atob(localStorage.getItem('peopleID'));
var peopleID = 1;
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 (peopleID,done, fail, always) {
requestByAjax({
url: resourcePath + 'people' + peopleID,
type: 'GET'
}, done, fail, always);
};
this.listAll = 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 PetDAO;
})();
...@@ -36,6 +36,7 @@ var PeopleView = (function() { ...@@ -36,6 +36,7 @@ var PeopleView = (function() {
function(person) { function(person) {
$('#person-' + person.id + ' td.name').text(person.name); $('#person-' + person.id + ' td.name').text(person.name);
$('#person-' + person.id + ' td.surname').text(person.surname); $('#person-' + person.id + ' td.surname').text(person.surname);
$('#person-' + person.id + ' td.pet_type').text(person.type);
self.resetForm(); self.resetForm();
}, },
showErrorMessage, showErrorMessage,
...@@ -168,6 +169,7 @@ var PeopleView = (function() { ...@@ -168,6 +169,7 @@ var PeopleView = (function() {
<td class="col-sm-3">\ <td class="col-sm-3">\
<a class="edit btn btn-primary" href="#">Editar</a>\ <a class="edit btn btn-primary" href="#">Editar</a>\
<a class="delete btn btn-warning" href="#">Eliminar</a>\ <a class="delete btn btn-warning" href="#">Eliminar</a>\
<a class="show btn btn-secondary" href="#">Mascotas</a>\
</td>\ </td>\
</tr>'; </tr>';
}; };
...@@ -184,6 +186,14 @@ var PeopleView = (function() { ...@@ -184,6 +186,14 @@ var PeopleView = (function() {
$('#person-' + person.id + ' a.delete').click(function() { $('#person-' + person.id + ' a.delete').click(function() {
self.deletePerson(person.id); self.deletePerson(person.id);
}); });
$('#person-' + person.id + ' a.show').click(function () {
document.getElementById("people-container").innerHTML = "<h1 class=display-5 mt-3 mb-3>Mascotas de "+person.name+" "+person.surname+"</h1>";
var view = new PetView(new PetDAO(),
'people-container', 'people-container',person.id);
view.init();
});
}; };
var appendToTable = function(person) { 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 formId = 'people-form';
var listId = 'people-list';
var formQuery = '#' + formId;
var listQuery = '#' + listId;
var humans = []
var humans_list = []
function Human(id, name, surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
var cont=0;
var daoPeople = new PeopleDAO();
daoPeople.listPeople(function (people) {
$.each(people, function (key, human) {
humans[human.id] = new Human(human.id, human.name, human.surname);
humans_list[cont] = new Human(human.id, human.name, human.surname);
cont++;
});
},
function () {
alert('No has sido posible acceder al listado de personas.');
});
function PetView(petDao, formContainerId, listContainerId,paramID) {
peopleID=paramID;
dao = petDao;
self = this;
insertPetForm($('#' + formContainerId), humans_list,humans);
insertPetList($('#' + listContainerId));
console.log(humans);
this.init = function () {
if(peopleID==="all"){
dao.listAll(function (people) {
$.each(people, function (key, pet) {
appendToTable(pet, humans);
});
},
function () {
alert('No has sido posible acceder al listado de mascotas.');
});
}else{
dao.listPetsByPeopleID(peopleID,function (people) {
$.each(people, function (key, pet) {
appendToTable(pet, humans);
});
},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) {
$('#person-' + pet.id + ' td.name').text(pet.name);
$('#person-' + pet.id + ' td.surname').text(humans[pet.peopleID].name+" "+humans[pet.peopleID].surname);
$('#person-' + pet.id + ' td.pet_type').text(pet.type);
self.resetForm();
},
showErrorMessage,
self.enableForm
);
} else {
dao.addPet(pet,
function (pet) {
appendToTable(pet,humans);
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(),
'type': form.find('input[name="type"]').val(),
'peopleID': document.getElementById('dueno').value
};
};
this.getPetInRow = function (id) {
var row = $('#person-' + id);
if (row !== undefined) {
return {
'id': id,
'name': row.find('td.name').text(),
'type': row.find('td.pet_type').text(),
'peopleID': row.find('td.surname').text()
};
} else {
return undefined;
}
};
this.editPet = function (id) {
var row = $('#person-' + 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="surname"]').val(row.find('td.surname').text());
form.find('input[name="type"]').val(row.find('td.pet_type').text());
$('input#btnSubmit').val('Modificar');
}
};
this.deletePet = function (id) {
if (confirm('Está a punto de eliminar a una persona. ¿Está seguro de que desea continuar?')) {
dao.deletePet(id,
function () {
$('tr#person-' + 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 returnHumansSelect = function (humans) {
var toret = "<select id=dueno class=form-control>";
var cont = 0
var i=0;
for (i=0;i<humans.length;i++){
toret+="<option value="+humans[i].id+">"+humans[i].name+" "+humans[i].surname+"</option>";
}
toret+="</select>";
return toret;
};
var returnHumanTextBox = function (human) {
var toret ="<input type=hidden id=dueno value=\""+human.id+"\"/><input name=owner type=text value=\""+human.name+" "
+human.surname+"\" placeholder=Dueño class=form-control readonly/>";
return toret;
};
var insertPetForm = function (parent, humans,humans_map) {
var txtToAppend="";
if(peopleID==='all'){
txtToAppend=returnHumansSelect(humans);
}else{
alert(peopleID);
txtToAppend=returnHumanTextBox(humans_map[peopleID]);
}
parent.append(
'<form id="' + formId + '" class="mb-5 mb-10">\
<input name="id" type="hidden" value=""/>\
<div class="row">\
<div class="col-sm-2">\
<input name="name" type="text" value="" placeholder="Nombre" class="form-control" required/>\
</div>\
<div class="col-sm-2">\
<input name="type" type="text" value="" placeholder="Tipo" class="form-control" required/>\
</div>\
<div class="col-sm-1">Dueño:</div>\
<div class="col-sm-3">'+ txtToAppend +'</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 insertPetList = function (parent) {
parent.append(
'<table id="' + listId + '" class="table">\
<thead>\
<tr class="row">\
<th class="col-sm-3">Nombre</th>\
<th class="col-sm-4">Dueño</th>\
<th class="col-sm-2">Tipo</th>\
<th class="col-sm-3">&nbsp;</th>\
</tr>\
</thead>\
<tbody>\
</tbody>\
</table>'
);
};
var createPetRow = function (pet, human) {
return '<tr id="person-' + pet.id + '" class="row">\
<td class="name col-sm-3">' + pet.name + '</td>\
<td class="surname col-sm-4">' + human[pet.peopleID].name + " " + human[pet.peopleID].surname + '</td>\
<td class="pet_type col-sm-2">' + pet.type + '</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) {
$('#person-' + pet.id + ' a.edit').click(function () {
self.editPet(pet.id);
});
$('#person-' + pet.id + ' a.delete').click(function () {
self.deletePet(pet.id);
});
};
var appendToTable = function (pet, humans) {
$(listQuery + ' > tbody:last')
.append(createPetRow(pet, humans));
addRowListeners(pet);
};
return PetView;
})();
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
<a href="#" class="navbar-brand d-flex align-items-center"> <a href="#" class="navbar-brand d-flex align-items-center">
<strong>DAA Example</strong> <strong>DAA Example</strong>
</a> </a>
<button id="mascotas" class="btn btn-white">Mascotas</button>
<button id="personas" class="btn btn-white">Personas</button>
<button id="logout" class="btn btn-dark">Cerrar sesión</button> <button id="logout" class="btn btn-dark">Cerrar sesión</button>
</div> </div>
</div> </div>
...@@ -22,7 +24,7 @@ ...@@ -22,7 +24,7 @@
<div class="container"> <div class="container">
<div id="people-container"> <div id="people-container">
<h1 class="display-5 mt-3 mb-3">Personas</h1>
</div> </div>
</div> </div>
...@@ -30,6 +32,8 @@ ...@@ -30,6 +32,8 @@
src="http://code.jquery.com/jquery-2.2.4.min.js"></script> src="http://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="js/dao/people.js"></script> <script type="text/javascript" src="js/dao/people.js"></script>
<script type="text/javascript" src="js/view/people.js"></script> <script type="text/javascript" src="js/view/people.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" src="js/login.js"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready( $(document).ready(
...@@ -39,12 +43,23 @@ ...@@ -39,12 +43,23 @@
doLogout(); doLogout();
}); });
var view = new PeopleView(new PeopleDAO(), $('#mascotas').click(function(event) {
'people-container', 'people-container' document.getElementById("people-container").innerHTML = "<h1 class=display-5 mt-3 mb-3>Mascotas</h1>";
);
var view = new PetView(new PetDAO(),
'people-container', 'people-container','all');
view.init(); view.init();
}); });
$('#personas').click(function(event) {
document.getElementById("people-container").innerHTML = "<h1 class=display-5 mt-3 mb-3>Personas</h1>";
var view = new PeopleView(new PeopleDAO(),
'people-container', 'people-container');
view.init();
});
});
</script> </script>
</body> </body>
</html> </html>
\ No newline at end of file
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 PetDataset {
private PetDataset() {}
public static Pet[] pets() {
return new Pet[] {
new Pet(1, "Trotsky", "Perro",1),
new Pet(2, "Cato", "Gato",2),
new Pet(3, "Hiroshi", "Conejo",1),
new Pet(4, "Jael", "Perro",3)
};
}
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 int existentId() {
return 4;
}
public static int nonExistentId() {
return 1234;
}
public static Pet existentPet() {
return pet(existentId());
}
public static Pet nonExistentPet() {
return new Pet(nonExistentId(), "Lolo", "Vaca",4);
}
public static String newName() {
return "Lucky";
}
public static String newType() {
return "Anaconda";
}
public static int newPeopleID() {
return 5;
}
public static Pet newPet() {
return new Pet(pets().length + 1, newName(), newType(),newPeopleID());
}
}
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 PetUnitTest {
@Test
public void testPetIntStringString() {
final int id = 1;
final String name = "Casper";
final String type = "Perro";
final int peopleID = 1;
final Pet pet = new Pet(id, name, type,peopleID);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getType(), is(equalTo(type)));
assertThat(pet.getPeopleID(), is(equalTo(peopleID)));
}
@Test(expected = NullPointerException.class)
public void testPetIntStringStringNullName() {
new Pet(1, null, "Perro",1);
}
@Test(expected = NullPointerException.class)
public void testPersonIntStringStringNullType() {
new Pet(1, "Casper",null,1);
}
/* public void testPersonIntStringStringNullPeopleID() {
new Pet(1, "Casper","Type",null);
}*/
@Test
public void testSetName() {
final int id = 1;
final String type = "Perro";
final int peopleID = 1;
final Pet pet = new Pet(id, "Casper", type,peopleID);
pet.setName("Juan");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo("Juan")));
assertThat(pet.getType(), is(equalTo(type)));
assertThat(pet.getPeopleID(), is(equalTo(peopleID)));
}
@Test(expected = NullPointerException.class)
public void testSetNullName() {
final Pet pet = new Pet(1, "Casper", "Perro",1);
pet.setName(null);
}
@Test
public void testSetType() {
final int id = 1;
final String name = "Casper";
final int peopleID = 1;
final Pet pet = new Pet(id,name,"Perro",peopleID);
pet.setType("Gato");
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getType(), is(equalTo("Gato")));
assertThat(pet.getPeopleID(), is(equalTo(peopleID)));
}
@Test(expected = NullPointerException.class)
public void testSetNullType() {
final Pet pet = new Pet(1, "Casper", "Perro",1);
pet.setType(null);
}
@Test
public void testSetPeopleID() {
final int id = 1;
final String name = "Casper";
final String type = "Gato";
final Pet pet = new Pet(id,name,type,1);
pet.setPeopleID(2);
assertThat(pet.getId(), is(equalTo(id)));
assertThat(pet.getName(), is(equalTo(name)));
assertThat(pet.getType(), is(equalTo(type)));
assertThat(pet.getPeopleID(), is(equalTo(2)));
}
@Test
public void testEqualsObject() {
final Pet petA = new Pet(1, "Name A", "Type A",1);
final Pet petB = new Pet(1, "Name B", "Type B",1);
assertTrue(petA.equals(petB));
}
@Test
public void testEqualsHashcode() {
EqualsVerifier.forClass(Pet.class)
.withIgnoredFields("name", "type","peopleID")
.suppress(Warning.STRICT_INHERITANCE)
.suppress(Warning.NONFINAL_FIELDS)
.verify();
}
}
...@@ -31,7 +31,7 @@ import es.uvigo.esei.daa.entities.User; ...@@ -31,7 +31,7 @@ import es.uvigo.esei.daa.entities.User;
@Priority(Priorities.AUTHENTICATION) @Priority(Priorities.AUTHENTICATION)
public class AuthorizationFilter implements ContainerRequestFilter { public class AuthorizationFilter implements ContainerRequestFilter {
// Add here the list of REST paths that an administrator can access. // Add here the list of REST paths that an administrator can access.
private final static List<String> ADMIN_PATHS = Arrays.asList("people"); private final static List<String> ADMIN_PATHS = Arrays.asList("people","pets");
private final UsersDAO dao; private final UsersDAO dao;
......
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("name", Pet::getName, actual)
&& checkAttribute("surname", Pet::getType, actual)
&& checkAttribute("peopleID", Pet::getPeopleID, actual);
}
}
/**
* Factory method that creates a new {@link IsEqualToEntity} matcher with
* the provided {@link Person} as the expected value.
*
* @param person the expected person.
* @return a new {@link IsEqualToEntity} matcher with the provided
* {@link Person} 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 IsEqualToPerson} matchers, each one using an {@link Person} of the
* provided ones as the expected value.
*
* @param persons the persons to be used as the expected values.
* @return a new {@link Matcher} that includes several
* {@link IsEqualToPerson} matchers, each one using an {@link Person} 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.PetDataset.existentId;
import static es.uvigo.esei.daa.dataset.PetDataset.existentPet;
import static es.uvigo.esei.daa.dataset.PetDataset.newName;
import static es.uvigo.esei.daa.dataset.PetDataset.newPet;
import static es.uvigo.esei.daa.dataset.PetDataset.newType;
import static es.uvigo.esei.daa.dataset.PetDataset.newPeopleID;
import static es.uvigo.esei.daa.dataset.PetDataset.nonExistentId;
import static es.uvigo.esei.daa.dataset.PetDataset.pets;
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.IsEqualToPet.containsPetsInAnyOrder;
import static es.uvigo.esei.daa.matchers.IsEqualToPet.equalsToPet;
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 java.io.IOException;
import java.util.List;
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.Test;
import org.junit.runner.RunWith;
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.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 PetResourceTest 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 testList() 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 testListUnauthorized() throws IOException {
final Response response = target("pets").request()
.header("Authorization", "Basic " + userToken(normalLogin()))
.get();
assertThat(response, hasUnauthorized());
}
@Test
public void testGet() 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 testGetUnauthorized() throws IOException {
final Response response = target("pets/" + existentId()).request()
.header("Authorization", "Basic " + userToken(normalLogin()))
.get();
assertThat(response, hasUnauthorized());
}
@Test
public void testGetInvalidId() throws IOException {
final Response response = target("pets/" + nonExistentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.get();
assertThat(response, hasBadRequestStatus());
}
@Test
@ExpectedDatabase("/datasets/dataset-add.xml")
public void testAdd() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("type", newType());
form.param("peopleID", String.valueOf(newPeopleID()));
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 testAddUnauthorized() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("type", newType());
form.param("peopleID", String.valueOf(newPeopleID()));
final Response response = target("pets").request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(normalLogin()))
.post(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasUnauthorized());
}
@Test
public void testAddMissingName() throws IOException {
final Form form = new Form();
form.param("type", newType());
form.param("peopleID", String.valueOf(newPeopleID()));
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 testAddMissingType() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("peopleID", String.valueOf(newPeopleID()));
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 testAddMissingPeopleID() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("type", newType());
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
@ExpectedDatabase("/datasets/dataset-modify.xml")
public void testModify() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("type", newType());
form.param("peopleID", String.valueOf(newPeopleID()));
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());
final Pet modifiedPet = response.readEntity(Pet.class);
final Pet pet = existentPet();
pet.setName(newName());
pet.setType(newType());
pet.setPeopleID(newPeopleID());
assertThat(modifiedPet, is(equalsToPet(pet)));
}
@Test
public void testModifyUnauthorized() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("type", newType());
form.param("peopleID", String.valueOf(newPeopleID()));
final Response response = target("pets/" + existentId()).request(MediaType.APPLICATION_JSON_TYPE)
.header("Authorization", "Basic " + userToken(normalLogin()))
.put(entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
assertThat(response, hasUnauthorized());
}
@Test
public void testModifyName() throws IOException {
final Form form = new Form();
form.param("name", newName());
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 testModifyType() throws IOException {
final Form form = new Form();
form.param("type", newType());
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 testModifyPeopleID() throws IOException {
final Form form = new Form();
form.param("peopleID", String.valueOf(newPeopleID()));
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 testModifyInvalidId() throws IOException {
final Form form = new Form();
form.param("name", newName());
form.param("type", newType());
form.param("peopleID", String.valueOf(newPeopleID()));
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-delete.xml")
public void testDelete() 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 testDeleteUnauthorized() throws IOException {
final Response response = target("pets/" + existentId()).request()
.header("Authorization", "Basic " + userToken(normalLogin()))
.delete();
assertThat(response, hasUnauthorized());
}
@Test
public void testDeleteInvalidId() throws IOException {
final Response response = target("pets/" + nonExistentId()).request()
.header("Authorization", "Basic " + userToken(adminLogin()))
.delete();
assertThat(response, hasBadRequestStatus());
}
}
...@@ -5,10 +5,12 @@ import org.junit.runners.Suite; ...@@ -5,10 +5,12 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
import es.uvigo.esei.daa.rest.PeopleResourceTest; import es.uvigo.esei.daa.rest.PeopleResourceTest;
import es.uvigo.esei.daa.rest.PetResourceTest;
import es.uvigo.esei.daa.rest.UsersResourceTest; import es.uvigo.esei.daa.rest.UsersResourceTest;
@SuiteClasses({ @SuiteClasses({
PeopleResourceTest.class, PeopleResourceTest.class,
PetResourceTest.class,
UsersResourceTest.class UsersResourceTest.class
}) })
@RunWith(Suite.class) @RunWith(Suite.class)
......
...@@ -5,9 +5,12 @@ import org.junit.runners.Suite; ...@@ -5,9 +5,12 @@ import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses; import org.junit.runners.Suite.SuiteClasses;
import es.uvigo.esei.daa.entities.PersonUnitTest; import es.uvigo.esei.daa.entities.PersonUnitTest;
import es.uvigo.esei.daa.entities.PetUnitTest;
@SuiteClasses({ @SuiteClasses({
PersonUnitTest.class PersonUnitTest.class,
PetUnitTest.class
}) })
@RunWith(Suite.class) @RunWith(Suite.class)
public class UnitTestSuite { public class UnitTestSuite {
......
...@@ -16,4 +16,10 @@ ...@@ -16,4 +16,10 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/> <users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" /> <users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" name="Trotsky" type="Perro" peopleID="1"/>
<pets id="2" name="Cato" type="Gato" peopleID="2"/>
<pets id="3" name="Hiroshi" type="Conejo" peopleID="1"/>
<pets id="4" name="Jael" type="Perro" peopleID="3"/>
<pets id="5" name="Lucky" type="Anaconda" peopleID="3"/>
</dataset> </dataset>
\ No newline at end of file
...@@ -14,4 +14,8 @@ ...@@ -14,4 +14,8 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/> <users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" /> <users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" name="Trotsky" type="Perro" peopleID="1"/>
<pets id="2" name="Cato" type="Gato" peopleID="2"/>
<pets id="3" name="Hiroshi" type="Conejo" peopleID="1"/>
</dataset> </dataset>
\ No newline at end of file
...@@ -15,4 +15,9 @@ ...@@ -15,4 +15,9 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/> <users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" /> <users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" name="Trotsky" type="Perro" peopleID="1"/>
<pets id="2" name="Cato" type="Gato" peopleID="2"/>
<pets id="3" name="Hiroshi" type="Conejo" peopleID="1"/>
<pets id="4" name="Lucky" type="Anaconda" peopleID="5"/>
</dataset> </dataset>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT dataset (people*, users*)> <!ELEMENT dataset (people*, users*,pets*)>
<!ELEMENT people EMPTY> <!ELEMENT people EMPTY>
<!ELEMENT users EMPTY> <!ELEMENT users EMPTY>
<!ELEMENT pets EMPTY>
<!ATTLIST people <!ATTLIST people
id CDATA #IMPLIED id CDATA #IMPLIED
name CDATA #IMPLIED name CDATA #IMPLIED
...@@ -12,3 +13,9 @@ ...@@ -12,3 +13,9 @@
password CDATA #IMPLIED password CDATA #IMPLIED
role CDATA #IMPLIED role CDATA #IMPLIED
> >
<!ATTLIST pets
id CDATA #IMPLIED
name CDATA #IMPLIED
type CDATA #IMPLIED
peopleID CDATA #IMPLIED
>
...@@ -15,4 +15,9 @@ ...@@ -15,4 +15,9 @@
<users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/> <users login="admin" password="713bfda78870bf9d1b261f565286f85e97ee614efe5f0faf7c34e7ca4f65baca" role="ADMIN"/>
<users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" /> <users login="normal" password="7bf24d6ca2242430343ab7e3efb89559a47784eea1123be989c1b2fb2ef66e83" role="USER" />
<pets id="1" name="Trotsky" type="Perro" peopleID="1" />
<pets id="2" name="Cato" type="Gato" peopleID="2" />
<pets id="3" name="Hiroshi" type="Conejo" peopleID="1" />
<pets id="4" name="Jael" type="Perro" peopleID="3" />
</dataset> </dataset>
\ No newline at end of file
DROP TABLE People IF EXISTS; DROP TABLE People IF EXISTS;
DROP TABLE Users IF EXISTS; DROP TABLE Users IF EXISTS;
DROP TABLE Pets IF EXISTS;
...@@ -11,3 +11,11 @@ CREATE TABLE users ( ...@@ -11,3 +11,11 @@ CREATE TABLE users (
role VARCHAR(5) NOT NULL, role VARCHAR(5) NOT NULL,
PRIMARY KEY (login) PRIMARY KEY (login)
); );
CREATE TABLE pets(
id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL,
name VARCHAR(50) NOT NULL,
type VARCHAR(100) NOT NULL,
peopleID INTEGER NOT NULL,
PRIMARY KEY (id)
);
\ 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