Skip to content

Commit eafb0fd

Browse files
author
Laszlo Radics
committed
fix: jsonb[] column parsing
1 parent eb16ea4 commit eafb0fd

9 files changed

+46
-11
lines changed

lib/pgConverters.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ export declare let arraySplitToNum: (val: any) => any;
44
export declare let arraySplitToNumWithValidation: (val: any) => any;
55
export declare let stringArrayToNumWithValidation: (val: any) => any;
66
export declare let arraySplitToDate: (val: any) => any;
7+
export declare let arraySplitToJson: (str: any) => any[];

lib/pgConverters.js

+7-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/pgConverters.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/pgDb.js

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/pgDb.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

spec/resources/init.sql

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS "users" (
3636
"aCategory" varchar,
3737

3838
"textList" text[],
39+
"jsonbList" jsonb[],
3940
"numberList" integer[], -- int4
4041
"bigNumberList" bigInt[], -- int8
4142
"timestamptzList" timestamptz[],

src/pgConverters.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import * as moment from 'moment';
44
export let arraySplit = (str) => {
55
if (str == "{}") return [];
66
str = str.substring(1, str.length - 1); //cut off {}
7-
let e = /(?:"((?:[^"]|\\")*)"|([^,"]*))(?:,|$)/g; //has to be mutable because of exec
7+
let e = /(?:("(?:[^"\\]|\\.)*")|([^,"]*))(?:,|$)/g; //has to be mutable because of exec
88
let valList = [];
99
let parsingResult;
1010
do {
1111
parsingResult = e.exec(str);
1212
let valStr = (parsingResult[2] == 'NULL') ? null :
13-
(parsingResult[1] == null ? parsingResult[2] : parsingResult[1].replace(/\\\\/g, '\\')).replace(/\\"/g,'"');
13+
(parsingResult[1] == null ? parsingResult[2] : JSON.parse(parsingResult[1])); // for string parsing, escape \
1414
valList.push(valStr);
15-
} while (parsingResult[0].substring(parsingResult[0].length - 1, parsingResult[0].length) == ',');
15+
} while (e.lastIndex < str.length);
1616
return valList;
1717
};
1818
export let numWithValidation = val => {
@@ -26,4 +26,7 @@ export let arraySplitToNum = val => val == "{}" ? [] : val.substring(1, val.leng
2626
export let arraySplitToNumWithValidation = val => val == "{}" ? [] : val.substring(1, val.length - 1).split(',').map(numWithValidation);
2727
export let stringArrayToNumWithValidation = val => val.map(numWithValidation);
2828
export let arraySplitToDate = val => val == "{}" ? [] : val.substring(1, val.length - 1).split(',').map(d => moment(d.substring(1, d.length - 1)).toDate());
29-
29+
export let arraySplitToJson = (str) => {
30+
let vals = arraySplit(str);
31+
return vals.map(s=> typeof s === 'string' ? JSON.parse(s) : s);
32+
};

src/pgDb.ts

+8
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ export class PgDb extends QueryAble {
298298
}
299299

300300
for (let r of specialTypeFields.rows) {
301+
// https://doxygen.postgresql.org/include_2catalog_2pg__type_8h_source.html
301302
switch (r.typid) {
302303
case 114: // json
303304
case 3802: // jsonb
@@ -313,6 +314,13 @@ export class PgDb extends QueryAble {
313314
case 1021: // real[] float4[]
314315
pg.types.setTypeParser(r.typid, PgConverters.arraySplitToNum);
315316
break;
317+
case 1009: // text[]
318+
case 1015: // varchar[]
319+
pg.types.setTypeParser(r.typid, PgConverters.arraySplit);
320+
break;
321+
case 3807:
322+
pg.types.setTypeParser(r.typid, PgConverters.arraySplitToJson);
323+
break;
316324
case 1016: // bigInt[] int8[]
317325
case 1022: // double[] float8[]
318326
//pg.types.setTypeParser(r.typid, arraySplitToNumWithValidation);

src/test/pgDbSpec.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/// <reference types="jasmine"/>
22
import {PgDb} from "../pgDb";
33
import {PgTable} from "../pgTable";
4+
import * as _ from 'lodash';
45

56
const util = require('util');
67

@@ -763,14 +764,24 @@ describe("pgdb", () => {
763764
}));
764765

765766
it("Testing text array parsing", w(async () => {
766-
let list = ["'A'", '"A"', '//', '\\', '""', "''", '--', '/*', '<!--'];
767+
let list = ["'A'", '"A"', 'normal','//', '\\', '""', "''", '--', '/*', '','<!--', JSON.stringify({a:1,b:"aprocska\"kalapocska'bennecsacskamacskamocska"})];
767768
await table.insert({name: 'A', textList: list});
768769
let rec: any = await table.findOne({name: 'A'});
769-
// console.log(list + '\n' + rec.textList);
770+
console.log(list + '\n' + rec.textList);
770771
let isDifferent = list.some((v, i) => rec.textList[i] !== v);
771772
expect(isDifferent).toBeFalsy();
772773
}));
773774

775+
it("Testing jsonb array parsing", w(async () => {
776+
let list = [{"id":"fl1ace84f744","name":"Wire 2017-09-17 at 11.57.55.png","type":"image/png","path":"/data/files/fl1ace84f744/Wire 2017-09-17 at 11.57.55.png","title":"Wire 2017-09-17 at 11.57.55"}];
777+
await table.insert({name: 'A', jsonbList: list});
778+
let rec: any = await table.findOne({name: 'A'});
779+
console.log('xxx',rec.jsonbList, typeof rec.jsonbList[0]);
780+
console.log(JSON.stringify(list) + '\n' + JSON.stringify(rec.jsonbList));
781+
let isDifferent = list.some((v, i) => !_.isEqual(rec.jsonbList[i] , v));
782+
expect(isDifferent).toBeFalsy();
783+
}));
784+
774785
it("Testing distinct", w(async () => {
775786
await table.insert({name: 'A', aCategory: 'A'});
776787
await table.insert({name: 'B', aCategory: 'A'});

0 commit comments

Comments
 (0)