From e6e7cf0f69ca8f3b78bdf8d214b45c5665159f89 Mon Sep 17 00:00:00 2001 From: Aditya Toshniwal Date: Wed, 27 Feb 2019 13:39:47 +0000 Subject: [PATCH] Fix support for bigint's in JSONB data. Fixes #3587 --- docs/en_US/release_notes_4_3.rst | 1 + web/package.json | 5 ++-- web/pgadmin/static/js/slickgrid/editors.js | 23 +++++++++++-------- web/pgadmin/utils/driver/psycopg2/typecast.py | 1 + web/webpack.shim.js | 1 + web/yarn.lock | 12 ++++++++++ 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/docs/en_US/release_notes_4_3.rst b/docs/en_US/release_notes_4_3.rst index ed0973330..fff7490d9 100644 --- a/docs/en_US/release_notes_4_3.rst +++ b/docs/en_US/release_notes_4_3.rst @@ -25,6 +25,7 @@ Bug fixes | `Bug #3352 `_ - Handle display of roles with expiration set to infinity correctly. | `Bug #3418 `_ - Allow editing of values in columns with the oid datatype which are not an actual row OID. | `Bug #3544 `_ - Make the Query Tool tab titles more concise and useful. +| `Bug #3587 `_ - Fix support for bigint's in JSONB data. | `Bug #3583 `_ - Update CodeMirror to 5.43.0 to resolve issues with auto-indent. | `Bug #3600 `_ - Ensure JSON data isn't modified in-flight by psycopg2 when using View/Edit data. | `Bug #3673 `_ - Modify the Download as CSV option to use the same connection as the Query Tool its running in so temporary tables etc. can be used. diff --git a/web/package.json b/web/package.json index 9a1a14202..f43dd12b9 100644 --- a/web/package.json +++ b/web/package.json @@ -59,6 +59,7 @@ "bignumber.js": "^6.0.0", "bootstrap": "^4.1.3", "bootstrap-datepicker": "^1.7.0", + "bootstrap4-toggle": "3.4.0", "bowser": "1.6.1", "browserify": "~14.1.0", "codemirror": "^5.43.0", @@ -75,6 +76,7 @@ "jquery": "3.3.1", "jquery-contextmenu": "^2.6.4", "jquery-ui": "^1.12.1", + "json-bignumber": "^1.0.1", "leaflet": "^1.3.3", "moment": "^2.20.1", "moment-timezone": "^0.5.21", @@ -97,8 +99,7 @@ "underscore.string": "^3.3.4", "watchify": "~3.9.0", "webcabin-docker": "git+https://github.com/EnterpriseDB/wcDocker/#9cf81f03bb350b76b77a264f1db5d55391d5e424", - "wkx": "^0.4.5", - "bootstrap4-toggle": "3.4.0" + "wkx": "^0.4.5" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgadmin/static/js/slickgrid/editors.js b/web/pgadmin/static/js/slickgrid/editors.js index 0fae86ca3..731d122e5 100644 --- a/web/pgadmin/static/js/slickgrid/editors.js +++ b/web/pgadmin/static/js/slickgrid/editors.js @@ -13,7 +13,9 @@ * @namespace Slick */ -(function($) { +import JSONBigNumber from 'json-bignumber'; + +(function($, JSONBigNumber) { // register namespace $.extend(true, window, { 'Slick': { @@ -108,7 +110,7 @@ } } else { if(column_type === 'jsonb') { - item[args.column.field] = JSON.parse(state); + item[args.column.field] = JSONBigNumber.stringify(JSONBigNumber.parse(state)); } else { item[args.column.field] = state; } @@ -369,13 +371,13 @@ this.loadValue = function(item) { var data = defaultValue = item[args.column.field]; /* If jsonb or array */ - if (data && typeof data === 'object' && !Array.isArray(data)) { - data = JSON.stringify(data, null, 4); + if(args.column.column_type_internal === 'jsonb' && !Array.isArray(data)) { + data = JSONBigNumber.stringify(JSONBigNumber.parse(data), null, 4); } else if (Array.isArray(data)) { var temp = []; $.each(data, function(i, val) { if (typeof val === 'object') { - temp.push(JSON.stringify(val, null, 4)); + temp.push(JSONBigNumber.stringify(val, null, 4)); } else { temp.push(val); } @@ -411,7 +413,8 @@ }; this.validate = function() { - if(args.column.column_type_internal === 'jsonb') { + if(args.column.column_type_internal === 'jsonb' || + args.column.column_type_internal === 'json') { try { JSON.parse($input.val()); } catch(e) { @@ -597,13 +600,13 @@ this.loadValue = function(item) { var data = defaultValue = item[args.column.field]; - if (typeof data === 'object' && !Array.isArray(data)) { - data = JSON.stringify(data, null, 4); + if(args.column.column_type_internal === 'jsonb' && !Array.isArray(data)) { + data = JSONBigNumber.stringify(JSONBigNumber.parse(data), null, 4); } else if (Array.isArray(data)) { var temp = []; $.each(data, function(i, val) { if (typeof val === 'object') { - temp.push(JSON.stringify(val, null, 4)); + temp.push(JSONBigNumber.stringify(val, null, 4)); } else { temp.push(val); } @@ -988,4 +991,4 @@ this.init(); } -})(window.jQuery); +})(window.jQuery, JSONBigNumber); diff --git a/web/pgadmin/utils/driver/psycopg2/typecast.py b/web/pgadmin/utils/driver/psycopg2/typecast.py index 1f462f08e..fe0edccd1 100644 --- a/web/pgadmin/utils/driver/psycopg2/typecast.py +++ b/web/pgadmin/utils/driver/psycopg2/typecast.py @@ -170,6 +170,7 @@ def register_global_typecasters(): # Treat JSON data as text because converting it to dict alters the data # which should not happen as per postgres docs psycopg2.extras.register_default_json(loads=lambda x: x) + psycopg2.extras.register_default_jsonb(loads=lambda x: x) # pysycopg2 adapt does not support dict by default. Need to register # Used http://initd.org/psycopg/docs/extras.html#json-adaptation diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 2244072fd..2a59c23d4 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -156,6 +156,7 @@ var webpackShimConfig = { 'jquery.contextmenu': path.join(__dirname, './node_modules/jquery-contextmenu/dist/jquery.contextMenu'), 'dropzone': path.join(__dirname, './node_modules/dropzone/dist/dropzone'), 'bignumber': path.join(__dirname, './node_modules/bignumber.js/bignumber'), + 'json-bignumber': path.join(__dirname, './node_modules/json-bignumber/dist/JSONBigNumber.min'), 'snap.svg': path.join(__dirname, './node_modules/snapsvg/dist/snap.svg'), 'spectrum': path.join(__dirname, './node_modules/spectrum-colorpicker/spectrum'), 'mousetrap': path.join(__dirname, './node_modules/mousetrap'), diff --git a/web/yarn.lock b/web/yarn.lock index b4ae18dc2..5a86322d5 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -1459,6 +1459,11 @@ bignumber.js@^6.0.0: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-6.0.0.tgz#bbfa047644609a5af093e9cbd83b0461fa3f6002" integrity sha512-x247jIuy60/+FtMRvscqfxtVHQf8AGx2hm9c6btkgC0x/hp9yt+teISNhvF8WlwRkCc5yF2fDECH8SIMe8j+GA== +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + bin-build@^2.0.0, bin-build@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-2.2.0.tgz#11f8dd61f70ffcfa2bdcaa5b46f5e8fedd4221cc" @@ -6179,6 +6184,13 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= +json-bignumber@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-bignumber/-/json-bignumber-1.0.1.tgz#2668e985346793c4b7a0c4b083450195fe7f20f8" + integrity sha512-3ocoLAUJNsPRmgVJmUGkN6TP5VLxO48mgIaz2xAOS9RppP1S3YSJE0jnpW+uk63CONqJaq0dKlS72wEhmG3XdA== + dependencies: + bignumber.js "^7.2.1" + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"