Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor permission queries to joins #1067

Merged
merged 2 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,20 @@ public static JSONObject getListOfMapLayersById(final List<Integer> layerIdList,
*/
public static JSONObject getListOfMapLayers(final List<OskariLayer> layers, final User user,
final String lang, final String crs, final boolean isPublished, final boolean isSecure) {
List<Resource> resources = permissionService.findResourcesByUser(user, ResourceType.maplayer);
List<Resource> resources;
if (layers.size() < 20) {
// usually the case with loading the default app setup
resources = layers.stream()
.map(OskariLayer::getId)
.map(id -> Integer.toString(id))
.map(id -> permissionService.findResource(ResourceType.maplayer, id))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
} else {
// more than 20 layers, just get all the permissions
resources = permissionService.findResourcesByUser(user, ResourceType.maplayer);
}
return getListOfMapLayers(layers, user, lang, isSecure, crs, isPublished, new PermissionSet(resources));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import fi.nls.oskari.log.Logger;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.mybatis.MyBatisHelper;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.oskari.permissions.model.Permission;
import org.oskari.permissions.model.PermissionExternalType;
import org.oskari.permissions.model.Resource;
Expand Down Expand Up @@ -42,11 +44,18 @@ public PermissionServiceMybatisImpl(DataSource ds) {
LOG.warn("DataSource was null, all future calls will throw NPEs!");
factory = null;
} else {
factory = MyBatisHelper.initMyBatis(ds, MAPPER);
factory = initializeMyBatis(ds);
}
cache = CacheManager.getCache(PermissionServiceMybatisImpl.class.getName());
}

private SqlSessionFactory initializeMyBatis(final DataSource dataSource) {
final Configuration configuration = MyBatisHelper.getConfig(dataSource);
MyBatisHelper.addAliases(configuration, Resource.class, Permission.class);
MyBatisHelper.addMappers(configuration, MAPPER);
return new SqlSessionFactoryBuilder().build(configuration);
}

public List<Resource> findResourcesByUser(User user, ResourceType type) {
// TODO: add userId and user.getRoles() to query and remove filtering on code
List<Resource> all = findResourcesByType(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import java.util.Set;

import fi.nls.oskari.domain.map.userlayer.UserLayerData;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Many;
Expand All @@ -19,46 +20,15 @@

public interface ResourceMapper {

// TODO: Join tables in SQL and map the result -> improves performance by ~5x
@Results(id = "ResourceResult", value = {
@Result(property="id", column="id", id=true),
@Result(property="type", column="resource_type"),
@Result(property="mapping", column="resource_mapping"),
@Result(property="permissions", column="id",
javaType=List.class, many=@Many(select="findPermissionsByResourceId", fetchType= FetchType.EAGER))
})
@Select("SELECT id,"
+ "resource_type,"
+ "resource_mapping "
+ "FROM oskari_resource "
+ "WHERE id = #{id}")
Resource findById(@Param("id") int id);

@Select("SELECT EXISTS (SELECT 1 FROM oskari_resource WHERE id = #{id})")
boolean existsById(@Param("id") int id);

@ResultMap("ResourceResult")
@Select("SELECT id,"
+ "resource_type,"
+ "resource_mapping "
+ "FROM oskari_resource")
List<Resource> findAll();

@ResultMap("ResourceResult")
@Select("SELECT id,"
+ "resource_type,"
+ "resource_mapping "
+ "FROM oskari_resource "
+ "WHERE resource_type = #{type}")
List<Resource> findByType(String type);
List<Resource> findByType(@Param("type") String type);

@ResultMap("ResourceResult")
@Select("SELECT id,"
+ "resource_type,"
+ "resource_mapping "
+ "FROM oskari_resource "
+ "WHERE resource_type = #{type} "
+ "AND resource_mapping = #{mapping}")
Resource findByTypeAndMapping(@Param("type") String type, @Param("mapping") String mapping);

@Select("SELECT EXISTS (SELECT 1 FROM oskari_resource WHERE resource_type = #{type} AND resource_mapping = #{mapping})")
Expand All @@ -79,20 +49,6 @@ Set<String> findMappingsForPermission(@Param("resourceType") String resourceType
@Param("permission") String permission,
@Param("external_id") String external_id);

@Results({
@Result(property="id", column="id", id=true),
@Result(property="type", column="permission"),
@Result(property="externalType", column="external_type"),
@Result(property="externalId", column="external_id")
})
@Select("SELECT id,"
+ "external_type,"
+ "permission,"
+ "external_id "
+ "FROM oskari_resource_permission "
+ "WHERE resource_id = #{resourceId}")
List<Permission> findPermissionsByResourceId(@Param("resourceId") int resourceId);

@Insert("INSERT INTO oskari_resource (resource_type, resource_mapping) VALUES (#{type},#{mapping})")
@Options(useGeneratedKeys=true, keyColumn="id", keyProperty="id")
void insertResource(Resource resource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public String getType() {

public void setType(String type) {
this.type = type;

}

public void setType(PermissionType type) {
Expand All @@ -39,6 +38,10 @@ public void setExternalType(String externalType) {
setExternalType(PermissionExternalType.valueOf(externalType));
}

public void setExternalTypeMybatis(String externalType) {
setExternalType(PermissionExternalType.valueOf(externalType));
}

public void setExternalType(PermissionExternalType externalType) {
this.externalType = externalType;
}
Expand All @@ -55,6 +58,11 @@ public void setExternalId(String externalId) {
setExternalId(Integer.parseInt(externalId));
}

public void setExternalIdMybatis(String externalId) {
setExternalId(externalId);
}


public void setRoleId(int roleId) {
setExternalType(PermissionExternalType.ROLE);
setExternalId(roleId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ public void setMapping(String namespace, String name) {

public List<Permission> getPermissions() {
if (permissions == null) {
return Collections.emptyList();
// mybatis calls get to fill in the results to
// -> we can't use Collections.emptyList() here
permissions = new ArrayList<>();
}
return permissions;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.oskari.permissions.ResourceMapper">

<resultMap id="resourceWithPermissions" type="Resource">
<id property="id" column="id" />
<result property="type" column="resource_type" javaType="String" />
<result property="mapping" column="resource_mapping" javaType="String" />
<collection property="permissions" javaType="list" ofType="Permission">
<result property="id" column="permission_id" javaType="int"/>
<result property="type" column="permission" javaType="String" />
<result property="externalTypeMybatis" column="external_type" javaType="String"/>
<result property="externalIdMybatis" column="external_id" javaType="String" />
</collection>
</resultMap>

<select id="findAll" resultMap="resourceWithPermissions" useCache="false">
SELECT r.id, r.resource_type, r.resource_mapping, p.id as permission_id, p.external_type, p.permission, p.external_id
FROM oskari_resource r
LEFT JOIN oskari_resource_permission p
ON r.id = p.resource_id
</select>

<select id="findById" resultMap="resourceWithPermissions" useCache="false">
SELECT r.id, r.resource_type, r.resource_mapping, p.id as permission_id, p.resource_id, p.external_type, p.permission, p.external_id
FROM oskari_resource r
JOIN oskari_resource_permission p
ON r.id = p.resource_id
WHERE r.id = #{id}
</select>

<select id="findByType" resultMap="resourceWithPermissions" useCache="false">
SELECT r.id, r.resource_type, r.resource_mapping, p.id as permission_id, p.external_type, p.permission, p.external_id
FROM oskari_resource r
LEFT JOIN oskari_resource_permission p
ON r.id = p.resource_id
WHERE r.resource_type = #{type}
</select>

<select id="findByTypeAndMapping" resultMap="resourceWithPermissions" useCache="false">
SELECT r.id, r.resource_type, r.resource_mapping, p.id as permission_id, p.external_type, p.permission, p.external_id
FROM oskari_resource r
LEFT JOIN oskari_resource_permission p
ON r.id = p.resource_id
WHERE r.resource_type = #{type}
AND r.resource_mapping = #{mapping}
</select>


</mapper>
Loading