Skip to content

Commit 46c65c5

Browse files
Merge pull request #8274 from carlobeltrame/shared-camps-better-performance
Add isPublic field for query performance
2 parents 779d177 + 4bad327 commit 46c65c5

30 files changed

+122
-271
lines changed

api/fixtures/camps.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ App\Entity\Camp:
5454
addressCity: <city()>
5555
owner: '@admin'
5656
creator: '@admin'
57+
isPublic: true
5758
isPrototype: true
5859
isShared: false
5960
sharedBy: null
@@ -69,6 +70,7 @@ App\Entity\Camp:
6970
addressCity: <city()>
7071
owner: '@admin'
7172
creator: '@admin'
73+
isPublic: true
7274
isPrototype: false
7375
isShared: true
7476
sharedBy: '@admin'
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20251004093025 extends AbstractMigration {
14+
public function getDescription(): string {
15+
return '';
16+
}
17+
18+
public function up(Schema $schema): void {
19+
// this up() migration is auto-generated, please modify it to your needs
20+
$this->addSql('ALTER TABLE camp ADD isPublic BOOLEAN DEFAULT false NOT NULL');
21+
$this->addSql('UPDATE camp SET isPublic = (isShared OR isPrototype)');
22+
$this->addSql('ALTER TABLE camp ADD CONSTRAINT enforce_public_flag CHECK (isPublic = (isShared OR isPrototype))');
23+
$this->addSql('CREATE INDEX IDX_C1944230FADC24C7 ON camp (isPublic)');
24+
$this->addSql(
25+
<<<'EOF'
26+
CREATE OR REPLACE VIEW public.view_user_camps
27+
AS
28+
SELECT CONCAT(u.id, c.id) id, u.id userid, c.id campid
29+
from camp c, "user" u
30+
where c.ispublic = TRUE
31+
union all
32+
select cc.id, cc.userid, cc.campid
33+
from camp_collaboration cc
34+
where cc.status = 'established'
35+
EOF
36+
);
37+
}
38+
39+
public function down(Schema $schema): void {
40+
// this down() migration is auto-generated, please modify it to your needs
41+
$this->addSql(
42+
<<<'EOF'
43+
CREATE OR REPLACE VIEW public.view_user_camps
44+
AS
45+
SELECT CONCAT(u.id, c.id) id, u.id userid, c.id campid
46+
from camp c, "user" u
47+
where c.isprototype = TRUE or c.isshared = TRUE
48+
union all
49+
select cc.id, cc.userid, cc.campid
50+
from camp_collaboration cc
51+
where cc.status = 'established'
52+
EOF
53+
);
54+
$this->addSql('DROP INDEX IDX_C1944230FADC24C7');
55+
$this->addSql('ALTER TABLE camp DROP CONSTRAINT enforce_public_flag');
56+
$this->addSql('ALTER TABLE camp DROP isPublic');
57+
}
58+
}

api/src/Entity/Activity.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@
3333
new Get(
3434
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
3535
security: 'is_granted("CAMP_COLLABORATOR", object) or
36-
is_granted("CAMP_IS_SHARED", object) or
37-
is_granted("CAMP_IS_PROTOTYPE", object)'
36+
is_granted("CAMP_IS_PUBLIC", object)'
3837
),
3938
new Patch(
4039
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
@@ -56,8 +55,7 @@
5655
toProperty: 'camp',
5756
fromClass: Camp::class,
5857
security: 'is_granted("CAMP_COLLABORATOR", camp) or
59-
is_granted("CAMP_IS_SHARED", camp) or
60-
is_granted("CAMP_IS_PROTOTYPE", camp)'
58+
is_granted("CAMP_IS_PUBLIC", camp)'
6159
),
6260
],
6361
normalizationContext: self::COLLECTION_NORMALIZATION_CONTEXT,

api/src/Entity/ActivityProgressLabel.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
new Get(
3131
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
3232
security: 'is_granted("CAMP_COLLABORATOR", object) or
33-
is_granted("CAMP_IS_SHARED", object) or
34-
is_granted("CAMP_IS_PROTOTYPE", object)'
33+
is_granted("CAMP_IS_PUBLIC", object)'
3534
),
3635
new Patch(
3736
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
@@ -53,8 +52,7 @@
5352
toProperty: 'camp',
5453
fromClass: Camp::class,
5554
security: 'is_granted("CAMP_COLLABORATOR", camp) or
56-
is_granted("CAMP_IS_SHARED", camp) or
57-
is_granted("CAMP_IS_PROTOTYPE", camp)'
55+
is_granted("CAMP_IS_PUBLIC", camp)'
5856
),
5957
],
6058
security: 'is_fully_authenticated()',

