Updated sqlitekvstore
This commit is contained in:
@@ -37,7 +37,7 @@ from osxphotos.exiftool import ExifToolCaching, get_exiftool_path
|
|||||||
from osxphotos.photoinfo import PhotoInfoNone
|
from osxphotos.photoinfo import PhotoInfoNone
|
||||||
from osxphotos.photosalbum import PhotosAlbumPhotoScript
|
from osxphotos.photosalbum import PhotosAlbumPhotoScript
|
||||||
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
|
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
|
||||||
from osxphotos.sqlitekvstore import SQLiteKeyValueStore
|
from osxphotos.sqlitekvstore import SQLiteKVStore
|
||||||
from osxphotos.utils import pluralize
|
from osxphotos.utils import pluralize
|
||||||
|
|
||||||
from .click_rich_echo import (
|
from .click_rich_echo import (
|
||||||
@@ -1293,7 +1293,7 @@ def import_cli(
|
|||||||
# report data is set even if no report is generated
|
# report data is set even if no report is generated
|
||||||
report_data: Dict[Path, ReportRecord] = {}
|
report_data: Dict[Path, ReportRecord] = {}
|
||||||
|
|
||||||
import_db = SQLiteKeyValueStore(
|
import_db = SQLiteKVStore(
|
||||||
get_data_dir() / IMPORT_DB,
|
get_data_dir() / IMPORT_DB,
|
||||||
wal=True,
|
wal=True,
|
||||||
serialize=ReportRecord.serialize,
|
serialize=ReportRecord.serialize,
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import os.path
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
from typing import Callable, Dict, Generator, Iterable, Optional, Tuple, TypeVar, Union
|
from typing import Callable, Dict, Generator, Iterable, Optional, Tuple, TypeVar, Union
|
||||||
|
|
||||||
# keep mypy happy
|
# keep mypy happy, keys/values can be any type supported by SQLite
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
__all__ = ["SQLiteKVStore"]
|
||||||
|
|
||||||
class SQLiteKeyValueStore:
|
|
||||||
|
class SQLiteKVStore:
|
||||||
"""Simple Key-Value Store that uses sqlite3 database as backend"""
|
"""Simple Key-Value Store that uses sqlite3 database as backend"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -50,7 +52,7 @@ class SQLiteKeyValueStore:
|
|||||||
self._conn.commit()
|
self._conn.commit()
|
||||||
|
|
||||||
def _create_database(self, dbpath: str):
|
def _create_database(self, dbpath: str):
|
||||||
"""Create the progress database"""
|
"""Create the key-value database"""
|
||||||
conn = sqlite3.Connection(dbpath)
|
conn = sqlite3.Connection(dbpath)
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
@@ -102,7 +104,10 @@ class SQLiteKeyValueStore:
|
|||||||
Args:
|
Args:
|
||||||
key: key to get from key-value store
|
key: key to get from key-value store
|
||||||
default: optional default value to return if key not found
|
default: optional default value to return if key not found
|
||||||
Returns: value for key or default (Note: does not insert key:default into database if key does not exist)
|
|
||||||
|
Returns: value for key or default
|
||||||
|
|
||||||
|
Note: does not insert key:default into database if key does not exist
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self._get(key)
|
return self._get(key)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
"""Test osxphotos.sqlitekvstore"""
|
"""Test sqlitekvstore"""
|
||||||
|
|
||||||
import gzip
|
import gzip
|
||||||
import json
|
import json
|
||||||
@@ -41,7 +41,7 @@ def unzip_and_unpickle(data: bytes) -> Any:
|
|||||||
def test_basic_get_set(tmpdir):
|
def test_basic_get_set(tmpdir):
|
||||||
"""Test basic functionality"""
|
"""Test basic functionality"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
kvstore.set("foo", "bar")
|
kvstore.set("foo", "bar")
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("FOOBAR") is None
|
assert kvstore.get("FOOBAR") is None
|
||||||
@@ -61,7 +61,7 @@ def test_basic_get_set(tmpdir):
|
|||||||
def test_basic_get_set_wal(tmpdir):
|
def test_basic_get_set_wal(tmpdir):
|
||||||
"""Test basic functionality with WAL mode"""
|
"""Test basic functionality with WAL mode"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath, wal=True)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath, wal=True)
|
||||||
kvstore.set("foo", "bar")
|
kvstore.set("foo", "bar")
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("FOOBAR") is None
|
assert kvstore.get("FOOBAR") is None
|
||||||
@@ -84,14 +84,14 @@ def test_set_many(tmpdir):
|
|||||||
"""Test set_many()"""
|
"""Test set_many()"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
|
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
kvstore.set_many([("foo", "bar"), ("baz", "qux")])
|
kvstore.set_many([("foo", "bar"), ("baz", "qux")])
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("baz") == "qux"
|
assert kvstore.get("baz") == "qux"
|
||||||
kvstore.close()
|
kvstore.close()
|
||||||
|
|
||||||
# make sure values got committed
|
# make sure values got committed
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("baz") == "qux"
|
assert kvstore.get("baz") == "qux"
|
||||||
kvstore.close()
|
kvstore.close()
|
||||||
@@ -101,14 +101,14 @@ def test_set_many_dict(tmpdir):
|
|||||||
"""Test set_many() with dict of values"""
|
"""Test set_many() with dict of values"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
|
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
kvstore.set_many({"foo": "bar", "baz": "qux"})
|
kvstore.set_many({"foo": "bar", "baz": "qux"})
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("baz") == "qux"
|
assert kvstore.get("baz") == "qux"
|
||||||
kvstore.close()
|
kvstore.close()
|
||||||
|
|
||||||
# make sure values got committed
|
# make sure values got committed
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("baz") == "qux"
|
assert kvstore.get("baz") == "qux"
|
||||||
kvstore.close()
|
kvstore.close()
|
||||||
@@ -118,7 +118,7 @@ def test_basic_context_handler(tmpdir):
|
|||||||
"""Test basic functionality with context handler"""
|
"""Test basic functionality with context handler"""
|
||||||
|
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
with osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath) as kvstore:
|
with osxphotos.sqlitekvstore.SQLiteKVStore(dbpath) as kvstore:
|
||||||
kvstore.set("foo", "bar")
|
kvstore.set("foo", "bar")
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
assert kvstore.get("FOOBAR") is None
|
assert kvstore.get("FOOBAR") is None
|
||||||
@@ -134,7 +134,7 @@ def test_basic_context_handler(tmpdir):
|
|||||||
def test_about(tmpdir):
|
def test_about(tmpdir):
|
||||||
"""Test about property"""
|
"""Test about property"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
with osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath) as kvstore:
|
with osxphotos.sqlitekvstore.SQLiteKVStore(dbpath) as kvstore:
|
||||||
kvstore.about = "My description"
|
kvstore.about = "My description"
|
||||||
assert kvstore.about == "My description"
|
assert kvstore.about == "My description"
|
||||||
kvstore.about = "My new description"
|
kvstore.about = "My new description"
|
||||||
@@ -144,17 +144,17 @@ def test_about(tmpdir):
|
|||||||
def test_existing_db(tmpdir):
|
def test_existing_db(tmpdir):
|
||||||
"""Test that opening an existing database works as expected"""
|
"""Test that opening an existing database works as expected"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
with osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath) as kvstore:
|
with osxphotos.sqlitekvstore.SQLiteKVStore(dbpath) as kvstore:
|
||||||
kvstore.set("foo", "bar")
|
kvstore.set("foo", "bar")
|
||||||
|
|
||||||
with osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath) as kvstore:
|
with osxphotos.sqlitekvstore.SQLiteKVStore(dbpath) as kvstore:
|
||||||
assert kvstore.get("foo") == "bar"
|
assert kvstore.get("foo") == "bar"
|
||||||
|
|
||||||
|
|
||||||
def test_dict_interface(tmpdir):
|
def test_dict_interface(tmpdir):
|
||||||
""" "Test dict interface"""
|
""" "Test dict interface"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
with osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath) as kvstore:
|
with osxphotos.sqlitekvstore.SQLiteKVStore(dbpath) as kvstore:
|
||||||
kvstore["foo"] = "bar"
|
kvstore["foo"] = "bar"
|
||||||
assert kvstore["foo"] == "bar"
|
assert kvstore["foo"] == "bar"
|
||||||
assert len(kvstore) == 1
|
assert len(kvstore) == 1
|
||||||
@@ -186,7 +186,7 @@ def test_dict_interface(tmpdir):
|
|||||||
def test_serialize_deserialize(tmpdir):
|
def test_serialize_deserialize(tmpdir):
|
||||||
"""Test serialize/deserialize"""
|
"""Test serialize/deserialize"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(
|
||||||
dbpath, serialize=json.dumps, deserialize=json.loads
|
dbpath, serialize=json.dumps, deserialize=json.loads
|
||||||
)
|
)
|
||||||
kvstore.set("foo", {"bar": "baz"})
|
kvstore.set("foo", {"bar": "baz"})
|
||||||
@@ -197,7 +197,7 @@ def test_serialize_deserialize(tmpdir):
|
|||||||
def test_serialize_deserialize_binary_data(tmpdir):
|
def test_serialize_deserialize_binary_data(tmpdir):
|
||||||
"""Test serialize/deserialize with binary data"""
|
"""Test serialize/deserialize with binary data"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(
|
||||||
dbpath, serialize=pickle_and_zip, deserialize=unzip_and_unpickle
|
dbpath, serialize=pickle_and_zip, deserialize=unzip_and_unpickle
|
||||||
)
|
)
|
||||||
kvstore.set("foo", {"bar": "baz"})
|
kvstore.set("foo", {"bar": "baz"})
|
||||||
@@ -209,20 +209,16 @@ def test_serialize_deserialize_bad_callable(tmpdir):
|
|||||||
"""Test serialize/deserialize with bad values"""
|
"""Test serialize/deserialize with bad values"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
osxphotos.sqlitekvstore.SQLiteKeyValueStore(
|
osxphotos.sqlitekvstore.SQLiteKVStore(dbpath, serialize=1, deserialize=None)
|
||||||
dbpath, serialize=1, deserialize=None
|
|
||||||
)
|
|
||||||
|
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
osxphotos.sqlitekvstore.SQLiteKeyValueStore(
|
osxphotos.sqlitekvstore.SQLiteKVStore(dbpath, serialize=None, deserialize=1)
|
||||||
dbpath, serialize=None, deserialize=1
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_iter(tmpdir):
|
def test_iter(tmpdir):
|
||||||
"""Test generator behavior"""
|
"""Test generator behavior"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
kvstore.set("foo", "bar")
|
kvstore.set("foo", "bar")
|
||||||
kvstore.set("baz", "qux")
|
kvstore.set("baz", "qux")
|
||||||
kvstore.set("quux", "corge")
|
kvstore.set("quux", "corge")
|
||||||
@@ -234,7 +230,7 @@ def test_iter(tmpdir):
|
|||||||
def test_keys_values_items(tmpdir):
|
def test_keys_values_items(tmpdir):
|
||||||
"""Test keys, values, items"""
|
"""Test keys, values, items"""
|
||||||
dbpath = tmpdir / "kvtest.db"
|
dbpath = tmpdir / "kvtest.db"
|
||||||
kvstore = osxphotos.sqlitekvstore.SQLiteKeyValueStore(dbpath)
|
kvstore = osxphotos.sqlitekvstore.SQLiteKVStore(dbpath)
|
||||||
kvstore.set("foo", "bar")
|
kvstore.set("foo", "bar")
|
||||||
kvstore.set("baz", "qux")
|
kvstore.set("baz", "qux")
|
||||||
kvstore.set("quux", "corge")
|
kvstore.set("quux", "corge")
|
||||||
|
|||||||
Reference in New Issue
Block a user