diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-03-06 16:53:10 +0100 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2017-03-06 16:53:10 +0100 | 
| commit | 67208dbd830ce4eb75d77f59d1ffd31c63b19d80 (patch) | |
| tree | cff73359a85d362bd3b24f853fb6d461a583b91b /archaeological_finds/models_finds.py | |
| parent | 161d29195cb9719b9c6ae4903c2c526f797bdf5f (diff) | |
| parent | ad5d9f7c0d5b0ca5a0ba76e279fc5d6e2683216a (diff) | |
| download | Ishtar-67208dbd830ce4eb75d77f59d1ffd31c63b19d80.tar.bz2 Ishtar-67208dbd830ce4eb75d77f59d1ffd31c63b19d80.zip  | |
Merge branch 'master' into v0.9
Diffstat (limited to 'archaeological_finds/models_finds.py')
| -rw-r--r-- | archaeological_finds/models_finds.py | 268 | 
1 files changed, 253 insertions, 15 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 8f0270236..bf5ba6380 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -22,6 +22,7 @@ import datetime  from django.conf import settings  from django.contrib.gis.db import models  from django.core.urlresolvers import reverse +from django.db import connection, transaction  from django.db.models import Max, Q  from django.db.models.signals import m2m_changed, post_save, post_delete  from django.utils.translation import ugettext_lazy as _, ugettext @@ -126,6 +127,26 @@ post_save.connect(post_save_cache, sender=ObjectType)  post_delete.connect(post_save_cache, sender=ObjectType) +class BFBulkView(object): +    CREATE_SQL = """ +        CREATE VIEW basefind_cached_bulk_update +        AS ( +            SELECT bf.id AS id, ope.code_patriarche AS main_ope_code, +                ope.year AS year, +                ope.operation_code AS ope_code, +                cr.label AS cr_label, +                bf.index AS index +            FROM archaeological_finds_basefind bf +            INNER JOIN archaeological_context_records_contextrecord cr +                ON cr.id = bf.context_record_id +            INNER JOIN archaeological_operations_operation ope +                ON ope.id = cr.operation_id +        );""" +    DELETE_SQL = """ +        DROP VIEW basefind_cached_bulk_update; +    """ + +  class BaseFind(BaseHistorizedItem, OwnPerms):      label = models.TextField(_(u"Free ID"))      external_id = models.TextField(_(u"External ID"), blank=True, null=True) @@ -199,34 +220,45 @@ class BaseFind(BaseHistorizedItem, OwnPerms):              return q.aggregate(Max('index'))['index__max']          return 0 -    def complete_id(self): -        # OPE|MAT.CODE|UE|FIND_index +    def _ope_code(self):          if not self.context_record.operation: -            return -        # find = self.get_last_find() +            return ''          ope = self.context_record.operation -        c_id = [unicode(ope.code_patriarche) if ope.code_patriarche else -                (unicode(ope.year) + "-" + unicode(ope.operation_code))] +        c_id = [] +        if ope.code_patriarche: +            c_id.append(settings.ISHTAR_OPE_PREFIX + +                        unicode(ope.code_patriarche)) +        elif ope.year and ope.operation_code: +            c_id.append( +                settings.ISHTAR_DEF_OPE_PREFIX + +                unicode(ope.year or '') + u"-" + +                unicode(ope.operation_code or '')) +        else: +            c_id.append('') +        return settings.JOINT.join(c_id) + +    def complete_id(self): +        # OPE|MAT.CODE|UE|FIND_index +        c_id = [self._ope_code()] +          materials = set()          for find in self.find.filter(downstream_treatment__isnull=True):              for mat in find.material_types.all():                  if mat.code:                      materials.add(mat.code)          c_id.append(u'-'.join(sorted(list(materials)))) +          c_id.append(self.context_record.label) -        max_index = str(self.get_max_index(ope)) -        c_id.append((u'{:0' + str(len(max_index)) + 'd}').format(self.index)) + +        c_id.append((u'{:0' + str(settings.ISHTAR_FINDS_INDEX_ZERO_LEN) + 'd}' +                     ).format(self.index))          return settings.JOINT.join(c_id)      def short_id(self):          # OPE|FIND_index -        if not self.context_record.operation: -            return -        ope = self.context_record.operation -        c_id = [(ope.code_patriarche and unicode(ope.code_patriarche)) or -                (unicode(ope.year) + "-" + unicode(ope.operation_code))] -        max_index = str(self.get_max_index(ope)) -        c_id.append((u'{:0' + str(len(max_index)) + 'd}').format(self.index)) +        c_id = [self._ope_code()] +        c_id.append((u'{:0' + str(settings.ISHTAR_FINDS_INDEX_ZERO_LEN) + 'd}' +                     ).format(self.index))          return settings.JOINT.join(c_id)      def full_label(self): @@ -290,6 +322,108 @@ class BaseFind(BaseHistorizedItem, OwnPerms):              self.save()          return returned +    @classmethod +    def cached_label_bulk_update(cls, operation_id=None, parcel_id=None): +        if operation_id: +            filters = """ +            INNER JOIN archaeological_context_records_contextrecord acr +            ON acr.operation_id = %s AND acr.id = mybf.context_record_id +            """ +            args = [int(operation_id)] +            kwargs = {'operation_id': operation_id} +        elif parcel_id: +            filters = """ +            INNER JOIN archaeological_context_records_contextrecord acr +            ON acr.parcel_id = %s AND acr.id = mybf.context_record_id +            """ +            args = [int(parcel_id)] +            kwargs = {'parcel_id': parcel_id} +        else: +            return + +        sql = """ +        UPDATE "archaeological_finds_basefind" AS bf +            SET cache_short_id = +                CASE +                WHEN basefind_cached_bulk_update.main_ope_code is NULL +                THEN +                    CASE +                    WHEN basefind_cached_bulk_update.year +                            IS NOT NULL +                        AND basefind_cached_bulk_update.ope_code +                            IS NOT NULL +                    THEN +                       '{ope_prefix}' || +                       basefind_cached_bulk_update.year || +                       '-' || +                       basefind_cached_bulk_update.ope_code +                    ELSE '' +                    END +                ELSE +                    '{main_ope_prefix}' || +                    basefind_cached_bulk_update.main_ope_code +                END +                || '{join}' || +                to_char(basefind_cached_bulk_update.index, 'fm{zeros}'), + +            cache_complete_id = +                CASE +                WHEN basefind_cached_bulk_update.main_ope_code IS NULL +                THEN +                    CASE +                    WHEN basefind_cached_bulk_update.year +                            IS NOT NULL +                        AND basefind_cached_bulk_update.ope_code +                            IS NOT NULL +                    THEN +                       '{ope_prefix}' || +                       basefind_cached_bulk_update.year || +                       '-' || +                       basefind_cached_bulk_update.ope_code +                    ELSE '' +                    END +                ELSE +                    '{main_ope_prefix}' || +                    basefind_cached_bulk_update.main_ope_code +                END +                || '{join}' || + +                COALESCE( +                (SELECT string_agg(code, '-') FROM +                 (SELECT DISTINCT mt.code AS code FROM +                    archaeological_finds_find_material_types fmt +                    INNER JOIN archaeological_finds_find f +                     ON f.id=fmt.find_id AND f.downstream_treatment_id IS NULL +                    INNER JOIN find_first_base_find fbf +                     ON fbf.find_id = f.id AND +                        basefind_cached_bulk_update.id = fbf.basefind_id +                    INNER JOIN archaeological_finds_materialtype mt +                     ON mt.id = fmt.materialtype_id ORDER BY mt.code) +                  as ag), +                 '-') + +                || '{join}' || +                basefind_cached_bulk_update.cr_label +                || '{join}' || +                to_char(basefind_cached_bulk_update.index, 'fm{zeros}') + +            FROM basefind_cached_bulk_update +            WHERE bf.id = basefind_cached_bulk_update.id +                    AND bf.id IN ( +                SELECT mybf.id FROM archaeological_finds_basefind mybf +                {filters} +            ); +        """.format(main_ope_prefix=settings.ISHTAR_OPE_PREFIX, +                   ope_prefix=settings.ISHTAR_DEF_OPE_PREFIX, +                   join=settings.JOINT, filters=filters, +                   zeros=settings.ISHTAR_FINDS_INDEX_ZERO_LEN * "0") +        # with connection.cursor() as c:  # django 1.8 +        c = connection.cursor() +        c.execute(sql, args) +        transaction.commit_unless_managed() +        cls._meta.get_field_by_name( +            'find')[0].model.cached_label_bulk_update(**kwargs) +  post_save.connect(post_save_point, sender=BaseFind) @@ -307,6 +441,42 @@ class FindBasket(Basket):                                     related_name='basket') +class FirstBaseFindView(object): +    CREATE_SQL = """ +    CREATE VIEW find_first_base_find +    AS ( +        SELECT find_id, min(basefind_id) as basefind_id +            FROM archaeological_finds_find_base_finds GROUP BY find_id +    );""" +    DELETE_SQL = """ +        DROP VIEW find_first_base_find; +    """ + + +class FBulkView(object): +    CREATE_SQL = """ +        CREATE VIEW find_cached_bulk_update +        AS ( +            SELECT f.id AS id, ope.code_patriarche AS main_ope_code, +                ope.year AS year, +                ope.operation_code AS ope_code, +                f.label AS label, +                f.index AS index +            FROM archaeological_finds_find f +            INNER JOIN find_first_base_find fbf +                ON fbf.find_id = f.id +            INNER JOIN archaeological_finds_basefind bf +                ON fbf.basefind_id = bf.id +            INNER JOIN archaeological_context_records_contextrecord cr +                ON cr.id = bf.context_record_id +            INNER JOIN archaeological_operations_operation ope +                ON ope.id = cr.operation_id +        );""" +    DELETE_SQL = """ +        DROP VIEW find_cached_bulk_update; +    """ + +  class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):      CHECK_DICT = dict(CHECK_CHOICES)      SHOW_URL = 'show-find' @@ -707,6 +877,74 @@ class Find(BaseHistorizedItem, ImageModel, OwnPerms, ShortMenuItem):      def _generate_cached_label(self):          return unicode(self) +    @classmethod +    def cached_label_bulk_update(cls, operation_id=None, parcel_id=None): +        if operation_id: +            filters = """ +            INNER JOIN find_first_base_find myfbf +                ON myfbf.find_id = myf.id +            INNER JOIN archaeological_finds_basefind mybf +                ON myfbf.basefind_id = mybf.id +            INNER JOIN archaeological_context_records_contextrecord acr +            ON acr.operation_id = %s AND acr.id = mybf.context_record_id +            """ +            args = [int(operation_id)] +        elif parcel_id: +            filters = """ +            INNER JOIN find_first_base_find myfbf +                ON myfbf.find_id = myf.id +            INNER JOIN archaeological_finds_basefind mybf +                ON myfbf.basefind_id = mybf.id +            INNER JOIN archaeological_context_records_contextrecord acr +            ON acr.parcel_id = %s AND acr.id = mybf.context_record_id +            """ +            args = [int(parcel_id)] +        else: +            return + +        sql = """ +        UPDATE "archaeological_finds_find" AS f +            SET cached_label = +                CASE +                WHEN find_cached_bulk_update.main_ope_code is NULL +                THEN +                    CASE +                    WHEN find_cached_bulk_update.year +                            IS NOT NULL +                        AND find_cached_bulk_update.ope_code +                            IS NOT NULL +                    THEN +                       '{ope_prefix}' || +                       find_cached_bulk_update.year || +                       '-' || +                       find_cached_bulk_update.ope_code +                    ELSE '' +                    END +                ELSE +                    '{main_ope_prefix}' || +                    find_cached_bulk_update.main_ope_code +                END +                || '-' || +                to_char(find_cached_bulk_update.index, 'fm{zeros}') +                || '{join}' || +                find_cached_bulk_update.label + + +            FROM find_cached_bulk_update +            WHERE f.id = find_cached_bulk_update.id +                    AND f.id IN ( +                SELECT myf.id FROM archaeological_finds_find myf +                {filters} +            ); +        """.format(main_ope_prefix=settings.ISHTAR_OPE_PREFIX, +                   ope_prefix=settings.ISHTAR_DEF_OPE_PREFIX, +                   join=settings.JOINT, filters=filters, +                   zeros=settings.ISHTAR_FINDS_INDEX_ZERO_LEN * "0") +        # with connection.cursor() as c:  # django 1.8 +        c = connection.cursor() +        c.execute(sql, args) +        transaction.commit_unless_managed() +      def save(self, *args, **kwargs):          super(Find, self).save(*args, **kwargs)  | 
