@lix-js/sdk 0.6.0-preview.2 → 0.6.0-preview.3
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 +4 -5
- package/dist/engine-wasm/wasm/lix_engine.js +1 -1
- package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
- package/dist/generated/builtin-schemas.d.ts +87 -162
- package/dist/generated/builtin-schemas.js +139 -236
- package/dist/open-lix.d.ts +1 -1
- 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 +10 -9
- 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 +40 -42
- package/dist-engine-src/src/session/create_version.rs +22 -14
- package/dist-engine-src/src/session/execute.rs +45 -14
- 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 +4 -2
- package/dist-engine-src/src/session/optimization9_sql2_bench.rs +100 -0
- package/dist-engine-src/src/session/switch_version.rs +16 -28
- package/dist-engine-src/src/sql2/change_provider.rs +14 -20
- package/dist-engine-src/src/sql2/classify.rs +61 -26
- 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 +21 -1
- package/dist-engine-src/src/sql2/execute.rs +325 -264
- 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 +6 -3
- 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 +166 -0
- package/dist-engine-src/src/sql2/public_bind/mod.rs +25 -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 +211 -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
|
@@ -6,20 +6,22 @@ use std::sync::Arc;
|
|
|
6
6
|
use serde_json::Value as JsonValue;
|
|
7
7
|
|
|
8
8
|
use crate::binary_cas::{BinaryCasContext, BlobDataReader};
|
|
9
|
-
use crate::
|
|
9
|
+
use crate::catalog::CatalogContext;
|
|
10
10
|
use crate::commit_graph::{CommitGraphContext, CommitGraphReader};
|
|
11
|
+
use crate::commit_store::CommitStoreContext;
|
|
11
12
|
use crate::entity_identity::EntityIdentity;
|
|
12
13
|
use crate::functions::FunctionProviderHandle;
|
|
13
14
|
use crate::json_store::JsonStoreContext;
|
|
14
15
|
use crate::live_state::{LiveStateContext, LiveStateReader, LiveStateRowRequest};
|
|
15
|
-
use crate::
|
|
16
|
-
use crate::sql2::{ChangelogQuerySource, SqlChangelogQuerySource, SqlExecutionContext};
|
|
16
|
+
use crate::sql2::{CommitStoreQuerySource, SqlCommitStoreQuerySource, SqlExecutionContext};
|
|
17
17
|
use crate::storage::{
|
|
18
18
|
ScopedStorageReader, StorageContext, StorageReadScope, StorageReadTransaction, StorageReader,
|
|
19
19
|
};
|
|
20
20
|
use crate::tracked_state::TrackedStateContext;
|
|
21
21
|
use crate::transaction::{open_transaction, Transaction};
|
|
22
|
-
use crate::version::{
|
|
22
|
+
use crate::version::{
|
|
23
|
+
VersionContext, VersionLifecycle, VersionOperation, VersionRefReader, VersionReferenceRole,
|
|
24
|
+
};
|
|
23
25
|
use crate::GLOBAL_VERSION_ID;
|
|
24
26
|
use crate::{LixError, NullableKeyFilter};
|
|
25
27
|
|
|
@@ -31,13 +33,13 @@ pub(crate) enum SessionMode {
|
|
|
31
33
|
Workspace,
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
/// Session-context state for
|
|
36
|
+
/// Session-context state for engine execution.
|
|
35
37
|
///
|
|
36
38
|
/// A session context pins the active version selector and shared execution
|
|
37
39
|
/// services. Each call to `execute(...)` projects this state into a read-only
|
|
38
40
|
/// SQL context or a transaction-owned write context.
|
|
39
41
|
///
|
|
40
|
-
/// Write transaction invariant: any
|
|
42
|
+
/// Write transaction invariant: any engine operation that may write must enter
|
|
41
43
|
/// through `SessionContext::with_write_transaction`. Reads that influence writes
|
|
42
44
|
/// are only available from that transaction capability, not from session-level
|
|
43
45
|
/// helpers.
|
|
@@ -48,9 +50,9 @@ pub struct SessionContext {
|
|
|
48
50
|
pub(super) live_state: Arc<LiveStateContext>,
|
|
49
51
|
pub(super) tracked_state: Arc<TrackedStateContext>,
|
|
50
52
|
pub(super) binary_cas: Arc<BinaryCasContext>,
|
|
51
|
-
pub(super)
|
|
53
|
+
pub(super) commit_store: Arc<CommitStoreContext>,
|
|
52
54
|
pub(super) version_ctx: Arc<VersionContext>,
|
|
53
|
-
pub(super)
|
|
55
|
+
pub(super) catalog_context: Arc<CatalogContext>,
|
|
54
56
|
closed: Arc<AtomicBool>,
|
|
55
57
|
}
|
|
56
58
|
|
|
@@ -60,9 +62,9 @@ impl SessionContext {
|
|
|
60
62
|
live_state: Arc<LiveStateContext>,
|
|
61
63
|
tracked_state: Arc<TrackedStateContext>,
|
|
62
64
|
binary_cas: Arc<BinaryCasContext>,
|
|
63
|
-
|
|
65
|
+
commit_store: Arc<CommitStoreContext>,
|
|
64
66
|
version_ctx: Arc<VersionContext>,
|
|
65
|
-
|
|
67
|
+
catalog_context: Arc<CatalogContext>,
|
|
66
68
|
) -> Result<Self, LixError> {
|
|
67
69
|
let session = Self::new(
|
|
68
70
|
SessionMode::Workspace,
|
|
@@ -70,9 +72,9 @@ impl SessionContext {
|
|
|
70
72
|
live_state,
|
|
71
73
|
tracked_state,
|
|
72
74
|
binary_cas,
|
|
73
|
-
|
|
75
|
+
commit_store,
|
|
74
76
|
version_ctx,
|
|
75
|
-
|
|
77
|
+
catalog_context,
|
|
76
78
|
);
|
|
77
79
|
session.active_version_id().await?;
|
|
78
80
|
Ok(session)
|
|
@@ -84,9 +86,9 @@ impl SessionContext {
|
|
|
84
86
|
live_state: Arc<LiveStateContext>,
|
|
85
87
|
tracked_state: Arc<TrackedStateContext>,
|
|
86
88
|
binary_cas: Arc<BinaryCasContext>,
|
|
87
|
-
|
|
89
|
+
commit_store: Arc<CommitStoreContext>,
|
|
88
90
|
version_ctx: Arc<VersionContext>,
|
|
89
|
-
|
|
91
|
+
catalog_context: Arc<CatalogContext>,
|
|
90
92
|
) -> Result<Self, LixError> {
|
|
91
93
|
Ok(Self::new(
|
|
92
94
|
SessionMode::Pinned {
|
|
@@ -96,9 +98,9 @@ impl SessionContext {
|
|
|
96
98
|
live_state,
|
|
97
99
|
tracked_state,
|
|
98
100
|
binary_cas,
|
|
99
|
-
|
|
101
|
+
commit_store,
|
|
100
102
|
version_ctx,
|
|
101
|
-
|
|
103
|
+
catalog_context,
|
|
102
104
|
))
|
|
103
105
|
}
|
|
104
106
|
|
|
@@ -108,9 +110,9 @@ impl SessionContext {
|
|
|
108
110
|
live_state: Arc<LiveStateContext>,
|
|
109
111
|
tracked_state: Arc<TrackedStateContext>,
|
|
110
112
|
binary_cas: Arc<BinaryCasContext>,
|
|
111
|
-
|
|
113
|
+
commit_store: Arc<CommitStoreContext>,
|
|
112
114
|
version_ctx: Arc<VersionContext>,
|
|
113
|
-
|
|
115
|
+
catalog_context: Arc<CatalogContext>,
|
|
114
116
|
) -> Self {
|
|
115
117
|
Self::new_with_closed(
|
|
116
118
|
mode,
|
|
@@ -118,9 +120,9 @@ impl SessionContext {
|
|
|
118
120
|
live_state,
|
|
119
121
|
tracked_state,
|
|
120
122
|
binary_cas,
|
|
121
|
-
|
|
123
|
+
commit_store,
|
|
122
124
|
version_ctx,
|
|
123
|
-
|
|
125
|
+
catalog_context,
|
|
124
126
|
Arc::new(AtomicBool::new(false)),
|
|
125
127
|
)
|
|
126
128
|
}
|
|
@@ -131,9 +133,9 @@ impl SessionContext {
|
|
|
131
133
|
live_state: Arc<LiveStateContext>,
|
|
132
134
|
tracked_state: Arc<TrackedStateContext>,
|
|
133
135
|
binary_cas: Arc<BinaryCasContext>,
|
|
134
|
-
|
|
136
|
+
commit_store: Arc<CommitStoreContext>,
|
|
135
137
|
version_ctx: Arc<VersionContext>,
|
|
136
|
-
|
|
138
|
+
catalog_context: Arc<CatalogContext>,
|
|
137
139
|
closed: Arc<AtomicBool>,
|
|
138
140
|
) -> Self {
|
|
139
141
|
Self {
|
|
@@ -142,9 +144,9 @@ impl SessionContext {
|
|
|
142
144
|
live_state,
|
|
143
145
|
tracked_state,
|
|
144
146
|
binary_cas,
|
|
145
|
-
|
|
147
|
+
commit_store,
|
|
146
148
|
version_ctx,
|
|
147
|
-
|
|
149
|
+
catalog_context,
|
|
148
150
|
closed,
|
|
149
151
|
}
|
|
150
152
|
}
|
|
@@ -256,18 +258,14 @@ impl SessionContext {
|
|
|
256
258
|
})?
|
|
257
259
|
.to_string();
|
|
258
260
|
|
|
259
|
-
let
|
|
260
|
-
|
|
261
|
-
.
|
|
262
|
-
|
|
261
|
+
let version_ref = self.version_ctx.ref_reader(&mut *reader);
|
|
262
|
+
VersionLifecycle::new(&version_ref)
|
|
263
|
+
.require_existing_ref(
|
|
264
|
+
&version_id,
|
|
265
|
+
VersionOperation::LoadWorkspaceSelector,
|
|
266
|
+
VersionReferenceRole::WorkspaceSelector,
|
|
267
|
+
)
|
|
263
268
|
.await?;
|
|
264
|
-
if head.is_none() {
|
|
265
|
-
return Err(LixError::version_not_found(
|
|
266
|
-
version_id,
|
|
267
|
-
"load_workspace_version_id",
|
|
268
|
-
"workspace_selector",
|
|
269
|
-
));
|
|
270
|
-
}
|
|
271
269
|
|
|
272
270
|
Ok(version_id)
|
|
273
271
|
}
|
|
@@ -285,9 +283,9 @@ impl SessionContext {
|
|
|
285
283
|
Arc::clone(&self.live_state),
|
|
286
284
|
Arc::clone(&self.tracked_state),
|
|
287
285
|
Arc::clone(&self.binary_cas),
|
|
288
|
-
Arc::clone(&self.
|
|
286
|
+
Arc::clone(&self.commit_store),
|
|
289
287
|
Arc::clone(&self.version_ctx),
|
|
290
|
-
Arc::clone(&self.
|
|
288
|
+
Arc::clone(&self.catalog_context),
|
|
291
289
|
)
|
|
292
290
|
.await?;
|
|
293
291
|
let mut transaction = opened.transaction;
|
|
@@ -321,7 +319,7 @@ pub(super) struct SessionSqlExecutionContext<'a> {
|
|
|
321
319
|
ScopedStorageReader<Box<dyn StorageReadTransaction + Send + Sync + 'static>>,
|
|
322
320
|
pub(super) live_state: Arc<LiveStateContext>,
|
|
323
321
|
pub(super) binary_cas: Arc<BinaryCasContext>,
|
|
324
|
-
pub(super)
|
|
322
|
+
pub(super) commit_store: Arc<CommitStoreContext>,
|
|
325
323
|
pub(super) version_ctx: Arc<VersionContext>,
|
|
326
324
|
pub(super) visible_schemas: Vec<JsonValue>,
|
|
327
325
|
pub(super) functions: FunctionProviderHandle,
|
|
@@ -336,16 +334,16 @@ impl SqlExecutionContext for SessionSqlExecutionContext<'_> {
|
|
|
336
334
|
Arc::new(self.live_state.reader(self.read_store.clone())) as Arc<dyn LiveStateReader>
|
|
337
335
|
}
|
|
338
336
|
|
|
339
|
-
fn
|
|
337
|
+
fn commit_store_query_source(&self) -> SqlCommitStoreQuerySource {
|
|
340
338
|
let read_scope = StorageReadScope::new(self.read_store.clone());
|
|
341
|
-
|
|
342
|
-
|
|
339
|
+
CommitStoreQuerySource {
|
|
340
|
+
commit_store_reader: Arc::new(self.commit_store.reader(read_scope.store())),
|
|
343
341
|
json_reader: JsonStoreContext::new().reader(read_scope.store()),
|
|
344
342
|
}
|
|
345
343
|
}
|
|
346
344
|
|
|
347
345
|
fn commit_graph(&self) -> Box<dyn CommitGraphReader> {
|
|
348
|
-
Box::new(CommitGraphContext::new(
|
|
346
|
+
Box::new(CommitGraphContext::new().reader(self.read_store.clone()))
|
|
349
347
|
}
|
|
350
348
|
|
|
351
349
|
fn version_ref(&self) -> Arc<dyn VersionRefReader> {
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
use crate::transaction::types::{
|
|
2
|
-
use crate::version::{
|
|
1
|
+
use crate::transaction::types::{TransactionWrite, TransactionWriteMode};
|
|
2
|
+
use crate::version::{
|
|
3
|
+
version_descriptor_stage_row, version_ref_stage_row, VersionLifecycle, VersionOperation,
|
|
4
|
+
VersionReferenceRole,
|
|
5
|
+
};
|
|
3
6
|
use crate::LixError;
|
|
4
7
|
|
|
5
8
|
use super::context::SessionContext;
|
|
@@ -7,7 +10,7 @@ use super::context::SessionContext;
|
|
|
7
10
|
/// Options for creating a new version from the session's active version.
|
|
8
11
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
9
12
|
pub struct CreateVersionOptions {
|
|
10
|
-
/// Optional caller-provided version id. If omitted,
|
|
13
|
+
/// Optional caller-provided version id. If omitted, engine generates one.
|
|
11
14
|
pub id: Option<String>,
|
|
12
15
|
/// User-facing version name.
|
|
13
16
|
pub name: String,
|
|
@@ -41,25 +44,30 @@ impl SessionContext {
|
|
|
41
44
|
.id
|
|
42
45
|
.unwrap_or_else(|| transaction.functions().call_uuid_v7());
|
|
43
46
|
let source_head = if let Some(from_commit_id) = options.from_commit_id {
|
|
47
|
+
let mut commit_graph = transaction.commit_graph_reader();
|
|
48
|
+
VersionLifecycle::require_existing_commit(
|
|
49
|
+
&mut commit_graph,
|
|
50
|
+
&from_commit_id,
|
|
51
|
+
VersionOperation::CreateVersion,
|
|
52
|
+
VersionReferenceRole::CommitSource,
|
|
53
|
+
)
|
|
54
|
+
.await?;
|
|
44
55
|
from_commit_id
|
|
45
56
|
} else {
|
|
46
57
|
let active_version_id = transaction.active_version_id().to_string();
|
|
47
58
|
let reader = transaction.version_ref_reader();
|
|
48
|
-
reader
|
|
49
|
-
.
|
|
59
|
+
VersionLifecycle::new(&reader)
|
|
60
|
+
.require_existing_commit_id(
|
|
61
|
+
&active_version_id,
|
|
62
|
+
VersionOperation::CreateVersion,
|
|
63
|
+
VersionReferenceRole::Source,
|
|
64
|
+
)
|
|
50
65
|
.await?
|
|
51
|
-
.ok_or_else(|| {
|
|
52
|
-
LixError::version_not_found(
|
|
53
|
-
active_version_id.clone(),
|
|
54
|
-
"create_version",
|
|
55
|
-
"source",
|
|
56
|
-
)
|
|
57
|
-
})?
|
|
58
66
|
};
|
|
59
67
|
|
|
60
68
|
transaction
|
|
61
|
-
.stage_write(
|
|
62
|
-
mode:
|
|
69
|
+
.stage_write(TransactionWrite::Rows {
|
|
70
|
+
mode: TransactionWriteMode::Insert,
|
|
63
71
|
rows: vec![
|
|
64
72
|
version_descriptor_stage_row(&version_id, &options.name, false),
|
|
65
73
|
version_ref_stage_row(&version_id, &source_head),
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
use std::sync::Arc;
|
|
2
2
|
|
|
3
3
|
use crate::functions::FunctionContext;
|
|
4
|
-
use crate::json_store::JsonStoreContext;
|
|
5
4
|
use crate::sql2;
|
|
6
5
|
use crate::storage::{StorageReadScope, StorageWriteSet};
|
|
7
6
|
use crate::{LixError, LixNotice, SqlQueryResult, Value};
|
|
8
7
|
|
|
9
8
|
use super::context::{SessionContext, SessionSqlExecutionContext};
|
|
10
9
|
|
|
11
|
-
/// Result of executing one SQL statement through
|
|
10
|
+
/// Result of executing one SQL statement through engine.
|
|
12
11
|
///
|
|
13
12
|
/// Column names live once at the result-set level. Individual rows only own
|
|
14
13
|
/// values, which keeps the public API row-oriented without copying schema
|
|
@@ -251,7 +250,7 @@ fn value_type_error(expected: &str, actual: &Value) -> LixError {
|
|
|
251
250
|
)
|
|
252
251
|
}
|
|
253
252
|
|
|
254
|
-
///
|
|
253
|
+
/// Zero-copy row view with access to the result-set column names.
|
|
255
254
|
///
|
|
256
255
|
/// This is the ergonomic path for callers that want `row.get("column")`
|
|
257
256
|
/// without storing column metadata on every owned row.
|
|
@@ -300,6 +299,7 @@ impl SessionContext {
|
|
|
300
299
|
let kind = sql2::classify_statement(sql)?;
|
|
301
300
|
if kind == sql2::SqlStatementKind::Write {
|
|
302
301
|
let sql = sql.to_string();
|
|
302
|
+
let sql_for_error = sql.clone();
|
|
303
303
|
let params = params.to_vec();
|
|
304
304
|
return self
|
|
305
305
|
.with_write_transaction(|transaction| {
|
|
@@ -313,7 +313,8 @@ impl SessionContext {
|
|
|
313
313
|
Ok(ExecuteResult::from_rows_affected(affected_rows))
|
|
314
314
|
})
|
|
315
315
|
})
|
|
316
|
-
.await
|
|
316
|
+
.await
|
|
317
|
+
.map_err(|error| normalize_sql_surface_error(error, &sql_for_error));
|
|
317
318
|
}
|
|
318
319
|
|
|
319
320
|
let read_scope = StorageReadScope::new(self.storage.begin_read_transaction().await?);
|
|
@@ -325,15 +326,15 @@ impl SessionContext {
|
|
|
325
326
|
let functions = runtime_functions.provider();
|
|
326
327
|
let active_version_id = self.active_version_id_from_reader(&mut read_store).await?;
|
|
327
328
|
let visible_schemas = self
|
|
328
|
-
.
|
|
329
|
-
.
|
|
329
|
+
.catalog_context
|
|
330
|
+
.schema_jsons_for_sql_read_planning(live_state.as_ref(), &active_version_id)
|
|
330
331
|
.await?;
|
|
331
332
|
let ctx = SessionSqlExecutionContext {
|
|
332
333
|
active_version_id: &active_version_id,
|
|
333
334
|
read_store,
|
|
334
335
|
live_state: Arc::clone(&self.live_state),
|
|
335
336
|
binary_cas: Arc::clone(&self.binary_cas),
|
|
336
|
-
|
|
337
|
+
commit_store: Arc::clone(&self.commit_store),
|
|
337
338
|
version_ctx: Arc::clone(&self.version_ctx),
|
|
338
339
|
visible_schemas,
|
|
339
340
|
functions: functions.clone(),
|
|
@@ -352,7 +353,7 @@ impl SessionContext {
|
|
|
352
353
|
}
|
|
353
354
|
Err(error) => {
|
|
354
355
|
let _ = read_scope.rollback().await;
|
|
355
|
-
return Err(error);
|
|
356
|
+
return Err(normalize_sql_surface_error(error, sql));
|
|
356
357
|
}
|
|
357
358
|
};
|
|
358
359
|
self.persist_runtime_functions_if_needed(&runtime_functions)
|
|
@@ -372,13 +373,8 @@ impl SessionContext {
|
|
|
372
373
|
) -> Result<(), LixError> {
|
|
373
374
|
let mut transaction = self.storage.begin_write_transaction().await?;
|
|
374
375
|
let mut writes = StorageWriteSet::new();
|
|
375
|
-
let mut json_writer = JsonStoreContext::new().writer();
|
|
376
376
|
runtime_functions
|
|
377
|
-
.stage_persist_if_needed(
|
|
378
|
-
&mut self.live_state.writer(transaction.as_mut()),
|
|
379
|
-
&mut writes,
|
|
380
|
-
&mut json_writer,
|
|
381
|
-
)
|
|
377
|
+
.stage_persist_if_needed(&mut writes)
|
|
382
378
|
.await?;
|
|
383
379
|
if !writes.is_empty() {
|
|
384
380
|
writes.apply(&mut transaction.as_mut()).await?;
|
|
@@ -387,6 +383,41 @@ impl SessionContext {
|
|
|
387
383
|
}
|
|
388
384
|
}
|
|
389
385
|
|
|
386
|
+
fn normalize_sql_surface_error(error: LixError, sql: &str) -> LixError {
|
|
387
|
+
if error.code.starts_with("LIX_ERROR_PATH_") && sql_uses_public_filesystem_path_surface(sql) {
|
|
388
|
+
return LixError {
|
|
389
|
+
code: LixError::CODE_INVALID_PARAM.to_string(),
|
|
390
|
+
..error
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
if error.code == LixError::CODE_INVALID_JSON_PATH
|
|
394
|
+
&& error
|
|
395
|
+
.message
|
|
396
|
+
.to_ascii_lowercase()
|
|
397
|
+
.contains("uses variadic path segments")
|
|
398
|
+
{
|
|
399
|
+
return LixError {
|
|
400
|
+
code: LixError::CODE_INVALID_PARAM.to_string(),
|
|
401
|
+
..error
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
if error.code == LixError::CODE_FOREIGN_KEY {
|
|
405
|
+
let lower = error.message.to_ascii_lowercase();
|
|
406
|
+
if lower.contains("schema 'lix_version_ref'") && lower.contains("target 'lix_commit.") {
|
|
407
|
+
return LixError {
|
|
408
|
+
code: LixError::CODE_VERSION_NOT_FOUND.to_string(),
|
|
409
|
+
..error
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
error
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
fn sql_uses_public_filesystem_path_surface(sql: &str) -> bool {
|
|
417
|
+
let lower = sql.to_ascii_lowercase();
|
|
418
|
+
(lower.contains("lix_file") || lower.contains("lix_directory")) && lower.contains("path")
|
|
419
|
+
}
|
|
420
|
+
|
|
390
421
|
fn affected_rows_from_query_result(result: SqlQueryResult) -> Result<u64, LixError> {
|
|
391
422
|
let Some(first_row) = result.rows.first() else {
|
|
392
423
|
return Ok(0);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
use crate::tracked_state::TrackedStateMergePlan;
|
|
2
|
-
use crate::transaction::types::
|
|
2
|
+
use crate::transaction::types::TransactionAdoptedChange;
|
|
3
3
|
|
|
4
4
|
pub(crate) fn adopted_changes_from_merge_plan(
|
|
5
5
|
plan: &TrackedStateMergePlan,
|
|
6
6
|
target_version_id: &str,
|
|
7
|
-
) -> Vec<
|
|
7
|
+
) -> Vec<TransactionAdoptedChange> {
|
|
8
8
|
plan.patches
|
|
9
9
|
.iter()
|
|
10
10
|
.map(|patch| stage_adopted_change_from_patch(patch, target_version_id))
|
|
@@ -14,8 +14,8 @@ pub(crate) fn adopted_changes_from_merge_plan(
|
|
|
14
14
|
fn stage_adopted_change_from_patch(
|
|
15
15
|
patch: &crate::tracked_state::TrackedStateMergePatch,
|
|
16
16
|
target_version_id: &str,
|
|
17
|
-
) ->
|
|
18
|
-
|
|
17
|
+
) -> TransactionAdoptedChange {
|
|
18
|
+
TransactionAdoptedChange {
|
|
19
19
|
version_id: target_version_id.to_string(),
|
|
20
20
|
change_id: patch.change_id().to_string(),
|
|
21
21
|
projected_row: patch.projected_row().clone(),
|
|
@@ -2,12 +2,13 @@ use crate::tracked_state::{
|
|
|
2
2
|
TrackedStateDiffEntry, TrackedStateDiffKind, TrackedStateMergeConflict, TrackedStateMergePlan,
|
|
3
3
|
};
|
|
4
4
|
use crate::LixError;
|
|
5
|
+
use serde_json::Value as JsonValue;
|
|
5
6
|
|
|
6
7
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
7
8
|
pub(crate) struct MergeConflict {
|
|
8
9
|
pub(crate) kind: MergeConflictKind,
|
|
9
10
|
pub(crate) schema_key: String,
|
|
10
|
-
pub(crate) entity_id:
|
|
11
|
+
pub(crate) entity_id: JsonValue,
|
|
11
12
|
pub(crate) file_id: Option<String>,
|
|
12
13
|
pub(crate) target: MergeConflictSide,
|
|
13
14
|
pub(crate) source: MergeConflictSide,
|
|
@@ -42,7 +43,7 @@ fn conflict_from_tracked(conflict: &TrackedStateMergeConflict) -> Result<MergeCo
|
|
|
42
43
|
Ok(MergeConflict {
|
|
43
44
|
kind: MergeConflictKind::SameEntityChanged,
|
|
44
45
|
schema_key: conflict.identity.schema_key.clone(),
|
|
45
|
-
entity_id: conflict.identity.entity_id.
|
|
46
|
+
entity_id: conflict.identity.entity_id.as_json_array_value()?,
|
|
46
47
|
file_id: conflict.identity.file_id.clone(),
|
|
47
48
|
target: conflict_side_from_diff_entry(&conflict.target),
|
|
48
49
|
source: conflict_side_from_diff_entry(&conflict.source),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
use serde_json::json;
|
|
1
|
+
use serde_json::{json, Value as JsonValue};
|
|
2
2
|
|
|
3
|
-
use crate::transaction::types::
|
|
4
|
-
use crate::version::
|
|
3
|
+
use crate::transaction::types::TransactionWrite;
|
|
4
|
+
use crate::version::{VersionLifecycle, VersionOperation, VersionReferenceRole};
|
|
5
5
|
use crate::LixError;
|
|
6
6
|
|
|
7
7
|
use super::analysis::{analyze, MergeCommits, MergeOutcome};
|
|
@@ -67,7 +67,7 @@ pub struct MergeVersionPreview {
|
|
|
67
67
|
pub struct MergeConflict {
|
|
68
68
|
pub kind: MergeConflictKind,
|
|
69
69
|
pub schema_key: String,
|
|
70
|
-
pub entity_id:
|
|
70
|
+
pub entity_id: JsonValue,
|
|
71
71
|
pub file_id: Option<String>,
|
|
72
72
|
pub target: MergeConflictSide,
|
|
73
73
|
pub source: MergeConflictSide,
|
|
@@ -117,26 +117,21 @@ impl SessionContext {
|
|
|
117
117
|
|
|
118
118
|
let (target_head, source_head) = {
|
|
119
119
|
let reader = transaction.version_ref_reader();
|
|
120
|
-
let
|
|
121
|
-
|
|
122
|
-
.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
source_version_id.clone(),
|
|
136
|
-
"merge_version_preview",
|
|
137
|
-
"source",
|
|
138
|
-
)
|
|
139
|
-
})?;
|
|
120
|
+
let lifecycle = VersionLifecycle::new(&reader);
|
|
121
|
+
let target_head = lifecycle
|
|
122
|
+
.require_existing_commit_id(
|
|
123
|
+
&active_version_id,
|
|
124
|
+
VersionOperation::MergeVersionPreview,
|
|
125
|
+
VersionReferenceRole::Target,
|
|
126
|
+
)
|
|
127
|
+
.await?;
|
|
128
|
+
let source_head = lifecycle
|
|
129
|
+
.require_existing_commit_id(
|
|
130
|
+
&source_version_id,
|
|
131
|
+
VersionOperation::MergeVersionPreview,
|
|
132
|
+
VersionReferenceRole::Source,
|
|
133
|
+
)
|
|
134
|
+
.await?;
|
|
140
135
|
(target_head, source_head)
|
|
141
136
|
};
|
|
142
137
|
|
|
@@ -189,26 +184,21 @@ impl SessionContext {
|
|
|
189
184
|
|
|
190
185
|
let (target_head, source_head) = {
|
|
191
186
|
let reader = transaction.version_ref_reader();
|
|
192
|
-
let
|
|
193
|
-
|
|
194
|
-
.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
source_version_id.clone(),
|
|
208
|
-
"merge_version",
|
|
209
|
-
"source",
|
|
210
|
-
)
|
|
211
|
-
})?;
|
|
187
|
+
let lifecycle = VersionLifecycle::new(&reader);
|
|
188
|
+
let target_head = lifecycle
|
|
189
|
+
.require_existing_commit_id(
|
|
190
|
+
&active_version_id,
|
|
191
|
+
VersionOperation::MergeVersion,
|
|
192
|
+
VersionReferenceRole::Target,
|
|
193
|
+
)
|
|
194
|
+
.await?;
|
|
195
|
+
let source_head = lifecycle
|
|
196
|
+
.require_existing_commit_id(
|
|
197
|
+
&source_version_id,
|
|
198
|
+
VersionOperation::MergeVersion,
|
|
199
|
+
VersionReferenceRole::Source,
|
|
200
|
+
)
|
|
201
|
+
.await?;
|
|
212
202
|
(target_head, source_head)
|
|
213
203
|
};
|
|
214
204
|
|
|
@@ -300,7 +290,7 @@ impl SessionContext {
|
|
|
300
290
|
}
|
|
301
291
|
|
|
302
292
|
transaction
|
|
303
|
-
.stage_write(
|
|
293
|
+
.stage_write(TransactionWrite::AdoptedChanges {
|
|
304
294
|
changes: adopted_changes,
|
|
305
295
|
})
|
|
306
296
|
.await?;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
//!
|
|
1
|
+
//! Engine session boundary.
|
|
2
2
|
//!
|
|
3
3
|
//! Transaction invariant:
|
|
4
|
-
//! any
|
|
4
|
+
//! any engine operation that may write must enter through
|
|
5
5
|
//! `SessionContext::with_write_transaction`. Reads that influence writes are
|
|
6
6
|
//! only available from the transaction capability. Session APIs must not
|
|
7
7
|
//! open `Transaction` directly or use session-level read helpers inside write
|
|
@@ -11,6 +11,8 @@ mod context;
|
|
|
11
11
|
mod create_version;
|
|
12
12
|
mod execute;
|
|
13
13
|
mod merge;
|
|
14
|
+
#[cfg(feature = "storage-benches")]
|
|
15
|
+
pub mod optimization9_sql2_bench;
|
|
14
16
|
mod switch_version;
|
|
15
17
|
|
|
16
18
|
pub use context::SessionContext;
|