introduce-separate-database-schema-hs-office-and-amend-generators (#105)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: #105 Reviewed-by: Marc Sandlus <marc.sandlus@hostsharing.net>
This commit is contained in:
parent
285e6fbeb5
commit
23b60641e3
@ -206,14 +206,14 @@ Limit (cost=6549.08..6549.35 rows=54 width=16)
|
||||
|
||||
```SQL
|
||||
SELECT hore1_0.uuid,a1_0.uuid,a1_0.familyname,a1_0.givenname,a1_0.persontype,a1_0.salutation,a1_0.title,a1_0.tradename,a1_0.version,c1_0.uuid,c1_0.caption,c1_0.emailaddresses,c1_0.phonenumbers,c1_0.postaladdress,c1_0.version,h1_0.uuid,h1_0.familyname,h1_0.givenname,h1_0.persontype,h1_0.salutation,h1_0.title,h1_0.tradename,h1_0.version,hore1_0.mark,hore1_0.type,hore1_0.version
|
||||
FROM hs_office_relation_rv hore1_0
|
||||
LEFT JOIN hs_office_person_rv a1_0 ON a1_0.uuid=hore1_0.anchoruuid
|
||||
LEFT JOIN hs_office_contact_rv c1_0 ON c1_0.uuid=hore1_0.contactuuid
|
||||
LEFT JOIN hs_office_person_rv h1_0 ON h1_0.uuid=hore1_0.holderuuid
|
||||
FROM hs_office.relation_rv hore1_0
|
||||
LEFT JOIN hs_office.person_rv a1_0 ON a1_0.uuid=hore1_0.anchoruuid
|
||||
LEFT JOIN hs_office.contact_rv c1_0 ON c1_0.uuid=hore1_0.contactuuid
|
||||
LEFT JOIN hs_office.person_rv h1_0 ON h1_0.uuid=hore1_0.holderuuid
|
||||
WHERE hore1_0.uuid=$1
|
||||
```
|
||||
|
||||
That query on the `hs_office_relation_rv`-table joins the three references anchor-person, holder-person and contact.
|
||||
That query on the `hs_office.relation_rv`-table joins the three references anchor-person, holder-person and contact.
|
||||
|
||||
|
||||
### Total-Query-Time > Total-Import-Runtime
|
||||
@ -270,16 +270,16 @@ At this point, the import took 21mins with these statistics:
|
||||
|
||||
| query | calls | total_m | mean_ms |
|
||||
|-------|-------|---------|---------|
|
||||
| select hore1_0.uuid,a1_0.uuid,a1_0.familyname,a1_0.givenname,a1_0.persontype,a1_0.salutation,a1_0.title,a1_0.tradename,a1_0.version,c1_0.uuid,c1_0.caption,c1_0.emailaddresses,c1_0.phonenumbers,c1_0.postaladdress, c1_0.version,h1_0.uuid,h1_0.familyname,h1_0.givenname,h1_0.persontype,h1_0.salutation,h1_0.title,h1_0.tradename,h1_0.version,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office_relation_rv hore1_0 left join public.hs_office_person_rv a1_0 on a1_0.uuid=hore1_0.anchoruuid left join public.hs_office_contact_rv c1_0 on c1_0.uuid=hore1_0.contactuuid left join public.hs_office_person_rv h1_0 on h1_0.uuid=hore1_0.holderuuid where hore1_0.uuid=$1 | 517 | 11 | 1282 |
|
||||
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office_person_rv hope1_0 where hope1_0.uuid=$1 | 973 | 4 | 254 |
|
||||
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 | 973 | 4 | 253 |
|
||||
| select hore1_0.uuid,a1_0.uuid,a1_0.familyname,a1_0.givenname,a1_0.persontype,a1_0.salutation,a1_0.title,a1_0.tradename,a1_0.version,c1_0.uuid,c1_0.caption,c1_0.emailaddresses,c1_0.phonenumbers,c1_0.postaladdress, c1_0.version,h1_0.uuid,h1_0.familyname,h1_0.givenname,h1_0.persontype,h1_0.salutation,h1_0.title,h1_0.tradename,h1_0.version,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office.relation_rv hore1_0 left join public.hs_office.person_rv a1_0 on a1_0.uuid=hore1_0.anchoruuid left join public.hs_office.contact_rv c1_0 on c1_0.uuid=hore1_0.contactuuid left join public.hs_office.person_rv h1_0 on h1_0.uuid=hore1_0.holderuuid where hore1_0.uuid=$1 | 517 | 11 | 1282 |
|
||||
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office.person_rv hope1_0 where hope1_0.uuid=$1 | 973 | 4 | 254 |
|
||||
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office.contact_rv hoce1_0 where hoce1_0.uuid=$1 | 973 | 4 | 253 |
|
||||
| call rbac.grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) | 31316 | 0 | 1 |
|
||||
| call buildRbacSystemForHsHostingAsset(NEW) | 2258 | 0 | 7 |
|
||||
| select * from rbac.isGranted(array[granteeId], grantedId) | 44613 | 0 | 0 |
|
||||
| insert into public.hs_hosting_asset_rv (alarmcontactuuid,assignedtoassetuuid,bookingitemuuid,caption,config,identifier,parentassetuuid,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) | 2207 | 0 | 7 |
|
||||
| insert into hs_hosting_asset (alarmcontactuuid, version, bookingitemuuid, type, parentassetuuid, assignedtoassetuuid, config, uuid, identifier, caption) values (new.alarmcontactuuid, new. version, new. bookingitemuuid, new. type, new. parentassetuuid, new. assignedtoassetuuid, new. config, new. uuid, new. identifier, new. caption) returning * | 2207 | 0 | 7 |
|
||||
| insert into public.hs_office_relation_rv (anchoruuid,contactuuid,holderuuid,mark,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7) | 1261 | 0 | 9 |
|
||||
| insert into hs_office_relation (uuid, version, anchoruuid, holderuuid, contactuuid, type, mark) values (new.uuid, new. version, new. anchoruuid, new. holderuuid, new. contactuuid, new. type, new. mark) returning * | 1261 | 0 | 9 |
|
||||
| insert into public.hs_office.relation_rv (anchoruuid,contactuuid,holderuuid,mark,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7) | 1261 | 0 | 9 |
|
||||
| insert into hs_office.relation (uuid, version, anchoruuid, holderuuid, contactuuid, type, mark) values (new.uuid, new. version, new. anchoruuid, new. holderuuid, new. contactuuid, new. type, new. mark) returning * | 1261 | 0 | 9 |
|
||||
| call buildRbacSystemForHsOfficeRelation(NEW) | 1276 | 0 | 8 |
|
||||
| with recursive grants as ( select descendantUuid, ascendantUuid from RbacGrants where descendantUuid = grantedId union all select ""grant"".descendantUuid, ""grant"".ascendantUuid from RbacGrants ""grant"" inner join grants recur on recur.ascendantUuid = ""grant"".descendantUuid ) select exists ( select $3 from grants where ascendantUuid = any(granteeIds) ) or grantedId = any(granteeIds) | 47540 | 0 | 0 |
|
||||
| insert into RbacGrants (grantedByTriggerOf, ascendantuuid, descendantUuid, assumed) values (currentTriggerObjectUuid(), superRoleId, subRoleId, doAssume) on conflict do nothing" | 40472 | 0 | 0 |
|
||||
@ -294,17 +294,17 @@ We changed these mappings from `EAGER` (default) to `LAZY` to `@ManyToOne(fetch
|
||||
:::small
|
||||
| query | calls | total (min) | mean (ms) |
|
||||
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------|-------------|----------|
|
||||
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office_person_rv hope1_0 where hope1_0.uuid=$1 | 1015 | 4 | 238 |
|
||||
| select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office_relation_rv hore1_0 where hore1_0.uuid=$1 | 517 | 4 | 439 |
|
||||
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 | 497 | 2 | 213 |
|
||||
| select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office.person_rv hope1_0 where hope1_0.uuid=$1 | 1015 | 4 | 238 |
|
||||
| select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office.relation_rv hore1_0 where hore1_0.uuid=$1 | 517 | 4 | 439 |
|
||||
| select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office.contact_rv hoce1_0 where hoce1_0.uuid=$1 | 497 | 2 | 213 |
|
||||
| call rbac.grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) | 31316 | 0 | 1 |
|
||||
| select * from rbac.isGranted(array[granteeId], grantedId) | 44613 | 0 | 0 |
|
||||
| call buildRbacSystemForHsHostingAsset(NEW) | 2258 | 0 | 7 |
|
||||
| insert into public.hs_hosting_asset_rv (alarmcontactuuid,assignedtoassetuuid,bookingitemuuid,caption,config,identifier,parentassetuuid,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10) | 2207 | 0 | 7 |
|
||||
| insert into hs_hosting_asset (alarmcontactuuid, version, bookingitemuuid, type, parentassetuuid, assignedtoassetuuid, config, uuid, identifier, caption) values (new.alarmcontactuuid, new. version, new. bookingitemuuid, new. type, new. parentassetuuid, new. assignedtoassetuuid, new. config, new. uuid, new. identifier, new. caption) returning * | 2207 | 0 | 7 |
|
||||
| with recursive grants as ( select descendantUuid, ascendantUuid from RbacGrants where descendantUuid = grantedId union all select ""grant"".descendantUuid, ""grant"".ascendantUuid from RbacGrants ""grant"" inner join grants recur on recur.ascendantUuid = ""grant"".descendantUuid ) select exists ( select $3 from grants where ascendantUuid = any(granteeIds) ) or grantedId = any(granteeIds) | 47538 | 0 | 0 |
|
||||
insert into public.hs_office_relation_rv (anchoruuid,contactuuid,holderuuid,mark,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7) | 1261 | 0 | 8 |
|
||||
| insert into hs_office_relation (uuid, version, anchoruuid, holderuuid, contactuuid, type, mark) values (new.uuid, new. version, new. anchoruuid, new. holderuuid, new. contactuuid, new. type, new. mark) returning * | 1261 | 0 | 8 |
|
||||
insert into public.hs_office.relation_rv (anchoruuid,contactuuid,holderuuid,mark,type,version,uuid) values ($1,$2,$3,$4,$5,$6,$7) | 1261 | 0 | 8 |
|
||||
| insert into hs_office.relation (uuid, version, anchoruuid, holderuuid, contactuuid, type, mark) values (new.uuid, new. version, new. anchoruuid, new. holderuuid, new. contactuuid, new. type, new. mark) returning * | 1261 | 0 | 8 |
|
||||
| call buildRbacSystemForHsOfficeRelation(NEW) | 1276 | 0 | 7 |
|
||||
| insert into public.hs_booking_item_rv (caption,parentitemuuid,projectuuid,resources,type,validity,version,uuid) values ($1,$2,$3,$4,$5,$6,$7,$8) | 926 | 0 | 7 |
|
||||
| insert into hs_booking_item (resources, version, projectuuid, type, parentitemuuid, validity, uuid, caption) values (new.resources, new. version, new. projectuuid, new. type, new. parentitemuuid, new. validity, new. uuid, new. caption) returning * | 926 | 0 | 7 |
|
||||
@ -331,13 +331,13 @@ Now, the longest running queries are these:
|
||||
| No.| calls | total_m | mean_ms | query |
|
||||
|---:|---------|--------:|--------:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 1 | 13.093 | 4 | 21 | insert into hs_hosting_asset( uuid, type, bookingitemuuid, parentassetuuid, assignedtoassetuuid, alarmcontactuuid, identifier, caption, config, version) values ( $1, $2, $3, $4, $5, $6, $7, $8, cast($9 as jsonb), $10) |
|
||||
| 2 | 517 | 4 | 502 | select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office_relation_rv hore1_0 where hore1_0.uuid=$1 |
|
||||
| 2 | 517 | 4 | 502 | select hore1_0.uuid,hore1_0.anchoruuid,hore1_0.contactuuid,hore1_0.holderuuid,hore1_0.mark,hore1_0.type,hore1_0.version from public.hs_office.relation_rv hore1_0 where hore1_0.uuid=$1 |
|
||||
| 3 | 13.144 | 4 | 21 | call buildRbacSystemForHsHostingAsset(NEW) |
|
||||
| 4 | 96.632 | 3 | 2 | call rbac.grantRoleToRole(roleUuid, superRoleUuid, superRoleDesc.assumed) |
|
||||
| 5 | 120.815 | 3 | 2 | select * from rbac.isGranted(array[granteeId], grantedId) |
|
||||
| 6 | 123.740 | 3 | 2 | with recursive grants as ( select descendantUuid, ascendantUuid from RbacGrants where descendantUuid = grantedId union all select "grant".descendantUuid, "grant".ascendantUuid from RbacGrants "grant" inner join grants recur on recur.ascendantUuid = "grant".descendantUuid ) select exists ( select $3 from grants where ascendantUuid = any(granteeIds) ) or grantedId = any(granteeIds) |
|
||||
| 7 | 497 | 2 | 259 | select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office_contact_rv hoce1_0 where hoce1_0.uuid=$1 |
|
||||
| 8 | 497 | 2 | 255 | select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office_person_rv hope1_0 where hope1_0.uuid=$1 |
|
||||
| 7 | 497 | 2 | 259 | select hoce1_0.uuid,hoce1_0.caption,hoce1_0.emailaddresses,hoce1_0.phonenumbers,hoce1_0.postaladdress,hoce1_0.version from public.hs_office.contact_rv hoce1_0 where hoce1_0.uuid=$1 |
|
||||
| 8 | 497 | 2 | 255 | select hope1_0.uuid,hope1_0.familyname,hope1_0.givenname,hope1_0.persontype,hope1_0.salutation,hope1_0.title,hope1_0.tradename,hope1_0.version from public.hs_office.person_rv hope1_0 where hope1_0.uuid=$1 |
|
||||
| 9 | 13.144 | 1 | 8 | SELECT createRoleWithGrants( hsHostingAssetTENANT(NEW), permissions => array[$7], incomingSuperRoles => array[ hsHostingAssetAGENT(NEW), hsOfficeContactADMIN(newAlarmContact)], outgoingSubRoles => array[ hsBookingItemTENANT(newBookingItem), hsHostingAssetTENANT(newParentAsset)] ) |
|
||||
| 10 | 13.144 | 1 | 5 | SELECT createRoleWithGrants( hsHostingAssetADMIN(NEW), permissions => array[$7], incomingSuperRoles => array[ hsBookingItemAGENT(newBookingItem), hsHostingAssetAGENT(newParentAsset), hsHostingAssetOWNER(NEW)] ) |
|
||||
|
||||
@ -345,7 +345,7 @@ That the `INSERT into hs_hosting_asset` (No. 1) takes up the most time, seems to
|
||||
|
||||
It seems that the trigger effects (eg. No. 3 and No. 4) are included in the measure for the causing INSERT, otherwise summing up the totals would exceed the actual total time of the whole import. And it was to be expected that building the RBAC rules for new business objects takes most of the time.
|
||||
|
||||
In production, the `SELECT ... FROM hs_office_relation_rv` (No. 2) with about 0.5 seconds could still be a problem. But once we apply the improvements from the hosting asset area also to the office area, this should not be a problem for the import anymore.
|
||||
In production, the `SELECT ... FROM hs_office.relation_rv` (No. 2) with about 0.5 seconds could still be a problem. But once we apply the improvements from the hosting asset area also to the office area, this should not be a problem for the import anymore.
|
||||
|
||||
|
||||
## Further Options To Explore
|
||||
|
@ -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();
|
||||
|
@ -384,7 +384,7 @@ create index on rbac.permission (objectUuid, op);
|
||||
create index on rbac.permission (opTableName, op);
|
||||
|
||||
ALTER TABLE rbac.permission
|
||||
ADD CONSTRAINT RbacPermission_uc UNIQUE NULLS NOT DISTINCT (objectUuid, op, opTableName);
|
||||
ADD CONSTRAINT unique_including_null_values UNIQUE NULLS NOT DISTINCT (objectUuid, op, opTableName);
|
||||
|
||||
call base.create_journal('rbac.permission');
|
||||
|
||||
|
@ -24,7 +24,7 @@ call rbac.generateRbacRoleDescriptors('testCustomer', 'rbactest.customer');
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForTestCustomer(
|
||||
create or replace procedure rbactest.customer_build_rbac_system(
|
||||
NEW rbactest.customer
|
||||
)
|
||||
language plpgsql as $$
|
||||
@ -60,19 +60,19 @@ end; $$;
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new rbactest.customer row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestCustomer_tf()
|
||||
create or replace function rbactest.customer_build_rbac_system_after_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForTestCustomer(NEW);
|
||||
call rbactest.customer_build_rbac_system(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestCustomer_tg
|
||||
create trigger build_rbac_system_after_insert_tg
|
||||
after insert on rbactest.customer
|
||||
for each row
|
||||
execute procedure insertTriggerForTestCustomer_tf();
|
||||
execute procedure rbactest.customer_build_rbac_system_after_insert_tf();
|
||||
--//
|
||||
|
||||
|
||||
@ -137,7 +137,7 @@ create or replace function rbactest.customer_insert_permission_check_tf()
|
||||
declare
|
||||
superObjectUuid uuid;
|
||||
begin
|
||||
-- check INSERT INSERT if rbac.global ADMIN
|
||||
-- check INSERT permission if rbac.global ADMIN
|
||||
if rbac.isGlobalAdmin() then
|
||||
return NEW;
|
||||
end if;
|
||||
|
@ -24,7 +24,7 @@ call rbac.generateRbacRoleDescriptors('testPackage', 'rbactest.package');
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForTestPackage(
|
||||
create or replace procedure rbactest.package_build_rbac_system(
|
||||
NEW rbactest.package
|
||||
)
|
||||
language plpgsql as $$
|
||||
@ -64,19 +64,19 @@ end; $$;
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new rbactest.package row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestPackage_tf()
|
||||
create or replace function rbactest.package_build_rbac_system_after_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForTestPackage(NEW);
|
||||
call rbactest.package_build_rbac_system(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestPackage_tg
|
||||
create trigger build_rbac_system_after_insert_tg
|
||||
after insert on rbactest.package
|
||||
for each row
|
||||
execute procedure insertTriggerForTestPackage_tf();
|
||||
execute procedure rbactest.package_build_rbac_system_after_insert_tf();
|
||||
--//
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ execute procedure insertTriggerForTestPackage_tf();
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForTestPackage(
|
||||
create or replace procedure rbactest.package_update_rbac_system(
|
||||
OLD rbactest.package,
|
||||
NEW rbactest.package
|
||||
)
|
||||
@ -122,22 +122,22 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new rbactest.package row.
|
||||
AFTER UPDATE TRIGGER to re-wire the grant structure for a new rbactest.package row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForTestPackage_tf()
|
||||
create or replace function rbactest.package_update_rbac_system_after_update_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForTestPackage(OLD, NEW);
|
||||
call rbactest.package_update_rbac_system(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForTestPackage_tg
|
||||
create trigger update_rbac_system_after_update_tg
|
||||
after update on rbactest.package
|
||||
for each row
|
||||
execute procedure updateTriggerForTestPackage_tf();
|
||||
execute procedure rbactest.package_update_rbac_system_after_update_tf();
|
||||
--//
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@ call rbac.generateRbacRoleDescriptors('testDomain', 'rbactest.domain');
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForTestDomain(
|
||||
create or replace procedure rbactest.domain_build_rbac_system(
|
||||
NEW rbactest.domain
|
||||
)
|
||||
language plpgsql as $$
|
||||
@ -60,19 +60,19 @@ end; $$;
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new rbactest.domain row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForTestDomain_tf()
|
||||
create or replace function rbactest.domain_build_rbac_system_after_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForTestDomain(NEW);
|
||||
call rbactest.domain_build_rbac_system(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForTestDomain_tg
|
||||
create trigger build_rbac_system_after_insert_tg
|
||||
after insert on rbactest.domain
|
||||
for each row
|
||||
execute procedure insertTriggerForTestDomain_tf();
|
||||
execute procedure rbactest.domain_build_rbac_system_after_insert_tf();
|
||||
--//
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ execute procedure insertTriggerForTestDomain_tf();
|
||||
Called from the AFTER UPDATE TRIGGER to re-wire the grants.
|
||||
*/
|
||||
|
||||
create or replace procedure updateRbacRulesForTestDomain(
|
||||
create or replace procedure rbactest.domain_update_rbac_system(
|
||||
OLD rbactest.domain,
|
||||
NEW rbactest.domain
|
||||
)
|
||||
@ -121,22 +121,22 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to re-wire the grant structure for a new rbactest.domain row.
|
||||
AFTER UPDATE TRIGGER to re-wire the grant structure for a new rbactest.domain row.
|
||||
*/
|
||||
|
||||
create or replace function updateTriggerForTestDomain_tf()
|
||||
create or replace function rbactest.domain_update_rbac_system_after_update_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call updateRbacRulesForTestDomain(OLD, NEW);
|
||||
call rbactest.domain_update_rbac_system(OLD, NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger updateTriggerForTestDomain_tg
|
||||
create trigger update_rbac_system_after_update_tg
|
||||
after update on rbactest.domain
|
||||
for each row
|
||||
execute procedure updateTriggerForTestDomain_tf();
|
||||
execute procedure rbactest.domain_update_rbac_system_after_update_tf();
|
||||
--//
|
||||
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-office-SCHEMA endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
CREATE SCHEMA hs_office;
|
||||
--//
|
@ -4,7 +4,7 @@
|
||||
--changeset michael.hoennig:hs-office-contact-MAIN-TABLE endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create table if not exists hs_office_contact
|
||||
create table if not exists hs_office.contact
|
||||
(
|
||||
uuid uuid unique references rbac.object (uuid) initially deferred,
|
||||
version int not null default 0,
|
||||
@ -20,5 +20,5 @@ create table if not exists hs_office_contact
|
||||
--changeset michael.hoennig:hs-office-contact-MAIN-TABLE-JOURNAL endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call base.create_journal('hs_office_contact');
|
||||
call base.create_journal('hs_office.contact');
|
||||
--//
|
||||
|
@ -3,29 +3,29 @@
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-office-contact-rbac-OBJECT endDelimiter:--//
|
||||
--changeset RbacObjectGenerator:hs-office-contact-rbac-OBJECT endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRelatedRbacObject('hs_office_contact');
|
||||
call rbac.generateRelatedRbacObject('hs_office.contact');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-office-contact-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
--changeset RbacRoleDescriptorsGenerator:hs-office-contact-rbac-ROLE-DESCRIPTORS endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRoleDescriptors('hsOfficeContact', 'hs_office_contact');
|
||||
call rbac.generateRbacRoleDescriptors('hsOfficeContact', 'hs_office.contact');
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-office-contact-rbac-insert-trigger endDelimiter:--//
|
||||
--changeset RolesGrantsAndPermissionsGenerator:hs-office-contact-rbac-insert-trigger endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Creates the roles, grants and permission for the AFTER INSERT TRIGGER.
|
||||
*/
|
||||
|
||||
create or replace procedure buildRbacSystemForHsOfficeContact(
|
||||
NEW hs_office_contact
|
||||
create or replace procedure hs_office.contact_build_rbac_system(
|
||||
NEW hs_office.contact
|
||||
)
|
||||
language plpgsql as $$
|
||||
|
||||
@ -37,7 +37,7 @@ begin
|
||||
perform rbac.defineRoleWithGrants(
|
||||
hsOfficeContactOWNER(NEW),
|
||||
permissions => array['DELETE'],
|
||||
incomingSuperRoles => array[rbac.globalAdmin()],
|
||||
incomingSuperRoles => array[rbac.globalADMIN()],
|
||||
subjectUuids => array[rbac.currentSubjectUuid()]
|
||||
);
|
||||
|
||||
@ -57,30 +57,30 @@ begin
|
||||
end; $$;
|
||||
|
||||
/*
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office_contact row.
|
||||
AFTER INSERT TRIGGER to create the role+grant structure for a new hs_office.contact row.
|
||||
*/
|
||||
|
||||
create or replace function insertTriggerForHsOfficeContact_tf()
|
||||
create or replace function hs_office.contact_build_rbac_system_after_insert_tf()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
strict as $$
|
||||
begin
|
||||
call buildRbacSystemForHsOfficeContact(NEW);
|
||||
call hs_office.contact_build_rbac_system(NEW);
|
||||
return NEW;
|
||||
end; $$;
|
||||
|
||||
create trigger insertTriggerForHsOfficeContact_tg
|
||||
after insert on hs_office_contact
|
||||
create trigger build_rbac_system_after_insert_tg
|
||||
after insert on hs_office.contact
|
||||
for each row
|
||||
execute procedure insertTriggerForHsOfficeContact_tf();
|
||||
execute procedure hs_office.contact_build_rbac_system_after_insert_tf();
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-office-contact-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
--changeset RbacIdentityViewGenerator:hs-office-contact-rbac-IDENTITY-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
call rbac.generateRbacIdentityViewFromProjection('hs_office_contact',
|
||||
call rbac.generateRbacIdentityViewFromProjection('hs_office.contact',
|
||||
$idName$
|
||||
caption
|
||||
$idName$);
|
||||
@ -88,9 +88,9 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office_contact',
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-office-contact-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-contact-rbac-RESTRICTED-VIEW endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
call rbac.generateRbacRestrictedView('hs_office_contact',
|
||||
call rbac.generateRbacRestrictedView('hs_office.contact',
|
||||
$orderBy$
|
||||
caption
|
||||
$orderBy$,
|
||||
|