Source code for wuttjamaican.db.handler

# -*- coding: utf-8; -*-
################################################################################
#
#  WuttJamaican -- Base package for Wutta Framework
#  Copyright © 2024-2025 Lance Edgar
#
#  This file is part of Wutta Framework.
#
#  Wutta Framework is free software: you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation, either version 3 of the License, or (at your option) any
#  later version.
#
#  Wutta Framework is distributed in the hope that it will be useful, but
#  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
#
#  You should have received a copy of the GNU General Public License along with
#  Wutta Framework.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Database Handler
"""

import sqlalchemy as sa

from wuttjamaican.app import GenericHandler


[docs] class DatabaseHandler(GenericHandler): """ Base class and default implementation for the :term:`db handler`. """ def get_dialect(self, bind): # pylint: disable=empty-docstring """ """ return bind.url.get_dialect().name
[docs] def next_counter_value(self, session, key): """ Return the next counter value for the given key. If the DB backend is PostgreSQL, then a proper "sequence" is used for the counter. All other backends use a "fake" sequence by creating a dedicated table with auto-increment primary key, to provide the counter. :param session: Current :term:`db session`. :param key: Unique key indicating the counter for which the next value should be fetched. :returns: Next value as integer. """ dialect = self.get_dialect(session.bind) # postgres uses "true" native sequence if dialect == "postgresql": sql = f"create sequence if not exists {key}_seq" session.execute(sa.text(sql)) sql = f"select nextval('{key}_seq')" value = session.execute(sa.text(sql)).scalar() return value # otherwise use "magic" workaround engine = session.bind metadata = sa.MetaData() table = sa.Table( f"_counter_{key}", metadata, sa.Column("value", sa.Integer(), primary_key=True), ) table.create(engine, checkfirst=True) with engine.begin() as cxn: result = cxn.execute(table.insert()) return result.lastrowid