<commit_before>"""
As we store content databases in separate SQLite files per channel, we need dynamic database connection routing.
This file contains a decorator/context manager, `using_content_database`, that allows a specific content
database to be specified for a block of code, as follows:

    with using_content_database("nalanda"):
        objects = ContentNode.objects.all()
        return objects.count()

Thanks to https://github.com/ambitioninc/django-dynamic-db-router for inspiration behind the approach taken here.
"""

import os
import threading
from functools import wraps

from django.apps import apps
from django.conf import settings
from django.db import DEFAULT_DB_ALIAS, connections
from django.db.utils import ConnectionDoesNotExist

from .errors import ContentModelUsedOutsideDBContext

THREAD_LOCAL = threading.local()


def get_active_content_database(return_none_if_not_set=False):

    # retrieve the temporary thread-local variable that `using_content_database` sets
    alias = getattr(THREAD_LOCAL, 'ACTIVE_CONTENT_DB_ALIAS', None)

    # if no content db alias has been activated, that's a problem
    if not alias:
        if return_none_if_not_set:
            return None
        else:
            raise ContentModelUsedOutsideDBContext()

    # try to connect to the content database, and if connection doesn't exist, create it
    try:
        connections[alias]
    except ConnectionDoesNotExist:
        filename = os.path.join(settings.CONTENT_DATABASE_DIR, alias + '.sqlite3')
        if not os.path.isfile(filename):
            raise KeyError("Content DB '%s' doesn't exist!!" % alias)
        connections.databases[alias] = {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': filename,
        }
        if not connections[alias].introspection.table_names():
            raise KeyError("Content DB '%s' is empty!!" % alias)

    return alias
<commit_msg>Allow full content DB paths to be passed into content DB router.<commit_after>"""
As we store content databases in separate SQLite files per channel, we need dynamic database connection routing.
This file contains a decorator/context manager, `using_content_database`, that allows a specific content
database to be specified for a block of code, as follows:

    with using_content_database("nalanda"):
        objects = ContentNode.objects.all()
        return objects.count()

Thanks to https://github.com/ambitioninc/django-dynamic-db-router for inspiration behind the approach taken here.
"""

import os
import threading
from functools import wraps

from django.apps import apps
from django.conf import settings
from django.db import DEFAULT_DB_ALIAS, connections
from django.db.utils import ConnectionDoesNotExist

from .errors import ContentModelUsedOutsideDBContext

THREAD_LOCAL = threading.local()


def get_active_content_database(return_none_if_not_set=False):

    # retrieve the temporary thread-local variable that `using_content_database` sets
    alias = getattr(THREAD_LOCAL, 'ACTIVE_CONTENT_DB_ALIAS', None)

    # if no content db alias has been activated, that's a problem
    if not alias:
        if return_none_if_not_set:
            return None
        else:
            raise ContentModelUsedOutsideDBContext()

    # try to connect to the content database, and if connection doesn't exist, create it
    try:
        connections[alias]
    except ConnectionDoesNotExist:
        if alias.endswith(".sqlite3"):
            filename = alias
        else:
            filename = os.path.join(settings.CONTENT_DATABASE_DIR, alias + '.sqlite3')
        if not os.path.isfile(filename):
            raise KeyError("Content DB '%s' doesn't exist!!" % alias)
        connections.databases[alias] = {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': filename,
        }
        if not connections[alias].introspection.table_names():
            raise KeyError("Content DB '%s' is empty!!" % alias)

    return alias

{'fraction_non_alphanumeric': 0.07593663565501635, 'fraction_numerical': 0.001257229067136032, 'mean_word_length': 3.4546472564389696, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4211417', 'n_tokens_mistral': 1076, 'n_tokens_neox': 1049, 'n_words': 360}