diff --git a/src/sakia/data/entities/identity.py b/src/sakia/data/entities/identity.py index 3637edefaa2d5412d66c9b17fb4960544274b973..8fa1a56570f9069a1c1bb2416450e078d89ebed7 100644 --- a/src/sakia/data/entities/identity.py +++ b/src/sakia/data/entities/identity.py @@ -13,7 +13,3 @@ class Identity: member = attr.ib(validator=attr.validators.instance_of(bool)) membership_buid = attr.ib(convert=block_uid) membership_timestamp = attr.ib(convert=int) - - def astuple(self): - return (self.currency, self.pubkey, self.uid, self.signature, self.blockstamp, self.timestamp, - self.member, self.membership_buid, self.membership_timestamp) \ No newline at end of file diff --git a/src/sakia/data/repositories/__init__.py b/src/sakia/data/repositories/__init__.py index 43de57a09ccb87905cd2d0d27f7fbbc8b3a18190..ea239c6ee545babb52adb06d72d9432e9f7194d3 100644 --- a/src/sakia/data/repositories/__init__.py +++ b/src/sakia/data/repositories/__init__.py @@ -1 +1,2 @@ -from .identities import IdentitiesRepo \ No newline at end of file +from .identities import IdentitiesRepo +from .meta import MetaDatabase \ No newline at end of file diff --git a/src/sakia/data/repositories/identities.py b/src/sakia/data/repositories/identities.py index 4df5b994d6a8e99dd7aedb29d95be1e0d7acb962..c9615450f56d19000be1decc4b801bf7e9974e26 100644 --- a/src/sakia/data/repositories/identities.py +++ b/src/sakia/data/repositories/identities.py @@ -1,32 +1,12 @@ -import sqlite3 +import attr from ..entities import Identity +@attr.s class IdentitiesRepo: - def __init__(self, conn): - """ - :param sqlite3.Connection conn: the cursor - """ - self._conn = conn - - def prepare(self): - """ - Prepares the database if the table is missing - """ - with self._conn: - self._conn.execute("create table if not exists identities(" - "CURRENCY varchar(30), " - "PUBKEY varchar(50)," - "UID varchar(255)," - "SIGNATURE varchar(100)," - "BLOCKSTAMP varchar(100)," - "TS int," - "MEMBER boolean," - "MS_BUID varchar(100)," - "MS_TIMESTAMP int," - "PRIMARY KEY (CURRENCY, PUBKEY)" - ")" - ) + """The repository for Identities entities. + """ + _conn = attr.ib() # :type sqlite3.Connection def insert(self, identity): """ @@ -34,7 +14,7 @@ class IdentitiesRepo: :param sakia.data.entities.Identity identity: the identity to commit """ with self._conn: - self._conn.execute("INSERT INTO identities VALUES (?,?,?,?,?,?,?,?,?)", identity.astuple()) + self._conn.execute("INSERT INTO identities VALUES (?,?,?,?,?,?,?,?,?)", attr.astuple(identity)) def update(self, identity): """ @@ -50,7 +30,7 @@ class IdentitiesRepo: "MEMBER=?," "MS_BUID=?," "MS_TIMESTAMP=?" - "WHERE CURRENCY=? AND PUBKEY=?", identity.astuple()[2:] + (identity.currency, + "WHERE CURRENCY=? AND PUBKEY=?", attr.astuple(identity)[2:] + (identity.currency, identity.pubkey) ) diff --git a/src/sakia/data/repositories/meta.py b/src/sakia/data/repositories/meta.py new file mode 100644 index 0000000000000000000000000000000000000000..1d831c5c6cf5cb06a3e044fdaaa52b168bc58e79 --- /dev/null +++ b/src/sakia/data/repositories/meta.py @@ -0,0 +1,70 @@ +import attr +from ..entities import Identity + + +@attr.s(frozen=True) +class MetaDatabase: + """The repository for Identities entities. + """ + + _conn = attr.ib() # :type sqlite3.Connection + + def prepare(self): + """ + Prepares the database if the table is missing + """ + with self._conn: + self._conn.execute("create table if not exists meta(" + "id integer not null," + "version integer not null," + "primary key (id)" + ")" + ) + + @property + def upgrades(self): + return [ + self.create_all_tables, + ] + + def upgrade_database(self): + """ + Execute the migrations + """ + version = self.version() + nb_versions = len(self.upgrades) + for v in range(version, nb_versions): + self.upgrades[v]() + with self._conn: + self._conn.execute("UPDATE meta SET version=? WHERE id=1", (version + 1,)) + + def create_all_tables(self): + """ + Init all the tables + :return: + """ + with self._conn: + self._conn.execute("create table if not exists identities(" + "CURRENCY varchar(30), " + "PUBKEY varchar(50)," + "UID varchar(255)," + "SIGNATURE varchar(100)," + "BLOCKSTAMP varchar(100)," + "TS int," + "MEMBER boolean," + "MS_BUID varchar(100)," + "MS_TIMESTAMP int," + "PRIMARY KEY (CURRENCY, PUBKEY)" + ")" + ) + + def version(self): + with self._conn: + c = self._conn.execute("SELECT * FROM meta WHERE id=1") + data = c.fetchone() + if data: + return data[1] + else: + self._conn.execute("INSERT INTO meta VALUES (1, 0)") + return 0 + diff --git a/src/sakia/tests/unit/data/test_identies_repo.py b/src/sakia/tests/unit/data/test_identies_repo.py index 68bc58e12431826f7cca461c619ddb36d356585d..c33059fd9e8020260f0cee6f0d6d66b0a8e4355b 100644 --- a/src/sakia/tests/unit/data/test_identies_repo.py +++ b/src/sakia/tests/unit/data/test_identies_repo.py @@ -1,4 +1,4 @@ -from sakia.data.repositories import IdentitiesRepo +from sakia.data.repositories import IdentitiesRepo, MetaDatabase from sakia.data.entities import Identity from duniterpy.documents import BlockUID import unittest @@ -16,8 +16,10 @@ class TestIdentitiesRepo(unittest.TestCase): self.con.close() def test_add_get_identity(self): + meta_repo = MetaDatabase(self.con) + meta_repo.prepare() + meta_repo.upgrade_database() identities_repo = IdentitiesRepo(self.con) - identities_repo.prepare() identities_repo.insert(Identity("testcurrency", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ", "john", "H41/8OGV2W4CLKbE35kk5t1HJQsb3jEM0/QGLUf80CwJvGZf3HvVCcNtHPUFoUBKEDQO9mPK3KJkqOoxHpqHCw==",