@qualithm/arrow-flight-sql-js 1.0.0 → 1.2.0

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.
@@ -0,0 +1,138 @@
1
+ import { tableFromIPC } from "apache-arrow";
2
+ /**
3
+ * Collects all FlightData from a doGet stream into Arrow IPC bytes.
4
+ *
5
+ * @param dataStream - The async iterable of FlightData messages
6
+ * @returns Combined IPC bytes for all batches
7
+ */
8
+ async function collectFlightData(dataStream) {
9
+ const chunks = [];
10
+ for await (const data of dataStream) {
11
+ // The first message contains the schema in dataHeader
12
+ if (data.dataHeader.length > 0) {
13
+ chunks.push(data.dataHeader);
14
+ }
15
+ // Data body contains the actual record batch
16
+ if (data.dataBody.length > 0) {
17
+ chunks.push(data.dataBody);
18
+ }
19
+ }
20
+ return chunks;
21
+ }
22
+ /**
23
+ * Executes a query and returns results as an Arrow Table.
24
+ *
25
+ * This is a convenience function that handles the entire query workflow:
26
+ * 1. Executes the query to get FlightInfo
27
+ * 2. Retrieves data from all endpoints
28
+ * 3. Combines the data into an Arrow Table
29
+ *
30
+ * @param client - The FlightSqlClient to use
31
+ * @param query - The SQL query to execute
32
+ * @returns An Arrow Table containing all query results
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * import { queryToTable } from "@qualithm/arrow-flight-sql-js"
37
+ *
38
+ * const table = await queryToTable(client, "SELECT * FROM users LIMIT 100")
39
+ * console.log("Rows:", table.numRows)
40
+ * console.log("Columns:", table.schema.fields.map(f => f.name))
41
+ *
42
+ * // Iterate over rows
43
+ * for (const row of table) {
44
+ * console.log(row.toJSON())
45
+ * }
46
+ * ```
47
+ */
48
+ export async function queryToTable(client, query) {
49
+ const info = await client.query(query);
50
+ return flightInfoToTable(client, info);
51
+ }
52
+ /**
53
+ * Retrieves data from FlightInfo and returns it as an Arrow Table.
54
+ *
55
+ * @param client - The FlightSqlClient to use
56
+ * @param info - The FlightInfo from a query
57
+ * @returns An Arrow Table containing all data from the endpoints
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const info = await client.query("SELECT * FROM users")
62
+ * const table = await flightInfoToTable(client, info)
63
+ * ```
64
+ */
65
+ export async function flightInfoToTable(client, info) {
66
+ const allChunks = [];
67
+ for (const endpoint of info.endpoint) {
68
+ if (!endpoint.ticket) {
69
+ continue;
70
+ }
71
+ const dataStream = client.doGet(endpoint.ticket);
72
+ const chunks = await collectFlightData(dataStream);
73
+ allChunks.push(...chunks);
74
+ }
75
+ if (allChunks.length === 0) {
76
+ throw new Error("no data returned from query");
77
+ }
78
+ // Combine all chunks and parse as IPC
79
+ const totalLength = allChunks.reduce((sum, chunk) => sum + chunk.length, 0);
80
+ const combined = new Uint8Array(totalLength);
81
+ let offset = 0;
82
+ for (const chunk of allChunks) {
83
+ combined.set(chunk, offset);
84
+ offset += chunk.length;
85
+ }
86
+ return tableFromIPC(combined);
87
+ }
88
+ /**
89
+ * Iterates over query results as Arrow record batches.
90
+ *
91
+ * This is useful for processing large result sets without loading
92
+ * everything into memory at once.
93
+ *
94
+ * @param client - The FlightSqlClient to use
95
+ * @param info - The FlightInfo from a query
96
+ * @yields FlightData messages containing Arrow IPC data
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const info = await client.query("SELECT * FROM large_table")
101
+ *
102
+ * for await (const data of iterateResults(client, info)) {
103
+ * // Process each batch of data
104
+ * console.log("Received batch:", data.dataBody.length, "bytes")
105
+ * }
106
+ * ```
107
+ */
108
+ export async function* iterateResults(client, info) {
109
+ for (const endpoint of info.endpoint) {
110
+ if (!endpoint.ticket) {
111
+ continue;
112
+ }
113
+ yield* client.doGet(endpoint.ticket);
114
+ }
115
+ }
116
+ /**
117
+ * Gets a single ticket's data as an Arrow Table.
118
+ *
119
+ * @param client - The FlightSqlClient to use
120
+ * @param ticket - The ticket to retrieve
121
+ * @returns An Arrow Table containing the ticket's data
122
+ */
123
+ export async function ticketToTable(client, ticket) {
124
+ const dataStream = client.doGet(ticket);
125
+ const chunks = await collectFlightData(dataStream);
126
+ if (chunks.length === 0) {
127
+ throw new Error("no data returned from ticket");
128
+ }
129
+ const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
130
+ const combined = new Uint8Array(totalLength);
131
+ let offset = 0;
132
+ for (const chunk of chunks) {
133
+ combined.set(chunk, offset);
134
+ offset += chunk.length;
135
+ }
136
+ return tableFromIPC(combined);
137
+ }
138
+ //# sourceMappingURL=results.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results.js","sourceRoot":"","sources":["../src/results.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qualithm/arrow-flight-sql-js",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Arrow Flight SQL client for JavaScript and TypeScript runtimes.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -12,7 +12,7 @@
12
12
  "typescript",
