Skip to content

Commit

Permalink
ZO-4267: Lock by uuid instead of path
Browse files Browse the repository at this point in the history
  • Loading branch information
louika committed Mar 1, 2024
1 parent e2be8d7 commit a2c4257
Showing 1 changed file with 30 additions and 34 deletions.
64 changes: 30 additions & 34 deletions core/src/zeit/connector/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,11 @@ def move(self, old_id, new_id):

def _foreign_child_lock_exists(self, id):
(parent, _) = self._pathkey(id)
locks = self.session.query(Lock).filter(Lock.parent_path.startswith(parent)).all()
stmt = (
select(Lock).join(Path, Path.id == Lock.id).where(Path.parent_path.startswith(parent))
)
result = self.session.execute(stmt)
locks = result.scalars().all()
return any([not self._is_current_principal(lock.principal) for lock in locks])

def _get_lock_status(self, id):
Expand All @@ -365,7 +369,7 @@ def _add_lock(self, id, principal, until):
if path is None:
log.warning('Unable to add lock to resource %s that does not exist.', str(id))
return
(stmt, token) = Lock.create(path=path, principal=principal, until=until)
(stmt, token) = Lock.create(id, principal=principal, until=until)
self.session.execute(stmt)
return token

Expand Down Expand Up @@ -401,7 +405,7 @@ def unlock(self, id, locktoken=None):
path = self.session.get(Path, self._pathkey(id))
if path is None:
raise KeyError(f'The resource {id} does not exist.')
lock = self.session.get(Lock, (path.parent_path, path.name, path.id))
lock = self.session.get(Lock, path.id)
if lock and self._is_current_principal(lock.principal):
locktoken = lock.token
if lock is None or lock.token != locktoken:
Expand All @@ -414,7 +418,7 @@ def locked(self, id):
if path is None:
log.warning('The resource %s does not exist.', str(id))
return (None, None, False)
lock = self.session.get(Lock, (path.parent_path, path.name, path.id))
lock = self.session.get(Lock, path.id)
if lock is None:
return (None, None, False)
is_my_lock = self._is_current_principal(lock.principal)
Expand Down Expand Up @@ -475,36 +479,6 @@ class Path(DBObject):
)


class Lock(DBObject):
__tablename__ = 'locks'

parent_path = Column(Unicode, primary_key=True)
name = Column(Unicode, primary_key=True)
id = Column(Uuid(as_uuid=False), primary_key=True)
principal = Column(Unicode, nullable=False)
until = Column(TIMESTAMP(timezone=True), nullable=False)
token = Column(Unicode, nullable=False)

__table_args__ = (
schema.ForeignKeyConstraint(
(parent_path, name, id), (Path.parent_path, Path.name, Path.id), onupdate='CASCADE'
),
)

@classmethod
def create(cls, path, principal, until):
token = secrets.token_hex()
stmt = insert(cls).values(
parent_path=path.parent_path,
name=path.name,
id=path.id,
principal=principal,
until=until,
token=token,
)
return stmt, token


class Content(DBObject):
__tablename__ = 'properties'

Expand Down Expand Up @@ -564,6 +538,28 @@ def from_webdav(self, props):
self.unsorted = unsorted


class Lock(DBObject):
__tablename__ = 'locks'

id = Column(Uuid(as_uuid=False), primary_key=True)
principal = Column(Unicode, nullable=False)
until = Column(TIMESTAMP(timezone=True), nullable=False)
token = Column(Unicode, nullable=False)

__table_args__ = (schema.ForeignKeyConstraint((id,), (Content.id,), onupdate='CASCADE'),)

@classmethod
def create(cls, uid, principal, until):
token = secrets.token_hex()
stmt = insert(cls).values(
id=uid,
principal=principal,
until=until,
token=token,
)
return stmt, token


class PassthroughConnector(Connector):
"""Development helper that transparently imports content objects (whenever
they are accessed) into SQL from another ("upstream") Connector.
Expand Down

0 comments on commit a2c4257

Please sign in to comment.