jiaofu-dbview 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. jiaofu_dbview-0.2.0/PKG-INFO +42 -0
  2. jiaofu_dbview-0.2.0/README.md +34 -0
  3. jiaofu_dbview-0.2.0/__init__.py +5 -0
  4. jiaofu_dbview-0.2.0/config.py +80 -0
  5. jiaofu_dbview-0.2.0/init_db_example.py +50 -0
  6. jiaofu_dbview-0.2.0/jiaofu_dbview.egg-info/PKG-INFO +42 -0
  7. jiaofu_dbview-0.2.0/jiaofu_dbview.egg-info/SOURCES.txt +87 -0
  8. jiaofu_dbview-0.2.0/jiaofu_dbview.egg-info/dependency_links.txt +1 -0
  9. jiaofu_dbview-0.2.0/jiaofu_dbview.egg-info/requires.txt +1 -0
  10. jiaofu_dbview-0.2.0/jiaofu_dbview.egg-info/top_level.txt +1 -0
  11. jiaofu_dbview-0.2.0/oceanbase/__init__.py +0 -0
  12. jiaofu_dbview-0.2.0/oceanbase/init_db.py +104 -0
  13. jiaofu_dbview-0.2.0/oceanbase/mysql_cli.py +58 -0
  14. jiaofu_dbview-0.2.0/pyproject.toml +30 -0
  15. jiaofu_dbview-0.2.0/pys/__init__.py +0 -0
  16. jiaofu_dbview-0.2.0/pys/agent_messages_dao.py +70 -0
  17. jiaofu_dbview-0.2.0/pys/agent_sessions_dao.py +28 -0
  18. jiaofu_dbview-0.2.0/pys/backend.py +13 -0
  19. jiaofu_dbview-0.2.0/pys/dbview_dataset.py +405 -0
  20. jiaofu_dbview-0.2.0/pys/loader.py +45 -0
  21. jiaofu_dbview-0.2.0/pys/profile_task_queue_dao.py +43 -0
  22. jiaofu_dbview-0.2.0/pys/request_traces_dao.py +21 -0
  23. jiaofu_dbview-0.2.0/pys/sql_executor.py +82 -0
  24. jiaofu_dbview-0.2.0/pys/user_books_dao.py +12 -0
  25. jiaofu_dbview-0.2.0/pys/user_feedback_dao.py +44 -0
  26. jiaofu_dbview-0.2.0/pys/user_profile_dao.py +16 -0
  27. jiaofu_dbview-0.2.0/pys/users_dao.py +12 -0
  28. jiaofu_dbview-0.2.0/setup.cfg +4 -0
  29. jiaofu_dbview-0.2.0/sqlite/__init__.py +0 -0
  30. jiaofu_dbview-0.2.0/sqlite/init_db.py +63 -0
  31. jiaofu_dbview-0.2.0/sqlite/main.py +405 -0
  32. jiaofu_dbview-0.2.0/sqls/ddl/oceanbase.sql +119 -0
  33. jiaofu_dbview-0.2.0/sqls/ddl/sqlite.sql +136 -0
  34. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/agent_messages.sql +116 -0
  35. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/agent_sessions.sql +53 -0
  36. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/profile_task_queue.sql +37 -0
  37. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/request_traces.sql +8 -0
  38. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/user_books.sql +31 -0
  39. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/user_feedback.sql +16 -0
  40. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/user_profile.sql +38 -0
  41. jiaofu_dbview-0.2.0/sqls/dml/oceanbase/users.sql +44 -0
  42. jiaofu_dbview-0.2.0/sqls/dml/sqlite/agent_messages.sql +116 -0
  43. jiaofu_dbview-0.2.0/sqls/dml/sqlite/agent_sessions.sql +45 -0
  44. jiaofu_dbview-0.2.0/sqls/dml/sqlite/profile_task_queue.sql +38 -0
  45. jiaofu_dbview-0.2.0/sqls/dml/sqlite/request_traces.sql +8 -0
  46. jiaofu_dbview-0.2.0/sqls/dml/sqlite/user_books.sql +32 -0
  47. jiaofu_dbview-0.2.0/sqls/dml/sqlite/user_feedback.sql +16 -0
  48. jiaofu_dbview-0.2.0/sqls/dml/sqlite/user_profile.sql +37 -0
  49. jiaofu_dbview-0.2.0/sqls/dml/sqlite/users.sql +43 -0
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.4
2
+ Name: jiaofu-dbview
3
+ Version: 0.2.0
4
+ Summary: Shared database access layer for Jiaofu AgentOS services
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: pymysql>=1.1.1
8
+
9
+ # jiaofu-dbview
10
+
11
+ Shared database access package for Jiaofu AgentOS services.
12
+
13
+ The distribution name is `jiaofu-dbview`; the Python import name remains
14
+ `dbview`, so existing application imports do not need to change:
15
+
16
+ ```python
17
+ from dbview.pys.dbview_dataset import DbViewDataset
18
+ ```
19
+
20
+ Both the OceanBase and SQLite SQL definitions are included in the wheel.
21
+ Runtime SQLite database files are deliberately not packaged.
22
+
23
+ Configuration is supplied explicitly by the caller; this package does not read
24
+ service config files or environment variables:
25
+
26
+ ```python
27
+ from dbview import OceanBaseConfig, SQLiteConfig
28
+ from dbview.pys.dbview_dataset import DbViewDataset
29
+
30
+ oceanbase = DbViewDataset(
31
+ "oceanbase",
32
+ OceanBaseConfig(
33
+ host="db.example.internal",
34
+ port=2880,
35
+ user="user",
36
+ password="secret",
37
+ database="tikumis",
38
+ ),
39
+ )
40
+
41
+ sqlite = DbViewDataset("sqlite", SQLiteConfig(path="/data/sessions.db"))
42
+ ```
@@ -0,0 +1,34 @@
1
+ # jiaofu-dbview
2
+
3
+ Shared database access package for Jiaofu AgentOS services.
4
+
5
+ The distribution name is `jiaofu-dbview`; the Python import name remains
6
+ `dbview`, so existing application imports do not need to change:
7
+
8
+ ```python
9
+ from dbview.pys.dbview_dataset import DbViewDataset
10
+ ```
11
+
12
+ Both the OceanBase and SQLite SQL definitions are included in the wheel.
13
+ Runtime SQLite database files are deliberately not packaged.
14
+
15
+ Configuration is supplied explicitly by the caller; this package does not read
16
+ service config files or environment variables:
17
+
18
+ ```python
19
+ from dbview import OceanBaseConfig, SQLiteConfig
20
+ from dbview.pys.dbview_dataset import DbViewDataset
21
+
22
+ oceanbase = DbViewDataset(
23
+ "oceanbase",
24
+ OceanBaseConfig(
25
+ host="db.example.internal",
26
+ port=2880,
27
+ user="user",
28
+ password="secret",
29
+ database="tikumis",
30
+ ),
31
+ )
32
+
33
+ sqlite = DbViewDataset("sqlite", SQLiteConfig(path="/data/sessions.db"))
34
+ ```
@@ -0,0 +1,5 @@
1
+ """Public configuration types for the dbview package."""
2
+
3
+ from dbview.config import OceanBaseConfig, SQLiteConfig
4
+
5
+ __all__ = ["OceanBaseConfig", "SQLiteConfig"]
@@ -0,0 +1,80 @@
1
+ """Explicit database configuration objects used by dbview callers."""
2
+ from __future__ import annotations
3
+
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+ from typing import Mapping, TypeAlias
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class OceanBaseConfig:
11
+ host: str
12
+ user: str
13
+ password: str
14
+ database: str
15
+ port: int = 2880
16
+ charset: str = "utf8mb4"
17
+
18
+ def connection_params(self) -> dict:
19
+ return {
20
+ "host": self.host,
21
+ "port": self.port,
22
+ "user": self.user,
23
+ "password": self.password,
24
+ "database": self.database,
25
+ "charset": self.charset,
26
+ }
27
+
28
+
29
+ @dataclass(frozen=True)
30
+ class SQLiteConfig:
31
+ path: str
32
+
33
+ def resolved_path(self) -> str:
34
+ return str(Path(self.path).expanduser().resolve())
35
+
36
+
37
+ DatabaseConfig: TypeAlias = OceanBaseConfig | SQLiteConfig
38
+
39
+
40
+ def normalize_config(
41
+ backend: str,
42
+ config: DatabaseConfig | Mapping[str, object],
43
+ ) -> DatabaseConfig:
44
+ """Validate and normalize a caller-provided backend configuration."""
45
+ if backend == "oceanbase":
46
+ if isinstance(config, OceanBaseConfig):
47
+ result = config
48
+ elif isinstance(config, Mapping):
49
+ required = ("host", "user", "password", "database")
50
+ missing = [key for key in required if key not in config]
51
+ if missing:
52
+ raise ValueError(f"missing OceanBase config fields: {', '.join(missing)}")
53
+ result = OceanBaseConfig(
54
+ host=str(config["host"]),
55
+ port=int(config.get("port", 2880)),
56
+ user=str(config["user"]),
57
+ password=str(config["password"]),
58
+ database=str(config["database"]),
59
+ charset=str(config.get("charset", "utf8mb4")),
60
+ )
61
+ else:
62
+ raise TypeError("oceanbase config must be OceanBaseConfig or a mapping")
63
+ if not result.host or not result.user or not result.database:
64
+ raise ValueError("OceanBase host, user and database must not be empty")
65
+ return result
66
+
67
+ if backend == "sqlite":
68
+ if isinstance(config, SQLiteConfig):
69
+ result = config
70
+ elif isinstance(config, Mapping):
71
+ if "path" not in config:
72
+ raise ValueError("missing SQLite config field: path")
73
+ result = SQLiteConfig(path=str(config["path"]))
74
+ else:
75
+ raise TypeError("sqlite config must be SQLiteConfig or a mapping")
76
+ if not result.path:
77
+ raise ValueError("SQLite path must not be empty")
78
+ return result
79
+
80
+ raise ValueError(f"unsupported dbview backend: {backend!r}")
@@ -0,0 +1,50 @@
1
+ """Unified database schema initializer."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+
6
+ from dbview.config import OceanBaseConfig, SQLiteConfig
7
+ from dbview.pys.dbview_dataset import DbViewDataset
8
+
9
+
10
+ def main() -> None:
11
+ parser = argparse.ArgumentParser(description="Initialize dbview schema")
12
+ parser.add_argument(
13
+ "--backend",
14
+ choices=("sqlite", "oceanbase"),
15
+ required=True,
16
+ help="database backend to initialize",
17
+ )
18
+ parser.add_argument("--sqlite-path")
19
+ parser.add_argument("--host")
20
+ parser.add_argument("--port", type=int, default=2880)
21
+ parser.add_argument("--user")
22
+ parser.add_argument("--password")
23
+ parser.add_argument("--database")
24
+ parser.add_argument("--charset", default="utf8mb4")
25
+ args = parser.parse_args()
26
+
27
+ if args.backend == "sqlite":
28
+ if not args.sqlite_path:
29
+ parser.error("--sqlite-path is required for sqlite")
30
+ config = SQLiteConfig(path=args.sqlite_path)
31
+ else:
32
+ missing = [name for name in ("host", "user", "password", "database") if not getattr(args, name)]
33
+ if missing:
34
+ parser.error("OceanBase requires: " + ", ".join(f"--{name}" for name in missing))
35
+ config = OceanBaseConfig(
36
+ host=args.host,
37
+ port=args.port,
38
+ user=args.user,
39
+ password=args.password,
40
+ database=args.database,
41
+ charset=args.charset,
42
+ )
43
+
44
+ dataset = DbViewDataset(args.backend, config)
45
+ dataset.init_schema()
46
+ print(f"initialized {dataset.backend} schema")
47
+
48
+
49
+ if __name__ == "__main__":
50
+ main()
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.4
2
+ Name: jiaofu-dbview
3
+ Version: 0.2.0
4
+ Summary: Shared database access layer for Jiaofu AgentOS services
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: pymysql>=1.1.1
8
+
9
+ # jiaofu-dbview
10
+
11
+ Shared database access package for Jiaofu AgentOS services.
12
+
13
+ The distribution name is `jiaofu-dbview`; the Python import name remains
14
+ `dbview`, so existing application imports do not need to change:
15
+
16
+ ```python
17
+ from dbview.pys.dbview_dataset import DbViewDataset
18
+ ```
19
+
20
+ Both the OceanBase and SQLite SQL definitions are included in the wheel.
21
+ Runtime SQLite database files are deliberately not packaged.
22
+
23
+ Configuration is supplied explicitly by the caller; this package does not read
24
+ service config files or environment variables:
25
+
26
+ ```python
27
+ from dbview import OceanBaseConfig, SQLiteConfig
28
+ from dbview.pys.dbview_dataset import DbViewDataset
29
+
30
+ oceanbase = DbViewDataset(
31
+ "oceanbase",
32
+ OceanBaseConfig(
33
+ host="db.example.internal",
34
+ port=2880,
35
+ user="user",
36
+ password="secret",
37
+ database="tikumis",
38
+ ),
39
+ )
40
+
41
+ sqlite = DbViewDataset("sqlite", SQLiteConfig(path="/data/sessions.db"))
42
+ ```
@@ -0,0 +1,87 @@
1
+ README.md
2
+ __init__.py
3
+ config.py
4
+ init_db_example.py
5
+ pyproject.toml
6
+ ./__init__.py
7
+ ./config.py
8
+ ./init_db_example.py
9
+ ./oceanbase/__init__.py
10
+ ./oceanbase/init_db.py
11
+ ./oceanbase/mysql_cli.py
12
+ ./pys/__init__.py
13
+ ./pys/agent_messages_dao.py
14
+ ./pys/agent_sessions_dao.py
15
+ ./pys/backend.py
16
+ ./pys/dbview_dataset.py
17
+ ./pys/loader.py
18
+ ./pys/profile_task_queue_dao.py
19
+ ./pys/request_traces_dao.py
20
+ ./pys/sql_executor.py
21
+ ./pys/user_books_dao.py
22
+ ./pys/user_feedback_dao.py
23
+ ./pys/user_profile_dao.py
24
+ ./pys/users_dao.py
25
+ ./sqlite/__init__.py
26
+ ./sqlite/init_db.py
27
+ ./sqlite/main.py
28
+ ./sqls/ddl/oceanbase.sql
29
+ ./sqls/ddl/sqlite.sql
30
+ ./sqls/dml/oceanbase/agent_messages.sql
31
+ ./sqls/dml/oceanbase/agent_sessions.sql
32
+ ./sqls/dml/oceanbase/profile_task_queue.sql
33
+ ./sqls/dml/oceanbase/request_traces.sql
34
+ ./sqls/dml/oceanbase/user_books.sql
35
+ ./sqls/dml/oceanbase/user_feedback.sql
36
+ ./sqls/dml/oceanbase/user_profile.sql
37
+ ./sqls/dml/oceanbase/users.sql
38
+ ./sqls/dml/sqlite/agent_messages.sql
39
+ ./sqls/dml/sqlite/agent_sessions.sql
40
+ ./sqls/dml/sqlite/profile_task_queue.sql
41
+ ./sqls/dml/sqlite/request_traces.sql
42
+ ./sqls/dml/sqlite/user_books.sql
43
+ ./sqls/dml/sqlite/user_feedback.sql
44
+ ./sqls/dml/sqlite/user_profile.sql
45
+ ./sqls/dml/sqlite/users.sql
46
+ jiaofu_dbview.egg-info/PKG-INFO
47
+ jiaofu_dbview.egg-info/SOURCES.txt
48
+ jiaofu_dbview.egg-info/dependency_links.txt
49
+ jiaofu_dbview.egg-info/requires.txt
50
+ jiaofu_dbview.egg-info/top_level.txt
51
+ oceanbase/__init__.py
52
+ oceanbase/init_db.py
53
+ oceanbase/mysql_cli.py
54
+ pys/__init__.py
55
+ pys/agent_messages_dao.py
56
+ pys/agent_sessions_dao.py
57
+ pys/backend.py
58
+ pys/dbview_dataset.py
59
+ pys/loader.py
60
+ pys/profile_task_queue_dao.py
61
+ pys/request_traces_dao.py
62
+ pys/sql_executor.py
63
+ pys/user_books_dao.py
64
+ pys/user_feedback_dao.py
65
+ pys/user_profile_dao.py
66
+ pys/users_dao.py
67
+ sqlite/__init__.py
68
+ sqlite/init_db.py
69
+ sqlite/main.py
70
+ sqls/ddl/oceanbase.sql
71
+ sqls/ddl/sqlite.sql
72
+ sqls/dml/oceanbase/agent_messages.sql
73
+ sqls/dml/oceanbase/agent_sessions.sql
74
+ sqls/dml/oceanbase/profile_task_queue.sql
75
+ sqls/dml/oceanbase/request_traces.sql
76
+ sqls/dml/oceanbase/user_books.sql
77
+ sqls/dml/oceanbase/user_feedback.sql
78
+ sqls/dml/oceanbase/user_profile.sql
79
+ sqls/dml/oceanbase/users.sql
80
+ sqls/dml/sqlite/agent_messages.sql
81
+ sqls/dml/sqlite/agent_sessions.sql
82
+ sqls/dml/sqlite/profile_task_queue.sql
83
+ sqls/dml/sqlite/request_traces.sql
84
+ sqls/dml/sqlite/user_books.sql
85
+ sqls/dml/sqlite/user_feedback.sql
86
+ sqls/dml/sqlite/user_profile.sql
87
+ sqls/dml/sqlite/users.sql
@@ -0,0 +1 @@
1
+ pymysql>=1.1.1
File without changes
@@ -0,0 +1,104 @@
1
+ """OceanBase (MySQL protocol) backend keyed by explicit connection config."""
2
+ from __future__ import annotations
3
+
4
+ import threading
5
+
6
+ from dbview.config import OceanBaseConfig
7
+
8
+
9
+ class OceanBaseDB:
10
+ _instances: dict[OceanBaseConfig, "OceanBaseDB"] = {}
11
+ _instances_lock = threading.Lock()
12
+
13
+ def __init__(self, config: OceanBaseConfig) -> None:
14
+ import pymysql # lazy: only needed on the mysql path
15
+ from pymysql.cursors import DictCursor
16
+
17
+ self._pymysql = pymysql
18
+ self._DictCursor = DictCursor
19
+ self._lock = threading.Lock()
20
+ self.config = config
21
+ self.conn = self._connect()
22
+
23
+ def _connect(self):
24
+ params = self.config.connection_params()
25
+ params["cursorclass"] = self._DictCursor
26
+ params["autocommit"] = False
27
+ return self._pymysql.connect(**params)
28
+
29
+ def _reconnect(self) -> None:
30
+ try:
31
+ self.conn.close()
32
+ except Exception:
33
+ pass
34
+ self.conn = self._connect()
35
+
36
+ def _ensure_connection(self) -> None:
37
+ try:
38
+ self.conn.ping(reconnect=True)
39
+ except Exception:
40
+ self._reconnect()
41
+
42
+ @classmethod
43
+ def instance(cls, config: OceanBaseConfig) -> "OceanBaseDB":
44
+ with cls._instances_lock:
45
+ if config not in cls._instances:
46
+ cls._instances[config] = cls(config)
47
+ return cls._instances[config]
48
+
49
+ def init_schema(self, statements: list[str]) -> None:
50
+ """Execute schema statements from the unified initializer."""
51
+ with self._lock:
52
+ self._ensure_connection()
53
+ with self.conn.cursor() as cur:
54
+ for stmt in statements:
55
+ try:
56
+ cur.execute(stmt)
57
+ except Exception as e:
58
+ code = getattr(e, "args", [None])[0]
59
+ if code not in (1050, 1061):
60
+ raise
61
+ self.conn.commit()
62
+
63
+ def execute(self, sql: str, params: dict | None = None, fetch: str = "none"):
64
+ """Run one statement; commit on writes."""
65
+ last_exc = None
66
+ for attempt in (1, 2):
67
+ with self._lock:
68
+ try:
69
+ self._ensure_connection()
70
+ with self.conn.cursor() as cur:
71
+ cur.execute(sql, params or {})
72
+ if fetch == "one":
73
+ row = cur.fetchone()
74
+ return row if row is not None else None
75
+ if fetch == "all":
76
+ return list(cur.fetchall())
77
+ if cur.description is None:
78
+ self.conn.commit()
79
+ return cur.rowcount
80
+ return None
81
+ except self._pymysql.err.InterfaceError as exc:
82
+ last_exc = exc
83
+ self._reconnect()
84
+ if attempt == 2:
85
+ raise
86
+ except self._pymysql.err.OperationalError as exc:
87
+ last_exc = exc
88
+ try:
89
+ self.conn.rollback()
90
+ except Exception:
91
+ pass
92
+ code = getattr(exc, "args", [None])[0]
93
+ if code in (2006, 2013, 0):
94
+ self._reconnect()
95
+ if attempt == 1:
96
+ continue
97
+ raise
98
+ except Exception:
99
+ try:
100
+ self.conn.rollback()
101
+ except Exception:
102
+ pass
103
+ raise
104
+ raise last_exc
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env python3
2
+ """Small OceanBase SQL client with explicit connection arguments."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+
7
+ import pymysql
8
+
9
+ from dbview.config import OceanBaseConfig
10
+
11
+
12
+ def main() -> None:
13
+ parser = argparse.ArgumentParser(description="Connect to OceanBase")
14
+ parser.add_argument("--host", required=True)
15
+ parser.add_argument("--port", type=int, default=2880)
16
+ parser.add_argument("--user", required=True)
17
+ parser.add_argument("--password", required=True)
18
+ parser.add_argument("--database", required=True)
19
+ parser.add_argument("--charset", default="utf8mb4")
20
+ parser.add_argument("sql", nargs="*")
21
+ args = parser.parse_args()
22
+
23
+ config = OceanBaseConfig(
24
+ host=args.host,
25
+ port=args.port,
26
+ user=args.user,
27
+ password=args.password,
28
+ database=args.database,
29
+ charset=args.charset,
30
+ )
31
+ conn = pymysql.connect(**config.connection_params())
32
+ cursor = conn.cursor()
33
+ try:
34
+ if args.sql:
35
+ statements = [" ".join(args.sql)]
36
+ else:
37
+ print("Connected to OceanBase. Type SQL (Ctrl+D to exit):")
38
+ statements = iter(lambda: input("mysql> ").strip(), "")
39
+
40
+ for sql in statements:
41
+ if not sql:
42
+ continue
43
+ cursor.execute(sql)
44
+ if cursor.description:
45
+ print("\t".join(item[0] for item in cursor.description))
46
+ for row in cursor.fetchall():
47
+ print("\t".join(str(value) for value in row))
48
+ print(f"Rows: {cursor.rowcount}")
49
+ conn.commit()
50
+ except EOFError:
51
+ pass
52
+ finally:
53
+ cursor.close()
54
+ conn.close()
55
+
56
+
57
+ if __name__ == "__main__":
58
+ main()
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "jiaofu-dbview"
7
+ version = "0.2.0"
8
+ description = "Shared database access layer for Jiaofu AgentOS services"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ dependencies = [
12
+ "pymysql>=1.1.1",
13
+ ]
14
+
15
+ [tool.setuptools]
16
+ packages = [
17
+ "dbview",
18
+ "dbview.oceanbase",
19
+ "dbview.pys",
20
+ "dbview.sqlite",
21
+ ]
22
+ package-dir = {dbview = "."}
23
+ include-package-data = true
24
+
25
+ [tool.setuptools.package-data]
26
+ dbview = [
27
+ "sqls/ddl/*.sql",
28
+ "sqls/dml/oceanbase/*.sql",
29
+ "sqls/dml/sqlite/*.sql",
30
+ ]
File without changes
@@ -0,0 +1,70 @@
1
+ """DAO for the agent_messages table (history reads + profile-worker reads)."""
2
+ from __future__ import annotations
3
+
4
+ from .backend import run
5
+
6
+
7
+ def insert_message(session_id: str, message_data: str, turn_number: int | None = None, book_id: str | None = None) -> None:
8
+ run("insert_message", {
9
+ "session_id": session_id,
10
+ "book_id": book_id or "",
11
+ "message_data": message_data,
12
+ "turn_number": turn_number,
13
+ })
14
+
15
+
16
+ def max_msg_id(session_id: str) -> dict | None:
17
+ return run("max_msg_id", {"session_id": session_id}, fetch="one")
18
+
19
+
20
+ def count_messages(cuid: str, uid: str | None = None) -> dict | None:
21
+ return run("count_messages", {"cuid": cuid, "uid": uid}, fetch="one")
22
+
23
+
24
+ def list_history_turns(cuid: str, before_msg_id: int, limit: int, uid: str | None = None) -> list[dict]:
25
+ return run("list_history_turns", {
26
+ "cuid": cuid,
27
+ "uid": uid,
28
+ "before_msg_id": before_msg_id,
29
+ "limit": limit,
30
+ }, fetch="all")
31
+
32
+
33
+ def list_turn_items(session_id: str, turn_number: int) -> list[dict]:
34
+ return run("list_turn_items", {
35
+ "session_id": session_id,
36
+ "turn_number": turn_number,
37
+ }, fetch="all")
38
+
39
+
40
+ def has_more_history(cuid: str, first_msg_id: int, uid: str | None = None) -> dict | None:
41
+ return run("has_more_history", {
42
+ "cuid": cuid,
43
+ "uid": uid,
44
+ "first_msg_id": first_msg_id,
45
+ }, fetch="one")
46
+
47
+
48
+ def list_items_by_msg_range(cuid: str, from_msg_id: int, max_turns: int, uid: str | None = None) -> list[dict]:
49
+ return run("list_items_by_msg_range", {
50
+ "cuid": cuid,
51
+ "uid": uid,
52
+ "from_msg_id": from_msg_id,
53
+ "max_turns": max_turns,
54
+ }, fetch="all")
55
+
56
+
57
+ def list_session_turn_items(session_id: str, from_turn: int | None = None, to_turn: int | None = None, book_id: str | None = None) -> list[dict]:
58
+ return run("list_session_turn_items", {
59
+ "session_id": session_id,
60
+ "book_id": book_id or "",
61
+ "from_turn": from_turn,
62
+ "to_turn": to_turn,
63
+ }, fetch="all")
64
+
65
+
66
+ def list_session_books(session_id: str) -> list[dict]:
67
+ return run("list_session_books", {"session_id": session_id}, fetch="all")
68
+
69
+ def max_turn_number(session_id: str) -> dict | None:
70
+ return run("max_turn_number", {"session_id": session_id}, fetch="one")
@@ -0,0 +1,28 @@
1
+ """DAO for the agent_sessions table."""
2
+ from __future__ import annotations
3
+
4
+ from .backend import run
5
+
6
+
7
+ def insert_session(session_id: str, cuid: str | None, last_book_id: str | None, uid: str | None = None) -> None:
8
+ updated = run("touch_session", {"session_id": session_id})
9
+ if updated:
10
+ return
11
+ run("insert_session", {
12
+ "session_id": session_id,
13
+ "cuid": cuid,
14
+ "uid": uid,
15
+ "book_id": last_book_id,
16
+ })
17
+
18
+
19
+ def touch_session(session_id: str) -> None:
20
+ run("touch_session", {"session_id": session_id})
21
+
22
+
23
+ def set_last_book(session_id: str, last_book_id: str | None) -> None:
24
+ run("set_last_book", {"session_id": session_id, "last_book_id": last_book_id})
25
+
26
+
27
+ def get_latest_session(cuid: str, uid: str | None = None) -> dict | None:
28
+ return run("get_latest_session", {"cuid": cuid, "uid": uid}, fetch="one")
@@ -0,0 +1,13 @@
1
+ """Deprecated function-style DAO dispatcher.
2
+
3
+ Use ``dbview.pys.dbview_dataset.DbViewDataset`` instead. Keeping this module only makes
4
+ old imports fail loudly instead of silently using an unintended database.
5
+ """
6
+ from __future__ import annotations
7
+
8
+
9
+ def run(*args, **kwargs):
10
+ raise RuntimeError(
11
+ "dbview.pys.backend.run is deprecated; create "
12
+ "DbViewDataset(backend, config) and call methods on that instance"
13
+ )