13
13
  "apache-arrow"
14
14
  ],
15
- "license": "MIT",
15
+ "license": "Apache-2.0",
16
16
  "author": "Qualithm",
17
17
  "repository": {
18
18
  "type": "git",
@@ -54,6 +54,7 @@
54
54
  "lint:fix": "eslint --fix .",
55
55
  "lint": "eslint .",
56
56
  "prepublishOnly": "bun run clean && bun run build",
57
+ "proto:generate": "grpc_tools_node_protoc --plugin=protoc-gen-ts_proto=./node_modules/.bin/protoc-gen-ts_proto --proto_path=./proto --ts_proto_out=./src/generated --ts_proto_opt=outputServices=grpc-js,esModuleInterop=true,importSuffix=.js,env=node,useExactTypes=false,snakeToCamel=true,outputPartialMethods=true,enumsAsLiterals=true proto/arrow/flight/protocol/sql/FlightSql.proto",
57
58
  "start": "bun run src/index.ts",
58
59
  "test:coverage": "bun test --coverage",
59
60
  "test:unit": "bun test src/__tests__/unit",
@@ -62,8 +63,16 @@
62
63
  "typecheck": "tsc -p tsconfig.node.json --noEmit"
63
64
  },
64
65
  "dependencies": {},
66
+ "peerDependencies": {
67
+ "@qualithm/arrow-flight-js": ">=1.0.0",
68
+ "apache-arrow": ">=17.0.0"
69
+ },
65
70
  "devDependencies": {
71
+ "@qualithm/arrow-flight-js": "1.5.0",
72
+ "apache-arrow": "19.0.1",
66
73
  "@eslint/js": "10.0.1",
74
+ "grpc-tools": "1.13.1",
75
+ "ts-proto": "2.11.2",
67
76
  "@types/bun": "1.3.9",
68
77
  "eslint": "10.0.0",
69
78
  "eslint-plugin-simple-import-sort": "12.1.1",
package/dist/greet.d.ts DELETED
@@ -1,26 +0,0 @@
1
- /**
2
- * Options for the greet function.
3
- */
4
- export type GreetOptions = {
5
- /** Name to greet. */
6
- name: string;
7
- /** Whether to use formal greeting. */
8
- formal?: boolean;
9
- };
10
- /**
11
- * Generate a greeting message.
12
- *
13
- * @param options - The greeting options.
14
- * @returns A greeting string.
15
- *
16
- * @example
17
- * ```ts
18
- * const message = greet({ name: "World" })
19
- * // => "Hello, World!"
20
- *
21
- * const formal = greet({ name: "World", formal: true })
22
- * // => "Good day, World."
23
- * ```
24
- */
25
- export declare function greet(options: GreetOptions): string;
26
- //# sourceMappingURL=greet.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"greet.d.ts","sourceRoot":"","sources":["../src/greet.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAQnD"}
package/dist/greet.js DELETED
@@ -1,23 +0,0 @@
1
- /**
2
- * Generate a greeting message.
3
- *
4
- * @param options - The greeting options.
5
- * @returns A greeting string.
6
- *
7
- * @example
8
- * ```ts
9
- * const message = greet({ name: "World" })
10
- * // => "Hello, World!"
11
- *
12
- * const formal = greet({ name: "World", formal: true })
13
- * // => "Good day, World."
14
- * ```
15
- */
16
- export function greet(options) {
17
- const { name, formal = false } = options;
18
- if (formal) {
19
- return `Good day, ${name}.`;
20
- }
21
- return `Hello, ${name}!`;
22
- }
23
- //# sourceMappingURL=greet.js.map
package/dist/greet.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"greet.js","sourceRoot":"","sources":["../src/greet.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,KAAK,CAAC,OAAqB;IACzC,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO,CAAA;IAExC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,aAAa,IAAI,GAAG,CAAA;IAC7B,CAAC;IAED,OAAO,UAAU,IAAI,GAAG,CAAA;AAC1B,CAAC"}