Line data Source code
1 : import type { CatalogNameDefaults } from '@ankoh/dashql-core';
2 :
3 : import type { ConnectionParams, HyperConnectionParams, SalesforceConnectionParams, TrinoConnectionParams } from './connection_params.js';
4 : import type { ConnectionStateDetailsVariant } from './connection_state_details.js';
5 : import type { ConnectionAction, ConnectionState } from './connection_state.js';
6 : import type { HyperConnectionDetails } from './hyper/hyper_connection_state.js';
7 : import type { SalesforceConnectionStateDetails } from './salesforce/salesforce_connection_state.js';
8 : import type { TrinoConnectionStateDetails } from './trino/trino_connection_state.js';
9 : import { ConnectorType, type ConnectorInfo } from './connector_info.js';
10 : import type { QueryExecutionArgs } from './query_execution_args.js';
11 : import type { QueryExecutionResponseStream } from '../query/query_execution_state.js';
12 : import { HYPER_CONNECTOR_DESCRIPTOR } from './hyper/hyper_connector_descriptor.js';
13 : import { SALESFORCE_CONNECTOR_DESCRIPTOR, SIDB_CONNECTOR_DESCRIPTOR } from './salesforce/salesforce_connector_descriptor.js';
14 : import { TRINO_CONNECTOR_DESCRIPTOR } from './trino/trino_connector_descriptor.js';
15 :
16 : /// The params of the connectors by the field of the connection params that holds them
17 : export interface ConnectorParamsMap {
18 : /// Direct-to-Hyper connections
19 : hyper: HyperConnectionParams;
20 : /// Salesforce Data Cloud connections
21 : salesforce: SalesforceConnectionParams;
22 : /// SIDB connections, they share the params of Salesforce Data Cloud connections
23 : sidb: SalesforceConnectionParams;
24 : /// Trino connections
25 : trino: TrinoConnectionParams;
26 : }
27 : /// The details of the connection state of the connectors
28 : interface ConnectorDetailsMap {
29 : /// Direct-to-Hyper connections
30 : hyper: HyperConnectionDetails;
31 : /// Salesforce Data Cloud connections
32 : salesforce: SalesforceConnectionStateDetails;
33 : /// SIDB connections
34 : sidb: SalesforceConnectionStateDetails;
35 : /// Trino connections
36 : trino: TrinoConnectionStateDetails;
37 : }
38 : /// The field of the connection params that holds the params of a connector, e.g. `{ hyper: ... }`
39 : export type ConnectorParamsKey = keyof ConnectorParamsMap;
40 :
41 : /// What the connection layer knows about a connector.
42 : ///
43 : /// Every connector describes itself once, operations on connections look up the connector instead
44 : /// of switching on its type. The params and details of the connection state always hold the params
45 : /// of the connector under its key, generic operations convert between them through `paramsKey`.
46 : export interface ConnectorDescriptor<K extends ConnectorParamsKey = ConnectorParamsKey> {
47 : /// The connector info
48 : info: ConnectorInfo;
49 : /// The field of the connection params that holds the params of the connector
50 : paramsKey: K;
51 : /// The variant type of the details of the connection state
52 : detailsType: ConnectionStateDetailsVariant['type'];
53 : /// The params of a new connection
54 : defaultParams(): ConnectorParamsMap[K];
55 : /// Create the details of the connection state
56 : createDetails(params: ConnectorParamsMap[K]): ConnectorDetailsMap[K];
57 : /// Apply an action of the connector to the connection state, null if the action is not one of its own
58 : reduce(state: ConnectionState, action: ConnectionAction): ConnectionState | null;
59 : /// Remove the raw form rows, they belong only to the local draft
60 : withoutDraftRows(params: ConnectorParamsMap[K]): ConnectorParamsMap[K];
61 : /// Strip the secrets before the params are shared, the login hint only if `withLoginHint` is false
62 : sanitizeForSharing(params: ConnectorParamsMap[K], withLoginHint: boolean): ConnectorParamsMap[K];
63 : /// The login hint (the account username or login) of the params, null if there is none
64 : loginHint(params: ConnectorParamsMap[K]): string | null;
65 : /// The params that identify the results of a query in the query result cache
66 : cacheSignature(params: ConnectorParamsMap[K]): unknown;
67 : /// The database and schema of the relations that unqualified statements create or drop.
68 : /// They match the names that the catalog loader gives the relations of the connection.
69 : catalogNameDefaults(details: ConnectorDetailsMap[K]): CatalogNameDefaults;
70 : /// Execute a query on the channel of a connection, a channel override of the connector wins
71 : executeQuery(details: ConnectorDetailsMap[K], args: QueryExecutionArgs, abort?: AbortSignal): Promise<QueryExecutionResponseStream>;
72 : /// The number of statements of a session run that a connection executes at once
73 : maxConcurrentQueries(details: ConnectorDetailsMap[K]): number;
74 : /// Does the catalog of a connection outlive the page? The relations of a database that is created anew with
75 : /// every page load and the catalog changes of its statements are neither persisted nor restored.
76 : catalogIsDurable(params: ConnectorParamsMap[K]): boolean;
77 : /// Can the queries of a connection read the data files that are attached to a session?
78 : readsAttachments(details: ConnectorDetailsMap[K]): boolean;
79 : }
80 :
81 : /// The connectors by connector type
82 1 : export const CONNECTOR_DESCRIPTORS: Record<ConnectorType, ConnectorDescriptor> = {
83 1 : [ConnectorType.HYPER]: HYPER_CONNECTOR_DESCRIPTOR,
84 1 : [ConnectorType.SALESFORCE_DATA_CLOUD]: SALESFORCE_CONNECTOR_DESCRIPTOR,
85 1 : [ConnectorType.TRINO]: TRINO_CONNECTOR_DESCRIPTOR,
86 1 : [ConnectorType.SIDB]: SIDB_CONNECTOR_DESCRIPTOR,
87 1 : };
88 1 : const DESCRIPTORS = Object.values(CONNECTOR_DESCRIPTORS);
89 :
90 : /// The connector of connection params
91 1 : export function connectorOfParams(params: ConnectionParams): ConnectorDescriptor {
92 1 : return DESCRIPTORS.find(connector => connector.paramsKey in params)!;
93 1 : }
94 :
95 : /// The connector of the details of a connection state
96 1 : export function connectorOfDetails(details: ConnectionStateDetailsVariant): ConnectorDescriptor {
97 1 : return DESCRIPTORS.find(connector => connector.detailsType === details.type)!;
98 1 : }
99 :
100 : /// The params of the connector of connection params
101 1 : export function connectorParams(connector: ConnectorDescriptor, params: ConnectionParams): ConnectorParamsMap[ConnectorParamsKey] {
102 1 : return (params as Partial<ConnectorParamsMap>)[connector.paramsKey]!;
103 1 : }
104 :
105 : /// The connection params that hold the params of a connector
106 1 : export function connectionParamsOf(connector: ConnectorDescriptor, params: ConnectorParamsMap[ConnectorParamsKey]): ConnectionParams {
107 1 : return { [connector.paramsKey]: params } as unknown as ConnectionParams;
108 1 : }
109 :
110 : /// The details of a connection state with connection params
111 1 : export function connectionStateDetailsOf(connector: ConnectorDescriptor, params: ConnectorParamsMap[ConnectorParamsKey]): ConnectionStateDetailsVariant {
112 1 : return { type: connector.detailsType, value: connector.createDetails(params) } as ConnectionStateDetailsVariant;
113 1 : }
114 :
115 : /// The database and schema of the relations that unqualified statements create or drop on a connection
116 1 : export function catalogNameDefaults(details: ConnectionStateDetailsVariant): CatalogNameDefaults {
117 1 : return connectorOfDetails(details).catalogNameDefaults(details.value);
118 1 : }
119 :
120 : /// Can the queries of a connection read the data files that are attached to a session?
121 1 : export function connectionReadsAttachments(details: ConnectionStateDetailsVariant | null | undefined): boolean {
122 1 : return details != null && connectorOfDetails(details).readsAttachments(details.value);
123 1 : }
|