blob: 059f871d2f7aa5dd5cbb50e76593207fa6f94466 (
plain) (
blame)
| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
 | # coding=utf-8
from flask import Blueprint
from rethinkdb.ast import Table
from _weakref import ref
from pysite.database import RethinkDB
class DBMixin():
    """
    Mixin for classes that make use of RethinkDB. It can automatically create a table with the specified primary
    key using the attributes set at class-level.
    This class is intended to be mixed in alongside one of the other view classes. For example:
    >>> class MyView(APIView, DBMixin):
    ...     name = "my_view"  # Flask internal name for this route
    ...     path = "/my_view"  # Actual URL path to reach this route
    ...     table_name = "my_table"  # Name of the table to create
    ...     table_primary_key = "username"  # Primary key to set for this table
    This class will also work with Websockets:
    >>> class MyWebsocket(WS, DBMixin):
    ...     name = "my_websocket"
    ...     path = "/my_websocket"
    ...     table_name = "my_table"
    ...     table_primary_key = "username"
    You may omit `table_primary_key` and it will be defaulted to RethinkDB's default column - "id".
    """
    table_name = ""  # type: str
    table_primary_key = "id"  # type: str
    @classmethod
    def setup(cls: "DBMixin", manager: "pysite.route_manager.RouteManager", blueprint: Blueprint):
        """
        Set up the view by creating the table specified by the class attributes - this will also deal with multiple
        inheritance by calling `super().setup()` as appropriate.
        :param manager: Instance of the current RouteManager (used to get a handle for the database object)
        :param blueprint: Current Flask blueprint
        """
        if hasattr(super(), "setup"):
            super().setup(manager, blueprint)  # pragma: no cover
        if not cls.table_name:
            raise RuntimeError("Routes using DBViewMixin must define `table_name`")
        cls._db = ref(manager.db)
        manager.db.create_table(cls.table_name, primary_key=cls.table_primary_key)
    @property
    def table(self) -> Table:
        return self.db.query(self.table_name)
    @property
    def db(self) -> RethinkDB:
        return self._db()
 |