Revision 2a3f6a3e snf-quotaholder-app/quotaholder_django/quotaholder_app/callpoint.py
b/snf-quotaholder-app/quotaholder_django/quotaholder_app/callpoint.py | ||
---|---|---|
43 | 43 |
Callpoint, CorruptedError, InvalidDataError, ReturnButFail) |
44 | 44 |
from synnefo.lib.commissioning.utils.newname import newname |
45 | 45 |
|
46 |
from django.db.models import Q |
|
46 |
from django.db.models import Q, Count
|
|
47 | 47 |
from django.db import transaction |
48 | 48 |
from .models import (Entity, Policy, Holding, |
49 | 49 |
Commission, Provision, ProvisionLog, CallSerial, |
... | ... | |
478 | 478 |
rejected = [] |
479 | 479 |
append = rejected.append |
480 | 480 |
|
481 |
q_holdings = Q() |
|
482 |
entities = [] |
|
483 |
for (entity, resource, key, _, _, _, _, _) in set_quota: |
|
484 |
|
|
485 |
q_holdings |= Q(entity=entity, resource=resource) |
|
486 |
entities.append(entity) |
|
487 |
|
|
488 |
hs = Holding.objects.filter(q_holdings).select_for_update() |
|
489 |
holdings = {} |
|
490 |
for h in hs: |
|
491 |
holdings[(h.entity_id, h.resource)] = h |
|
492 |
|
|
493 |
entities = Entity.objects.in_bulk(entities) |
|
494 |
|
|
495 |
old_policies = [] |
|
496 |
|
|
481 | 497 |
for (entity, resource, key, |
482 | 498 |
quantity, capacity, |
483 | 499 |
import_limit, export_limit, flags) in set_quota: |
484 | 500 |
|
485 |
try: |
|
486 |
e = Entity.objects.get(entity=entity, key=key) |
|
487 |
except Entity.DoesNotExist: |
|
501 |
e = entities.get(entity, None) |
|
502 |
if e is None or e.key != key: |
|
488 | 503 |
append((entity, resource)) |
489 | 504 |
continue |
490 | 505 |
|
... | ... | |
496 | 511 |
export_limit=export_limit) |
497 | 512 |
|
498 | 513 |
try: |
499 |
h = db_get_holding(entity=entity, resource=resource, |
|
500 |
for_update=True) |
|
501 |
p = h.policy |
|
514 |
h = holdings[(entity, resource)] |
|
515 |
old_policies.append(h.policy_id) |
|
502 | 516 |
h.policy = newp |
503 | 517 |
h.flags = flags |
504 |
except Holding.DoesNotExist:
|
|
518 |
except KeyError:
|
|
505 | 519 |
h = Holding(entity=e, resource=resource, |
506 | 520 |
policy=newp, flags=flags) |
507 |
p = None |
|
508 | 521 |
|
509 | 522 |
# the order is intentionally reversed so that it |
510 | 523 |
# would break if we are not within a transaction. |
511 | 524 |
# Has helped before. |
512 | 525 |
h.save() |
513 | 526 |
newp.save() |
527 |
holdings[(entity, resource)] = h |
|
514 | 528 |
|
515 |
if p is not None and p.holding_set.count() == 0:
|
|
516 |
p.delete()
|
|
529 |
objs = Policy.objects.annotate(refs=Count('holding'))
|
|
530 |
objs.filter(policy__in=old_policies, refs=0).delete()
|
|
517 | 531 |
|
518 | 532 |
if rejected: |
519 | 533 |
raise ReturnButFail(rejected) |
... | ... | |
536 | 550 |
except CallSerial.DoesNotExist: |
537 | 551 |
pass |
538 | 552 |
|
553 |
sources = sub_quota + add_quota |
|
554 |
q_holdings = Q() |
|
555 |
entities = [] |
|
556 |
for (entity, resource, key, _, _, _, _) in sources: |
|
557 |
|
|
558 |
q_holdings |= Q(entity=entity, resource=resource) |
|
559 |
entities.append(entity) |
|
560 |
|
|
561 |
hs = Holding.objects.filter(q_holdings).select_for_update() |
|
562 |
holdings = {} |
|
563 |
for h in hs: |
|
564 |
holdings[(h.entity_id, h.resource)] = h |
|
565 |
|
|
566 |
entities = Entity.objects.in_bulk(entities) |
|
567 |
|
|
568 |
pids = [h.policy_id for h in hs] |
|
569 |
policies = Policy.objects.in_bulk(pids) |
|
570 |
|
|
571 |
old_policies = [] |
|
572 |
|
|
539 | 573 |
for removing, source in [(True, sub_quota), (False, add_quota)]: |
540 | 574 |
for (entity, resource, key, |
541 | 575 |
quantity, capacity, |
542 | 576 |
import_limit, export_limit) in source: |
543 | 577 |
|
544 |
try: |
|
545 |
e = Entity.objects.get(entity=entity, key=key) |
|
546 |
except Entity.DoesNotExist: |
|
578 |
e = entities.get(entity, None) |
|
579 |
if e is None or e.key != key: |
|
547 | 580 |
append((entity, resource)) |
548 | 581 |
continue |
549 | 582 |
|
550 | 583 |
try: |
551 |
h = db_get_holding(entity=entity, resource=resource, |
|
552 |
for_update=True) |
|
553 |
p = h.policy |
|
554 |
except Holding.DoesNotExist: |
|
584 |
h = holdings[(entity, resource)] |
|
585 |
old_policies.append(h.policy_id) |
|
586 |
try: |
|
587 |
p = policies[h.policy_id] |
|
588 |
except KeyError: |
|
589 |
raise AssertionError("no policy %s" % h.policy_id) |
|
590 |
except KeyError: |
|
555 | 591 |
if removing: |
556 | 592 |
append((entity, resource)) |
557 | 593 |
continue |
... | ... | |
583 | 619 |
# Has helped before. |
584 | 620 |
h.save() |
585 | 621 |
newp.save() |
622 |
policies[policy] = newp |
|
623 |
holdings[(entity, resource)] = h |
|
586 | 624 |
|
587 |
if p is not None and p.holding_set.count() == 0:
|
|
588 |
p.delete()
|
|
625 |
objs = Policy.objects.annotate(refs=Count('holding'))
|
|
626 |
objs.filter(policy__in=old_policies, refs=0).delete()
|
|
589 | 627 |
|
590 | 628 |
if rejected: |
591 | 629 |
raise ReturnButFail(rejected) |
Also available in: Unified diff