|
1 |
# Generated by Django 2.2.17 on 2021-01-25 13:21
|
|
2 |
|
|
3 |
from __future__ import unicode_literals
|
|
4 |
|
|
5 |
from django.db import migrations, transaction
|
|
6 |
from django.db.migrations.operations.base import Operation
|
|
7 |
from django.db.utils import InternalError, OperationalError, ProgrammingError
|
|
8 |
|
|
9 |
|
|
10 |
class SafeExtensionOperation(Operation):
|
|
11 |
reversible = True
|
|
12 |
|
|
13 |
def state_forwards(self, app_label, state):
|
|
14 |
pass
|
|
15 |
|
|
16 |
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
|
17 |
if schema_editor.connection.vendor != 'postgresql':
|
|
18 |
return
|
|
19 |
try:
|
|
20 |
with transaction.atomic():
|
|
21 |
try:
|
|
22 |
schema_editor.execute('CREATE EXTENSION IF NOT EXISTS %s SCHEMA public' % self.name)
|
|
23 |
except (OperationalError, ProgrammingError):
|
|
24 |
# OperationalError if the extension is not available
|
|
25 |
# ProgrammingError in case of denied permission
|
|
26 |
RunSQLIfExtension.extensions_installed = False
|
|
27 |
except InternalError:
|
|
28 |
# InternalError (current transaction is aborted, commands ignored
|
|
29 |
# until end of transaction block) would be raised when django-
|
|
30 |
# tenant-schemas set search_path.
|
|
31 |
RunSQLIfExtension.extensions_installed = False
|
|
32 |
|
|
33 |
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
|
34 |
try:
|
|
35 |
with transaction.atomic():
|
|
36 |
schema_editor.execute('DROP EXTENSION IF EXISTS %s' % self.name)
|
|
37 |
except InternalError:
|
|
38 |
# Raised when other objects depend on the extension. This happens in a multitenant
|
|
39 |
# context, where extension in installed in schema "public" but referenced in others (via
|
|
40 |
# public.gist_trgm_ops). In this case, do nothing, as the query should be successful
|
|
41 |
# when last tenant is processed.
|
|
42 |
pass
|
|
43 |
|
|
44 |
|
|
45 |
class RunSQLIfExtension(migrations.RunSQL):
|
|
46 |
extensions_installed = True
|
|
47 |
|
|
48 |
def __getattribute__(self, name):
|
|
49 |
if name == 'sql' and not self.extensions_installed:
|
|
50 |
return migrations.RunSQL.noop
|
|
51 |
return object.__getattribute__(self, name)
|
|
52 |
|
|
53 |
|
|
54 |
class UnaccentExtension(SafeExtensionOperation):
|
|
55 |
name = 'unaccent'
|
|
56 |
|
|
57 |
|
|
58 |
class TrigramExtension(SafeExtensionOperation):
|
|
59 |
name = 'pg_trgm'
|
|
60 |
|
|
61 |
|
|
62 |
class Migration(migrations.Migration):
|
|
63 |
|
|
64 |
dependencies = [
|
|
65 |
('authentic2', '0032_initialize_search_vectors'),
|
|
66 |
]
|
|
67 |
|
|
68 |
operations = [
|
|
69 |
TrigramExtension(),
|
|
70 |
UnaccentExtension(),
|
|
71 |
RunSQLIfExtension(
|
|
72 |
sql=["CREATE OR REPLACE FUNCTION public.immutable_unaccent(text) RETURNS varchar AS $$ "
|
|
73 |
"SELECT public.unaccent('public.unaccent',$1::text); $$ LANGUAGE 'sql' IMMUTABLE"],
|
|
74 |
reverse_sql=[],
|
|
75 |
),
|
|
76 |
RunSQLIfExtension(
|
|
77 |
sql=["CREATE INDEX IF NOT EXISTS custom_user_name_gist_idx ON custom_user_user USING gist "
|
|
78 |
"(LOWER(public.immutable_unaccent(first_name || ' ' || last_name)) public.gist_trgm_ops)"],
|
|
79 |
reverse_sql=[],
|
|
80 |
),
|
|
81 |
]
|
0 |
|
-
|