124 lines
4.6 KiB
Python
124 lines
4.6 KiB
Python
"""FlowDeck — v6.5.0 database row content pages (synced blocks production).
|
|
|
|
A database row (``collection_pages``) has no block content of its own:
|
|
its Notion-style content lives in a shadow ``pages`` row linked via
|
|
``pages.collection_row_id``. The full page editor (synced blocks,
|
|
versions, realtime, permissions) is reused unchanged on that page.
|
|
|
|
``ensure_row_page()`` lazily creates (or heals) the shadow page and is
|
|
the single entry point used by the row-open endpoint.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
from app.db import get_conn
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _host_workspace(conn, coll: dict) -> tuple[str, int | None]:
|
|
"""Workspace (key, id) the shadow page should live in.
|
|
|
|
Resolution order: full-page database host page → inline parent page →
|
|
the collection's own ``workspace_id`` (key left empty).
|
|
"""
|
|
host = conn.execute(
|
|
"SELECT workspace, workspace_id FROM pages "
|
|
"WHERE collection_id=? AND deleted_at IS NULL "
|
|
"AND collection_row_id IS NULL LIMIT 1",
|
|
(coll.get("id"),),
|
|
).fetchone()
|
|
if not host and coll.get("parent_page_id"):
|
|
host = conn.execute(
|
|
"SELECT workspace, workspace_id FROM pages WHERE id=?",
|
|
(coll["parent_page_id"],),
|
|
).fetchone()
|
|
if host:
|
|
return host["workspace"] or "", host["workspace_id"]
|
|
if coll.get("gitea_owner") and coll.get("gitea_repo"):
|
|
return f"{coll['gitea_owner']}/{coll['gitea_repo']}", coll.get("workspace_id")
|
|
return "", coll.get("workspace_id")
|
|
|
|
|
|
def ensure_row_page(row_id: int) -> int:
|
|
"""Return the content page id for a database row, creating it if needed.
|
|
|
|
- existing live page → returned as-is;
|
|
- soft-deleted page → restored (title resynced);
|
|
- missing → created with the row's title and the collection workspace.
|
|
|
|
Raises ``KeyError`` when the row does not exist.
|
|
"""
|
|
with get_conn() as conn:
|
|
row = conn.execute(
|
|
"SELECT id, collection_id, title FROM collection_pages WHERE id=?",
|
|
(row_id,),
|
|
).fetchone()
|
|
if not row:
|
|
raise KeyError(f"row {row_id} not found")
|
|
coll_row = conn.execute(
|
|
"SELECT id, workspace_id, parent_page_id, gitea_owner, gitea_repo "
|
|
"FROM collections WHERE id=?",
|
|
(row["collection_id"],),
|
|
).fetchone()
|
|
coll = dict(coll_row) if coll_row else {"id": row["collection_id"]}
|
|
|
|
existing = conn.execute(
|
|
"SELECT id, deleted_at, title FROM pages WHERE collection_row_id=?",
|
|
(row_id,),
|
|
).fetchone()
|
|
if existing:
|
|
if existing["deleted_at"]:
|
|
conn.execute(
|
|
"UPDATE pages SET deleted_at=NULL, parent_section='DbRow', "
|
|
"title=?, updated_at=CURRENT_TIMESTAMP WHERE id=?",
|
|
(row["title"] or existing["title"] or "Untitled", existing["id"]),
|
|
)
|
|
conn.commit()
|
|
return existing["id"]
|
|
|
|
ws_key, ws_id = _host_workspace(conn, coll)
|
|
cur = conn.execute(
|
|
"""INSERT INTO pages
|
|
(workspace, workspace_id, title, content, content_format,
|
|
parent_section, collection_id, collection_row_id)
|
|
VALUES (?, ?, ?, '', 'blocks', 'DbRow', ?, ?)""",
|
|
(ws_key, ws_id, row["title"] or "Untitled",
|
|
row["collection_id"], row_id),
|
|
)
|
|
page_id = cur.lastrowid
|
|
conn.commit()
|
|
logger.debug("created content page %s for row %s", page_id, row_id)
|
|
return page_id
|
|
|
|
|
|
def sync_row_title_to_page(conn, row_id: int) -> None:
|
|
"""Row → page: copy the row's title onto its content page (if any)."""
|
|
conn.execute(
|
|
"""UPDATE pages SET title=(
|
|
SELECT title FROM collection_pages WHERE id=pages.collection_row_id
|
|
), updated_at=CURRENT_TIMESTAMP
|
|
WHERE collection_row_id=? AND EXISTS (
|
|
SELECT 1 FROM collection_pages cp
|
|
WHERE cp.id=pages.collection_row_id AND cp.title<>pages.title
|
|
)""",
|
|
(row_id,),
|
|
)
|
|
|
|
|
|
def sync_page_title_to_row(conn, page_id: int) -> None:
|
|
"""Page → row: a rename inside the editor propagates to the row."""
|
|
conn.execute(
|
|
"""UPDATE collection_pages SET title=(
|
|
SELECT title FROM pages WHERE id=?
|
|
), updated_at=CURRENT_TIMESTAMP
|
|
WHERE id=(SELECT collection_row_id FROM pages WHERE id=?)
|
|
AND EXISTS (
|
|
SELECT 1 FROM pages p
|
|
WHERE p.id=? AND p.collection_row_id IS NOT NULL
|
|
AND p.title<>collection_pages.title
|
|
)""",
|
|
(page_id, page_id, page_id),
|
|
)
|