avoid-recursive-rbac-query-for-global-admins in the _rv generator (#216)
Co-authored-by: Michael Hoennig <michael@hoennig.de> Reviewed-on: https://dev.hostsharing.net/hostsharing/hs.hsadmin.ng/pulls/216 Reviewed-by: Marc Sandlus <hsh-marcsandlus@noreply.dev.hostsharing.net>
This commit is contained in:
@@ -83,7 +83,7 @@ begin
|
||||
end; $$;
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbac-context-CONTEXT-DEFINED endDelimiter:--//
|
||||
--changeset michael.hoennig:rbac-context-CONTEXT-DEFINED runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Callback which is called after the context has been (re-) defined.
|
||||
@@ -98,6 +98,7 @@ create or replace procedure base.contextDefined(
|
||||
language plpgsql as $$
|
||||
declare
|
||||
currentSubjectUuid uuid;
|
||||
currentSubjectHasGlobalAdminRole boolean;
|
||||
begin
|
||||
execute format('set local hsadminng.currentTask to %L', currentTask);
|
||||
|
||||
@@ -111,6 +112,13 @@ begin
|
||||
execute format('set local hsadminng.currentSubjectOrAssumedRolesUuids to %L',
|
||||
(select array_to_string(rbac.determineCurrentSubjectOrAssumedRolesUuids(currentSubjectUuid, assumedRoles), ';')));
|
||||
|
||||
if currentSubjectUuid is null then
|
||||
currentSubjectHasGlobalAdminRole := false;
|
||||
else
|
||||
currentSubjectHasGlobalAdminRole := rbac.isGranted(array[currentSubjectUuid], rbac.findRoleId(rbac.global_ADMIN()));
|
||||
end if;
|
||||
execute format('set local hsadminng.isGlobalAdmin to %L', currentSubjectHasGlobalAdminRole::text);
|
||||
|
||||
raise notice 'Context defined as: %, %, %, [%]', currentTask, currentRequest, currentSubject, assumedRoles;
|
||||
end; $$;
|
||||
|
||||
@@ -181,4 +189,3 @@ begin
|
||||
return string_to_array(currentSubjectOrAssumedRolesUuids, ';');
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
@@ -179,8 +179,10 @@ create or replace procedure rbac.generateRbacRestrictedView(targetTable text, or
|
||||
declare
|
||||
sql text;
|
||||
newColumns text;
|
||||
functionName text;
|
||||
begin
|
||||
targetTable := lower(targetTable);
|
||||
functionName := replace(targetTable, '.', '_');
|
||||
if columnNames = '*' then
|
||||
columnNames := base.tableColumnNames(targetTable);
|
||||
end if;
|
||||
@@ -189,45 +191,62 @@ begin
|
||||
Creates a restricted view based on the 'SELECT' permission of the current subject.
|
||||
*/
|
||||
sql := format($sql$
|
||||
create or replace function rbac.select_%3$s_rv()
|
||||
returns setof %1$s
|
||||
language plpgsql
|
||||
as $f$
|
||||
begin
|
||||
if rbac.hasGlobalAdminRole() then
|
||||
return query
|
||||
select target.*
|
||||
from %1$s as target
|
||||
order by %2$s;
|
||||
else
|
||||
return query
|
||||
with accessible_uuids as (
|
||||
with recursive
|
||||
recursive_grants as
|
||||
(select distinct rbac.grant.descendantuuid,
|
||||
rbac.grant.ascendantuuid,
|
||||
1 as level,
|
||||
true
|
||||
from rbac.grant
|
||||
where rbac.grant.assumed
|
||||
and (rbac.grant.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids()))
|
||||
union all
|
||||
select distinct g.descendantuuid,
|
||||
g.ascendantuuid,
|
||||
grants.level + 1 as level,
|
||||
base.assertTrue(grants.level < 22, 'too many grant-levels: ' || grants.level)
|
||||
from rbac.grant g
|
||||
join recursive_grants grants on grants.descendantuuid = g.ascendantuuid
|
||||
where g.assumed),
|
||||
grant_count AS (
|
||||
SELECT COUNT(*) AS grant_count FROM recursive_grants
|
||||
),
|
||||
count_check as (select base.assertTrue((select count(*) as grant_count from recursive_grants) < 400000,
|
||||
'too many grants for current subjects: ' || (select count(*) as grant_count from recursive_grants))
|
||||
as valid)
|
||||
select distinct perm.objectuuid
|
||||
from recursive_grants
|
||||
join rbac.permission perm on recursive_grants.descendantuuid = perm.uuid
|
||||
join rbac.object obj on obj.uuid = perm.objectuuid
|
||||
join count_check cc on cc.valid
|
||||
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
|
||||
)
|
||||
select target.*
|
||||
from %1$s as target
|
||||
where target.uuid in (select * from accessible_uuids)
|
||||
order by %2$s;
|
||||
end if;
|
||||
end;
|
||||
$f$;
|
||||
|
||||
create or replace view %1$s_rv as
|
||||
with accessible_uuids as (
|
||||
with recursive
|
||||
recursive_grants as
|
||||
(select distinct rbac.grant.descendantuuid,
|
||||
rbac.grant.ascendantuuid,
|
||||
1 as level,
|
||||
true
|
||||
from rbac.grant
|
||||
where rbac.grant.assumed
|
||||
and (rbac.grant.ascendantuuid = any (rbac.currentSubjectOrAssumedRolesUuids()))
|
||||
union all
|
||||
select distinct g.descendantuuid,
|
||||
g.ascendantuuid,
|
||||
grants.level + 1 as level,
|
||||
base.assertTrue(grants.level < 22, 'too many grant-levels: ' || grants.level)
|
||||
from rbac.grant g
|
||||
join recursive_grants grants on grants.descendantuuid = g.ascendantuuid
|
||||
where g.assumed),
|
||||
grant_count AS (
|
||||
SELECT COUNT(*) AS grant_count FROM recursive_grants
|
||||
),
|
||||
count_check as (select base.assertTrue((select count(*) as grant_count from recursive_grants) < 400000,
|
||||
'too many grants for current subjects: ' || (select count(*) as grant_count from recursive_grants))
|
||||
as valid)
|
||||
select distinct perm.objectuuid
|
||||
from recursive_grants
|
||||
join rbac.permission perm on recursive_grants.descendantuuid = perm.uuid
|
||||
join rbac.object obj on obj.uuid = perm.objectuuid
|
||||
join count_check cc on cc.valid
|
||||
where obj.objectTable = '%1$s' -- 'SELECT' permission is included in all other permissions
|
||||
)
|
||||
select target.*
|
||||
from %1$s as target
|
||||
where rbac.hasGlobalAdminRole() or target.uuid in (select * from accessible_uuids)
|
||||
order by %2$s;
|
||||
select * from rbac.select_%3$s_rv();
|
||||
|
||||
grant all privileges on %1$s_rv to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
$sql$, targetTable, orderBy);
|
||||
$sql$, targetTable, orderBy, functionName);
|
||||
execute sql;
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,23 +23,34 @@ grant select on rbac.global to ${HSADMINNG_POSTGRES_RESTRICTED_USERNAME};
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbac-global-IS-GLOBAL-ADMIN endDelimiter:--//
|
||||
--changeset michael.hoennig:rbac-global-IS-GLOBAL-ADMIN runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ------------------------------------------------------------------
|
||||
|
||||
create or replace function rbac.isGlobalAdmin()
|
||||
returns boolean
|
||||
language plpgsql as $$
|
||||
declare
|
||||
isGlobalAdmin text;
|
||||
begin
|
||||
return rbac.isGranted(rbac.currentSubjectOrAssumedRolesUuids(), rbac.findRoleId(rbac.global_ADMIN()));
|
||||
isGlobalAdmin := current_setting('hsadminng.isGlobalAdmin', true);
|
||||
if isGlobalAdmin is not null then
|
||||
return isGlobalAdmin::boolean;
|
||||
end if;
|
||||
|
||||
raise exception '`hsadminng.isGlobalAdmin` should have been set by `rbac.defineContext()`';
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:rbac-global-HAS-GLOBAL-ADMIN-ROLE endDelimiter:--//
|
||||
--changeset michael.hoennig:rbac-global-HAS-GLOBAL-ADMIN-ROLE runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
/*
|
||||
Returns true if the current user is a global admin and has no assumed role.
|
||||
|
||||
ATTENTION: It's false if the global-admin role is assumed,
|
||||
because the global admin role does not have the global admin role, but it is the global admin role.
|
||||
The differentiation is important for the cases where this function is used.
|
||||
*/
|
||||
create or replace function rbac.hasGlobalAdminRole()
|
||||
returns boolean
|
||||
|
||||
+1
@@ -167,6 +167,7 @@ call rbac.generateRbacIdentityViewFromProjection('rbactest.customer',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:rbactest-customer-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('rbactest.customer',
|
||||
$orderBy$
|
||||
reference
|
||||
|
||||
+1
@@ -232,6 +232,7 @@ call rbac.generateRbacIdentityViewFromProjection('rbactest.package',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:rbactest-package-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('rbactest.package',
|
||||
$orderBy$
|
||||
name
|
||||
|
||||
+1
@@ -231,6 +231,7 @@ call rbac.generateRbacIdentityViewFromProjection('rbactest.domain',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:rbactest-domain-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('rbactest.domain',
|
||||
$orderBy$
|
||||
name
|
||||
|
||||
+1
@@ -90,6 +90,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.contact',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-contact-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.contact',
|
||||
$orderBy$
|
||||
caption
|
||||
|
||||
@@ -90,6 +90,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.person',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-person-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.person',
|
||||
$orderBy$
|
||||
concat(tradeName, familyName, givenName)
|
||||
|
||||
+1
@@ -245,6 +245,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.relation',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-relation-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.relation',
|
||||
$orderBy$
|
||||
(select idName from hs_office.person_iv p where p.uuid = target.holderUuid)
|
||||
|
||||
+1
@@ -244,6 +244,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.partner',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-partner-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.partner',
|
||||
$orderBy$
|
||||
'P-' || partnerNumber
|
||||
|
||||
+1
@@ -151,6 +151,7 @@ call rbac.generateRbacIdentityViewFromQuery('hs_office.partner_details',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-partner-details-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.partner_details',
|
||||
$orderBy$
|
||||
uuid
|
||||
|
||||
+1
@@ -90,6 +90,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.bankaccount',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-bankaccount-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.bankaccount',
|
||||
$orderBy$
|
||||
iban
|
||||
|
||||
+1
@@ -226,6 +226,7 @@ call rbac.generateRbacIdentityViewFromQuery('hs_office.debitor',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-debitor-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.debitor',
|
||||
$orderBy$
|
||||
defaultPrefix
|
||||
|
||||
+1
@@ -200,6 +200,7 @@ call rbac.generateRbacIdentityViewFromQuery('hs_office.sepamandate',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-sepamandate-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.sepamandate',
|
||||
$orderBy$
|
||||
validity
|
||||
|
||||
+1
@@ -182,6 +182,7 @@ call rbac.generateRbacIdentityViewFromQuery('hs_office.membership',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-membership-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.membership',
|
||||
$orderBy$
|
||||
validity
|
||||
|
||||
+1
@@ -155,6 +155,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.coopsharetx',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-coopsharetx-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.coopsharetx',
|
||||
$orderBy$
|
||||
reference
|
||||
|
||||
+1
@@ -155,6 +155,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_office.coopassettx',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-office-coopassettx-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_office.coopassettx',
|
||||
$orderBy$
|
||||
reference
|
||||
|
||||
+1
@@ -194,6 +194,7 @@ call rbac.generateRbacIdentityViewFromQuery('hs_booking.project',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-booking-project-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_booking.project',
|
||||
$orderBy$
|
||||
caption
|
||||
|
||||
+1
@@ -263,6 +263,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_booking.item',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-booking-item-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_booking.item',
|
||||
$orderBy$
|
||||
validity
|
||||
|
||||
+1
@@ -168,6 +168,7 @@ call rbac.generateRbacIdentityViewFromProjection('hs_hosting.asset',
|
||||
-- ============================================================================
|
||||
--changeset RbacRestrictedViewGenerator:hs-hosting-asset-rbac-RESTRICTED-VIEW runOnChange:true validCheckSum:ANY endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
-- trigger change of change in generateRbacRestrictedView regarding #453 optimization for global:ADMIN
|
||||
call rbac.generateRbacRestrictedView('hs_hosting.asset',
|
||||
$orderBy$
|
||||
identifier
|
||||
|
||||
@@ -0,0 +1,586 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-mass-test-data-GENERATORS context:!without-test-data endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Loop-based mass test-data generators for office/booking/hosting/accounts.
|
||||
*/
|
||||
create or replace procedure hs_office.contact_create_mass_test_data(
|
||||
startCount integer,
|
||||
endCount integer,
|
||||
captionPrefix varchar default 'mass contact '
|
||||
)
|
||||
language plpgsql as $$
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call base.defineContext('mass contact test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
call hs_office.contact_create_test_data(captionPrefix || base.intToVarChar(t, 4));
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.person_create_mass_test_data(
|
||||
startCount integer,
|
||||
endCount integer
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
idx varchar;
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call base.defineContext('mass person test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
if t % 5 = 0 then
|
||||
call hs_office.person_create_test_data('NP', null, 'MassFamily' || idx, 'MassGiven' || idx, true);
|
||||
else
|
||||
call hs_office.person_create_test_data('LP', 'Mass Partner ' || idx || ' GmbH', null, null, true);
|
||||
end if;
|
||||
call hs_office.person_create_test_data('NP', null, 'MassRep' || idx, 'User' || idx, true);
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.relation_create_mass_test_data(
|
||||
startCount integer,
|
||||
endCount integer,
|
||||
mandantTradeName varchar default 'Hostsharing eG',
|
||||
contactCaptionPrefix varchar default 'mass contact '
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
idx varchar;
|
||||
partnerPersonName varchar;
|
||||
representativeFamilyName varchar;
|
||||
contactCaption varchar;
|
||||
mandantPerson hs_office.person;
|
||||
partnerPerson hs_office.person;
|
||||
representativePerson hs_office.person;
|
||||
contact hs_office.contact;
|
||||
begin
|
||||
select p.* into mandantPerson from hs_office.person p where p.tradeName = mandantTradeName;
|
||||
if mandantPerson is null then
|
||||
raise exception 'mandant "%" not found', mandantTradeName;
|
||||
end if;
|
||||
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call base.defineContext('mass relation test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
partnerPersonName := case when t % 5 = 0 then 'MassFamily' || idx else 'Mass Partner ' || idx || ' GmbH' end;
|
||||
representativeFamilyName := 'MassRep' || idx;
|
||||
contactCaption := contactCaptionPrefix || idx;
|
||||
|
||||
select p.* into partnerPerson
|
||||
from hs_office.person p
|
||||
where p.tradeName = partnerPersonName or p.familyName = partnerPersonName;
|
||||
select p.* into representativePerson from hs_office.person p where p.familyName = representativeFamilyName;
|
||||
select c.* into contact from hs_office.contact c where c.caption = contactCaption;
|
||||
|
||||
if partnerPerson is null or representativePerson is null or contact is null then
|
||||
raise exception 'missing mass test base data for index %', idx;
|
||||
end if;
|
||||
|
||||
if not exists (
|
||||
select 1 from hs_office.relation r
|
||||
where r.type = 'PARTNER' and r.anchorUuid = mandantPerson.uuid and r.holderUuid = partnerPerson.uuid
|
||||
) then
|
||||
call hs_office.relation_create_test_data(partnerPersonName, 'PARTNER', mandantTradeName, contactCaption);
|
||||
end if;
|
||||
|
||||
if not exists (
|
||||
select 1 from hs_office.relation r
|
||||
where r.type = 'REPRESENTATIVE' and r.anchorUuid = partnerPerson.uuid and r.holderUuid = representativePerson.uuid and r.contactUuid = contact.uuid
|
||||
) then
|
||||
call hs_office.relation_create_test_data(representativeFamilyName, 'REPRESENTATIVE', partnerPersonName, contactCaption);
|
||||
end if;
|
||||
|
||||
if not exists (
|
||||
select 1 from hs_office.relation r
|
||||
where r.type = 'DEBITOR' and r.anchorUuid = partnerPerson.uuid and r.holderUuid = partnerPerson.uuid and r.contactUuid = contact.uuid
|
||||
) then
|
||||
call hs_office.relation_create_test_data(partnerPersonName, 'DEBITOR', partnerPersonName, contactCaption);
|
||||
end if;
|
||||
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.partner_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5),
|
||||
mandantTradeName varchar default 'Hostsharing eG',
|
||||
contactCaptionPrefix varchar default 'mass contact '
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
idx varchar;
|
||||
partnerPersonName varchar;
|
||||
contactCaption varchar;
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass partner test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
partnerPersonName := case when t % 5 = 0 then 'MassFamily' || idx else 'Mass Partner ' || idx || ' GmbH' end;
|
||||
contactCaption := contactCaptionPrefix || idx;
|
||||
|
||||
if not exists (select 1 from hs_office.partner p where p.partnerNumber = t) then
|
||||
call hs_office.partner_create_test_data(mandantTradeName, t, partnerPersonName, contactCaption);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.bankaccount_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
idx varchar;
|
||||
v_holder varchar;
|
||||
v_iban varchar;
|
||||
v_bic varchar;
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass bankaccount test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
v_holder := case when t % 5 = 0 then 'MassFamily' || idx else 'Mass Partner ' || idx || ' GmbH' end;
|
||||
v_iban := 'DE' || lpad(t::text, 20, '0');
|
||||
v_bic := 'MASSDEFF' || lpad((t % 1000)::text, 3, '0');
|
||||
|
||||
if not exists (
|
||||
select 1 from hs_office.bankaccount b where b.holder = v_holder and b.iban = v_iban
|
||||
) then
|
||||
call hs_office.bankaccount_create_test_data(v_holder, v_iban, v_bic);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.debitor_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5),
|
||||
contactCaptionPrefix varchar default 'mass contact '
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
idx varchar;
|
||||
partnerPersonName varchar;
|
||||
suffixNum integer;
|
||||
suffixText char(2);
|
||||
defaultPrefix char(3);
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass debitor test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
partnerPersonName := case when t % 5 = 0 then 'MassFamily' || idx else 'Mass Partner ' || idx || ' GmbH' end;
|
||||
suffixNum := 10 + (t % 90);
|
||||
suffixText := lpad(suffixNum::text, 2, '0');
|
||||
defaultPrefix := lower(
|
||||
chr(97 + ((t / 676) % 26)) ||
|
||||
chr(97 + ((t / 26) % 26)) ||
|
||||
chr(97 + (t % 26))
|
||||
);
|
||||
|
||||
if not exists (
|
||||
select 1
|
||||
from hs_office.debitor d
|
||||
join hs_office.relation debitorRel on debitorRel.uuid = d.debitorRelUuid and debitorRel.type = 'DEBITOR'
|
||||
join hs_office.relation partnerRel on partnerRel.holderUuid = debitorRel.anchorUuid and partnerRel.type = 'PARTNER'
|
||||
join hs_office.partner p on p.partnerRelUuid = partnerRel.uuid
|
||||
where p.partnerNumber = t and d.debitorNumberSuffix = suffixText
|
||||
) then
|
||||
call hs_office.debitor_create_test_data(suffixNum, partnerPersonName, contactCaptionPrefix || idx, defaultPrefix);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.sepamandate_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
suffixText char(2);
|
||||
iban varchar;
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass sepa-mandate test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
suffixText := lpad((10 + (t % 90))::text, 2, '0');
|
||||
iban := 'DE' || lpad(t::text, 20, '0');
|
||||
|
||||
if not exists (
|
||||
select 1
|
||||
from hs_office.sepamandate sm
|
||||
join hs_office.debitor d on d.uuid = sm.debitorUuid
|
||||
join hs_office.relation debitorRel on debitorRel.uuid = d.debitorRelUuid
|
||||
join hs_office.relation partnerRel on partnerRel.holderUuid = debitorRel.anchorUuid
|
||||
join hs_office.partner p on p.partnerRelUuid = partnerRel.uuid
|
||||
where p.partnerNumber = t and d.debitorNumberSuffix = suffixText
|
||||
) then
|
||||
call hs_office.sepamandate_create_test_data(t, suffixText, iban, 'mass-ref-' || t::text || '-' || suffixText);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.membership_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5),
|
||||
withMembershipPercentage integer default 80
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
memberSuffix char(2);
|
||||
begin
|
||||
if withMembershipPercentage < 0 or withMembershipPercentage > 100 then
|
||||
raise exception 'withMembershipPercentage must be between 0 and 100';
|
||||
end if;
|
||||
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass membership test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
if (t % 100) < withMembershipPercentage then
|
||||
memberSuffix := lpad((10 + (t % 90))::text, 2, '0');
|
||||
call hs_office.membership_create_test_data(t, memberSuffix, daterange('20221001', null, '[]'), 'ACTIVE');
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.coopsharetx_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5),
|
||||
withMembershipPercentage integer default 80
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
memberSuffix char(2);
|
||||
v_membershipUuid uuid;
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass coop-sharetx test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
if (t % 100) < withMembershipPercentage then
|
||||
memberSuffix := lpad((10 + (t % 90))::text, 2, '0');
|
||||
select m.uuid into v_membershipUuid
|
||||
from hs_office.membership m
|
||||
join hs_office.partner p on p.uuid = m.partnerUuid
|
||||
where p.partnerNumber = t and m.memberNumberSuffix = memberSuffix;
|
||||
|
||||
if v_membershipUuid is not null and not exists (
|
||||
select 1 from hs_office.coopsharetx tx where tx.membershipUuid = v_membershipUuid
|
||||
) then
|
||||
call hs_office.coopsharetx_create_test_data(t, memberSuffix);
|
||||
end if;
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.coopassettx_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5),
|
||||
withMembershipPercentage integer default 80
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
memberSuffix char(2);
|
||||
v_membershipUuid uuid;
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass coop-assettx test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
if (t % 100) < withMembershipPercentage then
|
||||
memberSuffix := lpad((10 + (t % 90))::text, 2, '0');
|
||||
select m.uuid into v_membershipUuid
|
||||
from hs_office.membership m
|
||||
join hs_office.partner p on p.uuid = m.partnerUuid
|
||||
where p.partnerNumber = t and m.memberNumberSuffix = memberSuffix;
|
||||
|
||||
if v_membershipUuid is not null and not exists (
|
||||
select 1 from hs_office.coopassettx tx where tx.membershipUuid = v_membershipUuid
|
||||
) then
|
||||
call hs_office.coopassettx_create_test_data(t, memberSuffix);
|
||||
end if;
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_booking.project_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
suffixText char(2);
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass booking-project test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
suffixText := lpad((10 + (t % 90))::text, 2, '0');
|
||||
if not exists (
|
||||
select 1 from hs_booking.project p where p.caption = 'D-' || t::text || suffixText || ' default project'
|
||||
) then
|
||||
call hs_booking.project_create_test_data(t, suffixText);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_booking.item_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
suffixText char(2);
|
||||
v_projectUuid uuid;
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass booking-item test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
suffixText := lpad((10 + (t % 90))::text, 2, '0');
|
||||
select p.uuid into v_projectUuid from hs_booking.project p where p.caption = 'D-' || t::text || suffixText || ' default project';
|
||||
if v_projectUuid is not null and not exists (
|
||||
select 1 from hs_booking.item i where i.projectUuid = v_projectUuid
|
||||
) then
|
||||
call hs_booking.item_create_test_data(t, suffixText);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_hosting.asset_create_mass_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5)
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
suffixText char(2);
|
||||
projectCaption varchar;
|
||||
v_debitorNumberSuffix char(2);
|
||||
v_defaultPrefix char(3);
|
||||
begin
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass hosting-asset test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
suffixText := lpad((10 + (t % 90))::text, 2, '0');
|
||||
projectCaption := 'D-' || t::text || suffixText || ' default project';
|
||||
select d.debitorNumberSuffix, d.defaultPrefix
|
||||
into v_debitorNumberSuffix, v_defaultPrefix
|
||||
from hs_booking.project p
|
||||
join hs_office.debitor d on d.uuid = p.debitorUuid
|
||||
where p.caption = projectCaption;
|
||||
if v_debitorNumberSuffix is not null
|
||||
and not exists (
|
||||
select 1
|
||||
from hs_hosting.asset a
|
||||
join hs_booking.item i on i.uuid = a.bookingItemUuid
|
||||
join hs_booking.project p on p.uuid = i.projectUuid
|
||||
where p.caption = projectCaption
|
||||
)
|
||||
and not exists (
|
||||
select 1 from hs_hosting.asset a
|
||||
where (a.type = 'MANAGED_SERVER' and a.identifier = 'vm10' || v_debitorNumberSuffix)
|
||||
or (a.type = 'CLOUD_SERVER' and a.identifier = 'vm20' || v_debitorNumberSuffix)
|
||||
or (a.type = 'MANAGED_WEBSPACE' and a.identifier = v_defaultPrefix || '01')
|
||||
or (a.type = 'MARIADB_INSTANCE' and a.identifier = 'vm10' || v_debitorNumberSuffix || '.MariaDB.default')
|
||||
or (a.type = 'MARIADB_USER' and a.identifier = v_defaultPrefix || '01_web')
|
||||
or (a.type = 'MARIADB_DATABASE' and a.identifier = v_defaultPrefix || '01_web')
|
||||
or (a.type = 'PGSQL_INSTANCE' and a.identifier = 'vm10' || v_debitorNumberSuffix || '.Postgresql.default')
|
||||
or (a.type = 'PGSQL_USER' and a.identifier = v_defaultPrefix || '01_web')
|
||||
or (a.type = 'PGSQL_DATABASE' and a.identifier = v_defaultPrefix || '01_web')
|
||||
or (a.type = 'EMAIL_ALIAS' and a.identifier = v_defaultPrefix || '01-web')
|
||||
or (a.type = 'UNIX_USER' and a.identifier = v_defaultPrefix || '01-web')
|
||||
or (a.type = 'UNIX_USER' and a.identifier = v_defaultPrefix || '01-mbox')
|
||||
or (a.type = 'DOMAIN_SETUP' and a.identifier = v_defaultPrefix || '.example.org')
|
||||
or (a.type = 'DOMAIN_DNS_SETUP' and a.identifier = v_defaultPrefix || '.example.org|DNS')
|
||||
or (a.type = 'DOMAIN_HTTP_SETUP' and a.identifier = v_defaultPrefix || '.example.org|HTTP')
|
||||
or (a.type = 'DOMAIN_SMTP_SETUP' and a.identifier = v_defaultPrefix || '.example.org|SMTP')
|
||||
or (a.type = 'DOMAIN_MBOX_SETUP' and a.identifier = v_defaultPrefix || '.example.org|MBOX')
|
||||
or (a.type = 'EMAIL_ADDRESS' and a.identifier = 'test@' || v_defaultPrefix || '.example.org')
|
||||
) then
|
||||
call hs_hosting.asset_create_test_data(projectCaption);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.person_create_mass_test_data_for_accounts(
|
||||
startCount integer,
|
||||
endCount integer
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
idx varchar;
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call base.defineContext('mass account-person test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
call hs_office.person_create_test_data('NP', null, 'MassAccountFamily' || idx, 'MassAccountGiven' || idx, true);
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_accounts.account_create_mass_test_data(
|
||||
startCount integer,
|
||||
endCount integer,
|
||||
emailPrefix varchar default 'mass-account-',
|
||||
uidOffset integer default 200000
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
idx varchar;
|
||||
accountEmail varchar;
|
||||
subjectUuid uuid;
|
||||
personUuid uuid;
|
||||
begin
|
||||
for t in startCount..endCount
|
||||
loop
|
||||
call base.defineContext('mass profile test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
idx := base.intToVarChar(t, 4);
|
||||
accountEmail := emailPrefix || idx || '@example.com';
|
||||
select p.uuid into personUuid
|
||||
from hs_office.person p
|
||||
where p.familyName = 'MassAccountFamily' || idx and p.givenName = 'MassAccountGiven' || idx;
|
||||
|
||||
if personUuid is not null and not exists (
|
||||
select 1 from hs_accounts.account pr where pr.person_uuid = personUuid
|
||||
) then
|
||||
perform rbac.create_subject(accountEmail);
|
||||
select s.uuid into subjectUuid from rbac.subject s where s.name = accountEmail;
|
||||
|
||||
insert into hs_accounts.account (
|
||||
uuid, version, person_uuid,
|
||||
global_uid, global_gid
|
||||
) values (
|
||||
subjectUuid, 0, personUuid,
|
||||
uidOffset + t, uidOffset + t
|
||||
);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
|
||||
create or replace procedure hs_office.partner_create_mass_bundle_test_data(
|
||||
startPartnerNumber numeric(5),
|
||||
endPartnerNumber numeric(5),
|
||||
withMembershipPercentage integer default 80
|
||||
)
|
||||
language plpgsql as $$
|
||||
declare
|
||||
t integer;
|
||||
idx varchar;
|
||||
personUuid uuid;
|
||||
accountEmail varchar;
|
||||
subjectUuid uuid;
|
||||
begin
|
||||
call base.defineContext('creating mass partner bundle test-data', null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
set constraints all deferred;
|
||||
|
||||
call hs_office.contact_create_mass_test_data(startPartnerNumber::integer, endPartnerNumber::integer);
|
||||
call hs_office.person_create_mass_test_data(startPartnerNumber::integer, endPartnerNumber::integer);
|
||||
call hs_office.relation_create_mass_test_data(startPartnerNumber::integer, endPartnerNumber::integer);
|
||||
call hs_office.partner_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
call hs_office.bankaccount_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
call hs_office.debitor_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
call hs_office.sepamandate_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
|
||||
call hs_office.membership_create_mass_test_data(startPartnerNumber, endPartnerNumber, withMembershipPercentage);
|
||||
call hs_office.coopsharetx_create_mass_test_data(startPartnerNumber, endPartnerNumber, withMembershipPercentage);
|
||||
call hs_office.coopassettx_create_mass_test_data(startPartnerNumber, endPartnerNumber, withMembershipPercentage);
|
||||
|
||||
call hs_booking.project_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
call hs_booking.item_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
call hs_hosting.asset_create_mass_test_data(startPartnerNumber, endPartnerNumber);
|
||||
|
||||
for t in startPartnerNumber::integer..endPartnerNumber::integer
|
||||
loop
|
||||
call base.defineContext('mass partner bundle account test-data #' || t, null, 'superuser-alex@hostsharing.net', 'rbac.global#global:ADMIN');
|
||||
if t % 5 = 0 then
|
||||
idx := base.intToVarChar(t, 4);
|
||||
select p.uuid into personUuid
|
||||
from hs_office.person p
|
||||
where p.familyName = 'MassFamily' || idx and p.givenName = 'MassGiven' || idx;
|
||||
|
||||
if personUuid is not null and not exists (
|
||||
select 1 from hs_accounts.account pr where pr.person_uuid = personUuid
|
||||
) then
|
||||
accountEmail := 'mass-person-' || idx || '@example.com';
|
||||
perform rbac.create_subject(accountEmail);
|
||||
select s.uuid into subjectUuid from rbac.subject s where s.name = accountEmail;
|
||||
|
||||
insert into hs_accounts.account (
|
||||
uuid, version, person_uuid,
|
||||
global_uid, global_gid
|
||||
) values (
|
||||
subjectUuid, 0, personUuid,
|
||||
300000 + t, 300000 + t
|
||||
);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
idx := base.intToVarChar(t, 4);
|
||||
select p.uuid into personUuid
|
||||
from hs_office.person p
|
||||
where p.familyName = 'MassRep' || idx and p.givenName = 'User' || idx;
|
||||
|
||||
if personUuid is not null and not exists (
|
||||
select 1 from hs_accounts.account pr where pr.person_uuid = personUuid
|
||||
) then
|
||||
accountEmail := 'mass-rep-' || idx || '@example.com';
|
||||
perform rbac.create_subject(accountEmail);
|
||||
select s.uuid into subjectUuid from rbac.subject s where s.name = accountEmail;
|
||||
|
||||
insert into hs_accounts.account (
|
||||
uuid, version, person_uuid,
|
||||
global_uid, global_gid
|
||||
) values (
|
||||
subjectUuid, 0, personUuid,
|
||||
400000 + t, 400000 + t
|
||||
);
|
||||
end if;
|
||||
commit;
|
||||
end loop;
|
||||
end; $$;
|
||||
--//
|
||||
@@ -0,0 +1,74 @@
|
||||
--liquibase formatted sql
|
||||
|
||||
|
||||
-- ============================================================================
|
||||
--changeset michael.hoennig:hs-mass-test-data-PERFORMANCE context:!without-test-data endDelimiter:--//
|
||||
-- ----------------------------------------------------------------------------
|
||||
|
||||
create or replace procedure hs_office.bench_debitor_sepamandates(iterations int default 10)
|
||||
language plpgsql
|
||||
as $$
|
||||
declare
|
||||
i int;
|
||||
t0 timestamptz;
|
||||
ms numeric;
|
||||
total_limit numeric := 0;
|
||||
total_count numeric := 0;
|
||||
min_limit numeric := null;
|
||||
max_limit numeric := null;
|
||||
min_count numeric := null;
|
||||
max_count numeric := null;
|
||||
rows_read bigint;
|
||||
begin
|
||||
for i in 1..iterations loop
|
||||
call base.defineContext(
|
||||
'query debitor',
|
||||
null,
|
||||
'superuser-alex@hostsharing.net');
|
||||
|
||||
t0 := clock_timestamp();
|
||||
select count(*) into rows_read
|
||||
from (
|
||||
select d.defaultprefix, b.iban, s.validity
|
||||
from hs_office.debitor d
|
||||
join hs_office.sepamandate_rv s on s.debitoruuid = d.uuid
|
||||
join hs_office.bankaccount b on b.uuid = s.bankaccountuuid
|
||||
where d.defaultprefix like 'dq%'
|
||||
limit 10
|
||||
) x;
|
||||
|
||||
ms := extract(epoch from (clock_timestamp() - t0)) * 1000;
|
||||
total_limit := total_limit + ms;
|
||||
if min_limit is null or ms < min_limit then min_limit := ms; end if;
|
||||
if max_limit is null or ms > max_limit then max_limit := ms; end if;
|
||||
|
||||
commit;
|
||||
end loop;
|
||||
|
||||
for i in 1..iterations loop
|
||||
call base.defineContext('query debitor',
|
||||
null,
|
||||
'superuser-alex@hostsharing.net');
|
||||
|
||||
t0 := clock_timestamp();
|
||||
select count(*) into rows_read
|
||||
from hs_office.debitor d
|
||||
join hs_office.sepamandate_rv s on s.debitoruuid = d.uuid
|
||||
join hs_office.bankaccount b on b.uuid = s.bankaccountuuid;
|
||||
|
||||
ms := extract(epoch from (clock_timestamp() - t0)) * 1000;
|
||||
total_count := total_count + ms;
|
||||
if min_count is null or ms < min_count then min_count := ms; end if;
|
||||
if max_count is null or ms > max_count then max_count := ms; end if;
|
||||
|
||||
commit;
|
||||
end loop;
|
||||
|
||||
raise notice 'limit10 min/avg/max: % ms / % ms / % ms',
|
||||
round(min_limit, 3), round(total_limit / iterations, 3), round(max_limit, 3);
|
||||
|
||||
raise notice 'count all min/avg/max: % ms / % ms / % ms',
|
||||
round(min_count, 3), round(total_count / iterations, 3), round(max_count, 3);
|
||||
end $$;
|
||||
--//
|
||||
|
||||
@@ -229,6 +229,12 @@ databaseChangeLog:
|
||||
- include:
|
||||
file: db/changelog/9-hs-global/950-accounts/9519-hs-accounts-test-data.sql
|
||||
context: "!only-prod-schema and !without-test-data"
|
||||
- include:
|
||||
file: db/changelog/9-hs-global/9520-hs-mass-test-data-generators.sql
|
||||
context: "!only-prod-schema and !without-test-data"
|
||||
- include:
|
||||
file: db/changelog/9-hs-global/9521-has-mass-test-data-performance.sql
|
||||
context: "!only-prod-schema and !without-test-data"
|
||||
|
||||
- include:
|
||||
file: db/changelog/9-hs-global/960-integrations/9600-hs-integration-schema.sql
|
||||
|
||||
Reference in New Issue
Block a user