summaryrefslogtreecommitdiff
path: root/archaeological_finds/models_finds.py
diff options
context:
space:
mode:
Diffstat (limited to 'archaeological_finds/models_finds.py')
-rw-r--r--archaeological_finds/models_finds.py262
1 files changed, 247 insertions, 15 deletions
diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py
index 8f0270236..e99b43bc7 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,104 @@ 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 basefind_cached_bulk_update.main_ope_code
+ WHEN NULL THEN
+ CASE basefind_cached_bulk_update.year
+ IS NOT NULL
+ AND basefind_cached_bulk_update.ope_code
+ IS NOT NULL
+ WHEN TRUE 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 basefind_cached_bulk_update.main_ope_code
+ WHEN NULL THEN
+ CASE basefind_cached_bulk_update.year
+ IS NOT NULL
+ AND basefind_cached_bulk_update.ope_code
+ IS NOT NULL
+ WHEN TRUE 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 +437,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 +873,72 @@ 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 find_cached_bulk_update.main_ope_code
+ WHEN NULL THEN
+ CASE find_cached_bulk_update.year
+ IS NOT NULL
+ AND find_cached_bulk_update.ope_code
+ IS NOT NULL
+ WHEN TRUE 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)