@sixb/sqlite 0.1.7 → 0.1.8
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/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 +1492 -380
- package/dist/index.js.map +16 -10
- 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/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/transactions.d.ts +8 -0
- package/dist/transactions.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/execution-storage.ts +22 -3
- package/src/index.ts +18 -3
- package/src/migrations/035-share-grants.sql +66 -0
- package/src/migrations/036-share-sessions.sql +226 -0
- package/src/migrations.ts +4 -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/share-grant-storage.ts +252 -0
- package/src/share-session-storage.ts +189 -0
- package/src/storage-errors.ts +4 -0
- package/src/transactions.ts +32 -0
- 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
|
@@ -5,6 +5,7 @@ import { ProviderMaterializationTransactionLifecycle } from "@sixb/core/internal
|
|
|
5
5
|
import {
|
|
6
6
|
createAgentOperationScope,
|
|
7
7
|
createAuthOperationScope,
|
|
8
|
+
createObjectOperationScope,
|
|
8
9
|
createOntologyOperationScope,
|
|
9
10
|
createOperationScopedFacade,
|
|
10
11
|
createStorageOperationScope,
|
|
@@ -3632,6 +3633,304 @@ CREATE INDEX idx_auth_device_authorizations_pending
|
|
|
3632
3633
|
ON auth_device_authorizations(project_id, status, expires_at);
|
|
3633
3634
|
`;
|
|
3634
3635
|
|
|
3636
|
+
// src/migrations/035-share-grants.sql
|
|
3637
|
+
var _035_share_grants_default = `CREATE TABLE share_grants (
|
|
3638
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3639
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
3640
|
+
definition_id TEXT NOT NULL CHECK (length(trim(definition_id)) > 0),
|
|
3641
|
+
target_object_type_id TEXT NOT NULL CHECK (length(trim(target_object_type_id)) > 0),
|
|
3642
|
+
target_primary_id TEXT NOT NULL CHECK (length(trim(target_primary_id)) > 0),
|
|
3643
|
+
issued_by_type TEXT NOT NULL CHECK (issued_by_type IN ('user', 'serviceAccount')),
|
|
3644
|
+
issued_by_id TEXT NOT NULL CHECK (length(trim(issued_by_id)) > 0),
|
|
3645
|
+
authority_version INTEGER NOT NULL CHECK (authority_version > 0),
|
|
3646
|
+
authority_snapshot TEXT NOT NULL CHECK (
|
|
3647
|
+
json_valid(authority_snapshot)
|
|
3648
|
+
AND json_type(authority_snapshot) = 'object'
|
|
3649
|
+
AND json_type(authority_snapshot, '$.version') = 'integer'
|
|
3650
|
+
AND json_extract(authority_snapshot, '$.version') = authority_version
|
|
3651
|
+
AND json_type(authority_snapshot, '$.access') = 'object'
|
|
3652
|
+
),
|
|
3653
|
+
authority_digest TEXT NOT NULL CHECK (
|
|
3654
|
+
length(authority_digest) = 64
|
|
3655
|
+
AND authority_digest = lower(authority_digest)
|
|
3656
|
+
AND authority_digest NOT GLOB '*[^0-9a-f]*'
|
|
3657
|
+
),
|
|
3658
|
+
token_hash TEXT NOT NULL CHECK (
|
|
3659
|
+
length(token_hash) = 64
|
|
3660
|
+
AND token_hash = lower(token_hash)
|
|
3661
|
+
AND token_hash NOT GLOB '*[^0-9a-f]*'
|
|
3662
|
+
),
|
|
3663
|
+
destination_path TEXT NOT NULL CHECK (
|
|
3664
|
+
substr(destination_path, 1, 1) = '/'
|
|
3665
|
+
AND instr(destination_path, '?') = 0
|
|
3666
|
+
AND instr(destination_path, '#') = 0
|
|
3667
|
+
AND instr(destination_path, char(92)) = 0
|
|
3668
|
+
),
|
|
3669
|
+
created_at TEXT NOT NULL,
|
|
3670
|
+
expires_at TEXT NOT NULL,
|
|
3671
|
+
revoked_at TEXT,
|
|
3672
|
+
revoked_by_type TEXT CHECK (
|
|
3673
|
+
revoked_by_type IS NULL OR revoked_by_type IN ('user', 'serviceAccount', 'system')
|
|
3674
|
+
),
|
|
3675
|
+
revoked_by_id TEXT CHECK (revoked_by_id IS NULL OR length(trim(revoked_by_id)) > 0),
|
|
3676
|
+
PRIMARY KEY (project_id, id),
|
|
3677
|
+
UNIQUE (project_id, token_hash),
|
|
3678
|
+
CHECK (expires_at > created_at),
|
|
3679
|
+
CHECK (revoked_at IS NULL OR revoked_at >= created_at),
|
|
3680
|
+
CHECK (
|
|
3681
|
+
(revoked_at IS NULL AND revoked_by_type IS NULL AND revoked_by_id IS NULL)
|
|
3682
|
+
OR
|
|
3683
|
+
(revoked_at IS NOT NULL AND revoked_by_type IS NOT NULL AND revoked_by_id IS NOT NULL)
|
|
3684
|
+
)
|
|
3685
|
+
);
|
|
3686
|
+
|
|
3687
|
+
CREATE INDEX idx_share_grants_target
|
|
3688
|
+
ON share_grants (
|
|
3689
|
+
project_id,
|
|
3690
|
+
definition_id,
|
|
3691
|
+
target_object_type_id,
|
|
3692
|
+
target_primary_id,
|
|
3693
|
+
created_at DESC,
|
|
3694
|
+
id DESC
|
|
3695
|
+
);
|
|
3696
|
+
|
|
3697
|
+
CREATE INDEX idx_share_grants_project_created
|
|
3698
|
+
ON share_grants (project_id, created_at DESC, id DESC);
|
|
3699
|
+
|
|
3700
|
+
CREATE INDEX idx_share_grants_expiry
|
|
3701
|
+
ON share_grants (project_id, expires_at)
|
|
3702
|
+
WHERE revoked_at IS NULL;
|
|
3703
|
+
`;
|
|
3704
|
+
|
|
3705
|
+
// src/migrations/036-share-sessions.sql
|
|
3706
|
+
var _036_share_sessions_default = `-- Shared sessions and their execution provenance.
|
|
3707
|
+
CREATE TABLE share_sessions (
|
|
3708
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3709
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
3710
|
+
grant_id TEXT NOT NULL CHECK (length(trim(grant_id)) > 0),
|
|
3711
|
+
token_hash TEXT NOT NULL CHECK (
|
|
3712
|
+
length(token_hash) = 64
|
|
3713
|
+
AND token_hash = lower(token_hash)
|
|
3714
|
+
AND token_hash NOT GLOB '*[^0-9a-f]*'
|
|
3715
|
+
),
|
|
3716
|
+
created_at TEXT NOT NULL,
|
|
3717
|
+
expires_at TEXT NOT NULL,
|
|
3718
|
+
absolute_expires_at TEXT NOT NULL,
|
|
3719
|
+
revoked_at TEXT,
|
|
3720
|
+
PRIMARY KEY (project_id, id),
|
|
3721
|
+
UNIQUE (project_id, id, grant_id),
|
|
3722
|
+
UNIQUE (project_id, token_hash),
|
|
3723
|
+
FOREIGN KEY (project_id, grant_id)
|
|
3724
|
+
REFERENCES share_grants (project_id, id),
|
|
3725
|
+
CHECK (expires_at > created_at),
|
|
3726
|
+
CHECK (absolute_expires_at > created_at),
|
|
3727
|
+
CHECK (expires_at <= absolute_expires_at),
|
|
3728
|
+
CHECK (revoked_at IS NULL OR revoked_at >= created_at)
|
|
3729
|
+
);
|
|
3730
|
+
|
|
3731
|
+
CREATE INDEX idx_share_sessions_grant
|
|
3732
|
+
ON share_sessions (project_id, grant_id, created_at DESC, id DESC);
|
|
3733
|
+
|
|
3734
|
+
CREATE INDEX idx_share_sessions_expiry
|
|
3735
|
+
ON share_sessions (project_id, expires_at)
|
|
3736
|
+
WHERE revoked_at IS NULL;
|
|
3737
|
+
|
|
3738
|
+
-- Persist shared-session provenance on request executions without fabricating a principal.
|
|
3739
|
+
CREATE TABLE executions_v2 (
|
|
3740
|
+
project_id TEXT NOT NULL CHECK (length(trim(project_id)) > 0),
|
|
3741
|
+
id TEXT NOT NULL CHECK (length(trim(id)) > 0),
|
|
3742
|
+
executor_kind TEXT NOT NULL CHECK (
|
|
3743
|
+
executor_kind IN (
|
|
3744
|
+
'request', 'action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow',
|
|
3745
|
+
'agent', 'kernel'
|
|
3746
|
+
)
|
|
3747
|
+
),
|
|
3748
|
+
executor_id TEXT NOT NULL CHECK (length(trim(executor_id)) > 0),
|
|
3749
|
+
source_kind TEXT NOT NULL CHECK (
|
|
3750
|
+
source_kind IN ('http', 'webhook', 'schedule', 'event', 'datasetVersion', 'execution')
|
|
3751
|
+
),
|
|
3752
|
+
source_id TEXT NOT NULL CHECK (length(trim(source_id)) > 0),
|
|
3753
|
+
requested_by_user_id TEXT,
|
|
3754
|
+
requested_by_service_account_id TEXT,
|
|
3755
|
+
correlation_id TEXT NOT NULL CHECK (length(trim(correlation_id)) > 0),
|
|
3756
|
+
parent_execution_id TEXT,
|
|
3757
|
+
authority_kind TEXT NOT NULL CHECK (
|
|
3758
|
+
authority_kind IN ('principal', 'trustedPrimitive', 'delegated', 'kernel', 'disabled')
|
|
3759
|
+
),
|
|
3760
|
+
authority_user_id TEXT,
|
|
3761
|
+
authority_service_account_id TEXT,
|
|
3762
|
+
authority_session_id TEXT,
|
|
3763
|
+
authority_access_token_id TEXT,
|
|
3764
|
+
authority_primitive_kind TEXT CHECK (
|
|
3765
|
+
authority_primitive_kind IS NULL
|
|
3766
|
+
OR authority_primitive_kind IN (
|
|
3767
|
+
'action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow'
|
|
3768
|
+
)
|
|
3769
|
+
),
|
|
3770
|
+
authority_primitive_id TEXT,
|
|
3771
|
+
authority_kernel_operation TEXT CHECK (
|
|
3772
|
+
authority_kernel_operation IS NULL OR authority_kernel_operation = 'ontology.recover'
|
|
3773
|
+
),
|
|
3774
|
+
authority_delegation_kind TEXT CHECK (
|
|
3775
|
+
authority_delegation_kind IS NULL OR authority_delegation_kind = 'share'
|
|
3776
|
+
),
|
|
3777
|
+
authority_delegation_id TEXT,
|
|
3778
|
+
authority_delegation_session_id TEXT,
|
|
3779
|
+
created_at TEXT NOT NULL,
|
|
3780
|
+
PRIMARY KEY (project_id, id),
|
|
3781
|
+
FOREIGN KEY (project_id, parent_execution_id) REFERENCES executions (project_id, id),
|
|
3782
|
+
FOREIGN KEY (project_id, requested_by_user_id) REFERENCES auth_users (project_id, id),
|
|
3783
|
+
FOREIGN KEY (project_id, requested_by_service_account_id)
|
|
3784
|
+
REFERENCES auth_service_accounts (project_id, id),
|
|
3785
|
+
FOREIGN KEY (project_id, authority_user_id) REFERENCES auth_users (project_id, id),
|
|
3786
|
+
FOREIGN KEY (project_id, authority_service_account_id)
|
|
3787
|
+
REFERENCES auth_service_accounts (project_id, id),
|
|
3788
|
+
FOREIGN KEY (project_id, authority_session_id) REFERENCES auth_sessions (project_id, id),
|
|
3789
|
+
FOREIGN KEY (project_id, authority_access_token_id)
|
|
3790
|
+
REFERENCES auth_access_tokens (project_id, id),
|
|
3791
|
+
FOREIGN KEY (
|
|
3792
|
+
project_id, authority_delegation_session_id, authority_delegation_id
|
|
3793
|
+
) REFERENCES share_sessions (project_id, id, grant_id),
|
|
3794
|
+
CHECK ((requested_by_user_id IS NOT NULL) + (requested_by_service_account_id IS NOT NULL) <= 1),
|
|
3795
|
+
CHECK (
|
|
3796
|
+
(source_kind = 'execution' AND parent_execution_id = source_id)
|
|
3797
|
+
OR (source_kind <> 'execution' AND parent_execution_id IS NULL)
|
|
3798
|
+
),
|
|
3799
|
+
CHECK (
|
|
3800
|
+
(
|
|
3801
|
+
authority_kind = 'principal'
|
|
3802
|
+
AND (authority_user_id IS NOT NULL) + (authority_service_account_id IS NOT NULL) = 1
|
|
3803
|
+
AND (authority_session_id IS NOT NULL) + (authority_access_token_id IS NOT NULL) <= 1
|
|
3804
|
+
AND (authority_session_id IS NULL OR authority_user_id IS NOT NULL)
|
|
3805
|
+
AND authority_primitive_kind IS NULL
|
|
3806
|
+
AND authority_primitive_id IS NULL
|
|
3807
|
+
AND authority_kernel_operation IS NULL
|
|
3808
|
+
AND authority_delegation_kind IS NULL
|
|
3809
|
+
AND authority_delegation_id IS NULL
|
|
3810
|
+
AND authority_delegation_session_id IS NULL
|
|
3811
|
+
)
|
|
3812
|
+
OR (
|
|
3813
|
+
authority_kind = 'trustedPrimitive'
|
|
3814
|
+
AND authority_user_id IS NULL
|
|
3815
|
+
AND authority_service_account_id IS NULL
|
|
3816
|
+
AND authority_session_id IS NULL
|
|
3817
|
+
AND authority_access_token_id IS NULL
|
|
3818
|
+
AND authority_primitive_kind IS NOT NULL
|
|
3819
|
+
AND authority_primitive_id IS NOT NULL
|
|
3820
|
+
AND length(trim(authority_primitive_id)) > 0
|
|
3821
|
+
AND authority_kernel_operation IS NULL
|
|
3822
|
+
AND authority_delegation_kind IS NULL
|
|
3823
|
+
AND authority_delegation_id IS NULL
|
|
3824
|
+
AND authority_delegation_session_id IS NULL
|
|
3825
|
+
)
|
|
3826
|
+
OR (
|
|
3827
|
+
authority_kind = 'delegated'
|
|
3828
|
+
AND authority_user_id IS NULL
|
|
3829
|
+
AND authority_service_account_id IS NULL
|
|
3830
|
+
AND authority_session_id IS NULL
|
|
3831
|
+
AND authority_access_token_id IS NULL
|
|
3832
|
+
AND authority_primitive_kind IS NULL
|
|
3833
|
+
AND authority_primitive_id IS NULL
|
|
3834
|
+
AND authority_kernel_operation IS NULL
|
|
3835
|
+
AND authority_delegation_kind IS NOT NULL
|
|
3836
|
+
AND authority_delegation_kind = 'share'
|
|
3837
|
+
AND authority_delegation_id IS NOT NULL
|
|
3838
|
+
AND length(trim(authority_delegation_id)) > 0
|
|
3839
|
+
AND authority_delegation_session_id IS NOT NULL
|
|
3840
|
+
AND length(trim(authority_delegation_session_id)) > 0
|
|
3841
|
+
)
|
|
3842
|
+
OR (
|
|
3843
|
+
authority_kind = 'kernel'
|
|
3844
|
+
AND authority_user_id IS NULL
|
|
3845
|
+
AND authority_service_account_id IS NULL
|
|
3846
|
+
AND authority_session_id IS NULL
|
|
3847
|
+
AND authority_access_token_id IS NULL
|
|
3848
|
+
AND authority_primitive_kind IS NULL
|
|
3849
|
+
AND authority_primitive_id IS NULL
|
|
3850
|
+
AND authority_kernel_operation IS NOT NULL
|
|
3851
|
+
AND authority_delegation_kind IS NULL
|
|
3852
|
+
AND authority_delegation_id IS NULL
|
|
3853
|
+
AND authority_delegation_session_id IS NULL
|
|
3854
|
+
)
|
|
3855
|
+
OR (
|
|
3856
|
+
authority_kind = 'disabled'
|
|
3857
|
+
AND authority_user_id IS NULL
|
|
3858
|
+
AND authority_service_account_id IS NULL
|
|
3859
|
+
AND authority_session_id IS NULL
|
|
3860
|
+
AND authority_access_token_id IS NULL
|
|
3861
|
+
AND authority_primitive_kind IS NULL
|
|
3862
|
+
AND authority_primitive_id IS NULL
|
|
3863
|
+
AND authority_kernel_operation IS NULL
|
|
3864
|
+
AND authority_delegation_kind IS NULL
|
|
3865
|
+
AND authority_delegation_id IS NULL
|
|
3866
|
+
AND authority_delegation_session_id IS NULL
|
|
3867
|
+
)
|
|
3868
|
+
),
|
|
3869
|
+
CHECK (
|
|
3870
|
+
(
|
|
3871
|
+
executor_kind = 'request'
|
|
3872
|
+
AND source_kind = 'http'
|
|
3873
|
+
AND executor_id = source_id
|
|
3874
|
+
AND (
|
|
3875
|
+
(
|
|
3876
|
+
authority_kind = 'principal'
|
|
3877
|
+
AND requested_by_user_id IS authority_user_id
|
|
3878
|
+
AND requested_by_service_account_id IS authority_service_account_id
|
|
3879
|
+
)
|
|
3880
|
+
OR (
|
|
3881
|
+
authority_kind IN ('delegated', 'disabled')
|
|
3882
|
+
AND requested_by_user_id IS NULL
|
|
3883
|
+
AND requested_by_service_account_id IS NULL
|
|
3884
|
+
)
|
|
3885
|
+
)
|
|
3886
|
+
)
|
|
3887
|
+
OR (
|
|
3888
|
+
executor_kind IN ('action', 'pipeline', 'projection', 'rule', 'sync', 'webhook', 'workflow')
|
|
3889
|
+
AND authority_kind = 'trustedPrimitive'
|
|
3890
|
+
AND executor_kind = authority_primitive_kind
|
|
3891
|
+
)
|
|
3892
|
+
OR (
|
|
3893
|
+
executor_kind = 'agent'
|
|
3894
|
+
AND source_kind = 'execution'
|
|
3895
|
+
AND (
|
|
3896
|
+
(
|
|
3897
|
+
authority_kind = 'principal'
|
|
3898
|
+
AND authority_service_account_id IS NOT NULL
|
|
3899
|
+
AND authority_session_id IS NULL
|
|
3900
|
+
AND authority_access_token_id IS NULL
|
|
3901
|
+
)
|
|
3902
|
+
OR (
|
|
3903
|
+
authority_kind = 'principal'
|
|
3904
|
+
AND authority_user_id IS NOT NULL
|
|
3905
|
+
AND (authority_session_id IS NOT NULL) + (authority_access_token_id IS NOT NULL) = 1
|
|
3906
|
+
)
|
|
3907
|
+
OR authority_kind = 'disabled'
|
|
3908
|
+
)
|
|
3909
|
+
)
|
|
3910
|
+
OR (executor_kind = 'kernel' AND authority_kind = 'kernel')
|
|
3911
|
+
)
|
|
3912
|
+
);
|
|
3913
|
+
|
|
3914
|
+
INSERT INTO executions_v2 (
|
|
3915
|
+
project_id, id, executor_kind, executor_id, source_kind, source_id,
|
|
3916
|
+
requested_by_user_id, requested_by_service_account_id, correlation_id, parent_execution_id,
|
|
3917
|
+
authority_kind, authority_user_id, authority_service_account_id, authority_session_id,
|
|
3918
|
+
authority_access_token_id, authority_primitive_kind, authority_primitive_id,
|
|
3919
|
+
authority_kernel_operation, authority_delegation_kind, authority_delegation_id,
|
|
3920
|
+
authority_delegation_session_id, created_at
|
|
3921
|
+
)
|
|
3922
|
+
SELECT
|
|
3923
|
+
project_id, id, executor_kind, executor_id, source_kind, source_id,
|
|
3924
|
+
requested_by_user_id, requested_by_service_account_id, correlation_id, parent_execution_id,
|
|
3925
|
+
authority_kind, authority_user_id, authority_service_account_id, authority_session_id,
|
|
3926
|
+
authority_access_token_id, authority_primitive_kind, authority_primitive_id,
|
|
3927
|
+
authority_kernel_operation, NULL, NULL, NULL, created_at
|
|
3928
|
+
FROM executions;
|
|
3929
|
+
|
|
3930
|
+
DROP TABLE executions;
|
|
3931
|
+
ALTER TABLE executions_v2 RENAME TO executions;
|
|
3932
|
+
`;
|
|
3933
|
+
|
|
3635
3934
|
// src/migrations.ts
|
|
3636
3935
|
var MIGRATIONS_TABLE_SQL = `
|
|
3637
3936
|
CREATE TABLE IF NOT EXISTS sixb_migrations (
|
|
@@ -3700,7 +3999,9 @@ var sqliteStorageMigrations = defineMigrations({
|
|
|
3700
3999
|
sqliteSql("031-subagent-runs", _031_subagent_runs_default),
|
|
3701
4000
|
sqliteSql("032-conversation-run-spec", _032_conversation_run_spec_default),
|
|
3702
4001
|
sqliteSql("033-retire-agent-definitions", _033_retire_agent_definitions_default),
|
|
3703
|
-
sqliteSql("034-device-authorizations", _034_device_authorizations_default)
|
|
4002
|
+
sqliteSql("034-device-authorizations", _034_device_authorizations_default),
|
|
4003
|
+
sqliteSql("035-share-grants", _035_share_grants_default),
|
|
4004
|
+
sqliteSql("036-share-sessions", _036_share_sessions_default)
|
|
3704
4005
|
]
|
|
3705
4006
|
});
|
|
3706
4007
|
function sqliteStoragePath(basePath) {
|
|
@@ -3879,6 +4180,7 @@ function closeSqliteStoreConnection(connection) {
|
|
|
3879
4180
|
}
|
|
3880
4181
|
}
|
|
3881
4182
|
var activeImmediateTransactions = new WeakSet;
|
|
4183
|
+
var activeDeferredReadTransactions = new WeakSet;
|
|
3882
4184
|
function runImmediateTransaction(db, run) {
|
|
3883
4185
|
if (activeImmediateTransactions.has(db)) {
|
|
3884
4186
|
return run();
|
|
@@ -3916,6 +4218,26 @@ async function runImmediateTransactionAsync(db, run) {
|
|
|
3916
4218
|
activeImmediateTransactions.delete(db);
|
|
3917
4219
|
}
|
|
3918
4220
|
}
|
|
4221
|
+
function runDeferredReadTransaction(db, run) {
|
|
4222
|
+
if (activeImmediateTransactions.has(db) || activeDeferredReadTransactions.has(db)) {
|
|
4223
|
+
return run();
|
|
4224
|
+
}
|
|
4225
|
+
if (db.inTransaction) {
|
|
4226
|
+
throw new Error("[SixbSqlite] Selected object reads cannot join an unverified SQLite transaction.");
|
|
4227
|
+
}
|
|
4228
|
+
db.run("BEGIN DEFERRED");
|
|
4229
|
+
activeDeferredReadTransactions.add(db);
|
|
4230
|
+
try {
|
|
4231
|
+
const result = run();
|
|
4232
|
+
db.run("COMMIT");
|
|
4233
|
+
return result;
|
|
4234
|
+
} catch (error) {
|
|
4235
|
+
rollbackQuietly2(db);
|
|
4236
|
+
throw error;
|
|
4237
|
+
} finally {
|
|
4238
|
+
activeDeferredReadTransactions.delete(db);
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
3919
4241
|
function rollbackQuietly2(db) {
|
|
3920
4242
|
try {
|
|
3921
4243
|
db.run("ROLLBACK");
|
|
@@ -4602,6 +4924,9 @@ import {
|
|
|
4602
4924
|
function isUniqueConstraintError2(error) {
|
|
4603
4925
|
return error instanceof Error && error.message.includes("UNIQUE constraint failed");
|
|
4604
4926
|
}
|
|
4927
|
+
function isForeignKeyConstraintError(error) {
|
|
4928
|
+
return error instanceof Error && error.message.includes("FOREIGN KEY constraint failed");
|
|
4929
|
+
}
|
|
4605
4930
|
|
|
4606
4931
|
// src/agents/messages.ts
|
|
4607
4932
|
class SqliteAgentMessageStore {
|
|
@@ -9081,15 +9406,18 @@ import { ExecutionStorageError } from "@sixb/core/storage";
|
|
|
9081
9406
|
class SqliteExecutionStorage {
|
|
9082
9407
|
db;
|
|
9083
9408
|
auth;
|
|
9084
|
-
|
|
9409
|
+
shareSessions;
|
|
9410
|
+
constructor(db, auth, shareSessions) {
|
|
9085
9411
|
this.db = db;
|
|
9086
9412
|
this.auth = auth;
|
|
9413
|
+
this.shareSessions = shareSessions;
|
|
9087
9414
|
}
|
|
9088
9415
|
async create(input) {
|
|
9089
9416
|
const record = normalizeExecutionRecord(input);
|
|
9090
9417
|
await validateExecutionRecordReferences(record, {
|
|
9091
9418
|
auth: this.auth,
|
|
9092
|
-
getExecution: (params) => this.getById(params)
|
|
9419
|
+
getExecution: (params) => this.getById(params),
|
|
9420
|
+
getShareSession: (params) => this.shareSessions.getById(params)
|
|
9093
9421
|
});
|
|
9094
9422
|
const row = executionRecordToStorageRow(record);
|
|
9095
9423
|
try {
|
|
@@ -9113,9 +9441,12 @@ class SqliteExecutionStorage {
|
|
|
9113
9441
|
authority_primitive_kind,
|
|
9114
9442
|
authority_primitive_id,
|
|
9115
9443
|
authority_kernel_operation,
|
|
9444
|
+
authority_delegation_kind,
|
|
9445
|
+
authority_delegation_id,
|
|
9446
|
+
authority_delegation_session_id,
|
|
9116
9447
|
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());
|
|
9448
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
9449
|
+
`).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.authorityDelegationKind, row.authorityDelegationId, row.authorityDelegationSessionId, row.createdAt.toISOString());
|
|
9119
9450
|
} catch (error) {
|
|
9120
9451
|
if (isDuplicateExecutionError(error)) {
|
|
9121
9452
|
throw new ExecutionStorageError("duplicate_execution", `[SixbSqlite] Execution '${record.id}' already exists in project '${record.projectId}'.`, { cause: error });
|
|
@@ -9153,6 +9484,9 @@ function toStorageRow(row) {
|
|
|
9153
9484
|
authorityPrimitiveKind: row.authority_primitive_kind,
|
|
9154
9485
|
authorityPrimitiveId: row.authority_primitive_id,
|
|
9155
9486
|
authorityKernelOperation: row.authority_kernel_operation,
|
|
9487
|
+
authorityDelegationKind: row.authority_delegation_kind,
|
|
9488
|
+
authorityDelegationId: row.authority_delegation_id,
|
|
9489
|
+
authorityDelegationSessionId: row.authority_delegation_session_id,
|
|
9156
9490
|
createdAt: new Date(row.created_at)
|
|
9157
9491
|
};
|
|
9158
9492
|
}
|
|
@@ -9160,56 +9494,62 @@ function isDuplicateExecutionError(error) {
|
|
|
9160
9494
|
return error instanceof Error && error.message.includes("UNIQUE constraint failed: executions.project_id, executions.id");
|
|
9161
9495
|
}
|
|
9162
9496
|
|
|
9163
|
-
// src/
|
|
9164
|
-
import { linkBatchKey, objectBatchKey } from "@sixb/core/storage";
|
|
9165
|
-
|
|
9166
|
-
// src/object-query-compiler.ts
|
|
9497
|
+
// src/objects/query-compiler.ts
|
|
9167
9498
|
import {
|
|
9168
9499
|
ObjectQueryExecutionError
|
|
9169
9500
|
} from "@sixb/core";
|
|
9170
9501
|
var PAGE_TOKEN_PREFIX = "keyset:";
|
|
9171
|
-
var exactContext = { probeLimit: false };
|
|
9172
9502
|
var DEFAULT_EXPANSION_FANOUT = 1000;
|
|
9173
9503
|
function compileObjectQuery(projectId, query, options = {}) {
|
|
9174
|
-
const
|
|
9175
|
-
|
|
9504
|
+
const source = options.source ?? DEFAULT_OBJECT_QUERY_SOURCE;
|
|
9505
|
+
const ctx = { probeLimit: options.includeTotal === false, source };
|
|
9506
|
+
return source.wrapQuery(compileObjectQueryInternal(projectId, query, ctx));
|
|
9507
|
+
}
|
|
9508
|
+
var DEFAULT_OBJECT_QUERY_SOURCE = {
|
|
9509
|
+
objectsTable: "objects",
|
|
9510
|
+
linksTable: "links",
|
|
9511
|
+
wrapStatement: (sql, args = []) => ({ sql, args: [...args] }),
|
|
9512
|
+
wrapQuery: (query) => query
|
|
9513
|
+
};
|
|
9514
|
+
function exactContext(ctx) {
|
|
9515
|
+
return ctx.probeLimit ? { ...ctx, probeLimit: false } : ctx;
|
|
9176
9516
|
}
|
|
9177
9517
|
function compileObjectQueryInternal(projectId, query, ctx) {
|
|
9178
9518
|
switch (query.kind) {
|
|
9179
9519
|
case "start":
|
|
9180
|
-
return compileStart(projectId, query);
|
|
9520
|
+
return compileStart(projectId, query, ctx);
|
|
9181
9521
|
case "refs":
|
|
9182
|
-
return compileRefs(projectId, query);
|
|
9522
|
+
return compileRefs(projectId, query, ctx);
|
|
9183
9523
|
case "filter":
|
|
9184
|
-
return compileFilter(projectId, query.input, query.predicate);
|
|
9524
|
+
return compileFilter(projectId, query.input, query.predicate, ctx);
|
|
9185
9525
|
case "sort":
|
|
9186
9526
|
return compileSort(projectId, query.input, query.fields, ctx);
|
|
9187
9527
|
case "limit":
|
|
9188
9528
|
return compileLimit(projectId, query.input, query.limit, ctx);
|
|
9189
9529
|
case "page":
|
|
9190
|
-
return compilePage(projectId, query.input, query.pageSize, query.pageToken);
|
|
9530
|
+
return compilePage(projectId, query.input, query.pageSize, query.pageToken, ctx);
|
|
9191
9531
|
case "traverse":
|
|
9192
|
-
return compileTraversal(projectId, query.input, query.linkId, query.direction, query.sourceObjectTypeId);
|
|
9532
|
+
return compileTraversal(projectId, query.input, query.linkId, query.direction, query.sourceObjectTypeId, ctx);
|
|
9193
9533
|
case "set":
|
|
9194
|
-
return compileSet(projectId, query.op, query.inputs);
|
|
9534
|
+
return compileSet(projectId, query.op, query.inputs, ctx);
|
|
9195
9535
|
case "project":
|
|
9196
9536
|
return compileProject(projectId, query.input, query.properties, ctx);
|
|
9197
9537
|
case "text":
|
|
9198
|
-
return compileText(projectId, query.input, query.query, query.fields, query.fieldsByObjectType);
|
|
9538
|
+
return compileText(projectId, query.input, query.query, query.fields, query.fieldsByObjectType, ctx);
|
|
9199
9539
|
case "expand":
|
|
9200
|
-
return compileExpand(projectId, query.input, query.expansions);
|
|
9540
|
+
return compileExpand(projectId, query.input, query.expansions, ctx);
|
|
9201
9541
|
case "vector":
|
|
9202
9542
|
throw new Error(`[Sixb] SQLite object storage does not support query node '${query.kind}'`);
|
|
9203
9543
|
}
|
|
9204
9544
|
}
|
|
9205
|
-
function compileStart(projectId, query) {
|
|
9545
|
+
function compileStart(projectId, query, ctx) {
|
|
9206
9546
|
if (query.includeSubtypes === true) {
|
|
9207
9547
|
throw new Error("[Sixb] SQLite object storage does not support start.includeSubtypes");
|
|
9208
9548
|
}
|
|
9209
9549
|
const order = compileOrder(identityOrderFields());
|
|
9210
9550
|
const sql = `
|
|
9211
9551
|
SELECT *, properties AS _cursor_properties
|
|
9212
|
-
FROM
|
|
9552
|
+
FROM ${ctx.source.objectsTable}
|
|
9213
9553
|
WHERE project_id = ? AND object_type_id = ?
|
|
9214
9554
|
ORDER BY ${order.sql}
|
|
9215
9555
|
`;
|
|
@@ -9217,7 +9557,7 @@ function compileStart(projectId, query) {
|
|
|
9217
9557
|
return {
|
|
9218
9558
|
sql,
|
|
9219
9559
|
args,
|
|
9220
|
-
totalSql:
|
|
9560
|
+
totalSql: `SELECT COUNT(*) as total FROM ${ctx.source.objectsTable} WHERE project_id = ? AND object_type_id = ?`,
|
|
9221
9561
|
totalArgs: [projectId, query.objectTypeId],
|
|
9222
9562
|
order,
|
|
9223
9563
|
hasMore: () => false,
|
|
@@ -9227,7 +9567,7 @@ function compileStart(projectId, query) {
|
|
|
9227
9567
|
}
|
|
9228
9568
|
};
|
|
9229
9569
|
}
|
|
9230
|
-
function compileRefs(projectId, query) {
|
|
9570
|
+
function compileRefs(projectId, query, ctx) {
|
|
9231
9571
|
if (query.refs.length === 0) {
|
|
9232
9572
|
throw new Error("[Sixb] SQLite object storage requires at least one ref");
|
|
9233
9573
|
}
|
|
@@ -9241,10 +9581,9 @@ function compileRefs(projectId, query) {
|
|
|
9241
9581
|
FROM json_each(?) AS ref
|
|
9242
9582
|
`;
|
|
9243
9583
|
const sql = `
|
|
9244
|
-
WITH requested AS (${requested})
|
|
9245
9584
|
SELECT selected.*, selected.properties AS _cursor_properties
|
|
9246
|
-
FROM requested
|
|
9247
|
-
JOIN
|
|
9585
|
+
FROM (${requested}) AS requested
|
|
9586
|
+
JOIN ${ctx.source.objectsTable} AS selected
|
|
9248
9587
|
ON selected.project_id = ?
|
|
9249
9588
|
AND selected.object_type_id = requested.object_type_id
|
|
9250
9589
|
AND selected.primary_id = requested.primary_id
|
|
@@ -9254,10 +9593,9 @@ function compileRefs(projectId, query) {
|
|
|
9254
9593
|
sql,
|
|
9255
9594
|
args: [refsJson, projectId, ...selectedOrder.args],
|
|
9256
9595
|
totalSql: `
|
|
9257
|
-
WITH requested AS (${requested})
|
|
9258
9596
|
SELECT COUNT(*) AS total
|
|
9259
|
-
FROM requested
|
|
9260
|
-
JOIN
|
|
9597
|
+
FROM (${requested}) AS requested
|
|
9598
|
+
JOIN ${ctx.source.objectsTable} AS selected
|
|
9261
9599
|
ON selected.project_id = ?
|
|
9262
9600
|
AND selected.object_type_id = requested.object_type_id
|
|
9263
9601
|
AND selected.primary_id = requested.primary_id
|
|
@@ -9271,12 +9609,12 @@ function compileRefs(projectId, query) {
|
|
|
9271
9609
|
}
|
|
9272
9610
|
};
|
|
9273
9611
|
}
|
|
9274
|
-
function compileFilter(projectId, inputQuery, predicateNode) {
|
|
9612
|
+
function compileFilter(projectId, inputQuery, predicateNode, ctx) {
|
|
9275
9613
|
const predicate = compilePredicate(predicateNode);
|
|
9276
|
-
return compileWhere(projectId, inputQuery, predicate);
|
|
9614
|
+
return compileWhere(projectId, inputQuery, predicate, ctx);
|
|
9277
9615
|
}
|
|
9278
|
-
function compileWhere(projectId, inputQuery, predicate) {
|
|
9279
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9616
|
+
function compileWhere(projectId, inputQuery, predicate, ctx) {
|
|
9617
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9280
9618
|
const sql = `
|
|
9281
9619
|
SELECT *
|
|
9282
9620
|
FROM (${input.sql}) AS input
|
|
@@ -9300,15 +9638,15 @@ function compileWhere(projectId, inputQuery, predicate) {
|
|
|
9300
9638
|
}
|
|
9301
9639
|
};
|
|
9302
9640
|
}
|
|
9303
|
-
function compileText(projectId, inputQuery, query, fields, fieldsByObjectType) {
|
|
9641
|
+
function compileText(projectId, inputQuery, query, fields, fieldsByObjectType, ctx) {
|
|
9304
9642
|
const predicate = fields && fields.length > 0 ? compileTextPredicate(query, fields) : compileScopedTextPredicate(query, fieldsByObjectType);
|
|
9305
9643
|
if (!predicate) {
|
|
9306
9644
|
throw new Error("[Sixb] SQLite object text search requires fields or resolved text defaults");
|
|
9307
9645
|
}
|
|
9308
|
-
return compileWhere(projectId, inputQuery, predicate);
|
|
9646
|
+
return compileWhere(projectId, inputQuery, predicate, ctx);
|
|
9309
9647
|
}
|
|
9310
9648
|
function compileSort(projectId, inputQuery, fields, ctx) {
|
|
9311
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9649
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9312
9650
|
const probeInput = ctx.probeLimit && needsLimitProbe(inputQuery) ? compileObjectQueryInternal(projectId, inputQuery, ctx) : undefined;
|
|
9313
9651
|
const order = compileOrder(sortOrderFields(fields));
|
|
9314
9652
|
return {
|
|
@@ -9337,7 +9675,7 @@ function compileSort(projectId, inputQuery, fields, ctx) {
|
|
|
9337
9675
|
};
|
|
9338
9676
|
}
|
|
9339
9677
|
function compileLimit(projectId, inputQuery, rawLimit, ctx) {
|
|
9340
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9678
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9341
9679
|
const limit = Math.max(0, rawLimit);
|
|
9342
9680
|
const rowLimit = ctx.probeLimit ? limit + 1 : limit;
|
|
9343
9681
|
return {
|
|
@@ -9361,8 +9699,8 @@ function compileLimit(projectId, inputQuery, rawLimit, ctx) {
|
|
|
9361
9699
|
}
|
|
9362
9700
|
};
|
|
9363
9701
|
}
|
|
9364
|
-
function compilePage(projectId, inputQuery, rawPageSize, pageToken) {
|
|
9365
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9702
|
+
function compilePage(projectId, inputQuery, rawPageSize, pageToken, ctx) {
|
|
9703
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9366
9704
|
const pageSize = Math.max(0, rawPageSize);
|
|
9367
9705
|
const cursor = pageToken ? decodePageToken(pageToken, input.order.fields) : undefined;
|
|
9368
9706
|
const cursorPredicate = cursor ? compileKeysetPredicate(input.order.fields, cursor, input.order.propertyColumn) : undefined;
|
|
@@ -9391,27 +9729,27 @@ function compilePage(projectId, inputQuery, rawPageSize, pageToken) {
|
|
|
9391
9729
|
}
|
|
9392
9730
|
};
|
|
9393
9731
|
}
|
|
9394
|
-
function compileTraversal(projectId, inputQuery, linkId, direction, sourceObjectTypeId) {
|
|
9395
|
-
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext);
|
|
9732
|
+
function compileTraversal(projectId, inputQuery, linkId, direction, sourceObjectTypeId, ctx) {
|
|
9733
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9396
9734
|
const outputAlias = direction === "outgoing" ? "target_object" : "source_object";
|
|
9397
9735
|
const joinSql = direction === "outgoing" ? `
|
|
9398
|
-
JOIN
|
|
9736
|
+
JOIN ${ctx.source.linksTable} AS edge
|
|
9399
9737
|
ON edge.project_id = input.project_id
|
|
9400
9738
|
AND edge.source_type_id = input.object_type_id
|
|
9401
9739
|
AND edge.source_id = input.primary_id
|
|
9402
9740
|
AND edge.link_id = ?
|
|
9403
|
-
JOIN
|
|
9741
|
+
JOIN ${ctx.source.objectsTable} AS target_object
|
|
9404
9742
|
ON target_object.project_id = edge.project_id
|
|
9405
9743
|
AND target_object.object_type_id = edge.target_type_id
|
|
9406
9744
|
AND target_object.primary_id = edge.target_id
|
|
9407
9745
|
` : `
|
|
9408
|
-
JOIN
|
|
9746
|
+
JOIN ${ctx.source.linksTable} AS edge
|
|
9409
9747
|
ON edge.project_id = input.project_id
|
|
9410
9748
|
AND edge.target_type_id = input.object_type_id
|
|
9411
9749
|
AND edge.target_id = input.primary_id
|
|
9412
9750
|
AND edge.link_id = ?${sourceObjectTypeId === undefined ? "" : `
|
|
9413
9751
|
AND edge.source_type_id = ?`}
|
|
9414
|
-
JOIN
|
|
9752
|
+
JOIN ${ctx.source.objectsTable} AS source_object
|
|
9415
9753
|
ON source_object.project_id = edge.project_id
|
|
9416
9754
|
AND source_object.object_type_id = edge.source_type_id
|
|
9417
9755
|
AND source_object.primary_id = edge.source_id
|
|
@@ -9443,9 +9781,9 @@ function compileTraversal(projectId, inputQuery, linkId, direction, sourceObject
|
|
|
9443
9781
|
}
|
|
9444
9782
|
};
|
|
9445
9783
|
}
|
|
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" }, "");
|
|
9784
|
+
function compileExpand(projectId, inputQuery, expansions, ctx) {
|
|
9785
|
+
const input = compileObjectQueryInternal(projectId, inputQuery, exactContext(ctx));
|
|
9786
|
+
const expand = compileExpansionsObject(expansions, { project: "input.project_id", type: "input.object_type_id", id: "input.primary_id" }, "", ctx);
|
|
9449
9787
|
const inputOrder = compileOrder(input.order.fields, "input", "input._cursor_properties");
|
|
9450
9788
|
const sql = `
|
|
9451
9789
|
SELECT input.*, ${expand.sql} AS _expand
|
|
@@ -9464,18 +9802,18 @@ function compileExpand(projectId, inputQuery, expansions) {
|
|
|
9464
9802
|
nextPageToken: input.nextPageToken
|
|
9465
9803
|
};
|
|
9466
9804
|
}
|
|
9467
|
-
function compileExpansionsObject(expansions, parent, pathPrefix) {
|
|
9805
|
+
function compileExpansionsObject(expansions, parent, pathPrefix, ctx) {
|
|
9468
9806
|
const parts = [];
|
|
9469
9807
|
const args = [];
|
|
9470
9808
|
expansions.forEach((expansion, index) => {
|
|
9471
9809
|
const path = pathPrefix === "" ? `${index}` : `${pathPrefix}_${index}`;
|
|
9472
|
-
const value = compileExpansionValue(expansion, parent, path);
|
|
9810
|
+
const value = compileExpansionValue(expansion, parent, path, ctx);
|
|
9473
9811
|
parts.push("?", `json(${value.sql})`);
|
|
9474
9812
|
args.push(expansion.linkId, ...value.args);
|
|
9475
9813
|
});
|
|
9476
9814
|
return { sql: `json_object(${parts.join(", ")})`, args };
|
|
9477
9815
|
}
|
|
9478
|
-
function compileExpansionValue(expansion, parent, path) {
|
|
9816
|
+
function compileExpansionValue(expansion, parent, path, ctx) {
|
|
9479
9817
|
const edge = `edge_${path}`;
|
|
9480
9818
|
const target = `tgt_${path}`;
|
|
9481
9819
|
const ranked = `ranked_${path}`;
|
|
@@ -9484,7 +9822,7 @@ function compileExpansionValue(expansion, parent, path) {
|
|
|
9484
9822
|
const neighborId = incoming ? `${edge}.source_id` : `${edge}.target_id`;
|
|
9485
9823
|
const parentType = incoming ? `${edge}.target_type_id` : `${edge}.source_type_id`;
|
|
9486
9824
|
const parentId = incoming ? `${edge}.target_id` : `${edge}.source_id`;
|
|
9487
|
-
const child = compileExpansionChildJson(expansion, edge, target, path);
|
|
9825
|
+
const child = compileExpansionChildJson(expansion, edge, target, path, ctx);
|
|
9488
9826
|
const order = compileExpansionOrder(expansion, target, neighborType, neighborId);
|
|
9489
9827
|
const whereParts = [
|
|
9490
9828
|
`${edge}.project_id = ${parent.project}`,
|
|
@@ -9499,8 +9837,8 @@ function compileExpansionValue(expansion, parent, path) {
|
|
|
9499
9837
|
}
|
|
9500
9838
|
const inner = `
|
|
9501
9839
|
SELECT ${child.sql} AS elem, row_number() OVER (ORDER BY ${order.sql}) AS _ord
|
|
9502
|
-
FROM
|
|
9503
|
-
JOIN
|
|
9840
|
+
FROM ${ctx.source.linksTable} AS ${edge}
|
|
9841
|
+
JOIN ${ctx.source.objectsTable} AS ${target}
|
|
9504
9842
|
ON ${target}.project_id = ${edge}.project_id
|
|
9505
9843
|
AND ${target}.object_type_id = ${neighborType}
|
|
9506
9844
|
AND ${target}.primary_id = ${neighborId}
|
|
@@ -9519,7 +9857,7 @@ function compileExpansionValue(expansion, parent, path) {
|
|
|
9519
9857
|
args: [...innerArgs, limit]
|
|
9520
9858
|
};
|
|
9521
9859
|
}
|
|
9522
|
-
function compileExpansionChildJson(expansion, edge, target, path) {
|
|
9860
|
+
function compileExpansionChildJson(expansion, edge, target, path, ctx) {
|
|
9523
9861
|
const fields = [
|
|
9524
9862
|
`'projectId', ${target}.project_id`,
|
|
9525
9863
|
`'objectTypeId', ${target}.object_type_id`,
|
|
@@ -9537,7 +9875,7 @@ function compileExpansionChildJson(expansion, edge, target, path) {
|
|
|
9537
9875
|
project: `${target}.project_id`,
|
|
9538
9876
|
type: `${target}.object_type_id`,
|
|
9539
9877
|
id: `${target}.primary_id`
|
|
9540
|
-
}, path);
|
|
9878
|
+
}, path, ctx);
|
|
9541
9879
|
fields.push(`'links', ${nested.sql}`);
|
|
9542
9880
|
args.push(...nested.args);
|
|
9543
9881
|
}
|
|
@@ -9561,13 +9899,13 @@ function compileExpansionOrder(expansion, target, neighborType, neighborId) {
|
|
|
9561
9899
|
clauses.push(`${neighborType} ASC`, `${neighborId} ASC`);
|
|
9562
9900
|
return { sql: clauses.join(", "), args };
|
|
9563
9901
|
}
|
|
9564
|
-
function compileSet(projectId, op, inputs) {
|
|
9902
|
+
function compileSet(projectId, op, inputs, ctx) {
|
|
9565
9903
|
if (inputs.length === 0) {
|
|
9566
9904
|
const order2 = compileOrder(identityOrderFields());
|
|
9567
9905
|
return {
|
|
9568
9906
|
sql: `
|
|
9569
9907
|
SELECT *
|
|
9570
|
-
FROM
|
|
9908
|
+
FROM ${ctx.source.objectsTable}
|
|
9571
9909
|
WHERE 1 = 0
|
|
9572
9910
|
ORDER BY ${order2.sql}
|
|
9573
9911
|
`,
|
|
@@ -9582,14 +9920,14 @@ function compileSet(projectId, op, inputs) {
|
|
|
9582
9920
|
}
|
|
9583
9921
|
};
|
|
9584
9922
|
}
|
|
9585
|
-
const compiledInputs = inputs.map((input) => compileObjectQueryInternal(projectId, input, exactContext));
|
|
9923
|
+
const compiledInputs = inputs.map((input) => compileObjectQueryInternal(projectId, input, exactContext(ctx)));
|
|
9586
9924
|
const identities = compileSetIdentities(op, compiledInputs);
|
|
9587
9925
|
const order = compileOrder(identityOrderFields());
|
|
9588
9926
|
const selectedOrder = compileOrder(identityOrderFields(), "selected");
|
|
9589
9927
|
const sql = `
|
|
9590
9928
|
SELECT selected.*, selected.properties AS _cursor_properties
|
|
9591
9929
|
FROM (${identities.sql}) AS ids
|
|
9592
|
-
JOIN
|
|
9930
|
+
JOIN ${ctx.source.objectsTable} AS selected
|
|
9593
9931
|
ON selected.project_id = ?
|
|
9594
9932
|
AND selected.object_type_id = ids.object_type_id
|
|
9595
9933
|
AND selected.primary_id = ids.primary_id
|
|
@@ -9674,7 +10012,7 @@ function compileProjectionExpression(properties) {
|
|
|
9674
10012
|
sql: `
|
|
9675
10013
|
COALESCE(
|
|
9676
10014
|
(
|
|
9677
|
-
SELECT json_group_object(projected.key, projected
|
|
10015
|
+
SELECT json_group_object(projected.key, ${sqliteJsonEachValue("projected")})
|
|
9678
10016
|
FROM json_each(input.properties) AS projected
|
|
9679
10017
|
WHERE projected.key IN (${properties.map(() => "?").join(", ")})
|
|
9680
10018
|
),
|
|
@@ -9684,6 +10022,13 @@ function compileProjectionExpression(properties) {
|
|
|
9684
10022
|
args: [...properties]
|
|
9685
10023
|
};
|
|
9686
10024
|
}
|
|
10025
|
+
function sqliteJsonEachValue(alias) {
|
|
10026
|
+
return `CASE ${alias}.type
|
|
10027
|
+
WHEN 'true' THEN json('true')
|
|
10028
|
+
WHEN 'false' THEN json('false')
|
|
10029
|
+
ELSE ${alias}.value
|
|
10030
|
+
END`;
|
|
10031
|
+
}
|
|
9687
10032
|
function compilePredicate(predicate) {
|
|
9688
10033
|
if ("scalarKind" in predicate && predicate.scalarKind === "decimal" && (predicate.op === "lt" || predicate.op === "lte" || predicate.op === "gt" || predicate.op === "gte")) {
|
|
9689
10034
|
throw new ObjectQueryExecutionError("exact_decimal_not_supported", "SQLite object storage cannot push down exact decimal predicates", "$.predicate");
|
|
@@ -10006,112 +10351,131 @@ function isPlainObject(value) {
|
|
|
10006
10351
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10007
10352
|
}
|
|
10008
10353
|
|
|
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
|
-
};
|
|
10354
|
+
// src/objects/reader.ts
|
|
10355
|
+
import { linkBatchKey, objectBatchKey } from "@sixb/core/storage";
|
|
10075
10356
|
|
|
10076
|
-
|
|
10077
|
-
|
|
10078
|
-
|
|
10079
|
-
|
|
10080
|
-
|
|
10081
|
-
|
|
10082
|
-
|
|
10083
|
-
|
|
10084
|
-
|
|
10357
|
+
// src/objects/rows.ts
|
|
10358
|
+
function rowToObject(row) {
|
|
10359
|
+
return {
|
|
10360
|
+
projectId: row.project_id,
|
|
10361
|
+
objectTypeId: row.object_type_id,
|
|
10362
|
+
primaryId: row.primary_id,
|
|
10363
|
+
properties: JSON.parse(row.properties),
|
|
10364
|
+
createdAt: new Date(row.created_at),
|
|
10365
|
+
updatedAt: new Date(row.updated_at),
|
|
10366
|
+
version: row.version,
|
|
10367
|
+
lastCommitId: row.last_commit_id
|
|
10368
|
+
};
|
|
10369
|
+
}
|
|
10370
|
+
function queryRowToObject(row) {
|
|
10371
|
+
const base = rowToObject(row);
|
|
10372
|
+
const links = reviveExpandedLinks(parseExpandColumn(row._expand));
|
|
10373
|
+
return links ? { ...base, links } : base;
|
|
10374
|
+
}
|
|
10375
|
+
function rowToLink(row) {
|
|
10376
|
+
return {
|
|
10377
|
+
projectId: row.project_id,
|
|
10378
|
+
sourceTypeId: row.source_type_id,
|
|
10379
|
+
sourceId: row.source_id,
|
|
10380
|
+
linkId: row.link_id,
|
|
10381
|
+
targetTypeId: row.target_type_id,
|
|
10382
|
+
targetId: row.target_id,
|
|
10383
|
+
...row.properties === null ? {} : { properties: JSON.parse(row.properties) },
|
|
10384
|
+
createdAt: new Date(row.created_at),
|
|
10385
|
+
updatedAt: new Date(row.updated_at),
|
|
10386
|
+
lastCommitId: row.last_commit_id
|
|
10387
|
+
};
|
|
10388
|
+
}
|
|
10389
|
+
function parseExpandColumn(value) {
|
|
10390
|
+
if (typeof value !== "string")
|
|
10391
|
+
return value ?? undefined;
|
|
10392
|
+
return JSON.parse(value);
|
|
10393
|
+
}
|
|
10394
|
+
function reviveExpandedLinks(value) {
|
|
10395
|
+
if (!isPlainObject2(value))
|
|
10396
|
+
return;
|
|
10397
|
+
const links = {};
|
|
10398
|
+
for (const [linkId, raw] of Object.entries(value)) {
|
|
10399
|
+
links[linkId] = reviveExpandedLinkValue(raw);
|
|
10085
10400
|
}
|
|
10086
|
-
|
|
10087
|
-
|
|
10401
|
+
return links;
|
|
10402
|
+
}
|
|
10403
|
+
function reviveExpandedLinkValue(value) {
|
|
10404
|
+
if (value === null || value === undefined)
|
|
10405
|
+
return null;
|
|
10406
|
+
if (Array.isArray(value))
|
|
10407
|
+
return value.map(reviveExpandedRow);
|
|
10408
|
+
return reviveExpandedRow(value);
|
|
10409
|
+
}
|
|
10410
|
+
function reviveExpandedRow(value) {
|
|
10411
|
+
const row = isPlainObject2(value) ? value : {};
|
|
10412
|
+
const expanded = {
|
|
10413
|
+
projectId: String(row.projectId),
|
|
10414
|
+
objectTypeId: String(row.objectTypeId),
|
|
10415
|
+
primaryId: String(row.primaryId),
|
|
10416
|
+
properties: isPlainObject2(row.properties) ? row.properties : {},
|
|
10417
|
+
createdAt: new Date(row.createdAt),
|
|
10418
|
+
updatedAt: new Date(row.updatedAt),
|
|
10419
|
+
version: Number(row.version),
|
|
10420
|
+
lastCommitId: String(row.lastCommitId)
|
|
10421
|
+
};
|
|
10422
|
+
if (isPlainObject2(row.linkProperties) && Object.keys(row.linkProperties).length > 0) {
|
|
10423
|
+
expanded.linkProperties = row.linkProperties;
|
|
10088
10424
|
}
|
|
10089
|
-
|
|
10425
|
+
const links = reviveExpandedLinks(row.links);
|
|
10426
|
+
if (links)
|
|
10427
|
+
expanded.links = links;
|
|
10428
|
+
return expanded;
|
|
10429
|
+
}
|
|
10430
|
+
function isPlainObject2(value) {
|
|
10431
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10432
|
+
}
|
|
10433
|
+
|
|
10434
|
+
// src/objects/reader.ts
|
|
10435
|
+
class SqliteObjectReader {
|
|
10436
|
+
db;
|
|
10437
|
+
source;
|
|
10438
|
+
constructor(db, source) {
|
|
10439
|
+
this.db = db;
|
|
10440
|
+
this.source = source;
|
|
10441
|
+
}
|
|
10442
|
+
queryObjects(params) {
|
|
10443
|
+
const source = this.source;
|
|
10090
10444
|
const compiled = compileObjectQuery(params.projectId, params.query, {
|
|
10091
|
-
includeTotal: params.includeTotal
|
|
10445
|
+
includeTotal: params.includeTotal,
|
|
10446
|
+
source
|
|
10092
10447
|
});
|
|
10093
10448
|
const total = params.includeTotal === false ? undefined : readTotal(this.db, compiled);
|
|
10094
10449
|
const rawRows = this.db.query(compiled.sql).all(...compiled.args);
|
|
10095
10450
|
const rows = compiled.trimRows(rawRows);
|
|
10096
10451
|
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
10452
|
return {
|
|
10098
|
-
objects: rows.map((row) =>
|
|
10453
|
+
objects: rows.map((row) => queryRowToObject(row)),
|
|
10099
10454
|
hasMore,
|
|
10100
10455
|
nextPageToken: compiled.nextPageToken(rows, rawRows.length),
|
|
10101
10456
|
...total === undefined ? {} : { total }
|
|
10102
10457
|
};
|
|
10103
10458
|
}
|
|
10104
|
-
|
|
10459
|
+
countObjects(params) {
|
|
10460
|
+
const source = this.source;
|
|
10105
10461
|
return {
|
|
10106
|
-
count: readTotal(this.db, compileObjectQuery(params.projectId, stripOuterRowShape(params.query)
|
|
10462
|
+
count: readTotal(this.db, compileObjectQuery(params.projectId, stripOuterRowShape(params.query), {
|
|
10463
|
+
source
|
|
10464
|
+
}))
|
|
10107
10465
|
};
|
|
10108
10466
|
}
|
|
10109
|
-
|
|
10110
|
-
const
|
|
10467
|
+
existsObjects(params) {
|
|
10468
|
+
const source = this.source;
|
|
10469
|
+
const compiled = compileObjectQuery(params.projectId, existsProbeQuery(params.query), {
|
|
10470
|
+
source
|
|
10471
|
+
});
|
|
10111
10472
|
return { exists: this.db.query(compiled.sql).get(...compiled.args) !== null };
|
|
10112
10473
|
}
|
|
10113
|
-
|
|
10114
|
-
const
|
|
10474
|
+
facetObjects(params) {
|
|
10475
|
+
const source = this.source;
|
|
10476
|
+
const compiled = compileObjectQuery(params.projectId, stripOuterRowShape(params.query), {
|
|
10477
|
+
source
|
|
10478
|
+
});
|
|
10115
10479
|
return {
|
|
10116
10480
|
facets: params.facets.map((facet) => ({
|
|
10117
10481
|
propertyId: facet.propertyId,
|
|
@@ -10119,14 +10483,43 @@ class SqliteObjectStorage {
|
|
|
10119
10483
|
}))
|
|
10120
10484
|
};
|
|
10121
10485
|
}
|
|
10122
|
-
|
|
10123
|
-
const
|
|
10124
|
-
|
|
10486
|
+
getByPrimaryId(params) {
|
|
10487
|
+
const source = this.source;
|
|
10488
|
+
const objectsTable = source.objectsTable;
|
|
10489
|
+
const statement = source.wrapStatement(`SELECT * FROM ${objectsTable} WHERE project_id = ? AND object_type_id = ? AND primary_id = ?`, [params.projectId, params.objectTypeId, params.primaryId]);
|
|
10490
|
+
const row = this.db.query(statement.sql).get(...statement.args);
|
|
10491
|
+
return row ? rowToObject(row) : null;
|
|
10125
10492
|
}
|
|
10126
|
-
|
|
10493
|
+
selectsObjectProperties(params) {
|
|
10494
|
+
const source = this.source;
|
|
10495
|
+
const result = params.items.map(() => false);
|
|
10496
|
+
if (params.items.length === 0)
|
|
10497
|
+
return result;
|
|
10498
|
+
const items = params.items.map((item, batchIndex) => ({ ...item, batchIndex }));
|
|
10499
|
+
const requestedType = "CAST(json_extract(requested.value, '$.objectTypeId') AS TEXT)";
|
|
10500
|
+
const requestedId = "CAST(json_extract(requested.value, '$.primaryId') AS TEXT)";
|
|
10501
|
+
const requestedProperty = "CAST(json_extract(requested.value, '$.propertyId') AS TEXT)";
|
|
10502
|
+
const selected = "objectPropertyPermissionsTable" in source;
|
|
10503
|
+
const storedTable = selected ? source.objectPropertyPermissionsTable : source.objectsTable;
|
|
10504
|
+
const propertyJoin = selected ? `AND stored.property_id = ${requestedProperty}` : "";
|
|
10505
|
+
const statement = source.wrapStatement(`SELECT DISTINCT
|
|
10506
|
+
CAST(json_extract(requested.value, '$.batchIndex') AS INTEGER) AS _batch_index
|
|
10507
|
+
FROM ${storedTable} AS stored
|
|
10508
|
+
JOIN json_each(?) AS requested
|
|
10509
|
+
ON stored.object_type_id = ${requestedType}
|
|
10510
|
+
AND stored.primary_id = ${requestedId}
|
|
10511
|
+
${propertyJoin}
|
|
10512
|
+
WHERE stored.project_id = ?`, [JSON.stringify(items), params.projectId]);
|
|
10513
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10514
|
+
for (const row of rows)
|
|
10515
|
+
result[row._batch_index] = true;
|
|
10516
|
+
return result;
|
|
10517
|
+
}
|
|
10518
|
+
listLinks(params) {
|
|
10519
|
+
const source = this.source;
|
|
10127
10520
|
const direction = params.direction ?? "outgoing";
|
|
10128
10521
|
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
|
|
10522
|
+
let query = `SELECT * FROM ${source.linksTable} WHERE project_id = ? AND ${directionWhere}`;
|
|
10130
10523
|
const args = direction === "both" ? [
|
|
10131
10524
|
params.projectId,
|
|
10132
10525
|
params.objectTypeId,
|
|
@@ -10138,64 +10531,104 @@ class SqliteObjectStorage {
|
|
|
10138
10531
|
query += " AND link_id = ?";
|
|
10139
10532
|
args.push(params.linkId);
|
|
10140
10533
|
}
|
|
10141
|
-
const
|
|
10142
|
-
|
|
10534
|
+
const statement = source.wrapStatement(query, args);
|
|
10535
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10536
|
+
return rows.map((row) => rowToLink(row));
|
|
10143
10537
|
}
|
|
10144
|
-
|
|
10538
|
+
getByPrimaryIdBatch(params) {
|
|
10539
|
+
const source = this.source;
|
|
10145
10540
|
const result = new Map;
|
|
10146
10541
|
if (params.items.length === 0)
|
|
10147
10542
|
return result;
|
|
10148
|
-
const
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
|
|
10543
|
+
const items = params.items.map((item, batchIndex) => ({ ...item, batchIndex }));
|
|
10544
|
+
const statement = source.wrapStatement(`
|
|
10545
|
+
SELECT
|
|
10546
|
+
object.*,
|
|
10547
|
+
CAST(json_extract(requested.value, '$.batchIndex') AS INTEGER) AS _batch_index
|
|
10548
|
+
FROM json_each(?) AS requested
|
|
10549
|
+
JOIN ${source.objectsTable} AS object
|
|
10550
|
+
ON object.project_id = ?
|
|
10551
|
+
AND object.object_type_id = json_extract(requested.value, '$.objectTypeId')
|
|
10552
|
+
AND object.primary_id = json_extract(requested.value, '$.primaryId')
|
|
10553
|
+
`, [JSON.stringify(items), params.projectId]);
|
|
10554
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10555
|
+
const rowsByIndex = new Map(rows.map((row) => [row._batch_index, row]));
|
|
10556
|
+
for (const [index, item] of params.items.entries()) {
|
|
10557
|
+
const row = rowsByIndex.get(index);
|
|
10558
|
+
if (row)
|
|
10559
|
+
result.set(objectBatchKey(item.objectTypeId, item.primaryId), rowToObject(row));
|
|
10158
10560
|
}
|
|
10159
10561
|
return result;
|
|
10160
10562
|
}
|
|
10161
|
-
|
|
10563
|
+
listLinksBatch(params) {
|
|
10564
|
+
const source = this.source;
|
|
10162
10565
|
const result = new Map;
|
|
10163
10566
|
if (params.items.length === 0)
|
|
10164
10567
|
return result;
|
|
10165
|
-
const
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10568
|
+
const direction = params.direction ?? "outgoing";
|
|
10569
|
+
const requestedType = "CAST(json_extract(requested.value, '$.objectTypeId') AS TEXT)";
|
|
10570
|
+
const requestedId = "CAST(json_extract(requested.value, '$.objectId') AS TEXT)";
|
|
10571
|
+
const requestedLink = "CAST(json_extract(requested.value, '$.linkId') AS TEXT)";
|
|
10572
|
+
const outgoing = `stored.source_type_id = ${requestedType} AND stored.source_id = ${requestedId}`;
|
|
10573
|
+
const incoming = `stored.target_type_id = ${requestedType} AND stored.target_id = ${requestedId}`;
|
|
10574
|
+
const directionJoin = direction === "both" ? `((${outgoing}) OR (${incoming}))` : direction === "incoming" ? incoming : outgoing;
|
|
10575
|
+
const items = params.items.map((item, batchIndex) => ({ ...item, batchIndex }));
|
|
10576
|
+
const statement = source.wrapStatement(`
|
|
10577
|
+
SELECT
|
|
10578
|
+
stored.*,
|
|
10579
|
+
CAST(json_extract(requested.value, '$.batchIndex') AS INTEGER) AS _batch_index
|
|
10580
|
+
FROM ${source.linksTable} AS stored
|
|
10581
|
+
JOIN json_each(?) AS requested
|
|
10582
|
+
ON ${directionJoin}
|
|
10583
|
+
AND stored.link_id = ${requestedLink}
|
|
10584
|
+
WHERE stored.project_id = ?
|
|
10585
|
+
ORDER BY _batch_index, source_type_id, source_id, link_id, target_type_id, target_id
|
|
10586
|
+
`, [JSON.stringify(items), params.projectId]);
|
|
10587
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10588
|
+
const rowsByIndex = params.items.map(() => new Map);
|
|
10589
|
+
for (const row of rows) {
|
|
10590
|
+
const link = rowToLink(row);
|
|
10591
|
+
rowsByIndex[row._batch_index]?.set(fullLinkIdentity(link), link);
|
|
10592
|
+
}
|
|
10593
|
+
for (const [index, item] of params.items.entries()) {
|
|
10594
|
+
const links = [...rowsByIndex[index]?.values() ?? []];
|
|
10595
|
+
if (links.length > 0) {
|
|
10596
|
+
result.set(linkBatchKey(item.objectTypeId, item.objectId, item.linkId), links);
|
|
10170
10597
|
}
|
|
10171
10598
|
}
|
|
10172
10599
|
return result;
|
|
10173
10600
|
}
|
|
10174
|
-
|
|
10175
|
-
|
|
10601
|
+
queryLinks(params) {
|
|
10602
|
+
const source = this.source;
|
|
10176
10603
|
if (params.objectRefs.length === 0 || params.endpointObjectTypeIds?.length === 0) {
|
|
10177
10604
|
return { links: [], hasMore: false };
|
|
10178
10605
|
}
|
|
10606
|
+
const requested = `
|
|
10607
|
+
SELECT DISTINCT
|
|
10608
|
+
json_extract(value, '$.objectTypeId') AS object_type_id,
|
|
10609
|
+
json_extract(value, '$.primaryId') AS object_id
|
|
10610
|
+
FROM json_each(?)
|
|
10611
|
+
`;
|
|
10612
|
+
const linksTable = source.linksTable;
|
|
10179
10613
|
const sourceJoin = `
|
|
10180
10614
|
SELECT link.*
|
|
10181
|
-
FROM
|
|
10182
|
-
JOIN requested
|
|
10615
|
+
FROM ${linksTable} AS link
|
|
10616
|
+
JOIN (${requested}) AS requested
|
|
10183
10617
|
ON requested.object_type_id = link.source_type_id
|
|
10184
10618
|
AND requested.object_id = link.source_id
|
|
10185
10619
|
WHERE link.project_id = ?
|
|
10186
10620
|
`;
|
|
10187
10621
|
const targetJoin = `
|
|
10188
10622
|
SELECT link.*
|
|
10189
|
-
FROM
|
|
10190
|
-
JOIN requested
|
|
10623
|
+
FROM ${linksTable} AS link
|
|
10624
|
+
JOIN (${requested}) AS requested
|
|
10191
10625
|
ON requested.object_type_id = link.target_type_id
|
|
10192
10626
|
AND requested.object_id = link.target_id
|
|
10193
10627
|
WHERE link.project_id = ?
|
|
10194
10628
|
`;
|
|
10195
10629
|
const incidentSql = params.direction === "outgoing" ? sourceJoin : params.direction === "incoming" ? targetJoin : `${sourceJoin} UNION ${targetJoin}`;
|
|
10196
|
-
const
|
|
10197
|
-
|
|
10198
|
-
args.push(params.projectId);
|
|
10630
|
+
const requestedJson = JSON.stringify(params.objectRefs);
|
|
10631
|
+
const args = params.direction === "both" ? [requestedJson, params.projectId, requestedJson, params.projectId] : [requestedJson, params.projectId];
|
|
10199
10632
|
const predicates = [];
|
|
10200
10633
|
if (params.linkId !== undefined) {
|
|
10201
10634
|
predicates.push("link_id = ?");
|
|
@@ -10212,24 +10645,622 @@ class SqliteObjectStorage {
|
|
|
10212
10645
|
}
|
|
10213
10646
|
args.push(params.limit + 1);
|
|
10214
10647
|
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);
|
|
10648
|
+
const statement = source.wrapStatement(`
|
|
10649
|
+
SELECT *
|
|
10650
|
+
FROM (${incidentSql}) AS incident
|
|
10651
|
+
${whereSql}
|
|
10652
|
+
ORDER BY source_type_id, source_id, link_id, target_type_id, target_id
|
|
10653
|
+
LIMIT ?
|
|
10654
|
+
`, args);
|
|
10655
|
+
const rows = this.db.query(statement.sql).all(...statement.args);
|
|
10228
10656
|
return {
|
|
10229
|
-
links: rows.slice(0, params.limit).map((row) =>
|
|
10657
|
+
links: rows.slice(0, params.limit).map((row) => rowToLink(row)),
|
|
10230
10658
|
hasMore: rows.length > params.limit
|
|
10231
10659
|
};
|
|
10232
10660
|
}
|
|
10661
|
+
list(params) {
|
|
10662
|
+
const source = this.source;
|
|
10663
|
+
let query = `SELECT * FROM ${source.objectsTable} WHERE project_id = ?`;
|
|
10664
|
+
const args = [params.projectId];
|
|
10665
|
+
if (params.objectTypeId) {
|
|
10666
|
+
if (typeof params.objectTypeId === "string") {
|
|
10667
|
+
query += " AND object_type_id = ?";
|
|
10668
|
+
args.push(params.objectTypeId);
|
|
10669
|
+
} else {
|
|
10670
|
+
query += ` AND object_type_id IN (${params.objectTypeId.map(() => "?").join(", ")})`;
|
|
10671
|
+
args.push(...params.objectTypeId);
|
|
10672
|
+
}
|
|
10673
|
+
}
|
|
10674
|
+
if (params.primaryIdPrefix) {
|
|
10675
|
+
query += " AND primary_id LIKE ?";
|
|
10676
|
+
args.push(`${params.primaryIdPrefix}%`);
|
|
10677
|
+
}
|
|
10678
|
+
if (params.primaryIdSuffix) {
|
|
10679
|
+
query += " AND primary_id LIKE ?";
|
|
10680
|
+
args.push(`%${params.primaryIdSuffix}`);
|
|
10681
|
+
}
|
|
10682
|
+
if (params.updatedAfter) {
|
|
10683
|
+
query += " AND updated_at >= ?";
|
|
10684
|
+
args.push(params.updatedAfter.toISOString());
|
|
10685
|
+
}
|
|
10686
|
+
if (params.updatedBefore) {
|
|
10687
|
+
query += " AND updated_at <= ?";
|
|
10688
|
+
args.push(params.updatedBefore.toISOString());
|
|
10689
|
+
}
|
|
10690
|
+
if (params.createdAfter) {
|
|
10691
|
+
query += " AND created_at >= ?";
|
|
10692
|
+
args.push(params.createdAfter.toISOString());
|
|
10693
|
+
}
|
|
10694
|
+
if (params.createdBefore) {
|
|
10695
|
+
query += " AND created_at <= ?";
|
|
10696
|
+
args.push(params.createdBefore.toISOString());
|
|
10697
|
+
}
|
|
10698
|
+
const countStatement = source.wrapStatement(`SELECT COUNT(*) as total FROM (${query}) AS filtered_objects`, args);
|
|
10699
|
+
const countResult = this.db.query(countStatement.sql).get(...countStatement.args);
|
|
10700
|
+
const total = countResult.total;
|
|
10701
|
+
const offset = params.offset ?? 0;
|
|
10702
|
+
const limit = params.limit ?? 50;
|
|
10703
|
+
if (limit === 0)
|
|
10704
|
+
return { objects: [], hasMore: offset < total, total };
|
|
10705
|
+
const orderBy = params.orderBy ?? "updatedAt";
|
|
10706
|
+
const order = params.order ?? "desc";
|
|
10707
|
+
const orderColumn = orderBy === "primaryId" ? "primary_id" : orderBy === "createdAt" ? "created_at" : "updated_at";
|
|
10708
|
+
query += ` ORDER BY ${orderColumn} ${order.toUpperCase()}`;
|
|
10709
|
+
query += " LIMIT ? OFFSET ?";
|
|
10710
|
+
args.push(limit + 1, offset);
|
|
10711
|
+
const rowsStatement = source.wrapStatement(query, args);
|
|
10712
|
+
const rows = this.db.query(rowsStatement.sql).all(...rowsStatement.args);
|
|
10713
|
+
const hasMore = rows.length > limit;
|
|
10714
|
+
const objects = rows.slice(0, limit).map((row) => rowToObject(row));
|
|
10715
|
+
return { objects, hasMore, total };
|
|
10716
|
+
}
|
|
10717
|
+
}
|
|
10718
|
+
function fullLinkIdentity(link) {
|
|
10719
|
+
return JSON.stringify([
|
|
10720
|
+
link.sourceTypeId,
|
|
10721
|
+
link.sourceId,
|
|
10722
|
+
link.linkId,
|
|
10723
|
+
link.targetTypeId,
|
|
10724
|
+
link.targetId
|
|
10725
|
+
]);
|
|
10726
|
+
}
|
|
10727
|
+
function assertLinkQueryLimit(limit) {
|
|
10728
|
+
if (!Number.isSafeInteger(limit) || limit <= 0) {
|
|
10729
|
+
throw new Error("Object link query limit must be a positive safe integer.");
|
|
10730
|
+
}
|
|
10731
|
+
}
|
|
10732
|
+
function readTotal(db, compiled) {
|
|
10733
|
+
const row = db.query(compiled.totalSql).get(...compiled.totalArgs);
|
|
10734
|
+
return row.total;
|
|
10735
|
+
}
|
|
10736
|
+
function readFacetBuckets(db, compiled, facet) {
|
|
10737
|
+
const path = sqliteJsonPath(facet.propertyId);
|
|
10738
|
+
const rows = db.query(`
|
|
10739
|
+
SELECT
|
|
10740
|
+
json_type(input.properties, ?) AS value_type,
|
|
10741
|
+
json_extract(input.properties, ?) AS value,
|
|
10742
|
+
COUNT(*) AS count
|
|
10743
|
+
FROM (${compiled.sql}) AS input
|
|
10744
|
+
WHERE json_type(input.properties, ?) IS NOT NULL
|
|
10745
|
+
GROUP BY value_type, value
|
|
10746
|
+
ORDER BY count DESC, CAST(value AS TEXT) ASC
|
|
10747
|
+
LIMIT ?
|
|
10748
|
+
`).all(path, path, ...compiled.args, path, facet.limit);
|
|
10749
|
+
return rows.map((row) => ({
|
|
10750
|
+
value: sqliteFacetValue(row.value_type, row.value),
|
|
10751
|
+
count: Number(row.count)
|
|
10752
|
+
}));
|
|
10753
|
+
}
|
|
10754
|
+
function sqliteJsonPath(propertyId) {
|
|
10755
|
+
return `$."${propertyId.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
10756
|
+
}
|
|
10757
|
+
function sqliteFacetValue(valueType, value) {
|
|
10758
|
+
if (valueType === "true")
|
|
10759
|
+
return true;
|
|
10760
|
+
if (valueType === "false")
|
|
10761
|
+
return false;
|
|
10762
|
+
if (valueType === "null")
|
|
10763
|
+
return null;
|
|
10764
|
+
return value;
|
|
10765
|
+
}
|
|
10766
|
+
function existsProbeQuery(query) {
|
|
10767
|
+
return { kind: "limit", limit: 1, input: stripOuterRowShape(query) };
|
|
10768
|
+
}
|
|
10769
|
+
function stripOuterRowShape(query) {
|
|
10770
|
+
switch (query.kind) {
|
|
10771
|
+
case "limit":
|
|
10772
|
+
case "page":
|
|
10773
|
+
case "project":
|
|
10774
|
+
case "sort":
|
|
10775
|
+
return stripOuterRowShape(query.input);
|
|
10776
|
+
default:
|
|
10777
|
+
return query;
|
|
10778
|
+
}
|
|
10779
|
+
}
|
|
10780
|
+
|
|
10781
|
+
// src/objects/selected-reader.ts
|
|
10782
|
+
import {
|
|
10783
|
+
assertObjectReaderProject,
|
|
10784
|
+
assertObjectReadFacetCount,
|
|
10785
|
+
assertObjectReadOutputWithinLimit,
|
|
10786
|
+
ObjectReadLimitExceededError,
|
|
10787
|
+
snapshotObjectReadExecutionLimits
|
|
10788
|
+
} from "@sixb/core/storage";
|
|
10789
|
+
|
|
10790
|
+
// src/objects/read-scope.ts
|
|
10791
|
+
function compileSqliteSelectedObjectReadSource(projectId, scope, maxTraversalFacts) {
|
|
10792
|
+
const scopeJson = JSON.stringify({
|
|
10793
|
+
roots: scope.roots,
|
|
10794
|
+
objects: scope.objects,
|
|
10795
|
+
steps: scope.steps
|
|
10796
|
+
});
|
|
10797
|
+
const compiled = compileSelectedReadScopeCte(scopeJson, projectId);
|
|
10798
|
+
const wrapStatement = (sql, args = []) => ({
|
|
10799
|
+
sql: `${compiled.sql}
|
|
10800
|
+
${sql}`,
|
|
10801
|
+
args: [...compiled.args, ...args]
|
|
10802
|
+
});
|
|
10803
|
+
return Object.freeze({
|
|
10804
|
+
objectsTable: "_sixb_scope_objects",
|
|
10805
|
+
linksTable: "_sixb_scope_links",
|
|
10806
|
+
objectPropertyPermissionsTable: "_sixb_scope_object_permissions",
|
|
10807
|
+
wrapStatement,
|
|
10808
|
+
wrapQuery: (query) => ({
|
|
10809
|
+
...query,
|
|
10810
|
+
...wrapStatement(query.sql, query.args),
|
|
10811
|
+
totalSql: `${compiled.sql}
|
|
10812
|
+
${query.totalSql}`,
|
|
10813
|
+
totalArgs: [...compiled.args, ...query.totalArgs],
|
|
10814
|
+
...query.hasMoreProbe ? {
|
|
10815
|
+
hasMoreProbe: {
|
|
10816
|
+
...query.hasMoreProbe,
|
|
10817
|
+
...wrapStatement(query.hasMoreProbe.sql, query.hasMoreProbe.args)
|
|
10818
|
+
}
|
|
10819
|
+
} : {}
|
|
10820
|
+
}),
|
|
10821
|
+
traversalProbe: wrapStatement(`
|
|
10822
|
+
SELECT COUNT(*) AS total
|
|
10823
|
+
FROM (
|
|
10824
|
+
SELECT 1 AS traversal_fact
|
|
10825
|
+
FROM _sixb_scope_root_facts
|
|
10826
|
+
|
|
10827
|
+
UNION ALL
|
|
10828
|
+
|
|
10829
|
+
SELECT 1 AS traversal_fact
|
|
10830
|
+
FROM _sixb_scope_reached_links
|
|
10831
|
+
|
|
10832
|
+
LIMIT ?
|
|
10833
|
+
) AS bounded_traversal_facts
|
|
10834
|
+
`, [BigInt(maxTraversalFacts) + 1n])
|
|
10835
|
+
});
|
|
10836
|
+
}
|
|
10837
|
+
function compileSelectedReadScopeCte(scopeJson, projectId) {
|
|
10838
|
+
return {
|
|
10839
|
+
sql: `
|
|
10840
|
+
WITH RECURSIVE
|
|
10841
|
+
_sixb_scope_document(scope) AS (
|
|
10842
|
+
SELECT json(?)
|
|
10843
|
+
),
|
|
10844
|
+
_sixb_scope_roots(root_id, node_id, object_type_id, primary_id) AS (
|
|
10845
|
+
SELECT
|
|
10846
|
+
CAST(root.key AS INTEGER),
|
|
10847
|
+
CAST(json_extract(root.value, '$.nodeId') AS INTEGER),
|
|
10848
|
+
CAST(json_extract(root.value, '$.objectTypeId') AS TEXT),
|
|
10849
|
+
CAST(json_extract(root.value, '$.primaryId') AS TEXT)
|
|
10850
|
+
FROM _sixb_scope_document AS document,
|
|
10851
|
+
json_each(json_extract(document.scope, '$.roots')) AS root
|
|
10852
|
+
),
|
|
10853
|
+
_sixb_scope_root_facts(project_id, root_id, node_id, object_type_id, primary_id) AS (
|
|
10854
|
+
SELECT anchor.project_id, root.root_id, root.node_id, root.object_type_id, root.primary_id
|
|
10855
|
+
FROM _sixb_scope_roots AS root
|
|
10856
|
+
JOIN objects AS anchor
|
|
10857
|
+
ON anchor.project_id = ?
|
|
10858
|
+
AND anchor.object_type_id = root.object_type_id
|
|
10859
|
+
AND anchor.primary_id = root.primary_id
|
|
10860
|
+
),
|
|
10861
|
+
_sixb_scope_object_selections(node_id, object_type_id, property_ids) AS (
|
|
10862
|
+
SELECT
|
|
10863
|
+
CAST(json_extract(selection.value, '$.nodeId') AS INTEGER),
|
|
10864
|
+
CAST(json_extract(selection.value, '$.objectTypeId') AS TEXT),
|
|
10865
|
+
json_extract(selection.value, '$.propertyIds')
|
|
10866
|
+
FROM _sixb_scope_document AS document,
|
|
10867
|
+
json_each(json_extract(document.scope, '$.objects')) AS selection
|
|
10868
|
+
),
|
|
10869
|
+
_sixb_scope_link_selections(
|
|
10870
|
+
step_id,
|
|
10871
|
+
node_id,
|
|
10872
|
+
parent_node_id,
|
|
10873
|
+
source_object_type_id,
|
|
10874
|
+
link_id,
|
|
10875
|
+
target_object_type_id,
|
|
10876
|
+
property_ids
|
|
10877
|
+
) AS (
|
|
10878
|
+
SELECT
|
|
10879
|
+
CAST(step.key AS INTEGER),
|
|
10880
|
+
CAST(json_extract(step.value, '$.nodeId') AS INTEGER),
|
|
10881
|
+
CAST(json_extract(step.value, '$.parentNodeId') AS INTEGER),
|
|
10882
|
+
CAST(json_extract(step.value, '$.sourceObjectTypeId') AS TEXT),
|
|
10883
|
+
CAST(json_extract(step.value, '$.linkId') AS TEXT),
|
|
10884
|
+
CAST(json_extract(step.value, '$.targetObjectTypeId') AS TEXT),
|
|
10885
|
+
json_extract(step.value, '$.propertyIds')
|
|
10886
|
+
FROM _sixb_scope_document AS document,
|
|
10887
|
+
json_each(json_extract(document.scope, '$.steps')) AS step
|
|
10888
|
+
),
|
|
10889
|
+
_sixb_scope_reachable(project_id, node_id, object_type_id, primary_id) AS (
|
|
10890
|
+
SELECT root.project_id, root.node_id, root.object_type_id, root.primary_id
|
|
10891
|
+
FROM _sixb_scope_root_facts AS root
|
|
10892
|
+
|
|
10893
|
+
UNION
|
|
10894
|
+
|
|
10895
|
+
SELECT edge.project_id, selection.node_id, edge.target_type_id, edge.target_id
|
|
10896
|
+
FROM _sixb_scope_reachable AS parent
|
|
10897
|
+
JOIN _sixb_scope_link_selections AS selection
|
|
10898
|
+
ON selection.parent_node_id = parent.node_id
|
|
10899
|
+
AND selection.source_object_type_id = parent.object_type_id
|
|
10900
|
+
JOIN links AS edge
|
|
10901
|
+
ON edge.project_id = parent.project_id
|
|
10902
|
+
AND edge.source_type_id = parent.object_type_id
|
|
10903
|
+
AND edge.source_id = parent.primary_id
|
|
10904
|
+
AND edge.link_id = selection.link_id
|
|
10905
|
+
AND edge.target_type_id = selection.target_object_type_id
|
|
10906
|
+
JOIN objects AS target
|
|
10907
|
+
ON target.project_id = edge.project_id
|
|
10908
|
+
AND target.object_type_id = edge.target_type_id
|
|
10909
|
+
AND target.primary_id = edge.target_id
|
|
10910
|
+
),
|
|
10911
|
+
_sixb_scope_object_permissions(project_id, object_type_id, primary_id, property_id) AS (
|
|
10912
|
+
SELECT DISTINCT
|
|
10913
|
+
reachable.project_id,
|
|
10914
|
+
reachable.object_type_id,
|
|
10915
|
+
reachable.primary_id,
|
|
10916
|
+
CAST(selected_property.value AS TEXT)
|
|
10917
|
+
FROM _sixb_scope_reachable AS reachable
|
|
10918
|
+
JOIN _sixb_scope_object_selections AS selection
|
|
10919
|
+
ON selection.node_id = reachable.node_id
|
|
10920
|
+
AND selection.object_type_id = reachable.object_type_id
|
|
10921
|
+
JOIN json_each(selection.property_ids) AS selected_property
|
|
10922
|
+
),
|
|
10923
|
+
_sixb_scope_object_ids(project_id, object_type_id, primary_id) AS (
|
|
10924
|
+
SELECT DISTINCT project_id, object_type_id, primary_id
|
|
10925
|
+
FROM _sixb_scope_reachable
|
|
10926
|
+
),
|
|
10927
|
+
_sixb_scope_objects AS (
|
|
10928
|
+
SELECT
|
|
10929
|
+
stored.project_id,
|
|
10930
|
+
stored.object_type_id,
|
|
10931
|
+
stored.primary_id,
|
|
10932
|
+
COALESCE(
|
|
10933
|
+
(
|
|
10934
|
+
SELECT json_group_object(property.key, ${sqliteJsonEachValue("property")})
|
|
10935
|
+
FROM json_each(stored.properties) AS property
|
|
10936
|
+
JOIN _sixb_scope_object_permissions AS permission
|
|
10937
|
+
ON permission.project_id = stored.project_id
|
|
10938
|
+
AND permission.object_type_id = stored.object_type_id
|
|
10939
|
+
AND permission.primary_id = stored.primary_id
|
|
10940
|
+
AND permission.property_id = property.key
|
|
10941
|
+
),
|
|
10942
|
+
json('{}')
|
|
10943
|
+
) AS properties,
|
|
10944
|
+
stored.created_at,
|
|
10945
|
+
stored.updated_at,
|
|
10946
|
+
stored.version,
|
|
10947
|
+
stored.last_commit_id
|
|
10948
|
+
FROM objects AS stored
|
|
10949
|
+
JOIN _sixb_scope_object_ids AS visible
|
|
10950
|
+
ON visible.project_id = stored.project_id
|
|
10951
|
+
AND visible.object_type_id = stored.object_type_id
|
|
10952
|
+
AND visible.primary_id = stored.primary_id
|
|
10953
|
+
),
|
|
10954
|
+
_sixb_scope_reached_links(
|
|
10955
|
+
project_id,
|
|
10956
|
+
step_id,
|
|
10957
|
+
node_id,
|
|
10958
|
+
parent_node_id,
|
|
10959
|
+
source_type_id,
|
|
10960
|
+
source_id,
|
|
10961
|
+
link_id,
|
|
10962
|
+
target_type_id,
|
|
10963
|
+
target_id,
|
|
10964
|
+
property_ids
|
|
10965
|
+
) AS (
|
|
10966
|
+
SELECT
|
|
10967
|
+
edge.project_id,
|
|
10968
|
+
selection.step_id,
|
|
10969
|
+
selection.node_id,
|
|
10970
|
+
selection.parent_node_id,
|
|
10971
|
+
edge.source_type_id,
|
|
10972
|
+
edge.source_id,
|
|
10973
|
+
edge.link_id,
|
|
10974
|
+
edge.target_type_id,
|
|
10975
|
+
edge.target_id,
|
|
10976
|
+
selection.property_ids
|
|
10977
|
+
FROM _sixb_scope_reachable AS parent
|
|
10978
|
+
JOIN _sixb_scope_link_selections AS selection
|
|
10979
|
+
ON selection.parent_node_id = parent.node_id
|
|
10980
|
+
AND selection.source_object_type_id = parent.object_type_id
|
|
10981
|
+
JOIN links AS edge
|
|
10982
|
+
ON edge.project_id = parent.project_id
|
|
10983
|
+
AND edge.source_type_id = parent.object_type_id
|
|
10984
|
+
AND edge.source_id = parent.primary_id
|
|
10985
|
+
AND edge.link_id = selection.link_id
|
|
10986
|
+
AND edge.target_type_id = selection.target_object_type_id
|
|
10987
|
+
JOIN objects AS target
|
|
10988
|
+
ON target.project_id = edge.project_id
|
|
10989
|
+
AND target.object_type_id = edge.target_type_id
|
|
10990
|
+
AND target.primary_id = edge.target_id
|
|
10991
|
+
),
|
|
10992
|
+
_sixb_scope_link_permissions(
|
|
10993
|
+
project_id,
|
|
10994
|
+
source_type_id,
|
|
10995
|
+
source_id,
|
|
10996
|
+
link_id,
|
|
10997
|
+
target_type_id,
|
|
10998
|
+
target_id,
|
|
10999
|
+
property_id
|
|
11000
|
+
) AS (
|
|
11001
|
+
SELECT DISTINCT
|
|
11002
|
+
reached.project_id,
|
|
11003
|
+
reached.source_type_id,
|
|
11004
|
+
reached.source_id,
|
|
11005
|
+
reached.link_id,
|
|
11006
|
+
reached.target_type_id,
|
|
11007
|
+
reached.target_id,
|
|
11008
|
+
CAST(selected_property.value AS TEXT)
|
|
11009
|
+
FROM _sixb_scope_reached_links AS reached
|
|
11010
|
+
JOIN json_each(reached.property_ids) AS selected_property
|
|
11011
|
+
),
|
|
11012
|
+
_sixb_scope_link_ids(
|
|
11013
|
+
project_id,
|
|
11014
|
+
source_type_id,
|
|
11015
|
+
source_id,
|
|
11016
|
+
link_id,
|
|
11017
|
+
target_type_id,
|
|
11018
|
+
target_id
|
|
11019
|
+
) AS (
|
|
11020
|
+
SELECT DISTINCT
|
|
11021
|
+
project_id,
|
|
11022
|
+
source_type_id,
|
|
11023
|
+
source_id,
|
|
11024
|
+
link_id,
|
|
11025
|
+
target_type_id,
|
|
11026
|
+
target_id
|
|
11027
|
+
FROM _sixb_scope_reached_links
|
|
11028
|
+
),
|
|
11029
|
+
_sixb_scope_links AS (
|
|
11030
|
+
SELECT
|
|
11031
|
+
stored.project_id,
|
|
11032
|
+
stored.source_type_id,
|
|
11033
|
+
stored.source_id,
|
|
11034
|
+
stored.link_id,
|
|
11035
|
+
stored.target_type_id,
|
|
11036
|
+
stored.target_id,
|
|
11037
|
+
CASE
|
|
11038
|
+
WHEN stored.properties IS NULL THEN NULL
|
|
11039
|
+
ELSE NULLIF(
|
|
11040
|
+
(
|
|
11041
|
+
SELECT json_group_object(property.key, ${sqliteJsonEachValue("property")})
|
|
11042
|
+
FROM json_each(stored.properties) AS property
|
|
11043
|
+
JOIN _sixb_scope_link_permissions AS permission
|
|
11044
|
+
ON permission.project_id = stored.project_id
|
|
11045
|
+
AND permission.source_type_id = stored.source_type_id
|
|
11046
|
+
AND permission.source_id = stored.source_id
|
|
11047
|
+
AND permission.link_id = stored.link_id
|
|
11048
|
+
AND permission.target_type_id = stored.target_type_id
|
|
11049
|
+
AND permission.target_id = stored.target_id
|
|
11050
|
+
AND permission.property_id = property.key
|
|
11051
|
+
),
|
|
11052
|
+
json('{}')
|
|
11053
|
+
)
|
|
11054
|
+
END AS properties,
|
|
11055
|
+
stored.created_at,
|
|
11056
|
+
stored.updated_at,
|
|
11057
|
+
stored.last_commit_id
|
|
11058
|
+
FROM links AS stored
|
|
11059
|
+
JOIN _sixb_scope_link_ids AS visible
|
|
11060
|
+
ON visible.project_id = stored.project_id
|
|
11061
|
+
AND visible.source_type_id = stored.source_type_id
|
|
11062
|
+
AND visible.source_id = stored.source_id
|
|
11063
|
+
AND visible.link_id = stored.link_id
|
|
11064
|
+
AND visible.target_type_id = stored.target_type_id
|
|
11065
|
+
AND visible.target_id = stored.target_id
|
|
11066
|
+
)
|
|
11067
|
+
`,
|
|
11068
|
+
args: [scopeJson, projectId]
|
|
11069
|
+
};
|
|
11070
|
+
}
|
|
11071
|
+
|
|
11072
|
+
// src/objects/selected-reader.ts
|
|
11073
|
+
function createSqliteSelectedReader(db, params, queryCapabilities) {
|
|
11074
|
+
const projectId = params.projectId;
|
|
11075
|
+
const limits = snapshotObjectReadExecutionLimits(params.limits);
|
|
11076
|
+
const source = compileSqliteSelectedObjectReadSource(projectId, params.scope, limits.maxTraversalFacts);
|
|
11077
|
+
const reader = new SqliteObjectReader(db, source);
|
|
11078
|
+
const assertProject = (actualProjectId) => assertObjectReaderProject(projectId, actualProjectId);
|
|
11079
|
+
const read = (run) => runDeferredReadTransaction(db, () => {
|
|
11080
|
+
assertTraversalBudget(db, source, limits.maxTraversalFacts);
|
|
11081
|
+
const value = run();
|
|
11082
|
+
assertObjectReadOutputWithinLimit(value, limits);
|
|
11083
|
+
return value;
|
|
11084
|
+
});
|
|
11085
|
+
const readMap = (run) => runDeferredReadTransaction(db, () => {
|
|
11086
|
+
assertTraversalBudget(db, source, limits.maxTraversalFacts);
|
|
11087
|
+
const value = run();
|
|
11088
|
+
assertObjectReadOutputWithinLimit([...value.entries()], limits);
|
|
11089
|
+
return value;
|
|
11090
|
+
});
|
|
11091
|
+
return Object.freeze({
|
|
11092
|
+
queryCapabilities,
|
|
11093
|
+
queryObjects: async (input) => {
|
|
11094
|
+
assertProject(input.projectId);
|
|
11095
|
+
return read(() => reader.queryObjects(input));
|
|
11096
|
+
},
|
|
11097
|
+
countObjects: async (input) => {
|
|
11098
|
+
assertProject(input.projectId);
|
|
11099
|
+
return read(() => reader.countObjects(input));
|
|
11100
|
+
},
|
|
11101
|
+
existsObjects: async (input) => {
|
|
11102
|
+
assertProject(input.projectId);
|
|
11103
|
+
return read(() => reader.existsObjects(input));
|
|
11104
|
+
},
|
|
11105
|
+
facetObjects: async (input) => {
|
|
11106
|
+
assertProject(input.projectId);
|
|
11107
|
+
assertObjectReadFacetCount(input.facets.length);
|
|
11108
|
+
return read(() => reader.facetObjects(input));
|
|
11109
|
+
},
|
|
11110
|
+
getByPrimaryId: async (input) => {
|
|
11111
|
+
assertProject(input.projectId);
|
|
11112
|
+
return read(() => reader.getByPrimaryId(input));
|
|
11113
|
+
},
|
|
11114
|
+
selectsObjectProperties: async (input) => {
|
|
11115
|
+
assertProject(input.projectId);
|
|
11116
|
+
return read(() => reader.selectsObjectProperties(input));
|
|
11117
|
+
},
|
|
11118
|
+
listLinks: async (input) => {
|
|
11119
|
+
assertProject(input.projectId);
|
|
11120
|
+
return read(() => reader.listLinks(input));
|
|
11121
|
+
},
|
|
11122
|
+
getByPrimaryIdBatch: async (input) => {
|
|
11123
|
+
assertProject(input.projectId);
|
|
11124
|
+
return readMap(() => reader.getByPrimaryIdBatch(input));
|
|
11125
|
+
},
|
|
11126
|
+
listLinksBatch: async (input) => {
|
|
11127
|
+
assertProject(input.projectId);
|
|
11128
|
+
return readMap(() => reader.listLinksBatch(input));
|
|
11129
|
+
},
|
|
11130
|
+
queryLinks: async (input) => {
|
|
11131
|
+
assertProject(input.projectId);
|
|
11132
|
+
assertLinkQueryLimit(input.limit);
|
|
11133
|
+
return read(() => reader.queryLinks(input));
|
|
11134
|
+
},
|
|
11135
|
+
list: async (input) => {
|
|
11136
|
+
assertProject(input.projectId);
|
|
11137
|
+
return read(() => reader.list(input));
|
|
11138
|
+
}
|
|
11139
|
+
});
|
|
11140
|
+
}
|
|
11141
|
+
function assertTraversalBudget(db, source, maxTraversalFacts) {
|
|
11142
|
+
const row = db.query(source.traversalProbe.sql).get(...source.traversalProbe.args);
|
|
11143
|
+
if (BigInt(row.total) > BigInt(maxTraversalFacts)) {
|
|
11144
|
+
throw new ObjectReadLimitExceededError("traversalFacts", maxTraversalFacts);
|
|
11145
|
+
}
|
|
11146
|
+
}
|
|
11147
|
+
|
|
11148
|
+
// src/objects/storage.ts
|
|
11149
|
+
var SQLITE_OBJECT_QUERY_CAPABILITIES = {
|
|
11150
|
+
queryObjects: true,
|
|
11151
|
+
countObjects: true,
|
|
11152
|
+
existsObjects: true,
|
|
11153
|
+
facetObjects: true,
|
|
11154
|
+
nodes: {
|
|
11155
|
+
start: true,
|
|
11156
|
+
refs: true,
|
|
11157
|
+
filter: true,
|
|
11158
|
+
text: true,
|
|
11159
|
+
sort: true,
|
|
11160
|
+
limit: true,
|
|
11161
|
+
page: true,
|
|
11162
|
+
traverse: true,
|
|
11163
|
+
set: true,
|
|
11164
|
+
project: true,
|
|
11165
|
+
expand: true
|
|
11166
|
+
},
|
|
11167
|
+
predicateOps: {
|
|
11168
|
+
and: true,
|
|
11169
|
+
or: true,
|
|
11170
|
+
not: true,
|
|
11171
|
+
eq: true,
|
|
11172
|
+
neq: true,
|
|
11173
|
+
lt: true,
|
|
11174
|
+
lte: true,
|
|
11175
|
+
gt: true,
|
|
11176
|
+
gte: true,
|
|
11177
|
+
in: true,
|
|
11178
|
+
exists: true,
|
|
11179
|
+
contains: true
|
|
11180
|
+
},
|
|
11181
|
+
sortKinds: {
|
|
11182
|
+
property: true
|
|
11183
|
+
},
|
|
11184
|
+
traversalDirections: {
|
|
11185
|
+
outgoing: true,
|
|
11186
|
+
incoming: true
|
|
11187
|
+
},
|
|
11188
|
+
setOps: {
|
|
11189
|
+
union: true,
|
|
11190
|
+
intersect: true,
|
|
11191
|
+
subtract: true
|
|
11192
|
+
},
|
|
11193
|
+
scalarOperations: {
|
|
11194
|
+
string: { equality: true, ordering: true },
|
|
11195
|
+
uuid: { equality: true, ordering: true },
|
|
11196
|
+
boolean: { equality: true },
|
|
11197
|
+
integer: { equality: true, ordering: true },
|
|
11198
|
+
double: { equality: true, ordering: true },
|
|
11199
|
+
decimal: { equality: true },
|
|
11200
|
+
date: { equality: true, ordering: true },
|
|
11201
|
+
timestamp: { equality: true, ordering: true }
|
|
11202
|
+
},
|
|
11203
|
+
limits: {
|
|
11204
|
+
totalCount: true,
|
|
11205
|
+
stablePageTokens: true
|
|
11206
|
+
},
|
|
11207
|
+
notes: [
|
|
11208
|
+
"SQLite object query pushdown supports start/refs/filter/text/sort/limit/page/traverse/set/project/expand over JSON properties and object links.",
|
|
11209
|
+
"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.",
|
|
11210
|
+
"Ordered decimal predicates and sorting use the bounded core fallback because SQLite has no native exact decimal type; canonical decimal equality remains pushdown-safe.",
|
|
11211
|
+
"Relevance sorting, vector search, and unresolved start.includeSubtypes remain planner fallback or rejection cases."
|
|
11212
|
+
]
|
|
11213
|
+
};
|
|
11214
|
+
|
|
11215
|
+
class SqliteObjectStorage {
|
|
11216
|
+
connection;
|
|
11217
|
+
db;
|
|
11218
|
+
reader;
|
|
11219
|
+
constructor(options = {}) {
|
|
11220
|
+
this.connection = openSqliteStoreConnection(options);
|
|
11221
|
+
this.db = this.connection.db;
|
|
11222
|
+
this.reader = new SqliteObjectReader(this.db, DEFAULT_OBJECT_QUERY_SOURCE);
|
|
11223
|
+
if (this.connection.installFreshSchema) {
|
|
11224
|
+
installFreshSqliteSchema(this.db);
|
|
11225
|
+
}
|
|
11226
|
+
}
|
|
11227
|
+
queryCapabilities() {
|
|
11228
|
+
return SQLITE_OBJECT_QUERY_CAPABILITIES;
|
|
11229
|
+
}
|
|
11230
|
+
createSelectedReadScope(params) {
|
|
11231
|
+
return createSqliteSelectedReader(this.db, params, () => this.queryCapabilities());
|
|
11232
|
+
}
|
|
11233
|
+
async queryObjects(params) {
|
|
11234
|
+
return this.reader.queryObjects(params);
|
|
11235
|
+
}
|
|
11236
|
+
async countObjects(params) {
|
|
11237
|
+
return this.reader.countObjects(params);
|
|
11238
|
+
}
|
|
11239
|
+
async existsObjects(params) {
|
|
11240
|
+
return this.reader.existsObjects(params);
|
|
11241
|
+
}
|
|
11242
|
+
async facetObjects(params) {
|
|
11243
|
+
return this.reader.facetObjects(params);
|
|
11244
|
+
}
|
|
11245
|
+
async getByPrimaryId(params) {
|
|
11246
|
+
return this.reader.getByPrimaryId(params);
|
|
11247
|
+
}
|
|
11248
|
+
async selectsObjectProperties(params) {
|
|
11249
|
+
return this.reader.selectsObjectProperties(params);
|
|
11250
|
+
}
|
|
11251
|
+
async listLinks(params) {
|
|
11252
|
+
return this.reader.listLinks(params);
|
|
11253
|
+
}
|
|
11254
|
+
async getByPrimaryIdBatch(params) {
|
|
11255
|
+
return this.reader.getByPrimaryIdBatch(params);
|
|
11256
|
+
}
|
|
11257
|
+
async listLinksBatch(params) {
|
|
11258
|
+
return this.reader.listLinksBatch(params);
|
|
11259
|
+
}
|
|
11260
|
+
async queryLinks(params) {
|
|
11261
|
+
assertLinkQueryLimit(params.limit);
|
|
11262
|
+
return this.reader.queryLinks(params);
|
|
11263
|
+
}
|
|
10233
11264
|
async listIncidentLinksBatch(params) {
|
|
10234
11265
|
if (params.items.length === 0)
|
|
10235
11266
|
return [];
|
|
@@ -10254,7 +11285,7 @@ class SqliteObjectStorage {
|
|
|
10254
11285
|
AND requested.object_id = link.target_id
|
|
10255
11286
|
WHERE link.project_id = ?
|
|
10256
11287
|
`).all(JSON.stringify(params.items), params.projectId, params.projectId);
|
|
10257
|
-
return rows.map((row) =>
|
|
11288
|
+
return rows.map((row) => rowToLink(row));
|
|
10258
11289
|
}
|
|
10259
11290
|
async listByPrimaryIdPage(params) {
|
|
10260
11291
|
assertReconciliationPageLimit(params.limit);
|
|
@@ -10266,7 +11297,7 @@ class SqliteObjectStorage {
|
|
|
10266
11297
|
LIMIT ?
|
|
10267
11298
|
`).all(params.projectId, params.objectTypeId, params.afterPrimaryId ?? null, params.afterPrimaryId ?? null, params.limit + 1);
|
|
10268
11299
|
const hasMore = rows.length > params.limit;
|
|
10269
|
-
const objects = rows.slice(0, params.limit).map((row) =>
|
|
11300
|
+
const objects = rows.slice(0, params.limit).map((row) => rowToObject(row));
|
|
10270
11301
|
const last = objects.at(-1);
|
|
10271
11302
|
return {
|
|
10272
11303
|
objects,
|
|
@@ -10274,88 +11305,7 @@ class SqliteObjectStorage {
|
|
|
10274
11305
|
};
|
|
10275
11306
|
}
|
|
10276
11307
|
async list(params) {
|
|
10277
|
-
|
|
10278
|
-
const args = [params.projectId];
|
|
10279
|
-
if (params.objectTypeId) {
|
|
10280
|
-
if (typeof params.objectTypeId === "string") {
|
|
10281
|
-
query += " AND object_type_id = ?";
|
|
10282
|
-
args.push(params.objectTypeId);
|
|
10283
|
-
} else {
|
|
10284
|
-
query += ` AND object_type_id IN (${params.objectTypeId.map(() => "?").join(", ")})`;
|
|
10285
|
-
args.push(...params.objectTypeId);
|
|
10286
|
-
}
|
|
10287
|
-
}
|
|
10288
|
-
if (params.primaryIdPrefix) {
|
|
10289
|
-
query += " AND primary_id LIKE ?";
|
|
10290
|
-
args.push(`${params.primaryIdPrefix}%`);
|
|
10291
|
-
}
|
|
10292
|
-
if (params.primaryIdSuffix) {
|
|
10293
|
-
query += " AND primary_id LIKE ?";
|
|
10294
|
-
args.push(`%${params.primaryIdSuffix}`);
|
|
10295
|
-
}
|
|
10296
|
-
if (params.updatedAfter) {
|
|
10297
|
-
query += " AND updated_at >= ?";
|
|
10298
|
-
args.push(params.updatedAfter.toISOString());
|
|
10299
|
-
}
|
|
10300
|
-
if (params.updatedBefore) {
|
|
10301
|
-
query += " AND updated_at <= ?";
|
|
10302
|
-
args.push(params.updatedBefore.toISOString());
|
|
10303
|
-
}
|
|
10304
|
-
if (params.createdAfter) {
|
|
10305
|
-
query += " AND created_at >= ?";
|
|
10306
|
-
args.push(params.createdAfter.toISOString());
|
|
10307
|
-
}
|
|
10308
|
-
if (params.createdBefore) {
|
|
10309
|
-
query += " AND created_at <= ?";
|
|
10310
|
-
args.push(params.createdBefore.toISOString());
|
|
10311
|
-
}
|
|
10312
|
-
const countResult = this.db.query(`SELECT COUNT(*) as total FROM (${query})`).get(...args);
|
|
10313
|
-
const total = countResult.total;
|
|
10314
|
-
const offset = params.offset ?? 0;
|
|
10315
|
-
const limit = params.limit ?? 50;
|
|
10316
|
-
if (limit === 0)
|
|
10317
|
-
return { objects: [], hasMore: offset < total, total };
|
|
10318
|
-
const orderBy = params.orderBy ?? "updatedAt";
|
|
10319
|
-
const order = params.order ?? "desc";
|
|
10320
|
-
const orderColumn = orderBy === "primaryId" ? "primary_id" : orderBy === "createdAt" ? "created_at" : "updated_at";
|
|
10321
|
-
query += ` ORDER BY ${orderColumn} ${order.toUpperCase()}`;
|
|
10322
|
-
query += " LIMIT ? OFFSET ?";
|
|
10323
|
-
args.push(limit + 1, offset);
|
|
10324
|
-
const rows = this.db.query(query).all(...args);
|
|
10325
|
-
const hasMore = rows.length > limit;
|
|
10326
|
-
const objects = rows.slice(0, limit).map((row) => this.rowToObject(row));
|
|
10327
|
-
return { objects, hasMore, total };
|
|
10328
|
-
}
|
|
10329
|
-
rowToObject(row) {
|
|
10330
|
-
return {
|
|
10331
|
-
projectId: row.project_id,
|
|
10332
|
-
objectTypeId: row.object_type_id,
|
|
10333
|
-
primaryId: row.primary_id,
|
|
10334
|
-
properties: JSON.parse(row.properties),
|
|
10335
|
-
createdAt: new Date(row.created_at),
|
|
10336
|
-
updatedAt: new Date(row.updated_at),
|
|
10337
|
-
version: row.version,
|
|
10338
|
-
lastCommitId: row.last_commit_id
|
|
10339
|
-
};
|
|
10340
|
-
}
|
|
10341
|
-
queryRowToObject(row) {
|
|
10342
|
-
const base = this.rowToObject(row);
|
|
10343
|
-
const links = reviveExpandedLinks(parseExpandColumn(row._expand));
|
|
10344
|
-
return links ? { ...base, links } : base;
|
|
10345
|
-
}
|
|
10346
|
-
rowToLink(row) {
|
|
10347
|
-
return {
|
|
10348
|
-
projectId: row.project_id,
|
|
10349
|
-
sourceTypeId: row.source_type_id,
|
|
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
|
|
10358
|
-
};
|
|
11308
|
+
return this.reader.list(params);
|
|
10359
11309
|
}
|
|
10360
11310
|
close() {
|
|
10361
11311
|
closeSqliteStoreConnection(this.connection);
|
|
@@ -10366,104 +11316,6 @@ function assertReconciliationPageLimit(limit) {
|
|
|
10366
11316
|
throw new Error("Object reconciliation page limit must be a positive safe integer.");
|
|
10367
11317
|
}
|
|
10368
11318
|
}
|
|
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
11319
|
// src/ontology-storage/shared.ts
|
|
10468
11320
|
import { parseSixbFailure as parseSixbFailure2 } from "@sixb/core/internal/errors";
|
|
10469
11321
|
import { MaterializationConflictError } from "@sixb/core/internal/materialization";
|
|
@@ -14069,6 +14921,258 @@ function rowToRuleStateRecord(row) {
|
|
|
14069
14921
|
};
|
|
14070
14922
|
}
|
|
14071
14923
|
|
|
14924
|
+
// src/share-grant-storage.ts
|
|
14925
|
+
import {
|
|
14926
|
+
normalizeGetShareGrantByIdInput,
|
|
14927
|
+
normalizeListShareGrantsInput,
|
|
14928
|
+
normalizeRevokeShareGrantInput,
|
|
14929
|
+
normalizeShareGrantCreate,
|
|
14930
|
+
parseShareGrantRecord
|
|
14931
|
+
} from "@sixb/core/internal/share-grant-storage-provider";
|
|
14932
|
+
import { ShareGrantStorageError } from "@sixb/core/storage";
|
|
14933
|
+
class SqliteShareGrantStorage {
|
|
14934
|
+
connection;
|
|
14935
|
+
db;
|
|
14936
|
+
constructor(options = {}) {
|
|
14937
|
+
this.connection = openSqliteStoreConnection(options);
|
|
14938
|
+
this.db = this.connection.db;
|
|
14939
|
+
if (this.connection.installFreshSchema)
|
|
14940
|
+
installFreshSqliteSchema(this.db);
|
|
14941
|
+
}
|
|
14942
|
+
async create(input) {
|
|
14943
|
+
const record = normalizeShareGrantCreate(input);
|
|
14944
|
+
try {
|
|
14945
|
+
this.db.query(`
|
|
14946
|
+
INSERT INTO share_grants (
|
|
14947
|
+
project_id, id, definition_id, target_object_type_id, target_primary_id,
|
|
14948
|
+
issued_by_type, issued_by_id, authority_version, authority_snapshot,
|
|
14949
|
+
authority_digest, token_hash, destination_path, created_at, expires_at
|
|
14950
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
14951
|
+
`).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());
|
|
14952
|
+
} catch (error) {
|
|
14953
|
+
if (isUniqueConstraintError2(error)) {
|
|
14954
|
+
throw new ShareGrantStorageError("duplicate", `[SixbSqlite] Share grant '${record.id}' conflicts with an existing record.`, { cause: error });
|
|
14955
|
+
}
|
|
14956
|
+
throw error;
|
|
14957
|
+
}
|
|
14958
|
+
return this.require(record.projectId, record.id, "create");
|
|
14959
|
+
}
|
|
14960
|
+
async getById(input) {
|
|
14961
|
+
const normalized = normalizeGetShareGrantByIdInput(input);
|
|
14962
|
+
return this.getRow(normalized.projectId, normalized.id);
|
|
14963
|
+
}
|
|
14964
|
+
async list(input) {
|
|
14965
|
+
const normalized = normalizeListShareGrantsInput(input);
|
|
14966
|
+
const where = ["project_id = ?"];
|
|
14967
|
+
const args = [normalized.projectId];
|
|
14968
|
+
if (normalized.definitionId !== undefined) {
|
|
14969
|
+
where.push("definition_id = ?");
|
|
14970
|
+
args.push(normalized.definitionId);
|
|
14971
|
+
}
|
|
14972
|
+
if (normalized.target !== undefined) {
|
|
14973
|
+
where.push("target_object_type_id = ?", "target_primary_id = ?");
|
|
14974
|
+
args.push(normalized.target.objectTypeId, normalized.target.primaryId);
|
|
14975
|
+
}
|
|
14976
|
+
if (!normalized.includeRevoked)
|
|
14977
|
+
where.push("revoked_at IS NULL");
|
|
14978
|
+
if (!normalized.includeExpired) {
|
|
14979
|
+
where.push("expires_at > ?");
|
|
14980
|
+
args.push(normalized.now.toISOString());
|
|
14981
|
+
}
|
|
14982
|
+
const predicate = where.join(" AND ");
|
|
14983
|
+
const totalRow = this.db.query(`SELECT COUNT(*) AS total FROM share_grants WHERE ${predicate}`).get(...args);
|
|
14984
|
+
const rows = this.db.query(`
|
|
14985
|
+
SELECT * FROM share_grants
|
|
14986
|
+
WHERE ${predicate}
|
|
14987
|
+
ORDER BY created_at DESC, id DESC
|
|
14988
|
+
LIMIT ? OFFSET ?
|
|
14989
|
+
`).all(...args, normalized.limit, normalized.offset);
|
|
14990
|
+
const grants = rows.map(rowToRecord);
|
|
14991
|
+
return {
|
|
14992
|
+
grants,
|
|
14993
|
+
total: totalRow.total,
|
|
14994
|
+
hasMore: normalized.offset + grants.length < totalRow.total
|
|
14995
|
+
};
|
|
14996
|
+
}
|
|
14997
|
+
async revoke(input) {
|
|
14998
|
+
const normalized = normalizeRevokeShareGrantInput(input);
|
|
14999
|
+
const current = this.getRow(normalized.projectId, normalized.id);
|
|
15000
|
+
if (!current || current.revokedAt)
|
|
15001
|
+
return current;
|
|
15002
|
+
const revocation = normalizeRevokeShareGrantInput(normalized, current.createdAt);
|
|
15003
|
+
this.db.query(`
|
|
15004
|
+
UPDATE share_grants
|
|
15005
|
+
SET revoked_at = ?, revoked_by_type = ?, revoked_by_id = ?
|
|
15006
|
+
WHERE project_id = ? AND id = ? AND revoked_at IS NULL
|
|
15007
|
+
`).run(revocation.revokedAt.toISOString(), revocation.revokedBy.type, revocation.revokedBy.id, revocation.projectId, revocation.id);
|
|
15008
|
+
return this.require(revocation.projectId, revocation.id, "revoke");
|
|
15009
|
+
}
|
|
15010
|
+
close() {
|
|
15011
|
+
closeSqliteStoreConnection(this.connection);
|
|
15012
|
+
}
|
|
15013
|
+
getRow(projectId, id) {
|
|
15014
|
+
const row = this.db.query("SELECT * FROM share_grants WHERE project_id = ? AND id = ?").get(projectId, id);
|
|
15015
|
+
return row ? rowToRecord(row) : null;
|
|
15016
|
+
}
|
|
15017
|
+
require(projectId, id, operation) {
|
|
15018
|
+
const record = this.getRow(projectId, id);
|
|
15019
|
+
if (!record) {
|
|
15020
|
+
throw new ShareGrantStorageError("invalid_record", `[SixbSqlite] Share grant '${id}' disappeared after ${operation}.`);
|
|
15021
|
+
}
|
|
15022
|
+
return record;
|
|
15023
|
+
}
|
|
15024
|
+
}
|
|
15025
|
+
function rowToRecord(row) {
|
|
15026
|
+
const authoritySnapshot = parseStoredJson(row.authority_snapshot, "authority snapshot");
|
|
15027
|
+
if (typeof row.authority_version !== "number" || !isRecord(authoritySnapshot) || authoritySnapshot.version !== row.authority_version) {
|
|
15028
|
+
throw invalidRecord("Share authority version does not match its snapshot.");
|
|
15029
|
+
}
|
|
15030
|
+
const hasRevokedAt = row.revoked_at !== null;
|
|
15031
|
+
const hasRevokedBy = row.revoked_by_type !== null || row.revoked_by_id !== null;
|
|
15032
|
+
if (hasRevokedAt !== hasRevokedBy) {
|
|
15033
|
+
throw invalidRecord("Share revocation time and actor must be stored together.");
|
|
15034
|
+
}
|
|
15035
|
+
return parseShareGrantRecord({
|
|
15036
|
+
projectId: row.project_id,
|
|
15037
|
+
id: row.id,
|
|
15038
|
+
definitionId: row.definition_id,
|
|
15039
|
+
target: {
|
|
15040
|
+
objectTypeId: row.target_object_type_id,
|
|
15041
|
+
primaryId: row.target_primary_id
|
|
15042
|
+
},
|
|
15043
|
+
issuedBy: { type: row.issued_by_type, id: row.issued_by_id },
|
|
15044
|
+
authoritySnapshot,
|
|
15045
|
+
authorityDigest: row.authority_digest,
|
|
15046
|
+
tokenHash: row.token_hash,
|
|
15047
|
+
destinationPath: row.destination_path,
|
|
15048
|
+
createdAt: row.created_at,
|
|
15049
|
+
expiresAt: row.expires_at,
|
|
15050
|
+
...hasRevokedAt ? { revokedAt: row.revoked_at } : {},
|
|
15051
|
+
...hasRevokedBy ? { revokedBy: { type: row.revoked_by_type, id: row.revoked_by_id } } : {}
|
|
15052
|
+
});
|
|
15053
|
+
}
|
|
15054
|
+
function parseStoredJson(value, field) {
|
|
15055
|
+
if (typeof value !== "string")
|
|
15056
|
+
throw invalidRecord(`Share ${field} must be stored as JSON text.`);
|
|
15057
|
+
try {
|
|
15058
|
+
return JSON.parse(value);
|
|
15059
|
+
} catch (cause) {
|
|
15060
|
+
throw new ShareGrantStorageError("invalid_record", `[SixbSqlite] Share ${field} contains invalid JSON.`, { cause });
|
|
15061
|
+
}
|
|
15062
|
+
}
|
|
15063
|
+
function isRecord(value) {
|
|
15064
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15065
|
+
}
|
|
15066
|
+
function invalidRecord(message) {
|
|
15067
|
+
return new ShareGrantStorageError("invalid_record", `[SixbSqlite] ${message}`);
|
|
15068
|
+
}
|
|
15069
|
+
|
|
15070
|
+
// src/share-session-storage.ts
|
|
15071
|
+
import {
|
|
15072
|
+
normalizeGetShareSessionByIdInput,
|
|
15073
|
+
normalizeRenewShareSessionIfValidInput,
|
|
15074
|
+
normalizeRevokeShareSessionInput,
|
|
15075
|
+
normalizeShareSessionCreate,
|
|
15076
|
+
parseShareSessionRecord
|
|
15077
|
+
} from "@sixb/core/internal/share-session-storage-provider";
|
|
15078
|
+
import { ShareSessionStorageError } from "@sixb/core/storage";
|
|
15079
|
+
class SqliteShareSessionStorage {
|
|
15080
|
+
connection;
|
|
15081
|
+
db;
|
|
15082
|
+
constructor(options = {}) {
|
|
15083
|
+
this.connection = openSqliteStoreConnection(options);
|
|
15084
|
+
this.db = this.connection.db;
|
|
15085
|
+
if (this.connection.installFreshSchema)
|
|
15086
|
+
installFreshSqliteSchema(this.db);
|
|
15087
|
+
}
|
|
15088
|
+
async create(input) {
|
|
15089
|
+
const record = normalizeShareSessionCreate(input);
|
|
15090
|
+
try {
|
|
15091
|
+
const row = this.db.query(`
|
|
15092
|
+
INSERT INTO share_sessions (
|
|
15093
|
+
project_id, id, grant_id, token_hash, created_at, expires_at,
|
|
15094
|
+
absolute_expires_at
|
|
15095
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
15096
|
+
RETURNING *
|
|
15097
|
+
`).get(record.projectId, record.id, record.grantId, record.tokenHash, record.createdAt.toISOString(), record.expiresAt.toISOString(), record.absoluteExpiresAt.toISOString());
|
|
15098
|
+
if (!row)
|
|
15099
|
+
throw invalidRecord2(`Share session '${record.id}' disappeared after create.`);
|
|
15100
|
+
return rowToRecord2(row);
|
|
15101
|
+
} catch (error) {
|
|
15102
|
+
if (isUniqueConstraintError2(error)) {
|
|
15103
|
+
throw new ShareSessionStorageError("duplicate", `[SixbSqlite] Share session '${record.id}' conflicts with an existing record.`, { cause: error });
|
|
15104
|
+
}
|
|
15105
|
+
if (isForeignKeyConstraintError(error)) {
|
|
15106
|
+
throw new ShareSessionStorageError("invalid_input", `[SixbSqlite] Share grant '${record.grantId}' does not exist in project '${record.projectId}'.`, { cause: error });
|
|
15107
|
+
}
|
|
15108
|
+
throw error;
|
|
15109
|
+
}
|
|
15110
|
+
}
|
|
15111
|
+
async getById(input) {
|
|
15112
|
+
const normalized = normalizeGetShareSessionByIdInput(input);
|
|
15113
|
+
return this.getRow(normalized.projectId, normalized.id);
|
|
15114
|
+
}
|
|
15115
|
+
async renewIfValid(input) {
|
|
15116
|
+
const normalized = normalizeRenewShareSessionIfValidInput(input);
|
|
15117
|
+
const requestedExpiry = normalized.expiresAt.toISOString();
|
|
15118
|
+
const now = normalized.now.toISOString();
|
|
15119
|
+
const row = this.db.query(`
|
|
15120
|
+
UPDATE share_sessions
|
|
15121
|
+
SET expires_at = CASE
|
|
15122
|
+
WHEN ? > absolute_expires_at THEN absolute_expires_at
|
|
15123
|
+
WHEN ? > expires_at THEN ?
|
|
15124
|
+
ELSE expires_at
|
|
15125
|
+
END
|
|
15126
|
+
WHERE project_id = ?
|
|
15127
|
+
AND id = ?
|
|
15128
|
+
AND grant_id = ?
|
|
15129
|
+
AND token_hash = ?
|
|
15130
|
+
AND revoked_at IS NULL
|
|
15131
|
+
AND created_at <= ?
|
|
15132
|
+
AND expires_at > ?
|
|
15133
|
+
AND absolute_expires_at > ?
|
|
15134
|
+
RETURNING *
|
|
15135
|
+
`).get(requestedExpiry, requestedExpiry, requestedExpiry, normalized.projectId, normalized.id, normalized.grantId, normalized.tokenHash, now, now, now);
|
|
15136
|
+
return row ? rowToRecord2(row) : null;
|
|
15137
|
+
}
|
|
15138
|
+
async revoke(input) {
|
|
15139
|
+
const normalized = normalizeRevokeShareSessionInput(input);
|
|
15140
|
+
const current = this.getRow(normalized.projectId, normalized.id);
|
|
15141
|
+
if (!current || current.revokedAt)
|
|
15142
|
+
return current;
|
|
15143
|
+
const revocation = normalizeRevokeShareSessionInput(normalized, current.createdAt);
|
|
15144
|
+
const row = this.db.query(`
|
|
15145
|
+
UPDATE share_sessions
|
|
15146
|
+
SET revoked_at = ?
|
|
15147
|
+
WHERE project_id = ? AND id = ? AND revoked_at IS NULL
|
|
15148
|
+
RETURNING *
|
|
15149
|
+
`).get(revocation.revokedAt.toISOString(), revocation.projectId, revocation.id);
|
|
15150
|
+
return row ? rowToRecord2(row) : this.getRow(revocation.projectId, revocation.id);
|
|
15151
|
+
}
|
|
15152
|
+
close() {
|
|
15153
|
+
closeSqliteStoreConnection(this.connection);
|
|
15154
|
+
}
|
|
15155
|
+
getRow(projectId, id) {
|
|
15156
|
+
const row = this.db.query("SELECT * FROM share_sessions WHERE project_id = ? AND id = ?").get(projectId, id);
|
|
15157
|
+
return row ? rowToRecord2(row) : null;
|
|
15158
|
+
}
|
|
15159
|
+
}
|
|
15160
|
+
function rowToRecord2(row) {
|
|
15161
|
+
return parseShareSessionRecord({
|
|
15162
|
+
projectId: row.project_id,
|
|
15163
|
+
id: row.id,
|
|
15164
|
+
grantId: row.grant_id,
|
|
15165
|
+
tokenHash: row.token_hash,
|
|
15166
|
+
createdAt: row.created_at,
|
|
15167
|
+
expiresAt: row.expires_at,
|
|
15168
|
+
absoluteExpiresAt: row.absolute_expires_at,
|
|
15169
|
+
...row.revoked_at === null ? {} : { revokedAt: row.revoked_at }
|
|
15170
|
+
});
|
|
15171
|
+
}
|
|
15172
|
+
function invalidRecord2(message) {
|
|
15173
|
+
return new ShareSessionStorageError("invalid_record", `[SixbSqlite] ${message}`);
|
|
15174
|
+
}
|
|
15175
|
+
|
|
14072
15176
|
// src/sync-run-storage.ts
|
|
14073
15177
|
import { parseSixbFailure as parseSixbFailure4, serializeSixbFailure as serializeSixbFailure5 } from "@sixb/core/internal/errors";
|
|
14074
15178
|
import { assertSyncRunExecution } from "@sixb/core/internal/sync-run-storage-provider";
|
|
@@ -15444,6 +16548,8 @@ class SqliteStorage {
|
|
|
15444
16548
|
timeseries;
|
|
15445
16549
|
webhookRuns;
|
|
15446
16550
|
rules;
|
|
16551
|
+
shareGrants;
|
|
16552
|
+
shareSessions;
|
|
15447
16553
|
connectorConnections;
|
|
15448
16554
|
migrators;
|
|
15449
16555
|
connection;
|
|
@@ -15475,7 +16581,7 @@ class SqliteStorage {
|
|
|
15475
16581
|
}, assertRootOperationAvailable) : scope;
|
|
15476
16582
|
const readObjects = path ? new SqliteObjectStorage({ connection: this.readConnection }) : stores.objects;
|
|
15477
16583
|
const readTimeseries = path ? new SqliteTimeseriesStorage({ connection: this.readConnection }) : stores.timeseries;
|
|
15478
|
-
this.objects =
|
|
16584
|
+
this.objects = createObjectOperationScope(readObjects, readScope);
|
|
15479
16585
|
this.ontology = createOntologyOperationScope(stores.ontology, ontologyScope);
|
|
15480
16586
|
this.auth = createAuthOperationScope(stores.auth, scope);
|
|
15481
16587
|
this.executions = createOperationScopedFacade(stores.executions, scope);
|
|
@@ -15492,6 +16598,8 @@ class SqliteStorage {
|
|
|
15492
16598
|
this.workflowInterventions = createOperationScopedFacade(stores.workflowInterventions, scope);
|
|
15493
16599
|
this.webhookRuns = createOperationScopedFacade(stores.webhookRuns, scope);
|
|
15494
16600
|
this.rules = createOperationScopedFacade(stores.rules, scope);
|
|
16601
|
+
this.shareGrants = createOperationScopedFacade(stores.shareGrants, scope);
|
|
16602
|
+
this.shareSessions = createOperationScopedFacade(stores.shareSessions, scope);
|
|
15495
16603
|
this.connectorConnections = createOperationScopedFacade(stores.connectorConnections, scope);
|
|
15496
16604
|
this.migrators = options.path ? createSqliteStorageMigrators(options.path) : [];
|
|
15497
16605
|
registerSqliteStorageTestingAdapter(this, (durationMs) => stores.connectorConnections.advanceTimeForTesting(durationMs));
|
|
@@ -15590,7 +16698,9 @@ class SqliteStorage {
|
|
|
15590
16698
|
}
|
|
15591
16699
|
function createSqliteStores(connection, options) {
|
|
15592
16700
|
const auth = new SqliteAuthStorage({ connection });
|
|
15593
|
-
const
|
|
16701
|
+
const shareGrants = new SqliteShareGrantStorage({ connection });
|
|
16702
|
+
const shareSessions = new SqliteShareSessionStorage({ connection });
|
|
16703
|
+
const executions = new SqliteExecutionStorage(connection.db, auth, shareSessions);
|
|
15594
16704
|
return {
|
|
15595
16705
|
objects: new SqliteObjectStorage({ connection }),
|
|
15596
16706
|
ontology: new SqliteOntologyStorage({
|
|
@@ -15613,6 +16723,8 @@ function createSqliteStores(connection, options) {
|
|
|
15613
16723
|
workflowInterventions: new SqliteWorkflowInterventionStorage({ connection }),
|
|
15614
16724
|
webhookRuns: new SqliteWebhookRunStorage({ connection, executions }),
|
|
15615
16725
|
rules: new SqliteRulesStorage({ connection }),
|
|
16726
|
+
shareGrants,
|
|
16727
|
+
shareSessions,
|
|
15616
16728
|
connectorConnections: new SqliteConnectorConnectionStorage(connection)
|
|
15617
16729
|
};
|
|
15618
16730
|
}
|
|
@@ -15621,4 +16733,4 @@ export {
|
|
|
15621
16733
|
SqliteStorage
|
|
15622
16734
|
};
|
|
15623
16735
|
|
|
15624
|
-
//# debugId=
|
|
16736
|
+
//# debugId=5ACA9B909AAC301E64756E2164756E21
|