@qualithm/arrow-flight-sql-js 0.3.0 → 0.4.1
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/README.md +86 -231
- package/dist/client.d.ts +68 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +112 -1
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/proto.d.ts +40 -0
- package/dist/proto.d.ts.map +1 -1
- package/dist/proto.js +68 -0
- package/dist/proto.js.map +1 -1
- package/dist/types.d.ts +56 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +12 -9
- package/proto/Flight.proto +38 -5
- package/proto/FlightSql.proto +60 -56
package/README.md
CHANGED
|
@@ -17,18 +17,6 @@ servers. It handles the complete protocol stack:
|
|
|
17
17
|
- **Arrow IPC Streaming** – Native Arrow record batch handling
|
|
18
18
|
- **Authentication** – Bearer tokens, basic auth, and custom handlers
|
|
19
19
|
|
|
20
|
-
## Design Goals
|
|
21
|
-
|
|
22
|
-
Arrow Flight SQL JS is modeled on the canonical implementations:
|
|
23
|
-
|
|
24
|
-
| Reference | What We Adopt |
|
|
25
|
-
| ------------------------- | ---------------------------------------------------- |
|
|
26
|
-
| **Java** (reference impl) | Comprehensive API surface, error handling patterns |
|
|
27
|
-
| **C++** | Streaming-first patterns, performance considerations |
|
|
28
|
-
| **Go** | Connection pooling, context/cancellation model |
|
|
29
|
-
|
|
30
|
-
We aim for **API parity** with the official clients where JavaScript idioms allow.
|
|
31
|
-
|
|
32
20
|
## Installation
|
|
33
21
|
|
|
34
22
|
```bash
|
|
@@ -121,85 +109,69 @@ await pool.withConnection(async (client) => {
|
|
|
121
109
|
await pool.close()
|
|
122
110
|
```
|
|
123
111
|
|
|
124
|
-
##
|
|
112
|
+
## Streaming Best Practices
|
|
125
113
|
|
|
126
|
-
|
|
114
|
+
Arrow Flight SQL is streaming-first by design. For large result sets, use streaming to minimize
|
|
115
|
+
memory usage:
|
|
127
116
|
|
|
128
117
|
```typescript
|
|
129
|
-
|
|
118
|
+
// ✅ GOOD: Stream results for memory efficiency
|
|
119
|
+
const result = await client.query("SELECT * FROM large_table")
|
|
120
|
+
let totalRows = 0
|
|
130
121
|
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
})
|
|
122
|
+
for await (const batch of result.stream()) {
|
|
123
|
+
// Process one batch at a time - memory-efficient
|
|
124
|
+
totalRows += batch.numRows
|
|
125
|
+
await processRecordBatch(batch) // Your processing logic
|
|
126
|
+
}
|
|
127
|
+
console.log(`Processed ${totalRows} rows`)
|
|
137
128
|
|
|
138
|
-
|
|
129
|
+
// ❌ AVOID: collect() loads entire result into memory
|
|
130
|
+
// const table = await result.collect() // May cause OOM for large results!
|
|
139
131
|
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
heartbeatMs: 30_000 // Server heartbeat interval
|
|
144
|
-
})
|
|
132
|
+
// ✅ GOOD: Process with backpressure-aware async iteration
|
|
133
|
+
async function processWithBackpressure(result: QueryResult) {
|
|
134
|
+
const stream = result.stream()
|
|
145
135
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
136
|
+
for await (const batch of stream) {
|
|
137
|
+
// Async work in the loop naturally creates backpressure
|
|
138
|
+
// The stream won't fetch the next batch until this completes
|
|
139
|
+
await uploadToS3(batch)
|
|
140
|
+
}
|
|
149
141
|
}
|
|
150
142
|
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
143
|
+
// ✅ GOOD: Early termination with break
|
|
144
|
+
async function findFirst(result: QueryResult, predicate: (row: any) => boolean) {
|
|
145
|
+
for await (const batch of result.stream()) {
|
|
146
|
+
for (let i = 0; i < batch.numRows; i++) {
|
|
147
|
+
const row = batch.get(i)
|
|
148
|
+
if (predicate(row)) {
|
|
149
|
+
return row // Stream automatically cleaned up
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return null
|
|
154
|
+
}
|
|
158
155
|
|
|
159
|
-
//
|
|
160
|
-
|
|
156
|
+
// ✅ GOOD: Use LIMIT at the SQL level when possible
|
|
157
|
+
const limitedResult = await client.query("SELECT * FROM large_table LIMIT 1000")
|
|
158
|
+
const table = await limitedResult.collect() // Safe with LIMIT
|
|
161
159
|
|
|
162
|
-
//
|
|
163
|
-
await
|
|
160
|
+
// ✅ GOOD: Monitor memory with batch sizes
|
|
161
|
+
for await (const batch of result.stream()) {
|
|
162
|
+
console.log(`Batch: ${batch.numRows} rows, ~${batch.byteLength} bytes`)
|
|
163
|
+
}
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
###
|
|
167
|
-
|
|
168
|
-
| Option | Default | Description |
|
|
169
|
-
| ---------------------- | ------------- | -------------------------------------------------- |
|
|
170
|
-
| `mode` | `ChangesOnly` | Subscription mode (Full, ChangesOnly, Tail) |
|
|
171
|
-
| `heartbeatMs` | `30000` | Server heartbeat interval in milliseconds |
|
|
172
|
-
| `signal` | - | AbortSignal for cancellation |
|
|
173
|
-
| `autoReconnect` | `true` | Auto-reconnect on connection loss |
|
|
174
|
-
| `maxReconnectAttempts` | `10` | Maximum reconnection attempts |
|
|
175
|
-
| `reconnectDelayMs` | `1000` | Initial reconnect delay |
|
|
176
|
-
| `maxReconnectDelayMs` | `30000` | Maximum reconnect delay (with exponential backoff) |
|
|
177
|
-
|
|
178
|
-
### Low-Level DoExchange
|
|
166
|
+
### When to Use `collect()` vs `stream()`
|
|
179
167
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
// Send data to server
|
|
189
|
-
await exchange.send({
|
|
190
|
-
dataHeader: new Uint8Array(),
|
|
191
|
-
dataBody: new Uint8Array(),
|
|
192
|
-
appMetadata: new TextEncoder().encode(JSON.stringify({ action: "subscribe" }))
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
// Receive data from server
|
|
196
|
-
for await (const data of exchange) {
|
|
197
|
-
console.log("Received:", data)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Half-close (signal end of client stream)
|
|
201
|
-
await exchange.end()
|
|
202
|
-
```
|
|
168
|
+
| Scenario | Recommendation |
|
|
169
|
+
| ------------------------------ | ------------------------------------------------------ |
|
|
170
|
+
| Small result sets (<100K rows) | `collect()` is fine |
|
|
171
|
+
| Large/unknown result size | Use `stream()` with batch processing |
|
|
172
|
+
| Need aggregations | Stream and aggregate incrementally |
|
|
173
|
+
| Export to file | Stream and write chunks |
|
|
174
|
+
| Memory-constrained environment | Always `stream()`, never `collect()` unbounded results |
|
|
203
175
|
|
|
204
176
|
## Observability & Metrics
|
|
205
177
|
|
|
@@ -380,6 +352,26 @@ for (const pk of primaryKeys) {
|
|
|
380
352
|
// Get foreign key relationships
|
|
381
353
|
const exportedKeys = await client.getExportedKeys("users") // Keys referencing this table
|
|
382
354
|
const importedKeys = await client.getImportedKeys("orders") // Keys this table references
|
|
355
|
+
|
|
356
|
+
// Get cross-reference between two tables
|
|
357
|
+
const refs = await client.getCrossReference({
|
|
358
|
+
pkTable: "users",
|
|
359
|
+
fkTable: "orders",
|
|
360
|
+
pkDbSchema: "public",
|
|
361
|
+
fkDbSchema: "public"
|
|
362
|
+
})
|
|
363
|
+
|
|
364
|
+
// Get server SQL info and capabilities
|
|
365
|
+
const sqlInfo = await client.getSqlInfo()
|
|
366
|
+
for (const info of sqlInfo) {
|
|
367
|
+
console.log(`Info ${info.infoName}: ${info.value}`)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Get supported data types
|
|
371
|
+
const typeInfo = await client.getXdbcTypeInfo()
|
|
372
|
+
for (const t of typeInfo) {
|
|
373
|
+
console.log(`${t.typeName}: SQL type ${t.dataType}`)
|
|
374
|
+
}
|
|
383
375
|
```
|
|
384
376
|
|
|
385
377
|
## Prepared Statements
|
|
@@ -406,89 +398,29 @@ try {
|
|
|
406
398
|
}
|
|
407
399
|
```
|
|
408
400
|
|
|
409
|
-
##
|
|
410
|
-
|
|
411
|
-
### FlightSqlClient
|
|
412
|
-
|
|
413
|
-
The main client for interacting with Flight SQL servers.
|
|
414
|
-
|
|
415
|
-
#### Constructor Options
|
|
401
|
+
## Real-Time Subscriptions
|
|
416
402
|
|
|
417
|
-
|
|
418
|
-
| ------------------ | ------------------------ | ------- | ------------------------------- |
|
|
419
|
-
| `host` | `string` | — | Server hostname |
|
|
420
|
-
| `port` | `number` | — | Server port |
|
|
421
|
-
| `tls` | `boolean` | `true` | Enable TLS |
|
|
422
|
-
| `auth` | `AuthConfig` | — | Authentication configuration |
|
|
423
|
-
| `credentials` | `ChannelCredentials` | — | Custom gRPC channel credentials |
|
|
424
|
-
| `metadata` | `Record<string, string>` | — | Custom metadata headers |
|
|
425
|
-
| `connectTimeoutMs` | `number` | `30000` | Connection timeout in ms |
|
|
426
|
-
| `requestTimeoutMs` | `number` | `60000` | Request timeout in ms |
|
|
403
|
+
> **Note:** Requires server support. Not all Flight SQL servers implement `DoExchange`.
|
|
427
404
|
|
|
428
|
-
|
|
405
|
+
Subscribe to live data updates:
|
|
429
406
|
|
|
430
407
|
```typescript
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
#### Methods
|
|
438
|
-
|
|
439
|
-
##### Query Execution
|
|
440
|
-
|
|
441
|
-
- `query(query: string, options?): Promise<QueryResult>` – Execute SQL, returns result with
|
|
442
|
-
`stream()` and `collect()` methods
|
|
443
|
-
- `execute(query: string, options?): Promise<FlightInfo>` – _(deprecated)_ Execute SQL, return
|
|
444
|
-
flight info
|
|
445
|
-
- `executeUpdate(query: string): Promise<bigint>` – Execute DML, return affected rows
|
|
446
|
-
- `prepare(query: string): Promise<PreparedStatement>` – Create prepared statement
|
|
447
|
-
|
|
448
|
-
##### Catalog Introspection
|
|
449
|
-
|
|
450
|
-
- `getCatalogs(): Promise<string[]>` – List available catalogs
|
|
451
|
-
- `getSchemas(catalog?, schemaPattern?): Promise<Schema[]>` – List schemas
|
|
452
|
-
- `getTables(options?): Promise<Table[]>` – List tables with filters
|
|
453
|
-
- `getTableTypes(): Promise<string[]>` – List table type names
|
|
454
|
-
- `getPrimaryKeys(table, catalog?, schema?): Promise<PrimaryKey[]>` – Get primary keys
|
|
455
|
-
- `getExportedKeys(table, catalog?, schema?): Promise<ForeignKey[]>` – Get exported foreign keys
|
|
456
|
-
- `getImportedKeys(table, catalog?, schema?): Promise<ForeignKey[]>` – Get imported foreign keys
|
|
457
|
-
|
|
458
|
-
##### Low-Level Flight Operations
|
|
459
|
-
|
|
460
|
-
- `getFlightInfo(descriptor): Promise<FlightInfo>` – Get flight metadata
|
|
461
|
-
- `doGet(ticket): AsyncIterable<RecordBatch>` – Fetch data by ticket
|
|
462
|
-
- `doPut(descriptor, stream): Promise<void>` – Upload Arrow data
|
|
463
|
-
- `doAction(type, body?): AsyncIterable<Result>` – Execute custom action
|
|
464
|
-
|
|
465
|
-
##### Connection Management
|
|
466
|
-
|
|
467
|
-
- `connect(): Promise<void>` – Establish connection and authenticate
|
|
468
|
-
- `close(): void` – Close connection and release resources
|
|
469
|
-
- `isConnected(): boolean` – Check connection status
|
|
408
|
+
const subscription = client.subscribe("SELECT * FROM events", {
|
|
409
|
+
mode: SubscriptionMode.ChangesOnly,
|
|
410
|
+
heartbeatMs: 30_000
|
|
411
|
+
})
|
|
470
412
|
|
|
471
|
-
|
|
413
|
+
for await (const batch of subscription) {
|
|
414
|
+
console.log(`Received ${batch.numRows} rows`)
|
|
415
|
+
}
|
|
472
416
|
|
|
417
|
+
// Cancel with AbortController
|
|
418
|
+
controller.abort()
|
|
419
|
+
// Or manually
|
|
420
|
+
await subscription.unsubscribe()
|
|
473
421
|
```
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
├─────────────────────────────────────────────────────────┤
|
|
477
|
-
│ Query Builder │ Prepared Statements │ Catalog API │
|
|
478
|
-
├─────────────────────────────────────────────────────────┤
|
|
479
|
-
│ Flight SQL Protocol │
|
|
480
|
-
│ (GetFlightInfo, DoGet, DoPut, DoAction) │
|
|
481
|
-
├─────────────────────────────────────────────────────────┤
|
|
482
|
-
│ Protocol Buffers Layer │
|
|
483
|
-
│ (FlightDescriptor, FlightInfo, etc.) │
|
|
484
|
-
├─────────────────────────────────────────────────────────┤
|
|
485
|
-
│ gRPC Transport │
|
|
486
|
-
│ (HTTP/2 + TLS + Auth Headers) │
|
|
487
|
-
├─────────────────────────────────────────────────────────┤
|
|
488
|
-
│ Connection Pool │
|
|
489
|
-
│ (Health checks, reconnection, backoff) │
|
|
490
|
-
└─────────────────────────────────────────────────────────┘
|
|
491
|
-
```
|
|
422
|
+
|
|
423
|
+
See the [API documentation](https://qualithm.github.io/arrow-flight-sql-js/) for full options.
|
|
492
424
|
|
|
493
425
|
## Compatibility
|
|
494
426
|
|
|
@@ -536,68 +468,6 @@ const result = await client.query("SELECT * FROM my_table")
|
|
|
536
468
|
- Bidirectional streaming (`DoExchange`, `Handshake`) is not supported
|
|
537
469
|
- Use bearer token auth via `setAuthToken()` instead of `Handshake`
|
|
538
470
|
|
|
539
|
-
**Envoy gRPC-Web Proxy Example:**
|
|
540
|
-
|
|
541
|
-
```yaml
|
|
542
|
-
# envoy.yaml
|
|
543
|
-
static_resources:
|
|
544
|
-
listeners:
|
|
545
|
-
- address:
|
|
546
|
-
socket_address:
|
|
547
|
-
address: 0.0.0.0
|
|
548
|
-
port_value: 8080
|
|
549
|
-
filter_chains:
|
|
550
|
-
- filters:
|
|
551
|
-
- name: envoy.filters.network.http_connection_manager
|
|
552
|
-
typed_config:
|
|
553
|
-
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
|
554
|
-
codec_type: AUTO
|
|
555
|
-
stat_prefix: ingress_http
|
|
556
|
-
route_config:
|
|
557
|
-
name: local_route
|
|
558
|
-
virtual_hosts:
|
|
559
|
-
- name: backend
|
|
560
|
-
domains: ["*"]
|
|
561
|
-
routes:
|
|
562
|
-
- match: { prefix: "/" }
|
|
563
|
-
route:
|
|
564
|
-
cluster: flight_sql_backend
|
|
565
|
-
cors:
|
|
566
|
-
allow_origin_string_match:
|
|
567
|
-
- prefix: "*"
|
|
568
|
-
allow_methods: "GET, PUT, DELETE, POST, OPTIONS"
|
|
569
|
-
allow_headers: "content-type,x-grpc-web,x-user-agent"
|
|
570
|
-
expose_headers: "grpc-status,grpc-message"
|
|
571
|
-
http_filters:
|
|
572
|
-
- name: envoy.filters.http.grpc_web
|
|
573
|
-
- name: envoy.filters.http.cors
|
|
574
|
-
- name: envoy.filters.http.router
|
|
575
|
-
clusters:
|
|
576
|
-
- name: flight_sql_backend
|
|
577
|
-
connect_timeout: 0.25s
|
|
578
|
-
type: LOGICAL_DNS
|
|
579
|
-
http2_protocol_options: {}
|
|
580
|
-
lb_policy: ROUND_ROBIN
|
|
581
|
-
load_assignment:
|
|
582
|
-
cluster_name: flight_sql_backend
|
|
583
|
-
endpoints:
|
|
584
|
-
- lb_endpoints:
|
|
585
|
-
- endpoint:
|
|
586
|
-
address:
|
|
587
|
-
socket_address:
|
|
588
|
-
address: your-flight-sql-server
|
|
589
|
-
port_value: 50051
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
### Flight SQL Servers
|
|
593
|
-
|
|
594
|
-
Tested against:
|
|
595
|
-
|
|
596
|
-
- Apache Arrow Flight SQL reference server
|
|
597
|
-
- DuckDB Flight SQL extension
|
|
598
|
-
- DataFusion Ballista
|
|
599
|
-
- Custom lakehouse implementations
|
|
600
|
-
|
|
601
471
|
## Development
|
|
602
472
|
|
|
603
473
|
```bash
|
|
@@ -621,23 +491,8 @@ bun run format:fix
|
|
|
621
491
|
bun run docs
|
|
622
492
|
```
|
|
623
493
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
This client implements the
|
|
627
|
-
[Arrow Flight SQL specification](https://arrow.apache.org/docs/format/FlightSql.html):
|
|
628
|
-
|
|
629
|
-
- **Flight SQL 13.0** – Current target version
|
|
630
|
-
- Full protobuf message support
|
|
631
|
-
- All standard actions (CreatePreparedStatement, ClosePreparedStatement, etc.)
|
|
632
|
-
- Catalog introspection commands
|
|
633
|
-
- Transaction support (where server supports it)
|
|
494
|
+
Implements [Arrow Flight SQL 13.0](https://arrow.apache.org/docs/format/FlightSql.html).
|
|
634
495
|
|
|
635
496
|
## License
|
|
636
497
|
|
|
637
498
|
MIT
|
|
638
|
-
|
|
639
|
-
## Related Projects
|
|
640
|
-
|
|
641
|
-
- [Apache Arrow](https://arrow.apache.org/) – The Arrow columnar format
|
|
642
|
-
- [Arrow Flight](https://arrow.apache.org/docs/format/Flight.html) – High-performance data transport
|
|
643
|
-
- [Arrow Flight SQL](https://arrow.apache.org/docs/format/FlightSql.html) – SQL over Flight
|
package/dist/client.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Modeled after the official Arrow Flight SQL clients (Java, C++, Go).
|
|
6
6
|
*/
|
|
7
7
|
import { type RecordBatch, type Schema, type Table } from "apache-arrow";
|
|
8
|
-
import { type Action, type ActionResult, type ActionType, type CatalogInfo, type ExecuteOptions, type FlightData, type FlightDescriptor, type FlightInfo, type FlightSqlClientOptions, type ForeignKeyInfo, type PrimaryKeyInfo, type SchemaInfo, type SchemaResult, type SubscribeOptions, type TableInfo, type TableType, type Ticket } from "./types.js";
|
|
8
|
+
import { type Action, type ActionResult, type ActionType, type CatalogInfo, type ExecuteOptions, type FlightData, type FlightDescriptor, type FlightInfo, type FlightSqlClientOptions, type ForeignKeyInfo, type PrimaryKeyInfo, type SchemaInfo, type SchemaResult, type SqlInfo, type SubscribeOptions, type TableInfo, type TableType, type Ticket, type XdbcTypeInfo } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* Flight SQL client for executing queries and managing data with Arrow Flight SQL servers.
|
|
11
11
|
*
|
|
@@ -223,6 +223,73 @@ export declare class FlightSqlClient {
|
|
|
223
223
|
* ```
|
|
224
224
|
*/
|
|
225
225
|
getImportedKeys(table: string, catalog?: string, schema?: string): Promise<ForeignKeyInfo[]>;
|
|
226
|
+
/**
|
|
227
|
+
* Get SQL server information and capabilities.
|
|
228
|
+
*
|
|
229
|
+
* @param infoCodes - Optional array of specific info codes to retrieve.
|
|
230
|
+
* If omitted, all available info is retrieved.
|
|
231
|
+
* @returns Array of SQL info name-value pairs
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* // Get all server information
|
|
236
|
+
* const allInfo = await client.getSqlInfo()
|
|
237
|
+
*
|
|
238
|
+
* // Get specific info (server name and version)
|
|
239
|
+
* const info = await client.getSqlInfo([0, 1])
|
|
240
|
+
* for (const item of info) {
|
|
241
|
+
* console.log(`${item.infoName}: ${item.value}`)
|
|
242
|
+
* }
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
getSqlInfo(infoCodes?: number[]): Promise<SqlInfo[]>;
|
|
246
|
+
/**
|
|
247
|
+
* Parse a SQL info row from the dense union value format.
|
|
248
|
+
*/
|
|
249
|
+
private parseSqlInfoRow;
|
|
250
|
+
/**
|
|
251
|
+
* Get XDBC type information supported by the server.
|
|
252
|
+
*
|
|
253
|
+
* @param dataType - Optional specific data type code to retrieve info for.
|
|
254
|
+
* If omitted, all types are retrieved.
|
|
255
|
+
* @returns Array of XDBC type info objects
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* // Get all supported types
|
|
260
|
+
* const types = await client.getXdbcTypeInfo()
|
|
261
|
+
* for (const t of types) {
|
|
262
|
+
* console.log(`${t.typeName}: SQL type ${t.dataType}`)
|
|
263
|
+
* }
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
getXdbcTypeInfo(dataType?: number): Promise<XdbcTypeInfo[]>;
|
|
267
|
+
/**
|
|
268
|
+
* Get the foreign key relationships between two tables.
|
|
269
|
+
*
|
|
270
|
+
* This returns foreign keys in the foreign key table that reference
|
|
271
|
+
* the primary key of the primary key table.
|
|
272
|
+
*
|
|
273
|
+
* @param options - Options specifying the primary key and foreign key tables
|
|
274
|
+
* @returns Array of foreign key information
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* // Find foreign keys from "orders" table that reference "users" table
|
|
279
|
+
* const refs = await client.getCrossReference({
|
|
280
|
+
* pkTable: "users",
|
|
281
|
+
* fkTable: "orders"
|
|
282
|
+
* })
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
getCrossReference(options: {
|
|
286
|
+
pkTable: string;
|
|
287
|
+
fkTable: string;
|
|
288
|
+
pkCatalog?: string;
|
|
289
|
+
pkDbSchema?: string;
|
|
290
|
+
fkCatalog?: string;
|
|
291
|
+
fkDbSchema?: string;
|
|
292
|
+
}): Promise<ForeignKeyInfo[]>;
|
|
226
293
|
/**
|
|
227
294
|
* Helper to fetch catalog results and map rows to typed objects
|
|
228
295
|
*/
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,WAAW,EAAqB,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { RecordBatchReader } from "apache-arrow";
|
|
8
8
|
import { collectToTable, parseFlightData, tryParseSchema } from "./arrow.js";
|
|
9
9
|
import { AuthenticationError, ConnectionError, FlightSqlError } from "./errors.js";
|
|
10
|
-
import { encodeActionClosePreparedStatementRequest, encodeActionCreatePreparedStatementRequest, encodeCommandGetCatalogs, encodeCommandGetDbSchemas, encodeCommandGetExportedKeys, encodeCommandGetImportedKeys, encodeCommandGetPrimaryKeys, encodeCommandGetTables, encodeCommandGetTableTypes, encodeCommandPreparedStatementQuery, encodeCommandStatementQuery, encodeCommandStatementUpdate, getBytesField, parseProtoFields, unwrapAny } from "./proto.js";
|
|
10
|
+
import { encodeActionClosePreparedStatementRequest, encodeActionCreatePreparedStatementRequest, encodeCommandGetCatalogs, encodeCommandGetCrossReference, encodeCommandGetDbSchemas, encodeCommandGetExportedKeys, encodeCommandGetImportedKeys, encodeCommandGetPrimaryKeys, encodeCommandGetSqlInfo, encodeCommandGetTables, encodeCommandGetTableTypes, encodeCommandGetXdbcTypeInfo, encodeCommandPreparedStatementQuery, encodeCommandStatementQuery, encodeCommandStatementUpdate, getBytesField, parseProtoFields, unwrapAny } from "./proto.js";
|
|
11
11
|
import { getTransportForRuntime } from "./transport-grpc-js.js";
|
|
12
12
|
import { SubscriptionMessageType, SubscriptionMode } from "./types.js";
|
|
13
13
|
// Default configuration values
|
|
@@ -452,6 +452,117 @@ export class FlightSqlClient {
|
|
|
452
452
|
const flightInfo = await this.getFlightInfo(descriptor);
|
|
453
453
|
return this.fetchForeignKeyResults(flightInfo);
|
|
454
454
|
}
|
|
455
|
+
/**
|
|
456
|
+
* Get SQL server information and capabilities.
|
|
457
|
+
*
|
|
458
|
+
* @param infoCodes - Optional array of specific info codes to retrieve.
|
|
459
|
+
* If omitted, all available info is retrieved.
|
|
460
|
+
* @returns Array of SQL info name-value pairs
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* // Get all server information
|
|
465
|
+
* const allInfo = await client.getSqlInfo()
|
|
466
|
+
*
|
|
467
|
+
* // Get specific info (server name and version)
|
|
468
|
+
* const info = await client.getSqlInfo([0, 1])
|
|
469
|
+
* for (const item of info) {
|
|
470
|
+
* console.log(`${item.infoName}: ${item.value}`)
|
|
471
|
+
* }
|
|
472
|
+
* ```
|
|
473
|
+
*/
|
|
474
|
+
async getSqlInfo(infoCodes) {
|
|
475
|
+
this.ensureConnected();
|
|
476
|
+
const command = encodeCommandGetSqlInfo(infoCodes);
|
|
477
|
+
const descriptor = {
|
|
478
|
+
type: 2, // CMD
|
|
479
|
+
cmd: command
|
|
480
|
+
};
|
|
481
|
+
const flightInfo = await this.getFlightInfo(descriptor);
|
|
482
|
+
return this.fetchCatalogResults(flightInfo, (row) => this.parseSqlInfoRow(row));
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Parse a SQL info row from the dense union value format.
|
|
486
|
+
*/
|
|
487
|
+
parseSqlInfoRow(row) {
|
|
488
|
+
const infoName = row.info_name;
|
|
489
|
+
const value = row.value;
|
|
490
|
+
return { infoName, value };
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Get XDBC type information supported by the server.
|
|
494
|
+
*
|
|
495
|
+
* @param dataType - Optional specific data type code to retrieve info for.
|
|
496
|
+
* If omitted, all types are retrieved.
|
|
497
|
+
* @returns Array of XDBC type info objects
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```typescript
|
|
501
|
+
* // Get all supported types
|
|
502
|
+
* const types = await client.getXdbcTypeInfo()
|
|
503
|
+
* for (const t of types) {
|
|
504
|
+
* console.log(`${t.typeName}: SQL type ${t.dataType}`)
|
|
505
|
+
* }
|
|
506
|
+
* ```
|
|
507
|
+
*/
|
|
508
|
+
async getXdbcTypeInfo(dataType) {
|
|
509
|
+
this.ensureConnected();
|
|
510
|
+
const command = encodeCommandGetXdbcTypeInfo(dataType);
|
|
511
|
+
const descriptor = {
|
|
512
|
+
type: 2, // CMD
|
|
513
|
+
cmd: command
|
|
514
|
+
};
|
|
515
|
+
const flightInfo = await this.getFlightInfo(descriptor);
|
|
516
|
+
return this.fetchCatalogResults(flightInfo, (row) => ({
|
|
517
|
+
typeName: row.type_name,
|
|
518
|
+
dataType: row.data_type,
|
|
519
|
+
columnSize: row.column_size,
|
|
520
|
+
literalPrefix: row.literal_prefix,
|
|
521
|
+
literalSuffix: row.literal_suffix,
|
|
522
|
+
createParams: row.create_params,
|
|
523
|
+
nullable: row.nullable,
|
|
524
|
+
caseSensitive: row.case_sensitive,
|
|
525
|
+
searchable: row.searchable,
|
|
526
|
+
unsignedAttribute: row.unsigned_attribute,
|
|
527
|
+
fixedPrecScale: row.fixed_prec_scale,
|
|
528
|
+
autoIncrement: row.auto_increment,
|
|
529
|
+
localTypeName: row.local_type_name,
|
|
530
|
+
minimumScale: row.minimum_scale,
|
|
531
|
+
maximumScale: row.maximum_scale,
|
|
532
|
+
sqlDataType: row.sql_data_type,
|
|
533
|
+
datetimeSubcode: row.datetime_subcode,
|
|
534
|
+
numPrecRadix: row.num_prec_radix,
|
|
535
|
+
intervalPrecision: row.interval_precision
|
|
536
|
+
}));
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Get the foreign key relationships between two tables.
|
|
540
|
+
*
|
|
541
|
+
* This returns foreign keys in the foreign key table that reference
|
|
542
|
+
* the primary key of the primary key table.
|
|
543
|
+
*
|
|
544
|
+
* @param options - Options specifying the primary key and foreign key tables
|
|
545
|
+
* @returns Array of foreign key information
|
|
546
|
+
*
|
|
547
|
+
* @example
|
|
548
|
+
* ```typescript
|
|
549
|
+
* // Find foreign keys from "orders" table that reference "users" table
|
|
550
|
+
* const refs = await client.getCrossReference({
|
|
551
|
+
* pkTable: "users",
|
|
552
|
+
* fkTable: "orders"
|
|
553
|
+
* })
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
async getCrossReference(options) {
|
|
557
|
+
this.ensureConnected();
|
|
558
|
+
const command = encodeCommandGetCrossReference(options);
|
|
559
|
+
const descriptor = {
|
|
560
|
+
type: 2, // CMD
|
|
561
|
+
cmd: command
|
|
562
|
+
};
|
|
563
|
+
const flightInfo = await this.getFlightInfo(descriptor);
|
|
564
|
+
return this.fetchForeignKeyResults(flightInfo);
|
|
565
|
+
}
|
|
455
566
|
/**
|
|
456
567
|
* Helper to fetch catalog results and map rows to typed objects
|
|
457
568
|
*/
|