~fabrixxm/activist

24c1b0df2e2af7d6bc54070ab808769614ece3a6 — fabrixxm 4 months ago 9c2e2ce pg
sqlbuilder: fix insert with ignore conflict, add tests
4 files changed, 27 insertions(+), 8 deletions(-)

M activist/db/models.py
M activist/db/sqlbuilder.py
M tests/models.py
M tests/test_sqlbuilder.py
M activist/db/models.py => activist/db/models.py +3 -3
@@ 195,9 195,9 @@ class List(Base):
        # a quanto pare non posso ignorare l'insert quando l'indice c'è già.
        # lo faccio a mano, cazzo
        cls.query().insert(
            id = cls.fqid(id),
            object = cls.oid(obj),
            on_conflict = "IGNORE"
            id=cls.fqid(id),
            object=cls.oid(obj),
            on_conflict_ignore=True,
        ).execute()

    @classmethod

M activist/db/sqlbuilder.py => activist/db/sqlbuilder.py +7 -3
@@ 117,6 117,7 @@ class Query(QueryBase):
        '(',    # special keyword to insert a list of values inside ( )        
        'VALUES',
        'DEFAULT',
        'ON CONFLICT',
        'UPDATE',
        'SET',
        '_q',   # special keywork to insert a subquery


@@ 177,7 178,7 @@ class Query(QueryBase):
            self.data['SELECT'].append(f"{self._ref_table(v)} AS {k}")
        return self

    def insert(self, *args, on_conflict:Optional[str] = None, **kwargs) -> Self:
    def insert(self, *args, on_conflict_ignore:bool = False, **kwargs) -> Self:
        """
            INSERT



@@ 190,8 191,11 @@ class Query(QueryBase):
        self.data['INTO'] = self.tables

        self.data['INSERT'] = [""]
        if on_conflict is not None:
            self.data['INSERT'] = [f"OR {on_conflict.upper()}"]
        if on_conflict_ignore:
            if DRIVER == "sqlite":
                self.data['INSERT'] = [f"OR IGNORE"]
            elif DRIVER == "postgres":
                self.data['ON CONFLICT'] = ["DO NOTHING"]
        
        if len(kwargs) == 0 and len(args) > 0:
            arg = args[0]

M tests/models.py => tests/models.py +8 -0
@@ 162,6 162,14 @@ class BaseModelList(unittest.TestCase):
        self.assertEqual(count, 2)

    @with_app_context
    def test_append_duplicate_ignore(self):
        db.List.append('followers', 'http://friendica.local/profile/admin')
        list = db.List.list_by_id('http://ragno2.local/followers')
        
        count = list.count()
        self.assertEqual(count, 1)

    @with_app_context
    def test_contains(self):
        res = db.List.contains('followers', 'http://friendica.local/profile/admin')
        self.assertTrue(res)

M tests/test_sqlbuilder.py => tests/test_sqlbuilder.py +9 -2
@@ 102,7 102,6 @@ class Sqlbuilder:
        q = self.q.insert("col").default()
        self.assertEqual(q.sql(), "INSERT INTO table ( col ) DEFAULT VALUES")


    # UPDATE
    def test_update_kwargs(self):
        q = self.q.update(cola=1, colb=2)


@@ 242,9 241,17 @@ class TestSqlbuilderSqlite(Sqlbuilder, unittest.TestCase):
        self.q = Query('table')
        self.ph = "?"

    def test_insert_ignore_conflict(self):
        q = self.q.insert("col", on_conflict_ignore=True)
        self.assertEqual(q.sql(), "INSERT OR IGNORE INTO table ( col )")


class TestSqlbuilderPostgres(Sqlbuilder, unittest.TestCase):
    def setUp(self):
        set_driver("postgres")
        self.q = Query('table')
        self.ph = "%s"
\ No newline at end of file
        self.ph = "%s"

    def test_insert_ignore_conflict(self):
        q = self.q.insert("col", on_conflict_ignore=True)
        self.assertEqual(q.sql(), "INSERT INTO table ( col ) ON CONFLICT DO NOTHING")
\ No newline at end of file