# Generated by Django 2.2.7 on 2019-12-16 15:06

import django.contrib.postgres.search
import django.contrib.postgres.indexes
from django.db import migrations, models
import django.db.models.deletion
from django.db import connection

FIELDS = {
    "music.Artist": {
        "fields": [
            'name',
        ],
        "trigger_name": "music_artist_update_body_text"
    },
    "music.Track": {
        "fields": ['title', 'copyright'],
        "trigger_name": "music_track_update_body_text"
    },
    "music.Album": {
        "fields": ['title'],
        "trigger_name": "music_album_update_body_text"
    },
}

def populate_body_text(apps, schema_editor):
    for label, search_config in FIELDS.items():
        model = apps.get_model(*label.split('.'))
        print('Populating search index for {}…'.format(model.__name__))
        vector = django.contrib.postgres.search.SearchVector(*search_config['fields'])
        model.objects.update(body_text=vector)

def rewind(apps, schema_editor):
    pass

def setup_triggers(apps, schema_editor):
    cursor = connection.cursor()
    for label, search_config in FIELDS.items():
        model = apps.get_model(*label.split('.'))
        table = model._meta.db_table
        print('Creating database trigger {} on {}…'.format(search_config['trigger_name'], table))
        sql = """
            CREATE TRIGGER {trigger_name}
                BEFORE INSERT OR UPDATE
                ON {table}
                FOR EACH ROW
                EXECUTE PROCEDURE
                    tsvector_update_trigger(body_text, 'pg_catalog.english', {fields})
        """.format(
            trigger_name=search_config['trigger_name'],
            table=table,
            fields=', '.join(search_config['fields']),
        )
        print(sql)
        cursor.execute(sql)

def rewind_triggers(apps, schema_editor):
    cursor = connection.cursor()
    for label, search_config in FIELDS.items():
        model = apps.get_model(*label.split('.'))
        table = model._meta.db_table
        print('Dropping database trigger {} on {}…'.format(search_config['trigger_name'], table))
        sql = """
            DROP TRIGGER IF EXISTS {trigger_name} ON {table}
        """.format(
            trigger_name=search_config['trigger_name'],
            table=table,
        )

        cursor.execute(sql)

class Migration(migrations.Migration):

    dependencies = [
        ('music', '0043_album_cover_attachment'),
    ]

    operations = [
        migrations.AddField(
            model_name='album',
            name='body_text',
            field=django.contrib.postgres.search.SearchVectorField(blank=True),
        ),
        migrations.AddField(
            model_name='artist',
            name='body_text',
            field=django.contrib.postgres.search.SearchVectorField(blank=True),
        ),
        migrations.AddField(
            model_name='track',
            name='body_text',
            field=django.contrib.postgres.search.SearchVectorField(blank=True),
        ),
        migrations.AddIndex(
            model_name='album',
            index=django.contrib.postgres.indexes.GinIndex(fields=['body_text'], name='music_album_body_te_0ec97a_gin'),
        ),
        migrations.AddIndex(
            model_name='artist',
            index=django.contrib.postgres.indexes.GinIndex(fields=['body_text'], name='music_artis_body_te_5c408d_gin'),
        ),
        migrations.AddIndex(
            model_name='track',
            index=django.contrib.postgres.indexes.GinIndex(fields=['body_text'], name='music_track_body_te_da0a66_gin'),
        ),

        migrations.RunPython(setup_triggers, rewind_triggers),
        migrations.RunPython(populate_body_text, rewind),
    ]
