# Path: jacquard/storage/file.py
# class FileStore(StorageEngine, threading.local):
#     """Flat(ish)-file SQLite3-based storage engine."""
# 
#     def __init__(self, connection_string):
#         """
#         Open up connection.
# 
#         The connection string is given as a file: URL for the path to the
#         database file. It needn't be absolute, and will be created if it
#         does not already exist.
#         """
#         self.db = sqlite3.connect(
#             connection_string, isolation_level=None, uri=True  # Explicit BEGIN
#         )
#         self.db.execute(
#             """
#             CREATE TABLE IF NOT EXISTS "configuration" (
#                 "key" TEXT NOT NULL PRIMARY KEY,
#                 "value" TEXT NOT NULL
#             );
#         """
#         )
# 
#     def begin(self):
#         """Begin transaction."""
#         self.db.execute("BEGIN")
#         self._transaction_keys = [
#             row[0]
#             for row in self.db.execute(
#                 """
#                 SELECT "key" FROM "configuration"
#             """
#             )
#         ]
# 
#     def commit(self, changes, deletions):
#         """Commit transaction."""
#         # Insertions
#         insertions = [
#             (key, value)
#             for key, value in changes.items()
#             if key not in self._transaction_keys
#         ]
#         if insertions:
#             self.db.executemany(
#                 """
#                 INSERT INTO "configuration"("key", "value") VALUES (?, ?)
#             """,
#                 insertions,
#             )
# 
#         # Updates
#         for key, value in changes.items():
#             if key in self._transaction_keys:
#                 self.db.execute(
#                     """
#                     UPDATE "configuration" SET "value" = ? WHERE "key" = ?
#                 """,
#                     (value, key),
#                 )
# 
#         # Deletions
#         for deletion in deletions:
#             self.db.execute(
#                 """
#                 DELETE FROM "configuration" WHERE "key" = ?
#             """,
#                 (deletion,),
#             )
# 
#         self.db.commit()
#         del self._transaction_keys
# 
#     def rollback(self):
#         """Roll back transaction."""
#         self.db.rollback()
#         del self._transaction_keys
# 
#     def get(self, key):
#         """Get value."""
#         rows = list(
#             self.db.execute(
#                 """
#             SELECT "value" FROM "configuration" WHERE "key" = ?
#         """,
#                 (key,),
#             )
#         )
# 
#         if len(rows) == 0:
#             return None
#         elif len(rows) > 1:
#             raise RuntimeError("Duplicate config for key {key!r}".format(key=key))
#         else:
#             return rows[0][0]
# 
#     def keys(self):
#         """All keys."""
#         return self._transaction_keys
# 
# Path: jacquard/storage/testing_utils.py
# class StorageGauntlet(object):
#     """A standard gamut of tests run for any storage engine."""
# 
#     def setUp(self):
#         super().setUp()
#         self.setup_example()
# 
#     def setup_example(self):
#         self.storage = self.open_storage()
# 
#     def open_storage(self):
#         raise NotImplementedError()
# 
#     def test_smoke(self):
#         with self.storage.transaction() as store:
#             pass
# 
#     def test_smoke_read_only(self):
#         with self.storage.transaction(read_only=True) as store:
#             pass
# 
#     @hypothesis.given(key=arbitrary_key)
#     def test_read_missing_key(self, key):
#         with self.storage.transaction(read_only=True) as store:
#             with pytest.raises(KeyError):
#                 store[key]
# 
#     @hypothesis.given(key=arbitrary_key, value=arbitrary_json)
#     def test_read_after_write(self, key, value):
#         with self.storage.transaction() as store:
#             store[key] = value
#         with self.storage.transaction(read_only=True) as store:
#             assert store[key] == value
# 
#     @hypothesis.given(
#         data=hypothesis.strategies.dictionaries(
#             arbitrary_key, arbitrary_json, average_size=2
#         )
#     )
#     def test_enumerate_keys(self, data):
#         with self.storage.transaction() as store:
#             store.update(data)
#         with self.storage.transaction(read_only=True) as store:
#             assert set(store.keys()) == set(data.keys())
# 
#     @hypothesis.given(key=arbitrary_key, value1=arbitrary_json, value2=arbitrary_json)
#     def test_last_write_wins(self, key, value1, value2):
#         with self.storage.transaction() as store:
#             store[key] = value1
#         with self.storage.transaction() as store:
#             store[key] = value2
#         with self.storage.transaction(read_only=True) as store:
#             assert store[key] == value2
# 
#     @hypothesis.given(key=arbitrary_key, value=arbitrary_json)
#     def test_deletions_remove_values(self, key, value):
#         with self.storage.transaction() as store:
#             store[key] = value
#         with self.storage.transaction() as store:
#             del store[key]
#         with self.storage.transaction(read_only=True) as store:
#             with pytest.raises(KeyError):
#                 store[key]
# 
#     @hypothesis.given(key=arbitrary_key, value=arbitrary_json)
#     def test_deletions_remove_keys(self, key, value):
#         with self.storage.transaction() as store:
#             store[key] = value
#         with self.storage.transaction() as store:
#             del store[key]
#         with self.storage.transaction(read_only=True) as store:
#             assert list(store.keys()) == []


import unittest
from jacquard.storage.file import FileStore
from jacquard.storage.testing_utils import StorageGauntlet



class FileGauntletTest(StorageGauntlet, unittest.TestCase):

    def open_storage(self):
        return FileStore(":memory:")


def test_exceptions_back_out_writes():

