<commit_before>"""A way to store large json-like object graphs"""

import bsddb
import collections
import json
import logging
import types

from .rollback import RollbackDict
from . import flatdict
from . import treeutils

LOGGER = logging.getLogger('jsdb')

class Jsdb(collections.MutableMapping):
    """A file-backed, persisted-object graph supporting json types"""
    def __init__(self, filename):
        self._filename = filename
        self._db = None
        self._data_file = None
        self._closed = False

    def _open(self):
        if self._closed:
            raise DbClosedError()

        if self._db is None:
            self._data_file = bsddb.btopen(self._filename, 'w')
            self._db = RollbackDict(flatdict.JsonFlatteningDict(JsonEncodeDict(self._data_file)))

    def __getitem__(self, key):
        self._open()
        return self._db[key]

    def __setitem__(self, key, value):
        self._open()
        self._db[key] = value

    def __len__(self):
        return len(self._db)

    def __iter__(self):
        return iter(self._db)

    def __delitem__(self, key):
        del self._db[key]

    def commit(self):
        self._db.commit()

    def close(self):
        if self._data_file:
            self._data_file.close()
        self._data_file = None
        self._db = None
        self._closed = True

    def python_copy(self):
        """Return a copy of the entire structure without backed proxies"""
        return self._db.python_copy()

class DbClosedError(Exception):
    """Database is closed"""
<commit_msg>jsdb -- Make context manager work<commit_after>"""A way to store large json-like object graphs"""

import bsddb
import collections
import json
import logging
import types

from .rollback import RollbackDict
from . import flatdict
from . import treeutils

LOGGER = logging.getLogger('jsdb')

class Jsdb(collections.MutableMapping):
    """A file-backed, persisted-object graph supporting json types"""
    def __init__(self, filename):
        self._filename = filename
        self._db = None
        self._data_file = None
        self._closed = False

    def _open(self):
        if self._closed:
            raise DbClosedError()

        if self._db is None:
            self._data_file = bsddb.btopen(self._filename, 'w')
            self._db = RollbackDict(flatdict.JsonFlatteningDict(JsonEncodeDict(self._data_file)))

    def __getitem__(self, key):
        self._open()
        return self._db[key]

    def __setitem__(self, key, value):
        self._open()
        self._db[key] = value

    def __len__(self):
        return len(self._db)

    def __iter__(self):
        return iter(self._db)

    def __delitem__(self, key):
        del self._db[key]

    def commit(self):
        self._db.commit()

    def __enter__(self):
        pass

    def __exit__(self, exc_type, _exc_value, _tb):
        if exc_type is None:
            self.commit()

    def close(self):
        if self._data_file:
            self._data_file.close()
        self._data_file = None
        self._db = None
        self._closed = True

    def python_copy(self):
        """Return a copy of the entire structure without backed proxies"""
        return self._db.python_copy()

class DbClosedError(Exception):
    """Database is closed"""

{'fraction_non_alphanumeric': 0.0996365838885524, 'fraction_numerical': 0.0, 'mean_word_length': 2.4768421052631577, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, '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': '447357', 'n_tokens_mistral': 993, 'n_tokens_neox': 952, 'n_words': 265}