From 0bd0a9e5d56dd2678516ec6a7ed551f09801c72a Mon Sep 17 00:00:00 2001
From: inso <insomniak.fr@gmaiL.com>
Date: Tue, 6 Sep 2016 08:36:03 +0200
Subject: [PATCH] New Entity and Repo "Identitiy" + tests

---
 src/sakia/data/__init__.py                    |  0
 src/sakia/data/entities/__init__.py           |  1 +
 src/sakia/data/entities/identity.py           | 19 +++++
 src/sakia/data/repositories/__init__.py       |  1 +
 src/sakia/data/repositories/identities.py     | 77 +++++++++++++++++++
 src/sakia/tests/unit/data/__init__.py         |  0
 .../tests/unit/data/test_identies_repo.py     | 46 +++++++++++
 7 files changed, 144 insertions(+)
 create mode 100644 src/sakia/data/__init__.py
 create mode 100644 src/sakia/data/entities/__init__.py
 create mode 100644 src/sakia/data/entities/identity.py
 create mode 100644 src/sakia/data/repositories/__init__.py
 create mode 100644 src/sakia/data/repositories/identities.py
 create mode 100644 src/sakia/tests/unit/data/__init__.py
 create mode 100644 src/sakia/tests/unit/data/test_identies_repo.py

diff --git a/src/sakia/data/__init__.py b/src/sakia/data/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/sakia/data/entities/__init__.py b/src/sakia/data/entities/__init__.py
new file mode 100644
index 00000000..73cc2df3
--- /dev/null
+++ b/src/sakia/data/entities/__init__.py
@@ -0,0 +1 @@
+from .identity import Identity
\ No newline at end of file
diff --git a/src/sakia/data/entities/identity.py b/src/sakia/data/entities/identity.py
new file mode 100644
index 00000000..3637edef
--- /dev/null
+++ b/src/sakia/data/entities/identity.py
@@ -0,0 +1,19 @@
+import attr
+from duniterpy.documents import block_uid
+
+
+@attr.s(slots=True)
+class Identity:
+    currency = attr.ib(convert=str)
+    pubkey = attr.ib(convert=str)
+    uid = attr.ib(convert=str)
+    signature = attr.ib(convert=str)
+    blockstamp = attr.ib(convert=block_uid)
+    timestamp = attr.ib(convert=int)
+    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
new file mode 100644
index 00000000..43de57a0
--- /dev/null
+++ b/src/sakia/data/repositories/__init__.py
@@ -0,0 +1 @@
+from .identities import IdentitiesRepo
\ No newline at end of file
diff --git a/src/sakia/data/repositories/identities.py b/src/sakia/data/repositories/identities.py
new file mode 100644
index 00000000..4df5b994
--- /dev/null
+++ b/src/sakia/data/repositories/identities.py
@@ -0,0 +1,77 @@
+import sqlite3
+from ..entities import Identity
+
+
+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)"
+                               ")"
+                               )
+
+    def insert(self, identity):
+        """
+        Commit an identity to the database
+        :param sakia.data.entities.Identity identity: the identity to commit
+        """
+        with self._conn:
+            self._conn.execute("INSERT INTO identities VALUES (?,?,?,?,?,?,?,?,?)", identity.astuple())
+
+    def update(self, identity):
+        """
+        Update an existing identity in the database
+        :param sakia.data.entities.Identity identity: the identity to update
+        """
+        with self._conn:
+            self.conn.execute("UPDATE identities SET "
+                              "UID=?, "
+                              "SIGNATURE=?, "
+                              "BLOCKSTAMP=?,"
+                              "TS=?,"
+                              "MEMBER=?,"
+                              "MS_BUID=?,"
+                              "MS_TIMESTAMP=?"
+                              "WHERE CURRENCY=? AND PUBKEY=?", identity.astuple()[2:] + (identity.currency,
+                                                                                         identity.pubkey)
+                              )
+
+    def get_one(self, currency, pubkey):
+        """
+        Get an existing identity in the database
+        :param str currency:
+        :param str pubkey:
+        :rtype: sakia.data.entities.Identity
+        """
+        with self._conn:
+            c = self._conn.execute("SELECT * FROM identities WHERE currency=? AND pubkey=?", (currency, pubkey))
+            data = c.fetchone()
+            if data:
+                return Identity(*data)
+
+    def drop(self, currency, pubkey):
+        """
+        Drop an existing identity from the database
+        :param str currency:
+        :param str pubkey:
+        """
+        with self._conn:
+            self._conn.execute("DELETE FROM identities WHERE currency=? AND pubkey=?", (currency, pubkey))
\ No newline at end of file
diff --git a/src/sakia/tests/unit/data/__init__.py b/src/sakia/tests/unit/data/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/sakia/tests/unit/data/test_identies_repo.py b/src/sakia/tests/unit/data/test_identies_repo.py
new file mode 100644
index 00000000..68bc58e1
--- /dev/null
+++ b/src/sakia/tests/unit/data/test_identies_repo.py
@@ -0,0 +1,46 @@
+from sakia.data.repositories import IdentitiesRepo
+from sakia.data.entities import Identity
+from duniterpy.documents import BlockUID
+import unittest
+import sqlite3
+
+
+class TestIdentitiesRepo(unittest.TestCase):
+    def setUp(self):
+        sqlite3.register_adapter(BlockUID, str)
+        sqlite3.register_adapter(bool, int)
+        sqlite3.register_converter("BOOLEAN", lambda v: bool(int(v)))
+        self.con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
+
+    def tearDown(self):
+        self.con.close()
+
+    def test_add_get_identity(self):
+        identities_repo = IdentitiesRepo(self.con)
+        identities_repo.prepare()
+        identities_repo.insert(Identity("testcurrency", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ",
+                                        "john",
+                                        "H41/8OGV2W4CLKbE35kk5t1HJQsb3jEM0/QGLUf80CwJvGZf3HvVCcNtHPUFoUBKEDQO9mPK3KJkqOoxHpqHCw==",
+                                        "20-7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67",
+                                        1473108382,
+                                        False,
+                                        None,
+                                        0))
+        identity = identities_repo.get_one("testcurrency", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
+        self.assertEqual(identity.currency, "testcurrency")
+        self.assertEqual(identity.pubkey, "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
+        self.assertEqual(identity.uid, "john")
+        self.assertEqual(identity.blockstamp.number, 20)
+        self.assertEqual(identity.blockstamp.sha_hash, "7518C700E78B56CC21FB1DDC6CBAB24E0FACC9A798F5ED8736EA007F38617D67")
+        self.assertEqual(identity.timestamp, 1473108382)
+        self.assertEqual(identity.signature, "H41/8OGV2W4CLKbE35kk5t1HJQsb3jEM0/QGLUf80CwJvGZf3HvVCcNtHPUFoUBKEDQO9mPK3KJkqOoxHpqHCw==")
+        self.assertEqual(identity.member, False)
+        self.assertEqual(identity.membership_buid, BlockUID.empty())
+        self.assertEqual(identity.membership_timestamp, 0)
+        identities_repo.drop("testcurrency", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
+        identity = identities_repo.get_one("testcurrency", "7Aqw6Efa9EzE7gtsc8SveLLrM7gm6NEGoywSv4FJx6pZ")
+        self.assertIsNone(identity)
+
+
+
+
-- 
GitLab