Skip to content

Commit df1237f

Browse files
committed
models: change tracking of domains
1 parent 9c99d66 commit df1237f

File tree

5 files changed

+57
-33
lines changed

5 files changed

+57
-33
lines changed

invenio_accounts/api.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ def __init__(self):
1616
"""Constructor."""
1717
self.updated_users = set()
1818
self.updated_roles = set()
19+
self.updated_domains = set()
1920
self.deleted_users = set()
2021
self.deleted_roles = set()
22+
self.deleted_domains = set()
2123

2224

2325
class DBUsersChangeHistory:
@@ -43,6 +45,12 @@ def add_updated_role(self, session_id, role_id):
4345
session = self._get_session(session_id)
4446
session.updated_roles.add(role_id)
4547

48+
def add_updated_domain(self, session_id, domain_id):
49+
"""Adds a user to the updated domains list."""
50+
assert domain_id is not None
51+
session = self._get_session(session_id)
52+
session.updated_domains.add(domain_id)
53+
4654
def add_deleted_user(self, session_id, user_id):
4755
"""Adds a user to the deleted users list."""
4856
assert user_id is not None
@@ -55,6 +63,12 @@ def add_deleted_role(self, session_id, role_id):
5563
session = self._get_session(session_id)
5664
session.deleted_roles.add(role_id)
5765

66+
def add_deleted_domain(self, session_id, domain_id):
67+
"""Adds a role to the deleted domain list."""
68+
assert domain_id is not None
69+
session = self._get_session(session_id)
70+
session.deleted_domains.add(domain_id)
71+
5872
def clear_dirty_sets(self, session):
5973
"""Removes session object."""
6074
sid = id(session)

invenio_accounts/datastore.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
from flask import current_app
1414
from flask_security import SQLAlchemyUserDatastore, user_confirmed
15+
from sqlalchemy.orm import joinedload
1516

1617
from .models import Domain, Role, User
1718
from .proxies import current_db_change_history
@@ -27,19 +28,17 @@ def verify_user(self, user):
2728
now = datetime.utcnow()
2829
user.blocked_at = None
2930
user.verified_at = now
31+
user.active = True
3032
if user.confirmed_at is None:
3133
user.confirmed_at = now
32-
if not user.active:
33-
user.active = True
3434
return True
3535

3636
def block_user(self, user):
3737
"""Verify a user."""
3838
now = datetime.utcnow()
3939
user.blocked_at = now
4040
user.verified_at = None
41-
if user.active:
42-
user.active = False
41+
user.active = False
4342
delete_user_sessions(user)
4443
return True
4544

@@ -113,7 +112,11 @@ def find_role_by_id(self, role_id):
113112

114113
def find_domain(self, domain):
115114
"""Find a domain."""
116-
return Domain.query.filter_by(domain=domain).one_or_none()
115+
return (
116+
Domain.query.filter_by(domain=domain)
117+
.options(joinedload(Domain.category_name))
118+
.one_or_none()
119+
)
117120

118121
def create_domain(self, domain, **kwargs):
119122
"""Create a new domain."""

invenio_accounts/domains.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def on_user_confirmed(app, user):
2020
domain = datastore.find_domain(user.domain)
2121
if domain is None:
2222
domain = datastore.create_domain(user.domain)
23+
datastore.mark_changed(id(datastore.db.session), model=domain)
2324

2425
# Verify user if domain is verified.
2526
if domain.status == DomainStatus.verified:

invenio_accounts/models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,6 @@ class DomainOrg(db.Model):
498498
parent = db.relationship("DomainOrg", remote_side=[id])
499499
"""Relationship to parent."""
500500

501-
domains = db.relationship("Domain", back_populates="org")
502-
"""Relationship to domains for this organisation."""
503-
504501
@classmethod
505502
def create(cls, pid, name, json=None, parent=None):
506503
"""Create a domain organisation."""
@@ -564,12 +561,15 @@ class Domain(db.Model, Timestamp):
564561
org_id = db.Column(db.Integer(), db.ForeignKey(DomainOrg.id), nullable=True)
565562
"""Organisation associated with domain."""
566563

567-
org = db.relationship("DomainOrg", back_populates="domains")
564+
org = db.relationship("DomainOrg", backref="domains")
568565

569566
# spammer, mail-provider, organisation, company
570567
category = db.Column(db.Integer(), db.ForeignKey(DomainCategory.id), nullable=True)
571568
"""Category of domain."""
572569

570+
category_name = db.relationship("DomainCategory", backref="domains")
571+
"""Relationship to category"""
572+
573573
num_users = db.Column(db.Integer(), default=0, nullable=False)
574574
"""Computed property to store number of users in domain."""
575575

invenio_accounts/tasks.py

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,27 +122,33 @@ def update_domain_status():
122122
# If statistics are updated regularly, the number of updates is relatively
123123
# low and hence fit in memory. We read all data first, to avoid starting
124124
# to modify the same table we're reading from.
125-
domain_updates = []
126-
for row in stmt.all():
127-
domain_updates.append(row)
128-
129-
# Update the database
130-
i = 0
131-
for row in domain_updates:
132-
domain, users, active, inactive, confirmed, verified, blocked = row
133-
db.session.query(Domain).filter(Domain.domain == domain).update(
134-
{
135-
"num_users": users,
136-
"num_active": active,
137-
"num_inactive": inactive,
138-
"num_confirmed": confirmed,
139-
"num_verified": verified,
140-
"num_blocked": blocked,
141-
}
142-
)
143-
i += 1
144-
# Commit batches of 500 updates
145-
if i % 500 == 0:
146-
db.session.commit()
147-
if i % 500 != 0:
148-
db.session.commit()
125+
domain_updates = list(stmt.all())
126+
127+
# Commit batches of 500 updates
128+
batch_size = 500
129+
now = datetime.utcnow()
130+
131+
# Process updates in batches
132+
for i in range(0, len(domain_updates), batch_size):
133+
with db.session.begin_nested(): # Use nested transactions for safety
134+
for (
135+
domain,
136+
users,
137+
active,
138+
inactive,
139+
confirmed,
140+
verified,
141+
blocked,
142+
) in domain_updates[i : i + batch_size]:
143+
db.session.query(Domain).filter(Domain.domain == domain).update(
144+
{
145+
"num_users": users,
146+
"num_active": active,
147+
"num_inactive": inactive,
148+
"num_confirmed": confirmed,
149+
"num_verified": verified,
150+
"num_blocked": blocked,
151+
"updated": now,
152+
}
153+
)
154+
db.session.commit() # Commit after each batch

0 commit comments

Comments
 (0)