@sixb/sqlite 0.1.7 → 0.1.9
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/dist/action-run-storage.d.ts.map +1 -1
- package/dist/agents/rows.d.ts +0 -1
- package/dist/agents/rows.d.ts.map +1 -1
- package/dist/agents/runs.d.ts.map +1 -1
- package/dist/ai-cost-storage.d.ts.map +1 -1
- package/dist/ai-usage-storage.d.ts.map +1 -1
- package/dist/execution-storage.d.ts +3 -2
- package/dist/execution-storage.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1567 -430
- package/dist/index.js.map +25 -19
- package/dist/migrations.d.ts.map +1 -1
- package/dist/objects/index.d.ts +3 -0
- package/dist/objects/index.d.ts.map +1 -0
- package/dist/{object-query-compiler.d.ts → objects/query-compiler.d.ts} +16 -1
- package/dist/objects/query-compiler.d.ts.map +1 -0
- package/dist/objects/read-scope.d.ts +17 -0
- package/dist/objects/read-scope.d.ts.map +1 -0
- package/dist/objects/reader.d.ts +51 -0
- package/dist/objects/reader.d.ts.map +1 -0
- package/dist/objects/rows.d.ts +33 -0
- package/dist/objects/rows.d.ts.map +1 -0
- package/dist/objects/selected-reader.d.ts +9 -0
- package/dist/objects/selected-reader.d.ts.map +1 -0
- package/dist/{object-storage.d.ts → objects/storage.d.ts} +12 -9
- package/dist/objects/storage.d.ts.map +1 -0
- package/dist/pipeline-run-storage.d.ts.map +1 -1
- package/dist/share-grant-storage.d.ts +20 -0
- package/dist/share-grant-storage.d.ts.map +1 -0
- package/dist/share-session-storage.d.ts +19 -0
- package/dist/share-session-storage.d.ts.map +1 -0
- package/dist/storage-errors.d.ts +1 -0
- package/dist/storage-errors.d.ts.map +1 -1
- package/dist/sync-run-storage.d.ts.map +1 -1
- package/dist/transactions.d.ts +8 -0
- package/dist/transactions.d.ts.map +1 -1
- package/dist/workflow-run-storage.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/action-run-storage.ts +6 -7
- package/src/agents/rows.ts +0 -2
- package/src/agents/runs.ts +3 -7
- package/src/ai-cost-groups.ts +3 -0
- package/src/ai-cost-storage.ts +11 -2
- package/src/ai-usage-storage.ts +1 -2
- package/src/execution-storage.ts +28 -7
- package/src/index.ts +22 -5
- package/src/migrations/035-share-grants.sql +66 -0
- package/src/migrations/036-share-sessions.sql +226 -0
- package/src/migrations/037-execution-requester-groups.sql +24 -0
- package/src/migrations.ts +9 -0
- package/src/objects/index.ts +2 -0
- package/src/{object-query-compiler.ts → objects/query-compiler.ts} +104 -54
- package/src/objects/read-scope.ts +316 -0
- package/src/objects/reader.ts +526 -0
- package/src/objects/rows.ts +123 -0
- package/src/objects/selected-reader.ts +119 -0
- package/src/objects/storage.ts +296 -0
- package/src/pipeline-run-storage.ts +2 -5
- package/src/share-grant-storage.ts +252 -0
- package/src/share-session-storage.ts +189 -0
- package/src/storage-errors.ts +4 -0
- package/src/sync-run-storage.ts +2 -5
- package/src/transactions.ts +32 -0
- package/src/workflow-run-storage.ts +1 -6
- package/dist/object-query-compiler.d.ts.map +0 -1
- package/dist/object-storage.d.ts.map +0 -1
- package/src/object-storage.ts +0 -709
package/dist/index.js
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
// src/index.ts
|
|
3
3
|
import { AsyncLocalStorage } from "async_hooks";
|
|
4
4
|
import { ProviderMaterializationTransactionLifecycle } from "@sixb/core/internal/ontology-storage-provider";
|
|
5
|
+
import {
|
|
6
|
+
createTransactionStorageProxy,
|
|
7
|
+
throwNestedStorageTransaction
|
|
8
|
+
} from "@sixb/core/internal/storage";
|
|
5
9
|
import {
|
|
6
10
|
createAgentOperationScope,
|
|
7
11
|
createAuthOperationScope,
|
|
12
|
+
createObjectOperationScope,
|
|
8
13
|
createOntologyOperationScope,
|
|
9
14
|
createOperationScopedFacade,
|
|
10
15
|
createStorageOperationScope,
|
|
11
16
|
createWorkflowRunOperationScope
|
|
12
17
|
} from "@sixb/core/internal/storage-operation-scope";
|
|
13
18
|
import {
|
|
14
|
-
|
|
15
|
-
StorageTransactionError,
|
|
16
|
-
throwNestedStorageTransaction
|
|
19
|
+
StorageTransactionError
|
|
17
20
|
} from "@sixb/core/storage";
|
|
18
21
|
|
|
19
22
|
// src/action-run-storage.ts
|
|
@@ -23,12 +26,11 @@ import {
|
|
|
23
26
|
} from "@sixb/core/internal/action-run-storage";
|
|
24
27
|
import { assertActionRunExecution } from "@sixb/core/internal/action-run-storage-provider";
|
|
25
28
|
import {
|
|
26
|
-
ActionRunError,
|
|
27
29
|
actionRunPhaseRecordsEqual,
|
|
28
30
|
canRequeueActionRunAfterEnqueueFailure,
|
|
29
|
-
finishActionRunPhase
|
|
30
|
-
|
|
31
|
-
} from "@sixb/core/storage";
|
|
31
|
+
finishActionRunPhase
|
|
32
|
+
} from "@sixb/core/internal/storage";
|
|
33
|
+
import { ActionRunError, isTerminalActionRun } from "@sixb/core/storage";
|
|
32
34
|
|
|
33
35
|
// src/migrations.ts
|
|
34
36
|
import { Database } from "bun:sqlite";
|
|
@@ -3632,6 +3634,331 @@ CREATE INDEX idx_auth_device_authorizations_pending
|
|
|
3632
3634
|
ON auth_device_authorizations(project_id, status, expires_at);
|
|
3633
3635
|
`;
|
|
3634
3636
|
|
|
3637
|
+
// src/migrations/035-share-grants.sql
|
|
3638
|
+
var _035_share_grants_default = `CREATE TABLE share_grants (
|
|
3639
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3640
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
3641
|
+
definition_id TEXT NOT NULL CHECK (length(trim(definition_id)) > 0),
|
|
3642
|
+
target_object_type_id TEXT NOT NULL CHECK (length(trim(target_object_type_id)) > 0),
|
|
3643
|
+
target_primary_id TEXT NOT NULL CHECK (length(trim(target_primary_id)) > 0),
|
|
3644
|
+
issued_by_type TEXT NOT NULL CHECK (issued_by_type IN ('user', 'serviceAccount')),
|
|
3645
|
+
issued_by_id TEXT NOT NULL CHECK (length(trim(issued_by_id)) > 0),
|
|
3646
|
+
authority_version INTEGER NOT NULL CHECK (authority_version > 0),
|
|
3647
|
+
authority_snapshot TEXT NOT NULL CHECK (
|
|
3648
|
+
json_valid(authority_snapshot)
|
|
3649
|
+
AND json_type(authority_snapshot) = 'object'
|
|
3650
|
+
AND json_type(authority_snapshot, '$.version') = 'integer'
|
|
3651
|
+
AND json_extract(authority_snapshot, '$.version') = authority_version
|
|
3652
|
+
AND json_type(authority_snapshot, '$.access') = 'object'
|
|
3653
|
+
),
|
|
3654
|
+
authority_digest TEXT NOT NULL CHECK (
|
|
3655
|
+
length(authority_digest) = 64
|
|
3656
|
+
AND authority_digest = lower(authority_digest)
|
|
3657
|
+
AND authority_digest NOT GLOB '*[^0-9a-f]*'
|
|
3658
|
+
),
|
|
3659
|
+
token_hash TEXT NOT NULL CHECK (
|
|
3660
|
+
length(token_hash) = 64
|
|
3661
|
+
AND token_hash = lower(token_hash)
|
|
3662
|
+
AND token_hash NOT GLOB '*[^0-9a-f]*'
|
|
3663
|
+
),
|
|
3664
|
+
destination_path TEXT NOT NULL CHECK (
|
|
3665
|
+
substr(destination_path, 1, 1) = '/'
|
|
3666
|
+
AND instr(destination_path, '?') = 0
|
|
3667
|
+
AND instr(destination_path, '#') = 0
|
|
3668
|
+
AND instr(destination_path, char(92)) = 0
|
|
3669
|
+
),
|
|
3670
|
+
created_at TEXT NOT NULL,
|
|
3671
|
+
expires_at TEXT NOT NULL,
|
|
3672
|
+
revoked_at TEXT,
|
|
3673
|
+
revoked_by_type TEXT CHECK (
|
|
3674
|
+
revoked_by_type IS NULL OR revoked_by_type IN ('user', 'serviceAccount', 'system')
|
|
3675
|
+
),
|
|
3676
|
+
revoked_by_id TEXT CHECK (revoked_by_id IS NULL OR length(trim(revoked_by_id)) > 0),
|
|
3677
|
+
PRIMARY KEY (project_id, id),
|
|
3678
|
+
UNIQUE (project_id, token_hash),
|
|
3679
|
+
CHECK (expires_at > created_at),
|
|
3680
|
+
CHECK (revoked_at IS NULL OR revoked_at >= created_at),
|
|
3681
|
+
CHECK (
|
|
3682
|
+
(revoked_at IS NULL AND revoked_by_type IS NULL AND revoked_by_id IS NULL)
|
|
3683
|
+
OR
|
|
3684
|
+
(revoked_at IS NOT NULL AND revoked_by_type IS NOT NULL AND revoked_by_id IS NOT NULL)
|
|
3685
|
+
)
|
|
3686
|
+
);
|
|
3687
|
+
|
|
3688
|
+
CREATE INDEX idx_share_grants_target
|
|
3689
|
+
ON share_grants (
|
|
3690
|
+
project_id,
|
|
3691
|
+
definition_id,
|
|
3692
|
+
target_object_type_id,
|
|
3693
|
+
target_primary_id,
|
|
3694
|
+
created_at DESC,
|
|
3695
|
+
id DESC
|
|
3696
|
+
);
|
|
3697
|
+
|
|
3698
|
+
CREATE INDEX idx_share_grants_project_created
|
|
3699
|
+
ON share_grants (project_id, created_at DESC, id DESC);
|
|
3700
|
+
|
|
3701
|
+
CREATE INDEX idx_share_grants_expiry
|
|
3702
|
+
ON share_grants (project_id, expires_at)
|
|
3703
|
+
WHERE revoked_at IS NULL;
|
|
3704
|
+
`;
|
|
3705
|
+
|
|
3706
|
+
// src/migrations/036-share-sessions.sql
|
|
3707
|
+
var _036_share_sessions_default = `-- Shared sessions and their execution provenance.
|
|
3708
|
+
CREATE TABLE share_sessions (
|
|
3709
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3710
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
3711
|
+
grant_id TEXT NOT NULL CHECK (length(trim(grant_id)) > 0),
|
|
3712
|
+
token_hash TEXT NOT NULL CHECK (
|
|
3713
|
+
length(token_hash) = 64
|
|
3714
|
+
AND token_hash = lower(token_hash)
|
|
3715
|
+
AND token_hash NOT GLOB '*[^0-9a-f]*'
|
|
3716
|
+
),
|
|
3717
|
+
created_at TEXT NOT NULL,
|
|
3718
|
+
expires_at TEXT NOT NULL,
|
|
3719
|
+
absolute_expires_at TEXT NOT NULL,
|
|
3720
|
+
revoked_at TEXT,
|
|
3721
|
+
PRIMARY KEY (project_id, id),
|
|
3722
|
+
UNIQUE (project_id, id, grant_id),
|
|
3723
|
+
UNIQUE (project_id, token_hash),
|
|
3724
|
+
FOREIGN KEY (project_id, grant_id)
|
|
3725
|
+
REFERENCES share_grants (project_id, id),
|
|
3726
|
+
CHECK (expires_at > created_at),
|
|
3727
|
+
CHECK (absolute_expires_at > created_at),
|
|
3728
|
+
CHECK (expires_at <= absolute_expires_at),
|
|
3729
|
+
CHECK (revoked_at IS NULL OR revoked_at >= created_at)
|
|
3730
|
+
);
|
|
3731
|
+
|
|
3732
|
+
CREATE INDEX idx_share_sessions_grant
|
|
3733
|
+
ON share_sessions (project_id, grant_id, created_at DESC, id DESC);
|
|
3734
|
+
|
|
3735
|
+
CREATE INDEX idx_share_sessions_expiry
|
|
3736
|
+
ON share_sessions (project_id, expires_at)
|
|
3737
|
+
WHERE revoked_at IS NULL;
|
|
3738
|
+
|
|
3739
|
+
-- Persist shared-session provenance on request executions without fabricating a principal.
|
|
3740
|
+
CREATE TABLE executions_v2 (
|
|
3741
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3742
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
3743
|
+
executor_kind TEXT NOT NULL CHECK (
|
|
3744
|
+
executor_kind IN (
|
|
3745
|
+
'request', 'action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow',
|
|
3746
|
+
'agent', 'kernel'
|
|
3747
|
+
)
|
|
3748
|
+
),
|
|
3749
|
+
executor_id TEXT NOT NULL CHECK (length(trim(executor_id)) > 0),
|
|
3750
|
+
source_kind TEXT NOT NULL CHECK (
|
|
3751
|
+
source_kind IN ('http', 'webhook', 'schedule', 'event', 'datasetVersion', 'execution')
|
|
3752
|
+
),
|
|
3753
|
+
source_id TEXT NOT NULL CHECK (length(trim(source_id)) > 0),
|
|
3754
|
+
requested_by_user_id TEXT,
|
|
3755
|
+
requested_by_service_account_id TEXT,
|
|
3756
|
+
correlation_id TEXT NOT NULL CHECK (length(trim(correlation_id)) > 0),
|
|
3757
|
+
parent_execution_id TEXT,
|
|
3758
|
+
authority_kind TEXT NOT NULL CHECK (
|
|
3759
|
+
authority_kind IN ('principal', 'trustedPrimitive', 'delegated', 'kernel', 'disabled')
|
|
3760
|
+
),
|
|
3761
|
+
authority_user_id TEXT,
|
|
3762
|
+
authority_service_account_id TEXT,
|
|
3763
|
+
authority_session_id TEXT,
|
|
3764
|
+
authority_access_token_id TEXT,
|
|
3765
|
+
authority_primitive_kind TEXT CHECK (
|
|
3766
|
+
authority_primitive_kind IS NULL
|
|
3767
|
+
OR authority_primitive_kind IN (
|
|
3768
|
+
'action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow'
|
|
3769
|
+
)
|
|
3770
|
+
),
|
|
3771
|
+
authority_primitive_id TEXT,
|
|
3772
|
+
authority_kernel_operation TEXT CHECK (
|
|
3773
|
+
authority_kernel_operation IS NULL OR authority_kernel_operation = 'ontology.recover'
|
|
3774
|
+
),
|
|
3775
|
+
authority_delegation_kind TEXT CHECK (
|
|
3776
|
+
authority_delegation_kind IS NULL OR authority_delegation_kind = 'share'
|
|
3777
|
+
),
|
|
3778
|
+
authority_delegation_id TEXT,
|
|
3779
|
+
authority_delegation_session_id TEXT,
|
|
3780
|
+
created_at TEXT NOT NULL,
|
|
3781
|
+
PRIMARY KEY (project_id, id),
|
|
3782
|
+
FOREIGN KEY (project_id, parent_execution_id) REFERENCES executions (project_id, id),
|
|
3783
|
+
FOREIGN KEY (project_id, requested_by_user_id) REFERENCES auth_users (project_id, id),
|
|
3784
|
+
FOREIGN KEY (project_id, requested_by_service_account_id)
|
|
3785
|
+
REFERENCES auth_service_accounts (project_id, id),
|
|
3786
|
+
FOREIGN KEY (project_id, authority_user_id) REFERENCES auth_users (project_id, id),
|
|
3787
|
+
FOREIGN KEY (project_id, authority_service_account_id)
|
|
3788
|
+
REFERENCES auth_service_accounts (project_id, id),
|
|
3789
|
+
FOREIGN KEY (project_id, authority_session_id) REFERENCES auth_sessions (project_id, id),
|
|
3790
|
+
FOREIGN KEY (project_id, authority_access_token_id)
|
|
3791
|
+
REFERENCES auth_access_tokens (project_id, id),
|
|
3792
|
+
FOREIGN KEY (
|
|
3793
|
+
project_id, authority_delegation_session_id, authority_delegation_id
|
|
3794
|
+
) REFERENCES share_sessions (project_id, id, grant_id),
|
|
3795
|
+
CHECK ((requested_by_user_id IS NOT NULL) + (requested_by_service_account_id IS NOT NULL) <= 1),
|
|
3796
|
+
CHECK (
|
|
3797
|
+
(source_kind = 'execution' AND parent_execution_id = source_id)
|
|
3798
|
+
OR (source_kind <> 'execution' AND parent_execution_id IS NULL)
|
|
3799
|
+
),
|
|
3800
|
+
CHECK (
|
|
3801
|
+
(
|
|
3802
|
+
authority_kind = 'principal'
|
|
3803
|
+
AND (authority_user_id IS NOT NULL) + (authority_service_account_id IS NOT NULL) = 1
|
|
3804
|
+
AND (authority_session_id IS NOT NULL) + (authority_access_token_id IS NOT NULL) <= 1
|
|
3805
|
+
AND (authority_session_id IS NULL OR authority_user_id IS NOT NULL)
|
|
3806
|
+
AND authority_primitive_kind IS NULL
|
|
3807
|
+
AND authority_primitive_id IS NULL
|
|
3808
|
+
AND authority_kernel_operation IS NULL
|
|
3809
|
+
AND authority_delegation_kind IS NULL
|
|
3810
|
+
AND authority_delegation_id IS NULL
|
|
3811
|
+
AND authority_delegation_session_id IS NULL
|
|
3812
|
+
)
|
|
3813
|
+
OR (
|
|
3814
|
+
authority_kind = 'trustedPrimitive'
|
|
3815
|
+
AND authority_user_id IS NULL
|
|
3816
|
+
AND authority_service_account_id IS NULL
|
|
3817
|
+
AND authority_session_id IS NULL
|
|
3818
|
+
AND authority_access_token_id IS NULL
|
|
3819
|
+
AND authority_primitive_kind IS NOT NULL
|
|
3820
|
+
AND authority_primitive_id IS NOT NULL
|
|
3821
|
+
AND length(trim(authority_primitive_id)) > 0
|
|
3822
|
+
AND authority_kernel_operation IS NULL
|
|
3823
|
+
AND authority_delegation_kind IS NULL
|
|
3824
|
+
AND authority_delegation_id IS NULL
|
|
3825
|
+
AND authority_delegation_session_id IS NULL
|
|
3826
|
+
)
|
|
3827
|
+
OR (
|
|
3828
|
+
authority_kind = 'delegated'
|
|
3829
|
+
AND authority_user_id IS NULL
|
|
3830
|
+
AND authority_service_account_id IS NULL
|
|
3831
|
+
AND authority_session_id IS NULL
|
|
3832
|
+
AND authority_access_token_id IS NULL
|
|
3833
|
+
AND authority_primitive_kind IS NULL
|
|
3834
|
+
AND authority_primitive_id IS NULL
|
|
3835
|
+
AND authority_kernel_operation IS NULL
|
|
3836
|
+
AND authority_delegation_kind IS NOT NULL
|
|
3837
|
+
AND authority_delegation_kind = 'share'
|
|
3838
|
+
AND authority_delegation_id IS NOT NULL
|
|
3839
|
+
AND length(trim(authority_delegation_id)) > 0
|
|
3840
|
+
AND authority_delegation_session_id IS NOT NULL
|
|
3841
|
+
AND length(trim(authority_delegation_session_id)) > 0
|
|
3842
|
+
)
|
|
3843
|
+
OR (
|
|
3844
|
+
authority_kind = 'kernel'
|
|
3845
|
+
AND authority_user_id IS NULL
|
|
3846
|
+
AND authority_service_account_id IS NULL
|
|
3847
|
+
AND authority_session_id IS NULL
|
|
3848
|
+
AND authority_access_token_id IS NULL
|
|
3849
|
+
AND authority_primitive_kind IS NULL
|
|
3850
|
+
AND authority_primitive_id IS NULL
|
|
3851
|
+
AND authority_kernel_operation IS NOT NULL
|
|
3852
|
+
AND authority_delegation_kind IS NULL
|
|
3853
|
+
AND authority_delegation_id IS NULL
|
|
3854
|
+
AND authority_delegation_session_id IS NULL
|
|
3855
|
+
)
|
|
3856
|
+
OR (
|
|
3857
|
+
authority_kind = 'disabled'
|
|
3858
|
+
AND authority_user_id IS NULL
|
|
3859
|
+
AND authority_service_account_id IS NULL
|
|
3860
|
+
AND authority_session_id IS NULL
|
|
3861
|
+
AND authority_access_token_id IS NULL
|
|
3862
|
+
AND authority_primitive_kind IS NULL
|
|
3863
|
+
AND authority_primitive_id IS NULL
|
|
3864
|
+
AND authority_kernel_operation IS NULL
|
|
3865
|
+
AND authority_delegation_kind IS NULL
|
|
3866
|
+
AND authority_delegation_id IS NULL
|
|
3867
|
+
AND authority_delegation_session_id IS NULL
|
|
3868
|
+
)
|
|
3869
|
+
),
|
|
3870
|
+
CHECK (
|
|
3871
|
+
(
|
|
3872
|
+
executor_kind = 'request'
|
|
3873
|
+
AND source_kind = 'http'
|
|
3874
|
+
AND executor_id = source_id
|
|
3875
|
+
AND (
|
|
3876
|
+
(
|
|
3877
|
+
authority_kind = 'principal'
|
|
3878
|
+
AND requested_by_user_id IS authority_user_id
|
|
3879
|
+
AND requested_by_service_account_id IS authority_service_account_id
|
|
3880
|
+
)
|
|
3881
|
+
OR (
|
|
3882
|
+
authority_kind IN ('delegated', 'disabled')
|
|
3883
|
+
AND requested_by_user_id IS NULL
|
|
3884
|
+
AND requested_by_service_account_id IS NULL
|
|
3885
|
+
)
|
|
3886
|
+
)
|
|
3887
|
+
)
|
|
3888
|
+
OR (
|
|
3889
|
+
executor_kind IN ('action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow')
|
|
3890
|
+
AND authority_kind = 'trustedPrimitive'
|
|
3891
|
+
AND executor_kind = authority_primitive_kind
|
|
3892
|
+
)
|
|
3893
|
+
OR (
|
|
3894
|
+
executor_kind = 'agent'
|
|
3895
|
+
AND source_kind = 'execution'
|
|
3896
|
+
AND (
|
|
3897
|
+
(
|
|
3898
|
+
authority_kind = 'principal'
|
|
3899
|
+
AND authority_service_account_id IS NOT NULL
|
|
3900
|
+
AND authority_session_id IS NULL
|
|
3901
|
+
AND authority_access_token_id IS NULL
|
|
3902
|
+
)
|
|
3903
|
+
OR (
|
|
3904
|
+
authority_kind = 'principal'
|
|
3905
|
+
AND authority_user_id IS NOT NULL
|
|
3906
|
+
AND (authority_session_id IS NOT NULL) + (authority_access_token_id IS NOT NULL) = 1
|
|
3907
|
+
)
|
|
3908
|
+
OR authority_kind = 'disabled'
|
|
3909
|
+
)
|
|
3910
|
+
)
|
|
3911
|
+
OR (executor_kind = 'kernel' AND authority_kind = 'kernel')
|
|
3912
|
+
)
|
|
3913
|
+
);
|
|
3914
|
+
|
|
3915
|
+
INSERT INTO executions_v2 (
|
|
3916
|
+
project_id, id, executor_kind, executor_id, source_kind, source_id,
|
|
3917
|
+
requested_by_user_id, requested_by_service_account_id, correlation_id, parent_execution_id,
|
|
3918
|
+
authority_kind, authority_user_id, authority_service_account_id, authority_session_id,
|
|
3919
|
+
authority_access_token_id, authority_primitive_kind, authority_primitive_id,
|
|
3920
|
+
authority_kernel_operation, authority_delegation_kind, authority_delegation_id,
|
|
3921
|
+
authority_delegation_session_id, created_at
|
|
3922
|
+
)
|
|
3923
|
+
SELECT
|
|
3924
|
+
project_id, id, executor_kind, executor_id, source_kind, source_id,
|
|
3925
|
+
requested_by_user_id, requested_by_service_account_id, correlation_id, parent_execution_id,
|
|
3926
|
+
authority_kind, authority_user_id, authority_service_account_id, authority_session_id,
|
|
3927
|
+
authority_access_token_id, authority_primitive_kind, authority_primitive_id,
|
|
3928
|
+
authority_kernel_operation, NULL, NULL, NULL, created_at
|
|
3929
|
+
FROM executions;
|
|
3930
|
+
|
|
3931
|
+
DROP TABLE executions;
|
|
3932
|
+
ALTER TABLE executions_v2 RENAME TO executions;
|
|
3933
|
+
`;
|
|
3934
|
+
|
|
3935
|
+
// src/migrations/037-execution-requester-groups.sql
|
|
3936
|
+
var _037_execution_requester_groups_default = `ALTER TABLE executions ADD COLUMN requester_group_ids TEXT NOT NULL DEFAULT '[]';
|
|
3937
|
+
|
|
3938
|
+
-- Preserve each admitted snapshot, including an intentionally empty one. Executions without
|
|
3939
|
+
-- their own historical snapshot inherit from their parent; historical roots remain unknown/empty.
|
|
3940
|
+
WITH RECURSIVE attribution(project_id, id, groups) AS (
|
|
3941
|
+
SELECT e.project_id, e.id, COALESCE(w.requester_group_ids, a.requester_group_ids, '[]')
|
|
3942
|
+
FROM executions e
|
|
3943
|
+
LEFT JOIN workflow_runs w ON w.project_id = e.project_id AND w.execution_id = e.id
|
|
3944
|
+
LEFT JOIN agent_runs a ON a.project_id = e.project_id AND a.execution_id = e.id
|
|
3945
|
+
WHERE e.parent_execution_id IS NULL
|
|
3946
|
+
UNION ALL
|
|
3947
|
+
SELECT e.project_id, e.id, COALESCE(w.requester_group_ids, a.requester_group_ids, p.groups)
|
|
3948
|
+
FROM executions e
|
|
3949
|
+
JOIN attribution p ON p.project_id = e.project_id AND p.id = e.parent_execution_id
|
|
3950
|
+
LEFT JOIN workflow_runs w ON w.project_id = e.project_id AND w.execution_id = e.id
|
|
3951
|
+
LEFT JOIN agent_runs a ON a.project_id = e.project_id AND a.execution_id = e.id
|
|
3952
|
+
)
|
|
3953
|
+
UPDATE executions SET requester_group_ids = (
|
|
3954
|
+
SELECT groups FROM attribution
|
|
3955
|
+
WHERE attribution.project_id = executions.project_id AND attribution.id = executions.id
|
|
3956
|
+
);
|
|
3957
|
+
|
|
3958
|
+
ALTER TABLE workflow_runs DROP COLUMN requester_group_ids;
|
|
3959
|
+
ALTER TABLE agent_runs DROP COLUMN requester_group_ids;
|
|
3960
|
+
`;
|
|
3961
|
+
|
|
3635
3962
|
// src/migrations.ts
|
|
3636
3963
|
var MIGRATIONS_TABLE_SQL = `
|
|
3637
3964
|
CREATE TABLE IF NOT EXISTS sixb_migrations (
|
|
@@ -3700,7 +4027,10 @@ var sqliteStorageMigrations = defineMigrations({
|
|
|
3700
4027
|
sqliteSql("031-subagent-runs", _031_subagent_runs_default),
|
|
3701
4028
|
sqliteSql("032-conversation-run-spec", _032_conversation_run_spec_default),
|
|
3702
4029
|
sqliteSql("033-retire-agent-definitions", _033_retire_agent_definitions_default),
|
|
3703
|
-
sqliteSql("034-device-authorizations", _034_device_authorizations_default)
|
|
4030
|
+
sqliteSql("034-device-authorizations", _034_device_authorizations_default),
|
|
4031
|
+
sqliteSql("035-share-grants", _035_share_grants_default),
|
|
4032
|
+
sqliteSql("036-share-sessions", _036_share_sessions_default),
|
|
4033
|
+
sqliteSql("037-execution-requester-groups", _037_execution_requester_groups_default)
|
|
3704
4034
|
]
|
|
3705
4035
|
});
|
|
3706
4036
|
function sqliteStoragePath(basePath) {
|
|
@@ -3879,6 +4209,7 @@ function closeSqliteStoreConnection(connection) {
|
|
|
3879
4209
|
}
|
|
3880
4210
|
}
|
|
3881
4211
|
var activeImmediateTransactions = new WeakSet;
|
|
4212
|
+
var activeDeferredReadTransactions = new WeakSet;
|
|
3882
4213
|
function runImmediateTransaction(db, run) {
|
|
3883
4214
|
if (activeImmediateTransactions.has(db)) {
|
|
3884
4215
|
return run();
|
|
@@ -3916,6 +4247,26 @@ async function runImmediateTransactionAsync(db, run) {
|
|
|
3916
4247
|
activeImmediateTransactions.delete(db);
|
|
3917
4248
|
}
|
|
3918
4249
|
}
|
|
4250
|
+
function runDeferredReadTransaction(db, run) {
|
|
4251
|
+
if (activeImmediateTransactions.has(db) || activeDeferredReadTransactions.has(db)) {
|
|
4252
|
+
return run();
|
|
4253
|
+
}
|
|
4254
|
+
if (db.inTransaction) {
|
|
4255
|
+
throw new Error("[SixbSqlite] Selected object reads cannot join an unverified SQLite transaction.");
|
|
4256
|
+
}
|
|
4257
|
+
db.run("BEGIN DEFERRED");
|
|
4258
|
+
activeDeferredReadTransactions.add(db);
|
|
4259
|
+
try {
|
|
4260
|
+
const result = run();
|
|
4261
|
+
db.run("COMMIT");
|
|
4262
|
+
return result;
|
|
4263
|
+
} catch (error) {
|
|
4264
|
+
rollbackQuietly2(db);
|
|
4265
|
+
throw error;
|
|
4266
|
+
} finally {
|
|
4267
|
+
activeDeferredReadTransactions.delete(db);
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
3919
4270
|
function rollbackQuietly2(db) {
|
|
3920
4271
|
try {
|
|
3921
4272
|
db.run("ROLLBACK");
|
|
@@ -4388,7 +4739,6 @@ function rowToRunRecord(row) {
|
|
|
4388
4739
|
id: row.id,
|
|
4389
4740
|
projectId: row.project_id,
|
|
4390
4741
|
executionId: row.execution_id,
|
|
4391
|
-
requesterGroupIds: JSON.parse(row.requester_group_ids),
|
|
4392
4742
|
status: row.status,
|
|
4393
4743
|
modelId: row.model_id ?? undefined,
|
|
4394
4744
|
finishReason: coerceAgentRunFinishReason(row.finish_reason),
|
|
@@ -4602,6 +4952,9 @@ import {
|
|
|
4602
4952
|
function isUniqueConstraintError2(error) {
|
|
4603
4953
|
return error instanceof Error && error.message.includes("UNIQUE constraint failed");
|
|
4604
4954
|
}
|
|
4955
|
+
function isForeignKeyConstraintError(error) {
|
|
4956
|
+
return error instanceof Error && error.message.includes("FOREIGN KEY constraint failed");
|
|
4957
|
+
}
|
|
4605
4958
|
|
|
4606
4959
|
// src/agents/messages.ts
|
|
4607
4960
|
class SqliteAgentMessageStore {
|
|
@@ -4731,7 +5084,6 @@ import {
|
|
|
4731
5084
|
assertSubagentRunResult,
|
|
4732
5085
|
subagentRunMatchesCreateInput
|
|
4733
5086
|
} from "@sixb/core/internal/agent-run-storage-provider";
|
|
4734
|
-
import { normalizeRequesterGroupIds } from "@sixb/core/internal/auth";
|
|
4735
5087
|
import { serializeSixbFailure } from "@sixb/core/internal/errors";
|
|
4736
5088
|
import {
|
|
4737
5089
|
AGENT_RUN_FAILURE_CODES as AGENT_RUN_FAILURE_CODES2,
|
|
@@ -4826,12 +5178,11 @@ class SqliteAgentRunStore {
|
|
|
4826
5178
|
thread_id,
|
|
4827
5179
|
trigger_message_id,
|
|
4828
5180
|
spec,
|
|
4829
|
-
requester_group_ids,
|
|
4830
5181
|
status,
|
|
4831
5182
|
attempt,
|
|
4832
5183
|
created_at
|
|
4833
|
-
) VALUES (?, ?, ?, 'conversation', ?, ?, ?,
|
|
4834
|
-
`).run(input.projectId, input.id, input.executionId, input.threadId, input.triggerMessageId, JSON.stringify(input.spec),
|
|
5184
|
+
) VALUES (?, ?, ?, 'conversation', ?, ?, ?, 'queued', 0, ?)
|
|
5185
|
+
`).run(input.projectId, input.id, input.executionId, input.threadId, input.triggerMessageId, JSON.stringify(input.spec), createdAt.toISOString());
|
|
4835
5186
|
} catch (error) {
|
|
4836
5187
|
if (isUniqueConstraintError2(error)) {
|
|
4837
5188
|
throw new AgentStorageError3("duplicate_id", `[SixbSqlite] Agent run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
@@ -4884,9 +5235,9 @@ class SqliteAgentRunStore {
|
|
|
4884
5235
|
this.db.query(`
|
|
4885
5236
|
INSERT INTO agent_runs (
|
|
4886
5237
|
project_id, id, execution_id, kind, parent_run_id, spawn_key, spec,
|
|
4887
|
-
|
|
4888
|
-
) VALUES (?, ?, ?, 'subagent', ?, ?, ?,
|
|
4889
|
-
`).run(input.projectId, input.id, input.executionId, input.parentRunId, input.spawnKey, JSON.stringify(input.spec),
|
|
5238
|
+
status, attempt, created_at
|
|
5239
|
+
) VALUES (?, ?, ?, 'subagent', ?, ?, ?, 'queued', 0, ?)
|
|
5240
|
+
`).run(input.projectId, input.id, input.executionId, input.parentRunId, input.spawnKey, JSON.stringify(input.spec), (input.createdAt ?? new Date).toISOString());
|
|
4890
5241
|
} catch (error) {
|
|
4891
5242
|
if (isUniqueConstraintError2(error)) {
|
|
4892
5243
|
throw new AgentStorageError3("duplicate_id", `[SixbSqlite] Subagent run '${input.id}' conflicts with an existing durable spawn.`);
|
|
@@ -5174,6 +5525,7 @@ import {
|
|
|
5174
5525
|
aiModelCallCostDetails,
|
|
5175
5526
|
aiModelCallCostMatchesUsage,
|
|
5176
5527
|
buildAiAccountingOverviewFromFragments,
|
|
5528
|
+
directModelCallAttribution,
|
|
5177
5529
|
normalizeAiAccountingQuery,
|
|
5178
5530
|
normalizeAiModelCallAccountingQuery as normalizeAiModelCallAccountingQuery2,
|
|
5179
5531
|
normalizeAiModelCallCostRecord,
|
|
@@ -5214,6 +5566,7 @@ WITH filtered AS (
|
|
|
5214
5566
|
SELECT COALESCE(root_agent.execution_id, usage.execution_id) AS root_execution_id,
|
|
5215
5567
|
usage.execution_id, usage.provider_id, usage.requested_model_id, usage.occurred_at,
|
|
5216
5568
|
usage.total_tokens,
|
|
5569
|
+
execution.executor_kind, execution.executor_id, execution.authority_primitive_id AS primitive_id,
|
|
5217
5570
|
COALESCE(cost.status, 'unvalued') AS valuation_status,
|
|
5218
5571
|
cost.currency AS amount_currency, cost.amount_nanos,
|
|
5219
5572
|
root_agent.id AS root_agent_run_id,
|
|
@@ -5226,6 +5579,7 @@ WITH filtered AS (
|
|
|
5226
5579
|
workflow_node.workflow_id AS workflow_id,
|
|
5227
5580
|
workflow_node.workflow_run_id AS workflow_run_id
|
|
5228
5581
|
FROM ai_model_call_usage AS usage
|
|
5582
|
+
JOIN executions AS execution ON execution.project_id = usage.project_id AND execution.id = usage.execution_id
|
|
5229
5583
|
LEFT JOIN agent_runs AS direct_agent
|
|
5230
5584
|
ON direct_agent.project_id = usage.project_id AND direct_agent.execution_id = usage.execution_id
|
|
5231
5585
|
LEFT JOIN agent_runs AS root_agent
|
|
@@ -5263,6 +5617,7 @@ SELECT filtered.root_execution_id, execution_id, provider_id, requested_model_id
|
|
|
5263
5617
|
CAST(SUM((amount_nanos / 1000000) % 1000000) AS TEXT) AS amount_middle,
|
|
5264
5618
|
CAST(SUM(amount_nanos % 1000000) AS TEXT) AS amount_low,
|
|
5265
5619
|
MAX(root_agent_run_id) AS root_agent_run_id,
|
|
5620
|
+
MAX(executor_kind) AS executor_kind, MAX(executor_id) AS executor_id, MAX(primitive_id) AS primitive_id,
|
|
5266
5621
|
MAX(root_thread_id) AS root_thread_id,
|
|
5267
5622
|
MAX(direct_kind) AS direct_kind,
|
|
5268
5623
|
MAX(direct_run_id) AS direct_run_id,
|
|
@@ -5277,12 +5632,11 @@ GROUP BY filtered.root_execution_id, execution_id, provider_id, requested_model_
|
|
|
5277
5632
|
`;
|
|
5278
5633
|
|
|
5279
5634
|
// src/ai-usage-storage.ts
|
|
5635
|
+
import { assertAiUsageExecutionId, normalizeAiModelCallRecord } from "@sixb/core/internal/storage";
|
|
5280
5636
|
import { isModelReasoning, normalizeModelProviderIds } from "@sixb/core/models";
|
|
5281
5637
|
import {
|
|
5282
5638
|
AiUsageStorageError,
|
|
5283
|
-
aggregateAiModelCallUsage
|
|
5284
|
-
assertAiUsageExecutionId,
|
|
5285
|
-
normalizeAiModelCallRecord
|
|
5639
|
+
aggregateAiModelCallUsage
|
|
5286
5640
|
} from "@sixb/core/storage";
|
|
5287
5641
|
class SqliteAiUsageStorage {
|
|
5288
5642
|
connection;
|
|
@@ -5605,6 +5959,7 @@ var SQLITE_ACCOUNTING_LIST_PAGE_SQL = `
|
|
|
5605
5959
|
workflow_agent.node_run_id AS attribution_node_run_id,
|
|
5606
5960
|
workflow_node.workflow_id AS attribution_workflow_id,
|
|
5607
5961
|
workflow_node.workflow_run_id AS attribution_workflow_run_id,
|
|
5962
|
+
execution.executor_kind, execution.executor_id, execution.authority_primitive_id AS primitive_id,
|
|
5608
5963
|
COALESCE((
|
|
5609
5964
|
SELECT json_group_array(group_id) FROM (
|
|
5610
5965
|
SELECT group_id FROM ai_model_call_usage_groups
|
|
@@ -5621,6 +5976,7 @@ var SQLITE_ACCOUNTING_LIST_PAGE_SQL = `
|
|
|
5621
5976
|
cost.details AS cost_details,
|
|
5622
5977
|
cost.rated_at AS cost_rated_at
|
|
5623
5978
|
FROM ai_model_call_usage AS usage
|
|
5979
|
+
JOIN executions AS execution ON execution.project_id = usage.project_id AND execution.id = usage.execution_id
|
|
5624
5980
|
LEFT JOIN agent_runs AS direct_agent
|
|
5625
5981
|
ON direct_agent.project_id = usage.project_id
|
|
5626
5982
|
AND direct_agent.execution_id = usage.execution_id
|
|
@@ -5655,7 +6011,9 @@ var SQLITE_ACCOUNTING_OVERVIEW_SQL = `
|
|
|
5655
6011
|
ELSE NULL
|
|
5656
6012
|
END AS attribution_agent_kind,
|
|
5657
6013
|
workflow_node.node_id AS attribution_agent_step_id,
|
|
5658
|
-
workflow_node.workflow_id
|
|
6014
|
+
COALESCE(workflow_node.workflow_id,
|
|
6015
|
+
CASE WHEN execution.executor_kind = 'workflow' THEN execution.authority_primitive_id END
|
|
6016
|
+
) AS attribution_workflow_id,
|
|
5659
6017
|
CASE
|
|
5660
6018
|
WHEN cost.status = 'rated' THEN 'rated'
|
|
5661
6019
|
WHEN cost.status = 'unpriceable' THEN 'unpriceable'
|
|
@@ -5664,6 +6022,7 @@ var SQLITE_ACCOUNTING_OVERVIEW_SQL = `
|
|
|
5664
6022
|
CASE WHEN cost.status = 'rated' THEN cost.currency ELSE NULL END AS amount_currency,
|
|
5665
6023
|
CASE WHEN cost.status = 'rated' THEN cost.amount_nanos ELSE NULL END AS amount_nanos
|
|
5666
6024
|
FROM ai_model_call_usage AS usage
|
|
6025
|
+
JOIN executions AS execution ON execution.project_id = usage.project_id AND execution.id = usage.execution_id
|
|
5667
6026
|
LEFT JOIN agent_runs AS direct_agent
|
|
5668
6027
|
ON direct_agent.project_id = usage.project_id
|
|
5669
6028
|
AND direct_agent.execution_id = usage.execution_id
|
|
@@ -5795,7 +6154,7 @@ function sqliteAggregateAmount(row) {
|
|
|
5795
6154
|
function accountingItemFromRow(row) {
|
|
5796
6155
|
const usage = usageFromRow2(row, parseStringArray(row.requester_group_ids));
|
|
5797
6156
|
const cost = row.cost_status === null ? undefined : costFromJoinedRow(row);
|
|
5798
|
-
const attribution = row.attribution_kind === null ?
|
|
6157
|
+
const attribution = row.attribution_kind === null ? directModelCallAttribution(row.executor_kind, row.executor_id, row.primitive_id) : row.attribution_kind === "agent" ? {
|
|
5799
6158
|
kind: "agent",
|
|
5800
6159
|
agentRunId: required(row.attribution_agent_run_id),
|
|
5801
6160
|
threadId: required(row.attribution_thread_id)
|
|
@@ -7207,8 +7566,8 @@ class SqliteAuthAccessTokenStore {
|
|
|
7207
7566
|
}
|
|
7208
7567
|
function assertSubjectExists(db, projectId, subjectType, subjectId) {
|
|
7209
7568
|
if (subjectType === "user") {
|
|
7210
|
-
const
|
|
7211
|
-
if (
|
|
7569
|
+
const row = db.query("SELECT * FROM auth_users WHERE project_id = ? AND id = ?").get(projectId, subjectId);
|
|
7570
|
+
if (row)
|
|
7212
7571
|
return;
|
|
7213
7572
|
throw new AuthStorageError2("missing_user", `[Sixb] User '${subjectId}' not found for project '${projectId}'.`);
|
|
7214
7573
|
}
|
|
@@ -8339,7 +8698,7 @@ class SqliteAuthStorage {
|
|
|
8339
8698
|
}
|
|
8340
8699
|
this.consumeOidcAttempt(input, completedAt, projectId);
|
|
8341
8700
|
if (!userRow) {
|
|
8342
|
-
const
|
|
8701
|
+
const user = this.insertUser({
|
|
8343
8702
|
id: newUserId ?? assertNonEmpty(input.newUserId, "User id"),
|
|
8344
8703
|
projectId,
|
|
8345
8704
|
email,
|
|
@@ -8348,14 +8707,14 @@ class SqliteAuthStorage {
|
|
|
8348
8707
|
createdAt: completedAt
|
|
8349
8708
|
});
|
|
8350
8709
|
userRow = {
|
|
8351
|
-
project_id:
|
|
8352
|
-
id:
|
|
8353
|
-
email:
|
|
8354
|
-
display_name:
|
|
8355
|
-
avatar_url:
|
|
8356
|
-
status:
|
|
8357
|
-
created_at: toIso(
|
|
8358
|
-
updated_at: toIso(
|
|
8710
|
+
project_id: user.projectId,
|
|
8711
|
+
id: user.id,
|
|
8712
|
+
email: user.email,
|
|
8713
|
+
display_name: user.displayName ?? null,
|
|
8714
|
+
avatar_url: user.avatarUrl ?? null,
|
|
8715
|
+
status: user.status,
|
|
8716
|
+
created_at: toIso(user.createdAt),
|
|
8717
|
+
updated_at: toIso(user.updatedAt)
|
|
8359
8718
|
};
|
|
8360
8719
|
}
|
|
8361
8720
|
const user = rowToUserRecord(userRow);
|
|
@@ -9073,23 +9432,24 @@ function assertChanged(changes, label, id) {
|
|
|
9073
9432
|
import {
|
|
9074
9433
|
executionRecordFromStorageRow,
|
|
9075
9434
|
executionRecordToStorageRow,
|
|
9076
|
-
|
|
9077
|
-
validateExecutionRecordReferences
|
|
9435
|
+
prepareExecutionRecord
|
|
9078
9436
|
} from "@sixb/core/internal/execution-storage";
|
|
9079
9437
|
import { ExecutionStorageError } from "@sixb/core/storage";
|
|
9080
9438
|
|
|
9081
9439
|
class SqliteExecutionStorage {
|
|
9082
9440
|
db;
|
|
9083
9441
|
auth;
|
|
9084
|
-
|
|
9442
|
+
shareSessions;
|
|
9443
|
+
constructor(db, auth, shareSessions) {
|
|
9085
9444
|
this.db = db;
|
|
9086
9445
|
this.auth = auth;
|
|
9446
|
+
this.shareSessions = shareSessions;
|
|
9087
9447
|
}
|
|
9088
9448
|
async create(input) {
|
|
9089
|
-
const record =
|
|
9090
|
-
await validateExecutionRecordReferences(record, {
|
|
9449
|
+
const record = await prepareExecutionRecord(input, {
|
|
9091
9450
|
auth: this.auth,
|
|
9092
|
-
getExecution: (params) => this.getById(params)
|
|
9451
|
+
getExecution: (params) => this.getById(params),
|
|
9452
|
+
getShareSession: (params) => this.shareSessions.getById(params)
|
|
9093
9453
|
});
|
|
9094
9454
|
const row = executionRecordToStorageRow(record);
|
|
9095
9455
|
try {
|
|
@@ -9103,6 +9463,7 @@ class SqliteExecutionStorage {
|
|
|
9103
9463
|
source_id,
|
|
9104
9464
|
requested_by_user_id,
|
|
9105
9465
|
requested_by_service_account_id,
|
|
9466
|
+
requester_group_ids,
|
|
9106
9467
|
correlation_id,
|
|
9107
9468
|
parent_execution_id,
|
|
9108
9469
|
authority_kind,
|
|
@@ -9113,9 +9474,12 @@ class SqliteExecutionStorage {
|
|
|
9113
9474
|
authority_primitive_kind,
|
|
9114
9475
|
authority_primitive_id,
|
|
9115
9476
|
authority_kernel_operation,
|
|
9477
|
+
authority_delegation_kind,
|
|
9478
|
+
authority_delegation_id,
|
|
9479
|
+
authority_delegation_session_id,
|
|
9116
9480
|
created_at
|
|
9117
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
9118
|
-
`).run(row.projectId, row.id, row.executorKind, row.executorId, row.sourceKind, row.sourceId, row.requestedByUserId, row.requestedByServiceAccountId, row.correlationId, row.parentExecutionId, row.authorityKind, row.authorityUserId, row.authorityServiceAccountId, row.authoritySessionId, row.authorityAccessTokenId, row.authorityPrimitiveKind, row.authorityPrimitiveId, row.authorityKernelOperation, row.createdAt.toISOString());
|
|
9481
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
9482
|
+
`).run(row.projectId, row.id, row.executorKind, row.executorId, row.sourceKind, row.sourceId, row.requestedByUserId, row.requestedByServiceAccountId, JSON.stringify(row.requesterGroupIds), row.correlationId, row.parentExecutionId, row.authorityKind, row.authorityUserId, row.authorityServiceAccountId, row.authoritySessionId, row.authorityAccessTokenId, row.authorityPrimitiveKind, row.authorityPrimitiveId, row.authorityKernelOperation, row.authorityDelegationKind, row.authorityDelegationId, row.authorityDelegationSessionId, row.createdAt.toISOString());
|
|
9119
9483
|
} catch (error) {
|
|
9120
9484
|
if (isDuplicateExecutionError(error)) {
|
|
9121
9485
|
throw new ExecutionStorageError("duplicate_execution", `[SixbSqlite] Execution '${record.id}' already exists in project '${record.projectId}'.`, { cause: error });
|
|
@@ -9143,6 +9507,7 @@ function toStorageRow(row) {
|
|
|
9143
9507
|
sourceId: row.source_id,
|
|
9144
9508
|
requestedByUserId: row.requested_by_user_id,
|
|
9145
9509
|
requestedByServiceAccountId: row.requested_by_service_account_id,
|
|
9510
|
+
requesterGroupIds: JSON.parse(row.requester_group_ids),
|
|
9146
9511
|
correlationId: row.correlation_id,
|
|
9147
9512
|
parentExecutionId: row.parent_execution_id,
|
|
9148
9513
|
authorityKind: row.authority_kind,
|
|
@@ -9153,6 +9518,9 @@ function toStorageRow(row) {
|
|
|
9153
9518
|
authorityPrimitiveKind: row.authority_primitive_kind,
|
|
9154
9519
|
authorityPrimitiveId: row.authority_primitive_id,
|
|
9155
9520
|
authorityKernelOperation: row.authority_kernel_operation,
|
|
9521
|
+
authorityDelegationKind: row.authority_delegation_kind,
|
|
9522
|
+
authorityDelegationId: row.authority_delegation_id,
|
|
9523
|
+
authorityDelegationSessionId: row.authority_delegation_session_id,
|
|
9156
9524
|
createdAt: new Date(row.created_at)
|
|
9157
9525
|
};
|
|
9158
9526
|
}
|
|
@@ -9160,56 +9528,62 @@ function isDuplicateExecutionError(error) {
|
|
|
9160
9528
|
return error instanceof Error && error.message.includes("UNIQUE constraint failed: executions.project_id, executions.id");
|
|
9161
9529
|
}
|
|
9162
9530
|
|
|
9163
|
-
// src/
|
|
9164
|
-
import { linkBatchKey, objectBatchKey } from "@sixb/core/storage";
|
|
9165
|
-
|
|
9166
|
-
// src/object-query-compiler.ts
|
|
9531
|
+
// src/objects/query-compiler.ts
|
|
9167
9532
|
import {
|
|
9168
9533
|
ObjectQueryExecutionError
|
|
9169
9534
|
} from "@sixb/core";
|
|
9170
9535
|
var PAGE_TOKEN_PREFIX = "keyset:";
|
|
9171
|
-
var exactContext = { probeLimit: false };
|
|
9172
9536
|
var DEFAULT_EXPANSION_FANOUT = 1000;
|
|
9173
9537
|
function compileObjectQuery(projectId, query, options = {}) {
|
|
9174
|
-
const
|
|
9175
|
-
|
|
9538
|
+
const source = options.source ?? DEFAULT_OBJECT_QUERY_SOURCE;
|
|
9539
|
+
const ctx = { probeLimit: options.includeTotal === false, source };
|
|
9540
|
+
return source.wrapQuery(compileObjectQueryInternal(projectId, query, ctx));
|
|
9541
|
+
}
|
|
9542
|
+
var DEFAULT_OBJECT_QUERY_SOURCE = {
|
|
9543
|
+
objectsTable: "objects",
|
|
9544
|
+
linksTable: "links",
|
|
9545
|
+
wrapStatement: (sql, args = []) => ({ sql, args: [...args] }),
|
|
9546
|
+
wrapQuery: (query) => query
|
|
9547
|
+
};
|
|
9548
|
+
function exactContext(ctx) {
|
|
9549
|
+
return ctx.probeLimit ? { ...ctx, probeLimit: false } : ctx;
|
|
9176
9550
|
}
|
|
9177
9551
|
function compileObjectQueryInternal(projectId, query, ctx) {
|
|
9178
9552
|
switch (query.kind) {
|
|
9179
9553
|
case "start":
|
|
9180
|
-
return compileStart(projectId, query);
|
|
9554
|
+
return compileStart(projectId, query, ctx);
|
|
9181
9555
|
case "refs":
|
|
9182
|
-
return compileRefs(projectId, query);
|
|
9556
|
+
return compileRefs(projectId, query, ctx);
|
|
9183
9557
|
case "filter":
|
|
9184
|
-
return compileFilter(projectId, query.input, query.predicate);
|
|
9558
|
+
return compileFilter(projectId, query.input, query.predicate, ctx);
|
|
9185
9559
|
case "sort":
|
|
9186
9560
|
return compileSort(projectId, query.input, query.fields, ctx);
|
|
9187
9561
|
case "limit":
|
|
9188
9562
|
return compileLimit(projectId, query.input, query.limit, ctx);
|
|
9189
9563
|
case "page":
|
|
9190
|
-
return compilePage(projectId, query.input, query.pageSize, query.pageToken);
|
|
9564
|
+
return compilePage(projectId, query.input, query.pageSize, query.pageToken, ctx);
|
|
9191
9565
|
case "traverse":
|
|
9192
|
-
return compileTraversal(projectId, query.input, query.linkId, query.direction, query.sourceObjectTypeId);
|
|
9566
|
+
return compileTraversal(projectId, query.input, query.linkId, query.direction, query.sourceObjectTypeId, ctx);
|
|
9193
9567
|
case "set":
|
|
9194
|
-
return compileSet(projectId, query.op, query.inputs);
|
|
9568
|
+
return compileSet(projectId, query.op, query.inputs, ctx);
|
|
9195
9569
|
case "project":
|
|
9196
9570
|
return compileProject(projectId, query.input, query.properties, ctx);
|
|
9197
9571
|
case "text":
|
|
9198
|
-
return compileText(projectId, query.input, query.query, query.fields, query.fieldsByObjectType);
|
|
9572
|
+
return compileText(projectId, query.input, query.query, query.fields, query.fieldsByObjectType, ctx);
|
|
9199
9573
|
case "expand":
|
|
9200
|
-
return compileExpand(projectId, query.input, query.expansions);
|
|
9574
|
+
return compileExpand(projectId, query.input, query.expansions, ctx);
|
|
9201
9575
|
case "vector":
|
|
9202
9576
|
throw new Error(`[Sixb] SQLite object storage does not support query node '${query.kind}'`);
|
|
9203
9577
|
}
|
|
9204
9578
|
}
|
|
9205
|
-
function compileStart(projectId, query) {
|
|
9579
|
+
function compileStart(projectId, query, ctx) {
|
|
9206
9580
|
if (query.includeSubtypes === true) {
|
|
9207
9581
|
throw new Error("[Sixb] SQLite object storage does not support start.includeSubtypes");
|
|
9208
9582
|
}
|
|
9209
9583
|
const order = compileOrder(identityOrderFields());
|
|
9210
9584
|
const sql = `
|
|
9211
9585
|
SELECT *, properties AS _cursor_properties
|
|
9212
|
-
FROM
|
|
9586
|
+
FROM ${ctx.source.objectsTable}
|
|
9213
9587
|
WHERE project_id = ? AND object_type_id = ?
|
|
9214
9588
|
ORDER BY ${order.sql}
|
|
9215
9589
|
`;
|
|
@@ -9217,7 +9591,7 @@ function compileStart(projectId, query) {
|
|
|
9217
9591
|
return {
|
|
9218
9592
|
sql,
|
|
9219
9593
|
args,
|
|
9220
|
-
totalSql:
|
|
9594
|
+
totalSql: `SELECT COUNT(*) as total FROM ${ctx.source.objectsTable} WHERE project_id = ? AND object_type_id = ?`,
|
|
9221
9595
|
totalArgs: [projectId, query.objectTypeId],
|
|
9222
9596
|
order,
|
|
9223
9597
|
hasMore: () => false,
|
|
@@ -9227,7 +9601,7 @@ function compileStart(projectId, query) {
|
|
|
9227
9601
|
}
|
|
9228
9602
|
};
|
|
9229
9603
|
}
|
|
9230
|
-
function compileRefs(projectId, query) {
|
|
9604
|
+
function compileRefs(projectId, query, ctx) {
|
|
9231
9605
|
if (query.refs.length === 0) {
|
|
9232
9606
|
throw new Error("[Sixb] SQLite object storage requires at least one ref");
|
|
9233
9607
|
}
|
|
@@ -9241,10 +9615,9 @@ function compileRefs(projectId, query) {
|
|
|
9241
9615
|
FROM json_each(?) AS ref
|
|
9242
9616
|
`;
|
|
9243
9617
|
const sql = `
|
|
9244
|
-
WITH requested AS (${requested})
|
|
9245
9618
|
SELECT selected.*, selected.properties AS _cursor_properties
|
|
9246
|
-
FROM requested
|
|
9247
|
-
JOIN
|
|
9619
|
+
FROM (${requested}) AS requested
|
|
9620
|
+
JOIN ${ctx.source.objectsTable} AS selected
|
|
9248
9621
|
ON selected.project_id = ?
|
|
9249
9622
|
AND selected.object_type_id = requested.object_type_id
|
|
9250
9623
|
AND selected.primary_id = requested.primary_id
|
|
@@ -9254,10 +9627,9 @@ function compileRefs(projectId, query) {
|
|
|
9254
9627
|
sql,
|
|
9255
9628
|
args: [refsJson, projectId, ...selectedOrder.args],
|
|
9256
9629
|
totalSql: `
|
|
9257
|
-
WITH requested AS (${requested})
|
|
9258
9630
|
SELECT COUNT(*) AS total
|
|
9259
|
-
FROM requested
|
|
9260
|
-
JOIN
|
|
9631
|
+
FROM (${requested}) AS requested
|
|
9632
|
+
JOIN ${ctx.source.objectsTable} AS selected
|
|
9261
9633
|
ON selected.project_id = ?
|
|
9262
9634
|
AND selected.object_type_id = requested.object_type_id
|
|
9263
9635
|
AND selected.primary_id = requested.primary_id
|
|
@@ -9271,12 +9643,12 @@ function compileRefs(projectId, query) {
|
|
|
9271
9643
|
}
|
|
9272
9644
|
};
|
|
9273
9645
|
}
|
|
9274
|
-
function compileFilter(projectId, inputQuery, predicateNode) {
|
|
9646
|
+
function compileFilter(projectId, inputQuery, predicateNode, ctx) {
|
|
9275
9647
|
const predicate = compilePredicate(predicateNode);
|
|
9276
|
-
return compileWhere(projectId, inputQuery, predicate);
|
|
9648
|
+
return compileWhere(projectId, inputQuery, predicate, ctx);
|
|
9277
9649
|
}
|
|
9278
|
-
function compileWhere(projectId, inputQuery, predicate) {
|
|
9279
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9650
|
+
function compileWhere(projectId, inputQuery, predicate, ctx) {
|
|
9651
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9280
9652
|
const sql = `
|
|
9281
9653
|
SELECT *
|
|
9282
9654
|
FROM (${input.sql}) AS input
|
|
@@ -9300,15 +9672,15 @@ function compileWhere(projectId, inputQuery, predicate) {
|
|
|
9300
9672
|
}
|
|
9301
9673
|
};
|
|
9302
9674
|
}
|
|
9303
|
-
function compileText(projectId, inputQuery, query, fields, fieldsByObjectType) {
|
|
9675
|
+
function compileText(projectId, inputQuery, query, fields, fieldsByObjectType, ctx) {
|
|
9304
9676
|
const predicate = fields && fields.length > 0 ? compileTextPredicate(query, fields) : compileScopedTextPredicate(query, fieldsByObjectType);
|
|
9305
9677
|
if (!predicate) {
|
|
9306
9678
|
throw new Error("[Sixb] SQLite object text search requires fields or resolved text defaults");
|
|
9307
9679
|
}
|
|
9308
|
-
return compileWhere(projectId, inputQuery, predicate);
|
|
9680
|
+
return compileWhere(projectId, inputQuery, predicate, ctx);
|
|
9309
9681
|
}
|
|
9310
9682
|
function compileSort(projectId, inputQuery, fields, ctx) {
|
|
9311
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9683
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9312
9684
|
const probeInput = ctx.probeLimit && needsLimitProbe(inputQuery) ? compileObjectQueryInternal(projectId, inputQuery, ctx) : undefined;
|
|
9313
9685
|
const order = compileOrder(sortOrderFields(fields));
|
|
9314
9686
|
return {
|
|
@@ -9337,7 +9709,7 @@ function compileSort(projectId, inputQuery, fields, ctx) {
|
|
|
9337
9709
|
};
|
|
9338
9710
|
}
|
|
9339
9711
|
function compileLimit(projectId, inputQuery, rawLimit, ctx) {
|
|
9340
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9712
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9341
9713
|
const limit = Math.max(0, rawLimit);
|
|
9342
9714
|
const rowLimit = ctx.probeLimit ? limit + 1 : limit;
|
|
9343
9715
|
return {
|
|
@@ -9361,8 +9733,8 @@ function compileLimit(projectId, inputQuery, rawLimit, ctx) {
|
|
|
9361
9733
|
}
|
|
9362
9734
|
};
|
|
9363
9735
|
}
|
|
9364
|
-
function compilePage(projectId, inputQuery, rawPageSize, pageToken) {
|
|
9365
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9736
|
+
function compilePage(projectId, inputQuery, rawPageSize, pageToken, ctx) {
|
|
9737
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9366
9738
|
const pageSize = Math.max(0, rawPageSize);
|
|
9367
9739
|
const cursor = pageToken ? decodePageToken(pageToken, input.order.fields) : undefined;
|
|
9368
9740
|
const cursorPredicate = cursor ? compileKeysetPredicate(input.order.fields, cursor, input.order.propertyColumn) : undefined;
|
|
@@ -9391,27 +9763,27 @@ function compilePage(projectId, inputQuery, rawPageSize, pageToken) {
|
|
|
9391
9763
|
}
|
|
9392
9764
|
};
|
|
9393
9765
|
}
|
|
9394
|
-
function compileTraversal(projectId, inputQuery, linkId, direction, sourceObjectTypeId) {
|
|
9395
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9766
|
+
function compileTraversal(projectId, inputQuery, linkId, direction, sourceObjectTypeId, ctx) {
|
|
9767
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9396
9768
|
const outputAlias = direction === "outgoing" ? "target_object" : "source_object";
|
|
9397
9769
|
const joinSql = direction === "outgoing" ? `
|
|
9398
|
-
JOIN
|
|
9770
|
+
JOIN ${ctx.source.linksTable} AS edge
|
|
9399
9771
|
ON edge.project_id = input.project_id
|
|
9400
9772
|
AND edge.source_type_id = input.object_type_id
|
|
9401
9773
|
AND edge.source_id = input.primary_id
|
|
9402
9774
|
AND edge.link_id = ?
|
|
9403
|
-
JOIN
|
|
9775
|
+
JOIN ${ctx.source.objectsTable} AS target_object
|
|
9404
9776
|
ON target_object.project_id = edge.project_id
|
|
9405
9777
|
AND target_object.object_type_id = edge.target_type_id
|
|
9406
9778
|
AND target_object.primary_id = edge.target_id
|
|
9407
9779
|
` : `
|
|
9408
|
-
JOIN
|
|
9780
|
+
JOIN ${ctx.source.linksTable} AS edge
|
|
9409
9781
|
ON edge.project_id = input.project_id
|
|
9410
9782
|
AND edge.target_type_id = input.object_type_id
|
|
9411
9783
|
AND edge.target_id = input.primary_id
|
|
9412
9784
|
AND edge.link_id = ?${sourceObjectTypeId === undefined ? "" : `
|
|
9413
9785
|
AND edge.source_type_id = ?`}
|
|
9414
|
-
JOIN
|
|
9786
|
+
JOIN ${ctx.source.objectsTable} AS source_object
|
|
9415
9787
|
ON source_object.project_id = edge.project_id
|
|
9416
9788
|
AND source_object.object_type_id = edge.source_type_id
|
|
9417
9789
|
AND source_object.primary_id = edge.source_id
|
|
@@ -9443,9 +9815,9 @@ function compileTraversal(projectId, inputQuery, linkId, direction, sourceObject
|
|
|
9443
9815
|
}
|
|
9444
9816
|
};
|
|
9445
9817
|
}
|
|
9446
|
-
function compileExpand(projectId, inputQuery, expansions) {
|
|
9447
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9448
|
-
const expand = compileExpansionsObject(expansions, { project: "input.project_id", type: "input.object_type_id", id: "input.primary_id" }, "");
|
|
9818
|
+
function compileExpand(projectId, inputQuery, expansions, ctx) {
|
|
9819
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9820
|
+
const expand = compileExpansionsObject(expansions, { project: "input.project_id", type: "input.object_type_id", id: "input.primary_id" }, "", ctx);
|
|
9449
9821
|
const inputOrder = compileOrder(input.order.fields, "input", "input._cursor_properties");
|
|
9450
9822
|
const sql = `
|
|
9451
9823
|
SELECT input.*, ${expand.sql} AS _expand
|
|
@@ -9464,18 +9836,18 @@ function compileExpand(projectId, inputQuery, expansions) {
|
|
|
9464
9836
|
nextPageToken: input.nextPageToken
|
|
9465
9837
|
};
|
|
9466
9838
|
}
|
|
9467
|
-
function compileExpansionsObject(expansions, parent, pathPrefix) {
|
|
9839
|
+
function compileExpansionsObject(expansions, parent, pathPrefix, ctx) {
|
|
9468
9840
|
const parts = [];
|
|
9469
9841
|
const args = [];
|
|
9470
9842
|
expansions.forEach((expansion, index) => {
|
|
9471
9843
|
const path = pathPrefix === "" ? `${index}` : `${pathPrefix}_${index}`;
|
|
9472
|
-
const value = compileExpansionValue(expansion, parent, path);
|
|
9844
|
+
const value = compileExpansionValue(expansion, parent, path, ctx);
|
|
9473
9845
|
parts.push("?", `json(${value.sql})`);
|
|
9474
9846
|
args.push(expansion.linkId, ...value.args);
|
|
9475
9847
|
});
|
|
9476
9848
|
return { sql: `json_object(${parts.join(", ")})`, args };
|
|
9477
9849
|
}
|
|
9478
|
-
function compileExpansionValue(expansion, parent, path) {
|
|
9850
|
+
function compileExpansionValue(expansion, parent, path, ctx) {
|
|
9479
9851
|
const edge = `edge_${path}`;
|
|
9480
9852
|
const target = `tgt_${path}`;
|
|
9481
9853
|
const ranked = `ranked_${path}`;
|
|
@@ -9484,7 +9856,7 @@ function compileExpansionValue(expansion, parent, path) {
|
|
|
9484
9856
|
const neighborId = incoming ? `${edge}.source_id` : `${edge}.target_id`;
|
|
9485
9857
|
const parentType = incoming ? `${edge}.target_type_id` : `${edge}.source_type_id`;
|
|
9486
9858
|
const parentId = incoming ? `${edge}.target_id` : `${edge}.source_id`;
|
|
9487
|
-
const child = compileExpansionChildJson(expansion, edge, target, path);
|
|
9859
|
+
const child = compileExpansionChildJson(expansion, edge, target, path, ctx);
|
|
9488
9860
|
const order = compileExpansionOrder(expansion, target, neighborType, neighborId);
|
|
9489
9861
|
const whereParts = [
|
|
9490
9862
|
`${edge}.project_id = ${parent.project}`,
|
|
@@ -9499,8 +9871,8 @@ function compileExpansionValue(expansion, parent, path) {
|
|
|
9499
9871
|
}
|
|
9500
9872
|
const inner = `
|
|
9501
9873
|
SELECT ${child.sql} AS elem, row_number() OVER (ORDER BY ${order.sql}) AS _ord
|
|
9502
|
-
FROM
|
|
9503
|
-
JOIN
|
|
9874
|
+
FROM ${ctx.source.linksTable} AS ${edge}
|
|
9875
|
+
JOIN ${ctx.source.objectsTable} AS ${target}
|
|
9504
9876
|
ON ${target}.project_id = ${edge}.project_id
|
|
9505
9877
|
AND ${target}.object_type_id = ${neighborType}
|
|
9506
9878
|
AND ${target}.primary_id = ${neighborId}
|
|
@@ -9519,7 +9891,7 @@ function compileExpansionValue(expansion, parent, path) {
|
|
|
9519
9891
|
args: [...innerArgs, limit]
|
|
9520
9892
|
};
|
|
9521
9893
|
}
|
|
9522
|
-
function compileExpansionChildJson(expansion, edge, target, path) {
|
|
9894
|
+
function compileExpansionChildJson(expansion, edge, target, path, ctx) {
|
|
9523
9895
|
const fields = [
|
|
9524
9896
|
`'projectId', ${target}.project_id`,
|
|
9525
9897
|
`'objectTypeId', ${target}.object_type_id`,
|
|
@@ -9537,7 +9909,7 @@ function compileExpansionChildJson(expansion, edge, target, path) {
|
|
|
9537
9909
|
project: `${target}.project_id`,
|
|
9538
9910
|
type: `${target}.object_type_id`,
|
|
9539
9911
|
id: `${target}.primary_id`
|
|
9540
|
-
}, path);
|
|
9912
|
+
}, path, ctx);
|
|
9541
9913
|
fields.push(`'links', ${nested.sql}`);
|
|
9542
9914
|
args.push(...nested.args);
|
|
9543
9915
|
}
|
|
@@ -9561,20 +9933,20 @@ function compileExpansionOrder(expansion, target, neighborType, neighborId) {
|
|
|
9561
9933
|
clauses.push(`${neighborType} ASC`, `${neighborId} ASC`);
|
|
9562
9934
|
return { sql: clauses.join(", "), args };
|
|
9563
9935
|
}
|
|
9564
|
-
function compileSet(projectId, op, inputs) {
|
|
9936
|
+
function compileSet(projectId, op, inputs, ctx) {
|
|
9565
9937
|
if (inputs.length === 0) {
|
|
9566
|
-
const
|
|
9938
|
+
const order = compileOrder(identityOrderFields());
|
|
9567
9939
|
return {
|
|
9568
9940
|
sql: `
|
|
9569
9941
|
SELECT *
|
|
9570
|
-
FROM
|
|
9942
|
+
FROM ${ctx.source.objectsTable}
|
|
9571
9943
|
WHERE 1 = 0
|
|
9572
|
-
ORDER BY ${
|
|
9944
|
+
ORDER BY ${order.sql}
|
|
9573
9945
|
`,
|
|
9574
|
-
args:
|
|
9946
|
+
args: order.args,
|
|
9575
9947
|
totalSql: "SELECT 0 as total",
|
|
9576
9948
|
totalArgs: [],
|
|
9577
|
-
order
|
|
9949
|
+
order,
|
|
9578
9950
|
hasMore: () => false,
|
|
9579
9951
|
trimRows: identityRows,
|
|
9580
9952
|
nextPageToken: () => {
|
|
@@ -9582,14 +9954,14 @@ function compileSet(projectId, op, inputs) {
|
|
|
9582
9954
|
}
|
|
9583
9955
|
};
|
|
9584
9956
|
}
|
|
9585
|
-
const compiledInputs = inputs.map((input) => compileObjectQueryInternal(projectId, input, exactContext));
|
|
9957
|
+
const compiledInputs = inputs.map((input) => compileObjectQueryInternal(projectId, input, exactContext(ctx)));
|
|
9586
9958
|
const identities = compileSetIdentities(op, compiledInputs);
|
|
9587
9959
|
const order = compileOrder(identityOrderFields());
|
|
9588
9960
|
const selectedOrder = compileOrder(identityOrderFields(), "selected");
|
|
9589
9961
|
const sql = `
|
|
9590
9962
|
SELECT selected.*, selected.properties AS _cursor_properties
|
|
9591
9963
|
FROM (${identities.sql}) AS ids
|
|
9592
|
-
JOIN
|
|
9964
|
+
JOIN ${ctx.source.objectsTable} AS selected
|
|
9593
9965
|
ON selected.project_id = ?
|
|
9594
9966
|
AND selected.object_type_id = ids.object_type_id
|
|
9595
9967
|
AND selected.primary_id = ids.primary_id
|
|
@@ -9674,7 +10046,7 @@ function compileProjectionExpression(properties) {
|
|
|
9674
10046
|
sql: `
|
|
9675
10047
|
COALESCE(
|
|
9676
10048
|
(
|
|
9677
|
-
SELECT json_group_object(projected.key, projected
|
|
10049
|
+
SELECT json_group_object(projected.key, ${sqliteJsonEachValue("projected")})
|
|
9678
10050
|
FROM json_each(input.properties) AS projected
|
|
9679
10051
|
WHERE projected.key IN (${properties.map(() => "?").join(", ")})
|
|
9680
10052
|
),
|
|
@@ -9684,6 +10056,13 @@ function compileProjectionExpression(properties) {
|
|
|
9684
10056
|
args: [...properties]
|
|
9685
10057
|
};
|
|
9686
10058
|
}
|
|
10059
|
+
function sqliteJsonEachValue(alias) {
|
|
10060
|
+
return `CASE ${alias}.type
|
|
10061
|
+
WHEN 'true' THEN json('true')
|
|
10062
|
+
WHEN 'false' THEN json('false')
|
|
10063
|
+
ELSE ${alias}.value
|
|
10064
|
+
END`;
|
|
10065
|
+
}
|
|
9687
10066
|
function compilePredicate(predicate) {
|
|
9688
10067
|
if ("scalarKind" in predicate && predicate.scalarKind === "decimal" && (predicate.op === "lt" || predicate.op === "lte" || predicate.op === "gt" || predicate.op === "gte")) {
|
|
9689
10068
|
throw new ObjectQueryExecutionError("exact_decimal_not_supported", "SQLite object storage cannot push down exact decimal predicates", "$.predicate");
|
|
@@ -10006,112 +10385,131 @@ function isPlainObject(value) {
|
|
|
10006
10385
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10007
10386
|
}
|
|
10008
10387
|
|
|
10009
|
-
// src/
|
|
10010
|
-
|
|
10011
|
-
queryObjects: true,
|
|
10012
|
-
countObjects: true,
|
|
10013
|
-
existsObjects: true,
|
|
10014
|
-
facetObjects: true,
|
|
10015
|
-
nodes: {
|
|
10016
|
-
start: true,
|
|
10017
|
-
refs: true,
|
|
10018
|
-
filter: true,
|
|
10019
|
-
text: true,
|
|
10020
|
-
sort: true,
|
|
10021
|
-
limit: true,
|
|
10022
|
-
page: true,
|
|
10023
|
-
traverse: true,
|
|
10024
|
-
set: true,
|
|
10025
|
-
project: true,
|
|
10026
|
-
expand: true
|
|
10027
|
-
},
|
|
10028
|
-
predicateOps: {
|
|
10029
|
-
and: true,
|
|
10030
|
-
or: true,
|
|
10031
|
-
not: true,
|
|
10032
|
-
eq: true,
|
|
10033
|
-
neq: true,
|
|
10034
|
-
lt: true,
|
|
10035
|
-
lte: true,
|
|
10036
|
-
gt: true,
|
|
10037
|
-
gte: true,
|
|
10038
|
-
in: true,
|
|
10039
|
-
exists: true,
|
|
10040
|
-
contains: true
|
|
10041
|
-
},
|
|
10042
|
-
sortKinds: {
|
|
10043
|
-
property: true
|
|
10044
|
-
},
|
|
10045
|
-
traversalDirections: {
|
|
10046
|
-
outgoing: true,
|
|
10047
|
-
incoming: true
|
|
10048
|
-
},
|
|
10049
|
-
setOps: {
|
|
10050
|
-
union: true,
|
|
10051
|
-
intersect: true,
|
|
10052
|
-
subtract: true
|
|
10053
|
-
},
|
|
10054
|
-
scalarOperations: {
|
|
10055
|
-
string: { equality: true, ordering: true },
|
|
10056
|
-
uuid: { equality: true, ordering: true },
|
|
10057
|
-
boolean: { equality: true },
|
|
10058
|
-
integer: { equality: true, ordering: true },
|
|
10059
|
-
double: { equality: true, ordering: true },
|
|
10060
|
-
decimal: { equality: true },
|
|
10061
|
-
date: { equality: true, ordering: true },
|
|
10062
|
-
timestamp: { equality: true, ordering: true }
|
|
10063
|
-
},
|
|
10064
|
-
limits: {
|
|
10065
|
-
totalCount: true,
|
|
10066
|
-
stablePageTokens: true
|
|
10067
|
-
},
|
|
10068
|
-
notes: [
|
|
10069
|
-
"SQLite object query pushdown supports start/refs/filter/text/sort/limit/page/traverse/set/project/expand over JSON properties and object links.",
|
|
10070
|
-
"expand hydrates linked objects in-database (top-N per parent via row_number() + json_group_array); core resolves each expansion's cardinality before pushdown, and a mixed/unresolved one stays on the fallback.",
|
|
10071
|
-
"Ordered decimal predicates and sorting use the bounded core fallback because SQLite has no native exact decimal type; canonical decimal equality remains pushdown-safe.",
|
|
10072
|
-
"Relevance sorting, vector search, and unresolved start.includeSubtypes remain planner fallback or rejection cases."
|
|
10073
|
-
]
|
|
10074
|
-
};
|
|
10388
|
+
// src/objects/reader.ts
|
|
10389
|
+
import { linkBatchKey, objectBatchKey } from "@sixb/core/storage";
|
|
10075
10390
|
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10391
|
+
// src/objects/rows.ts
|
|
10392
|
+
function rowToObject(row) {
|
|
10393
|
+
return {
|
|
10394
|
+
projectId: row.project_id,
|
|
10395
|
+
objectTypeId: row.object_type_id,
|
|
10396
|
+
primaryId: row.primary_id,
|
|
10397
|
+
properties: JSON.parse(row.properties),
|
|
10398
|
+
createdAt: new Date(row.created_at),
|
|
10399
|
+
updatedAt: new Date(row.updated_at),
|
|
10400
|
+
version: row.version,
|
|
10401
|
+
lastCommitId: row.last_commit_id
|
|
10402
|
+
};
|
|
10403
|
+
}
|
|
10404
|
+
function queryRowToObject(row) {
|
|
10405
|
+
const base = rowToObject(row);
|
|
10406
|
+
const links = reviveExpandedLinks(parseExpandColumn(row._expand));
|
|
10407
|
+
return links ? { ...base, links } : base;
|
|
10408
|
+
}
|
|
10409
|
+
function rowToLink(row) {
|
|
10410
|
+
return {
|
|
10411
|
+
projectId: row.project_id,
|
|
10412
|
+
sourceTypeId: row.source_type_id,
|
|
10413
|
+
sourceId: row.source_id,
|
|
10414
|
+
linkId: row.link_id,
|
|
10415
|
+
targetTypeId: row.target_type_id,
|
|
10416
|
+
targetId: row.target_id,
|
|
10417
|
+
...row.properties === null ? {} : { properties: JSON.parse(row.properties) },
|
|
10418
|
+
createdAt: new Date(row.created_at),
|
|
10419
|
+
updatedAt: new Date(row.updated_at),
|
|
10420
|
+
lastCommitId: row.last_commit_id
|
|
10421
|
+
};
|
|
10422
|
+
}
|
|
10423
|
+
function parseExpandColumn(value) {
|
|
10424
|
+
if (typeof value !== "string")
|
|
10425
|
+
return value ?? undefined;
|
|
10426
|
+
return JSON.parse(value);
|
|
10427
|
+
}
|
|
10428
|
+
function reviveExpandedLinks(value) {
|
|
10429
|
+
if (!isPlainObject2(value))
|
|
10430
|
+
return;
|
|
10431
|
+
const links = {};
|
|
10432
|
+
for (const [linkId, raw] of Object.entries(value)) {
|
|
10433
|
+
links[linkId] = reviveExpandedLinkValue(raw);
|
|
10085
10434
|
}
|
|
10086
|
-
|
|
10087
|
-
|
|
10435
|
+
return links;
|
|
10436
|
+
}
|
|
10437
|
+
function reviveExpandedLinkValue(value) {
|
|
10438
|
+
if (value === null || value === undefined)
|
|
10439
|
+
return null;
|
|
10440
|
+
if (Array.isArray(value))
|
|
10441
|
+
return value.map(reviveExpandedRow);
|
|
10442
|
+
return reviveExpandedRow(value);
|
|
10443
|
+
}
|
|
10444
|
+
function reviveExpandedRow(value) {
|
|
10445
|
+
const row = isPlainObject2(value) ? value : {};
|
|
10446
|
+
const expanded = {
|
|
10447
|
+
projectId: String(row.projectId),
|
|
10448
|
+
objectTypeId: String(row.objectTypeId),
|
|
10449
|
+
primaryId: String(row.primaryId),
|
|
10450
|
+
properties: isPlainObject2(row.properties) ? row.properties : {},
|
|
10451
|
+
createdAt: new Date(row.createdAt),
|
|
10452
|
+
updatedAt: new Date(row.updatedAt),
|
|
10453
|
+
version: Number(row.version),
|
|
10454
|
+
lastCommitId: String(row.lastCommitId)
|
|
10455
|
+
};
|
|
10456
|
+
if (isPlainObject2(row.linkProperties) && Object.keys(row.linkProperties).length > 0) {
|
|
10457
|
+
expanded.linkProperties = row.linkProperties;
|
|
10088
10458
|
}
|
|
10089
|
-
|
|
10459
|
+
const links = reviveExpandedLinks(row.links);
|
|
10460
|
+
if (links)
|
|
10461
|
+
expanded.links = links;
|
|
10462
|
+
return expanded;
|
|
10463
|
+
}
|
|
10464
|
+
function isPlainObject2(value) {
|
|
10465
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10466
|
+
}
|
|
10467
|
+
|
|
10468
|
+
// src/objects/reader.ts
|
|
10469
|
+
class SqliteObjectReader {
|
|
10470
|
+
db;
|
|
10471
|
+
source;
|
|
10472
|
+
constructor(db, source) {
|
|
10473
|
+
this.db = db;
|
|
10474
|
+
this.source = source;
|
|
10475
|
+
}
|
|
10476
|
+
queryObjects(params) {
|
|
10477
|
+
const source = this.source;
|
|
10090
10478
|
const compiled = compileObjectQuery(params.projectId, params.query, {
|
|
10091
|
-
includeTotal: params.includeTotal
|
|
10479
|
+
includeTotal: params.includeTotal,
|
|
10480
|
+
source
|
|
10092
10481
|
});
|
|
10093
10482
|
const total = params.includeTotal === false ? undefined : readTotal(this.db, compiled);
|
|
10094
10483
|
const rawRows = this.db.query(compiled.sql).all(...compiled.args);
|
|
10095
10484
|
const rows = compiled.trimRows(rawRows);
|
|
10096
10485
|
const hasMore = total === undefined && compiled.hasMoreProbe ? compiled.hasMoreProbe.hasMore(this.db.query(compiled.hasMoreProbe.sql).all(...compiled.hasMoreProbe.args).length) : compiled.hasMore(rawRows.length, total);
|
|
10097
10486
|
return {
|
|
10098
|
-
objects: rows.map((row) =>
|
|
10487
|
+
objects: rows.map((row) => queryRowToObject(row)),
|
|
10099
10488
|
hasMore,
|
|
10100
10489
|
nextPageToken: compiled.nextPageToken(rows, rawRows.length),
|
|
10101
10490
|
...total === undefined ? {} : { total }
|
|
10102
10491
|
};
|
|
10103
10492
|
}
|
|
10104
|
-
|
|
10493
|
+
countObjects(params) {
|
|
10494
|
+
const source = this.source;
|
|
10105
10495
|
return {
|
|
10106
|
-
count: readTotal(this.db, compileObjectQuery(params.projectId, stripOuterRowShape(params.query)
|
|
10496
|
+
count: readTotal(this.db, compileObjectQuery(params.projectId, stripOuterRowShape(params.query), {
|
|
10497
|
+
source
|
|
10498
|
+
}))
|
|
10107
10499
|
};
|
|
10108
10500
|
}
|
|
10109
|
-
|
|
10110
|
-
const
|
|
10501
|
+
existsObjects(params) {
|
|
10502
|
+
const source = this.source;
|
|
10503
|
+
const compiled = compileObjectQuery(params.projectId, existsProbeQuery(params.query), {
|
|
10504
|
+
source
|
|
10505
|
+
});
|
|
10111
10506
|
return { exists: this.db.query(compiled.sql).get(...compiled.args) !== null };
|
|
10112
10507
|
}
|
|
10113
|
-
|
|
10114
|
-
const
|
|
10508
|
+
facetObjects(params) {
|
|
10509
|
+
const source = this.source;
|
|
10510
|
+
const compiled = compileObjectQuery(params.projectId, stripOuterRowShape(params.query), {
|
|
10511
|
+
source
|
|
10512
|
+
});
|
|
10115
10513
|
return {
|
|
10116
10514
|
facets: params.facets.map((facet) => ({
|
|
10117
10515
|
propertyId: facet.propertyId,
|
|
@@ -10119,14 +10517,43 @@ class SqliteObjectStorage {
|
|
|
10119
10517
|
}))
|
|
10120
10518
|
};
|
|
10121
10519
|
}
|
|
10122
|
-
|
|
10123
|
-
const
|
|
10124
|
-
|
|
10520
|
+
getByPrimaryId(params) {
|
|
10521
|
+
const source = this.source;
|
|
10522
|
+
const objectsTable = source.objectsTable;
|
|
10523
|
+
const statement = source.wrapStatement(`SELECT * FROM ${objectsTable} WHERE project_id = ? AND object_type_id = ? AND primary_id = ?`, [params.projectId, params.objectTypeId, params.primaryId]);
|
|
10524
|
+
const row = this.db.query(statement.sql).get(...statement.args);
|
|
10525
|
+
return row ? rowToObject(row) : null;
|
|
10125
10526
|
}
|
|
10126
|
-
|
|
10527
|
+
selectsObjectProperties(params) {
|
|
10528
|
+
const source = this.source;
|
|
10529
|
+
const result = params.items.map(() => false);
|
|
10530
|
+
if (params.items.length === 0)
|
|
10531
|
+
return result;
|
|
10532
|
+
const items = params.items.map((item, batchIndex) => ({ ...item, batchIndex }));
|
|
10533
|
+
const requestedType = "CAST(json_extract(requested.value, '$.objectTypeId') AS TEXT)";
|
|
10534
|
+
const requestedId = "CAST(json_extract(requested.value, '$.primaryId') AS TEXT)";
|
|
10535
|
+
const requestedProperty = "CAST(json_extract(requested.value, '$.propertyId') AS TEXT)";
|
|
10536
|
+
const selected = "objectPropertyPermissionsTable" in source;
|
|
10537
|
+
const storedTable = selected ? source.objectPropertyPermissionsTable : source.objectsTable;
|
|
10538
|
+
const propertyJoin = selected ? `AND stored.property_id = ${requestedProperty}` : "";
|
|
10539
|
+
const statement = source.wrapStatement(`SELECT DISTINCT
|
|
10540
|
+
CAST(json_extract(requested.value, '$.batchIndex') AS INTEGER) AS _batch_index
|
|
10541
|
+
FROM ${storedTable} AS stored
|
|
10542
|
+
JOIN json_each(?) AS requested
|
|
10543
|
+
ON stored.object_type_id = ${requestedType}
|
|
10544
|
+
AND stored.primary_id = ${requestedId}
|
|
10545
|
+
${propertyJoin}
|
|
10546
|
+
WHERE stored.project_id = ?`, [JSON.stringify(items), params.projectId]);
|
|
10547
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10548
|
+
for (const row of rows)
|
|
10549
|
+
result[row._batch_index] = true;
|
|
10550
|
+
return result;
|
|
10551
|
+
}
|
|
10552
|
+
listLinks(params) {
|
|
10553
|
+
const source = this.source;
|
|
10127
10554
|
const direction = params.direction ?? "outgoing";
|
|
10128
10555
|
const directionWhere = direction === "incoming" ? "target_type_id = ? AND target_id = ?" : direction === "both" ? "((source_type_id = ? AND source_id = ?) OR (target_type_id = ? AND target_id = ?))" : "source_type_id = ? AND source_id = ?";
|
|
10129
|
-
let query = `SELECT * FROM
|
|
10556
|
+
let query = `SELECT * FROM ${source.linksTable} WHERE project_id = ? AND ${directionWhere}`;
|
|
10130
10557
|
const args = direction === "both" ? [
|
|
10131
10558
|
params.projectId,
|
|
10132
10559
|
params.objectTypeId,
|
|
@@ -10138,64 +10565,104 @@ class SqliteObjectStorage {
|
|
|
10138
10565
|
query += " AND link_id = ?";
|
|
10139
10566
|
args.push(params.linkId);
|
|
10140
10567
|
}
|
|
10141
|
-
const
|
|
10142
|
-
|
|
10568
|
+
const statement = source.wrapStatement(query, args);
|
|
10569
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10570
|
+
return rows.map((row) => rowToLink(row));
|
|
10143
10571
|
}
|
|
10144
|
-
|
|
10572
|
+
getByPrimaryIdBatch(params) {
|
|
10573
|
+
const source = this.source;
|
|
10145
10574
|
const result = new Map;
|
|
10146
10575
|
if (params.items.length === 0)
|
|
10147
10576
|
return result;
|
|
10148
|
-
const
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10577
|
+
const items = params.items.map((item, batchIndex) => ({ ...item, batchIndex }));
|
|
10578
|
+
const statement = source.wrapStatement(`
|
|
10579
|
+
SELECT
|
|
10580
|
+
object.*,
|
|
10581
|
+
CAST(json_extract(requested.value, '$.batchIndex') AS INTEGER) AS _batch_index
|
|
10582
|
+
FROM json_each(?) AS requested
|
|
10583
|
+
JOIN ${source.objectsTable} AS object
|
|
10584
|
+
ON object.project_id = ?
|
|
10585
|
+
AND object.object_type_id = json_extract(requested.value, '$.objectTypeId')
|
|
10586
|
+
AND object.primary_id = json_extract(requested.value, '$.primaryId')
|
|
10587
|
+
`, [JSON.stringify(items), params.projectId]);
|
|
10588
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10589
|
+
const rowsByIndex = new Map(rows.map((row) => [row._batch_index, row]));
|
|
10590
|
+
for (const [index, item] of params.items.entries()) {
|
|
10591
|
+
const row = rowsByIndex.get(index);
|
|
10592
|
+
if (row)
|
|
10593
|
+
result.set(objectBatchKey(item.objectTypeId, item.primaryId), rowToObject(row));
|
|
10158
10594
|
}
|
|
10159
10595
|
return result;
|
|
10160
10596
|
}
|
|
10161
|
-
|
|
10597
|
+
listLinksBatch(params) {
|
|
10598
|
+
const source = this.source;
|
|
10162
10599
|
const result = new Map;
|
|
10163
10600
|
if (params.items.length === 0)
|
|
10164
10601
|
return result;
|
|
10165
|
-
const
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10602
|
+
const direction = params.direction ?? "outgoing";
|
|
10603
|
+
const requestedType = "CAST(json_extract(requested.value, '$.objectTypeId') AS TEXT)";
|
|
10604
|
+
const requestedId = "CAST(json_extract(requested.value, '$.objectId') AS TEXT)";
|
|
10605
|
+
const requestedLink = "CAST(json_extract(requested.value, '$.linkId') AS TEXT)";
|
|
10606
|
+
const outgoing = `stored.source_type_id = ${requestedType} AND stored.source_id = ${requestedId}`;
|
|
10607
|
+
const incoming = `stored.target_type_id = ${requestedType} AND stored.target_id = ${requestedId}`;
|
|
10608
|
+
const directionJoin = direction === "both" ? `((${outgoing}) OR (${incoming}))` : direction === "incoming" ? incoming : outgoing;
|
|
10609
|
+
const items = params.items.map((item, batchIndex) => ({ ...item, batchIndex }));
|
|
10610
|
+
const statement = source.wrapStatement(`
|
|
10611
|
+
SELECT
|
|
10612
|
+
stored.*,
|
|
10613
|
+
CAST(json_extract(requested.value, '$.batchIndex') AS INTEGER) AS _batch_index
|
|
10614
|
+
FROM ${source.linksTable} AS stored
|
|
10615
|
+
JOIN json_each(?) AS requested
|
|
10616
|
+
ON ${directionJoin}
|
|
10617
|
+
AND stored.link_id = ${requestedLink}
|
|
10618
|
+
WHERE stored.project_id = ?
|
|
10619
|
+
ORDER BY _batch_index, source_type_id, source_id, link_id, target_type_id, target_id
|
|
10620
|
+
`, [JSON.stringify(items), params.projectId]);
|
|
10621
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10622
|
+
const rowsByIndex = params.items.map(() => new Map);
|
|
10623
|
+
for (const row of rows) {
|
|
10624
|
+
const link = rowToLink(row);
|
|
10625
|
+
rowsByIndex[row._batch_index]?.set(fullLinkIdentity(link), link);
|
|
10626
|
+
}
|
|
10627
|
+
for (const [index, item] of params.items.entries()) {
|
|
10628
|
+
const links = [...rowsByIndex[index]?.values() ?? []];
|
|
10629
|
+
if (links.length > 0) {
|
|
10630
|
+
result.set(linkBatchKey(item.objectTypeId, item.objectId, item.linkId), links);
|
|
10170
10631
|
}
|
|
10171
10632
|
}
|
|
10172
10633
|
return result;
|
|
10173
10634
|
}
|
|
10174
|
-
|
|
10175
|
-
|
|
10635
|
+
queryLinks(params) {
|
|
10636
|
+
const source = this.source;
|
|
10176
10637
|
if (params.objectRefs.length === 0 || params.endpointObjectTypeIds?.length === 0) {
|
|
10177
10638
|
return { links: [], hasMore: false };
|
|
10178
10639
|
}
|
|
10640
|
+
const requested = `
|
|
10641
|
+
SELECT DISTINCT
|
|
10642
|
+
json_extract(value, '$.objectTypeId') AS object_type_id,
|
|
10643
|
+
json_extract(value, '$.primaryId') AS object_id
|
|
10644
|
+
FROM json_each(?)
|
|
10645
|
+
`;
|
|
10646
|
+
const linksTable = source.linksTable;
|
|
10179
10647
|
const sourceJoin = `
|
|
10180
10648
|
SELECT link.*
|
|
10181
|
-
FROM
|
|
10182
|
-
JOIN requested
|
|
10649
|
+
FROM ${linksTable} AS link
|
|
10650
|
+
JOIN (${requested}) AS requested
|
|
10183
10651
|
ON requested.object_type_id = link.source_type_id
|
|
10184
10652
|
AND requested.object_id = link.source_id
|
|
10185
10653
|
WHERE link.project_id = ?
|
|
10186
10654
|
`;
|
|
10187
10655
|
const targetJoin = `
|
|
10188
10656
|
SELECT link.*
|
|
10189
|
-
FROM
|
|
10190
|
-
JOIN requested
|
|
10657
|
+
FROM ${linksTable} AS link
|
|
10658
|
+
JOIN (${requested}) AS requested
|
|
10191
10659
|
ON requested.object_type_id = link.target_type_id
|
|
10192
10660
|
AND requested.object_id = link.target_id
|
|
10193
10661
|
WHERE link.project_id = ?
|
|
10194
10662
|
`;
|
|
10195
10663
|
const incidentSql = params.direction === "outgoing" ? sourceJoin : params.direction === "incoming" ? targetJoin : `${sourceJoin} UNION ${targetJoin}`;
|
|
10196
|
-
const
|
|
10197
|
-
|
|
10198
|
-
args.push(params.projectId);
|
|
10664
|
+
const requestedJson = JSON.stringify(params.objectRefs);
|
|
10665
|
+
const args = params.direction === "both" ? [requestedJson, params.projectId, requestedJson, params.projectId] : [requestedJson, params.projectId];
|
|
10199
10666
|
const predicates = [];
|
|
10200
10667
|
if (params.linkId !== undefined) {
|
|
10201
10668
|
predicates.push("link_id = ?");
|
|
@@ -10212,69 +10679,22 @@ class SqliteObjectStorage {
|
|
|
10212
10679
|
}
|
|
10213
10680
|
args.push(params.limit + 1);
|
|
10214
10681
|
const whereSql = predicates.length > 0 ? `WHERE ${predicates.join(" AND ")}` : "";
|
|
10215
|
-
const
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
|
|
10221
|
-
|
|
10222
|
-
|
|
10223
|
-
FROM incident
|
|
10224
|
-
${whereSql}
|
|
10225
|
-
ORDER BY source_type_id, source_id, link_id, target_type_id, target_id
|
|
10226
|
-
LIMIT ?
|
|
10227
|
-
`).all(...args);
|
|
10682
|
+
const statement = source.wrapStatement(`
|
|
10683
|
+
SELECT *
|
|
10684
|
+
FROM (${incidentSql}) AS incident
|
|
10685
|
+
${whereSql}
|
|
10686
|
+
ORDER BY source_type_id, source_id, link_id, target_type_id, target_id
|
|
10687
|
+
LIMIT ?
|
|
10688
|
+
`, args);
|
|
10689
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10228
10690
|
return {
|
|
10229
|
-
links: rows.slice(0, params.limit).map((row) =>
|
|
10691
|
+
links: rows.slice(0, params.limit).map((row) => rowToLink(row)),
|
|
10230
10692
|
hasMore: rows.length > params.limit
|
|
10231
10693
|
};
|
|
10232
10694
|
}
|
|
10233
|
-
|
|
10234
|
-
|
|
10235
|
-
|
|
10236
|
-
const rows = this.db.query(`
|
|
10237
|
-
WITH requested AS (
|
|
10238
|
-
SELECT
|
|
10239
|
-
json_extract(value, '$.objectTypeId') AS object_type_id,
|
|
10240
|
-
json_extract(value, '$.objectId') AS object_id
|
|
10241
|
-
FROM json_each(?)
|
|
10242
|
-
)
|
|
10243
|
-
SELECT link.*
|
|
10244
|
-
FROM links AS link
|
|
10245
|
-
JOIN requested
|
|
10246
|
-
ON requested.object_type_id = link.source_type_id
|
|
10247
|
-
AND requested.object_id = link.source_id
|
|
10248
|
-
WHERE link.project_id = ?
|
|
10249
|
-
UNION
|
|
10250
|
-
SELECT link.*
|
|
10251
|
-
FROM links AS link
|
|
10252
|
-
JOIN requested
|
|
10253
|
-
ON requested.object_type_id = link.target_type_id
|
|
10254
|
-
AND requested.object_id = link.target_id
|
|
10255
|
-
WHERE link.project_id = ?
|
|
10256
|
-
`).all(JSON.stringify(params.items), params.projectId, params.projectId);
|
|
10257
|
-
return rows.map((row) => this.rowToLink(row));
|
|
10258
|
-
}
|
|
10259
|
-
async listByPrimaryIdPage(params) {
|
|
10260
|
-
assertReconciliationPageLimit(params.limit);
|
|
10261
|
-
const rows = this.db.query(`
|
|
10262
|
-
SELECT * FROM objects
|
|
10263
|
-
WHERE project_id = ? AND object_type_id = ?
|
|
10264
|
-
AND (? IS NULL OR primary_id > ?)
|
|
10265
|
-
ORDER BY primary_id ASC
|
|
10266
|
-
LIMIT ?
|
|
10267
|
-
`).all(params.projectId, params.objectTypeId, params.afterPrimaryId ?? null, params.afterPrimaryId ?? null, params.limit + 1);
|
|
10268
|
-
const hasMore = rows.length > params.limit;
|
|
10269
|
-
const objects = rows.slice(0, params.limit).map((row) => this.rowToObject(row));
|
|
10270
|
-
const last = objects.at(-1);
|
|
10271
|
-
return {
|
|
10272
|
-
objects,
|
|
10273
|
-
...hasMore && last ? { nextPrimaryId: last.primaryId } : {}
|
|
10274
|
-
};
|
|
10275
|
-
}
|
|
10276
|
-
async list(params) {
|
|
10277
|
-
let query = "SELECT * FROM objects WHERE project_id = ?";
|
|
10695
|
+
list(params) {
|
|
10696
|
+
const source = this.source;
|
|
10697
|
+
let query = `SELECT * FROM ${source.objectsTable} WHERE project_id = ?`;
|
|
10278
10698
|
const args = [params.projectId];
|
|
10279
10699
|
if (params.objectTypeId) {
|
|
10280
10700
|
if (typeof params.objectTypeId === "string") {
|
|
@@ -10309,7 +10729,8 @@ class SqliteObjectStorage {
|
|
|
10309
10729
|
query += " AND created_at <= ?";
|
|
10310
10730
|
args.push(params.createdBefore.toISOString());
|
|
10311
10731
|
}
|
|
10312
|
-
const
|
|
10732
|
+
const countStatement = source.wrapStatement(`SELECT COUNT(*) as total FROM (${query}) AS filtered_objects`, args);
|
|
10733
|
+
const countResult = this.db.query(countStatement.sql).get(...countStatement.args);
|
|
10313
10734
|
const total = countResult.total;
|
|
10314
10735
|
const offset = params.offset ?? 0;
|
|
10315
10736
|
const limit = params.limit ?? 50;
|
|
@@ -10321,42 +10742,605 @@ class SqliteObjectStorage {
|
|
|
10321
10742
|
query += ` ORDER BY ${orderColumn} ${order.toUpperCase()}`;
|
|
10322
10743
|
query += " LIMIT ? OFFSET ?";
|
|
10323
10744
|
args.push(limit + 1, offset);
|
|
10324
|
-
const
|
|
10745
|
+
const rowsStatement = source.wrapStatement(query, args);
|
|
10746
|
+
const rows = this.db.query(rowsStatement.sql).all(...rowsStatement.args);
|
|
10325
10747
|
const hasMore = rows.length > limit;
|
|
10326
|
-
const objects = rows.slice(0, limit).map((row) =>
|
|
10748
|
+
const objects = rows.slice(0, limit).map((row) => rowToObject(row));
|
|
10327
10749
|
return { objects, hasMore, total };
|
|
10328
10750
|
}
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10751
|
+
}
|
|
10752
|
+
function fullLinkIdentity(link) {
|
|
10753
|
+
return JSON.stringify([
|
|
10754
|
+
link.sourceTypeId,
|
|
10755
|
+
link.sourceId,
|
|
10756
|
+
link.linkId,
|
|
10757
|
+
link.targetTypeId,
|
|
10758
|
+
link.targetId
|
|
10759
|
+
]);
|
|
10760
|
+
}
|
|
10761
|
+
function assertLinkQueryLimit(limit) {
|
|
10762
|
+
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
10763
|
+
throw new Error("Object link query limit must be a positive safe integer.");
|
|
10764
|
+
}
|
|
10765
|
+
}
|
|
10766
|
+
function readTotal(db, compiled) {
|
|
10767
|
+
const row = db.query(compiled.totalSql).get(...compiled.totalArgs);
|
|
10768
|
+
return row.total;
|
|
10769
|
+
}
|
|
10770
|
+
function readFacetBuckets(db, compiled, facet) {
|
|
10771
|
+
const path = sqliteJsonPath(facet.propertyId);
|
|
10772
|
+
const rows = db.query(`
|
|
10773
|
+
SELECT
|
|
10774
|
+
json_type(input.properties, ?) AS value_type,
|
|
10775
|
+
json_extract(input.properties, ?) AS value,
|
|
10776
|
+
COUNT(*) AS count
|
|
10777
|
+
FROM (${compiled.sql}) AS input
|
|
10778
|
+
WHERE json_type(input.properties, ?) IS NOT NULL
|
|
10779
|
+
GROUP BY value_type, value
|
|
10780
|
+
ORDER BY count DESC, CAST(value AS TEXT) ASC
|
|
10781
|
+
LIMIT ?
|
|
10782
|
+
`).all(path, path, ...compiled.args, path, facet.limit);
|
|
10783
|
+
return rows.map((row) => ({
|
|
10784
|
+
value: sqliteFacetValue(row.value_type, row.value),
|
|
10785
|
+
count: Number(row.count)
|
|
10786
|
+
}));
|
|
10787
|
+
}
|
|
10788
|
+
function sqliteJsonPath(propertyId) {
|
|
10789
|
+
return `$."${propertyId.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
10790
|
+
}
|
|
10791
|
+
function sqliteFacetValue(valueType, value) {
|
|
10792
|
+
if (valueType === "true")
|
|
10793
|
+
return true;
|
|
10794
|
+
if (valueType === "false")
|
|
10795
|
+
return false;
|
|
10796
|
+
if (valueType === "null")
|
|
10797
|
+
return null;
|
|
10798
|
+
return value;
|
|
10799
|
+
}
|
|
10800
|
+
function existsProbeQuery(query) {
|
|
10801
|
+
return { kind: "limit", limit: 1, input: stripOuterRowShape(query) };
|
|
10802
|
+
}
|
|
10803
|
+
function stripOuterRowShape(query) {
|
|
10804
|
+
switch (query.kind) {
|
|
10805
|
+
case "limit":
|
|
10806
|
+
case "page":
|
|
10807
|
+
case "project":
|
|
10808
|
+
case "sort":
|
|
10809
|
+
return stripOuterRowShape(query.input);
|
|
10810
|
+
default:
|
|
10811
|
+
return query;
|
|
10812
|
+
}
|
|
10813
|
+
}
|
|
10814
|
+
|
|
10815
|
+
// src/objects/selected-reader.ts
|
|
10816
|
+
import {
|
|
10817
|
+
assertObjectReaderProject,
|
|
10818
|
+
assertObjectReadFacetCount,
|
|
10819
|
+
assertObjectReadOutputWithinLimit,
|
|
10820
|
+
ObjectReadLimitExceededError,
|
|
10821
|
+
snapshotObjectReadExecutionLimits
|
|
10822
|
+
} from "@sixb/core/storage";
|
|
10823
|
+
|
|
10824
|
+
// src/objects/read-scope.ts
|
|
10825
|
+
function compileSqliteSelectedObjectReadSource(projectId, scope, maxTraversalFacts) {
|
|
10826
|
+
const scopeJson = JSON.stringify({
|
|
10827
|
+
roots: scope.roots,
|
|
10828
|
+
objects: scope.objects,
|
|
10829
|
+
steps: scope.steps
|
|
10830
|
+
});
|
|
10831
|
+
const compiled = compileSelectedReadScopeCte(scopeJson, projectId);
|
|
10832
|
+
const wrapStatement = (sql, args = []) => ({
|
|
10833
|
+
sql: `${compiled.sql}
|
|
10834
|
+
${sql}`,
|
|
10835
|
+
args: [...compiled.args, ...args]
|
|
10836
|
+
});
|
|
10837
|
+
return Object.freeze({
|
|
10838
|
+
objectsTable: "_sixb_scope_objects",
|
|
10839
|
+
linksTable: "_sixb_scope_links",
|
|
10840
|
+
objectPropertyPermissionsTable: "_sixb_scope_object_permissions",
|
|
10841
|
+
wrapStatement,
|
|
10842
|
+
wrapQuery: (query) => ({
|
|
10843
|
+
...query,
|
|
10844
|
+
...wrapStatement(query.sql, query.args),
|
|
10845
|
+
totalSql: `${compiled.sql}
|
|
10846
|
+
${query.totalSql}`,
|
|
10847
|
+
totalArgs: [...compiled.args, ...query.totalArgs],
|
|
10848
|
+
...query.hasMoreProbe ? {
|
|
10849
|
+
hasMoreProbe: {
|
|
10850
|
+
...query.hasMoreProbe,
|
|
10851
|
+
...wrapStatement(query.hasMoreProbe.sql, query.hasMoreProbe.args)
|
|
10852
|
+
}
|
|
10853
|
+
} : {}
|
|
10854
|
+
}),
|
|
10855
|
+
traversalProbe: wrapStatement(`
|
|
10856
|
+
SELECT COUNT(*) AS total
|
|
10857
|
+
FROM (
|
|
10858
|
+
SELECT 1 AS traversal_fact
|
|
10859
|
+
FROM _sixb_scope_root_facts
|
|
10860
|
+
|
|
10861
|
+
UNION ALL
|
|
10862
|
+
|
|
10863
|
+
SELECT 1 AS traversal_fact
|
|
10864
|
+
FROM _sixb_scope_reached_links
|
|
10865
|
+
|
|
10866
|
+
LIMIT ?
|
|
10867
|
+
) AS bounded_traversal_facts
|
|
10868
|
+
`, [BigInt(maxTraversalFacts) + 1n])
|
|
10869
|
+
});
|
|
10870
|
+
}
|
|
10871
|
+
function compileSelectedReadScopeCte(scopeJson, projectId) {
|
|
10872
|
+
return {
|
|
10873
|
+
sql: `
|
|
10874
|
+
WITH RECURSIVE
|
|
10875
|
+
_sixb_scope_document(scope) AS (
|
|
10876
|
+
SELECT json(?)
|
|
10877
|
+
),
|
|
10878
|
+
_sixb_scope_roots(root_id, node_id, object_type_id, primary_id) AS (
|
|
10879
|
+
SELECT
|
|
10880
|
+
CAST(root.key AS INTEGER),
|
|
10881
|
+
CAST(json_extract(root.value, '$.nodeId') AS INTEGER),
|
|
10882
|
+
CAST(json_extract(root.value, '$.objectTypeId') AS TEXT),
|
|
10883
|
+
CAST(json_extract(root.value, '$.primaryId') AS TEXT)
|
|
10884
|
+
FROM _sixb_scope_document AS document,
|
|
10885
|
+
json_each(json_extract(document.scope, '$.roots')) AS root
|
|
10886
|
+
),
|
|
10887
|
+
_sixb_scope_root_facts(project_id, root_id, node_id, object_type_id, primary_id) AS (
|
|
10888
|
+
SELECT anchor.project_id, root.root_id, root.node_id, root.object_type_id, root.primary_id
|
|
10889
|
+
FROM _sixb_scope_roots AS root
|
|
10890
|
+
JOIN objects AS anchor
|
|
10891
|
+
ON anchor.project_id = ?
|
|
10892
|
+
AND anchor.object_type_id = root.object_type_id
|
|
10893
|
+
AND anchor.primary_id = root.primary_id
|
|
10894
|
+
),
|
|
10895
|
+
_sixb_scope_object_selections(node_id, object_type_id, property_ids) AS (
|
|
10896
|
+
SELECT
|
|
10897
|
+
CAST(json_extract(selection.value, '$.nodeId') AS INTEGER),
|
|
10898
|
+
CAST(json_extract(selection.value, '$.objectTypeId') AS TEXT),
|
|
10899
|
+
json_extract(selection.value, '$.propertyIds')
|
|
10900
|
+
FROM _sixb_scope_document AS document,
|
|
10901
|
+
json_each(json_extract(document.scope, '$.objects')) AS selection
|
|
10902
|
+
),
|
|
10903
|
+
_sixb_scope_link_selections(
|
|
10904
|
+
step_id,
|
|
10905
|
+
node_id,
|
|
10906
|
+
parent_node_id,
|
|
10907
|
+
source_object_type_id,
|
|
10908
|
+
link_id,
|
|
10909
|
+
target_object_type_id,
|
|
10910
|
+
property_ids
|
|
10911
|
+
) AS (
|
|
10912
|
+
SELECT
|
|
10913
|
+
CAST(step.key AS INTEGER),
|
|
10914
|
+
CAST(json_extract(step.value, '$.nodeId') AS INTEGER),
|
|
10915
|
+
CAST(json_extract(step.value, '$.parentNodeId') AS INTEGER),
|
|
10916
|
+
CAST(json_extract(step.value, '$.sourceObjectTypeId') AS TEXT),
|
|
10917
|
+
CAST(json_extract(step.value, '$.linkId') AS TEXT),
|
|
10918
|
+
CAST(json_extract(step.value, '$.targetObjectTypeId') AS TEXT),
|
|
10919
|
+
json_extract(step.value, '$.propertyIds')
|
|
10920
|
+
FROM _sixb_scope_document AS document,
|
|
10921
|
+
json_each(json_extract(document.scope, '$.steps')) AS step
|
|
10922
|
+
),
|
|
10923
|
+
_sixb_scope_reachable(project_id, node_id, object_type_id, primary_id) AS (
|
|
10924
|
+
SELECT root.project_id, root.node_id, root.object_type_id, root.primary_id
|
|
10925
|
+
FROM _sixb_scope_root_facts AS root
|
|
10926
|
+
|
|
10927
|
+
UNION
|
|
10928
|
+
|
|
10929
|
+
SELECT edge.project_id, selection.node_id, edge.target_type_id, edge.target_id
|
|
10930
|
+
FROM _sixb_scope_reachable AS parent
|
|
10931
|
+
JOIN _sixb_scope_link_selections AS selection
|
|
10932
|
+
ON selection.parent_node_id = parent.node_id
|
|
10933
|
+
AND selection.source_object_type_id = parent.object_type_id
|
|
10934
|
+
JOIN links AS edge
|
|
10935
|
+
ON edge.project_id = parent.project_id
|
|
10936
|
+
AND edge.source_type_id = parent.object_type_id
|
|
10937
|
+
AND edge.source_id = parent.primary_id
|
|
10938
|
+
AND edge.link_id = selection.link_id
|
|
10939
|
+
AND edge.target_type_id = selection.target_object_type_id
|
|
10940
|
+
JOIN objects AS target
|
|
10941
|
+
ON target.project_id = edge.project_id
|
|
10942
|
+
AND target.object_type_id = edge.target_type_id
|
|
10943
|
+
AND target.primary_id = edge.target_id
|
|
10944
|
+
),
|
|
10945
|
+
_sixb_scope_object_permissions(project_id, object_type_id, primary_id, property_id) AS (
|
|
10946
|
+
SELECT DISTINCT
|
|
10947
|
+
reachable.project_id,
|
|
10948
|
+
reachable.object_type_id,
|
|
10949
|
+
reachable.primary_id,
|
|
10950
|
+
CAST(selected_property.value AS TEXT)
|
|
10951
|
+
FROM _sixb_scope_reachable AS reachable
|
|
10952
|
+
JOIN _sixb_scope_object_selections AS selection
|
|
10953
|
+
ON selection.node_id = reachable.node_id
|
|
10954
|
+
AND selection.object_type_id = reachable.object_type_id
|
|
10955
|
+
JOIN json_each(selection.property_ids) AS selected_property
|
|
10956
|
+
),
|
|
10957
|
+
_sixb_scope_object_ids(project_id, object_type_id, primary_id) AS (
|
|
10958
|
+
SELECT DISTINCT project_id, object_type_id, primary_id
|
|
10959
|
+
FROM _sixb_scope_reachable
|
|
10960
|
+
),
|
|
10961
|
+
_sixb_scope_objects AS (
|
|
10962
|
+
SELECT
|
|
10963
|
+
stored.project_id,
|
|
10964
|
+
stored.object_type_id,
|
|
10965
|
+
stored.primary_id,
|
|
10966
|
+
COALESCE(
|
|
10967
|
+
(
|
|
10968
|
+
SELECT json_group_object(property.key, ${sqliteJsonEachValue("property")})
|
|
10969
|
+
FROM json_each(stored.properties) AS property
|
|
10970
|
+
JOIN _sixb_scope_object_permissions AS permission
|
|
10971
|
+
ON permission.project_id = stored.project_id
|
|
10972
|
+
AND permission.object_type_id = stored.object_type_id
|
|
10973
|
+
AND permission.primary_id = stored.primary_id
|
|
10974
|
+
AND permission.property_id = property.key
|
|
10975
|
+
),
|
|
10976
|
+
json('{}')
|
|
10977
|
+
) AS properties,
|
|
10978
|
+
stored.created_at,
|
|
10979
|
+
stored.updated_at,
|
|
10980
|
+
stored.version,
|
|
10981
|
+
stored.last_commit_id
|
|
10982
|
+
FROM objects AS stored
|
|
10983
|
+
JOIN _sixb_scope_object_ids AS visible
|
|
10984
|
+
ON visible.project_id = stored.project_id
|
|
10985
|
+
AND visible.object_type_id = stored.object_type_id
|
|
10986
|
+
AND visible.primary_id = stored.primary_id
|
|
10987
|
+
),
|
|
10988
|
+
_sixb_scope_reached_links(
|
|
10989
|
+
project_id,
|
|
10990
|
+
step_id,
|
|
10991
|
+
node_id,
|
|
10992
|
+
parent_node_id,
|
|
10993
|
+
source_type_id,
|
|
10994
|
+
source_id,
|
|
10995
|
+
link_id,
|
|
10996
|
+
target_type_id,
|
|
10997
|
+
target_id,
|
|
10998
|
+
property_ids
|
|
10999
|
+
) AS (
|
|
11000
|
+
SELECT
|
|
11001
|
+
edge.project_id,
|
|
11002
|
+
selection.step_id,
|
|
11003
|
+
selection.node_id,
|
|
11004
|
+
selection.parent_node_id,
|
|
11005
|
+
edge.source_type_id,
|
|
11006
|
+
edge.source_id,
|
|
11007
|
+
edge.link_id,
|
|
11008
|
+
edge.target_type_id,
|
|
11009
|
+
edge.target_id,
|
|
11010
|
+
selection.property_ids
|
|
11011
|
+
FROM _sixb_scope_reachable AS parent
|
|
11012
|
+
JOIN _sixb_scope_link_selections AS selection
|
|
11013
|
+
ON selection.parent_node_id = parent.node_id
|
|
11014
|
+
AND selection.source_object_type_id = parent.object_type_id
|
|
11015
|
+
JOIN links AS edge
|
|
11016
|
+
ON edge.project_id = parent.project_id
|
|
11017
|
+
AND edge.source_type_id = parent.object_type_id
|
|
11018
|
+
AND edge.source_id = parent.primary_id
|
|
11019
|
+
AND edge.link_id = selection.link_id
|
|
11020
|
+
AND edge.target_type_id = selection.target_object_type_id
|
|
11021
|
+
JOIN objects AS target
|
|
11022
|
+
ON target.project_id = edge.project_id
|
|
11023
|
+
AND target.object_type_id = edge.target_type_id
|
|
11024
|
+
AND target.primary_id = edge.target_id
|
|
11025
|
+
),
|
|
11026
|
+
_sixb_scope_link_permissions(
|
|
11027
|
+
project_id,
|
|
11028
|
+
source_type_id,
|
|
11029
|
+
source_id,
|
|
11030
|
+
link_id,
|
|
11031
|
+
target_type_id,
|
|
11032
|
+
target_id,
|
|
11033
|
+
property_id
|
|
11034
|
+
) AS (
|
|
11035
|
+
SELECT DISTINCT
|
|
11036
|
+
reached.project_id,
|
|
11037
|
+
reached.source_type_id,
|
|
11038
|
+
reached.source_id,
|
|
11039
|
+
reached.link_id,
|
|
11040
|
+
reached.target_type_id,
|
|
11041
|
+
reached.target_id,
|
|
11042
|
+
CAST(selected_property.value AS TEXT)
|
|
11043
|
+
FROM _sixb_scope_reached_links AS reached
|
|
11044
|
+
JOIN json_each(reached.property_ids) AS selected_property
|
|
11045
|
+
),
|
|
11046
|
+
_sixb_scope_link_ids(
|
|
11047
|
+
project_id,
|
|
11048
|
+
source_type_id,
|
|
11049
|
+
source_id,
|
|
11050
|
+
link_id,
|
|
11051
|
+
target_type_id,
|
|
11052
|
+
target_id
|
|
11053
|
+
) AS (
|
|
11054
|
+
SELECT DISTINCT
|
|
11055
|
+
project_id,
|
|
11056
|
+
source_type_id,
|
|
11057
|
+
source_id,
|
|
11058
|
+
link_id,
|
|
11059
|
+
target_type_id,
|
|
11060
|
+
target_id
|
|
11061
|
+
FROM _sixb_scope_reached_links
|
|
11062
|
+
),
|
|
11063
|
+
_sixb_scope_links AS (
|
|
11064
|
+
SELECT
|
|
11065
|
+
stored.project_id,
|
|
11066
|
+
stored.source_type_id,
|
|
11067
|
+
stored.source_id,
|
|
11068
|
+
stored.link_id,
|
|
11069
|
+
stored.target_type_id,
|
|
11070
|
+
stored.target_id,
|
|
11071
|
+
CASE
|
|
11072
|
+
WHEN stored.properties IS NULL THEN NULL
|
|
11073
|
+
ELSE NULLIF(
|
|
11074
|
+
(
|
|
11075
|
+
SELECT json_group_object(property.key, ${sqliteJsonEachValue("property")})
|
|
11076
|
+
FROM json_each(stored.properties) AS property
|
|
11077
|
+
JOIN _sixb_scope_link_permissions AS permission
|
|
11078
|
+
ON permission.project_id = stored.project_id
|
|
11079
|
+
AND permission.source_type_id = stored.source_type_id
|
|
11080
|
+
AND permission.source_id = stored.source_id
|
|
11081
|
+
AND permission.link_id = stored.link_id
|
|
11082
|
+
AND permission.target_type_id = stored.target_type_id
|
|
11083
|
+
AND permission.target_id = stored.target_id
|
|
11084
|
+
AND permission.property_id = property.key
|
|
11085
|
+
),
|
|
11086
|
+
json('{}')
|
|
11087
|
+
)
|
|
11088
|
+
END AS properties,
|
|
11089
|
+
stored.created_at,
|
|
11090
|
+
stored.updated_at,
|
|
11091
|
+
stored.last_commit_id
|
|
11092
|
+
FROM links AS stored
|
|
11093
|
+
JOIN _sixb_scope_link_ids AS visible
|
|
11094
|
+
ON visible.project_id = stored.project_id
|
|
11095
|
+
AND visible.source_type_id = stored.source_type_id
|
|
11096
|
+
AND visible.source_id = stored.source_id
|
|
11097
|
+
AND visible.link_id = stored.link_id
|
|
11098
|
+
AND visible.target_type_id = stored.target_type_id
|
|
11099
|
+
AND visible.target_id = stored.target_id
|
|
11100
|
+
)
|
|
11101
|
+
`,
|
|
11102
|
+
args: [scopeJson, projectId]
|
|
11103
|
+
};
|
|
11104
|
+
}
|
|
11105
|
+
|
|
11106
|
+
// src/objects/selected-reader.ts
|
|
11107
|
+
function createSqliteSelectedReader(db, params, queryCapabilities) {
|
|
11108
|
+
const projectId = params.projectId;
|
|
11109
|
+
const limits = snapshotObjectReadExecutionLimits(params.limits);
|
|
11110
|
+
const source = compileSqliteSelectedObjectReadSource(projectId, params.scope, limits.maxTraversalFacts);
|
|
11111
|
+
const reader = new SqliteObjectReader(db, source);
|
|
11112
|
+
const assertProject = (actualProjectId) => assertObjectReaderProject(projectId, actualProjectId);
|
|
11113
|
+
const read = (run) => runDeferredReadTransaction(db, () => {
|
|
11114
|
+
assertTraversalBudget(db, source, limits.maxTraversalFacts);
|
|
11115
|
+
const value = run();
|
|
11116
|
+
assertObjectReadOutputWithinLimit(value, limits);
|
|
11117
|
+
return value;
|
|
11118
|
+
});
|
|
11119
|
+
const readMap = (run) => runDeferredReadTransaction(db, () => {
|
|
11120
|
+
assertTraversalBudget(db, source, limits.maxTraversalFacts);
|
|
11121
|
+
const value = run();
|
|
11122
|
+
assertObjectReadOutputWithinLimit([...value.entries()], limits);
|
|
11123
|
+
return value;
|
|
11124
|
+
});
|
|
11125
|
+
return Object.freeze({
|
|
11126
|
+
queryCapabilities,
|
|
11127
|
+
queryObjects: async (input) => {
|
|
11128
|
+
assertProject(input.projectId);
|
|
11129
|
+
return read(() => reader.queryObjects(input));
|
|
11130
|
+
},
|
|
11131
|
+
countObjects: async (input) => {
|
|
11132
|
+
assertProject(input.projectId);
|
|
11133
|
+
return read(() => reader.countObjects(input));
|
|
11134
|
+
},
|
|
11135
|
+
existsObjects: async (input) => {
|
|
11136
|
+
assertProject(input.projectId);
|
|
11137
|
+
return read(() => reader.existsObjects(input));
|
|
11138
|
+
},
|
|
11139
|
+
facetObjects: async (input) => {
|
|
11140
|
+
assertProject(input.projectId);
|
|
11141
|
+
assertObjectReadFacetCount(input.facets.length);
|
|
11142
|
+
return read(() => reader.facetObjects(input));
|
|
11143
|
+
},
|
|
11144
|
+
getByPrimaryId: async (input) => {
|
|
11145
|
+
assertProject(input.projectId);
|
|
11146
|
+
return read(() => reader.getByPrimaryId(input));
|
|
11147
|
+
},
|
|
11148
|
+
selectsObjectProperties: async (input) => {
|
|
11149
|
+
assertProject(input.projectId);
|
|
11150
|
+
return read(() => reader.selectsObjectProperties(input));
|
|
11151
|
+
},
|
|
11152
|
+
listLinks: async (input) => {
|
|
11153
|
+
assertProject(input.projectId);
|
|
11154
|
+
return read(() => reader.listLinks(input));
|
|
11155
|
+
},
|
|
11156
|
+
getByPrimaryIdBatch: async (input) => {
|
|
11157
|
+
assertProject(input.projectId);
|
|
11158
|
+
return readMap(() => reader.getByPrimaryIdBatch(input));
|
|
11159
|
+
},
|
|
11160
|
+
listLinksBatch: async (input) => {
|
|
11161
|
+
assertProject(input.projectId);
|
|
11162
|
+
return readMap(() => reader.listLinksBatch(input));
|
|
11163
|
+
},
|
|
11164
|
+
queryLinks: async (input) => {
|
|
11165
|
+
assertProject(input.projectId);
|
|
11166
|
+
assertLinkQueryLimit(input.limit);
|
|
11167
|
+
return read(() => reader.queryLinks(input));
|
|
11168
|
+
},
|
|
11169
|
+
list: async (input) => {
|
|
11170
|
+
assertProject(input.projectId);
|
|
11171
|
+
return read(() => reader.list(input));
|
|
11172
|
+
}
|
|
11173
|
+
});
|
|
11174
|
+
}
|
|
11175
|
+
function assertTraversalBudget(db, source, maxTraversalFacts) {
|
|
11176
|
+
const row = db.query(source.traversalProbe.sql).get(...source.traversalProbe.args);
|
|
11177
|
+
if (BigInt(row.total) > BigInt(maxTraversalFacts)) {
|
|
11178
|
+
throw new ObjectReadLimitExceededError("traversalFacts", maxTraversalFacts);
|
|
11179
|
+
}
|
|
11180
|
+
}
|
|
11181
|
+
|
|
11182
|
+
// src/objects/storage.ts
|
|
11183
|
+
var SQLITE_OBJECT_QUERY_CAPABILITIES = {
|
|
11184
|
+
queryObjects: true,
|
|
11185
|
+
countObjects: true,
|
|
11186
|
+
existsObjects: true,
|
|
11187
|
+
facetObjects: true,
|
|
11188
|
+
nodes: {
|
|
11189
|
+
start: true,
|
|
11190
|
+
refs: true,
|
|
11191
|
+
filter: true,
|
|
11192
|
+
text: true,
|
|
11193
|
+
sort: true,
|
|
11194
|
+
limit: true,
|
|
11195
|
+
page: true,
|
|
11196
|
+
traverse: true,
|
|
11197
|
+
set: true,
|
|
11198
|
+
project: true,
|
|
11199
|
+
expand: true
|
|
11200
|
+
},
|
|
11201
|
+
predicateOps: {
|
|
11202
|
+
and: true,
|
|
11203
|
+
or: true,
|
|
11204
|
+
not: true,
|
|
11205
|
+
eq: true,
|
|
11206
|
+
neq: true,
|
|
11207
|
+
lt: true,
|
|
11208
|
+
lte: true,
|
|
11209
|
+
gt: true,
|
|
11210
|
+
gte: true,
|
|
11211
|
+
in: true,
|
|
11212
|
+
exists: true,
|
|
11213
|
+
contains: true
|
|
11214
|
+
},
|
|
11215
|
+
sortKinds: {
|
|
11216
|
+
property: true
|
|
11217
|
+
},
|
|
11218
|
+
traversalDirections: {
|
|
11219
|
+
outgoing: true,
|
|
11220
|
+
incoming: true
|
|
11221
|
+
},
|
|
11222
|
+
setOps: {
|
|
11223
|
+
union: true,
|
|
11224
|
+
intersect: true,
|
|
11225
|
+
subtract: true
|
|
11226
|
+
},
|
|
11227
|
+
scalarOperations: {
|
|
11228
|
+
string: { equality: true, ordering: true },
|
|
11229
|
+
uuid: { equality: true, ordering: true },
|
|
11230
|
+
boolean: { equality: true },
|
|
11231
|
+
integer: { equality: true, ordering: true },
|
|
11232
|
+
double: { equality: true, ordering: true },
|
|
11233
|
+
decimal: { equality: true },
|
|
11234
|
+
date: { equality: true, ordering: true },
|
|
11235
|
+
timestamp: { equality: true, ordering: true }
|
|
11236
|
+
},
|
|
11237
|
+
limits: {
|
|
11238
|
+
totalCount: true,
|
|
11239
|
+
stablePageTokens: true
|
|
11240
|
+
},
|
|
11241
|
+
notes: [
|
|
11242
|
+
"SQLite object query pushdown supports start/refs/filter/text/sort/limit/page/traverse/set/project/expand over JSON properties and object links.",
|
|
11243
|
+
"expand hydrates linked objects in-database (top-N per parent via row_number() + json_group_array); core resolves each expansion's cardinality before pushdown, and a mixed/unresolved one stays on the fallback.",
|
|
11244
|
+
"Ordered decimal predicates and sorting use the bounded core fallback because SQLite has no native exact decimal type; canonical decimal equality remains pushdown-safe.",
|
|
11245
|
+
"Relevance sorting, vector search, and unresolved start.includeSubtypes remain planner fallback or rejection cases."
|
|
11246
|
+
]
|
|
11247
|
+
};
|
|
11248
|
+
|
|
11249
|
+
class SqliteObjectStorage {
|
|
11250
|
+
connection;
|
|
11251
|
+
db;
|
|
11252
|
+
reader;
|
|
11253
|
+
constructor(options = {}) {
|
|
11254
|
+
this.connection = openSqliteStoreConnection(options);
|
|
11255
|
+
this.db = this.connection.db;
|
|
11256
|
+
this.reader = new SqliteObjectReader(this.db, DEFAULT_OBJECT_QUERY_SOURCE);
|
|
11257
|
+
if (this.connection.installFreshSchema) {
|
|
11258
|
+
installFreshSqliteSchema(this.db);
|
|
11259
|
+
}
|
|
11260
|
+
}
|
|
11261
|
+
queryCapabilities() {
|
|
11262
|
+
return SQLITE_OBJECT_QUERY_CAPABILITIES;
|
|
11263
|
+
}
|
|
11264
|
+
createSelectedReadScope(params) {
|
|
11265
|
+
return createSqliteSelectedReader(this.db, params, () => this.queryCapabilities());
|
|
11266
|
+
}
|
|
11267
|
+
async queryObjects(params) {
|
|
11268
|
+
return this.reader.queryObjects(params);
|
|
11269
|
+
}
|
|
11270
|
+
async countObjects(params) {
|
|
11271
|
+
return this.reader.countObjects(params);
|
|
11272
|
+
}
|
|
11273
|
+
async existsObjects(params) {
|
|
11274
|
+
return this.reader.existsObjects(params);
|
|
11275
|
+
}
|
|
11276
|
+
async facetObjects(params) {
|
|
11277
|
+
return this.reader.facetObjects(params);
|
|
11278
|
+
}
|
|
11279
|
+
async getByPrimaryId(params) {
|
|
11280
|
+
return this.reader.getByPrimaryId(params);
|
|
11281
|
+
}
|
|
11282
|
+
async selectsObjectProperties(params) {
|
|
11283
|
+
return this.reader.selectsObjectProperties(params);
|
|
11284
|
+
}
|
|
11285
|
+
async listLinks(params) {
|
|
11286
|
+
return this.reader.listLinks(params);
|
|
11287
|
+
}
|
|
11288
|
+
async getByPrimaryIdBatch(params) {
|
|
11289
|
+
return this.reader.getByPrimaryIdBatch(params);
|
|
11290
|
+
}
|
|
11291
|
+
async listLinksBatch(params) {
|
|
11292
|
+
return this.reader.listLinksBatch(params);
|
|
11293
|
+
}
|
|
11294
|
+
async queryLinks(params) {
|
|
11295
|
+
assertLinkQueryLimit(params.limit);
|
|
11296
|
+
return this.reader.queryLinks(params);
|
|
10340
11297
|
}
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
11298
|
+
async listIncidentLinksBatch(params) {
|
|
11299
|
+
if (params.items.length === 0)
|
|
11300
|
+
return [];
|
|
11301
|
+
const rows = this.db.query(`
|
|
11302
|
+
WITH requested AS (
|
|
11303
|
+
SELECT
|
|
11304
|
+
json_extract(value, '$.objectTypeId') AS object_type_id,
|
|
11305
|
+
json_extract(value, '$.objectId') AS object_id
|
|
11306
|
+
FROM json_each(?)
|
|
11307
|
+
)
|
|
11308
|
+
SELECT link.*
|
|
11309
|
+
FROM links AS link
|
|
11310
|
+
JOIN requested
|
|
11311
|
+
ON requested.object_type_id = link.source_type_id
|
|
11312
|
+
AND requested.object_id = link.source_id
|
|
11313
|
+
WHERE link.project_id = ?
|
|
11314
|
+
UNION
|
|
11315
|
+
SELECT link.*
|
|
11316
|
+
FROM links AS link
|
|
11317
|
+
JOIN requested
|
|
11318
|
+
ON requested.object_type_id = link.target_type_id
|
|
11319
|
+
AND requested.object_id = link.target_id
|
|
11320
|
+
WHERE link.project_id = ?
|
|
11321
|
+
`).all(JSON.stringify(params.items), params.projectId, params.projectId);
|
|
11322
|
+
return rows.map((row) => rowToLink(row));
|
|
10345
11323
|
}
|
|
10346
|
-
|
|
11324
|
+
async listByPrimaryIdPage(params) {
|
|
11325
|
+
assertReconciliationPageLimit(params.limit);
|
|
11326
|
+
const rows = this.db.query(`
|
|
11327
|
+
SELECT * FROM objects
|
|
11328
|
+
WHERE project_id = ? AND object_type_id = ?
|
|
11329
|
+
AND (? IS NULL OR primary_id > ?)
|
|
11330
|
+
ORDER BY primary_id ASC
|
|
11331
|
+
LIMIT ?
|
|
11332
|
+
`).all(params.projectId, params.objectTypeId, params.afterPrimaryId ?? null, params.afterPrimaryId ?? null, params.limit + 1);
|
|
11333
|
+
const hasMore = rows.length > params.limit;
|
|
11334
|
+
const objects = rows.slice(0, params.limit).map((row) => rowToObject(row));
|
|
11335
|
+
const last = objects.at(-1);
|
|
10347
11336
|
return {
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
sourceId: row.source_id,
|
|
10351
|
-
linkId: row.link_id,
|
|
10352
|
-
targetTypeId: row.target_type_id,
|
|
10353
|
-
targetId: row.target_id,
|
|
10354
|
-
properties: row.properties ? JSON.parse(row.properties) : undefined,
|
|
10355
|
-
createdAt: new Date(row.created_at),
|
|
10356
|
-
updatedAt: new Date(row.updated_at),
|
|
10357
|
-
lastCommitId: row.last_commit_id
|
|
11337
|
+
objects,
|
|
11338
|
+
...hasMore && last ? { nextPrimaryId: last.primaryId } : {}
|
|
10358
11339
|
};
|
|
10359
11340
|
}
|
|
11341
|
+
async list(params) {
|
|
11342
|
+
return this.reader.list(params);
|
|
11343
|
+
}
|
|
10360
11344
|
close() {
|
|
10361
11345
|
closeSqliteStoreConnection(this.connection);
|
|
10362
11346
|
}
|
|
@@ -10366,104 +11350,6 @@ function assertReconciliationPageLimit(limit) {
|
|
|
10366
11350
|
throw new Error("Object reconciliation page limit must be a positive safe integer.");
|
|
10367
11351
|
}
|
|
10368
11352
|
}
|
|
10369
|
-
function assertLinkQueryLimit(limit) {
|
|
10370
|
-
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
10371
|
-
throw new Error("Object link query limit must be a positive safe integer.");
|
|
10372
|
-
}
|
|
10373
|
-
}
|
|
10374
|
-
function readTotal(db, compiled) {
|
|
10375
|
-
const row = db.query(compiled.totalSql).get(...compiled.totalArgs);
|
|
10376
|
-
return row.total;
|
|
10377
|
-
}
|
|
10378
|
-
function readFacetBuckets(db, compiled, facet) {
|
|
10379
|
-
const path = sqliteJsonPath(facet.propertyId);
|
|
10380
|
-
const rows = db.query(`
|
|
10381
|
-
SELECT
|
|
10382
|
-
json_type(input.properties, ?) AS value_type,
|
|
10383
|
-
json_extract(input.properties, ?) AS value,
|
|
10384
|
-
COUNT(*) AS count
|
|
10385
|
-
FROM (${compiled.sql}) AS input
|
|
10386
|
-
WHERE json_type(input.properties, ?) IS NOT NULL
|
|
10387
|
-
GROUP BY value_type, value
|
|
10388
|
-
ORDER BY count DESC, CAST(value AS TEXT) ASC
|
|
10389
|
-
LIMIT ?
|
|
10390
|
-
`).all(path, path, ...compiled.args, path, facet.limit);
|
|
10391
|
-
return rows.map((row) => ({
|
|
10392
|
-
value: sqliteFacetValue(row.value_type, row.value),
|
|
10393
|
-
count: Number(row.count)
|
|
10394
|
-
}));
|
|
10395
|
-
}
|
|
10396
|
-
function sqliteJsonPath(propertyId) {
|
|
10397
|
-
return `$."${propertyId.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
10398
|
-
}
|
|
10399
|
-
function sqliteFacetValue(valueType, value) {
|
|
10400
|
-
if (valueType === "true")
|
|
10401
|
-
return true;
|
|
10402
|
-
if (valueType === "false")
|
|
10403
|
-
return false;
|
|
10404
|
-
if (valueType === "null")
|
|
10405
|
-
return null;
|
|
10406
|
-
return value;
|
|
10407
|
-
}
|
|
10408
|
-
function parseExpandColumn(value) {
|
|
10409
|
-
if (typeof value !== "string")
|
|
10410
|
-
return value ?? undefined;
|
|
10411
|
-
return JSON.parse(value);
|
|
10412
|
-
}
|
|
10413
|
-
function reviveExpandedLinks(value) {
|
|
10414
|
-
if (!isPlainObject2(value))
|
|
10415
|
-
return;
|
|
10416
|
-
const links = {};
|
|
10417
|
-
for (const [linkId, raw] of Object.entries(value)) {
|
|
10418
|
-
links[linkId] = reviveExpandedLinkValue(raw);
|
|
10419
|
-
}
|
|
10420
|
-
return links;
|
|
10421
|
-
}
|
|
10422
|
-
function reviveExpandedLinkValue(value) {
|
|
10423
|
-
if (value === null || value === undefined)
|
|
10424
|
-
return null;
|
|
10425
|
-
if (Array.isArray(value))
|
|
10426
|
-
return value.map(reviveExpandedRow);
|
|
10427
|
-
return reviveExpandedRow(value);
|
|
10428
|
-
}
|
|
10429
|
-
function reviveExpandedRow(value) {
|
|
10430
|
-
const row = isPlainObject2(value) ? value : {};
|
|
10431
|
-
const expanded = {
|
|
10432
|
-
projectId: String(row.projectId),
|
|
10433
|
-
objectTypeId: String(row.objectTypeId),
|
|
10434
|
-
primaryId: String(row.primaryId),
|
|
10435
|
-
properties: isPlainObject2(row.properties) ? row.properties : {},
|
|
10436
|
-
createdAt: new Date(row.createdAt),
|
|
10437
|
-
updatedAt: new Date(row.updatedAt),
|
|
10438
|
-
version: Number(row.version),
|
|
10439
|
-
lastCommitId: String(row.lastCommitId)
|
|
10440
|
-
};
|
|
10441
|
-
if (isPlainObject2(row.linkProperties) && Object.keys(row.linkProperties).length > 0) {
|
|
10442
|
-
expanded.linkProperties = row.linkProperties;
|
|
10443
|
-
}
|
|
10444
|
-
const links = reviveExpandedLinks(row.links);
|
|
10445
|
-
if (links)
|
|
10446
|
-
expanded.links = links;
|
|
10447
|
-
return expanded;
|
|
10448
|
-
}
|
|
10449
|
-
function isPlainObject2(value) {
|
|
10450
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10451
|
-
}
|
|
10452
|
-
function existsProbeQuery(query) {
|
|
10453
|
-
return { kind: "limit", limit: 1, input: stripOuterRowShape(query) };
|
|
10454
|
-
}
|
|
10455
|
-
function stripOuterRowShape(query) {
|
|
10456
|
-
switch (query.kind) {
|
|
10457
|
-
case "limit":
|
|
10458
|
-
case "page":
|
|
10459
|
-
case "project":
|
|
10460
|
-
case "sort":
|
|
10461
|
-
return stripOuterRowShape(query.input);
|
|
10462
|
-
default:
|
|
10463
|
-
return query;
|
|
10464
|
-
}
|
|
10465
|
-
}
|
|
10466
|
-
|
|
10467
11353
|
// src/ontology-storage/shared.ts
|
|
10468
11354
|
import { parseSixbFailure as parseSixbFailure2 } from "@sixb/core/internal/errors";
|
|
10469
11355
|
import { MaterializationConflictError } from "@sixb/core/internal/materialization";
|
|
@@ -11019,13 +11905,13 @@ class SqliteMaterializationStateReader {
|
|
|
11019
11905
|
ORDER BY requested.scope_sort_key, ${linkSortExpression("links")}
|
|
11020
11906
|
`).iterate(requestedJson, this.projectId);
|
|
11021
11907
|
for (const row of rows) {
|
|
11022
|
-
const
|
|
11023
|
-
if (!
|
|
11908
|
+
const accumulator = accumulators.get(row.scope_sort_key);
|
|
11909
|
+
if (!accumulator) {
|
|
11024
11910
|
throw new MaterializationConflictError2("effective-state", `Unexpected link scope '${row.scope_sort_key}' returned by storage.`);
|
|
11025
11911
|
}
|
|
11026
11912
|
const snapshot = effectiveLinkSnapshot(row);
|
|
11027
|
-
appendScopeSnapshot(
|
|
11028
|
-
effective.set(row.scope_sort_key,
|
|
11913
|
+
appendScopeSnapshot(accumulator, snapshot);
|
|
11914
|
+
effective.set(row.scope_sort_key, accumulator.effectiveCount === 1 ? snapshot : null);
|
|
11029
11915
|
}
|
|
11030
11916
|
return {
|
|
11031
11917
|
revisions: scopes.map(({ source, linkId }) => finishScopeAccumulator(accumulators.get(linkScopeSortKey(source, linkId)))),
|
|
@@ -13037,11 +13923,8 @@ class SqliteOntologyStorage {
|
|
|
13037
13923
|
// src/pipeline-run-storage.ts
|
|
13038
13924
|
import { parseSixbFailure as parseSixbFailure3, serializeSixbFailure as serializeSixbFailure3 } from "@sixb/core/internal/errors";
|
|
13039
13925
|
import { assertPipelineRunExecution } from "@sixb/core/internal/pipeline-run-storage-provider";
|
|
13040
|
-
import {
|
|
13041
|
-
|
|
13042
|
-
PIPELINE_RUN_FAILURE_CODES,
|
|
13043
|
-
PipelineRunError
|
|
13044
|
-
} from "@sixb/core/storage";
|
|
13926
|
+
import { canRequeuePipelineRunAfterEnqueueFailure } from "@sixb/core/internal/storage";
|
|
13927
|
+
import { PIPELINE_RUN_FAILURE_CODES, PipelineRunError } from "@sixb/core/storage";
|
|
13045
13928
|
|
|
13046
13929
|
// src/latest-run-query.ts
|
|
13047
13930
|
function queryLatestRunsByOwnerId(input) {
|
|
@@ -14069,14 +14952,263 @@ function rowToRuleStateRecord(row) {
|
|
|
14069
14952
|
};
|
|
14070
14953
|
}
|
|
14071
14954
|
|
|
14955
|
+
// src/share-grant-storage.ts
|
|
14956
|
+
import {
|
|
14957
|
+
normalizeGetShareGrantByIdInput,
|
|
14958
|
+
normalizeListShareGrantsInput,
|
|
14959
|
+
normalizeRevokeShareGrantInput,
|
|
14960
|
+
normalizeShareGrantCreate,
|
|
14961
|
+
parseShareGrantRecord
|
|
14962
|
+
} from "@sixb/core/internal/share-grant-storage-provider";
|
|
14963
|
+
import { ShareGrantStorageError } from "@sixb/core/storage";
|
|
14964
|
+
class SqliteShareGrantStorage {
|
|
14965
|
+
connection;
|
|
14966
|
+
db;
|
|
14967
|
+
constructor(options = {}) {
|
|
14968
|
+
this.connection = openSqliteStoreConnection(options);
|
|
14969
|
+
this.db = this.connection.db;
|
|
14970
|
+
if (this.connection.installFreshSchema)
|
|
14971
|
+
installFreshSqliteSchema(this.db);
|
|
14972
|
+
}
|
|
14973
|
+
async create(input) {
|
|
14974
|
+
const record = normalizeShareGrantCreate(input);
|
|
14975
|
+
try {
|
|
14976
|
+
this.db.query(`
|
|
14977
|
+
INSERT INTO share_grants (
|
|
14978
|
+
project_id, id, definition_id, target_object_type_id, target_primary_id,
|
|
14979
|
+
issued_by_type, issued_by_id, authority_version, authority_snapshot,
|
|
14980
|
+
authority_digest, token_hash, destination_path, created_at, expires_at
|
|
14981
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
14982
|
+
`).run(record.projectId, record.id, record.definitionId, record.target.objectTypeId, record.target.primaryId, record.issuedBy.type, record.issuedBy.id, record.authoritySnapshot.version, JSON.stringify(record.authoritySnapshot), record.authorityDigest, record.tokenHash, record.destinationPath, record.createdAt.toISOString(), record.expiresAt.toISOString());
|
|
14983
|
+
} catch (error) {
|
|
14984
|
+
if (isUniqueConstraintError2(error)) {
|
|
14985
|
+
throw new ShareGrantStorageError("duplicate", `[SixbSqlite] Share grant '${record.id}' conflicts with an existing record.`, { cause: error });
|
|
14986
|
+
}
|
|
14987
|
+
throw error;
|
|
14988
|
+
}
|
|
14989
|
+
return this.require(record.projectId, record.id, "create");
|
|
14990
|
+
}
|
|
14991
|
+
async getById(input) {
|
|
14992
|
+
const normalized = normalizeGetShareGrantByIdInput(input);
|
|
14993
|
+
return this.getRow(normalized.projectId, normalized.id);
|
|
14994
|
+
}
|
|
14995
|
+
async list(input) {
|
|
14996
|
+
const normalized = normalizeListShareGrantsInput(input);
|
|
14997
|
+
const where = ["project_id = ?"];
|
|
14998
|
+
const args = [normalized.projectId];
|
|
14999
|
+
if (normalized.definitionId !== undefined) {
|
|
15000
|
+
where.push("definition_id = ?");
|
|
15001
|
+
args.push(normalized.definitionId);
|
|
15002
|
+
}
|
|
15003
|
+
if (normalized.target !== undefined) {
|
|
15004
|
+
where.push("target_object_type_id = ?", "target_primary_id = ?");
|
|
15005
|
+
args.push(normalized.target.objectTypeId, normalized.target.primaryId);
|
|
15006
|
+
}
|
|
15007
|
+
if (!normalized.includeRevoked)
|
|
15008
|
+
where.push("revoked_at IS NULL");
|
|
15009
|
+
if (!normalized.includeExpired) {
|
|
15010
|
+
where.push("expires_at > ?");
|
|
15011
|
+
args.push(normalized.now.toISOString());
|
|
15012
|
+
}
|
|
15013
|
+
const predicate = where.join(" AND ");
|
|
15014
|
+
const totalRow = this.db.query(`SELECT COUNT(*) AS total FROM share_grants WHERE ${predicate}`).get(...args);
|
|
15015
|
+
const rows = this.db.query(`
|
|
15016
|
+
SELECT * FROM share_grants
|
|
15017
|
+
WHERE ${predicate}
|
|
15018
|
+
ORDER BY created_at DESC, id DESC
|
|
15019
|
+
LIMIT ? OFFSET ?
|
|
15020
|
+
`).all(...args, normalized.limit, normalized.offset);
|
|
15021
|
+
const grants = rows.map(rowToRecord);
|
|
15022
|
+
return {
|
|
15023
|
+
grants,
|
|
15024
|
+
total: totalRow.total,
|
|
15025
|
+
hasMore: normalized.offset + grants.length < totalRow.total
|
|
15026
|
+
};
|
|
15027
|
+
}
|
|
15028
|
+
async revoke(input) {
|
|
15029
|
+
const normalized = normalizeRevokeShareGrantInput(input);
|
|
15030
|
+
const current = this.getRow(normalized.projectId, normalized.id);
|
|
15031
|
+
if (!current || current.revokedAt)
|
|
15032
|
+
return current;
|
|
15033
|
+
const revocation = normalizeRevokeShareGrantInput(normalized, current.createdAt);
|
|
15034
|
+
this.db.query(`
|
|
15035
|
+
UPDATE share_grants
|
|
15036
|
+
SET revoked_at = ?, revoked_by_type = ?, revoked_by_id = ?
|
|
15037
|
+
WHERE project_id = ? AND id = ? AND revoked_at IS NULL
|
|
15038
|
+
`).run(revocation.revokedAt.toISOString(), revocation.revokedBy.type, revocation.revokedBy.id, revocation.projectId, revocation.id);
|
|
15039
|
+
return this.require(revocation.projectId, revocation.id, "revoke");
|
|
15040
|
+
}
|
|
15041
|
+
close() {
|
|
15042
|
+
closeSqliteStoreConnection(this.connection);
|
|
15043
|
+
}
|
|
15044
|
+
getRow(projectId, id) {
|
|
15045
|
+
const row = this.db.query("SELECT * FROM share_grants WHERE project_id = ? AND id = ?").get(projectId, id);
|
|
15046
|
+
return row ? rowToRecord(row) : null;
|
|
15047
|
+
}
|
|
15048
|
+
require(projectId, id, operation) {
|
|
15049
|
+
const record = this.getRow(projectId, id);
|
|
15050
|
+
if (!record) {
|
|
15051
|
+
throw new ShareGrantStorageError("invalid_record", `[SixbSqlite] Share grant '${id}' disappeared after ${operation}.`);
|
|
15052
|
+
}
|
|
15053
|
+
return record;
|
|
15054
|
+
}
|
|
15055
|
+
}
|
|
15056
|
+
function rowToRecord(row) {
|
|
15057
|
+
const authoritySnapshot = parseStoredJson(row.authority_snapshot, "authority snapshot");
|
|
15058
|
+
if (typeof row.authority_version !== "number" || !isRecord(authoritySnapshot) || authoritySnapshot.version !== row.authority_version) {
|
|
15059
|
+
throw invalidRecord("Share authority version does not match its snapshot.");
|
|
15060
|
+
}
|
|
15061
|
+
const hasRevokedAt = row.revoked_at !== null;
|
|
15062
|
+
const hasRevokedBy = row.revoked_by_type !== null || row.revoked_by_id !== null;
|
|
15063
|
+
if (hasRevokedAt !== hasRevokedBy) {
|
|
15064
|
+
throw invalidRecord("Share revocation time and actor must be stored together.");
|
|
15065
|
+
}
|
|
15066
|
+
return parseShareGrantRecord({
|
|
15067
|
+
projectId: row.project_id,
|
|
15068
|
+
id: row.id,
|
|
15069
|
+
definitionId: row.definition_id,
|
|
15070
|
+
target: {
|
|
15071
|
+
objectTypeId: row.target_object_type_id,
|
|
15072
|
+
primaryId: row.target_primary_id
|
|
15073
|
+
},
|
|
15074
|
+
issuedBy: { type: row.issued_by_type, id: row.issued_by_id },
|
|
15075
|
+
authoritySnapshot,
|
|
15076
|
+
authorityDigest: row.authority_digest,
|
|
15077
|
+
tokenHash: row.token_hash,
|
|
15078
|
+
destinationPath: row.destination_path,
|
|
15079
|
+
createdAt: row.created_at,
|
|
15080
|
+
expiresAt: row.expires_at,
|
|
15081
|
+
...hasRevokedAt ? { revokedAt: row.revoked_at } : {},
|
|
15082
|
+
...hasRevokedBy ? { revokedBy: { type: row.revoked_by_type, id: row.revoked_by_id } } : {}
|
|
15083
|
+
});
|
|
15084
|
+
}
|
|
15085
|
+
function parseStoredJson(value, field) {
|
|
15086
|
+
if (typeof value !== "string")
|
|
15087
|
+
throw invalidRecord(`Share ${field} must be stored as JSON text.`);
|
|
15088
|
+
try {
|
|
15089
|
+
return JSON.parse(value);
|
|
15090
|
+
} catch (cause) {
|
|
15091
|
+
throw new ShareGrantStorageError("invalid_record", `[SixbSqlite] Share ${field} contains invalid JSON.`, { cause });
|
|
15092
|
+
}
|
|
15093
|
+
}
|
|
15094
|
+
function isRecord(value) {
|
|
15095
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15096
|
+
}
|
|
15097
|
+
function invalidRecord(message) {
|
|
15098
|
+
return new ShareGrantStorageError("invalid_record", `[SixbSqlite] ${message}`);
|
|
15099
|
+
}
|
|
15100
|
+
|
|
15101
|
+
// src/share-session-storage.ts
|
|
15102
|
+
import {
|
|
15103
|
+
normalizeGetShareSessionByIdInput,
|
|
15104
|
+
normalizeRenewShareSessionIfValidInput,
|
|
15105
|
+
normalizeRevokeShareSessionInput,
|
|
15106
|
+
normalizeShareSessionCreate,
|
|
15107
|
+
parseShareSessionRecord
|
|
15108
|
+
} from "@sixb/core/internal/share-session-storage-provider";
|
|
15109
|
+
import { ShareSessionStorageError } from "@sixb/core/storage";
|
|
15110
|
+
class SqliteShareSessionStorage {
|
|
15111
|
+
connection;
|
|
15112
|
+
db;
|
|
15113
|
+
constructor(options = {}) {
|
|
15114
|
+
this.connection = openSqliteStoreConnection(options);
|
|
15115
|
+
this.db = this.connection.db;
|
|
15116
|
+
if (this.connection.installFreshSchema)
|
|
15117
|
+
installFreshSqliteSchema(this.db);
|
|
15118
|
+
}
|
|
15119
|
+
async create(input) {
|
|
15120
|
+
const record = normalizeShareSessionCreate(input);
|
|
15121
|
+
try {
|
|
15122
|
+
const row = this.db.query(`
|
|
15123
|
+
INSERT INTO share_sessions (
|
|
15124
|
+
project_id, id, grant_id, token_hash, created_at, expires_at,
|
|
15125
|
+
absolute_expires_at
|
|
15126
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
15127
|
+
RETURNING *
|
|
15128
|
+
`).get(record.projectId, record.id, record.grantId, record.tokenHash, record.createdAt.toISOString(), record.expiresAt.toISOString(), record.absoluteExpiresAt.toISOString());
|
|
15129
|
+
if (!row)
|
|
15130
|
+
throw invalidRecord2(`Share session '${record.id}' disappeared after create.`);
|
|
15131
|
+
return rowToRecord2(row);
|
|
15132
|
+
} catch (error) {
|
|
15133
|
+
if (isUniqueConstraintError2(error)) {
|
|
15134
|
+
throw new ShareSessionStorageError("duplicate", `[SixbSqlite] Share session '${record.id}' conflicts with an existing record.`, { cause: error });
|
|
15135
|
+
}
|
|
15136
|
+
if (isForeignKeyConstraintError(error)) {
|
|
15137
|
+
throw new ShareSessionStorageError("invalid_input", `[SixbSqlite] Share grant '${record.grantId}' does not exist in project '${record.projectId}'.`, { cause: error });
|
|
15138
|
+
}
|
|
15139
|
+
throw error;
|
|
15140
|
+
}
|
|
15141
|
+
}
|
|
15142
|
+
async getById(input) {
|
|
15143
|
+
const normalized = normalizeGetShareSessionByIdInput(input);
|
|
15144
|
+
return this.getRow(normalized.projectId, normalized.id);
|
|
15145
|
+
}
|
|
15146
|
+
async renewIfValid(input) {
|
|
15147
|
+
const normalized = normalizeRenewShareSessionIfValidInput(input);
|
|
15148
|
+
const requestedExpiry = normalized.expiresAt.toISOString();
|
|
15149
|
+
const now = normalized.now.toISOString();
|
|
15150
|
+
const row = this.db.query(`
|
|
15151
|
+
UPDATE share_sessions
|
|
15152
|
+
SET expires_at = CASE
|
|
15153
|
+
WHEN ? > absolute_expires_at THEN absolute_expires_at
|
|
15154
|
+
WHEN ? > expires_at THEN ?
|
|
15155
|
+
ELSE expires_at
|
|
15156
|
+
END
|
|
15157
|
+
WHERE project_id = ?
|
|
15158
|
+
AND id = ?
|
|
15159
|
+
AND grant_id = ?
|
|
15160
|
+
AND token_hash = ?
|
|
15161
|
+
AND revoked_at IS NULL
|
|
15162
|
+
AND created_at <= ?
|
|
15163
|
+
AND expires_at > ?
|
|
15164
|
+
AND absolute_expires_at > ?
|
|
15165
|
+
RETURNING *
|
|
15166
|
+
`).get(requestedExpiry, requestedExpiry, requestedExpiry, normalized.projectId, normalized.id, normalized.grantId, normalized.tokenHash, now, now, now);
|
|
15167
|
+
return row ? rowToRecord2(row) : null;
|
|
15168
|
+
}
|
|
15169
|
+
async revoke(input) {
|
|
15170
|
+
const normalized = normalizeRevokeShareSessionInput(input);
|
|
15171
|
+
const current = this.getRow(normalized.projectId, normalized.id);
|
|
15172
|
+
if (!current || current.revokedAt)
|
|
15173
|
+
return current;
|
|
15174
|
+
const revocation = normalizeRevokeShareSessionInput(normalized, current.createdAt);
|
|
15175
|
+
const row = this.db.query(`
|
|
15176
|
+
UPDATE share_sessions
|
|
15177
|
+
SET revoked_at = ?
|
|
15178
|
+
WHERE project_id = ? AND id = ? AND revoked_at IS NULL
|
|
15179
|
+
RETURNING *
|
|
15180
|
+
`).get(revocation.revokedAt.toISOString(), revocation.projectId, revocation.id);
|
|
15181
|
+
return row ? rowToRecord2(row) : this.getRow(revocation.projectId, revocation.id);
|
|
15182
|
+
}
|
|
15183
|
+
close() {
|
|
15184
|
+
closeSqliteStoreConnection(this.connection);
|
|
15185
|
+
}
|
|
15186
|
+
getRow(projectId, id) {
|
|
15187
|
+
const row = this.db.query("SELECT * FROM share_sessions WHERE project_id = ? AND id = ?").get(projectId, id);
|
|
15188
|
+
return row ? rowToRecord2(row) : null;
|
|
15189
|
+
}
|
|
15190
|
+
}
|
|
15191
|
+
function rowToRecord2(row) {
|
|
15192
|
+
return parseShareSessionRecord({
|
|
15193
|
+
projectId: row.project_id,
|
|
15194
|
+
id: row.id,
|
|
15195
|
+
grantId: row.grant_id,
|
|
15196
|
+
tokenHash: row.token_hash,
|
|
15197
|
+
createdAt: row.created_at,
|
|
15198
|
+
expiresAt: row.expires_at,
|
|
15199
|
+
absoluteExpiresAt: row.absolute_expires_at,
|
|
15200
|
+
...row.revoked_at === null ? {} : { revokedAt: row.revoked_at }
|
|
15201
|
+
});
|
|
15202
|
+
}
|
|
15203
|
+
function invalidRecord2(message) {
|
|
15204
|
+
return new ShareSessionStorageError("invalid_record", `[SixbSqlite] ${message}`);
|
|
15205
|
+
}
|
|
15206
|
+
|
|
14072
15207
|
// src/sync-run-storage.ts
|
|
14073
15208
|
import { parseSixbFailure as parseSixbFailure4, serializeSixbFailure as serializeSixbFailure5 } from "@sixb/core/internal/errors";
|
|
15209
|
+
import { canRequeueSyncRunAfterEnqueueFailure } from "@sixb/core/internal/storage";
|
|
14074
15210
|
import { assertSyncRunExecution } from "@sixb/core/internal/sync-run-storage-provider";
|
|
14075
|
-
import {
|
|
14076
|
-
canRequeueSyncRunAfterEnqueueFailure,
|
|
14077
|
-
SYNC_RUN_FAILURE_CODES,
|
|
14078
|
-
SyncRunError
|
|
14079
|
-
} from "@sixb/core/storage";
|
|
15211
|
+
import { SYNC_RUN_FAILURE_CODES, SyncRunError } from "@sixb/core/storage";
|
|
14080
15212
|
class SqliteSyncRunStorage {
|
|
14081
15213
|
connection;
|
|
14082
15214
|
db;
|
|
@@ -14792,7 +15924,6 @@ function assertNonNegativeInteger(value, fieldName) {
|
|
|
14792
15924
|
}
|
|
14793
15925
|
|
|
14794
15926
|
// src/workflow-run-storage.ts
|
|
14795
|
-
import { normalizeRequesterGroupIds as normalizeRequesterGroupIds2 } from "@sixb/core/internal/auth";
|
|
14796
15927
|
import { parseSixbFailure as parseSixbFailure6, serializeSixbFailure as serializeSixbFailure7 } from "@sixb/core/internal/errors";
|
|
14797
15928
|
import {
|
|
14798
15929
|
assertWorkflowAgentNodeRunExecution,
|
|
@@ -14839,10 +15970,9 @@ class SqliteWorkflowRunStorage {
|
|
|
14839
15970
|
input,
|
|
14840
15971
|
queued_at,
|
|
14841
15972
|
started_at,
|
|
14842
|
-
requester_group_ids,
|
|
14843
15973
|
attempt
|
|
14844
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
|
|
14845
|
-
`).run(input.projectId, input.id, input.executionId, input.workflowId, "queued", serializeRecord2(input.input), queuedAt.toISOString(), queuedAt.toISOString(),
|
|
15974
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
15975
|
+
`).run(input.projectId, input.id, input.executionId, input.workflowId, "queued", serializeRecord2(input.input), queuedAt.toISOString(), queuedAt.toISOString(), 0);
|
|
14846
15976
|
} catch (error) {
|
|
14847
15977
|
if (isUniqueConstraintError2(error)) {
|
|
14848
15978
|
throw new WorkflowRunError(`[SixbSqlite] Workflow run '${input.id}' or execution '${input.executionId}' is already linked for project '${input.projectId}'.`);
|
|
@@ -15353,7 +16483,6 @@ function rowToWorkflowRunRecord(row) {
|
|
|
15353
16483
|
startedAt: new Date(row.started_at),
|
|
15354
16484
|
finishedAt: row.finished_at ? new Date(row.finished_at) : undefined,
|
|
15355
16485
|
error: row.error === null ? undefined : parseSixbFailure6(row.error, WORKFLOW_RUN_FAILURE_CODES),
|
|
15356
|
-
requesterGroupIds: JSON.parse(row.requester_group_ids),
|
|
15357
16486
|
attempt: row.attempt,
|
|
15358
16487
|
...row.execution_token && row.execution_queue_lease_expires_at ? {
|
|
15359
16488
|
execution: {
|
|
@@ -15444,6 +16573,8 @@ class SqliteStorage {
|
|
|
15444
16573
|
timeseries;
|
|
15445
16574
|
webhookRuns;
|
|
15446
16575
|
rules;
|
|
16576
|
+
shareGrants;
|
|
16577
|
+
shareSessions;
|
|
15447
16578
|
connectorConnections;
|
|
15448
16579
|
migrators;
|
|
15449
16580
|
connection;
|
|
@@ -15475,7 +16606,7 @@ class SqliteStorage {
|
|
|
15475
16606
|
}, assertRootOperationAvailable) : scope;
|
|
15476
16607
|
const readObjects = path ? new SqliteObjectStorage({ connection: this.readConnection }) : stores.objects;
|
|
15477
16608
|
const readTimeseries = path ? new SqliteTimeseriesStorage({ connection: this.readConnection }) : stores.timeseries;
|
|
15478
|
-
this.objects =
|
|
16609
|
+
this.objects = createObjectOperationScope(readObjects, readScope);
|
|
15479
16610
|
this.ontology = createOntologyOperationScope(stores.ontology, ontologyScope);
|
|
15480
16611
|
this.auth = createAuthOperationScope(stores.auth, scope);
|
|
15481
16612
|
this.executions = createOperationScopedFacade(stores.executions, scope);
|
|
@@ -15492,6 +16623,8 @@ class SqliteStorage {
|
|
|
15492
16623
|
this.workflowInterventions = createOperationScopedFacade(stores.workflowInterventions, scope);
|
|
15493
16624
|
this.webhookRuns = createOperationScopedFacade(stores.webhookRuns, scope);
|
|
15494
16625
|
this.rules = createOperationScopedFacade(stores.rules, scope);
|
|
16626
|
+
this.shareGrants = createOperationScopedFacade(stores.shareGrants, scope);
|
|
16627
|
+
this.shareSessions = createOperationScopedFacade(stores.shareSessions, scope);
|
|
15495
16628
|
this.connectorConnections = createOperationScopedFacade(stores.connectorConnections, scope);
|
|
15496
16629
|
this.migrators = options.path ? createSqliteStorageMigrators(options.path) : [];
|
|
15497
16630
|
registerSqliteStorageTestingAdapter(this, (durationMs) => stores.connectorConnections.advanceTimeForTesting(durationMs));
|
|
@@ -15590,7 +16723,9 @@ class SqliteStorage {
|
|
|
15590
16723
|
}
|
|
15591
16724
|
function createSqliteStores(connection, options) {
|
|
15592
16725
|
const auth = new SqliteAuthStorage({ connection });
|
|
15593
|
-
const
|
|
16726
|
+
const shareGrants = new SqliteShareGrantStorage({ connection });
|
|
16727
|
+
const shareSessions = new SqliteShareSessionStorage({ connection });
|
|
16728
|
+
const executions = new SqliteExecutionStorage(connection.db, auth, shareSessions);
|
|
15594
16729
|
return {
|
|
15595
16730
|
objects: new SqliteObjectStorage({ connection }),
|
|
15596
16731
|
ontology: new SqliteOntologyStorage({
|
|
@@ -15613,12 +16748,14 @@ function createSqliteStores(connection, options) {
|
|
|
15613
16748
|
workflowInterventions: new SqliteWorkflowInterventionStorage({ connection }),
|
|
15614
16749
|
webhookRuns: new SqliteWebhookRunStorage({ connection, executions }),
|
|
15615
16750
|
rules: new SqliteRulesStorage({ connection }),
|
|
16751
|
+
shareGrants,
|
|
16752
|
+
shareSessions,
|
|
15616
16753
|
connectorConnections: new SqliteConnectorConnectionStorage(connection)
|
|
15617
16754
|
};
|
|
15618
16755
|
}
|
|
15619
16756
|
export {
|
|
15620
|
-
|
|
15621
|
-
|
|
16757
|
+
SqliteStorage,
|
|
16758
|
+
migrateSqliteStorage
|
|
15622
16759
|
};
|
|
15623
16760
|
|
|
15624
|
-
//# debugId=
|
|
16761
|
+
//# debugId=8848EEC97F2007FB64756E2164756E21
|