CartoDB-SQL-API/lib/models/formats/pg/json.js

174 lines
4.6 KiB
JavaScript
Raw Normal View History

2018-10-24 21:42:33 +08:00
'use strict';
2015-05-13 19:00:01 +08:00
var _ = require('underscore');
2019-12-24 01:19:08 +08:00
var Pg = require('./../pg');
const errorHandlerFactory = require('../../../services/error-handler-factory');
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
function JsonFormat () {
this.buffer = '';
this.lastKnownResult = {};
}
2013-05-16 17:24:52 +08:00
2019-01-16 22:58:11 +08:00
JsonFormat.prototype = new Pg('json');
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
JsonFormat.prototype._contentType = 'application/json; charset=utf-8';
2013-05-16 17:24:52 +08:00
2019-12-24 01:19:08 +08:00
JsonFormat.prototype.formatResultFields = function (flds) {
flds = flds || [];
var nfields = {};
for (var i = 0; i < flds.length; ++i) {
var f = flds[i];
var cname = this.client.typeName(f.dataTypeID);
var tname;
if (!cname) {
tname = 'unknown(' + f.dataTypeID + ')';
} else {
if (cname.match('bool')) {
tname = 'boolean';
} else if (cname.match(/int|float|numeric/)) {
tname = 'number';
} else if (cname.match(/text|char|unknown/)) {
tname = 'string';
} else if (cname.match(/date|time/)) {
tname = 'date';
} else {
tname = cname;
}
if (tname && cname.match(/^_/)) {
tname += '[]';
}
}
2019-12-24 01:19:08 +08:00
if (['geography', 'geometry', 'raster'].includes(cname)) {
const { wkbtype, ndims, srid } = this.client.typeModInfo(f.dataTypeModifier);
nfields[f.name] = { type: tname, wkbtype, dims: ndims, srid };
} else {
nfields[f.name] = { type: tname, pgtype: cname };
}
}
2019-12-24 01:19:08 +08:00
return nfields;
};
2019-12-24 01:19:08 +08:00
JsonFormat.prototype.startStreaming = function () {
this.total_rows = 0;
if (this.opts.beforeSink) {
this.opts.beforeSink();
}
if (this.opts.callback) {
this.buffer += this.opts.callback + '(';
}
this.buffer += '{"rows":[';
this._streamingStarted = true;
};
2019-12-24 01:19:08 +08:00
JsonFormat.prototype.handleQueryRow = function (row, result) {
if (!this._streamingStarted) {
this.startStreaming();
}
this.lastKnownResult = result;
this.buffer += (this.total_rows++ ? ',' : '') + JSON.stringify(row, function (key, value) {
2019-12-27 01:01:38 +08:00
if (value !== value) { // eslint-disable-line no-self-compare
return 'NaN';
}
if (value === Infinity) {
return 'Infinity';
}
if (value === -Infinity) {
return '-Infinity';
}
return value;
});
2014-12-02 19:32:54 +08:00
if (this.total_rows % (this.opts.bufferedRows || 1000)) {
this.opts.sink.write(this.buffer);
this.buffer = '';
}
};
2019-12-24 01:19:08 +08:00
JsonFormat.prototype.handleQueryEnd = function (result) {
if (this.error && !this._streamingStarted) {
this.callback(this.error);
return;
}
2019-12-24 01:19:08 +08:00
if (this.opts.profiler) {
2015-05-13 19:00:01 +08:00
this.opts.profiler.done('gotRows');
}
2019-12-24 01:19:08 +08:00
if (!this._streamingStarted) {
this.startStreaming();
}
2019-12-24 01:19:08 +08:00
this.opts.total_time = (Date.now() - this.start_time) / 1000;
result = result || this.lastKnownResult || {};
// Drop field description for skipped fields
if (this.hasSkipFields) {
var newfields = [];
var sf = this.opts.skipfields;
for (var i = 0; i < result.fields.length; i++) {
var f = result.fields[i];
2019-12-24 01:19:08 +08:00
if (sf.indexOf(f.name) === -1) {
2015-05-13 19:00:01 +08:00
newfields.push(f);
}
}
result.fields = newfields;
}
2019-12-27 01:01:38 +08:00
var totalTime = (Date.now() - this.start_time) / 1000;
var out = [
'],', // end of "rows" array
2019-12-27 01:01:38 +08:00
'"time":', JSON.stringify(totalTime),
',"fields":', JSON.stringify(this.formatResultFields(result.fields)),
',"total_rows":', JSON.stringify(result.rowCount || this.total_rows)
];
if (this.error) {
out.push(',"error":', JSON.stringify(errorHandlerFactory(this.error).getResponse().error));
}
2019-12-24 01:19:08 +08:00
if (result.notices && result.notices.length > 0) {
var notices = {};
var severities = [];
_.each(result.notices, function (notice) {
var severity = notice.severity.toLowerCase() + 's';
if (!notices[severity]) {
severities.push(severity);
notices[severity] = [];
}
2015-05-13 19:00:01 +08:00
notices[severity].push(notice.message);
});
2019-12-24 01:19:08 +08:00
_.each(severities, function (severity) {
out.push(',');
out.push(JSON.stringify(severity));
out.push(':');
out.push(JSON.stringify(notices[severity]));
});
}
out.push('}');
this.buffer += out.join('');
if (this.opts.callback) {
this.buffer += ')';
}
this.opts.sink.write(this.buffer);
this.opts.sink.end();
this.buffer = '';
this.callback();
2013-05-16 17:24:52 +08:00
};
module.exports = JsonFormat;