api/src/Entity/ActivityResponsible.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#[ApiResource(
2424
operations: [
2525
new Get(
26-
security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_SHARED", object) or is_granted("CAMP_IS_PROTOTYPE", object)'
26+
security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_PUBLIC", object)'
2727
),
2828
new Delete(
2929
security: 'is_granted("CAMP_MEMBER", object) or is_granted("CAMP_MANAGER", object)'

api/src/Entity/Camp.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
operations: [
3636
new Get(
3737
security: 'is_granted("CAMP_COLLABORATOR", object) or
38-
is_granted("CAMP_IS_SHARED", object) or
39-
is_granted("CAMP_IS_PROTOTYPE", object)',
38+
is_granted("CAMP_IS_PUBLIC", object)',
4039
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
4140
),
4241
new Patch(
@@ -69,6 +68,7 @@
6968
#[ORM\Entity(repositoryClass: CampRepository::class)]
7069
#[ORM\Index(columns: ['isPrototype'])]
7170
#[ORM\Index(columns: ['isShared'])]
71+
#[ORM\Index(columns: ['isPublic'])]
7272
#[ORM\Index(columns: ['updateTime'])] // TODO unclear why this is necessary, but doctrine forgot about this index from BaseEntity...
7373
class Camp extends BaseEntity implements BelongsToCampInterface, CopyFromPrototypeInterface {
7474
public const ITEM_NORMALIZATION_CONTEXT = [
@@ -228,6 +228,14 @@ class Camp extends BaseEntity implements BelongsToCampInterface, CopyFromPrototy
228228
#[ORM\Column(type: 'boolean')]
229229
public bool $isPrototype = false;
230230

231+
/**
232+
* Automatically set to the value (isShared || isPrototype). Used for more efficient
233+
* database filtering operations, since OR queries are very expensive to compute.
234+
* This is only used in the database, and therefore not available on the API.
235+
*/
236+
#[ORM\Column(type: 'boolean', nullable: false, options: ['default' => false])]
237+
public bool $isPublic = false;
238+
231239
/**
232240
* An optional short title for the camp. Can be used in the UI where space is tight. If
233241
* not present, frontends may auto-shorten the title if the shortTitle is not set.

api/src/Entity/CampCollaboration.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
operations: [
3636
new Get(
3737
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
38-
security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_SHARED", object) or is_granted("CAMP_IS_PROTOTYPE", object)'
38+
security: 'is_granted("CAMP_COLLABORATOR", object) or is_granted("CAMP_IS_PUBLIC", object)'
3939
),
4040
new Patch(
4141
processor: CampCollaborationUpdateProcessor::class,
@@ -68,8 +68,7 @@
6868
toProperty: 'camp',
6969
fromClass: Camp::class,
7070
security: 'is_granted("CAMP_COLLABORATOR", camp) or
71-
is_granted("CAMP_IS_SHARED", camp) or
72-
is_granted("CAMP_IS_PROTOTYPE", camp)'
71+
is_granted("CAMP_IS_PUBLIC", camp)'
7372
),
7473
],
7574
security: 'is_fully_authenticated()',

api/src/Entity/Category.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@
3636
new Get(
3737
normalizationContext: self::ITEM_NORMALIZATION_CONTEXT,
3838
security: 'is_granted("CAMP_COLLABORATOR", object) or
39-
is_granted("CAMP_IS_SHARED", object) or
40-
is_granted("CAMP_IS_PROTOTYPE", object)'
39+
is_granted("CAMP_IS_PUBLIC", object)'
4140
),
4241
new Patch(
4342
denormalizationContext: ['groups' => ['write', 'update']],
@@ -66,8 +65,7 @@
6665
fromClass: Camp::class,
6766
toProperty: 'camp',
6867
security: 'is_granted("CAMP_COLLABORATOR", camp) or
69-
is_granted("CAMP_IS_SHARED", camp) or
70-
is_granted("CAMP_IS_PROTOTYPE", camp)'
68+
is_granted("CAMP_IS_PUBLIC", camp)'
7169
),
7270
],
7371
extraProperties: [

api/src/Entity/Checklist.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@
3030
operations: [
3131
new Get(
3232
security: 'is_granted("CHECKLIST_IS_PROTOTYPE", object) or
33-
is_granted("CAMP_IS_PROTOTYPE", object) or
34-
is_granted("CAMP_IS_SHARED", object) or
33+
is_granted("CAMP_IS_PUBLIC", object) or
3534
is_granted("CAMP_COLLABORATOR", object)
3635
'
3736
),
@@ -64,8 +63,7 @@
6463
toProperty: 'camp',
6564
fromClass: Camp::class,
6665
security: 'is_granted("CAMP_COLLABORATOR", camp) or
67-
is_granted("CAMP_IS_SHARED", camp) or
68-
is_granted("CAMP_IS_PROTOTYPE", camp)'
66+
is_granted("CAMP_IS_PUBLIC", camp)'
6967
),
7068
],
7169
extraProperties: [

api/src/Entity/ChecklistItem.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@
3333
operations: [
3434
new Get(
3535
security: 'is_granted("CHECKLIST_IS_PROTOTYPE", object) or
36-
is_granted("CAMP_IS_PROTOTYPE", object) or
37-
is_granted("CAMP_IS_SHARED", object) or
36+
is_granted("CAMP_IS_PUBLIC", object) or
3837
is_granted("CAMP_COLLABORATOR", object)
3938
'
4039
),
@@ -65,8 +64,7 @@
6564
fromClass: Checklist::class,
6665
toProperty: 'checklist',
6766
security: 'is_granted("CHECKLIST_IS_PROTOTYPE", checklist) or
68-
is_granted("CAMP_IS_PROTOTYPE", checklist) or
69-
is_granted("CAMP_IS_SHARED", checklist) or
67+
is_granted("CAMP_IS_PUBLIC", checklist) or
7068
is_granted("CAMP_COLLABORATOR", checklist)'
7169
),
7270
],

0 commit comments

Comments
 (0)