예제 #1
0
    async def _upsert_listing(self, txn, log, batch, update=False):
        descs = self.table_descriptors
        rendered = [(dataset.id, *self.render_listing(dataset))
                    for dataset in batch]
        listing_values = ((id, rowdumps(row), *fields.values())
                          for id, row, fields, _ in rendered)
        relvalues = sorted((key, value, id) for id, _, _, relfields in rendered
                           for key, values in relfields.items()
                           for value in values)

        await txn.execute_query(
            Query.into(descs[0].table).columns(
                'id', 'row', *rendered[0][2].keys()).insert(
                    *listing_values).ignore().get_sql().replace(
                        'IGNORE', 'OR REPLACE'))

        for key, group in groupby(relvalues, key=lambda x: x[0]):
            group = list(group)
            values = {(x[1], ) for x in group}
            relations = [(x[1], x[2]) for x in group]

            desc = [x for x in descs if x.key == key][0]
            await self.site.db.update_listing_relations(desc,
                                                        values,
                                                        relations,
                                                        txn=txn)

        for dataset in batch:
            log.info(f'{"updated" if update else "added"} %r', dataset)
    def get_user(self, u: types.User) -> tuple:
        query = SQLLiteQuery.from_(USER).select('*').where(
            USER.telegram_id.eq(u.id))

        db_user = self._cursor.execute(query.get_sql()).fetchone()
        if not db_user:
            raise DoesNotExist(query.get_sql())

        return db_user
    def set_interval_seconds(self, u: types.User,
                             interval_seconds: int) -> int:
        query = SQLLiteQuery.update(USER) \
            .set(USER.interval_seconds, interval_seconds) \
            .where(USER.telegram_id.eq(u.id))

        _ = self._cursor.execute(query.get_sql())
        self._con.commit()

        return self._cursor.rowcount
    def _get_active_session(self, u: types.User) -> tuple:
        query = SQLLiteQuery.from_(SESSION).select(SESSION.id) \
            .where(SESSION.user_telegram_id.eq(u.id)) \
            .where(SESSION.stop_at.isnull())

        session = self._cursor.execute(query.get_sql()).fetchone()
        if not session:
            raise DoesNotExist(query.get_sql())

        return session
    def register_user(self, u: types.User) -> None:
        columns = 'telegram_id', 'interval_seconds', 'first_name', 'last_name', 'created_at'
        values = u.id, constants.DEFAULT_INTERVAL_SECONDS, u.first_name, u.last_name, str(
            datetime.now())
        column_value_map = dict(zip(columns, values))
        params = map(lambda col: f':{col}', columns)
        query = SQLLiteQuery.into(USER).columns(*columns).insert(
            *map(Parameter, params))

        _ = self._cursor.execute(query.get_sql(), column_value_map)
        self._con.commit()
    def create_default_categories(self,
                                  u: types.User) -> Tuple[Tuple[int, str]]:
        categories = tuple((u.id, category_name)
                           for category_name in constants.DEFAULT_CATEGORIES)
        query = SQLLiteQuery.into(CATEGORY).columns(
            CATEGORY.user_telegram_id, CATEGORY.name).insert(*categories)

        _ = self._cursor.execute(query.get_sql())
        self._con.commit()

        return categories
    def get_last_started_session(self, u: types.User) -> int:
        query = SQLLiteQuery().from_(SESSION).select('*') \
            .where(SESSION.user_telegram_id.eq(Parameter(':user_id'))) \
            .orderby(SESSION.start_at, order=Order.desc) \
            .limit(1).get_sql()

        session = self._cursor.execute(query, {'user_id': u.id}).fetchone()

        if not session:
            raise DoesNotExist()

        return session
    def get_category(self, category_id: int) -> tuple:
        query = SQLLiteQuery.from_(CATEGORY).select('*') \
            .where(CATEGORY.id == Parameter(':category_id'))

        category = self._cursor.execute(query.get_sql(), {
            'category_id': category_id
        }).fetchone()

        if not category:
            raise DoesNotExist()

        return category
    def create_session(self, u: types.User):
        columns = 'user_telegram_id', 'start_at'
        values = u.id, str(datetime.now())
        column_value_map = dict(zip(columns, values))
        params = map(lambda col: f':{col}', columns)
        query = SQLLiteQuery.into(SESSION).columns(*columns).insert(
            *map(Parameter, params))

        _ = self._cursor.execute(query.get_sql(), column_value_map)
        self._con.commit()

        created_session_id = self._cursor.lastrowid
        return created_session_id
    def stop_activity(self, activity_id: str, category_id: int):
        _ = self.get_unstopped_activity(activity_id)  # check existing

        column_value_map = {'activity_id': activity_id}
        query = SQLLiteQuery.update(TIMESHEET).set(
            TIMESHEET.default_category_id, category_id).where(
                TIMESHEET.activity_id == Parameter(':activity_id'))

        self._cursor.execute(query.get_sql(), column_value_map)
        self._con.commit()

        if self._cursor.rowcount > 1:
            raise RuntimeError()
    def get_unstopped_activity(self, activity_id: str) -> tuple:
        column_value_map = {'activity_id': activity_id}
        query = SQLLiteQuery.from_(TIMESHEET).select(
            '*').where((TIMESHEET.activity_id == Parameter(':activity_id'))
                       & (TIMESHEET.default_category_id.isnull())
                       & (TIMESHEET.user_category_id.isnull()))

        activity = self._cursor.execute(query.get_sql(),
                                        column_value_map).fetchone()
        if not activity:
            raise DoesNotExist()

        return activity
    def start_activity(self, session_id: int, interval_seconds: int) -> str:
        finish = datetime.now()
        start = finish - timedelta(0, interval_seconds)
        columns = 'activity_id', 'session_id', 'start', 'finish'
        values = str(uuid()), session_id, str(start), str(finish)
        column_value_map = dict(zip(columns, values))
        params = map(lambda col: f':{col}', columns)
        query = SQLLiteQuery.into(TIMESHEET).columns(*columns).insert(
            *map(Parameter, params))

        _ = self._cursor.execute(query.get_sql(), column_value_map)
        self._con.commit()

        return column_value_map['activity_id']
 def try_stop_session(self, u: types.User) -> bool:
     """Return True if session stopped or False otherwise
     that means that there is no active session to stop"""
     try:
         opened_session = self._get_active_session(u)
     except DoesNotExist:
         return False
     else:
         session_id, *_ = opened_session
         query = SQLLiteQuery.update(SESSION) \
             .set(SESSION.stop_at, datetime.now()) \
             .where(SESSION.id.eq(session_id))
         self._cursor.execute(query.get_sql())
         self._con.commit()
         return True
    def get_timesheet_frame_by_sessions(self,
                                        session_ids: tuple) -> List[tuple]:
        if not session_ids:
            raise DoesNotExist()

        query = SQLLiteQuery().from_(TIMESHEET) \
            .inner_join(CATEGORY).on(Criterion.all((
                TIMESHEET.default_category_id.notnull(),
                TIMESHEET.default_category_id.eq(CATEGORY.id),
            ))) \
            .select(
                TIMESHEET.star,
                # (TIMESHEET.finish - TIMESHEET.start).as_('activity_duration'),  # datetime in sqlite in str
                CATEGORY.name) \
            .where(TIMESHEET.session_id.isin(session_ids)).get_sql()

        timesheet_frame = self._cursor.execute(query).fetchall()

        if not timesheet_frame:
            raise DoesNotExist()

        return timesheet_frame
