@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.
- package/SKILL.md +46 -8
- package/dist/engine-wasm/wasm/lix_engine.d.ts +25 -1
- package/dist/engine-wasm/wasm/lix_engine.js +60 -2
- package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
- package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +5 -0
- package/dist/generated/builtin-schemas.d.ts +87 -162
- package/dist/generated/builtin-schemas.js +139 -236
- package/dist/open-lix.d.ts +10 -3
- package/dist/open-lix.js +39 -0
- package/dist-engine-src/src/binary_cas/types.rs +0 -6
- package/dist-engine-src/src/catalog/context.rs +412 -0
- package/dist-engine-src/src/catalog/mod.rs +10 -0
- package/dist-engine-src/src/catalog/schema.rs +4 -0
- package/dist-engine-src/src/catalog/snapshot.rs +1114 -0
- package/dist-engine-src/src/cel/mod.rs +1 -1
- package/dist-engine-src/src/cel/provider.rs +1 -1
- package/dist-engine-src/src/commit_graph/context.rs +328 -1015
- package/dist-engine-src/src/commit_graph/mod.rs +2 -3
- package/dist-engine-src/src/commit_graph/types.rs +7 -43
- package/dist-engine-src/src/commit_graph/walker.rs +57 -81
- package/dist-engine-src/src/commit_store/codec.rs +887 -0
- package/dist-engine-src/src/commit_store/context.rs +944 -0
- package/dist-engine-src/src/commit_store/materialization.rs +84 -0
- package/dist-engine-src/src/commit_store/mod.rs +16 -0
- package/dist-engine-src/src/commit_store/storage.rs +600 -0
- package/dist-engine-src/src/commit_store/types.rs +215 -0
- package/dist-engine-src/src/common/identity.rs +15 -5
- package/dist-engine-src/src/common/json_pointer.rs +67 -0
- package/dist-engine-src/src/common/metadata.rs +17 -12
- package/dist-engine-src/src/common/mod.rs +5 -5
- package/dist-engine-src/src/domain.rs +324 -0
- package/dist-engine-src/src/engine.rs +29 -43
- package/dist-engine-src/src/entity_identity.rs +238 -118
- package/dist-engine-src/src/functions/context.rs +17 -52
- package/dist-engine-src/src/functions/deterministic.rs +1 -1
- package/dist-engine-src/src/functions/mod.rs +1 -1
- package/dist-engine-src/src/functions/provider.rs +4 -4
- package/dist-engine-src/src/functions/state.rs +39 -66
- package/dist-engine-src/src/functions/types.rs +1 -1
- package/dist-engine-src/src/init.rs +204 -151
- package/dist-engine-src/src/json_store/context.rs +354 -60
- package/dist-engine-src/src/json_store/encoded.rs +6 -6
- package/dist-engine-src/src/json_store/mod.rs +4 -1
- package/dist-engine-src/src/json_store/store.rs +884 -11
- package/dist-engine-src/src/json_store/types.rs +166 -1
- package/dist-engine-src/src/lib.rs +11 -10
- package/dist-engine-src/src/live_state/context.rs +608 -830
- package/dist-engine-src/src/live_state/mod.rs +3 -3
- package/dist-engine-src/src/live_state/overlay.rs +7 -7
- package/dist-engine-src/src/live_state/reader.rs +5 -5
- package/dist-engine-src/src/live_state/types.rs +19 -36
- package/dist-engine-src/src/live_state/visibility.rs +19 -14
- package/dist-engine-src/src/plugin/archive.rs +3 -6
- package/dist-engine-src/src/plugin/install.rs +0 -18
- package/dist-engine-src/src/plugin/plugin_manifest.json +0 -1
- package/dist-engine-src/src/schema/annotations/defaults.rs +2 -7
- package/dist-engine-src/src/schema/builtin/lix_account.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_active_account.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_change.json +11 -10
- package/dist-engine-src/src/schema/builtin/lix_change_author.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_commit.json +8 -46
- package/dist-engine-src/src/schema/builtin/lix_commit_edge.json +29 -22
- package/dist-engine-src/src/schema/builtin/lix_directory_descriptor.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_file_descriptor.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_key_value.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_label.json +10 -3
- package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +74 -0
- package/dist-engine-src/src/schema/builtin/lix_registered_schema.json +2 -8
- package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -1
- package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -1
- package/dist-engine-src/src/schema/builtin/mod.rs +10 -59
- package/dist-engine-src/src/schema/compatibility.rs +787 -0
- package/dist-engine-src/src/schema/definition.json +47 -17
- package/dist-engine-src/src/schema/definition.rs +202 -96
- package/dist-engine-src/src/schema/key.rs +9 -77
- package/dist-engine-src/src/schema/mod.rs +4 -4
- package/dist-engine-src/src/schema/tests.rs +133 -92
- package/dist-engine-src/src/session/context.rs +86 -48
- package/dist-engine-src/src/session/create_version.rs +22 -14
- package/dist-engine-src/src/session/execute.rs +117 -23
- package/dist-engine-src/src/session/merge/apply.rs +4 -4
- package/dist-engine-src/src/session/merge/conflicts.rs +3 -2
- package/dist-engine-src/src/session/merge/stats.rs +1 -1
- package/dist-engine-src/src/session/merge/version.rs +35 -45
- package/dist-engine-src/src/session/mod.rs +9 -7
- package/dist-engine-src/src/session/optimization9_sql2_bench.rs +100 -0
- package/dist-engine-src/src/session/switch_version.rs +17 -28
- package/dist-engine-src/src/session/transaction.rs +76 -0
- package/dist-engine-src/src/sql2/change_provider.rs +14 -20
- package/dist-engine-src/src/sql2/classify.rs +75 -48
- package/dist-engine-src/src/sql2/context.rs +22 -18
- package/dist-engine-src/src/sql2/directory_history_provider.rs +28 -20
- package/dist-engine-src/src/sql2/directory_provider.rs +131 -83
- package/dist-engine-src/src/sql2/entity_history_provider.rs +10 -14
- package/dist-engine-src/src/sql2/entity_provider.rs +680 -169
- package/dist-engine-src/src/sql2/error.rs +24 -5
- package/dist-engine-src/src/sql2/execute.rs +426 -272
- package/dist-engine-src/src/sql2/file_history_provider.rs +29 -21
- package/dist-engine-src/src/sql2/file_provider.rs +533 -108
- package/dist-engine-src/src/sql2/filesystem_planner.rs +58 -94
- package/dist-engine-src/src/sql2/filesystem_visibility.rs +37 -23
- package/dist-engine-src/src/sql2/history_projection.rs +3 -27
- package/dist-engine-src/src/sql2/history_provider.rs +11 -17
- package/dist-engine-src/src/sql2/history_route.rs +22 -8
- package/dist-engine-src/src/sql2/lix_state_provider.rs +178 -96
- package/dist-engine-src/src/sql2/mod.rs +8 -4
- package/dist-engine-src/src/sql2/predicate_typecheck.rs +246 -0
- package/dist-engine-src/src/sql2/public_bind/assignment.rs +46 -0
- package/dist-engine-src/src/sql2/public_bind/capability.rs +41 -0
- package/dist-engine-src/src/sql2/public_bind/dml.rs +172 -0
- package/dist-engine-src/src/sql2/public_bind/mod.rs +26 -0
- package/dist-engine-src/src/sql2/public_bind/table.rs +168 -0
- package/dist-engine-src/src/sql2/read_only.rs +10 -12
- package/dist-engine-src/src/sql2/session.rs +7 -10
- package/dist-engine-src/src/sql2/udfs/lix_timestamp.rs +76 -0
- package/dist-engine-src/src/sql2/udfs/mod.rs +8 -1
- package/dist-engine-src/src/sql2/udfs/public_call.rs +238 -0
- package/dist-engine-src/src/sql2/version_provider.rs +46 -31
- package/dist-engine-src/src/sql2/version_scope.rs +4 -4
- package/dist-engine-src/src/storage_bench.rs +1782 -325
- package/dist-engine-src/src/test_support.rs +183 -36
- package/dist-engine-src/src/tracked_state/by_file_index.rs +20 -24
- package/dist-engine-src/src/tracked_state/codec.rs +1519 -181
- package/dist-engine-src/src/tracked_state/context.rs +1155 -271
- package/dist-engine-src/src/tracked_state/diff.rs +249 -57
- package/dist-engine-src/src/tracked_state/materialization.rs +365 -103
- package/dist-engine-src/src/tracked_state/materializer.rs +488 -0
- package/dist-engine-src/src/tracked_state/merge.rs +37 -19
- package/dist-engine-src/src/tracked_state/mod.rs +8 -7
- package/dist-engine-src/src/tracked_state/storage.rs +138 -6
- package/dist-engine-src/src/tracked_state/tree.rs +695 -252
- package/dist-engine-src/src/tracked_state/types.rs +176 -6
- package/dist-engine-src/src/transaction/commit.rs +695 -435
- package/dist-engine-src/src/transaction/context.rs +551 -310
- package/dist-engine-src/src/transaction/live_state_overlay.rs +9 -8
- package/dist-engine-src/src/transaction/mod.rs +2 -0
- package/dist-engine-src/src/transaction/normalization.rs +311 -447
- package/dist-engine-src/src/transaction/prep.rs +37 -0
- package/dist-engine-src/src/transaction/schema_resolver.rs +93 -71
- package/dist-engine-src/src/transaction/staging.rs +701 -406
- package/dist-engine-src/src/transaction/types.rs +231 -122
- package/dist-engine-src/src/transaction/validation.rs +2717 -1698
- package/dist-engine-src/src/untracked_state/codec.rs +40 -96
- package/dist-engine-src/src/untracked_state/context.rs +21 -5
- package/dist-engine-src/src/untracked_state/materialization.rs +10 -104
- package/dist-engine-src/src/untracked_state/mod.rs +3 -5
- package/dist-engine-src/src/untracked_state/storage.rs +105 -57
- package/dist-engine-src/src/untracked_state/types.rs +63 -13
- package/dist-engine-src/src/version/context.rs +1 -13
- package/dist-engine-src/src/version/lifecycle.rs +221 -0
- package/dist-engine-src/src/version/mod.rs +3 -2
- package/dist-engine-src/src/version/refs.rs +12 -103
- package/dist-engine-src/src/version/stage_rows.rs +15 -19
- package/package.json +1 -1
- package/dist-engine-src/src/changelog/codec.rs +0 -321
- package/dist-engine-src/src/changelog/context.rs +0 -92
- package/dist-engine-src/src/changelog/materialization.rs +0 -121
- package/dist-engine-src/src/changelog/mod.rs +0 -13
- package/dist-engine-src/src/changelog/reader.rs +0 -20
- package/dist-engine-src/src/changelog/storage.rs +0 -220
- package/dist-engine-src/src/changelog/types.rs +0 -38
- package/dist-engine-src/src/schema/builtin/lix_change_set.json +0 -18
- package/dist-engine-src/src/schema/builtin/lix_change_set_element.json +0 -75
- package/dist-engine-src/src/schema/builtin/lix_entity_label.json +0 -63
- package/dist-engine-src/src/schema_registry.rs +0 -294
- package/dist-engine-src/src/sql2/commit_derived_provider.rs +0 -591
- package/dist-engine-src/src/tracked_state/rebuild.rs +0 -771
- package/dist-engine-src/src/tracked_state/tree_types.rs +0 -176
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
use datafusion::sql::parser::Statement as DataFusionStatement;
|
|
1
2
|
use datafusion::sql::sqlparser::ast::{
|
|
2
|
-
FromTable, ObjectName, Query, SetExpr, Statement, TableFactor, TableObject,
|
|
3
|
+
FromTable, ObjectName, Query, SetExpr, Statement as SqlStatement, TableFactor, TableObject,
|
|
4
|
+
TableWithJoins,
|
|
3
5
|
};
|
|
4
|
-
use datafusion::sql::sqlparser::dialect::GenericDialect;
|
|
5
|
-
use datafusion::sql::sqlparser::parser::Parser;
|
|
6
6
|
|
|
7
7
|
use crate::LixError;
|
|
8
8
|
|
|
@@ -13,56 +13,73 @@ pub(crate) enum SqlStatementKind {
|
|
|
13
13
|
Other,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
pub(crate) fn
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
pub(crate) fn validate_supported_datafusion_statement_ast(
|
|
17
|
+
statement: &DataFusionStatement,
|
|
18
|
+
) -> Result<(), LixError> {
|
|
19
|
+
match statement {
|
|
20
|
+
DataFusionStatement::Statement(statement) => validate_supported_ast_statement(statement),
|
|
21
|
+
DataFusionStatement::Explain(explain) => {
|
|
22
|
+
if classify_datafusion_statement(explain.statement.as_ref()) == SqlStatementKind::Write
|
|
23
|
+
{
|
|
24
|
+
return Err(unsupported_sql_error(
|
|
25
|
+
"EXPLAIN of write statements is not supported by Lix SQL",
|
|
26
|
+
));
|
|
27
|
+
}
|
|
28
|
+
validate_supported_datafusion_statement_ast(explain.statement.as_ref())
|
|
29
|
+
}
|
|
30
|
+
_ => Err(unsupported_sql_error(format!(
|
|
31
|
+
"SQL statement is not supported by Lix SQL: {statement}"
|
|
32
|
+
))),
|
|
33
|
+
}
|
|
22
34
|
}
|
|
23
35
|
|
|
24
|
-
pub(crate) fn
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
validate_supported_ast_statement(statement)
|
|
36
|
+
pub(crate) fn classify_datafusion_statement(statement: &DataFusionStatement) -> SqlStatementKind {
|
|
37
|
+
match statement {
|
|
38
|
+
DataFusionStatement::Statement(statement) => classify_ast_statement(statement),
|
|
39
|
+
DataFusionStatement::Explain(_) => SqlStatementKind::Read,
|
|
40
|
+
_ => SqlStatementKind::Other,
|
|
41
|
+
}
|
|
32
42
|
}
|
|
33
43
|
|
|
34
|
-
pub(crate) fn
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return Ok(Vec::new());
|
|
38
|
-
};
|
|
44
|
+
pub(crate) fn datafusion_statement_dml_target_table_names(
|
|
45
|
+
statement: &DataFusionStatement,
|
|
46
|
+
) -> Vec<String> {
|
|
39
47
|
let mut targets = Vec::new();
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
collect_datafusion_statement_dml_target_table_names(statement, &mut targets);
|
|
49
|
+
targets
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
fn
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
)
|
|
50
|
-
|
|
52
|
+
fn collect_datafusion_statement_dml_target_table_names(
|
|
53
|
+
statement: &DataFusionStatement,
|
|
54
|
+
targets: &mut Vec<String>,
|
|
55
|
+
) {
|
|
56
|
+
match statement {
|
|
57
|
+
DataFusionStatement::Statement(statement) => {
|
|
58
|
+
collect_dml_target_table_names(statement, targets);
|
|
59
|
+
}
|
|
60
|
+
DataFusionStatement::Explain(explain) => {
|
|
61
|
+
collect_datafusion_statement_dml_target_table_names(
|
|
62
|
+
explain.statement.as_ref(),
|
|
63
|
+
targets,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
_ => {}
|
|
67
|
+
}
|
|
51
68
|
}
|
|
52
69
|
|
|
53
|
-
fn collect_dml_target_table_names(statement: &
|
|
70
|
+
fn collect_dml_target_table_names(statement: &SqlStatement, targets: &mut Vec<String>) {
|
|
54
71
|
match statement {
|
|
55
|
-
|
|
72
|
+
SqlStatement::Insert(insert) => {
|
|
56
73
|
if let TableObject::TableName(name) = &insert.table {
|
|
57
74
|
if let Some(table_name) = object_name_table_part(name) {
|
|
58
75
|
targets.push(table_name);
|
|
59
76
|
}
|
|
60
77
|
}
|
|
61
78
|
}
|
|
62
|
-
|
|
79
|
+
SqlStatement::Update(update) => {
|
|
63
80
|
collect_table_with_joins_target(&update.table, targets);
|
|
64
81
|
}
|
|
65
|
-
|
|
82
|
+
SqlStatement::Delete(delete) => {
|
|
66
83
|
let tables = match &delete.from {
|
|
67
84
|
FromTable::WithFromKeyword(tables) | FromTable::WithoutKeyword(tables) => tables,
|
|
68
85
|
};
|
|
@@ -70,7 +87,7 @@ fn collect_dml_target_table_names(statement: &Statement, targets: &mut Vec<Strin
|
|
|
70
87
|
collect_table_with_joins_target(table, targets);
|
|
71
88
|
}
|
|
72
89
|
}
|
|
73
|
-
|
|
90
|
+
SqlStatement::Explain { statement, .. } => {
|
|
74
91
|
collect_dml_target_table_names(statement.as_ref(), targets);
|
|
75
92
|
}
|
|
76
93
|
_ => {}
|
|
@@ -86,28 +103,38 @@ fn collect_table_with_joins_target(table: &TableWithJoins, targets: &mut Vec<Str
|
|
|
86
103
|
}
|
|
87
104
|
|
|
88
105
|
fn object_name_table_part(name: &ObjectName) -> Option<String> {
|
|
89
|
-
name.0
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
106
|
+
name.0.last().and_then(|part| part.as_ident()).map(|ident| {
|
|
107
|
+
if ident.quote_style.is_some() {
|
|
108
|
+
ident.value.clone()
|
|
109
|
+
} else {
|
|
110
|
+
ident.value.to_ascii_lowercase()
|
|
111
|
+
}
|
|
112
|
+
})
|
|
93
113
|
}
|
|
94
114
|
|
|
95
|
-
fn classify_ast_statement(statement: &
|
|
115
|
+
fn classify_ast_statement(statement: &SqlStatement) -> SqlStatementKind {
|
|
96
116
|
match statement {
|
|
97
|
-
|
|
117
|
+
SqlStatement::Insert(_) | SqlStatement::Update(_) | SqlStatement::Delete(_) => {
|
|
98
118
|
SqlStatementKind::Write
|
|
99
119
|
}
|
|
100
|
-
|
|
101
|
-
|
|
120
|
+
SqlStatement::Query(_) => SqlStatementKind::Read,
|
|
121
|
+
SqlStatement::Explain { .. } => SqlStatementKind::Read,
|
|
102
122
|
_ => SqlStatementKind::Other,
|
|
103
123
|
}
|
|
104
124
|
}
|
|
105
125
|
|
|
106
|
-
fn validate_supported_ast_statement(statement: &
|
|
126
|
+
fn validate_supported_ast_statement(statement: &SqlStatement) -> Result<(), LixError> {
|
|
107
127
|
match statement {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
128
|
+
SqlStatement::Query(query) => validate_supported_query(query),
|
|
129
|
+
SqlStatement::Insert(_) | SqlStatement::Update(_) | SqlStatement::Delete(_) => Ok(()),
|
|
130
|
+
SqlStatement::Explain { statement, .. } => {
|
|
131
|
+
if classify_ast_statement(statement.as_ref()) == SqlStatementKind::Write {
|
|
132
|
+
return Err(unsupported_sql_error(
|
|
133
|
+
"EXPLAIN of write statements is not supported by Lix SQL",
|
|
134
|
+
));
|
|
135
|
+
}
|
|
136
|
+
validate_supported_ast_statement(statement)
|
|
137
|
+
}
|
|
111
138
|
_ => Err(unsupported_sql_error(format!(
|
|
112
139
|
"SQL statement is not supported by Lix SQL: {statement}"
|
|
113
140
|
))),
|
|
@@ -6,26 +6,27 @@ use serde_json::Value as JsonValue;
|
|
|
6
6
|
use tokio::sync::Mutex;
|
|
7
7
|
|
|
8
8
|
use crate::binary_cas::{BlobBytesBatch, BlobDataReader, BlobHash};
|
|
9
|
-
use crate::changelog::ChangelogReader;
|
|
10
9
|
use crate::commit_graph::CommitGraphReader;
|
|
10
|
+
use crate::commit_store::CommitStoreReader;
|
|
11
11
|
use crate::functions::FunctionProviderHandle;
|
|
12
12
|
use crate::json_store::JsonStoreReader;
|
|
13
13
|
use crate::live_state::{
|
|
14
|
-
LiveStateFilter, LiveStateReader,
|
|
14
|
+
LiveStateFilter, LiveStateReader, LiveStateRowRequest, LiveStateScanRequest,
|
|
15
|
+
MaterializedLiveStateRow,
|
|
15
16
|
};
|
|
16
17
|
use crate::storage::{ScopedStorageReader, StorageReadTransaction};
|
|
17
|
-
use crate::transaction::types::{
|
|
18
|
+
use crate::transaction::types::{TransactionWrite, TransactionWriteOutcome};
|
|
18
19
|
use crate::version::{VersionHead, VersionRefReader};
|
|
19
20
|
use crate::LixError;
|
|
20
21
|
|
|
21
22
|
pub(crate) type SqlReadStore =
|
|
22
23
|
ScopedStorageReader<Box<dyn StorageReadTransaction + Send + Sync + 'static>>;
|
|
23
|
-
pub(crate) type
|
|
24
|
+
pub(crate) type SqlCommitStoreQuerySource = CommitStoreQuerySource<SqlReadStore>;
|
|
24
25
|
pub(crate) type SqlJsonReader = JsonStoreReader<ScopedStorageReader<SqlReadStore>>;
|
|
25
26
|
|
|
26
27
|
#[derive(Clone)]
|
|
27
|
-
pub(crate) struct
|
|
28
|
-
pub(crate)
|
|
28
|
+
pub(crate) struct CommitStoreQuerySource<S> {
|
|
29
|
+
pub(crate) commit_store_reader: Arc<CommitStoreReader<ScopedStorageReader<S>>>,
|
|
29
30
|
pub(crate) json_reader: JsonStoreReader<ScopedStorageReader<S>>,
|
|
30
31
|
}
|
|
31
32
|
|
|
@@ -43,7 +44,7 @@ pub(crate) trait SqlExecutionContext {
|
|
|
43
44
|
fn active_version_id(&self) -> &str;
|
|
44
45
|
fn live_state(&self) -> Arc<dyn LiveStateReader>;
|
|
45
46
|
fn functions(&self) -> FunctionProviderHandle;
|
|
46
|
-
fn
|
|
47
|
+
fn commit_store_query_source(&self) -> SqlCommitStoreQuerySource;
|
|
47
48
|
fn commit_graph(&self) -> Box<dyn CommitGraphReader>;
|
|
48
49
|
fn version_ref(&self) -> Arc<dyn VersionRefReader>;
|
|
49
50
|
fn blob_reader(&self) -> Arc<dyn BlobDataReader>;
|
|
@@ -52,9 +53,9 @@ pub(crate) trait SqlExecutionContext {
|
|
|
52
53
|
|
|
53
54
|
/// Write-capable SQL runtime boundary.
|
|
54
55
|
///
|
|
55
|
-
/// Providers that mutate
|
|
56
|
+
/// Providers that mutate engine state should target this shape instead of
|
|
56
57
|
/// reaching through session/backend escape hatches. The request and write
|
|
57
|
-
/// payloads stay in the existing
|
|
58
|
+
/// payloads stay in the existing engine forms so this boundary centralizes
|
|
58
59
|
/// authority without adding another translation layer.
|
|
59
60
|
#[async_trait]
|
|
60
61
|
#[allow(dead_code)]
|
|
@@ -68,11 +69,14 @@ pub(crate) trait SqlWriteExecutionContext {
|
|
|
68
69
|
async fn scan_live_state(
|
|
69
70
|
&mut self,
|
|
70
71
|
request: &LiveStateScanRequest,
|
|
71
|
-
) -> Result<Vec<
|
|
72
|
+
) -> Result<Vec<MaterializedLiveStateRow>, LixError>;
|
|
72
73
|
|
|
73
74
|
async fn load_version_head(&mut self, version_id: &str) -> Result<Option<String>, LixError>;
|
|
74
75
|
|
|
75
|
-
async fn stage_write(
|
|
76
|
+
async fn stage_write(
|
|
77
|
+
&mut self,
|
|
78
|
+
write: TransactionWrite,
|
|
79
|
+
) -> Result<TransactionWriteOutcome, LixError>;
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
#[derive(Clone)]
|
|
@@ -123,7 +127,7 @@ impl SqlWriteContext {
|
|
|
123
127
|
pub(crate) async fn scan_live_state(
|
|
124
128
|
&self,
|
|
125
129
|
request: &LiveStateScanRequest,
|
|
126
|
-
) -> Result<Vec<
|
|
130
|
+
) -> Result<Vec<MaterializedLiveStateRow>, LixError> {
|
|
127
131
|
let _guard = self.gate.lock().await;
|
|
128
132
|
unsafe {
|
|
129
133
|
self.ptr
|
|
@@ -170,8 +174,8 @@ impl SqlWriteContext {
|
|
|
170
174
|
|
|
171
175
|
pub(crate) async fn stage_write(
|
|
172
176
|
&self,
|
|
173
|
-
write:
|
|
174
|
-
) -> Result<
|
|
177
|
+
write: TransactionWrite,
|
|
178
|
+
) -> Result<TransactionWriteOutcome, LixError> {
|
|
175
179
|
let _guard = self.gate.lock().await;
|
|
176
180
|
unsafe {
|
|
177
181
|
self.ptr
|
|
@@ -219,12 +223,12 @@ impl WriteAccess {
|
|
|
219
223
|
|
|
220
224
|
pub(crate) fn require_write(
|
|
221
225
|
&self,
|
|
222
|
-
|
|
226
|
+
action: &str,
|
|
223
227
|
) -> Result<SqlWriteContext, datafusion::error::DataFusionError> {
|
|
224
228
|
match self {
|
|
225
229
|
Self::Write { ctx } => Ok(ctx.clone()),
|
|
226
230
|
Self::ReadOnly => Err(datafusion::error::DataFusionError::Execution(format!(
|
|
227
|
-
"{
|
|
231
|
+
"{action} requires a write transaction"
|
|
228
232
|
))),
|
|
229
233
|
}
|
|
230
234
|
}
|
|
@@ -249,14 +253,14 @@ impl LiveStateReader for WriteContextLiveStateReader {
|
|
|
249
253
|
async fn scan_rows(
|
|
250
254
|
&self,
|
|
251
255
|
request: &LiveStateScanRequest,
|
|
252
|
-
) -> Result<Vec<
|
|
256
|
+
) -> Result<Vec<MaterializedLiveStateRow>, LixError> {
|
|
253
257
|
self.ctx.scan_live_state(request).await
|
|
254
258
|
}
|
|
255
259
|
|
|
256
260
|
async fn load_row(
|
|
257
261
|
&self,
|
|
258
262
|
request: &LiveStateRowRequest,
|
|
259
|
-
) -> Result<Option<
|
|
263
|
+
) -> Result<Option<MaterializedLiveStateRow>, LixError> {
|
|
260
264
|
let mut rows = self
|
|
261
265
|
.ctx
|
|
262
266
|
.scan_live_state(&LiveStateScanRequest {
|
|
@@ -21,7 +21,6 @@ use futures_util::stream;
|
|
|
21
21
|
use serde::Deserialize;
|
|
22
22
|
use tokio::sync::Mutex;
|
|
23
23
|
|
|
24
|
-
use crate::changelog::MaterializedCanonicalChange;
|
|
25
24
|
use crate::commit_graph::CommitGraphReader;
|
|
26
25
|
use crate::serialize_row_metadata;
|
|
27
26
|
use crate::LixError;
|
|
@@ -32,17 +31,18 @@ use super::history_route::{
|
|
|
32
31
|
HistoryColumnStyle, HistoryEntry, HistoryRoute, HistoryViewDescriptor, HISTORY_COL_CHANGE_ID,
|
|
33
32
|
HISTORY_COL_COMMIT_CREATED_AT, HISTORY_COL_DEPTH, HISTORY_COL_ENTITY_ID, HISTORY_COL_FILE_ID,
|
|
34
33
|
HISTORY_COL_METADATA, HISTORY_COL_OBSERVED_COMMIT_ID, HISTORY_COL_SCHEMA_KEY,
|
|
35
|
-
|
|
34
|
+
HISTORY_COL_SNAPSHOT_CONTENT, HISTORY_COL_START_COMMIT_ID,
|
|
36
35
|
};
|
|
37
36
|
use super::result_metadata::json_field;
|
|
38
|
-
use super::
|
|
37
|
+
use super::SqlCommitStoreQuerySource;
|
|
38
|
+
use crate::commit_store::MaterializedChange;
|
|
39
39
|
|
|
40
40
|
const DIRECTORY_DESCRIPTOR_SCHEMA_KEY: &str = "lix_directory_descriptor";
|
|
41
41
|
|
|
42
42
|
pub(crate) async fn register_lix_directory_history_provider(
|
|
43
43
|
session: &datafusion::prelude::SessionContext,
|
|
44
44
|
commit_graph: Box<dyn CommitGraphReader>,
|
|
45
|
-
query_source:
|
|
45
|
+
query_source: SqlCommitStoreQuerySource,
|
|
46
46
|
) -> Result<(), LixError> {
|
|
47
47
|
session
|
|
48
48
|
.register_table(
|
|
@@ -59,7 +59,7 @@ pub(crate) async fn register_lix_directory_history_provider(
|
|
|
59
59
|
struct LixDirectoryHistoryProvider {
|
|
60
60
|
schema: SchemaRef,
|
|
61
61
|
commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
|
|
62
|
-
query_source:
|
|
62
|
+
query_source: SqlCommitStoreQuerySource,
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
impl std::fmt::Debug for LixDirectoryHistoryProvider {
|
|
@@ -71,7 +71,7 @@ impl std::fmt::Debug for LixDirectoryHistoryProvider {
|
|
|
71
71
|
impl LixDirectoryHistoryProvider {
|
|
72
72
|
fn new(
|
|
73
73
|
commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
|
|
74
|
-
query_source:
|
|
74
|
+
query_source: SqlCommitStoreQuerySource,
|
|
75
75
|
) -> Self {
|
|
76
76
|
Self {
|
|
77
77
|
schema: lix_directory_history_schema(),
|
|
@@ -130,7 +130,7 @@ impl TableProvider for LixDirectoryHistoryProvider {
|
|
|
130
130
|
|
|
131
131
|
struct LixDirectoryHistoryScanExec {
|
|
132
132
|
commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
|
|
133
|
-
query_source:
|
|
133
|
+
query_source: SqlCommitStoreQuerySource,
|
|
134
134
|
schema: SchemaRef,
|
|
135
135
|
route: HistoryRoute,
|
|
136
136
|
limit: Option<usize>,
|
|
@@ -149,7 +149,7 @@ impl std::fmt::Debug for LixDirectoryHistoryScanExec {
|
|
|
149
149
|
impl LixDirectoryHistoryScanExec {
|
|
150
150
|
fn new(
|
|
151
151
|
commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
|
|
152
|
-
query_source:
|
|
152
|
+
query_source: SqlCommitStoreQuerySource,
|
|
153
153
|
schema: SchemaRef,
|
|
154
154
|
route: HistoryRoute,
|
|
155
155
|
limit: Option<usize>,
|
|
@@ -265,7 +265,7 @@ struct DirectoryHistoryOutputRow {
|
|
|
265
265
|
parent_id: Option<String>,
|
|
266
266
|
name: Option<String>,
|
|
267
267
|
hidden: Option<bool>,
|
|
268
|
-
descriptor_change:
|
|
268
|
+
descriptor_change: MaterializedChange,
|
|
269
269
|
event: DirectoryHistoryEvent,
|
|
270
270
|
}
|
|
271
271
|
|
|
@@ -274,7 +274,7 @@ struct DirectoryHistoryEvent {
|
|
|
274
274
|
directory_id: String,
|
|
275
275
|
start_commit_id: String,
|
|
276
276
|
depth: u32,
|
|
277
|
-
change:
|
|
277
|
+
change: MaterializedChange,
|
|
278
278
|
observed_commit_id: String,
|
|
279
279
|
commit_created_at: String,
|
|
280
280
|
}
|
|
@@ -289,7 +289,7 @@ struct DirectoryDescriptorSnapshot {
|
|
|
289
289
|
|
|
290
290
|
async fn load_directory_history_rows(
|
|
291
291
|
commit_graph: Arc<Mutex<Box<dyn CommitGraphReader>>>,
|
|
292
|
-
query_source:
|
|
292
|
+
query_source: SqlCommitStoreQuerySource,
|
|
293
293
|
route: &HistoryRoute,
|
|
294
294
|
) -> Result<Vec<DirectoryHistoryOutputRow>, LixError> {
|
|
295
295
|
let event_route = route.traversal_only();
|
|
@@ -356,9 +356,10 @@ async fn load_directory_history_rows(
|
|
|
356
356
|
});
|
|
357
357
|
}
|
|
358
358
|
output.retain(|row| {
|
|
359
|
+
let entity_id = entity_id_json_array(&row.entity_id).ok();
|
|
359
360
|
route.matches_surface_row(
|
|
360
361
|
DIRECTORY_DESCRIPTOR_SCHEMA_KEY,
|
|
361
|
-
&row.entity_id,
|
|
362
|
+
entity_id.as_deref().unwrap_or(&row.entity_id),
|
|
362
363
|
None,
|
|
363
364
|
row.event.depth,
|
|
364
365
|
)
|
|
@@ -388,7 +389,7 @@ fn parse_directory_history_records(
|
|
|
388
389
|
.map(|entry| {
|
|
389
390
|
let Some(snapshot_content) = entry.change.snapshot_content.as_deref() else {
|
|
390
391
|
return Ok(DirectoryHistoryRecord {
|
|
391
|
-
id: entry.change.entity_id.
|
|
392
|
+
id: entry.change.entity_id.as_single_string_owned()?,
|
|
392
393
|
parent_id: None,
|
|
393
394
|
name: None,
|
|
394
395
|
hidden: None,
|
|
@@ -528,15 +529,15 @@ fn directory_history_column_array(
|
|
|
528
529
|
"hidden" => Arc::new(BooleanArray::from(
|
|
529
530
|
rows.iter().map(|row| row.hidden).collect::<Vec<_>>(),
|
|
530
531
|
)) as ArrayRef,
|
|
531
|
-
HISTORY_COL_ENTITY_ID =>
|
|
532
|
+
HISTORY_COL_ENTITY_ID => Arc::new(StringArray::from(
|
|
533
|
+
rows.iter()
|
|
534
|
+
.map(|row| entity_id_json_array(&row.entity_id).map(Some))
|
|
535
|
+
.collect::<std::result::Result<Vec<_>, _>>()?,
|
|
536
|
+
)) as ArrayRef,
|
|
532
537
|
HISTORY_COL_SCHEMA_KEY => {
|
|
533
538
|
string_array(rows.iter().map(|_| Some(DIRECTORY_DESCRIPTOR_SCHEMA_KEY)))
|
|
534
539
|
}
|
|
535
540
|
HISTORY_COL_FILE_ID => string_array(rows.iter().map(|_| None)),
|
|
536
|
-
HISTORY_COL_SCHEMA_VERSION => string_array(
|
|
537
|
-
rows.iter()
|
|
538
|
-
.map(|row| Some(row.descriptor_change.schema_version.as_str())),
|
|
539
|
-
),
|
|
540
541
|
HISTORY_COL_CHANGE_ID => {
|
|
541
542
|
string_array(rows.iter().map(|row| Some(row.event.change.id.as_str())))
|
|
542
543
|
}
|
|
@@ -589,11 +590,10 @@ fn lix_directory_history_schema() -> SchemaRef {
|
|
|
589
590
|
Field::new("parent_id", DataType::Utf8, true),
|
|
590
591
|
Field::new("name", DataType::Utf8, true),
|
|
591
592
|
Field::new("hidden", DataType::Boolean, true),
|
|
592
|
-
|
|
593
|
+
json_field(HISTORY_COL_ENTITY_ID, false),
|
|
593
594
|
Field::new(HISTORY_COL_SCHEMA_KEY, DataType::Utf8, false),
|
|
594
595
|
Field::new(HISTORY_COL_FILE_ID, DataType::Utf8, true),
|
|
595
596
|
json_field(HISTORY_COL_SNAPSHOT_CONTENT, true),
|
|
596
|
-
Field::new(HISTORY_COL_SCHEMA_VERSION, DataType::Utf8, false),
|
|
597
597
|
Field::new(HISTORY_COL_CHANGE_ID, DataType::Utf8, false),
|
|
598
598
|
json_field(HISTORY_COL_METADATA, true),
|
|
599
599
|
Field::new(HISTORY_COL_OBSERVED_COMMIT_ID, DataType::Utf8, false),
|
|
@@ -618,6 +618,14 @@ fn datafusion_error_to_lix_error(error: DataFusionError) -> LixError {
|
|
|
618
618
|
super::error::datafusion_error_to_lix_error(error)
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
+
fn entity_id_json_array(entity_id: &str) -> Result<String, LixError> {
|
|
622
|
+
serde_json::to_string(&[entity_id]).map_err(|error| {
|
|
623
|
+
LixError::unknown(format!(
|
|
624
|
+
"failed to encode history entity id as JSON: {error}"
|
|
625
|
+
))
|
|
626
|
+
})
|
|
627
|
+
}
|
|
628
|
+
|
|
621
629
|
fn lix_error_to_datafusion_error(error: LixError) -> DataFusionError {
|
|
622
630
|
super::error::lix_error_to_datafusion_error(error)
|
|
623
631
|
}
|