Commit d2d3a98b authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Created SQL and DAO in order to use Postgres ltree extension

parent 417a88f5
FROM library/postgres:11
COPY ../gms/src/main/resources/sql/init.sql /docker-entrypoint-initdb.d/
......@@ -63,6 +63,12 @@
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.zonky.test</groupId>
<artifactId>embedded-database-spring-test</artifactId>
<version>1.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......
package it.inaf.ia2.gms.persistence;
import it.inaf.ia2.gms.persistence.model.NewGroup;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class GroupsDAO {
private final JdbcTemplate jdbcTemplate;
@Autowired
public GroupsDAO(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
public NewGroup createGroup(NewGroup group) {
String sql = "INSERT INTO gms_group (id, name, path) VALUES (?, ?, ?)";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, group.getId());
ps.setString(2, group.getName());
ps.setObject(3, group.getPath(), Types.OTHER);
return ps;
});
return group;
}
public void deleteGroupById(String groupId) {
String sql = "DELETE FROM gms_group WHERE id = ?";
jdbcTemplate.update(sql, groupId);
}
public List<NewGroup> listSubGroups(String path) {
String sql = "SELECT id, name, path from gms_group WHERE path ~ ? ORDER BY name";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, getSubGroupsPath(path), Types.OTHER);
return ps;
}, resultSet -> {
List<NewGroup> groups = new ArrayList<>();
while (resultSet.next()) {
NewGroup group = new NewGroup();
group.setId(resultSet.getString("id"));
group.setName(resultSet.getString("name"));
group.setPath(resultSet.getString("path"));
groups.add(group);
}
return groups;
});
}
private String getSubGroupsPath(String path) {
if (!path.isEmpty()) {
path += ".";
}
path += "*{1}";
return path;
}
public Map<String, Boolean> getHasChildrenMap(Set<String> groupIds) {
String sql = "SELECT g.id, COUNT(s.*) > 0 AS has_children \n"
+ "FROM gms_group g\n"
+ "LEFT JOIN gms_group s ON s.path <@ g.path AND s.path <> g.path\n"
+ "WHERE g.id IN("
+ String.join(",", groupIds.stream().map(g -> "?").collect(Collectors.toList()))
+ ") GROUP BY g.id";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
int i = 0;
for (String groupId : groupIds) {
ps.setString(++i, groupId);
}
return ps;
}, resultSet -> {
Map<String, Boolean> map = new HashMap<>();
while (resultSet.next()) {
map.put(resultSet.getString("id"), resultSet.getBoolean("has_children"));
}
return map;
});
}
}
package it.inaf.ia2.gms.persistence;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.model.UserPermission;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
@Component
public class PermissionsDAO {
private final JdbcTemplate jdbcTemplate;
@Autowired
public PermissionsDAO(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
public UserPermission createPermission(UserPermission userPermission) {
String sql = "INSERT INTO gms_permission(group_id, user_id, permission) VALUES(?, ?, ?)";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userPermission.getGroupId());
ps.setString(2, userPermission.getUserId());
ps.setObject(3, userPermission.getPermission().toString(), Types.OTHER);
return ps;
});
return userPermission;
}
public List<UserPermission> findUserPermissions(String userId) {
String sql = "SELECT group_id, permission FROM gms_permission WHERE user_id = ?";
return jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userId);
return ps;
}, resultSet -> {
List<UserPermission> permissions = new ArrayList<>();
while (resultSet.next()) {
UserPermission permission = new UserPermission();
permission.setGroupId(resultSet.getString("group_id"));
permission.setUserId(userId);
permission.setPermission(Permission.valueOf(resultSet.getString("permission")));
permissions.add(permission);
}
return permissions;
});
}
public void deletePermission(UserPermission userPermission) {
String sql = "DELETE FROM gms_permission WHERE group_id = ? AND user_id = ? AND permission = ?";
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, userPermission.getGroupId());
ps.setString(2, userPermission.getUserId());
ps.setObject(3, userPermission.getPermission().toString(), Types.OTHER);
return ps;
});
}
}
package it.inaf.ia2.gms.persistence.model;
import it.inaf.ia2.gms.model.Permission;
public class UserPermission {
private String userId;
private String groupId;
private Permission permission;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public Permission getPermission() {
return permission;
}
public void setPermission(Permission permission) {
this.permission = permission;
}
}
CREATE EXTENSION IF NOT EXISTS ltree;
CREATE TABLE gms_group (
id varchar NOT NULL,
name text NOT NULL,
path ltree NOT NULL,
primary key(id)
);
CREATE INDEX group_path_gist_idx ON gms_group USING GIST(path);
CREATE INDEX group_path_idx ON gms_group USING btree(path);
CREATE INDEX group_name_idx ON gms_group USING btree(name);
CREATE TABLE gms_membership (
group_id varchar NOT NULL,
user_id varchar NOT NULL,
primary key (group_id, user_id),
foreign key (group_id) references gms_group(id)
);
CREATE TYPE permission_type AS ENUM ('VIEW_MEMBERS', 'MANAGE_MEMBERS', 'ADMIN');
CREATE TABLE gms_permission (
group_id varchar NOT NULL,
user_id varchar NOT NULL,
permission permission_type NOT NULL,
primary key (group_id, user_id, permission),
foreign key (group_id) references gms_group(id)
);
package it.inaf.ia2.gms.persistence;
import com.google.common.collect.ImmutableSet;
import io.zonky.test.db.AutoConfigureEmbeddedDatabase;
import it.inaf.ia2.gms.persistence.model.NewGroup;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.sql.DataSource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@AutoConfigureEmbeddedDatabase(beanName = "dataSource")
public class GroupsDAOTest {
@Autowired
private DataSource dataSource;
private GroupsDAO dao;
@Before
public void setUp() {
dao = new GroupsDAO(dataSource);
}
@Test
@Sql("/sql/init.sql")
public void testAll() {
// Create groups
NewGroup root = new NewGroup();
root.setId("ROOT");
root.setName("ROOT");
root.setPath("");
dao.createGroup(root);
NewGroup lbt = new NewGroup();
lbt.setId(getNewGroupId());
lbt.setName("LBT");
lbt.setPath(lbt.getId());
dao.createGroup(lbt);
NewGroup tng = new NewGroup();
tng.setId(getNewGroupId());
tng.setName("TNG");
tng.setPath(tng.getId());
dao.createGroup(tng);
NewGroup lbtInaf = new NewGroup();
lbtInaf.setId(getNewGroupId());
lbtInaf.setName("INAF");
lbtInaf.setPath(lbt.getId() + "." + lbtInaf.getId());
dao.createGroup(lbtInaf);
// Sub list
List<NewGroup> groups = dao.listSubGroups("");
assertEquals(2, groups.size());
assertEquals("LBT", groups.get(0).getName());
assertEquals("TNG", groups.get(1).getName());
groups = dao.listSubGroups(lbt.getId());
assertEquals(1, groups.size());
assertEquals("INAF", groups.get(0).getName());
// Children map
Map<String, Boolean> childrenMap = dao.getHasChildrenMap(ImmutableSet.of(root.getId()));
assertEquals(1, childrenMap.size());
assertTrue(childrenMap.get(root.getId()));
childrenMap = dao.getHasChildrenMap(ImmutableSet.of(lbt.getId(), tng.getId()));
assertEquals(2, childrenMap.size());
assertTrue(childrenMap.get(lbt.getId()));
assertFalse(childrenMap.get(tng.getId()));
// Delete
dao.deleteGroupById(lbtInaf.getId());
groups = dao.listSubGroups(lbt.getId());
assertTrue(groups.isEmpty());
}
private String getNewGroupId() {
return UUID.randomUUID().toString().replaceAll("-", "");
}
}
package it.inaf.ia2.gms.persistence;
import io.zonky.test.db.AutoConfigureEmbeddedDatabase;
import it.inaf.ia2.gms.model.Permission;
import it.inaf.ia2.gms.persistence.model.UserPermission;
import it.inaf.ia2.gms.persistence.model.NewGroup;
import java.util.List;
import javax.sql.DataSource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.jdbc.Sql;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@AutoConfigureEmbeddedDatabase(beanName = "dataSource")
public class PermissionsDAOTest {
@Autowired
private DataSource dataSource;
private GroupsDAO groupsDAO;
private PermissionsDAO permissionsDAO;
@Before
public void setUp() {
groupsDAO = new GroupsDAO(dataSource);
permissionsDAO = new PermissionsDAO(dataSource);
}
@Test
@Sql("/sql/init.sql")
public void testAll() {
NewGroup root = new NewGroup();
root.setId("ROOT");
root.setName("ROOT");
root.setPath("");
groupsDAO.createGroup(root);
String userId = "user_id";
UserPermission permission = new UserPermission();
permission.setGroupId(root.getId());
permission.setUserId(userId);
permission.setPermission(Permission.ADMIN);
permissionsDAO.createPermission(permission);
List<UserPermission> permissions = permissionsDAO.findUserPermissions(userId);
assertEquals(1, permissions.size());
assertEquals(Permission.ADMIN, permissions.get(0).getPermission());
assertEquals(userId, permissions.get(0).getUserId());
permissionsDAO.deletePermission(permission);
permissions = permissionsDAO.findUserPermissions(userId);
assertTrue(permissions.isEmpty());
}
}
Supports Markdown
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