datanotes 2.0.1 → 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.
Files changed (181) hide show
  1. package/NOTICE +9 -0
  2. package/README.md +207 -28
  3. package/SECURITY.md +92 -45
  4. package/dist/THIRD-PARTY-NOTICES.txt +682 -0
  5. package/dist/api/catalog.d.cts +69 -0
  6. package/dist/api/catalog.d.ts +50 -2
  7. package/dist/api/cli-options.d.cts +39 -0
  8. package/dist/api/cli-options.d.ts +39 -0
  9. package/dist/api/client.d.cts +89 -0
  10. package/dist/api/client.d.ts +19 -30
  11. package/dist/api/docs.d.cts +211 -0
  12. package/dist/api/docs.d.ts +211 -0
  13. package/dist/api/guidance.d.cts +81 -0
  14. package/dist/api/guidance.d.ts +81 -0
  15. package/dist/api/index.cjs +6610 -2247
  16. package/dist/api/index.d.cts +13 -0
  17. package/dist/api/index.d.ts +10 -7
  18. package/dist/api/index.js +6610 -2247
  19. package/dist/api/local.cjs +118 -6
  20. package/dist/api/local.d.cts +95 -0
  21. package/dist/api/local.d.ts +70 -6
  22. package/dist/api/local.js +104 -6
  23. package/dist/api/mcp.cjs +17384 -0
  24. package/dist/api/mcp.d.cts +108 -0
  25. package/dist/api/mcp.d.ts +108 -0
  26. package/dist/api/mcp.js +17334 -0
  27. package/dist/api/otlp.d.cts +65 -0
  28. package/dist/api/redact.d.cts +17 -0
  29. package/dist/api/redact.d.ts +17 -0
  30. package/dist/api/requests.d.cts +26 -0
  31. package/dist/api/requests.d.ts +14 -16
  32. package/dist/api/results.d.cts +16 -0
  33. package/dist/api/results.d.ts +2 -1
  34. package/dist/api/tokens.d.cts +7 -0
  35. package/dist/datanotes.cjs +62511 -28069
  36. package/dist/docs/administration/configuration.md +59 -0
  37. package/dist/docs/administration/docker.md +80 -0
  38. package/dist/docs/administration/git-sync.md +71 -0
  39. package/dist/docs/administration/limits.md +69 -0
  40. package/dist/docs/administration/run-the-service.md +219 -0
  41. package/dist/docs/administration/status.md +61 -0
  42. package/dist/docs/administration/use-with-obsidian.md +75 -0
  43. package/dist/docs/api/operations/add_column.md +49 -0
  44. package/dist/docs/api/operations/add_constraint.md +55 -0
  45. package/dist/docs/api/operations/adopt_rows.md +50 -0
  46. package/dist/docs/api/operations/align_relations.md +41 -0
  47. package/dist/docs/api/operations/alter_column.md +46 -0
  48. package/dist/docs/api/operations/alter_table.md +67 -0
  49. package/dist/docs/api/operations/batch.md +48 -0
  50. package/dist/docs/api/operations/changes_stream.md +28 -0
  51. package/dist/docs/api/operations/check_table.md +29 -0
  52. package/dist/docs/api/operations/clone_table.md +48 -0
  53. package/dist/docs/api/operations/comment_on.md +42 -0
  54. package/dist/docs/api/operations/configure_database.md +52 -0
  55. package/dist/docs/api/operations/create_table.md +78 -0
  56. package/dist/docs/api/operations/create_view.md +54 -0
  57. package/dist/docs/api/operations/create_webhook.md +37 -0
  58. package/dist/docs/api/operations/define_base.md +52 -0
  59. package/dist/docs/api/operations/delete_rows.md +43 -0
  60. package/dist/docs/api/operations/delete_webhook.md +31 -0
  61. package/dist/docs/api/operations/describe_database.md +30 -0
  62. package/dist/docs/api/operations/describe_history.md +40 -0
  63. package/dist/docs/api/operations/describe_semantic_index.md +24 -0
  64. package/dist/docs/api/operations/describe_table.md +38 -0
  65. package/dist/docs/api/operations/docs.md +13 -0
  66. package/dist/docs/api/operations/drop_column.md +41 -0
  67. package/dist/docs/api/operations/drop_constraint.md +39 -0
  68. package/dist/docs/api/operations/drop_table.md +43 -0
  69. package/dist/docs/api/operations/drop_view.md +38 -0
  70. package/dist/docs/api/operations/engine_status.md +23 -0
  71. package/dist/docs/api/operations/graph_neighbors.md +32 -0
  72. package/dist/docs/api/operations/graph_path.md +32 -0
  73. package/dist/docs/api/operations/graph_traverse.md +43 -0
  74. package/dist/docs/api/operations/identify_session.md +24 -0
  75. package/dist/docs/api/operations/infer_table.md +43 -0
  76. package/dist/docs/api/operations/insert_row.md +48 -0
  77. package/dist/docs/api/operations/list_changes.md +35 -0
  78. package/dist/docs/api/operations/list_folder.md +28 -0
  79. package/dist/docs/api/operations/list_link_targets.md +44 -0
  80. package/dist/docs/api/operations/list_migrations.md +35 -0
  81. package/dist/docs/api/operations/list_tables.md +32 -0
  82. package/dist/docs/api/operations/list_webhooks.md +23 -0
  83. package/dist/docs/api/operations/manual_index.md +14 -0
  84. package/dist/docs/api/operations/manual_page.md +22 -0
  85. package/dist/docs/api/operations/merge_rows.md +44 -0
  86. package/dist/docs/api/operations/move_rows.md +52 -0
  87. package/dist/docs/api/operations/openapi.md +13 -0
  88. package/dist/docs/api/operations/openapi_post.md +20 -0
  89. package/dist/docs/api/operations/read_note.md +29 -0
  90. package/dist/docs/api/operations/recompute_columns.md +44 -0
  91. package/dist/docs/api/operations/record_tool_call.md +36 -0
  92. package/dist/docs/api/operations/rename_column.md +44 -0
  93. package/dist/docs/api/operations/rename_value.md +45 -0
  94. package/dist/docs/api/operations/restore_database.md +51 -0
  95. package/dist/docs/api/operations/restore_table.md +46 -0
  96. package/dist/docs/api/operations/search_notes.md +28 -0
  97. package/dist/docs/api/operations/select_rows.md +61 -0
  98. package/dist/docs/api/operations/semantic_search.md +34 -0
  99. package/dist/docs/api/operations/semantic_search_docs.md +26 -0
  100. package/dist/docs/api/operations/set_table_bases.md +44 -0
  101. package/dist/docs/api/operations/status.md +13 -0
  102. package/dist/docs/api/operations/stop_engine.md +23 -0
  103. package/dist/docs/api/operations/sync_semantic_index.md +33 -0
  104. package/dist/docs/api/operations/table_changes.md +31 -0
  105. package/dist/docs/api/operations/tags/auxiliary.md +14 -0
  106. package/dist/docs/api/operations/tags/change-feed.md +8 -0
  107. package/dist/docs/api/operations/tags/history.md +17 -0
  108. package/dist/docs/api/operations/tags/queries.md +15 -0
  109. package/dist/docs/api/operations/tags/rows-dml.md +16 -0
  110. package/dist/docs/api/operations/tags/schema-ddl.md +22 -0
  111. package/dist/docs/api/operations/tags/service.md +15 -0
  112. package/dist/docs/api/operations/tags/tokens.md +13 -0
  113. package/dist/docs/api/operations/tokens_create.md +34 -0
  114. package/dist/docs/api/operations/tokens_delete.md +29 -0
  115. package/dist/docs/api/operations/tokens_list.md +21 -0
  116. package/dist/docs/api/operations/tokens_me.md +20 -0
  117. package/dist/docs/api/operations/tokens_rotate.md +29 -0
  118. package/dist/docs/api/operations/tokens_update.md +34 -0
  119. package/dist/docs/api/operations/undo_migration.md +46 -0
  120. package/dist/docs/api/operations/update_row.md +60 -0
  121. package/dist/docs/api/operations/update_rows.md +46 -0
  122. package/dist/docs/api/operations/vacuum_table.md +37 -0
  123. package/dist/docs/api.md +135 -0
  124. package/dist/docs/develop/build-an-app.md +320 -0
  125. package/dist/docs/develop/build-on-datanotes.md +138 -0
  126. package/dist/docs/develop/change-feed-and-webhooks.md +70 -0
  127. package/dist/docs/develop/client.md +116 -0
  128. package/dist/docs/develop/concurrency.md +153 -0
  129. package/dist/docs/develop/http-api.md +79 -0
  130. package/dist/docs/develop/telemetry.md +86 -0
  131. package/dist/docs/guides/agents/docs-offline.md +99 -0
  132. package/dist/docs/guides/agents/how-agents-use-datanotes.md +124 -0
  133. package/dist/docs/guides/agents/prompts.md +495 -0
  134. package/dist/docs/guides/agents/reading-errors.md +112 -0
  135. package/dist/docs/guides/data-quality/check-constraints.md +379 -0
  136. package/dist/docs/guides/data-quality/check-table.md +63 -0
  137. package/dist/docs/guides/data-quality/hand-edits.md +507 -0
  138. package/dist/docs/guides/data-quality/sync-between-devices.md +51 -0
  139. package/dist/docs/guides/data-quality/validation.md +90 -0
  140. package/dist/docs/guides/database-objects/bases.md +480 -0
  141. package/dist/docs/guides/database-objects/catalogs-and-schemas.md +897 -0
  142. package/dist/docs/guides/database-objects/columns.md +1332 -0
  143. package/dist/docs/guides/database-objects/relations.md +1454 -0
  144. package/dist/docs/guides/database-objects/tables.md +1404 -0
  145. package/dist/docs/guides/database-objects/views.md +1003 -0
  146. package/dist/docs/guides/history/back-up.md +195 -0
  147. package/dist/docs/guides/history/change-data-feed.md +247 -0
  148. package/dist/docs/guides/history/journal-and-undo.md +262 -0
  149. package/dist/docs/guides/history/restore.md +341 -0
  150. package/dist/docs/guides/history/table-history.md +657 -0
  151. package/dist/docs/guides/history/vacuum.md +35 -0
  152. package/dist/docs/guides/read-and-write/automatic-links.md +768 -0
  153. package/dist/docs/guides/read-and-write/batch.md +139 -0
  154. package/dist/docs/guides/read-and-write/import-notes.md +896 -0
  155. package/dist/docs/guides/read-and-write/joins-and-aggregates.md +251 -0
  156. package/dist/docs/guides/read-and-write/read-and-filter.md +536 -0
  157. package/dist/docs/guides/read-and-write/write-rows.md +573 -0
  158. package/dist/docs/guides/search/link-graph.md +146 -0
  159. package/dist/docs/guides/search/semantic.md +133 -0
  160. package/dist/docs/guides/search/text.md +142 -0
  161. package/dist/docs/guides/security/security-model.md +110 -0
  162. package/dist/docs/guides/security/tokens.md +60 -0
  163. package/dist/docs/guides/security/who-did-what.md +42 -0
  164. package/dist/docs/index.md +113 -0
  165. package/dist/docs/llms.txt +33 -0
  166. package/dist/docs/reference/cli.md +136 -0
  167. package/dist/docs/reference/compatibility.md +63 -0
  168. package/dist/docs/reference/errors.md +72 -0
  169. package/dist/docs/reference/glossary.md +161 -0
  170. package/dist/docs/reference/operations/auxiliary.md +116 -0
  171. package/dist/docs/reference/operations/history.md +168 -0
  172. package/dist/docs/reference/operations/queries.md +169 -0
  173. package/dist/docs/reference/operations/rows.md +185 -0
  174. package/dist/docs/reference/operations/schema.md +316 -0
  175. package/dist/docs/reference/operations.md +96 -0
  176. package/dist/docs/reference/settings.md +31 -0
  177. package/dist/docs/release-notes.md +67 -0
  178. package/dist/docs/start/connect-agents.md +204 -0
  179. package/dist/docs/start/how-it-works.md +317 -0
  180. package/dist/docs/start/quick-start.md +126 -0
  181. package/package.json +58 -14
