luckyframework / luckyframework/avram
Consider adding counter cache functionality that uses triggers
Nobody has claimed this yet.
- Dominant language
- Crystal
- Stars
- 183
- Forks
- 67
- PR merge metrics
- No merged PRs in 30d
Description
`Triggered` by #337.
This may be something that should be its own shard. I've considered creating a shard for this, but I thought it would be good to discuss it here first.
I have a couple counter caches in my app that are implemented with triggers. The migrations are definitely a little hairy and it would be nice to be able to just say something like:
```crystal
def migrate
alter table_for(Comments) do
add_counter_cache like_count : Int64, count_table: :likes, foreign_key: comment_id
end
end
def rollback
alter table_for(Comments) do
remove_counter_cache :like_count, count_table: :likes, foreign_key: comment_id
end
end
```
Here's some actual code to create a counter cache trigger. There's a lot of boilerplate in there:
```crystal
def migrate
execute <<-SQL
CREATE FUNCTION maintain_campaign_call_count_trg() RETURNS TRIGGER AS
$$
BEGIN
IF TG_OP IN ('UPDATE', 'DELETE') THEN
UPDATE campaigns SET call_count = call_count - 1 WHERE id = old.campaign_id;
END IF;
IF TG_OP IN ('INSERT', 'UPDATE') THEN
UPDATE campaigns SET call_count = call_count + 1 WHERE id = new.campaign_id;
END IF;
RETURN NULL;
END
$$
LANGUAGE plpgsql;
SQL
execute <<-SQL
CREATE TRIGGER maintain_campaign_call_count
AFTER INSERT OR UPDATE OF campaign_id OR DELETE ON calls
FOR EACH ROW
EXECUTE PROCEDURE maintain_campaign_call_count_trg();
SQL
execute <<-SQL
CREATE FUNCTION maintain_campaign_call_count_after_truncate_trg() RETURNS TRIGGER AS
$$
BEGIN
UPDATE campaigns SET call_count = 0;
RETURN NULL;
END
$$
LANGUAGE plpgsql;
SQL
execute <<-SQL
CREATE TRIGGER maintain_campaign_call_count_after_truncate
AFTER TRUNCATE ON calls
EXECUTE PROCEDURE maintain_campaign_call_count_after_truncate_trg();
SQL
end
def rollback
execute "DROP TRIGGER maintain_campaign_call_count ON calls;"
execute "DROP FUNCTION maintain_campaign_call_count_trg();"
execute "DROP TRIGGER maintain_campaign_call_count_after_truncate ON calls;"
execute "DROP FUNCTION maintain_campaign_call_count_after_truncate_trg();"
end
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The issue names migration entry points using alter table_for, add_counter_cache, remove_counter_cache, and raw execute SQL, but no repository files or tests. Start by locating those migration APIs and reviewing the PostgreSQL trigger examples; done would require an agreed scope and verified migration and rollback behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- crystal, postgresql
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100