datanotes 2.0.0 → 3.0.0
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.
- package/NOTICE +9 -0
- package/README.md +207 -28
- package/SECURITY.md +92 -45
- package/dist/THIRD-PARTY-NOTICES.txt +682 -0
- package/dist/api/catalog.d.cts +69 -0
- package/dist/api/catalog.d.ts +50 -2
- package/dist/api/cli-options.d.cts +39 -0
- package/dist/api/cli-options.d.ts +39 -0
- package/dist/api/client.d.cts +89 -0
- package/dist/api/client.d.ts +19 -30
- package/dist/api/docs.d.cts +211 -0
- package/dist/api/docs.d.ts +211 -0
- package/dist/api/guidance.d.cts +81 -0
- package/dist/api/guidance.d.ts +81 -0
- package/dist/api/index.cjs +6610 -2247
- package/dist/api/index.d.cts +13 -0
- package/dist/api/index.d.ts +10 -7
- package/dist/api/index.js +6610 -2247
- package/dist/api/local.cjs +118 -6
- package/dist/api/local.d.cts +95 -0
- package/dist/api/local.d.ts +70 -6
- package/dist/api/local.js +104 -6
- package/dist/api/mcp.cjs +17384 -0
- package/dist/api/mcp.d.cts +108 -0
- package/dist/api/mcp.d.ts +108 -0
- package/dist/api/mcp.js +17334 -0
- package/dist/api/otlp.d.cts +65 -0
- package/dist/api/redact.d.cts +17 -0
- package/dist/api/redact.d.ts +17 -0
- package/dist/api/requests.d.cts +26 -0
- package/dist/api/requests.d.ts +14 -16
- package/dist/api/results.d.cts +16 -0
- package/dist/api/results.d.ts +2 -1
- package/dist/api/tokens.d.cts +7 -0
- package/dist/datanotes.cjs +62911 -28409
- package/dist/docs/administration/configuration.md +59 -0
- package/dist/docs/administration/docker.md +80 -0
- package/dist/docs/administration/git-sync.md +71 -0
- package/dist/docs/administration/limits.md +69 -0
- package/dist/docs/administration/run-the-service.md +219 -0
- package/dist/docs/administration/status.md +61 -0
- package/dist/docs/administration/use-with-obsidian.md +75 -0
- package/dist/docs/api/operations/add_column.md +49 -0
- package/dist/docs/api/operations/add_constraint.md +55 -0
- package/dist/docs/api/operations/adopt_rows.md +50 -0
- package/dist/docs/api/operations/align_relations.md +41 -0
- package/dist/docs/api/operations/alter_column.md +46 -0
- package/dist/docs/api/operations/alter_table.md +67 -0
- package/dist/docs/api/operations/batch.md +48 -0
- package/dist/docs/api/operations/changes_stream.md +28 -0
- package/dist/docs/api/operations/check_table.md +29 -0
- package/dist/docs/api/operations/clone_table.md +48 -0
- package/dist/docs/api/operations/comment_on.md +42 -0
- package/dist/docs/api/operations/configure_database.md +52 -0
- package/dist/docs/api/operations/create_table.md +78 -0
- package/dist/docs/api/operations/create_view.md +54 -0
- package/dist/docs/api/operations/create_webhook.md +37 -0
- package/dist/docs/api/operations/define_base.md +52 -0
- package/dist/docs/api/operations/delete_rows.md +43 -0
- package/dist/docs/api/operations/delete_webhook.md +31 -0
- package/dist/docs/api/operations/describe_database.md +30 -0
- package/dist/docs/api/operations/describe_history.md +40 -0
- package/dist/docs/api/operations/describe_semantic_index.md +24 -0
- package/dist/docs/api/operations/describe_table.md +38 -0
- package/dist/docs/api/operations/docs.md +13 -0
- package/dist/docs/api/operations/drop_column.md +41 -0
- package/dist/docs/api/operations/drop_constraint.md +39 -0
- package/dist/docs/api/operations/drop_table.md +43 -0
- package/dist/docs/api/operations/drop_view.md +38 -0
- package/dist/docs/api/operations/engine_status.md +23 -0
- package/dist/docs/api/operations/graph_neighbors.md +32 -0
- package/dist/docs/api/operations/graph_path.md +32 -0
- package/dist/docs/api/operations/graph_traverse.md +43 -0
- package/dist/docs/api/operations/identify_session.md +24 -0
- package/dist/docs/api/operations/infer_table.md +43 -0
- package/dist/docs/api/operations/insert_row.md +48 -0
- package/dist/docs/api/operations/list_changes.md +35 -0
- package/dist/docs/api/operations/list_folder.md +28 -0
- package/dist/docs/api/operations/list_link_targets.md +44 -0
- package/dist/docs/api/operations/list_migrations.md +35 -0
- package/dist/docs/api/operations/list_tables.md +32 -0
- package/dist/docs/api/operations/list_webhooks.md +23 -0
- package/dist/docs/api/operations/manual_index.md +14 -0
- package/dist/docs/api/operations/manual_page.md +22 -0
- package/dist/docs/api/operations/merge_rows.md +44 -0
- package/dist/docs/api/operations/move_rows.md +52 -0
- package/dist/docs/api/operations/openapi.md +13 -0
- package/dist/docs/api/operations/openapi_post.md +20 -0
- package/dist/docs/api/operations/read_note.md +29 -0
- package/dist/docs/api/operations/recompute_columns.md +44 -0
- package/dist/docs/api/operations/record_tool_call.md +36 -0
- package/dist/docs/api/operations/rename_column.md +44 -0
- package/dist/docs/api/operations/rename_value.md +45 -0
- package/dist/docs/api/operations/restore_database.md +51 -0
- package/dist/docs/api/operations/restore_table.md +46 -0
- package/dist/docs/api/operations/search_notes.md +28 -0
- package/dist/docs/api/operations/select_rows.md +61 -0
- package/dist/docs/api/operations/semantic_search.md +34 -0
- package/dist/docs/api/operations/semantic_search_docs.md +26 -0
- package/dist/docs/api/operations/set_table_bases.md +44 -0
- package/dist/docs/api/operations/status.md +13 -0
- package/dist/docs/api/operations/stop_engine.md +23 -0
- package/dist/docs/api/operations/sync_semantic_index.md +33 -0
- package/dist/docs/api/operations/table_changes.md +31 -0
- package/dist/docs/api/operations/tags/auxiliary.md +14 -0
- package/dist/docs/api/operations/tags/change-feed.md +8 -0
- package/dist/docs/api/operations/tags/history.md +17 -0
- package/dist/docs/api/operations/tags/queries.md +15 -0
- package/dist/docs/api/operations/tags/rows-dml.md +16 -0
- package/dist/docs/api/operations/tags/schema-ddl.md +22 -0
- package/dist/docs/api/operations/tags/service.md +15 -0
- package/dist/docs/api/operations/tags/tokens.md +13 -0
- package/dist/docs/api/operations/tokens_create.md +34 -0
- package/dist/docs/api/operations/tokens_delete.md +29 -0
- package/dist/docs/api/operations/tokens_list.md +21 -0
- package/dist/docs/api/operations/tokens_me.md +20 -0
- package/dist/docs/api/operations/tokens_rotate.md +29 -0
- package/dist/docs/api/operations/tokens_update.md +34 -0
- package/dist/docs/api/operations/undo_migration.md +46 -0
- package/dist/docs/api/operations/update_row.md +60 -0
- package/dist/docs/api/operations/update_rows.md +46 -0
- package/dist/docs/api/operations/vacuum_table.md +37 -0
- package/dist/docs/api.md +135 -0
- package/dist/docs/develop/build-an-app.md +320 -0
- package/dist/docs/develop/build-on-datanotes.md +138 -0
- package/dist/docs/develop/change-feed-and-webhooks.md +70 -0
- package/dist/docs/develop/client.md +116 -0
- package/dist/docs/develop/concurrency.md +153 -0
- package/dist/docs/develop/http-api.md +79 -0
- package/dist/docs/develop/telemetry.md +86 -0
- package/dist/docs/guides/agents/docs-offline.md +99 -0
- package/dist/docs/guides/agents/how-agents-use-datanotes.md +124 -0
- package/dist/docs/guides/agents/prompts.md +495 -0
- package/dist/docs/guides/agents/reading-errors.md +112 -0
- package/dist/docs/guides/data-quality/check-constraints.md +379 -0
- package/dist/docs/guides/data-quality/check-table.md +63 -0
- package/dist/docs/guides/data-quality/hand-edits.md +507 -0
- package/dist/docs/guides/data-quality/sync-between-devices.md +51 -0
- package/dist/docs/guides/data-quality/validation.md +90 -0
- package/dist/docs/guides/database-objects/bases.md +480 -0
- package/dist/docs/guides/database-objects/catalogs-and-schemas.md +897 -0
- package/dist/docs/guides/database-objects/columns.md +1332 -0
- package/dist/docs/guides/database-objects/relations.md +1454 -0
- package/dist/docs/guides/database-objects/tables.md +1404 -0
- package/dist/docs/guides/database-objects/views.md +1003 -0
- package/dist/docs/guides/history/back-up.md +195 -0
- package/dist/docs/guides/history/change-data-feed.md +247 -0
- package/dist/docs/guides/history/journal-and-undo.md +262 -0
- package/dist/docs/guides/history/restore.md +341 -0
- package/dist/docs/guides/history/table-history.md +657 -0
- package/dist/docs/guides/history/vacuum.md +35 -0
- package/dist/docs/guides/read-and-write/automatic-links.md +768 -0
- package/dist/docs/guides/read-and-write/batch.md +139 -0
- package/dist/docs/guides/read-and-write/import-notes.md +896 -0
- package/dist/docs/guides/read-and-write/joins-and-aggregates.md +251 -0
- package/dist/docs/guides/read-and-write/read-and-filter.md +536 -0
- package/dist/docs/guides/read-and-write/write-rows.md +573 -0
- package/dist/docs/guides/search/link-graph.md +146 -0
- package/dist/docs/guides/search/semantic.md +133 -0
- package/dist/docs/guides/search/text.md +142 -0
- package/dist/docs/guides/security/security-model.md +110 -0
- package/dist/docs/guides/security/tokens.md +60 -0
- package/dist/docs/guides/security/who-did-what.md +42 -0
- package/dist/docs/index.md +113 -0
- package/dist/docs/llms.txt +33 -0
- package/dist/docs/reference/cli.md +136 -0
- package/dist/docs/reference/compatibility.md +63 -0
- package/dist/docs/reference/errors.md +72 -0
- package/dist/docs/reference/glossary.md +161 -0
- package/dist/docs/reference/operations/auxiliary.md +116 -0
- package/dist/docs/reference/operations/history.md +168 -0
- package/dist/docs/reference/operations/queries.md +169 -0
- package/dist/docs/reference/operations/rows.md +185 -0
- package/dist/docs/reference/operations/schema.md +316 -0
- package/dist/docs/reference/operations.md +96 -0
- package/dist/docs/reference/settings.md +31 -0
- package/dist/docs/release-notes.md +67 -0
- package/dist/docs/start/connect-agents.md +204 -0
- package/dist/docs/start/how-it-works.md +317 -0
- package/dist/docs/start/quick-start.md +126 -0
- package/package.json +59 -14
|
@@ -0,0 +1,1003 @@
|
|
|
1
|
+
# Views
|
|
2
|
+
|
|
3
|
+
> Store a query as a view, change it, join and combine tables in it, put it in a schema, and read the note that shows it.
|
|
4
|
+
|
|
5
|
+
A view is a `select_rows` query stored under a name in `metastore.yaml`. You read it like a table, narrow it with more filters, and agents read it instead of rebuilding the filter, so the answer follows your definition.
|
|
6
|
+
|
|
7
|
+
The examples query a diary of classic films with three tables: `film`, `actor` for the cast, and `watch` with one row per viewing from the last few weeks.
|
|
8
|
+
|
|
9
|
+
## Store a query as a view
|
|
10
|
+
|
|
11
|
+
`create_view` stores a query in `metastore.yaml` under a name; give it the `vw_` prefix. You select a view like a table and can narrow it further, and it writes no note.
|
|
12
|
+
|
|
13
|
+
Agents find a view by its `description` and `aliases`. `labels` are the column headings a client shows when it renders the view as a table in a note; `select_rows` still answers with the column names.
|
|
14
|
+
|
|
15
|
+
**`create_view`**
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"name": "vw_recent_watches",
|
|
20
|
+
"query": {
|
|
21
|
+
"table": "watch",
|
|
22
|
+
"columns": ["film", "occurred_at", "where", "place"],
|
|
23
|
+
"where": { "occurred_at": { "gte": "{today-14d}" } },
|
|
24
|
+
"order_by": "-occurred_at"
|
|
25
|
+
},
|
|
26
|
+
"description": "Films watched in the last two weeks",
|
|
27
|
+
"aliases": ["what I watched lately"],
|
|
28
|
+
"labels": {
|
|
29
|
+
"film": "Film",
|
|
30
|
+
"occurred_at": "Watched",
|
|
31
|
+
"where": "Where",
|
|
32
|
+
"place": "Place"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Answer:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"ok": true,
|
|
42
|
+
"op": "create_view",
|
|
43
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
44
|
+
"migration_id": "20261012T071956-create_view-create-view-main-public-vw_rec"
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
A `where` in `select_rows` narrows the view. It combines with the view’s own filter this way:
|
|
49
|
+
|
|
50
|
+
* **A column the view doesn’t filter**: the engine adds the condition to the view’s filter
|
|
51
|
+
* **A column the view filters**: the engine replaces an operator the view already has and adds a new one
|
|
52
|
+
* **`or`, `and` or `not` on either side**: both filters apply
|
|
53
|
+
|
|
54
|
+
**`select_rows`**
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{ "table": "vw_recent_watches", "where": { "where": "home" } }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Answer:
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"table": "main.public.watch",
|
|
65
|
+
"total": 2,
|
|
66
|
+
"rows": [
|
|
67
|
+
{
|
|
68
|
+
"path": "datanotes/main/public/watch/2026-10-10T2030.md",
|
|
69
|
+
"film": "[[The Gold Rush]]",
|
|
70
|
+
"occurred_at": "2026-10-10T20:30",
|
|
71
|
+
"where": "home",
|
|
72
|
+
"place": "my living room"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"path": "datanotes/main/public/watch/2026-10-07T2115.md",
|
|
76
|
+
"film": "[[Charade]]",
|
|
77
|
+
"occurred_at": "2026-10-07T21:15",
|
|
78
|
+
"where": "home",
|
|
79
|
+
"place": "my living room"
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"view": "main.public.vw_recent_watches"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`list_tables` lists the views next to the tables:
|
|
87
|
+
|
|
88
|
+
**`list_tables`** (no arguments)
|
|
89
|
+
|
|
90
|
+
Answer:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"views": [
|
|
95
|
+
{
|
|
96
|
+
"name": "vw_recent_watches",
|
|
97
|
+
"catalog": "main",
|
|
98
|
+
"schema": "public",
|
|
99
|
+
"qualified": "main.public.vw_recent_watches",
|
|
100
|
+
"description": "Films watched in the last two weeks",
|
|
101
|
+
"aliases": ["what I watched lately"]
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Change an existing view
|
|
108
|
+
|
|
109
|
+
Once a view exists, `create_view` refuses its name. `replace: true` replaces the whole view, like `CREATE OR REPLACE VIEW` in Structured Query Language (SQL), so pass its `description`, `aliases` and `labels` again.
|
|
110
|
+
|
|
111
|
+
**`create_view`**
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"name": "vw_recent_watches",
|
|
116
|
+
"query": { "table": "watch", "where": { "occurred_at": { "gte": "{today-30d}" } } }
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Refused:
|
|
121
|
+
|
|
122
|
+
```text
|
|
123
|
+
create_view refused — nothing was written:
|
|
124
|
+
conflict main.public.vw_recent_watches: main.public.vw_recent_watches already exists (pass replace)
|
|
125
|
+
Hint: The name is taken: choose another one, or pass replace: true to replace a view.
|
|
126
|
+
Docs: https://datanotes.dev/guides/database-objects/catalogs-and-schemas.md#place-tables-in-catalogs-and-schemas (offline: read_docs("guides/database-objects/catalogs-and-schemas#place-tables-in-catalogs-and-schemas"))
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**`create_view`**
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"name": "vw_recent_watches",
|
|
134
|
+
"replace": true,
|
|
135
|
+
"query": {
|
|
136
|
+
"table": "watch",
|
|
137
|
+
"columns": ["film", "occurred_at", "where", "place"],
|
|
138
|
+
"where": { "occurred_at": { "gte": "{today-30d}" } },
|
|
139
|
+
"order_by": "-occurred_at"
|
|
140
|
+
},
|
|
141
|
+
"description": "Films watched in the last month",
|
|
142
|
+
"aliases": ["what I watched lately"],
|
|
143
|
+
"labels": {
|
|
144
|
+
"film": "Film",
|
|
145
|
+
"occurred_at": "Watched",
|
|
146
|
+
"where": "Where",
|
|
147
|
+
"place": "Place"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Answer:
|
|
153
|
+
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"ok": true,
|
|
157
|
+
"op": "create_view",
|
|
158
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
159
|
+
"migration_id": "20261012T071956-create_view-create-view-main-public-vw_rec-2"
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Join and expand rows in a view
|
|
164
|
+
|
|
165
|
+
A view stores any query. This one keeps the last three films watched (`order_by`, `limit`) and puts the notes of each film’s cast inline (`expand`). A `left` join attaches the viewing of the `watched_on` day, so a film with no viewing logged that day gets an empty list.
|
|
166
|
+
|
|
167
|
+
**`create_view`**
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"name": "vw_last_watched",
|
|
172
|
+
"query": {
|
|
173
|
+
"table": "film",
|
|
174
|
+
"columns": ["title", "watched_on", "cast"],
|
|
175
|
+
"where": { "status": "watched" },
|
|
176
|
+
"expand": ["cast"],
|
|
177
|
+
"join": {
|
|
178
|
+
"table": "watch",
|
|
179
|
+
"on": { "watched_on": "date(occurred_at)" },
|
|
180
|
+
"as": "viewing",
|
|
181
|
+
"type": "left",
|
|
182
|
+
"columns": ["where"]
|
|
183
|
+
},
|
|
184
|
+
"order_by": "-watched_on",
|
|
185
|
+
"limit": 3
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Answer:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"ok": true,
|
|
195
|
+
"op": "create_view",
|
|
196
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
197
|
+
"migration_id": "20261012T071956-create_view-create-view-main-public-vw_las"
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**`select_rows`**
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{ "table": "vw_last_watched" }
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Answer (65 lines)
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"table": "main.public.film",
|
|
212
|
+
"total": 6,
|
|
213
|
+
"rows": [
|
|
214
|
+
{
|
|
215
|
+
"path": "datanotes/main/public/film/Night of the Living Dead.md",
|
|
216
|
+
"title": "Night of the Living Dead",
|
|
217
|
+
"watched_on": "2026-10-11",
|
|
218
|
+
"cast": [
|
|
219
|
+
{
|
|
220
|
+
"path": "datanotes/main/public/actor/Duane Jones.md",
|
|
221
|
+
"table": "main.public.actor",
|
|
222
|
+
"id": "01a12efb-7fd1-74b0-ad94-c0ee904521ad",
|
|
223
|
+
"name": "Duane Jones",
|
|
224
|
+
"born": "1937-04-02"
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
"viewing": [
|
|
228
|
+
{ "path": "datanotes/main/public/watch/2026-10-11T2200.md", "where": "cinema" }
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"path": "datanotes/main/public/film/The Gold Rush.md",
|
|
233
|
+
"title": "The Gold Rush",
|
|
234
|
+
"watched_on": "2026-10-10",
|
|
235
|
+
"cast": [
|
|
236
|
+
{
|
|
237
|
+
"path": "datanotes/main/public/actor/Charlie Chaplin.md",
|
|
238
|
+
"table": "main.public.actor",
|
|
239
|
+
"id": "01a12efb-7fb2-7ee5-99d8-282dff2a79e5",
|
|
240
|
+
"name": "Charlie Chaplin",
|
|
241
|
+
"born": "1889-04-16"
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
"viewing": [
|
|
245
|
+
{ "path": "datanotes/main/public/watch/2026-10-10T2030.md", "where": "home" }
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"path": "datanotes/main/public/film/Charade.md",
|
|
250
|
+
"title": "Charade",
|
|
251
|
+
"watched_on": "2026-10-07",
|
|
252
|
+
"cast": [
|
|
253
|
+
{
|
|
254
|
+
"path": "datanotes/main/public/actor/Cary Grant.md",
|
|
255
|
+
"table": "main.public.actor",
|
|
256
|
+
"id": "01a12efb-7fbf-77c3-888b-698d82923a6f",
|
|
257
|
+
"name": "Cary Grant",
|
|
258
|
+
"born": "1904-01-18"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"path": "datanotes/main/public/actor/Audrey Hepburn.md",
|
|
262
|
+
"table": "main.public.actor",
|
|
263
|
+
"id": "01a12efb-7fca-74dd-b41c-fed458b65dc9",
|
|
264
|
+
"name": "Audrey Hepburn",
|
|
265
|
+
"born": "1929-05-04"
|
|
266
|
+
}
|
|
267
|
+
],
|
|
268
|
+
"viewing": [
|
|
269
|
+
{ "path": "datanotes/main/public/watch/2026-10-07T2115.md", "where": "home" }
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
],
|
|
273
|
+
"view": "main.public.vw_last_watched"
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Combine several tables in one view
|
|
278
|
+
|
|
279
|
+
A view with `union` stacks the rows of several queries, like SQL’s `UNION ALL`, on one table or on several. It tags each row with `_source`, and each branch takes `table`, `columns` and `where`. Next to `union`, these keys apply to the whole view:
|
|
280
|
+
|
|
281
|
+
* **`columns`**: the columns of every branch that gives none
|
|
282
|
+
* **`where`**: a filter on every branch, on top of its own
|
|
283
|
+
* **`expand`**: the links to expand in every branch
|
|
284
|
+
* **`order_by`** and **`limit`**: the order and the number of the stacked rows
|
|
285
|
+
|
|
286
|
+
This view stacks the films made before 1960 and the actors. Its `where` keeps the notes that at least two other notes link to: the films and actors your diary mentions most.
|
|
287
|
+
|
|
288
|
+
**`create_view`**
|
|
289
|
+
|
|
290
|
+
```json
|
|
291
|
+
{
|
|
292
|
+
"name": "vw_most_linked",
|
|
293
|
+
"query": {
|
|
294
|
+
"union": [
|
|
295
|
+
{
|
|
296
|
+
"table": "film",
|
|
297
|
+
"columns": ["title", "year"],
|
|
298
|
+
"where": { "year": { "lt": 1960 } }
|
|
299
|
+
},
|
|
300
|
+
{ "table": "actor" }
|
|
301
|
+
],
|
|
302
|
+
"columns": ["name"],
|
|
303
|
+
"where": { "file_backlink_count": { "gte": 2 } },
|
|
304
|
+
"order_by": "path"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Answer:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"ok": true,
|
|
314
|
+
"op": "create_view",
|
|
315
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
316
|
+
"migration_id": "20261012T071956-create_view-create-view-main-public-vw_mos"
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**`select_rows`**
|
|
321
|
+
|
|
322
|
+
```json
|
|
323
|
+
{ "table": "vw_most_linked" }
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Answer:
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{
|
|
330
|
+
"table": "union",
|
|
331
|
+
"total": 3,
|
|
332
|
+
"rows": [
|
|
333
|
+
{
|
|
334
|
+
"path": "datanotes/main/public/actor/Cary Grant.md",
|
|
335
|
+
"name": "Cary Grant",
|
|
336
|
+
"_source": "actor"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"path": "datanotes/main/public/film/His Girl Friday.md",
|
|
340
|
+
"title": "His Girl Friday",
|
|
341
|
+
"year": 1940,
|
|
342
|
+
"_source": "film"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"path": "datanotes/main/public/film/The Gold Rush.md",
|
|
346
|
+
"title": "The Gold Rush",
|
|
347
|
+
"year": 1925,
|
|
348
|
+
"_source": "film"
|
|
349
|
+
}
|
|
350
|
+
],
|
|
351
|
+
"view": "main.public.vw_most_linked"
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
The branches can read the same table. This view stacks every trip to the cinema and the last week’s viewings at home. It keeps the three latest and puts each film’s note inline:
|
|
356
|
+
|
|
357
|
+
**`create_view`**
|
|
358
|
+
|
|
359
|
+
```json
|
|
360
|
+
{
|
|
361
|
+
"name": "vw_latest_watches",
|
|
362
|
+
"query": {
|
|
363
|
+
"union": [
|
|
364
|
+
{ "table": "watch", "where": { "where": "cinema" } },
|
|
365
|
+
{
|
|
366
|
+
"table": "watch",
|
|
367
|
+
"where": { "where": "home", "occurred_at": { "gte": "{today-7d}" } }
|
|
368
|
+
}
|
|
369
|
+
],
|
|
370
|
+
"columns": ["film", "occurred_at", "where"],
|
|
371
|
+
"expand": ["film"],
|
|
372
|
+
"order_by": "-occurred_at",
|
|
373
|
+
"limit": 3
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Answer:
|
|
379
|
+
|
|
380
|
+
```json
|
|
381
|
+
{
|
|
382
|
+
"ok": true,
|
|
383
|
+
"op": "create_view",
|
|
384
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
385
|
+
"migration_id": "20261012T071956-create_view-create-view-main-public-vw_lat"
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
**`select_rows`**
|
|
390
|
+
|
|
391
|
+
```json
|
|
392
|
+
{ "table": "vw_latest_watches" }
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Answer (64 lines)
|
|
396
|
+
|
|
397
|
+
```json
|
|
398
|
+
{
|
|
399
|
+
"table": "union",
|
|
400
|
+
"total": 4,
|
|
401
|
+
"rows": [
|
|
402
|
+
{
|
|
403
|
+
"path": "datanotes/main/public/watch/2026-10-11T2200.md",
|
|
404
|
+
"film": {
|
|
405
|
+
"path": "datanotes/main/public/film/Night of the Living Dead.md",
|
|
406
|
+
"table": "main.public.film",
|
|
407
|
+
"id": "01a12efb-801a-78dc-83af-7ff7ecf09dd4",
|
|
408
|
+
"title": "Night of the Living Dead",
|
|
409
|
+
"year": 1968,
|
|
410
|
+
"minutes": 96,
|
|
411
|
+
"status": "watched",
|
|
412
|
+
"rating": 4,
|
|
413
|
+
"watched_on": "2026-10-11",
|
|
414
|
+
"director": "George A. Romero",
|
|
415
|
+
"cast": ["[[Duane Jones]]"]
|
|
416
|
+
},
|
|
417
|
+
"occurred_at": "2026-10-11T22:00",
|
|
418
|
+
"where": "cinema",
|
|
419
|
+
"_source": "watch"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
"path": "datanotes/main/public/watch/2026-10-10T2030.md",
|
|
423
|
+
"film": {
|
|
424
|
+
"path": "datanotes/main/public/film/The Gold Rush.md",
|
|
425
|
+
"table": "main.public.film",
|
|
426
|
+
"id": "01a12efb-7ffa-7aa8-988d-eba752b6277e",
|
|
427
|
+
"title": "The Gold Rush",
|
|
428
|
+
"year": 1925,
|
|
429
|
+
"minutes": 95,
|
|
430
|
+
"status": "watched",
|
|
431
|
+
"rating": 5,
|
|
432
|
+
"watched_on": "2026-10-10",
|
|
433
|
+
"director": "Charlie Chaplin",
|
|
434
|
+
"cast": ["[[Charlie Chaplin]]"]
|
|
435
|
+
},
|
|
436
|
+
"occurred_at": "2026-10-10T20:30",
|
|
437
|
+
"where": "home",
|
|
438
|
+
"_source": "watch"
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"path": "datanotes/main/public/watch/2026-10-07T2115.md",
|
|
442
|
+
"film": {
|
|
443
|
+
"path": "datanotes/main/public/film/Charade.md",
|
|
444
|
+
"table": "main.public.film",
|
|
445
|
+
"id": "01a12efb-8012-7876-bcf6-ea1a58b2cdec",
|
|
446
|
+
"title": "Charade",
|
|
447
|
+
"year": 1963,
|
|
448
|
+
"minutes": 113,
|
|
449
|
+
"status": "watched",
|
|
450
|
+
"rating": 4,
|
|
451
|
+
"watched_on": "2026-10-07",
|
|
452
|
+
"director": "Stanley Donen",
|
|
453
|
+
"cast": ["[[Cary Grant]]", "[[Audrey Hepburn]]"]
|
|
454
|
+
},
|
|
455
|
+
"occurred_at": "2026-10-07T21:15",
|
|
456
|
+
"where": "home",
|
|
457
|
+
"_source": "watch"
|
|
458
|
+
}
|
|
459
|
+
],
|
|
460
|
+
"view": "main.public.vw_latest_watches"
|
|
461
|
+
}
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
`drop_view` removes a view, and `undo_migration` puts it back, as it does for every schema change:
|
|
465
|
+
|
|
466
|
+
**`drop_view`**
|
|
467
|
+
|
|
468
|
+
```json
|
|
469
|
+
{ "view": "vw_most_linked" }
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Answer:
|
|
473
|
+
|
|
474
|
+
```json
|
|
475
|
+
{
|
|
476
|
+
"ok": true,
|
|
477
|
+
"op": "drop_view",
|
|
478
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
479
|
+
"migration_id": "20261012T071956-drop_view-drop-view-main-public-vw_most_"
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
**`undo_migration`**
|
|
484
|
+
|
|
485
|
+
```json
|
|
486
|
+
{ "migration_id": "20261012T071956-drop_view-drop-view-main-public-vw_most_" }
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Answer:
|
|
490
|
+
|
|
491
|
+
```json
|
|
492
|
+
{
|
|
493
|
+
"ok": true,
|
|
494
|
+
"op": "undo_migration",
|
|
495
|
+
"undoes": "20261012T071956-drop_view-drop-view-main-public-vw_most_",
|
|
496
|
+
"migration_id": "20261012T071956-undo_migration-undo-20261012t071956-drop_view",
|
|
497
|
+
"conflicts": [],
|
|
498
|
+
"failed": []
|
|
499
|
+
}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
## Put a view in a schema of its own
|
|
503
|
+
|
|
504
|
+
`catalog` and `schema` place a view the way they place a table, and default to the database’s default catalog and schema. A schema can hold views only. The query can read the tables of any schema, named here in full.
|
|
505
|
+
|
|
506
|
+
**`create_view`**
|
|
507
|
+
|
|
508
|
+
```json
|
|
509
|
+
{
|
|
510
|
+
"catalog": "main",
|
|
511
|
+
"schema": "reports",
|
|
512
|
+
"name": "vw_watches_by_place",
|
|
513
|
+
"query": {
|
|
514
|
+
"table": "main.public.watch",
|
|
515
|
+
"group_by": "where",
|
|
516
|
+
"aggregates": { "viewings": "count" }
|
|
517
|
+
},
|
|
518
|
+
"description": "Viewings at the cinema, at home and outdoors"
|
|
519
|
+
}
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Answer:
|
|
523
|
+
|
|
524
|
+
```json
|
|
525
|
+
{
|
|
526
|
+
"ok": true,
|
|
527
|
+
"op": "create_view",
|
|
528
|
+
"planned_texts": ["datanotes/metastore.yaml"],
|
|
529
|
+
"migration_id": "20261012T071956-create_view-create-view-main-reports-vw_wa"
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
**`select_rows`**
|
|
534
|
+
|
|
535
|
+
```json
|
|
536
|
+
{ "table": "reports.vw_watches_by_place" }
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
Answer:
|
|
540
|
+
|
|
541
|
+
```json
|
|
542
|
+
{
|
|
543
|
+
"table": "main.public.watch",
|
|
544
|
+
"total": 3,
|
|
545
|
+
"rows": [
|
|
546
|
+
{ "where": "cinema", "viewings": 2 },
|
|
547
|
+
{ "where": "home", "viewings": 4 },
|
|
548
|
+
{ "where": "outdoor screening", "viewings": 1 }
|
|
549
|
+
],
|
|
550
|
+
"view": "main.reports.vw_watches_by_place"
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
## Read the note that shows a view with `{this.*}`
|
|
555
|
+
|
|
556
|
+
A view can read the note that shows it, so one view serves every note of a kind. These are the tokens:
|
|
557
|
+
|
|
558
|
+
* **`{this.<property>}`**: a front matter key of that note, such as `{this.watched_on}`; `{this.watched_on+1d}` is the day after and `{this.watched_on-1w}` a week before
|
|
559
|
+
* **`{this.link}`**: a link to the note
|
|
560
|
+
* **`{this.name}`** and **`{this.path}`**: the note’s name and vault path
|
|
561
|
+
|
|
562
|
+
The engine stores the tokens as written. It fills them in when `select_rows` names the note with `this_note`, which a client passes when it shows the view inside a note. This `batch` creates four views:
|
|
563
|
+
|
|
564
|
+
* **`vw_watches_that_day`**: the viewings on a film’s `watched_on` day
|
|
565
|
+
* **`vw_film_watches`**: every viewing of a film
|
|
566
|
+
* **`vw_same_status`**: the other films with the film’s status
|
|
567
|
+
* **`vw_films_with`**: the films of an actor’s note
|
|
568
|
+
|
|
569
|
+
**`batch`**
|
|
570
|
+
|
|
571
|
+
```json
|
|
572
|
+
{
|
|
573
|
+
"summary": "views for film and actor notes",
|
|
574
|
+
"operations": [
|
|
575
|
+
{
|
|
576
|
+
"op": "create_view",
|
|
577
|
+
"name": "vw_watches_that_day",
|
|
578
|
+
"query": {
|
|
579
|
+
"table": "watch",
|
|
580
|
+
"where": {
|
|
581
|
+
"occurred_at": { "gte": "{this.watched_on}", "lt": "{this.watched_on+1d}" }
|
|
582
|
+
},
|
|
583
|
+
"order_by": "occurred_at"
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
"op": "create_view",
|
|
588
|
+
"name": "vw_film_watches",
|
|
589
|
+
"query": {
|
|
590
|
+
"table": "watch",
|
|
591
|
+
"columns": ["occurred_at", "where"],
|
|
592
|
+
"where": { "film": "{this.link}" }
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"op": "create_view",
|
|
597
|
+
"name": "vw_same_status",
|
|
598
|
+
"query": {
|
|
599
|
+
"table": "film",
|
|
600
|
+
"columns": ["title"],
|
|
601
|
+
"where": { "status": "{this.status}", "path": { "ne": "{this.path}" } }
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
"op": "create_view",
|
|
606
|
+
"name": "vw_films_with",
|
|
607
|
+
"query": {
|
|
608
|
+
"table": "film",
|
|
609
|
+
"columns": ["title", "year"],
|
|
610
|
+
"where": { "cast": { "contains": "[[{this.name}]]" } }
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
]
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Answer:
|
|
618
|
+
|
|
619
|
+
```json
|
|
620
|
+
{
|
|
621
|
+
"ok": true,
|
|
622
|
+
"migration_id": "20261012T071957-batch-views-for-film-and-actor-notes",
|
|
623
|
+
"steps": [
|
|
624
|
+
{ "op": "create_view", "ok": true },
|
|
625
|
+
{ "op": "create_view", "ok": true },
|
|
626
|
+
{ "op": "create_view", "ok": true },
|
|
627
|
+
{ "op": "create_view", "ok": true }
|
|
628
|
+
]
|
|
629
|
+
}
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
`this_note` takes the vault path of the note the result is for, and the tokens read that note. These are the viewings of The Gold Rush, as its note shows them:
|
|
633
|
+
|
|
634
|
+
**`select_rows`**
|
|
635
|
+
|
|
636
|
+
```json
|
|
637
|
+
{ "table": "vw_film_watches", "this_note": "datanotes/main/public/film/The Gold Rush.md" }
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
Answer:
|
|
641
|
+
|
|
642
|
+
```json
|
|
643
|
+
{
|
|
644
|
+
"table": "main.public.watch",
|
|
645
|
+
"total": 2,
|
|
646
|
+
"rows": [
|
|
647
|
+
{
|
|
648
|
+
"path": "datanotes/main/public/watch/2026-09-23T2100.md",
|
|
649
|
+
"occurred_at": "2026-09-23T21:00",
|
|
650
|
+
"where": "home"
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
"path": "datanotes/main/public/watch/2026-10-10T2030.md",
|
|
654
|
+
"occurred_at": "2026-10-10T20:30",
|
|
655
|
+
"where": "home"
|
|
656
|
+
}
|
|
657
|
+
],
|
|
658
|
+
"view": "main.public.vw_film_watches"
|
|
659
|
+
}
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
For the same note, `{this.watched_on}` is the day you last watched The Gold Rush:
|
|
663
|
+
|
|
664
|
+
**`select_rows`**
|
|
665
|
+
|
|
666
|
+
```json
|
|
667
|
+
{
|
|
668
|
+
"table": "vw_watches_that_day",
|
|
669
|
+
"columns": ["film", "occurred_at", "where"],
|
|
670
|
+
"this_note": "datanotes/main/public/film/The Gold Rush.md"
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
Answer:
|
|
675
|
+
|
|
676
|
+
```json
|
|
677
|
+
{
|
|
678
|
+
"table": "main.public.watch",
|
|
679
|
+
"total": 1,
|
|
680
|
+
"rows": [
|
|
681
|
+
{
|
|
682
|
+
"path": "datanotes/main/public/watch/2026-10-10T2030.md",
|
|
683
|
+
"film": "[[The Gold Rush]]",
|
|
684
|
+
"occurred_at": "2026-10-10T20:30",
|
|
685
|
+
"where": "home"
|
|
686
|
+
}
|
|
687
|
+
],
|
|
688
|
+
"view": "main.public.vw_watches_that_day"
|
|
689
|
+
}
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
For Metropolis’s note, `{this.status}` is its `status` and `{this.path}` leaves Metropolis itself out. This is the other film still to watch:
|
|
693
|
+
|
|
694
|
+
**`select_rows`**
|
|
695
|
+
|
|
696
|
+
```json
|
|
697
|
+
{ "table": "vw_same_status", "this_note": "datanotes/main/public/film/Metropolis.md" }
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
Answer:
|
|
701
|
+
|
|
702
|
+
```json
|
|
703
|
+
{
|
|
704
|
+
"table": "main.public.film",
|
|
705
|
+
"total": 1,
|
|
706
|
+
"rows": [
|
|
707
|
+
{
|
|
708
|
+
"path": "datanotes/main/public/film/Battleship Potemkin.md",
|
|
709
|
+
"title": "Battleship Potemkin"
|
|
710
|
+
}
|
|
711
|
+
],
|
|
712
|
+
"view": "main.public.vw_same_status"
|
|
713
|
+
}
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
For Cary Grant’s note, `[[{this.name}]]` is a link to him:
|
|
717
|
+
|
|
718
|
+
**`select_rows`**
|
|
719
|
+
|
|
720
|
+
```json
|
|
721
|
+
{ "table": "vw_films_with", "this_note": "datanotes/main/public/actor/Cary Grant.md" }
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
Answer:
|
|
725
|
+
|
|
726
|
+
```json
|
|
727
|
+
{
|
|
728
|
+
"table": "main.public.film",
|
|
729
|
+
"total": 2,
|
|
730
|
+
"rows": [
|
|
731
|
+
{ "path": "datanotes/main/public/film/Charade.md", "title": "Charade", "year": 1963 },
|
|
732
|
+
{
|
|
733
|
+
"path": "datanotes/main/public/film/His Girl Friday.md",
|
|
734
|
+
"title": "His Girl Friday",
|
|
735
|
+
"year": 1940
|
|
736
|
+
}
|
|
737
|
+
],
|
|
738
|
+
"view": "main.public.vw_films_with"
|
|
739
|
+
}
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
Without `this_note`, a token stays as written and matches no row, whatever its operator. That holds for `film: "{this.link}"` here, for a `ne` like the `path` one, and for `within`.
|
|
743
|
+
|
|
744
|
+
**`select_rows`**
|
|
745
|
+
|
|
746
|
+
```json
|
|
747
|
+
{ "table": "vw_film_watches" }
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
Answer:
|
|
751
|
+
|
|
752
|
+
```json
|
|
753
|
+
{
|
|
754
|
+
"table": "main.public.watch",
|
|
755
|
+
"total": 0,
|
|
756
|
+
"rows": [],
|
|
757
|
+
"view": "main.public.vw_film_watches"
|
|
758
|
+
}
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
## See the views in `metastore.yaml`
|
|
762
|
+
|
|
763
|
+
The engine wrote this page’s views under `views:` in their schema, next to the tables. It keeps each query as you gave it, with its relative dates and `{this.*}` tokens.
|
|
764
|
+
|
|
765
|
+
`datanotes/metastore.yaml` now reads:
|
|
766
|
+
|
|
767
|
+
```yaml
|
|
768
|
+
# Metastore (Datanotes): catalogs, schemas, tables, columns, views.
|
|
769
|
+
id: 01a12efb-7f9b-7cd3-a1ae-d70e8a8d4ef4
|
|
770
|
+
config:
|
|
771
|
+
history: true
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
catalogs:
|
|
775
|
+
main:
|
|
776
|
+
schemas:
|
|
777
|
+
public:
|
|
778
|
+
tables:
|
|
779
|
+
actor:
|
|
780
|
+
description: Actors of the films I watch
|
|
781
|
+
options:
|
|
782
|
+
filename: "{name}"
|
|
783
|
+
archive: _archive
|
|
784
|
+
columns:
|
|
785
|
+
- name: id
|
|
786
|
+
type: string
|
|
787
|
+
required: true
|
|
788
|
+
description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
|
|
789
|
+
unique: true
|
|
790
|
+
identity: uuid
|
|
791
|
+
dense: true
|
|
792
|
+
- name: name
|
|
793
|
+
type: string
|
|
794
|
+
required: true
|
|
795
|
+
description: The actor's name, as credited
|
|
796
|
+
- name: born
|
|
797
|
+
type: date
|
|
798
|
+
description: The actor's date of birth
|
|
799
|
+
film:
|
|
800
|
+
description: Classic films I watched or want to watch
|
|
801
|
+
options:
|
|
802
|
+
filename: "{title}"
|
|
803
|
+
archive: _archive
|
|
804
|
+
columns:
|
|
805
|
+
- name: id
|
|
806
|
+
type: string
|
|
807
|
+
required: true
|
|
808
|
+
description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
|
|
809
|
+
unique: true
|
|
810
|
+
identity: uuid
|
|
811
|
+
dense: true
|
|
812
|
+
- name: title
|
|
813
|
+
type: string
|
|
814
|
+
required: true
|
|
815
|
+
description: The film's title, as on its poster
|
|
816
|
+
unique: true
|
|
817
|
+
- name: year
|
|
818
|
+
type: integer
|
|
819
|
+
description: Year the film first came out
|
|
820
|
+
- name: minutes
|
|
821
|
+
type: integer
|
|
822
|
+
min: 1
|
|
823
|
+
description: Running time in minutes
|
|
824
|
+
- name: status
|
|
825
|
+
type: enum
|
|
826
|
+
values:
|
|
827
|
+
- to watch
|
|
828
|
+
- watched
|
|
829
|
+
description: Where the film is on my list
|
|
830
|
+
ordered: true
|
|
831
|
+
- name: rating
|
|
832
|
+
type: integer
|
|
833
|
+
min: 1
|
|
834
|
+
max: 5
|
|
835
|
+
description: My rating, from 1 (poor) to 5 (a masterpiece)
|
|
836
|
+
- name: watched_on
|
|
837
|
+
type: date
|
|
838
|
+
description: The day I last watched it
|
|
839
|
+
- name: director
|
|
840
|
+
type: string
|
|
841
|
+
description: Who directed the film
|
|
842
|
+
- name: cast
|
|
843
|
+
type: list
|
|
844
|
+
items: link
|
|
845
|
+
ref: main.public.actor
|
|
846
|
+
description: The actors in the film
|
|
847
|
+
watch:
|
|
848
|
+
description: Each time I watch a film
|
|
849
|
+
options:
|
|
850
|
+
filename: "{occurred_at:YYYY-MM-DD[T]HHmm}"
|
|
851
|
+
archive: _archive
|
|
852
|
+
columns:
|
|
853
|
+
- name: id
|
|
854
|
+
type: string
|
|
855
|
+
required: true
|
|
856
|
+
description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
|
|
857
|
+
unique: true
|
|
858
|
+
identity: uuid
|
|
859
|
+
dense: true
|
|
860
|
+
- name: film
|
|
861
|
+
type: link
|
|
862
|
+
required: true
|
|
863
|
+
ref: main.public.film
|
|
864
|
+
description: The film I watched
|
|
865
|
+
- name: occurred_at
|
|
866
|
+
type: datetime
|
|
867
|
+
required: true
|
|
868
|
+
description: When the film started
|
|
869
|
+
- name: where
|
|
870
|
+
type: enum
|
|
871
|
+
values:
|
|
872
|
+
- cinema
|
|
873
|
+
- home
|
|
874
|
+
- outdoor screening
|
|
875
|
+
description: The kind of place I watched it in
|
|
876
|
+
- name: place
|
|
877
|
+
type: string
|
|
878
|
+
description: The cinema, park or room, in my words
|
|
879
|
+
- name: with
|
|
880
|
+
type: string
|
|
881
|
+
description: Who watched it with me
|
|
882
|
+
views:
|
|
883
|
+
vw_recent_watches:
|
|
884
|
+
description: Films watched in the last month
|
|
885
|
+
aliases:
|
|
886
|
+
- what I watched lately
|
|
887
|
+
labels:
|
|
888
|
+
film: Film
|
|
889
|
+
occurred_at: Watched
|
|
890
|
+
where: Where
|
|
891
|
+
place: Place
|
|
892
|
+
query:
|
|
893
|
+
table: watch
|
|
894
|
+
columns:
|
|
895
|
+
- film
|
|
896
|
+
- occurred_at
|
|
897
|
+
- where
|
|
898
|
+
- place
|
|
899
|
+
where:
|
|
900
|
+
occurred_at:
|
|
901
|
+
gte: "{today-30d}"
|
|
902
|
+
order_by: -occurred_at
|
|
903
|
+
vw_last_watched:
|
|
904
|
+
query:
|
|
905
|
+
table: film
|
|
906
|
+
columns:
|
|
907
|
+
- title
|
|
908
|
+
- watched_on
|
|
909
|
+
- cast
|
|
910
|
+
where:
|
|
911
|
+
status: watched
|
|
912
|
+
expand:
|
|
913
|
+
- cast
|
|
914
|
+
join:
|
|
915
|
+
table: watch
|
|
916
|
+
on:
|
|
917
|
+
watched_on: date(occurred_at)
|
|
918
|
+
as: viewing
|
|
919
|
+
type: left
|
|
920
|
+
columns:
|
|
921
|
+
- where
|
|
922
|
+
order_by: -watched_on
|
|
923
|
+
limit: 3
|
|
924
|
+
vw_most_linked:
|
|
925
|
+
query:
|
|
926
|
+
union:
|
|
927
|
+
- table: film
|
|
928
|
+
columns:
|
|
929
|
+
- title
|
|
930
|
+
- year
|
|
931
|
+
where:
|
|
932
|
+
year:
|
|
933
|
+
lt: 1960
|
|
934
|
+
- table: actor
|
|
935
|
+
columns:
|
|
936
|
+
- name
|
|
937
|
+
where:
|
|
938
|
+
file_backlink_count:
|
|
939
|
+
gte: 2
|
|
940
|
+
order_by: path
|
|
941
|
+
vw_latest_watches:
|
|
942
|
+
query:
|
|
943
|
+
union:
|
|
944
|
+
- table: watch
|
|
945
|
+
where:
|
|
946
|
+
where: cinema
|
|
947
|
+
- table: watch
|
|
948
|
+
where:
|
|
949
|
+
where: home
|
|
950
|
+
occurred_at:
|
|
951
|
+
gte: "{today-7d}"
|
|
952
|
+
columns:
|
|
953
|
+
- film
|
|
954
|
+
- occurred_at
|
|
955
|
+
- where
|
|
956
|
+
expand:
|
|
957
|
+
- film
|
|
958
|
+
order_by: -occurred_at
|
|
959
|
+
limit: 3
|
|
960
|
+
vw_watches_that_day:
|
|
961
|
+
query:
|
|
962
|
+
table: watch
|
|
963
|
+
where:
|
|
964
|
+
occurred_at:
|
|
965
|
+
gte: "{this.watched_on}"
|
|
966
|
+
lt: "{this.watched_on+1d}"
|
|
967
|
+
order_by: occurred_at
|
|
968
|
+
vw_film_watches:
|
|
969
|
+
query:
|
|
970
|
+
table: watch
|
|
971
|
+
columns:
|
|
972
|
+
- occurred_at
|
|
973
|
+
- where
|
|
974
|
+
where:
|
|
975
|
+
film: "{this.link}"
|
|
976
|
+
vw_same_status:
|
|
977
|
+
query:
|
|
978
|
+
table: film
|
|
979
|
+
columns:
|
|
980
|
+
- title
|
|
981
|
+
where:
|
|
982
|
+
status: "{this.status}"
|
|
983
|
+
path:
|
|
984
|
+
ne: "{this.path}"
|
|
985
|
+
vw_films_with:
|
|
986
|
+
query:
|
|
987
|
+
table: film
|
|
988
|
+
columns:
|
|
989
|
+
- title
|
|
990
|
+
- year
|
|
991
|
+
where:
|
|
992
|
+
cast:
|
|
993
|
+
contains: "[[{this.name}]]"
|
|
994
|
+
reports:
|
|
995
|
+
views:
|
|
996
|
+
vw_watches_by_place:
|
|
997
|
+
description: Viewings at the cinema, at home and outdoors
|
|
998
|
+
query:
|
|
999
|
+
table: main.public.watch
|
|
1000
|
+
group_by: where
|
|
1001
|
+
aggregates:
|
|
1002
|
+
viewings: count
|
|
1003
|
+
```
|