Commit 33d94a8e authored by Giorgos Korfiatis's avatar Giorgos Korfiatis

astakos: Remove custom ForUpdateManager

Remove custom manager that implemented select_for_update(), since this
is already implemented in Django 1.4.
parent 8f47a9c6
......@@ -290,7 +290,7 @@ def get_project_by_id(project_id):
def get_project_for_update(project_id):
try:
return Project.objects.get_for_update(id=project_id)
return Project.objects.select_for_update().get(id=project_id)
except Project.DoesNotExist:
m = _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id
raise ProjectNotFound(m)
......@@ -302,7 +302,7 @@ def get_project_of_application_for_update(app_id):
def get_project_lock():
ProjectLock.objects.get_for_update(pk=1)
ProjectLock.objects.select_for_update().get(pk=1)
def get_application(application_id):
......@@ -965,7 +965,7 @@ def get_pending_app_diff(user, project):
def qh_add_pending_app(user, project=None, force=False):
user = AstakosUser.forupdate.get_for_update(id=user.id)
user = AstakosUser.objects.select_for_update().get(id=user.id)
diff = get_pending_app_diff(user, project)
return register_pending_apps(user, diff, force)
......@@ -982,5 +982,5 @@ def check_pending_app_quota(user, project=None):
def qh_release_pending_app(user, locked=False):
if not locked:
user = AstakosUser.forupdate.get_for_update(id=user.id)
user = AstakosUser.objects.select_for_update().get(id=user.id)
register_pending_apps(user, -1)
......@@ -109,7 +109,7 @@ class Command(BaseCommand):
def get_resource(self, resource_name):
try:
return Resource.objects.get_for_update(name=resource_name)
return Resource.objects.select_for_update().get(name=resource_name)
except Resource.DoesNotExist:
raise CommandError("Resource %s does not exist."
% resource_name)
......
......@@ -62,7 +62,6 @@ from astakos.im import settings as astakos_settings
from astakos.im import auth_providers as auth
import astakos.im.messages as astakos_messages
from snf_django.lib.db.managers import ForUpdateManager
from synnefo.lib.ordereddict import OrderedDict
from snf_django.lib.db.fields import intDecimalField
......@@ -237,8 +236,6 @@ class Resource(models.Model):
uplimit = intDecimalField(default=0)
allow_in_projects = models.BooleanField(default=True)
objects = ForUpdateManager()
def __str__(self):
return self.name
......@@ -455,7 +452,6 @@ class AstakosUser(User):
default=False, db_index=True)
objects = AstakosUserManager()
forupdate = ForUpdateManager()
def __init__(self, *args, **kwargs):
super(AstakosUser, self).__init__(*args, **kwargs)
......@@ -1261,8 +1257,6 @@ class UserSetting(models.Model):
setting = models.CharField(max_length=255)
value = models.IntegerField()
objects = ForUpdateManager()
class Meta:
unique_together = ("user", "setting")
......@@ -1272,7 +1266,6 @@ class UserSetting(models.Model):
class Chain(models.Model):
chain = models.AutoField(primary_key=True)
objects = ForUpdateManager()
def __str__(self):
return "%s" % (self.chain,)
......@@ -1283,7 +1276,7 @@ def new_chain():
return c
class ProjectApplicationManager(ForUpdateManager):
class ProjectApplicationManager(models.Manager):
def pending_per_project(self, projects):
apps = self.filter(state=self.model.PENDING,
......@@ -1527,7 +1520,7 @@ def invert_dict(d):
return dict((v, k) for k, v in d.iteritems())
class ProjectManager(ForUpdateManager):
class ProjectManager(models.Manager):
def all_with_pending(self, flt=None):
flt = Q() if flt is None else flt
......@@ -1802,10 +1795,10 @@ class ProjectLog(models.Model):
class ProjectLock(models.Model):
objects = ForUpdateManager()
pass
class ProjectMembershipManager(ForUpdateManager):
class ProjectMembershipManager(models.Manager):
def any_accepted(self):
q = self.model.Q_ACCEPTED_STATES
......
......@@ -255,7 +255,7 @@ def list_user_quotas(users):
def get_users_for_update(user_ids):
uids = sorted(user_ids)
objs = AstakosUser.forupdate
objs = AstakosUser.objects
return list(objs.filter(id__in=uids).order_by('id').select_for_update())
......@@ -313,8 +313,8 @@ def qh_sync_project(project):
def qh_add_resource_limit(resource, diff):
objs = AstakosUser.forupdate.filter(Q(email_verified=True) &
~Q(policy=resource))
objs = AstakosUser.objects.filter(Q(email_verified=True) &
~Q(policy=resource))
users = objs.order_by('id').select_for_update()
uuids = [u.uuid for u in users]
qh.add_resource_limit(holders=uuids, sources=[SYSTEM],
......@@ -322,7 +322,7 @@ def qh_add_resource_limit(resource, diff):
def qh_sync_new_resource(resource, limit):
users = AstakosUser.forupdate.filter(
users = AstakosUser.objects.filter(
email_verified=True).order_by('id').select_for_update()
resource_name = resource.name
......
......@@ -59,7 +59,7 @@ def add_resource(resource_dict):
raise RegisterException(m)
try:
r = Resource.objects.get_for_update(name=name)
r = Resource.objects.select_for_update().get(name=name)
exists = True
if r.service_type != service_type:
m = ("There already exists a resource named %s with service "
......
......@@ -35,7 +35,6 @@ from snf_django.lib.db.fields import intDecimalField
from django.db.models import (Model, BigIntegerField, CharField, DateTimeField,
ForeignKey, AutoField)
from snf_django.lib.db.managers import ForUpdateManager
class Holding(Model):
......@@ -48,8 +47,6 @@ class Holding(Model):
usage_min = intDecimalField(default=0)
usage_max = intDecimalField(default=0)
objects = ForUpdateManager()
class Meta:
unique_together = (('holder', 'source', 'resource'),)
......@@ -61,8 +58,6 @@ class Commission(Model):
clientkey = CharField(max_length=4096, null=False)
issue_datetime = DateTimeField()
objects = ForUpdateManager()
class Provision(Model):
......@@ -75,8 +70,6 @@ class Provision(Model):
quantity = intDecimalField()
objects = ForUpdateManager()
def todict(self):
return {'holder': self.holder,
'source': self.source,
......@@ -102,5 +95,3 @@ class ProvisionLog(Model):
usage_max = intDecimalField()
delta_quantity = intDecimalField()
reason = CharField(max_length=4096)
objects = ForUpdateManager()
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# The views and conclusions contained in the software and documentation are
# those of the authors and should not be interpreted as representing official
# policies, either expressed or implied, of GRNET S.A.
from django.db import connections
from django.db.models import Manager
from django.db.models.query import QuerySet, EmptyQuerySet
from django.db.models.sql.datastructures import EmptyResultSet
class ForUpdateManager(Manager):
""" Model manager implementing SELECT .. FOR UPDATE statement
This manager implements select_for_update() method in order to use
row-level locking in the database and guarantee exclusive access, since
this method is only implemented in Django>=1.4.
Non-blocking reads are not implemented, and each query including a row
that is locked by another transaction will block until the lock is
released. Also care must be taken in order to avoid deadlocks or retry
transactions that abort due to deadlocks.
Example:
networks = Network.objects.filter(public=True).select_for_update()
"""
def get_query_set(self):
return ForUpdateQuerySet(self.model, using=self._db)
def get_for_update(self, *args, **kwargs):
query = for_update(self.filter(*args, **kwargs))
query = list(query)
num = len(query)
if num == 1:
return query[0]
if not num:
raise self.model.DoesNotExist(
"%s matching query does not exist. "
"Lookup parameters were %s" %
(self.model._meta.object_name, kwargs))
raise self.model.MultipleObjectsReturned(
"get() returned more than one %s -- it returned %s! "
"Lookup parameters were %s" %
(self.model._meta.object_name, num, kwargs))
class ForUpdateQuerySet(QuerySet):
def select_for_update(self):
return for_update(self)
def for_update(query):
""" Rewrite query using SELECT .. FOR UPDATE.
"""
if 'sqlite' in connections[query.db].settings_dict['ENGINE'].lower():
# SQLite does not support FOR UPDATE
return query
try:
sql, params = query.query.get_compiler(query.db).as_sql()
except EmptyResultSet:
return EmptyQuerySet()
return query.model._default_manager.raw(sql.rstrip() + ' FOR UPDATE',
params)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment