Skip to content

Commit

Permalink
Split migrations
Browse files Browse the repository at this point in the history
- move create publication to core
- use ivm entries for the nutrition publications
  • Loading branch information
rolandgeider committed Sep 25, 2024
1 parent aec1246 commit 8a6c2b4
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 35 deletions.
48 changes: 48 additions & 0 deletions wger/core/migrations/0018_create_publication_add_ivm_extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Generated by Django 4.2.13 on 2024-09-19 13:43

from django.db import migrations

from wger.utils.db import postgres_only


@postgres_only
def add_publication(apps, schema_editor):
# Note that "FOR ALL TABLES" applies for all tables created in the future as well
schema_editor.execute(
"""
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_publication WHERE pubname = 'powersync'
) THEN
CREATE PUBLICATION powersync FOR ALL TABLES;
END IF;
END $$;
"""
)


@postgres_only
def remove_publication(apps, schema_editor):
schema_editor.execute('DROP PUBLICATION IF EXISTS powersync;')


@postgres_only
def add_ivm_extension(apps, schema_editor):
schema_editor.execute('CREATE EXTENSION IF NOT EXISTS pg_ivm;')


@postgres_only
def remove_ivm_extension(apps, schema_editor):
schema_editor.execute('DROP EXTENSION IF EXISTS pg_ivm;')


class Migration(migrations.Migration):
dependencies = [
('core', '0017_language_full_name_en'),
]

operations = [
migrations.RunPython(add_publication, reverse_code=remove_publication),
migrations.RunPython(add_ivm_extension, reverse_code=remove_ivm_extension),
]
69 changes: 69 additions & 0 deletions wger/nutrition/migrations/0025_create_ivm_entries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from django.db import migrations

from wger.utils.db import postgres_only


@postgres_only
def add_ivm_views(apps, schema_editor):
"""
Note: the select statements are written a bit weirdly because of this issue
https://github.com/sraoss/pg_ivm/issues/85
When this is resolved, we can remove the subqueries and write e.g.
SELECT m.*, p.user_id
FROM nutrition_meal AS m
JOIN nutrition_nutritionplan AS p ON m.plan_id = p.id;
"""

schema_editor.execute(
"""
SELECT create_immv(
'ivm_nutrition_meal',
'SELECT m.*, p.user_id
FROM (SELECT * FROM nutrition_meal) AS m
JOIN (SELECT id, user_id FROM nutrition_nutritionplan) AS p ON m.plan_id = p.id;'
);
"""
)

schema_editor.execute(
"""
SELECT create_immv(
'ivm_nutrition_mealitem',
'SELECT mi.*, p.user_id
FROM (SELECT * FROM nutrition_mealitem) AS mi
JOIN (SELECT id, plan_id FROM nutrition_meal) AS m ON mi.meal_id = m.id
JOIN (SELECT id, user_id FROM nutrition_nutritionplan) AS p ON m.plan_id = p.id;'
);
"""
)

schema_editor.execute(
"""
SELECT create_immv(
'ivm_nutrition_logitem',
'SELECT li.*, p.user_id
FROM (SELECT * FROM nutrition_logitem) AS li
JOIN (SELECT id, user_id FROM nutrition_nutritionplan) AS p ON li.plan_id = p.id;'
);
"""
)


@postgres_only
def remove_ivm_views(apps, schema_editor):
schema_editor.execute('DROP TABLE IF EXISTS ivm_nutrition_mealitem;')
schema_editor.execute('DROP TABLE IF EXISTS ivm_nutrition_meal;')
schema_editor.execute('DROP TABLE IF EXISTS ivm_nutrition_logitem;')


class Migration(migrations.Migration):
dependencies = [
('nutrition', '0024_remove_ingredient_status'),
('core', '0018_create_publication_add_ivm_extension'),
]

operations = [
migrations.RunPython(add_ivm_views, reverse_code=remove_ivm_views),
]
35 changes: 0 additions & 35 deletions wger/nutrition/migrations/0025_create_publication.py

This file was deleted.

16 changes: 16 additions & 0 deletions wger/utils/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,25 @@
#
# You should have received a copy of the GNU Affero General Public License

# Standard Library
from functools import wraps

# Django
from django.conf import settings


def is_postgres_db():
return 'postgres' in settings.DATABASES['default']['ENGINE']


def postgres_only(func):
"""Decorator that runs the decorated function only if the database is PostgreSQL."""

@wraps(func)
def wrapper(*args, **kwargs):
if is_postgres_db():
return func(*args, **kwargs)
else:
return

return wrapper

0 comments on commit 8a6c2b4

Please sign in to comment.