@lix-js/sdk 0.6.0-preview.2 → 0.6.0-preview.4

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 (169) hide show
  1. package/SKILL.md +46 -8
  2. package/dist/engine-wasm/wasm/lix_engine.d.ts +25 -1
  3. package/dist/engine-wasm/wasm/lix_engine.js +60 -2
  4. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  5. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +5 -0
  6. package/dist/generated/builtin-schemas.d.ts +87 -162
  7. package/dist/generated/builtin-schemas.js +139 -236
  8. package/dist/open-lix.d.ts +10 -3
  9. package/dist/open-lix.js +39 -0
  10. package/dist-engine-src/src/binary_cas/types.rs +0 -6
  11. package/dist-engine-src/src/catalog/context.rs +412 -0
  12. package/dist-engine-src/src/catalog/mod.rs +10 -0
  13. package/dist-engine-src/src/catalog/schema.rs +4 -0
  14. package/dist-engine-src/src/catalog/snapshot.rs +1114 -0
  15. package/dist-engine-src/src/cel/mod.rs +1 -1
  16. package/dist-engine-src/src/cel/provider.rs +1 -1
  17. package/dist-engine-src/src/commit_graph/context.rs +328 -1015
  18. package/dist-engine-src/src/commit_graph/mod.rs +2 -3
  19. package/dist-engine-src/src/commit_graph/types.rs +7 -43
  20. package/dist-engine-src/src/commit_graph/walker.rs +57 -81
  21. package/dist-engine-src/src/commit_store/codec.rs +887 -0
  22. package/dist-engine-src/src/commit_store/context.rs +944 -0
  23. package/dist-engine-src/src/commit_store/materialization.rs +84 -0
  24. package/dist-engine-src/src/commit_store/mod.rs +16 -0
  25. package/dist-engine-src/src/commit_store/storage.rs +600 -0
  26. package/dist-engine-src/src/commit_store/types.rs +215 -0
  27. package/dist-engine-src/src/common/identity.rs +15 -5
  28. package/dist-engine-src/src/common/json_pointer.rs +67 -0
  29. package/dist-engine-src/src/common/metadata.rs +17 -12
  30. package/dist-engine-src/src/common/mod.rs +5 -5
  31. package/dist-engine-src/src/domain.rs +324 -0
  32. package/dist-engine-src/src/engine.rs +29 -43
  33. package/dist-engine-src/src/entity_identity.rs +238 -118
  34. package/dist-engine-src/src/functions/context.rs +17 -52
  35. package/dist-engine-src/src/functions/deterministic.rs +1 -1
  36. package/dist-engine-src/src/functions/mod.rs +1 -1
  37. package/dist-engine-src/src/functions/provider.rs +4 -4
  38. package/dist-engine-src/src/functions/state.rs +39 -66
  39. package/dist-engine-src/src/functions/types.rs +1 -1
  40. package/dist-engine-src/src/init.rs +204 -151
  41. package/dist-engine-src/src/json_store/context.rs +354 -60
  42. package/dist-engine-src/src/json_store/encoded.rs +6 -6
  43. package/dist-engine-src/src/json_store/mod.rs +4 -1
  44. package/dist-engine-src/src/json_store/store.rs +884 -11
  45. package/dist-engine-src/src/json_store/types.rs +166 -1
  46. package/dist-engine-src/src/lib.rs +11 -10
  47. package/dist-engine-src/src/live_state/context.rs +608 -830
  48. package/dist-engine-src/src/live_state/mod.rs +3 -3
  49. package/dist-engine-src/src/live_state/overlay.rs +7 -7
  50. package/dist-engine-src/src/live_state/reader.rs +5 -5
  51. package/dist-engine-src/src/live_state/types.rs +19 -36
  52. package/dist-engine-src/src/live_state/visibility.rs +19 -14
  53. package/dist-engine-src/src/plugin/archive.rs +3 -6
  54. package/dist-engine-src/src/plugin/install.rs +0 -18
  55. package/dist-engine-src/src/plugin/plugin_manifest.json +0 -1
  56. package/dist-engine-src/src/schema/annotations/defaults.rs +2 -7
  57. package/dist-engine-src/src/schema/builtin/lix_account.json +0 -1
  58. package/dist-engine-src/src/schema/builtin/lix_active_account.json +0 -1
  59. package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +0 -1
  60. package/dist-engine-src/src/schema/builtin/lix_change.json +11 -10
  61. package/dist-engine-src/src/schema/builtin/lix_change_author.json +0 -1
  62. package/dist-engine-src/src/schema/builtin/lix_commit.json +8 -46
  63. package/dist-engine-src/src/schema/builtin/lix_commit_edge.json +29 -22
  64. package/dist-engine-src/src/schema/builtin/lix_directory_descriptor.json +0 -1
  65. package/dist-engine-src/src/schema/builtin/lix_file_descriptor.json +0 -1
  66. package/dist-engine-src/src/schema/builtin/lix_key_value.json +0 -1
  67. package/dist-engine-src/src/schema/builtin/lix_label.json +10 -3
  68. package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +74 -0
  69. package/dist-engine-src/src/schema/builtin/lix_registered_schema.json +2 -8
  70. package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -1
  71. package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -1
  72. package/dist-engine-src/src/schema/builtin/mod.rs +10 -59
  73. package/dist-engine-src/src/schema/compatibility.rs +787 -0
  74. package/dist-engine-src/src/schema/definition.json +47 -17
  75. package/dist-engine-src/src/schema/definition.rs +202 -96
  76. package/dist-engine-src/src/schema/key.rs +9 -77
  77. package/dist-engine-src/src/schema/mod.rs +4 -4
  78. package/dist-engine-src/src/schema/tests.rs +133 -92
  79. package/dist-engine-src/src/session/context.rs +86 -48
  80. package/dist-engine-src/src/session/create_version.rs +22 -14
  81. package/dist-engine-src/src/session/execute.rs +117 -23
  82. package/dist-engine-src/src/session/merge/apply.rs +4 -4
  83. package/dist-engine-src/src/session/merge/conflicts.rs +3 -2
  84. package/dist-engine-src/src/session/merge/stats.rs +1 -1
  85. package/dist-engine-src/src/session/merge/version.rs +35 -45
  86. package/dist-engine-src/src/session/mod.rs +9 -7
  87. package/dist-engine-src/src/session/optimization9_sql2_bench.rs +100 -0
  88. package/dist-engine-src/src/session/switch_version.rs +17 -28
  89. package/dist-engine-src/src/session/transaction.rs +76 -0
  90. package/dist-engine-src/src/sql2/change_provider.rs +14 -20
  91. package/dist-engine-src/src/sql2/classify.rs +75 -48
  92. package/dist-engine-src/src/sql2/context.rs +22 -18
  93. package/dist-engine-src/src/sql2/directory_history_provider.rs +28 -20
  94. package/dist-engine-src/src/sql2/directory_provider.rs +131 -83
  95. package/dist-engine-src/src/sql2/entity_history_provider.rs +10 -14
  96. package/dist-engine-src/src/sql2/entity_provider.rs +680 -169
  97. package/dist-engine-src/src/sql2/error.rs +24 -5
  98. package/dist-engine-src/src/sql2/execute.rs +426 -272
  99. package/dist-engine-src/src/sql2/file_history_provider.rs +29 -21
  100. package/dist-engine-src/src/sql2/file_provider.rs +533 -108
  101. package/dist-engine-src/src/sql2/filesystem_planner.rs +58 -94
  102. package/dist-engine-src/src/sql2/filesystem_visibility.rs +37 -23
  103. package/dist-engine-src/src/sql2/history_projection.rs +3 -27
  104. package/dist-engine-src/src/sql2/history_provider.rs +11 -17
  105. package/dist-engine-src/src/sql2/history_route.rs +22 -8
  106. package/dist-engine-src/src/sql2/lix_state_provider.rs +178 -96
  107. package/dist-engine-src/src/sql2/mod.rs +8 -4
  108. package/dist-engine-src/src/sql2/predicate_typecheck.rs +246 -0
  109. package/dist-engine-src/src/sql2/public_bind/assignment.rs +46 -0
  110. package/dist-engine-src/src/sql2/public_bind/capability.rs +41 -0
  111. package/dist-engine-src/src/sql2/public_bind/dml.rs +172 -0
  112. package/dist-engine-src/src/sql2/public_bind/mod.rs +26 -0
  113. package/dist-engine-src/src/sql2/public_bind/table.rs +168 -0
  114. package/dist-engine-src/src/sql2/read_only.rs +10 -12
  115. package/dist-engine-src/src/sql2/session.rs +7 -10
  116. package/dist-engine-src/src/sql2/udfs/lix_timestamp.rs +76 -0
  117. package/dist-engine-src/src/sql2/udfs/mod.rs +8 -1
  118. package/dist-engine-src/src/sql2/udfs/public_call.rs +238 -0
  119. package/dist-engine-src/src/sql2/version_provider.rs +46 -31
  120. package/dist-engine-src/src/sql2/version_scope.rs +4 -4
  121. package/dist-engine-src/src/storage_bench.rs +1782 -325
  122. package/dist-engine-src/src/test_support.rs +183 -36
  123. package/dist-engine-src/src/tracked_state/by_file_index.rs +20 -24
  124. package/dist-engine-src/src/tracked_state/codec.rs +1519 -181
  125. package/dist-engine-src/src/tracked_state/context.rs +1155 -271
  126. package/dist-engine-src/src/tracked_state/diff.rs +249 -57
  127. package/dist-engine-src/src/tracked_state/materialization.rs +365 -103
  128. package/dist-engine-src/src/tracked_state/materializer.rs +488 -0
  129. package/dist-engine-src/src/tracked_state/merge.rs +37 -19
  130. package/dist-engine-src/src/tracked_state/mod.rs +8 -7
  131. package/dist-engine-src/src/tracked_state/storage.rs +138 -6
  132. package/dist-engine-src/src/tracked_state/tree.rs +695 -252
  133. package/dist-engine-src/src/tracked_state/types.rs +176 -6
  134. package/dist-engine-src/src/transaction/commit.rs +695 -435
  135. package/dist-engine-src/src/transaction/context.rs +551 -310
  136. package/dist-engine-src/src/transaction/live_state_overlay.rs +9 -8
  137. package/dist-engine-src/src/transaction/mod.rs +2 -0
  138. package/dist-engine-src/src/transaction/normalization.rs +311 -447
  139. package/dist-engine-src/src/transaction/prep.rs +37 -0
  140. package/dist-engine-src/src/transaction/schema_resolver.rs +93 -71
  141. package/dist-engine-src/src/transaction/staging.rs +701 -406
  142. package/dist-engine-src/src/transaction/types.rs +231 -122
  143. package/dist-engine-src/src/transaction/validation.rs +2717 -1698
  144. package/dist-engine-src/src/untracked_state/codec.rs +40 -96
  145. package/dist-engine-src/src/untracked_state/context.rs +21 -5
  146. package/dist-engine-src/src/untracked_state/materialization.rs +10 -104
  147. package/dist-engine-src/src/untracked_state/mod.rs +3 -5
  148. package/dist-engine-src/src/untracked_state/storage.rs +105 -57
  149. package/dist-engine-src/src/untracked_state/types.rs +63 -13
  150. package/dist-engine-src/src/version/context.rs +1 -13
  151. package/dist-engine-src/src/version/lifecycle.rs +221 -0
  152. package/dist-engine-src/src/version/mod.rs +3 -2
  153. package/dist-engine-src/src/version/refs.rs +12 -103
  154. package/dist-engine-src/src/version/stage_rows.rs +15 -19
  155. package/package.json +1 -1
  156. package/dist-engine-src/src/changelog/codec.rs +0 -321
  157. package/dist-engine-src/src/changelog/context.rs +0 -92
  158. package/dist-engine-src/src/changelog/materialization.rs +0 -121
  159. package/dist-engine-src/src/changelog/mod.rs +0 -13
  160. package/dist-engine-src/src/changelog/reader.rs +0 -20
  161. package/dist-engine-src/src/changelog/storage.rs +0 -220
  162. package/dist-engine-src/src/changelog/types.rs +0 -38
  163. package/dist-engine-src/src/schema/builtin/lix_change_set.json +0 -18
  164. package/dist-engine-src/src/schema/builtin/lix_change_set_element.json +0 -75
  165. package/dist-engine-src/src/schema/builtin/lix_entity_label.json +0 -63
  166. package/dist-engine-src/src/schema_registry.rs +0 -294
  167. package/dist-engine-src/src/sql2/commit_derived_provider.rs +0 -591
  168. package/dist-engine-src/src/tracked_state/rebuild.rs +0 -771
  169. package/dist-engine-src/src/tracked_state/tree_types.rs +0 -176
