From e31898ba962b5cb28a39f57160f950f1296602b3 Mon Sep 17 00:00:00 2001 From: Tomasz Wejroch Date: Fri, 24 Oct 2025 19:32:02 +0200 Subject: [PATCH] Changes to init syntax --- dbzero/dbzero/__init__.py | 4 +- dbzero/dbzero/connection.py | 62 --------------------------- dbzero/dbzero/initialization.py | 53 +++++++++++++++++++++++ dbzero/dbzero/storage_api.py | 2 +- python_tests/conftest.py | 15 ++++--- python_tests/migration2_init.py | 2 +- python_tests/migration2_test.py | 2 +- python_tests/migration_init.py | 2 +- python_tests/migration_test_1.py | 2 +- python_tests/migration_test_2.py | 2 +- python_tests/test_autocommit.py | 4 +- python_tests/test_crash_recovery.py | 2 +- python_tests/test_init.py | 2 +- python_tests/test_load.py | 4 ++ python_tests/test_select.py | 4 ++ samples/explore.py | 2 +- samples/explore_queries.py | 2 +- src/dbzero/bindings/python/dbzero.cpp | 2 +- 18 files changed, 84 insertions(+), 84 deletions(-) delete mode 100644 dbzero/dbzero/connection.py create mode 100644 dbzero/dbzero/initialization.py diff --git a/dbzero/dbzero/__init__.py b/dbzero/dbzero/__init__.py index 02821d8e..38fdbfff 100644 --- a/dbzero/dbzero/__init__.py +++ b/dbzero/dbzero/__init__.py @@ -6,8 +6,8 @@ from .storage_api import * from .atomic import * from .locked import * -from .connection import * from .utilities import taggify from .decorators import * from .select import * -from .compare import * \ No newline at end of file +from .compare import * +from .initialization import init \ No newline at end of file diff --git a/dbzero/dbzero/connection.py b/dbzero/dbzero/connection.py deleted file mode 100644 index daabc967..00000000 --- a/dbzero/dbzero/connection.py +++ /dev/null @@ -1,62 +0,0 @@ -import dbzero as db0 - - -class Connection: - db0_dir: str = '' - db0_default_prefix: str = None - read_write: bool = True - client_app = None - __is_initialized: bool = False - # configure autocommit on all prefixes - __config = { - "autocommit": True, - "autocommit_interval": 250, - "cache_size": 4 << 30 - } - - @classmethod - def setup(cls, db0_dir:str = None, prefix:str = None, read_write:bool = True, client_app:str = None, - autocommit:bool = None, autocommit_interval:int = None, cache_size:int = None, **kwargs): - cls.db0_dir = db0_dir or cls.db0_dir - cls.db0_default_prefix = prefix or cls.db0_default_prefix - cls.read_write = read_write - cls.client_app = client_app - if autocommit is not None: - cls.__config["autocommit"] = autocommit - if autocommit_interval is not None: - cls.__config["autocommit_interval"] = autocommit_interval - if cache_size is not None: - cls.__config["cache_size"] = cache_size - - @classmethod - def assure_initialized(cls, db0_dir:str = None, prefix:str = None): - if cls.__is_initialized: - return - - init_dir = db0_dir or cls.db0_dir - if init_dir is None: - raise ValueError("db0_dir is not set") - - # make init_dir if does not exist - cls.db0_dir = init_dir - db0.init(init_dir, cls.__config) - init_prefix = prefix or cls.db0_default_prefix - # set cache size if configured - if cls.__config["cache_size"] is not None: - db0.set_cache_size(cls.__config["cache_size"]) - - if init_prefix is not None: - db0.open(init_prefix, "rw" if cls.read_write else "r") - - # for read-only client apps the private fq-cache prefix should be opened as default one - if cls.client_app and not cls.read_write: - db0.init_fast_query(prefix=f"__fq_cache/{cls.client_app}") - cls.__is_initialized = True - - - @classmethod - def close(cls): - if cls.__is_initialized: - db0.close() - cls.__is_initialized = False - \ No newline at end of file diff --git a/dbzero/dbzero/initialization.py b/dbzero/dbzero/initialization.py new file mode 100644 index 00000000..169b7b28 --- /dev/null +++ b/dbzero/dbzero/initialization.py @@ -0,0 +1,53 @@ +"""dbzero initialization functions""" +from .dbzero import _init, open as dbzero_open + +def init(dbzero_root: str, **kwargs) -> None: + """Initialize the dbzero environment in a specified directory and apply global configurations. + + This function sets up the underlying state management engine. + It must be called once before interacting with any data. + If you need to switch to a different working directory, you should first call + dbzero.close() and then dbzero.init() again with the new path. + + Parameters + ---------- + dbzero_root : str + The path to dbzero data files directory. If the directory doesn't exist, + it will be created. + **kwargs : dict + Additional keyword arguments: + * prefix (str) shortcut to open a prefix after initialization + * read_write (bool, default True) set the open mode for the prefix + + Configure global dbzero behavior: + * autocommit (bool, default True) to enable automatic commits + * autocommit_interval (int, default 250) for commit interval in milliseconds + * cache_size (int, default 2 GiB) for main object cache size in bytes + * lang_cache_size (int, default 1024) for language model data cache size + * lock_flags (dict) to configure locking behavior when opening the prefix in read-write mode + + Lock flags (dict): + * blocking (bool, default False) wait when trying to acquire the lock + * timeout (int) maximum waiting time in seconds when blocking wait is enabled + * force_unlock (bool, default False) force unlocking of existing lock + """ + + init_kwargs = {} + + config_keys = ("autocommit", "autocommit_interval", "cache_size", "lang_cache_size") + config = {} + for key in config_keys: + if key in kwargs: + config[key] = kwargs[key] + + if config: + init_kwargs["config"] = config + + if "lock_flags" in kwargs: + init_kwargs["lock_flags"] = kwargs["lock_flags"] + + _init(dbzero_root, **init_kwargs) + + if "prefix" in kwargs: + open_mode = "rw" if kwargs.get("read_write", True) else "r" + dbzero_open(kwargs["prefix"], open_mode=open_mode) diff --git a/dbzero/dbzero/storage_api.py b/dbzero/dbzero/storage_api.py index 6e81ec9c..dbdb8306 100644 --- a/dbzero/dbzero/storage_api.py +++ b/dbzero/dbzero/storage_api.py @@ -18,7 +18,7 @@ def get_prefixes() -> Iterator[PrefixMetaData]: Discovering and opening all available prefixes: >>> # First, initialize the dbzero environment - >>> dbzero.init(path="/path/to/my/data") + >>> dbzero.init(dbzero_root="/path/to/my/data") >>> >>> # Discover all available prefixes >>> all_prefixes = dbzero.get_prefixes() diff --git a/python_tests/conftest.py b/python_tests/conftest.py index 6cc2e74a..2b874843 100644 --- a/python_tests/conftest.py +++ b/python_tests/conftest.py @@ -51,10 +51,11 @@ def db0_slab_size(request): shutil.rmtree(DB0_DIR) # create empty directory os.mkdir(DB0_DIR) - db0.init(DB0_DIR, config = { - "autocommit": request.param.get("autocommit", True), - "autocommit_interval": request.param.get("autocommit_interval", 250), - }) + db0.init( + DB0_DIR, + autocommit=request.param.get("autocommit", True), + autocommit_interval=request.param.get("autocommit_interval", 250), + ) db0.open("my-test-prefix", slab_size=request.param["slab_size"]) yield db0 gc.collect() @@ -72,7 +73,7 @@ def db0_autocommit_fixture(request): shutil.rmtree(DB0_DIR) # create empty directory os.mkdir(DB0_DIR) - db0.init(DB0_DIR, config = {"autocommit": True, "autocommit_interval": request.param}) + db0.init(DB0_DIR, autocommit=True, autocommit_interval=request.param) db0.open("my-test-prefix") yield db0 gc.collect() @@ -91,7 +92,7 @@ def db0_no_autocommit(): # create empty directory os.mkdir(DB0_DIR) # disable autocommit on all prefixes - db0.init(DB0_DIR, config = {"autocommit": False}) + db0.init(DB0_DIR, autocommit=False) db0.open("my-test-prefix") yield db0 db0.close() @@ -160,7 +161,7 @@ def db0_metaio_fixture(): shutil.rmtree(DB0_DIR) # create empty directory os.mkdir(DB0_DIR) - db0.init(DB0_DIR, config = {"autocommit": False}) + db0.init(DB0_DIR, autocommit=False) db0.open("my-test-prefix", meta_io_step_size=16) yield db0 gc.collect() diff --git a/python_tests/migration2_init.py b/python_tests/migration2_init.py index 2be8d314..e25f4dd4 100644 --- a/python_tests/migration2_init.py +++ b/python_tests/migration2_init.py @@ -33,7 +33,7 @@ def __init__(self): def start(): # Configure the dbzero connection without connecting yet - db0.init(os.path.join(os.getcwd(), "app-data"), config=config) + db0.init(os.path.join(os.getcwd(), "app-data"), **config) db0.open(config["prefix"]) root = Root([]) for _ in range(10): diff --git a/python_tests/migration2_test.py b/python_tests/migration2_test.py index ce97880a..1cd5aca7 100644 --- a/python_tests/migration2_test.py +++ b/python_tests/migration2_test.py @@ -35,7 +35,7 @@ def __init__(self): def start(): # Configure the dbzero connection without connecting yet - db0.init(os.path.join(os.getcwd(), "app-data"), config=config) + db0.init(os.path.join(os.getcwd(), "app-data"), **config) db0.open(config["prefix"]) root = Root() print(f"Root has: {len(root.value)} items") diff --git a/python_tests/migration_init.py b/python_tests/migration_init.py index b5bd5026..1b9662d8 100644 --- a/python_tests/migration_init.py +++ b/python_tests/migration_init.py @@ -23,7 +23,7 @@ def __init__(self, value): def start(): # Configure the dbzero connection without connecting yet - db0.init(os.path.join(os.getcwd(), "app-data"), config=config) + db0.init(os.path.join(os.getcwd(), "app-data") **config) db0.open(config["prefix"]) obj = MySingleton(123) db0.close() diff --git a/python_tests/migration_test_1.py b/python_tests/migration_test_1.py index 239078df..4f3afa3c 100644 --- a/python_tests/migration_test_1.py +++ b/python_tests/migration_test_1.py @@ -33,7 +33,7 @@ def items(self): def start(): # Configure the dbzero connection without connecting yet - db0.init(os.path.join(os.getcwd(), "app-data"), config=config) + db0.init(os.path.join(os.getcwd(), "app-data"), **config) db0.open(config["prefix"]) obj = MySingleton(123) print(f"int param: {obj.int_param}") diff --git a/python_tests/migration_test_2.py b/python_tests/migration_test_2.py index 584786ff..b6d687aa 100644 --- a/python_tests/migration_test_2.py +++ b/python_tests/migration_test_2.py @@ -43,7 +43,7 @@ def str_items(self): def start(): # Configure the dbzero connection without connecting yet - db0.init(os.path.join(os.getcwd(), "app-data"), config=config) + db0.init(os.path.join(os.getcwd(), "app-data"), **config) db0.open(config["prefix"]) obj = MySingleton(123) print(f"int param: {obj.int_param}") diff --git a/python_tests/test_autocommit.py b/python_tests/test_autocommit.py index 6207729d..56b7d9aa 100644 --- a/python_tests/test_autocommit.py +++ b/python_tests/test_autocommit.py @@ -136,13 +136,13 @@ def test_autocommit_config(db0_fixture): assert cfg['autocommit_interval'] == 250 db0.close() - db0.init(DB0_DIR, config={'autocommit': False, 'autocommit_interval': 1000}) + db0.init(DB0_DIR, autocommit=False, autocommit_interval=1000) cfg = db0.get_config() assert cfg['autocommit'] == False assert cfg['autocommit_interval'] == 1000 db0.close() - db0.init(DB0_DIR, config={'autocommit': False}) + db0.init(DB0_DIR, autocommit=False) cfg = db0.get_config() assert cfg['autocommit'] == False assert cfg['autocommit_interval'] == 250 diff --git a/python_tests/test_crash_recovery.py b/python_tests/test_crash_recovery.py index 61c2cb92..d7747722 100644 --- a/python_tests/test_crash_recovery.py +++ b/python_tests/test_crash_recovery.py @@ -20,7 +20,7 @@ def rand_chars(length): # start a child process that will change the singleton def generator_process(op_size, op_count, crash_after): - db0.init(DB0_DIR, config = {"autocommit": False}) + db0.init(DB0_DIR, autocommit=False) db0.open(px_name, "rw") root = MemoTestSingleton() next_id = len(root.value) diff --git a/python_tests/test_init.py b/python_tests/test_init.py index 60928a6c..fcc14140 100644 --- a/python_tests/test_init.py +++ b/python_tests/test_init.py @@ -6,7 +6,7 @@ def test_cache_size_can_be_specified_on_init(db0_fixture): db0.close() - db0.init(DB0_DIR, config={"cache_size": 123456, "lang_cache_size": 9876}) + db0.init(DB0_DIR, cache_size=123456, lang_cache_size=9876) db0.open("my-test-prefix") assert db0.get_lang_cache_stats()["capacity"] == 9876 diff --git a/python_tests/test_load.py b/python_tests/test_load.py index 29efdaed..1df1be51 100644 --- a/python_tests/test_load.py +++ b/python_tests/test_load.py @@ -242,6 +242,8 @@ def test_load_set_of_objects(db0_fixture): assert loaded == [{"value": "a"}, {"value": "b"}] class TestObject: + __test__ = False + def __init__(self, value, other_value): self.value = value self.other_value = other_value @@ -260,6 +262,8 @@ def test_load_python_object(db0_fixture): @db0.memo class TestObjectNoLoad: + __test__ = False + def __init__(self, value, other_value): self.value = value self.other_value = other_value diff --git a/python_tests/test_select.py b/python_tests/test_select.py index 5effb464..5ad596d3 100644 --- a/python_tests/test_select.py +++ b/python_tests/test_select.py @@ -157,12 +157,16 @@ def test_select_new_miltiple_prefixes(db0_fixture, memo_tags): @db0.memo(prefix="some/test/prefix") class TestClassWithPrefix: + __test__ = False + def __init__(self, value): self.value = value @db0.memo(prefix="/some/test/prefix/x") class TestClassWithPrefixStartingWithSlash: + __test__ = False + def __init__(self, value): self.value = value diff --git a/samples/explore.py b/samples/explore.py index c52e7c4a..cb1aeeb8 100644 --- a/samples/explore.py +++ b/samples/explore.py @@ -35,7 +35,7 @@ def __main__(): parser.add_argument('--uuid', default=None, type=str, help="UUID of the object to be shown") args = parser.parse_args() - db0.init(path=args.path) + db0.init(dbzero_root=args.path) try: for prefix in db0.get_prefixes(): # open prefix to make it the default one diff --git a/samples/explore_queries.py b/samples/explore_queries.py index b9aed768..e6d11288 100644 --- a/samples/explore_queries.py +++ b/samples/explore_queries.py @@ -72,7 +72,7 @@ def __main__(): print(f"Query args: {query_args}") try: - db0.init(path=args.path) + db0.init(dbzero_root=args.path) db0.init_fast_query(prefix="fq_cache") # open fq_cache as the initially default prefix db0.open("fq_cache") diff --git a/src/dbzero/bindings/python/dbzero.cpp b/src/dbzero/bindings/python/dbzero.cpp index a4b01b0b..1bd22f4f 100644 --- a/src/dbzero/bindings/python/dbzero.cpp +++ b/src/dbzero/bindings/python/dbzero.cpp @@ -31,7 +31,7 @@ namespace py = db0::python; static PyMethodDef dbzero_methods[] = { - {"init", (PyCFunction)&py::PyAPI_init, METH_VARARGS | METH_KEYWORDS, "Initialize dbzero CE workspace at a specific root path"}, + {"_init", (PyCFunction)&py::PyAPI_init, METH_VARARGS | METH_KEYWORDS, "Initialize dbzero workspace at a specific root path"}, {"open", (PyCFunction)&py::PyAPI_open, METH_VARARGS | METH_KEYWORDS, "Open or create a prefix for read or read/write"}, {"close", &py::PyAPI_close, METH_VARARGS, ""}, {"drop", &py::PyAPI_drop, METH_VARARGS, "Drop prefix (if exists)"},