1
0

introduce-separate-database-schema-hs-office-and-amend-generators (#105)

Co-authored-by: Michael Hoennig <michael@hoennig.de>
Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/105
Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
Michael Hoennig
2024-09-18 10:28:21 +02:00
parent 285e6fbeb5
commit 23b60641e3
91 changed files with 1015 additions and 1002 deletions
@@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProject;
import net.hostsharing.hsadminng.hs.booking.project.HsBookingProjectRbacEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
@@ -49,7 +49,7 @@ public class HsBookingItemRbacEntity extends HsBookingItem {
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.toRole(GLOBAL, ADMIN).grantPermission(DELETE)
.importEntityAlias("project", HsBookingProject.class, usingDefaultCase(),
.importEntityAlias("project", HsBookingProjectRbacEntity.class, usingDefaultCase(),
dependsOnColumn("projectUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
@@ -68,11 +68,11 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
}
public static RbacView rbac() {
return rbacViewFor("project", HsBookingProject.class)
return rbacViewFor("project", HsBookingProjectRbacEntity.class)
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
JOIN hs_office.debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
"""))
.withRestrictedViewOrderBy(SQL.expression("caption"))
.withUpdatableColumns("version", "caption")
@@ -86,8 +86,8 @@ public abstract class HsBookingProject implements Stringifyable, BaseEntity<HsBo
dependsOnColumn("debitorUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_relation debitorRel
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
FROM hs_office.relation debitorRel
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
WHERE debitor.uuid = ${REF}.debitorUuid
"""),
NOT_NULL)
@@ -44,7 +44,7 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
.withIdentityView(SQL.query("""
SELECT bookingProject.uuid as uuid, debitorIV.idName || '-' || base.cleanIdentifier(bookingProject.caption) as idName
FROM hs_booking_project bookingProject
JOIN hs_office_debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
JOIN hs_office.debitor_iv debitorIV ON debitorIV.uuid = bookingProject.debitorUuid
"""))
.withRestrictedViewOrderBy(SQL.expression("caption"))
.withUpdatableColumns("version", "caption")
@@ -58,8 +58,8 @@ public class HsBookingProjectRbacEntity extends HsBookingProject {
dependsOnColumn("debitorUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_relation debitorRel
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
FROM hs_office.relation debitorRel
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
WHERE debitor.uuid = ${REF}.debitorUuid
"""),
NOT_NULL)
@@ -4,7 +4,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItem;
import net.hostsharing.hsadminng.hs.booking.item.HsBookingItemRbacEntity;
import net.hostsharing.hsadminng.hs.office.contact.HsOfficeContactRbacEntity;
import net.hostsharing.hsadminng.rbac.generator.RbacView;
import net.hostsharing.hsadminng.rbac.generator.RbacView.SQL;
@@ -47,7 +47,7 @@ public class HsHostingAssetRbacEntity extends HsHostingAsset {
.withUpdatableColumns("version", "caption", "config", "assignedToAssetUuid", "alarmContactUuid")
.toRole(GLOBAL, ADMIN).grantPermission(INSERT) // TODO.impl: Why is this necessary to insert test data?
.importEntityAlias("bookingItem", HsBookingItem.class, usingDefaultCase(),
.importEntityAlias("bookingItem", HsBookingItemRbacEntity.class, usingDefaultCase(),
dependsOnColumn("bookingItemUuid"),
directlyFetchedByDependsOnColumn(),
NULLABLE)
@@ -19,7 +19,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_bankaccount_rv")
@Table(schema = "hs_office", name = "bankaccount_rv")
@Getter
@Setter
@Builder
@@ -16,7 +16,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.Role.*;
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_office_contact_rv")
@Table(schema = "hs_office", name = "contact_rv")
@Getter
@Setter
@NoArgsConstructor
@@ -10,7 +10,7 @@ import jakarta.persistence.Entity;
import jakarta.persistence.Table;
@Entity
@Table(name = "hs_office_contact")
@Table(schema = "hs_office", name = "contact")
@Getter
@Setter
@NoArgsConstructor
@@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_coopassetstransaction_rv")
@Table(schema = "hs_office", name = "coopassetstransaction_rv")
@Getter
@Setter
@Builder
@@ -32,7 +32,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_coopsharestransaction_rv")
@Table(schema = "hs_office", name = "coopsharestransaction_rv")
@Getter
@Setter
@Builder
@@ -54,7 +54,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_debitor_rv")
@Table(schema = "hs_office", name = "debitor_rv")
@Getter
@Setter
@Builder(toBuilder = true)
@@ -87,10 +87,10 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
value = """
(
SELECT DISTINCT partner.uuid
FROM hs_office_partner_rv partner
JOIN hs_office_relation_rv dRel
FROM hs_office.partner_rv partner
JOIN hs_office.relation_rv dRel
ON dRel.uuid = debitorreluuid AND dRel.type = 'DEBITOR'
JOIN hs_office_relation_rv pRel
JOIN hs_office.relation_rv pRel
ON pRel.uuid = partner.partnerRelUuid AND pRel.type = 'PARTNER'
WHERE pRel.holderUuid = dRel.anchorUuid
)
@@ -170,14 +170,14 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
.withIdentityView(SQL.query("""
SELECT debitor.uuid AS uuid,
'D-' || (SELECT partner.partnerNumber
FROM hs_office_partner partner
JOIN hs_office_relation partnerRel
FROM hs_office.partner partner
JOIN hs_office.relation partnerRel
ON partnerRel.uuid = partner.partnerRelUUid AND partnerRel.type = 'PARTNER'
JOIN hs_office_relation debitorRel
JOIN hs_office.relation debitorRel
ON debitorRel.anchorUuid = partnerRel.holderUuid AND debitorRel.type = 'DEBITOR'
WHERE debitorRel.uuid = debitor.debitorRelUuid)
|| debitorNumberSuffix as idName
FROM hs_office_debitor AS debitor
FROM hs_office.debitor AS debitor
"""))
.withRestrictedViewOrderBy(SQL.projection("defaultPrefix"))
.withUpdatableColumns(
@@ -209,8 +209,8 @@ public class HsOfficeDebitorEntity implements BaseEntity<HsOfficeDebitorEntity>,
dependsOnColumn("debitorRelUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_relation AS partnerRel
JOIN hs_office_relation AS debitorRel
FROM hs_office.relation AS partnerRel
JOIN hs_office.relation AS debitorRel
ON debitorRel.type = 'DEBITOR' AND debitorRel.anchorUuid = partnerRel.holderUuid
WHERE partnerRel.type = 'PARTNER'
AND ${REF}.debitorRelUuid = debitorRel.uuid
@@ -56,7 +56,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_membership_rv")
@Table(schema = "hs_office", name = "membership_rv")
@Getter
@Setter
@Builder
@@ -160,8 +160,8 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
.withIdentityView(SQL.query("""
SELECT m.uuid AS uuid,
'M-' || p.partnerNumber || m.memberNumberSuffix as idName
FROM hs_office_membership AS m
JOIN hs_office_partner AS p ON p.uuid = m.partnerUuid
FROM hs_office.membership AS m
JOIN hs_office.partner AS p ON p.uuid = m.partnerUuid
"""))
.withRestrictedViewOrderBy(SQL.projection("validity"))
.withUpdatableColumns("validity", "membershipFeeBillable", "status")
@@ -170,8 +170,8 @@ public class HsOfficeMembershipEntity implements BaseEntity<HsOfficeMembershipEn
dependsOnColumn("partnerUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_partner AS partner
JOIN hs_office_relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
FROM hs_office.partner AS partner
JOIN hs_office.relation AS partnerRel ON partnerRel.uuid = partner.partnerRelUuid
WHERE partner.uuid = ${REF}.partnerUuid
"""),
NOT_NULL)
@@ -20,7 +20,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_partner_details_rv")
@Table(schema = "hs_office", name = "partner_details_rv")
@Getter
@Setter
@Builder
@@ -71,9 +71,9 @@ public class HsOfficePartnerDetailsEntity implements BaseEntity<HsOfficePartnerD
return rbacViewFor("partnerDetails", HsOfficePartnerDetailsEntity.class)
.withIdentityView(SQL.query("""
SELECT partnerDetails.uuid as uuid, partner_iv.idName as idName
FROM hs_office_partner_details AS partnerDetails
JOIN hs_office_partner partner ON partner.detailsUuid = partnerDetails.uuid
JOIN hs_office_partner_iv partner_iv ON partner_iv.uuid = partner.uuid
FROM hs_office.partner_details AS partnerDetails
JOIN hs_office.partner partner ON partner.detailsUuid = partnerDetails.uuid
JOIN hs_office.partner_iv partner_iv ON partner_iv.uuid = partner.uuid
"""))
.withRestrictedViewOrderBy(SQL.expression("uuid"))
.withUpdatableColumns(
@@ -36,7 +36,7 @@ import static java.util.Optional.ofNullable;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_partner_rv")
@Table(schema = "hs_office", name = "partner_rv")
@Getter
@Setter
@Builder
@@ -22,7 +22,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_person_rv")
@Table(schema = "hs_office", name = "person_rv")
@Getter
@Setter
@Builder
@@ -34,7 +34,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.SQL.directlyFetc
import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
@Entity
@Table(name = "hs_office_relation_rv")
@Table(schema = "hs_office", name = "relation_rv")
@NoArgsConstructor
@Getter
@Setter
@@ -45,12 +45,12 @@ public class HsOfficeRelationRbacEntity extends HsOfficeRelation {
public static RbacView rbac() {
return rbacViewFor("relation", HsOfficeRelationRbacEntity.class)
.withIdentityView(SQL.projection("""
(select idName from hs_office_person_iv p where p.uuid = anchorUuid)
(select idName from hs_office.person_iv p where p.uuid = anchorUuid)
|| '-with-' || target.type || '-'
|| (select idName from hs_office_person_iv p where p.uuid = holderUuid)
|| (select idName from hs_office.person_iv p where p.uuid = holderUuid)
"""))
.withRestrictedViewOrderBy(SQL.expression(
"(select idName from hs_office_person_iv p where p.uuid = target.holderUuid)"))
"(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)"))
.withUpdatableColumns("contactUuid")
.importEntityAlias("anchorPerson", HsOfficePersonEntity.class, usingDefaultCase(),
dependsOnColumn("anchorUuid"),
@@ -17,13 +17,13 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
}
@Query(value = """
SELECT p.* FROM hs_office_relation_rv AS p
SELECT p.* FROM hs_office.relation_rv AS p
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
""", nativeQuery = true)
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
@Query(value = """
SELECT p.* FROM hs_office_relation_rv AS p
SELECT p.* FROM hs_office.relation_rv AS p
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
""", nativeQuery = true)
@@ -11,7 +11,7 @@ import jakarta.persistence.Table;
@Entity
@Table(name = "hs_office_relation")
@Table(schema = "hs_office", name = "relation")
@NoArgsConstructor
@Getter
@Setter
@@ -17,13 +17,13 @@ public interface HsOfficeRelationRealRepository extends Repository<HsOfficeRelat
}
@Query(value = """
SELECT p.* FROM hs_office_relation AS p
SELECT p.* FROM hs_office.relation AS p
WHERE p.anchorUuid = :personUuid OR p.holderUuid = :personUuid
""", nativeQuery = true)
List<HsOfficeRelationRealEntity> findRelationRelatedToPersonUuid(@NotNull UUID personUuid);
@Query(value = """
SELECT p.* FROM hs_office_relation AS p
SELECT p.* FROM hs_office.relation AS p
WHERE (:relationType IS NULL OR p.type = cast(:relationType AS HsOfficeRelationType))
AND ( p.anchorUuid = :personUuid OR p.holderUuid = :personUuid)
""", nativeQuery = true)
@@ -33,7 +33,7 @@ import static net.hostsharing.hsadminng.rbac.generator.RbacView.rbacViewFor;
import static net.hostsharing.hsadminng.stringify.Stringify.stringify;
@Entity
@Table(name = "hs_office_sepamandate_rv")
@Table(schema = "hs_office", name = "sepamandate_rv")
@Getter
@Setter
@Builder
@@ -104,8 +104,8 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOf
return rbacViewFor("sepaMandate", HsOfficeSepaMandateEntity.class)
.withIdentityView(query("""
select sm.uuid as uuid, ba.iban || '-' || sm.validity as idName
from hs_office_sepamandate sm
join hs_office_bankaccount ba on ba.uuid = sm.bankAccountUuid
from hs_office.sepamandate sm
join hs_office.bankaccount ba on ba.uuid = sm.bankAccountUuid
"""))
.withRestrictedViewOrderBy(expression("validity"))
.withUpdatableColumns("reference", "agreement", "validity")
@@ -114,8 +114,8 @@ public class HsOfficeSepaMandateEntity implements Stringifyable, BaseEntity<HsOf
dependsOnColumn("debitorUuid"),
fetchedBySql("""
SELECT ${columns}
FROM hs_office_relation debitorRel
JOIN hs_office_debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
FROM hs_office.relation debitorRel
JOIN hs_office.debitor debitor ON debitor.debitorRelUuid = debitorRel.uuid
WHERE debitor.uuid = ${REF}.debitorUuid
"""),
NOT_NULL)
@@ -213,7 +213,7 @@ public class InsertTriggerGenerator {
if (g.getSuperRoleDef().isGlobal(GUEST)) {
plPgSql.writeLn(
"""
-- check INSERT INSERT permission for rbac.global anyone
-- check INSERT permission for rbac.global anyone
if ${caseCondition}true then
return NEW;
end if;
@@ -222,7 +222,7 @@ public class InsertTriggerGenerator {
} else if (g.getSuperRoleDef().isGlobal(ADMIN)) {
plPgSql.writeLn(
"""
-- check INSERT INSERT if rbac.global ADMIN
-- check INSERT permission if rbac.global ADMIN
if ${caseCondition}rbac.isGlobalAdmin() then
return NEW;
end if;
@@ -12,7 +12,6 @@ import jakarta.persistence.Version;
import jakarta.validation.constraints.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Consumer;
@@ -983,10 +982,10 @@ public class RbacView {
String getRawTableShortName() {
// TODO.impl: some combined function and trigger names are too long
// maybe we should shorten the table name e.g. hs_office_coopsharestransaction -> hsof.coopsharetx
// maybe we should shorten the table name e.g. hs_office.coopsharestransaction -> hsof.coopsharetx
// this is just a workaround:
return getRawTableName()
.replace("hs_office_", "hsof_")
.replace("hs_office.", "hsof.")
.replace("hs_booking_", "hsbk_")
.replace("hs_hosting_", "hsho_")
.replace("coopsharestransaction", "coopsharetx")
@@ -1274,13 +1273,14 @@ public class RbacView {
public static Set<Class<? extends BaseEntity>> findRbacEntityClasses(String packageName) {
final var reflections = new Reflections(packageName, TypeAnnotationsScanner.class);
return reflections.getTypesAnnotatedWith(Entity.class).stream()
.filter(c -> stream(c.getInterfaces()).anyMatch(i -> i== BaseEntity.class))
final Set<Class<? extends BaseEntity>> rbacEntityClasses = reflections.getTypesAnnotatedWith(Entity.class).stream()
.filter(BaseEntity.class::isAssignableFrom)
.filter(c -> stream(c.getDeclaredMethods())
.anyMatch(m -> m.getName().equals("rbac") && Modifier.isStatic(m.getModifiers()))
.anyMatch(m -> m.getName().equals("rbac") && isStatic(m.getModifiers()))
)
.map(RbacView::castToSubclassOfBaseEntity)
.collect(Collectors.toSet());
return rbacEntityClasses;
}
@SuppressWarnings("unchecked")
@@ -29,7 +29,7 @@ class RolesGrantsAndPermissionsGenerator {
private final String liquibaseTagPrefix;
private final String simpleEntityName;
private final String simpleEntityVarName;
private final String rawTableName;
private final String qualifiedRawTableName;
RolesGrantsAndPermissionsGenerator(final RbacView rbacDef, final String liquibaseTagPrefix) {
this.rbacDef = rbacDef;
@@ -40,7 +40,7 @@ class RolesGrantsAndPermissionsGenerator {
simpleEntityVarName = rbacDef.getRootEntityAlias().simpleName();
simpleEntityName = capitalize(simpleEntityVarName);
rawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
qualifiedRawTableName = rbacDef.getRootEntityAlias().getRawTableNameWithSchema();
}
void generateTo(final StringWriter plPgSql) {
@@ -66,13 +66,12 @@ class RolesGrantsAndPermissionsGenerator {
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
*/
create or replace procedure buildRbacSystemFor${simpleEntityName}(
NEW ${rawTableName}
create or replace procedure ${rawTableQualifiedName}_build_rbac_system(
NEW ${rawTableQualifiedName}
)
language plpgsql as $$
"""
.replace("${simpleEntityName}", simpleEntityName)
.replace("${rawTableName}", rawTableName));
.replace("${rawTableQualifiedName}", qualifiedRawTableName));
plPgSql.writeLn("declare");
plPgSql.indented(() -> {
@@ -106,21 +105,21 @@ class RolesGrantsAndPermissionsGenerator {
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
*/
create or replace procedure updateRbacRulesFor${simpleEntityName}(
OLD ${rawTableName},
NEW ${rawTableName}
create or replace procedure ${rawTableQualifiedName}_update_rbac_system(
OLD ${rawTableQualifiedName},
NEW ${rawTableQualifiedName}
)
language plpgsql as $$
begin
if ${updateConditions} then
delete from rbac.grants g where g.grantedbytriggerof = OLD.uuid;
call buildRbacSystemFor${simpleEntityName}(NEW);
call ${rawTableQualifiedName}_build_rbac_system(NEW);
end if;
end; $$;
""",
with("simpleEntityName", simpleEntityName),
with("rawTableName", rawTableName),
with("rawTableQualifiedName", qualifiedRawTableName),
with("updateConditions", updateConditions));
}
@@ -130,16 +129,15 @@ class RolesGrantsAndPermissionsGenerator {
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
*/
create or replace procedure updateRbacRulesFor${simpleEntityName}(
OLD ${rawTableName},
NEW ${rawTableName}
create or replace procedure ${rawTableQualifiedName}_update_rbac_system(
OLD ${rawTableQualifiedName},
NEW ${rawTableQualifiedName}
)
language plpgsql as $$
declare
"""
.replace("${simpleEntityName}", simpleEntityName)
.replace("${rawTableName}", rawTableName));
""",
with("rawTableQualifiedName", qualifiedRawTableName));
plPgSql.chopEmptyLines();
plPgSql.indented(() -> {
@@ -514,25 +512,25 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.writeLn("""
/*
AFTER INSERT TRIGGER to create the role+grant structure for a new ${rawTableName} row.
AFTER INSERT TRIGGER to create the role+grant structure for a new ${rawTableQualifiedName} row.
*/
create or replace function insertTriggerFor${simpleEntityName}_tf()
create or replace function ${rawTableQualifiedName}_build_rbac_system_after_insert_tf()
returns trigger
language plpgsql
strict as $$
begin
call buildRbacSystemFor${simpleEntityName}(NEW);
call ${rawTableQualifiedName}_build_rbac_system(NEW);
return NEW;
end; $$;
create trigger insertTriggerFor${simpleEntityName}_tg
after insert on ${rawTableName}
create trigger build_rbac_system_after_insert_tg
after insert on ${rawTableQualifiedName}
for each row
execute procedure insertTriggerFor${simpleEntityName}_tf();
execute procedure ${rawTableQualifiedName}_build_rbac_system_after_insert_tf();
"""
.replace("${simpleEntityName}", simpleEntityName)
.replace("${rawTableName}", rawTableName)
.replace("${schemaPrefix}", schemaPrefix(qualifiedRawTableName))
.replace("${rawTableQualifiedName}", qualifiedRawTableName)
);
generateFooter(plPgSql);
@@ -549,30 +547,35 @@ class RolesGrantsAndPermissionsGenerator {
plPgSql.writeLn("""
/*
AFTER INSERT TRIGGER to re-wire the grant structure for a new ${rawTableName} row.
AFTER UPDATE TRIGGER to re-wire the grant structure for a new ${rawTableQualifiedName} row.
*/
create or replace function updateTriggerFor${simpleEntityName}_tf()
create or replace function ${rawTableQualifiedName}_update_rbac_system_after_update_tf()
returns trigger
language plpgsql
strict as $$
begin
call updateRbacRulesFor${simpleEntityName}(OLD, NEW);
call ${rawTableQualifiedName}_update_rbac_system(OLD, NEW);
return NEW;
end; $$;
create trigger updateTriggerFor${simpleEntityName}_tg
after update on ${rawTableName}
create trigger update_rbac_system_after_update_tg
after update on ${rawTableQualifiedName}
for each row
execute procedure updateTriggerFor${simpleEntityName}_tf();
execute procedure ${rawTableQualifiedName}_update_rbac_system_after_update_tf();
"""
.replace("${simpleEntityName}", simpleEntityName)
.replace("${rawTableName}", rawTableName)
.replace("${rawTableQualifiedName}", qualifiedRawTableName)
);
generateFooter(plPgSql);
}
private String schemaPrefix(final String qualifiedIdentifier) {
return qualifiedIdentifier.contains(".")
? qualifiedIdentifier.split("\\.")[0] + "."
: "";
}
private static void generateFooter(final StringWriter plPgSql) {
plPgSql.writeLn("--//");
plPgSql.writeLn();