예제 #15
0
 def test_make_tables_factory_with_dialect_query_cls(self):
     t1, t2 = SQLLiteQuery.Tables("abc", "def")
     q1 = t1.select("1")
     q2 = t2.select("2")
     self.assertIs(q1.dialect, Dialects.SQLITE)
     self.assertIs(q2.dialect, Dialects.SQLITE)
예제 #16
0
 async def store_db_version(self, txn):
     metadata = Table('metadata')
     await txn.exq(
         Query.into(metadata).columns(metadata.key, metadata.value).insert(
             'database_version', self.db.VERSION))
예제 #17
0
 def test_table_factory_with_dialect_query_cls(self):
     table = SQLLiteQuery.Table("abc")
     q = table.select("1")
     self.assertIs(q.dialect, Dialects.SQLITE)
예제 #18
0
    def test_update_with_bool(self):
        q = SQLLiteQuery.update(self.table_abc).set(self.table_abc.foo, True)

        self.assertEqual('UPDATE "abc" SET "foo"=1', str(q))
예제 #19
0
 def test_update_with_limit_order(self):
     q = (SQLLiteQuery.update(self.table_abc).set(
         self.table_abc.lname, "test").limit(1).orderby(self.table_abc.id))
     self.assertEqual(
         'UPDATE "abc" SET "lname"=\'test\' ORDER BY "id" LIMIT 1', str(q))
예제 #20
0
 def test_delete_with_orderby_limit(self):
     q = SQLLiteQuery.from_(self.table_abc).orderby(
         self.table_abc.id).limit(1).delete()
     self.assertEqual('DELETE FROM "abc" ORDER BY "id" LIMIT 1', str(q))
 def list_categories(self, u: types.User) -> Tuple[tuple]:
     """Get categories for current user"""
     query = SQLLiteQuery.from_(CATEGORY).select('*').where(
         CATEGORY.user_telegram_id.eq(u.id))
     categories = self._cursor.execute(query.get_sql())
     return tuple(categories)