# Path: jacquard/storage/file.py
# class FileStore(StorageEngine, threading.local):
#     """Flat(ish)-file SQLite3-based storage engine."""
# 
#     def __init__(self, connection_string):
#         """
#         Open up connection.
# 
#         The connection string is given as a file: URL for the path to the
#         database file. It needn't be absolute, and will be created if it
#         does not already exist.
#         """
#         self.db = sqlite3.connect(
#             connection_string, isolation_level=None, uri=True  # Explicit BEGIN
#         )
#         self.db.execute(
#             """
#             CREATE TABLE IF NOT EXISTS "configuration" (
#                 "key" TEXT NOT NULL PRIMARY KEY,
#                 "value" TEXT NOT NULL
#             );
#         """
#         )
# 
#     def begin(self):
#         """Begin transaction."""
#         self.db.execute("BEGIN")
#         self._transaction_keys = [
#             row[0]
#             for row in self.db.execute(
#                 """
#                 SELECT "key" FROM "configuration"
#             """
#             )
#         ]
# 
#     def commit(self, changes, deletions):
#         """Commit transaction."""
#         # Insertions
#         insertions = [
#             (key, value)
#             for key, value in changes.items()
#             if key not in self._transaction_keys
#         ]
#         if insertions:
#             self.db.executemany(
#                 """
#                 INSERT INTO "configuration"("key", "value") VALUES (?, ?)
#             """,
#                 insertions,
#             )
# 
#         # Updates
#         for key, value in changes.items():
#             if key in self._transaction_keys:
#                 self.db.execute(
#                     """
#                     UPDATE "configuration" SET "value" = ? WHERE "key" = ?
#                 """,
#                     (value, key),
#                 )
# 
#         # Deletions
#         for deletion in deletions:
#             self.db.execute(
#                 """
#                 DELETE FROM "configuration" WHERE "key" = ?
#             """,
#                 (deletion,),
#             )
# 
#         self.db.commit()
#         del self._transaction_keys
# 
#     def rollback(self):
#         """Roll back transaction."""
#         self.db.rollback()
#         del self._transaction_keys
# 
#     def get(self, key):
#         """Get value."""
#         rows = list(
#             self.db.execute(
#                 """
#             SELECT "value" FROM "configuration" WHERE "key" = ?
#         """,
#                 (key,),
#             )
#         )
# 
#         if len(rows) == 0:
#             return None
#         elif len(rows) > 1:
#             raise RuntimeError("Duplicate config for key {key!r}".format(key=key))
#         else:
#             return rows[0][0]
# 
#     def keys(self):
#         """All keys."""
#         return self._transaction_keys
# 
# Path: jacquard/storage/testing_utils.py
# class StorageGauntlet(object):
#     """A standard gamut of tests run for any storage engine."""
# 
#     def setUp(self):
#         super().setUp()
#         self.setup_example()
# 
#     def setup_example(self):
#         self.storage = self.open_storage()
# 
#     def open_storage(self):
#         raise NotImplementedError()
# 
#     def test_smoke(self):
#         with self.storage.transaction() as store:
#             pass
# 
#     def test_smoke_read_only(self):
#         with self.storage.transaction(read_only=True) as store:
#             pass
# 
#     @hypothesis.given(key=arbitrary_key)
#     def test_read_missing_key(self, key):
#         with self.storage.transaction(read_only=True) as store:
#             with pytest.raises(KeyError):
#                 store[key]
# 
#     @hypothesis.given(key=arbitrary_key, value=arbitrary_json)
#     def test_read_after_write(self, key, value):
#         with self.storage.transaction() as store:
#             store[key] = value
#         with self.storage.transaction(read_only=True) as store:
#             assert store[key] == value
# 
#     @hypothesis.given(
#         data=hypothesis.strategies.dictionaries(
#             arbitrary_key, arbitrary_json, average_size=2
#         )
#     )
#     def test_enumerate_keys(self, data):
#         with self.storage.transaction() as store:
#             store.update(data)
#         with self.storage.transaction(read_only=True) as store:
#             assert set(store.keys()) == set(data.keys())
# 
#     @hypothesis.given(key=arbitrary_key, value1=arbitrary_json, value2=arbitrary_json)
#     def test_last_write_wins(self, key, value1, value2):
#         with self.storage.transaction() as store:
#             store[key] = value1
#         with self.storage.transaction() as store:
#             store[key] = value2
#         with self.storage.transaction(read_only=True) as store:
#             assert store[key] == value2
# 
#     @hypothesis.given(key=arbitrary_key, value=arbitrary_json)
#     def test_deletions_remove_values(self, key, value):
#         with self.storage.transaction() as store:
#             store[key] = value
#         with self.storage.transaction() as store:
#             del store[key]
#         with self.storage.transaction(read_only=True) as store:
#             with pytest.raises(KeyError):
#                 store[key]
# 
#     @hypothesis.given(key=arbitrary_key, value=arbitrary_json)
#     def test_deletions_remove_keys(self, key, value):
#         with self.storage.transaction() as store:
#             store[key] = value
#         with self.storage.transaction() as store:
#             del store[key]
#         with self.storage.transaction(read_only=True) as store:
#             assert list(store.keys()) == []


# Path: jacquard/storage/tests/test_file.py
import unittest
from jacquard.storage.file import FileStore
from jacquard.storage.testing_utils import StorageGauntlet




class FileGauntletTest(StorageGauntlet, unittest.TestCase):

    def open_storage(self):
        return FileStore(":memory:")


def test_exceptions_back_out_writes():

    storage = FileStore(":memory:")