@@ -0,0 +1,897 @@
1
+ # Catalogs, schemas and the database
2
+
3
+ > Group tables in catalogs and schemas, describe the database, query its own schema, set its settings and move its folder.
4
+
5
+ Tables live in catalogs and schemas, and you name a table `catalog.schema.table`. Each catalog and schema is a folder under `datanotes/`, and `datanotes/metastore.yaml` defines all of them. A short name such as `film` resolves through the database’s default catalog and schema.
6
+
7
+ The examples on this page keep a diary of classic films in its own catalog, `diary`. You group the tables, describe them, read the database’s own schema and change the settings of the whole database.
8
+
9
+ ## Place tables in catalogs and schemas
10
+
11
+ `catalog` and `schema` place a table, and default to `main` and `public`. The full name, like `diary.classics.film`, works wherever an operation takes a table. A shorter name works too when only one table matches it.
12
+
13
+ **`create_table`**
14
+
15
+ ```json
16
+ {
17
+ "catalog": "diary",
18
+ "schema": "classics",
19
+ "name": "film",
20
+ "columns": [
21
+ {
22
+ "name": "title",
23
+ "type": "string",
24
+ "required": true,
25
+ "unique": true,
26
+ "description": "The film's title, as on its poster"
27
+ },
28
+ { "name": "year", "type": "integer", "description": "Year the film first came out" },
29
+ {
30
+ "name": "minutes",
31
+ "type": "integer",
32
+ "min": 1,
33
+ "description": "Running time in minutes"
34
+ },
35
+ {
36
+ "name": "status",
37
+ "type": "enum",
38
+ "values": ["to watch", "watched"],
39
+ "ordered": true,
40
+ "description": "Where the film is on my list"
41
+ },
42
+ {
43
+ "name": "rating",
44
+ "type": "integer",
45
+ "min": 1,
46
+ "max": 5,
47
+ "description": "My rating, from 1 (poor) to 5 (a masterpiece)"
48
+ }
49
+ ],
50
+ "filename": "{title}",
51
+ "description": "One note per film",
52
+ "aliases": ["films I watched"]
53
+ }
54
+ ```
55
+
56
+ Answer:
57
+
58
+ ```json
59
+ {
60
+ "ok": true,
61
+ "op": "create_table",
62
+ "planned_texts": ["datanotes/metastore.yaml"],
63
+ "commits": [
64
+ { "table": "diary.classics.film", "version": 0, "operation": "CREATE TABLE" }
65
+ ],
66
+ "migration_id": "20261012T072003-create_table-create-table-diary-classics-fi"
67
+ }
68
+ ```
69
+
70
+ **`insert_row`**
71
+
72
+ ```json
73
+ {
74
+ "table": "classics.film",
75
+ "values": {
76
+ "title": "Nosferatu",
77
+ "year": 1922,
78
+ "minutes": 94,
79
+ "status": "watched",
80
+ "rating": 5
81
+ }
82
+ }
83
+ ```
84
+
85
+ Answer:
86
+
87
+ ```json
88
+ {
89
+ "ok": true,
90
+ "op": "insert_row",
91
+ "files_created": 1,
92
+ "planned_creates": ["datanotes/diary/classics/film/Nosferatu.md"],
93
+ "commits": [{ "table": "diary.classics.film", "version": 1, "operation": "WRITE" }],
94
+ "migration_id": "20261012T072003-insert_row-insert-into-film"
95
+ }
96
+ ```
97
+
98
+ ## Describe tables, catalogs and schemas
99
+
100
+ `alter_table` changes how agents find a table, through its `description` and `aliases`. Tags are key/value labels on a table: you set them with `tags` in `create_table` or `alter_table`, and they merge into the tags the table has. `comment_on` says what a catalog, or one of its schemas, holds.
101
+
102
+ `metastore.yaml` keeps all of it, and you change it only through operations like these, never by hand.
103
+
104
+ **`alter_table`**
105
+
106
+ ```json
107
+ {
108
+ "table": "film",
109
+ "description": "One note per classic film: what I watched and what I thought",
110
+ "aliases": ["films I watched", "film diary"]
111
+ }
112
+ ```
113
+
114
+ **`alter_table`**
115
+
116
+ ```json
117
+ { "table": "film", "tags": { "domain": "films", "review": "weekly" } }
118
+ ```
119
+
120
+ Answer:
121
+
122
+ ```json
123
+ {
124
+ "ok": true,
125
+ "op": "alter_table",
126
+ "planned_texts": ["datanotes/metastore.yaml"],
127
+ "commits": [
128
+ { "table": "diary.classics.film", "version": 3, "operation": "ALTER TABLE" }
129
+ ],
130
+ "migration_id": "20261012T072003-alter_table-alter-table-diary-classics-fil-2"
131
+ }
132
+ ```
133
+
134
+ **`comment_on`**
135
+
136
+ ```json
137
+ { "catalog": "diary", "description": "My diaries: films, for now" }
138
+ ```
139
+
140
+ Answer:
141
+
142
+ ```json
143
+ {
144
+ "ok": true,
145
+ "op": "comment_on",
146
+ "planned_texts": ["datanotes/metastore.yaml"],
147
+ "migration_id": "20261012T072003-comment_on-comment-on-catalog-diary"
148
+ }
149
+ ```
150
+
151
+ **`comment_on`**
152
+
153
+ ```json
154
+ {
155
+ "catalog": "diary",
156
+ "schema": "classics",
157
+ "description": "Public-domain classic films and their actors"
158
+ }
159
+ ```
160
+
161
+ Answer:
162
+
163
+ ```json
164
+ {
165
+ "ok": true,
166
+ "op": "comment_on",
167
+ "planned_texts": ["datanotes/metastore.yaml"],
168
+ "migration_id": "20261012T072003-comment_on-comment-on-schema-diary-classi"
169
+ }
170
+ ```
171
+
172
+ `datanotes/metastore.yaml` now reads:
173
+
174
+ ```yaml
175
+ # Metastore (Datanotes): catalogs, schemas, tables, columns, views.
176
+ id: 01a12efb-9b58-7bc6-9f52-b4394f27c37d
177
+ config:
178
+ history: true
179
+
180
+
181
+ catalogs:
182
+ diary:
183
+ description: "My diaries: films, for now"
184
+ schemas:
185
+ classics:
186
+ description: Public-domain classic films and their actors
187
+ tables:
188
+ film:
189
+ description: "One note per classic film: what I watched and what I thought"
190
+ aliases:
191
+ - films I watched
192
+ - film diary
193
+ tags:
194
+ domain: films
195
+ review: weekly
196
+ options:
197
+ filename: "{title}"
198
+ archive: _archive
199
+ columns:
200
+ - name: id
201
+ type: string
202
+ unique: true
203
+ identity: uuid
204
+ required: true
205
+ dense: true
206
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
207
+ - name: title
208
+ type: string
209
+ required: true
210
+ description: The film's title, as on its poster
211
+ unique: true
212
+ - name: year
213
+ type: integer
214
+ description: Year the film first came out
215
+ - name: minutes
216
+ type: integer
217
+ min: 1
218
+ description: Running time in minutes
219
+ - name: status
220
+ type: enum
221
+ values:
222
+ - to watch
223
+ - watched
224
+ description: Where the film is on my list
225
+ ordered: true
226
+ - name: rating
227
+ type: integer
228
+ min: 1
229
+ max: 5
230
+ description: My rating, from 1 (poor) to 5 (a masterpiece)
231
+ ```
232
+
233
+ `describe_database` shows the descriptions and the tags. `list_tables` and `describe_table` show the tags too. `system.information_schema` has the descriptions in the `comment` of `catalogs` and `schemata`, as databases name it, and the tags in `tables`:
234
+
235
+ **`describe_database`** (no arguments)
236
+
237
+ Answer:
238
+
239
+ ```json
240
+ [
241
+ {
242
+ "catalog": "diary",
243
+ "description": "My diaries: films, for now",
244
+ "schemas": [
245
+ {
246
+ "schema": "classics",
247
+ "description": "Public-domain classic films and their actors",
248
+ "tables": [{ "name": "film", "tags": { "domain": "films", "review": "weekly" } }]
249
+ }
250
+ ]
251
+ }
252
+ ]
253
+ ```
254
+
255
+ A `null` value removes a tag, and `comment_on` with `description: ""` removes a description:
256
+
257
+ **`alter_table`**
258
+
259
+ ```json
260
+ { "table": "film", "tags": { "review": null } }
261
+ ```
262
+
263
+ Answer:
264
+
265
+ ```json
266
+ {
267
+ "ok": true,
268
+ "op": "alter_table",
269
+ "planned_texts": ["datanotes/metastore.yaml"],
270
+ "commits": [
271
+ { "table": "diary.classics.film", "version": 4, "operation": "ALTER TABLE" }
272
+ ],
273
+ "migration_id": "20261012T072003-alter_table-alter-table-diary-classics-fil-3"
274
+ }
275
+ ```
276
+
277
+ **`comment_on`**
278
+
279
+ ```json
280
+ { "catalog": "diary", "schema": "classics", "description": "" }
281
+ ```
282
+
283
+ Answer:
284
+
285
+ ```json
286
+ {
287
+ "ok": true,
288
+ "op": "comment_on",
289
+ "planned_texts": ["datanotes/metastore.yaml"],
290
+ "migration_id": "20261012T072003-comment_on-remove-the-comment-on-schema-d"
291
+ }
292
+ ```
293
+
294
+ `clear_tags: true` removes every tag first, so with `tags` the table keeps exactly the tags you pass:
295
+
296
+ **`alter_table`**
297
+
298
+ ```json
299
+ { "table": "film", "clear_tags": true, "tags": { "area": "films" } }
300
+ ```
301
+
302
+ Answer:
303
+
304
+ ```json
305
+ {
306
+ "ok": true,
307
+ "op": "alter_table",
308
+ "planned_texts": ["datanotes/metastore.yaml"],
309
+ "commits": [
310
+ { "table": "diary.classics.film", "version": 5, "operation": "ALTER TABLE" }
311
+ ],
312
+ "migration_id": "20261012T072003-alter_table-alter-table-diary-classics-fil-4"
313
+ }
314
+ ```
315
+
316
+ **`describe_table`**
317
+
318
+ ```json
319
+ { "table": "film" }
320
+ ```
321
+
322
+ Answer:
323
+
324
+ ```json
325
+ {
326
+ "qualified": "diary.classics.film",
327
+ "description": "One note per classic film: what I watched and what I thought",
328
+ "aliases": ["films I watched", "film diary"],
329
+ "tags": { "area": "films" }
330
+ }
331
+ ```
332
+
333
+ ## Describe the whole database
334
+
335
+ `describe_database` shows the configuration and every catalog, schema and table, with row counts. A table you create as plain `film` goes to the default catalog `main` and schema `public`.
336
+
337
+ **`describe_database`** (no arguments)
338
+
339
+ Answer (49 lines)
340
+
341
+ ```json
342
+ {
343
+ "root": "datanotes",
344
+ "metastore": "datanotes/metastore.yaml",
345
+ "journal": "store:journal",
346
+ "config": {
347
+ "default_catalog": "main",
348
+ "default_schema": "public",
349
+ "default_partition": "",
350
+ "default_filename": "YYYY-MM-DD[T]HHmm",
351
+ "archive_folder": "_archive",
352
+ "timezone": "",
353
+ "history": true,
354
+ "autolink": true
355
+ },
356
+ "catalogs": [
357
+ {
358
+ "catalog": "main",
359
+ "default": true,
360
+ "schemas": [
361
+ {
362
+ "schema": "public",
363
+ "tables": [
364
+ {
365
+ "name": "film",
366
+ "qualified": "main.public.film",
367
+ "row_count": 1,
368
+ "description": "Classic films I watched or want to watch"
369
+ },
370
+ {
371
+ "name": "watch",
372
+ "qualified": "main.public.watch",
373
+ "row_count": 1,
374
+ "description": "Each time I watch a film",
375
+ "tags": { "area": "films" }
376
+ },
377
+ {
378
+ "name": "review",
379
+ "qualified": "main.public.review",
380
+ "row_count": 0,
381
+ "description": "What I wrote about a film after watching it"
382
+ }
383
+ ],
384
+ "views": []
385
+ }
386
+ ]
387
+ }
388
+ ],
389
+ "bases": []
390
+ }
391
+ ```
392
+
393
+ ## Query the database’s own schema
394
+
395
+ `system.information_schema` describes the database as tables that you query with `select_rows`. It has these tables:
396
+
397
+ * **`catalogs`** and **`schemata`**: the catalogs and their schemas
398
+ * **`tables`** and **`views`**: the tables and the stored views
399
+ * **`columns`**: the columns of every table
400
+ * **`check_constraints`**: the CHECK constraints, the rules that every row of a table must satisfy
401
+
402
+ This query lists the columns of `watch`:
403
+
404
+ **`select_rows`**
405
+
406
+ ```json
407
+ {
408
+ "table": "system.information_schema.columns",
409
+ "columns": ["table_name", "column_name", "data_type", "is_nullable"],
410
+ "where": { "table_name": "watch" }
411
+ }
412
+ ```
413
+
414
+ Answer (48 lines)
415
+
416
+ ```json
417
+ {
418
+ "table": "system.information_schema.columns",
419
+ "total": 6,
420
+ "rows": [
421
+ {
422
+ "path": "system/information_schema/columns/00013",
423
+ "table_name": "watch",
424
+ "column_name": "id",
425
+ "data_type": "string",
426
+ "is_nullable": "NO"
427
+ },
428
+ {
429
+ "path": "system/information_schema/columns/00014",
430
+ "table_name": "watch",
431
+ "column_name": "film",
432
+ "data_type": "link",
433
+ "is_nullable": "NO"
434
+ },
435
+ {
436
+ "path": "system/information_schema/columns/00015",
437
+ "table_name": "watch",
438
+ "column_name": "occurred_at",
439
+ "data_type": "datetime",
440
+ "is_nullable": "NO"
441
+ },
442
+ {
443
+ "path": "system/information_schema/columns/00016",
444
+ "table_name": "watch",
445
+ "column_name": "where",
446
+ "data_type": "enum(cinema,home,outdoor screening)",
447
+ "is_nullable": "YES"
448
+ },
449
+ {
450
+ "path": "system/information_schema/columns/00017",
451
+ "table_name": "watch",
452
+ "column_name": "place",
453
+ "data_type": "string",
454
+ "is_nullable": "YES"
455
+ },
456
+ {
457
+ "path": "system/information_schema/columns/00018",
458
+ "table_name": "watch",
459
+ "column_name": "with",
460
+ "data_type": "string",
461
+ "is_nullable": "YES"
462
+ }
463
+ ]
464
+ }
465
+ ```
466
+
467
+ ## Configure the database settings
468
+
469
+ `configure_database` sets defaults stored in `metastore.yaml`:
470
+
471
+ * **`timezone`**: the offset for date-times written without one
472
+ * **`default_catalog`** and **`default_schema`**: where new tables go
473
+ * **`default_filename`**: the file-name format of new time-named tables
474
+ * **`archive_folder`**: the archive folder
475
+
476
+ **`configure_database`**
477
+
478
+ ```json
479
+ { "timezone": "Europe/Rome", "default_catalog": "diary" }
480
+ ```
481
+
482
+ Answer:
483
+
484
+ ```json
485
+ {
486
+ "default_catalog": "diary",
487
+ "default_schema": "public",
488
+ "default_partition": "",
489
+ "default_filename": "YYYY-MM-DD[T]HHmm",
490
+ "archive_folder": "_archive",
491
+ "timezone": "Europe/Rome",
492
+ "history": true,
493
+ "autolink": true
494
+ }
495
+ ```
496
+
497
+ ## Move the database folder
498
+
499
+ A vault holds one database, in one folder: `datanotes/` for a new database. `root` renames or moves that folder, with `metastore.yaml` and every row in it. The folder can be anywhere in the vault, also in a subfolder.
500
+
501
+ The move is one operation. In it, the engine:
502
+
503
+ * rewrites every link into the folder, across the vault
504
+ * recomputes the generated columns
505
+ * moves a table’s `archive` or `exclude` folder inside the database folder
506
+
507
+ The journal lists the move as `move_database`, which undo refuses. To move the folder back, call `configure_database` again.
508
+
509
+ **`alter_table`**
510
+
511
+ ```json
512
+ { "table": "diary.classics.film", "exclude": ["datanotes/diary/classics/film/Templates"] }
513
+ ```
514
+
515
+ **`configure_database`**
516
+
517
+ ```json
518
+ { "root": "Areas/Diary" }
519
+ ```
520
+
521
+ Answer:
522
+
523
+ ```json
524
+ { "root": "Areas/Diary", "metastore": "Areas/Diary/metastore.yaml" }
525
+ ```
526
+
527
+ **`list_folder`**
528
+
529
+ ```json
530
+ { "folder": "Areas" }
531
+ ```
532
+
533
+ Answer:
534
+
535
+ ```json
536
+ { "folder": "Areas", "folders": ["Areas/Diary"], "files": [] }
537
+ ```
538
+
539
+ The `exclude` folder of `film`, set right before the move, moved with the database:
540
+
541
+ **`describe_table`**
542
+
543
+ ```json
544
+ { "table": "diary.classics.film" }
545
+ ```
546
+
547
+ Answer:
548
+
549
+ ```json
550
+ { "exclude": ["Areas/Diary/diary/classics/film/Templates"] }
551
+ ```
552
+
553
+ Editors hide folders whose name starts with a dot, so the engine refuses one. It also refuses the vault root, a folder that exists, and a folder inside the database:
554
+
555
+ **`configure_database`**
556
+
557
+ ```json
558
+ { "root": "Areas/.diary" }
559
+ ```
560
+
561
+ Refused:
562
+
563
+ ```text
564
+ "root" cannot have a dot segment: "Areas/.diary"
565
+ Hint: Editors hide folders whose name starts with a dot, so the rows would vanish from view: name folders without a leading dot, e.g. root: "datanotes".
566
+ Docs: https://datanotes.dev/start/how-it-works.md#move-the-vault-or-the-database-folder (offline: read_docs("start/how-it-works#move-the-vault-or-the-database-folder"))
567
+ ```
568
+
569
+ This call moves the folder back:
570
+
571
+ **`configure_database`**
572
+
573
+ ```json
574
+ { "root": "datanotes" }
575
+ ```
576
+
577
+ Answer:
578
+
579
+ ```json
580
+ { "root": "datanotes", "metastore": "datanotes/metastore.yaml" }
581
+ ```
582
+
583
+ ## See the database’s definition in `metastore.yaml`
584
+
585
+ This is the database of this page as the engine wrote it. `metastore.yaml` holds:
586
+
587
+ * the catalogs with their descriptions
588
+ * the tables with their tags, `bases`, `constraints` and `options`
589
+ * the bases, with `ref: self` kept as written
590
+ * the settings under `config`
591
+
592
+ `datanotes/metastore.yaml` now reads:
593
+
594
+ ```yaml
595
+ # Metastore (Datanotes): catalogs, schemas, tables, columns, views.
596
+ id: 01a12efb-9b58-7bc6-9f52-b4394f27c37d
597
+ config:
598
+ history: true
599
+ default_catalog: diary
600
+ timezone: Europe/Rome
601
+ default_schema: log
602
+ default_partition: YYYY/MM
603
+ default_filename: YYYY-MM-DD HHmm
604
+ archive_folder: _old
605
+
606
+
607
+ catalogs:
608
+ diary:
609
+ description: "My diaries: films, for now"
610
+ schemas:
611
+ classics:
612
+ tables:
613
+ film:
614
+ description: "One note per classic film: what I watched and what I thought"
615
+ aliases:
616
+ - films I watched
617
+ - film diary
618
+ tags:
619
+ area: films
620
+ bases:
621
+ - entry
622
+ constraints:
623
+ rated_when_watched:
624
+ or:
625
+ - status:
626
+ ne: watched
627
+ - rating:
628
+ exists: true
629
+ options:
630
+ partition: "{year}"
631
+ filename: "{title} ({year})"
632
+ archive: _done
633
+ exclude: datanotes/diary/classics/film/Templates
634
+ fields:
635
+ cut: restored
636
+ columns:
637
+ - name: id
638
+ type: string
639
+ unique: true
640
+ identity: uuid
641
+ required: true
642
+ dense: true
643
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
644
+ - name: title
645
+ type: string
646
+ required: true
647
+ description: The film's title, as on its poster
648
+ unique: true
649
+ - name: year
650
+ type: integer
651
+ description: Year the film first came out
652
+ - name: minutes
653
+ type: integer
654
+ min: 1
655
+ description: Running time in minutes
656
+ - name: status
657
+ type: enum
658
+ values:
659
+ - to watch
660
+ - watched
661
+ description: Where the film is on my list
662
+ ordered: true
663
+ - name: rating
664
+ type: integer
665
+ min: 1
666
+ max: 5
667
+ description: My rating, from 1 (poor) to 5 (a masterpiece)
668
+ genre:
669
+ description: Eras and genres of cinema, as a tree
670
+ options:
671
+ filename: "{name}"
672
+ archive: _archive
673
+ columns:
674
+ - name: id
675
+ type: string
676
+ required: true
677
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
678
+ unique: true
679
+ identity: uuid
680
+ dense: true
681
+ - name: name
682
+ type: string
683
+ required: true
684
+ description: The name of the era or genre
685
+ bases:
686
+ - tree
687
+ genre_draft:
688
+ description: Eras and genres of cinema, as a tree
689
+ options:
690
+ filename: "{name}"
691
+ archive: _archive
692
+ columns:
693
+ - name: id
694
+ type: string
695
+ unique: true
696
+ identity: uuid
697
+ required: true
698
+ dense: true
699
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
700
+ - name: name
701
+ type: string
702
+ required: true
703
+ description: The name of the era or genre
704
+ credits:
705
+ tables:
706
+ actor:
707
+ description: Actors of the films in the diary
708
+ bases:
709
+ - credited
710
+ options:
711
+ filename: "{name}"
712
+ archive: _archive
713
+ columns:
714
+ - name: id
715
+ type: string
716
+ unique: true
717
+ identity: uuid
718
+ required: true
719
+ dense: true
720
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
721
+ - name: name
722
+ type: string
723
+ required: true
724
+ description: The actor's name, as credited
725
+ log:
726
+ tables:
727
+ watch:
728
+ description: Each time I watch a film
729
+ options:
730
+ partition: "{occurred_at:YYYY/MM}"
731
+ filename: "{occurred_at:YYYY-MM-DD HHmm}"
732
+ archive: _old
733
+ columns:
734
+ - name: id
735
+ type: string
736
+ required: true
737
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
738
+ unique: true
739
+ identity: uuid
740
+ dense: true
741
+ - name: film
742
+ type: link
743
+ required: true
744
+ ref: diary.classics.film
745
+ description: The film I watched
746
+ - name: occurred_at
747
+ type: datetime
748
+ required: true
749
+ description: When the film started
750
+ - name: where
751
+ type: enum
752
+ values:
753
+ - cinema
754
+ - home
755
+ - outdoor screening
756
+ description: The kind of place I watched it in
757
+ - name: place
758
+ type: string
759
+ description: The cinema, park or room, in my words
760
+ sandbox:
761
+ schemas:
762
+ classics:
763
+ tables:
764
+ film_copy:
765
+ description: "One note per classic film: what I watched and what I thought"
766
+ aliases:
767
+ - films I watched
768
+ - film diary
769
+ tags:
770
+ area: films
771
+ bases:
772
+ - entry
773
+ constraints:
774
+ rated_when_watched:
775
+ or:
776
+ - status:
777
+ ne: watched
778
+ - rating:
779
+ exists: true
780
+ options:
781
+ partition: "{year}"
782
+ filename: "{title} ({year})"
783
+ archive: _done
784
+ fields:
785
+ cut: restored
786
+ columns:
787
+ - name: id
788
+ type: string
789
+ unique: true
790
+ identity: uuid
791
+ required: true
792
+ dense: true
793
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
794
+ - name: title
795
+ type: string
796
+ required: true
797
+ description: The film's title, as on its poster
798
+ unique: true
799
+ - name: year
800
+ type: integer
801
+ description: Year the film first came out
802
+ - name: minutes
803
+ type: integer
804
+ min: 1
805
+ description: Running time in minutes
806
+ - name: status
807
+ type: enum
808
+ values:
809
+ - to watch
810
+ - watched
811
+ description: Where the film is on my list
812
+ ordered: true
813
+ - name: rating
814
+ type: integer
815
+ min: 1
816
+ max: 5
817
+ description: My rating, from 1 (poor) to 5 (a masterpiece)
818
+ film_empty:
819
+ description: "One note per classic film: what I watched and what I thought"
820
+ aliases:
821
+ - films I watched
822
+ - film diary
823
+ tags:
824
+ area: films
825
+ bases:
826
+ - entry
827
+ constraints:
828
+ rated_when_watched:
829
+ or:
830
+ - status:
831
+ ne: watched
832
+ - rating:
833
+ exists: true
834
+ options:
835
+ partition: "{year}"
836
+ filename: "{title} ({year})"
837
+ archive: _done
838
+ fields:
839
+ cut: restored
840
+ columns:
841
+ - name: id
842
+ type: string
843
+ unique: true
844
+ identity: uuid
845
+ required: true
846
+ dense: true
847
+ description: "Unique id of the row (UUIDv7): set when the row is created, never changes"
848
+ - name: title
849
+ type: string
850
+ required: true
851
+ description: The film's title, as on its poster
852
+ unique: true
853
+ - name: year
854
+ type: integer
855
+ description: Year the film first came out
856
+ - name: minutes
857
+ type: integer
858
+ min: 1
859
+ description: Running time in minutes
860
+ - name: status
861
+ type: enum
862
+ values:
863
+ - to watch
864
+ - watched
865
+ description: Where the film is on my list
866
+ ordered: true
867
+ - name: rating
868
+ type: integer
869
+ min: 1
870
+ max: 5
871
+ description: My rating, from 1 (poor) to 5 (a masterpiece)
872
+ bases:
873
+ entry:
874
+ description: A note of the film diary
875
+ columns:
876
+ - name: added_on
877
+ type: date
878
+ description: When I added it to the diary
879
+ credited:
880
+ description: Someone in the credits of a film
881
+ bases:
882
+ - entry
883
+ columns:
884
+ - name: films
885
+ type: list
886
+ items: link
887
+ ref: diary.classics.film
888
+ description: The films they’re credited in
889
+ tree:
890
+ description: Rows arranged in a tree
891
+ columns:
892
+ - name: parent
893
+ type: link
894
+ ref: self
895
+ hierarchy: true
896
+ description: The row above this one
897
+ ```