From 6022013d37d66410298408a862aad5814cd5ee50 Mon Sep 17 00:00:00 2001 From: Matt Newville Date: Thu, 25 Jun 2026 22:54:00 -0500 Subject: [PATCH 1/2] add table for versions numbers --- src/zarr_sqlite/zarr_sqlite.py | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/zarr_sqlite/zarr_sqlite.py b/src/zarr_sqlite/zarr_sqlite.py index 42e0074..5e17ff8 100644 --- a/src/zarr_sqlite/zarr_sqlite.py +++ b/src/zarr_sqlite/zarr_sqlite.py @@ -1,5 +1,7 @@ from __future__ import annotations +__version__ = "0.1.0" + import asyncio import sqlite3 from pathlib import Path @@ -16,6 +18,8 @@ ) from zarr.core.buffer import Buffer from zarr.core.common import BytesLike +from zarr import __version__ as zarr_version +from sys import version as py_version if TYPE_CHECKING: from collections.abc import AsyncIterator, Iterable, Sequence @@ -177,9 +181,35 @@ async def _execute( return cur.execute(query, params) async def _create_schema(self) -> None: - await self._execute_write( - "CREATE TABLE IF NOT EXISTS zarr(k TEXT PRIMARY KEY, v BLOB)" - ) + await self._ensure_open() + if self._lock is None: + raise ValueError("Store is not open") + + schema = ["CREATE TABLE IF NOT EXISTS zarr(k TEXT PRIMARY KEY, v BLOB)", + "CREATE TABLE IF NOT EXISTS zarr_versions(name TEXT PRIMARY KEY, version TEXT)"] + + set_version = "INSERT OR REPLACE INTO zarr_versions (name, version) VALUES (?, ?)" + versions = {'SqliteStore': __version__, + 'Zarr_Create': zarr_version, + 'Python_Create': py_version} + async with self._lock: + cursor = self._con.cursor() + for statement in schema: + _ = cursor.execute(statement) + for name, ver in versions.items(): + _ = cursor.execute(set_version, (name, ver)) + self._con.commit() + + async def get_versions(self): + "return a dict of version information" + cur = await self._execute("SELECT * from zarr_versions;") + result = {} + print(cur) + for row in cur.fetchall(): + result[row.name] = row.version + print("got result ", row) + return result + @override def close(self) -> None: @@ -200,7 +230,8 @@ async def is_empty(self, prefix: str) -> bool: @override async def clear(self) -> None: """Clear the store.""" - await self._execute_write("DROP TABLE IF EXISTS zarr") + await self._execute_write("DROP TABLE IF EXISTS zarr;") + await self._execute_write("DROP TABLE IF exists zarr_versions;") await self._create_schema() @override From dfdff003031f19fdeaa2edceec2520239f9a319d Mon Sep 17 00:00:00 2001 From: Matt Newville Date: Fri, 26 Jun 2026 12:12:20 -0500 Subject: [PATCH 2/2] version_table: add schema version, create datetime, make get_version() method be synchronous (needs discussion) --- src/zarr_sqlite/zarr_sqlite.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/zarr_sqlite/zarr_sqlite.py b/src/zarr_sqlite/zarr_sqlite.py index 5e17ff8..92bb6f1 100644 --- a/src/zarr_sqlite/zarr_sqlite.py +++ b/src/zarr_sqlite/zarr_sqlite.py @@ -1,6 +1,7 @@ from __future__ import annotations __version__ = "0.1.0" +schema_version = "1.0" import asyncio import sqlite3 @@ -8,6 +9,7 @@ from typing import TYPE_CHECKING, override, cast import urllib.parse import uuid +from datetime import datetime from zarr.abc.store import ( ByteRequest, @@ -189,9 +191,12 @@ async def _create_schema(self) -> None: "CREATE TABLE IF NOT EXISTS zarr_versions(name TEXT PRIMARY KEY, version TEXT)"] set_version = "INSERT OR REPLACE INTO zarr_versions (name, version) VALUES (?, ?)" - versions = {'SqliteStore': __version__, - 'Zarr_Create': zarr_version, - 'Python_Create': py_version} + versions = {'sqlitestore_version': __version__, + 'sqlitestore_schema': schema_version, + 'create_zarr_version': zarr_version, + 'create_python_version': py_version, + 'create_datetime': datetime.now().isoformat(sep=' ', timespec='seconds'), + } async with self._lock: cursor = self._con.cursor() for statement in schema: @@ -200,14 +205,14 @@ async def _create_schema(self) -> None: _ = cursor.execute(set_version, (name, ver)) self._con.commit() - async def get_versions(self): - "return a dict of version information" - cur = await self._execute("SELECT * from zarr_versions;") + def get_versions(self): + """return a dict of version information (non-async)""" result = {} - print(cur) - for row in cur.fetchall(): - result[row.name] = row.version - print("got result ", row) + with sqlite3.connect(self.database_uri, uri=True, autocommit=False, check_same_thread=False) as con: + cur = con.cursor() + cur.execute("SELECT * from zarr_versions") + for row in cur.fetchall(): + result[row[0]] = row[1] return result