diff --git a/src/statement/stream/jsonStream.ts b/src/statement/stream/jsonStream.ts index b57d855a..61167dc9 100644 --- a/src/statement/stream/jsonStream.ts +++ b/src/statement/stream/jsonStream.ts @@ -10,7 +10,15 @@ export class JSONStream { executeQueryOptions: ExecuteQueryOptions; emitter: RowStream; rowParser: RowParser; - state: "meta" | "meta-array" | "rootKeys" | "data" | "data-array" | null; + state: + | "meta" + | "meta-array" + | "rootKeys" + | "data" + | "data-array" + | "query" + | "query-object" + | null; columns: Meta[]; rows: unknown[]; @@ -66,7 +74,11 @@ export class JSONStream { } handleRootKeys(line: string) { - if (line === '"meta":') { + if (line === "query") { + this.state = "query"; + } else if (line === '"query": {') { + this.state = "query-object"; + } else if (line === '"meta":') { this.state = "meta"; } else if (line === '"data":') { this.state = "data"; @@ -128,6 +140,23 @@ export class JSONStream { } } + handleQuery(line: string) { + if (line === "{") { + this.state = "query-object"; + } + } + + handleQueryObject(line: string) { + if (line.match(/^},?$/)) { + const queryStr = this.objBuffer + "}"; + const query = JSONbig.parse(queryStr); + this.objBuffer = undefined; + this.state = "rootKeys"; + } else { + this.objBuffer += line; + } + } + processLine(line: string) { line = line.trim(); @@ -147,6 +176,10 @@ export class JSONStream { this.handleMetaArray(line); } else if (this.state === "data-array") { this.handleDataArray(line); + } else if (this.state === "query") { + this.handleQuery(line); + } else if (this.state === "query-object") { + this.handleQueryObject(line); } } } diff --git a/src/types.ts b/src/types.ts index a052ec0b..a0b7bff5 100644 --- a/src/types.ts +++ b/src/types.ts @@ -24,7 +24,8 @@ export type QueryResponse = { export enum OutputFormat { // JSON_COMPACT_LIMITED = "FB_JSONCompactLimited", - JSON_COMPACT = "JSONCompact", + COMPACT = "JSON_Compact", // supported in v3 of packdb + JSON_COMPACT = "JSONCompact", // to be as above, after ensure all clients has v3 JSON = "JSON" } diff --git a/test/integration/outputFormat.test.ts b/test/integration/outputFormat.test.ts new file mode 100644 index 00000000..fb250703 --- /dev/null +++ b/test/integration/outputFormat.test.ts @@ -0,0 +1,37 @@ +import { Firebolt } from "../../src/index"; +import { OutputFormat } from "../../src/types"; + +const connectionParams = { + username: process.env.FIREBOLT_USERNAME as string, + password: process.env.FIREBOLT_PASSWORD as string, + database: process.env.FIREBOLT_DATABASE as string, + engineName: process.env.FIREBOLT_ENGINE_NAME as string +}; + +jest.setTimeout(50000); + +describe("integration test", () => { + it("works", async () => { + const firebolt = Firebolt({ + apiEndpoint: process.env.FIREBOLT_API_ENDPOINT as string + }); + + const connection = await firebolt.connect(connectionParams); + + const statement = await connection.execute( + "select 1, 'a', 123.4, 9223372036854775806, [1, 2, 4]", + { + settings: { output_format: OutputFormat.COMPACT } + } + ); + const { data, meta } = await statement.fetchResult(); + expect(data.length).toEqual(1); + expect(meta.length).toEqual(5); + const [int_type, text_type, double_type, long_type, array_type] = meta; + expect(int_type.type).toEqual("int"); + expect(text_type.type).toEqual("text"); + expect(double_type.type).toEqual("double"); + expect(long_type.type).toEqual("long"); + expect(array_type.type).toEqual("array(int)"); + }); +});