From 23d612c373151c1e7e3b286732c60bad0d2b4391 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 10 Nov 2020 15:57:45 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Create=20Makeable=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- royalnet/alchemist/__init__.py | 1 + royalnet/alchemist/make.py | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 royalnet/alchemist/make.py diff --git a/royalnet/alchemist/__init__.py b/royalnet/alchemist/__init__.py index 218f2767..67d160d4 100644 --- a/royalnet/alchemist/__init__.py +++ b/royalnet/alchemist/__init__.py @@ -1,3 +1,4 @@ from .func import * +from .make import * from .repr import * from .update import * diff --git a/royalnet/alchemist/make.py b/royalnet/alchemist/make.py new file mode 100644 index 00000000..e975ea44 --- /dev/null +++ b/royalnet/alchemist/make.py @@ -0,0 +1,38 @@ +from royalnet.typing import * +import sqlalchemy.orm as o + + +T = TypeVar('T') + + +class Makeable: + """ + A mixin that can be added to a declared class to add the make and unmake methods, that try find an item with + specific properties and either create it if it doesn't exist or delete it if it exists. + """ + + @classmethod + def make(cls: Type[T], session: o.session.Session, **kwargs) -> T: + """Find the item with the specified name, or create it if it doesn't exist.""" + # Find the item + item = session.query(cls).filter_by(**kwargs).one_or_none() + # Create the item + if item is None: + item = cls(**kwargs) + session.add(item) + # Return the item + return item + + @classmethod + def unmake(cls: Type[T], session: o.session.Session, **kwargs) -> None: + """Find the item with the specified name, and delete it if it exists.""" + # Find the item + item = session.query(cls).filter_by(**kwargs).one_or_none() + # Delete the item + if item is not None: + session.delete(item) + + +__all__ = ( + "Makeable", +)