@@ -1,591 +0,0 @@
1
- use std::any::Any;
2
- use std::collections::BTreeSet;
3
- use std::sync::Arc;
4
-
5
- use async_trait::async_trait;
6
- use datafusion::arrow::array::{ArrayRef, BooleanArray, StringArray};
7
- use datafusion::arrow::datatypes::{DataType, Field, Schema, SchemaRef};
8
- use datafusion::arrow::record_batch::RecordBatch;
9
- use datafusion::catalog::{Session, TableProvider};
10
- use datafusion::common::{DataFusionError, Result};
11
- use datafusion::datasource::TableType;
12
- use datafusion::execution::TaskContext;
13
- use datafusion::logical_expr::{Expr, TableProviderFilterPushDown};
14
- use datafusion::physical_expr::EquivalenceProperties;
15
- use datafusion::physical_plan::execution_plan::{Boundedness, EmissionType, PlanProperties};
16
- use datafusion::physical_plan::stream::RecordBatchStreamAdapter;
17
- use datafusion::physical_plan::{
18
- DisplayAs, DisplayFormatType, ExecutionPlan, Partitioning, SendableRecordBatchStream,
19
- };
20
- use futures_util::stream;
21
- use tokio::sync::Mutex;
22
-
23
- use crate::commit_graph::CommitGraphReader;
24
- use crate::sql2::version_scope::{resolve_provider_version_ids, VersionBinding};
25
- use crate::version::VersionRefReader;
26
- use crate::LixError;
27
- use crate::GLOBAL_VERSION_ID;
28
-
29
- use super::record_batch::record_batch_with_row_count;
30
-
31
- pub(crate) async fn register_commit_derived_providers(
32
- session: &datafusion::prelude::SessionContext,
33
- commit_graph: Box<dyn CommitGraphReader>,
34
- version_ref: Arc<dyn VersionRefReader>,
35
- ) -> Result<(), LixError> {
36
- let commit_graph = Arc::new(Mutex::new(commit_graph));
37
- for surface in CommitSurface::all() {
38
- let provider = Arc::new(CommitSurfaceProvider::new(
39
- surface,
40
- Arc::clone(&commit_graph),
41
- Arc::clone(&version_ref),
42
- ));
43
- session
44
- .register_table(surface.table_name(), provider)
45
- .map_err(datafusion_error_to_lix_error)?;
46
- }
47
- Ok(())
48
- }
49
-
50
- #[derive(Debug, Clone, Copy)]
51
- enum CommitSurface {
52
- CommitEdge,
53
- CommitEdgeByVersion,
54
- ChangeSet,
55
- ChangeSetByVersion,
56
- ChangeSetElement,
57
- ChangeSetElementByVersion,
58
- }
59
-
60
- impl CommitSurface {
61
- fn all() -> [Self; 6] {
62
- [
63
- Self::CommitEdge,
64
- Self::CommitEdgeByVersion,
65
- Self::ChangeSet,
66
- Self::ChangeSetByVersion,
67
- Self::ChangeSetElement,
68
- Self::ChangeSetElementByVersion,
69
- ]
70
- }
71
-
72
- fn table_name(self) -> &'static str {
73
- match self {
74
- Self::CommitEdge => "lix_commit_edge",
75
- Self::CommitEdgeByVersion => "lix_commit_edge_by_version",
76
- Self::ChangeSet => "lix_change_set",
77
- Self::ChangeSetByVersion => "lix_change_set_by_version",
78
- Self::ChangeSetElement => "lix_change_set_element",
79
- Self::ChangeSetElementByVersion => "lix_change_set_element_by_version",
80
- }
81
- }
82
-
83
- fn schema(self) -> SchemaRef {
84
- match self {
85
- Self::CommitEdge => commit_edge_schema(false),
86
- Self::CommitEdgeByVersion => commit_edge_schema(true),
87
- Self::ChangeSet => change_set_schema(false),
88
- Self::ChangeSetByVersion => change_set_schema(true),
89
- Self::ChangeSetElement => change_set_element_schema(false),
90
- Self::ChangeSetElementByVersion => change_set_element_schema(true),
91
- }
92
- }
93
-
94
- fn by_version(self) -> bool {
95
- matches!(
96
- self,
97
- Self::CommitEdgeByVersion | Self::ChangeSetByVersion | Self::ChangeSetElementByVersion
98
- )
99
- }
100
- }
101
-
102
- struct CommitSurfaceProvider {
103
- surface: CommitSurface,
104
- schema: SchemaRef,
105
- commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
106
- version_ref: Arc<dyn VersionRefReader>,
107
- }
108
-
109
- impl std::fmt::Debug for CommitSurfaceProvider {
110
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111
- f.debug_struct("CommitSurfaceProvider")
112
- .field("surface", &self.surface)
113
- .finish()
114
- }
115
- }
116
-
117
- impl CommitSurfaceProvider {
118
- fn new(
119
- surface: CommitSurface,
120
- commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
121
- version_ref: Arc<dyn VersionRefReader>,
122
- ) -> Self {
123
- Self {
124
- surface,
125
- schema: surface.schema(),
126
- commit_graph,
127
- version_ref,
128
- }
129
- }
130
- }
131
-
132
- #[async_trait]
133
- impl TableProvider for CommitSurfaceProvider {
134
- fn as_any(&self) -> &dyn Any {
135
- self
136
- }
137
-
138
- fn schema(&self) -> SchemaRef {
139
- Arc::clone(&self.schema)
140
- }
141
-
142
- fn table_type(&self) -> TableType {
143
- TableType::View
144
- }
145
-
146
- fn supports_filters_pushdown(
147
- &self,
148
- filters: &[&Expr],
149
- ) -> Result<Vec<TableProviderFilterPushDown>> {
150
- Ok(filters
151
- .iter()
152
- .map(|_| TableProviderFilterPushDown::Unsupported)
153
- .collect())
154
- }
155
-
156
- async fn scan(
157
- &self,
158
- _state: &dyn Session,
159
- projection: Option<&Vec<usize>>,
160
- _filters: &[Expr],
161
- limit: Option<usize>,
162
- ) -> Result<Arc<dyn ExecutionPlan>> {
163
- Ok(Arc::new(CommitSurfaceScanExec::new(
164
- self.surface,
165
- Arc::clone(&self.commit_graph),
166
- Arc::clone(&self.version_ref),
167
- projected_schema(&self.schema, projection),
168
- projection.cloned(),
169
- limit,
170
- )))
171
- }
172
- }
173
-
174
- struct CommitSurfaceScanExec {
175
- surface: CommitSurface,
176
- commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
177
- version_ref: Arc<dyn VersionRefReader>,
178
- schema: SchemaRef,
179
- projection: Option<Vec<usize>>,
180
- limit: Option<usize>,
181
- properties: Arc<PlanProperties>,
182
- }
183
-
184
- impl std::fmt::Debug for CommitSurfaceScanExec {
185
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186
- f.debug_struct("CommitSurfaceScanExec")
187
- .field("surface", &self.surface)
188
- .finish()
189
- }
190
- }
191
-
192
- impl CommitSurfaceScanExec {
193
- fn new(
194
- surface: CommitSurface,
195
- commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
196
- version_ref: Arc<dyn VersionRefReader>,
197
- schema: SchemaRef,
198
- projection: Option<Vec<usize>>,
199
- limit: Option<usize>,
200
- ) -> Self {
201
- let properties = PlanProperties::new(
202
- EquivalenceProperties::new(schema.clone()),
203
- Partitioning::UnknownPartitioning(1),
204
- EmissionType::Incremental,
205
- Boundedness::Bounded,
206
- );
207
- Self {
208
- surface,
209
- commit_graph,
210
- version_ref,
211
- schema,
212
- projection,
213
- limit,
214
- properties: Arc::new(properties),
215
- }
216
- }
217
- }
218
-
219
- impl DisplayAs for CommitSurfaceScanExec {
220
- fn fmt_as(&self, t: DisplayFormatType, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
221
- match t {
222
- DisplayFormatType::Default | DisplayFormatType::Verbose => {
223
- write!(f, "CommitSurfaceScanExec")
224
- }
225
- DisplayFormatType::TreeRender => write!(f, "CommitSurfaceScanExec"),
226
- }
227
- }
228
- }
229
-
230
- impl ExecutionPlan for CommitSurfaceScanExec {
231
- fn name(&self) -> &str {
232
- "CommitSurfaceScanExec"
233
- }
234
-
235
- fn as_any(&self) -> &dyn Any {
236
- self
237
- }
238
-
239
- fn properties(&self) -> &Arc<PlanProperties> {
240
- &self.properties
241
- }
242
-
243
- fn children(&self) -> Vec<&Arc<dyn ExecutionPlan>> {
244
- Vec::new()
245
- }
246
-
247
- fn with_new_children(
248
- self: Arc<Self>,
249
- children: Vec<Arc<dyn ExecutionPlan>>,
250
- ) -> Result<Arc<dyn ExecutionPlan>> {
251
- if !children.is_empty() {
252
- return Err(DataFusionError::Execution(
253
- "CommitSurfaceScanExec does not accept children".to_string(),
254
- ));
255
- }
256
- Ok(self)
257
- }
258
-
259
- fn execute(
260
- &self,
261
- partition: usize,
262
- _context: Arc<TaskContext>,
263
- ) -> Result<SendableRecordBatchStream> {
264
- if partition != 0 {
265
- return Err(DataFusionError::Execution(format!(
266
- "CommitSurfaceScanExec only exposes one partition, got {partition}"
267
- )));
268
- }
269
-
270
- let surface = self.surface;
271
- let commit_graph = Arc::clone(&self.commit_graph);
272
- let version_ref = Arc::clone(&self.version_ref);
273
- let projection = self.projection.clone();
274
- let limit = self.limit;
275
- let schema = Arc::clone(&self.schema);
276
- let stream = stream::once(async move {
277
- let version_ids = if surface.by_version() {
278
- resolve_provider_version_ids(
279
- version_ref.as_ref(),
280
- &VersionBinding::explicit(),
281
- Vec::new(),
282
- )
283
- .await
284
- .map_err(lix_error_to_datafusion_error)?
285
- } else {
286
- vec![GLOBAL_VERSION_ID.to_string()]
287
- };
288
- let rows = rows_for_surface(surface, &version_ids, Arc::clone(&commit_graph))
289
- .await
290
- .map_err(lix_error_to_datafusion_error)?;
291
- let rows = match limit {
292
- Some(limit) => rows.into_iter().take(limit).collect::<Vec<_>>(),
293
- None => rows,
294
- };
295
- surface_record_batch(surface, projection.as_ref(), &rows)
296
- });
297
- Ok(Box::pin(RecordBatchStreamAdapter::new(schema, stream)))
298
- }
299
- }
300
-
301
- #[derive(Debug, Clone)]
302
- enum SurfaceRow {
303
- CommitEdge {
304
- version_id: Option<String>,
305
- parent_id: String,
306
- child_id: String,
307
- },
308
- ChangeSet {
309
- version_id: Option<String>,
310
- id: String,
311
- },
312
- ChangeSetElement {
313
- version_id: Option<String>,
314
- change_set_id: String,
315
- change_id: String,
316
- entity_id: String,
317
- schema_key: String,
318
- file_id: Option<String>,
319
- },
320
- }
321
-
322
- async fn rows_for_surface(
323
- surface: CommitSurface,
324
- version_ids: &[String],
325
- commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
326
- ) -> Result<Vec<SurfaceRow>, LixError> {
327
- let mut rows = Vec::new();
328
- let mut seen = BTreeSet::<String>::new();
329
- let mut graph = commit_graph.lock().await;
330
- let commits = graph.all_commits().await?;
331
-
332
- for version_id in version_ids {
333
- match surface {
334
- CommitSurface::CommitEdge | CommitSurface::CommitEdgeByVersion => {
335
- for edge in graph.commit_edges(&commits) {
336
- let key = format!(
337
- "{version_id}\0edge\0{}\0{}",
338
- edge.parent_commit_id, edge.child_commit_id
339
- );
340
- if seen.insert(key) {
341
- rows.push(SurfaceRow::CommitEdge {
342
- version_id: surface.by_version().then(|| version_id.clone()),
343
- parent_id: edge.parent_commit_id,
344
- child_id: edge.child_commit_id,
345
- });
346
- }
347
- }
348
- }
349
- CommitSurface::ChangeSet | CommitSurface::ChangeSetByVersion => {
350
- for change_set in graph.change_sets(&commits) {
351
- let key = format!("{version_id}\0change_set\0{}", change_set.id);
352
- if seen.insert(key) {
353
- rows.push(SurfaceRow::ChangeSet {
354
- version_id: surface.by_version().then(|| version_id.clone()),
355
- id: change_set.id,
356
- });
357
- }
358
- }
359
- }
360
- CommitSurface::ChangeSetElement | CommitSurface::ChangeSetElementByVersion => {
361
- for element in graph.change_set_elements(&commits).await? {
362
- let key = format!(
363
- "{version_id}\0change_set_element\0{}\0{}",
364
- element.change_set_id, element.change.id
365
- );
366
- if seen.insert(key) {
367
- rows.push(SurfaceRow::ChangeSetElement {
368
- version_id: surface.by_version().then(|| version_id.clone()),
369
- change_set_id: element.change_set_id,
370
- entity_id: element.change.entity_id.as_string()?,
371
- change_id: element.change.id,
372
- schema_key: element.change.schema_key,
373
- file_id: element.change.file_id,
374
- });
375
- }
376
- }
377
- }
378
- }
379
- }
380
- Ok(rows)
381
- }
382
-
383
- fn surface_record_batch(
384
- surface: CommitSurface,
385
- projection: Option<&Vec<usize>>,
386
- rows: &[SurfaceRow],
387
- ) -> Result<RecordBatch> {
388
- let columns = surface_columns(surface, projection);
389
- let arrays = columns
390
- .iter()
391
- .map(|column| column.array(rows))
392
- .collect::<Vec<_>>();
393
- record_batch_with_row_count(surface_schema(&columns), arrays, rows.len()).map_err(|error| {
394
- DataFusionError::Execution(format!(
395
- "failed to build {} batch: {error}",
396
- surface.table_name()
397
- ))
398
- })
399
- }
400
-
401
- #[derive(Debug, Clone, Copy)]
402
- enum SurfaceColumn {
403
- Id,
404
- ChangeSetId,
405
- ParentId,
406
- ChildId,
407
- ChangeId,
408
- EntityId,
409
- SchemaKey,
410
- FileId,
411
- VersionId,
412
- Global,
413
- Untracked,
414
- }
415
-
416
- impl SurfaceColumn {
417
- fn field(self) -> Field {
418
- match self {
419
- Self::Id => Field::new("id", DataType::Utf8, false),
420
- Self::ChangeSetId => Field::new("change_set_id", DataType::Utf8, false),
421
- Self::ParentId => Field::new("parent_id", DataType::Utf8, false),
422
- Self::ChildId => Field::new("child_id", DataType::Utf8, false),
423
- Self::ChangeId => Field::new("change_id", DataType::Utf8, false),
424
- Self::EntityId => Field::new("entity_id", DataType::Utf8, false),
425
- Self::SchemaKey => Field::new("schema_key", DataType::Utf8, false),
426
- Self::FileId => Field::new("file_id", DataType::Utf8, true),
427
- Self::VersionId => Field::new("lixcol_version_id", DataType::Utf8, false),
428
- Self::Global => Field::new("lixcol_global", DataType::Boolean, false),
429
- Self::Untracked => Field::new("lixcol_untracked", DataType::Boolean, false),
430
- }
431
- }
432
-
433
- fn array(self, rows: &[SurfaceRow]) -> ArrayRef {
434
- match self {
435
- Self::Id => string_array(rows.iter().map(|row| match row {
436
- SurfaceRow::ChangeSet { id, .. } => Some(id.as_str()),
437
- _ => None,
438
- })),
439
- Self::ChangeSetId => string_array(rows.iter().map(|row| match row {
440
- SurfaceRow::ChangeSetElement { change_set_id, .. } => Some(change_set_id.as_str()),
441
- _ => None,
442
- })),
443
- Self::ParentId => string_array(rows.iter().map(|row| match row {
444
- SurfaceRow::CommitEdge { parent_id, .. } => Some(parent_id.as_str()),
445
- _ => None,
446
- })),
447
- Self::ChildId => string_array(rows.iter().map(|row| match row {
448
- SurfaceRow::CommitEdge { child_id, .. } => Some(child_id.as_str()),
449
- _ => None,
450
- })),
451
- Self::ChangeId => string_array(rows.iter().map(|row| match row {
452
- SurfaceRow::ChangeSetElement { change_id, .. } => Some(change_id.as_str()),
453
- _ => None,
454
- })),
455
- Self::EntityId => string_array(rows.iter().map(|row| match row {
456
- SurfaceRow::ChangeSetElement { entity_id, .. } => Some(entity_id.as_str()),
457
- _ => None,
458
- })),
459
- Self::SchemaKey => string_array(rows.iter().map(|row| match row {
460
- SurfaceRow::ChangeSetElement { schema_key, .. } => Some(schema_key.as_str()),
461
- _ => None,
462
- })),
463
- Self::FileId => string_array(rows.iter().map(|row| match row {
464
- SurfaceRow::ChangeSetElement { file_id, .. } => file_id.as_deref(),
465
- _ => None,
466
- })),
467
- Self::VersionId => string_array(rows.iter().map(|row| match row {
468
- SurfaceRow::CommitEdge { version_id, .. }
469
- | SurfaceRow::ChangeSet { version_id, .. }
470
- | SurfaceRow::ChangeSetElement { version_id, .. } => version_id.as_deref(),
471
- })),
472
- Self::Global => Arc::new(BooleanArray::from(vec![true; rows.len()])) as ArrayRef,
473
- Self::Untracked => Arc::new(BooleanArray::from(vec![false; rows.len()])) as ArrayRef,
474
- }
475
- }
476
- }
477
-
478
- fn surface_columns(surface: CommitSurface, projection: Option<&Vec<usize>>) -> Vec<SurfaceColumn> {
479
- let all_columns = match surface {
480
- CommitSurface::CommitEdge => vec![
481
- SurfaceColumn::ParentId,
482
- SurfaceColumn::ChildId,
483
- SurfaceColumn::Global,
484
- SurfaceColumn::Untracked,
485
- ],
486
- CommitSurface::CommitEdgeByVersion => vec![
487
- SurfaceColumn::ParentId,
488
- SurfaceColumn::ChildId,
489
- SurfaceColumn::VersionId,
490
- SurfaceColumn::Global,
491
- SurfaceColumn::Untracked,
492
- ],
493
- CommitSurface::ChangeSet => vec![
494
- SurfaceColumn::Id,
495
- SurfaceColumn::Global,
496
- SurfaceColumn::Untracked,
497
- ],
498
- CommitSurface::ChangeSetByVersion => vec![
499
- SurfaceColumn::Id,
500
- SurfaceColumn::VersionId,
501
- SurfaceColumn::Global,
502
- SurfaceColumn::Untracked,
503
- ],
504
- CommitSurface::ChangeSetElement => vec![
505
- SurfaceColumn::ChangeSetId,
506
- SurfaceColumn::ChangeId,
507
- SurfaceColumn::EntityId,
508
- SurfaceColumn::SchemaKey,
509
- SurfaceColumn::FileId,
510
- SurfaceColumn::Global,
511
- SurfaceColumn::Untracked,
512
- ],
513
- CommitSurface::ChangeSetElementByVersion => vec![
514
- SurfaceColumn::ChangeSetId,
515
- SurfaceColumn::ChangeId,
516
- SurfaceColumn::EntityId,
517
- SurfaceColumn::SchemaKey,
518
- SurfaceColumn::FileId,
519
- SurfaceColumn::VersionId,
520
- SurfaceColumn::Global,
521
- SurfaceColumn::Untracked,
522
- ],
523
- };
524
- projection.map_or(all_columns.clone(), |indices| {
525
- indices
526
- .iter()
527
- .filter_map(|index| all_columns.get(*index).copied())
528
- .collect()
529
- })
530
- }
531
-
532
- fn surface_schema(columns: &[SurfaceColumn]) -> SchemaRef {
533
- Arc::new(Schema::new(
534
- columns
535
- .iter()
536
- .map(|column| column.field())
537
- .collect::<Vec<_>>(),
538
- ))
539
- }
540
-
541
- fn commit_edge_schema(by_version: bool) -> SchemaRef {
542
- surface_schema(&surface_columns(
543
- if by_version {
544
- CommitSurface::CommitEdgeByVersion
545
- } else {
546
- CommitSurface::CommitEdge
547
- },
548
- None,
549
- ))
550
- }
551
-
552
- fn change_set_schema(by_version: bool) -> SchemaRef {
553
- surface_schema(&surface_columns(
554
- if by_version {
555
- CommitSurface::ChangeSetByVersion
556
- } else {
557
- CommitSurface::ChangeSet
558
- },
559
- None,
560
- ))
561
- }
562
-
563
- fn change_set_element_schema(by_version: bool) -> SchemaRef {
564
- surface_schema(&surface_columns(
565
- if by_version {
566
- CommitSurface::ChangeSetElementByVersion
567
- } else {
568
- CommitSurface::ChangeSetElement
569
- },
570
- None,
571
- ))
572
- }
573
-
574
- fn projected_schema(schema: &SchemaRef, projection: Option<&Vec<usize>>) -> SchemaRef {
575
- match projection {
576
- Some(projection) => Arc::new(schema.project(projection).expect("projection is valid")),
577
- None => Arc::clone(schema),
578
- }
579
- }
580
-
581
- fn string_array<'a>(values: impl Iterator<Item = Option<&'a str>>) -> ArrayRef {
582
- Arc::new(StringArray::from(values.collect::<Vec<_>>())) as ArrayRef
583
- }
584
-
585
- fn datafusion_error_to_lix_error(error: DataFusionError) -> LixError {
586
- super::error::datafusion_error_to_lix_error(error)
587
- }
588
-
589
- fn lix_error_to_datafusion_error(error: LixError) -> DataFusionError {
590
- super::error::lix_error_to_datafusion_error(error)
591
- }