From 1c762e576748e2dda7a4d305dbf0123c180646b3 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 6 Aug 2024 18:52:34 -0500 Subject: [PATCH] feat: add app handler methods `save_setting()`, `delete_setting()` --- src/wuttjamaican/app.py | 65 +++++++++++++++++++++++++++++++++++++++-- tests/test_app.py | 62 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index 7dc7a29..9b38960 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -370,14 +370,16 @@ class AppHandler: def get_setting(self, session, name, **kwargs): """ - Get a setting value from the DB. + Get a :term:`config setting` value from the DB. - This does *not* consult the config object directly to + This does *not* consult the :term:`config object` directly to determine the setting value; it always queries the DB. Default implementation is just a convenience wrapper around :func:`~wuttjamaican.db.conf.get_setting()`. + See also :meth:`save_setting()` and :meth:`delete_setting()`. + :param session: App DB session. :param name: Name of the setting to get. @@ -388,6 +390,65 @@ class AppHandler: return get_setting(session, name) + def save_setting( + self, + session, + name, + value, + force_create=False, + ): + """ + Save a :term:`config setting` value to the DB. + + See also :meth:`get_setting()` and :meth:`delete_setting()`. + + :param session: Current :term:`db session`. + + :param name: Name of the setting to save. + + :param value: Value to be saved for the setting; should be + either a string or ``None``. + + :param force_create: If ``False`` (the default) then logic + will first try to locate an existing setting of the same + name, and update it if found, or create if not. + + But if this param is ``True`` then logic will only try to + create a new record, and not bother checking to see if it + exists. + + (Theoretically the latter offers a slight efficiency gain.) + """ + model = self.model + + # maybe fetch existing setting + setting = None + if not force_create: + setting = session.get(model.Setting, name) + + # create setting if needed + if not setting: + setting = model.Setting(name=name) + session.add(setting) + + # set value + setting.value = value + + def delete_setting(self, session, name): + """ + Delete a :term:`config setting` from the DB. + + See also :meth:`get_setting()` and :meth:`save_setting()`. + + :param session: Current :term:`db session`. + + :param name: Name of the setting to delete. + """ + model = self.model + setting = session.get(model.Setting, name) + if setting: + session.delete(setting) + ############################## # getters for other handlers ############################## diff --git a/tests/test_app.py b/tests/test_app.py index 8525a26..d57b756 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -97,6 +97,68 @@ class TestAppHandler(TestCase): value = self.app.get_setting(session, 'foo') self.assertEqual(value, 'bar') + def test_save_setting(self): + try: + import sqlalchemy as sa + from sqlalchemy import orm + except ImportError: + pytest.skip("test is not relevant without sqlalchemy") + + Session = orm.sessionmaker() + engine = sa.create_engine('sqlite://') + session = Session(bind=engine) + session.execute(sa.text(""" + create table setting ( + name varchar(255) primary key, + value text + ); + """)) + session.commit() + + # value null by default + value = self.app.get_setting(session, 'foo') + self.assertIsNone(value) + + # unless we save a value + self.app.save_setting(session, 'foo', '1') + session.commit() + value = self.app.get_setting(session, 'foo') + self.assertEqual(value, '1') + + def test_delete_setting(self): + try: + import sqlalchemy as sa + from sqlalchemy import orm + except ImportError: + pytest.skip("test is not relevant without sqlalchemy") + + Session = orm.sessionmaker() + engine = sa.create_engine('sqlite://') + session = Session(bind=engine) + session.execute(sa.text(""" + create table setting ( + name varchar(255) primary key, + value text + ); + """)) + session.commit() + + # value null by default + value = self.app.get_setting(session, 'foo') + self.assertIsNone(value) + + # unless we save a value + self.app.save_setting(session, 'foo', '1') + session.commit() + value = self.app.get_setting(session, 'foo') + self.assertEqual(value, '1') + + # but then if we delete it, should be null again + self.app.delete_setting(session, 'foo') + session.commit() + value = self.app.get_setting(session, 'foo') + self.assertIsNone(value) + def test_model(self): try: from wuttjamaican.db import model