From 0fa66b216c84b3d481da7600fcca2dd874b5fea9 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Tue, 4 Jun 2019 15:58:57 -0400 Subject: [PATCH] package_show: FOR UPDATE context parameter --- ckan/logic/action/get.py | 4 +++- ckan/logic/action/update.py | 8 +++++--- ckan/model/domain_object.py | 10 ++++++---- ckan/model/package.py | 9 ++++++--- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/ckan/logic/action/get.py b/ckan/logic/action/get.py index 8a5ca8acdb6..432719a24f6 100644 --- a/ckan/logic/action/get.py +++ b/ckan/logic/action/get.py @@ -989,7 +989,9 @@ def package_show(context, data_dict): context['session'] = model.Session name_or_id = data_dict.get("id") or _get_or_bust(data_dict, 'name_or_id') - pkg = model.Package.get(name_or_id) + pkg = model.Package.get( + name_or_id, + for_update=context.get('for_update', False)) if pkg is None: raise NotFound diff --git a/ckan/logic/action/update.py b/ckan/logic/action/update.py index 72f4ae3d1ab..763f4b277ae 100644 --- a/ckan/logic/action/update.py +++ b/ckan/logic/action/update.py @@ -409,8 +409,11 @@ def package_sfu(context, data_dict): if name_or_id is None: raise ValidationError({'select__id': _('Missing value')}) - package_show_context = dict(context, return_type='dict') - orig = _get_action('package_show')( # FIXME: for_update=True + package_show_context = dict( + context, + return_type='dict', + for_update=True) + orig = _get_action('package_show')( package_show_context, {'id': name_or_id}) @@ -443,7 +446,6 @@ def package_sfu(context, data_dict): for k, v in sorted(data['update__'].items()): dfunc.update_merge_string_key(orig, k, v) - # immutable fields orig['id'] = pkg.id orig['type'] = pkg.type diff --git a/ckan/model/domain_object.py b/ckan/model/domain_object.py index c7b5ae1cf16..ecaccb666c6 100644 --- a/ckan/model/domain_object.py +++ b/ckan/model/domain_object.py @@ -41,10 +41,12 @@ def count(cls): return cls.Session.query(cls).count() @classmethod - def by_name(cls, name, autoflush=True): - obj = meta.Session.query(cls).autoflush(autoflush)\ - .filter_by(name=name).first() - return obj + def by_name(cls, name, autoflush=True, for_update=False): + q = meta.Session.query(cls).autoflush(autoflush + ).filter_by(name=name) + if for_update: + q = q.with_for_update() + return q.first() @classmethod def text_search(cls, query, term): diff --git a/ckan/model/package.py b/ckan/model/package.py index 56997589436..18e289393ed 100644 --- a/ckan/model/package.py +++ b/ckan/model/package.py @@ -77,14 +77,17 @@ def search_by_name(cls, text_query): return meta.Session.query(cls).filter(cls.name.contains(text_query.lower())) @classmethod - def get(cls, reference): + def get(cls, reference, for_update=False): '''Returns a package object referenced by its id or name.''' if not reference: return None - pkg = meta.Session.query(cls).get(reference) + q = meta.Session.query(cls) + if for_update: + q = q.with_for_update() + pkg = q.get(reference) if pkg == None: - pkg = cls.by_name(reference) + pkg = cls.by_name(reference, for_update=for_update) return pkg # Todo: Make sure package names can't be changed to look like package IDs?