diff --git a/index.js b/index.js index f1a0051..7bb8d39 100644 --- a/index.js +++ b/index.js @@ -31,9 +31,6 @@ function setTypeParser (oid, format, parseFn) { parseFn = format format = 'text' } - if (!Number.isInteger(oid)) { - throw new TypeError('oid must be an integer: ' + oid) - } typeParsers[format][oid] = parseFn }; diff --git a/lib/binaryParsers.js b/lib/binaryParsers.js index 6ccd36c..8edcc28 100644 --- a/lib/binaryParsers.js +++ b/lib/binaryParsers.js @@ -17,11 +17,27 @@ const parseFloat64 = function (value) { return value.readDoubleBE(0) } -const parseTimestampUTC = function (value) { +const parseDate = function (isUTC, value) { const rawValue = 0x100000000 * value.readInt32BE(0) + value.readUInt32BE(4) // discard usecs and shift from 2000 to 1970 - const result = new Date(Math.round(rawValue / 1000) + 946684800000) + const result = new Date((rawValue / 1000) + 946684800000) + + if (!isUTC) { + result.setTime(result.getTime() + result.getTimezoneOffset() * 60000) + } + + // add microseconds to the date + result.usec = rawValue % 1000 + result.getMicroSeconds = function () { + return this.usec + } + result.setMicroSeconds = function (value) { + this.usec = value + } + result.getUTCMicroSeconds = function () { + return this.usec + } return result } @@ -110,8 +126,8 @@ const init = function (register) { register(700, parseFloat32) register(701, parseFloat64) register(16, parseBool) - register(1114, parseTimestampUTC) - register(1184, parseTimestampUTC) + register(1114, parseDate.bind(null, false)) + register(1184, parseDate.bind(null, true)) register(1000, parseArray) register(1007, parseArray) register(1016, parseArray) diff --git a/lib/textParsers.js b/lib/textParsers.js index 2d8bbf1..d83c642 100644 --- a/lib/textParsers.js +++ b/lib/textParsers.js @@ -1,5 +1,5 @@ const array = require('postgres-array') -const parseTimestampTz = require('postgres-date') +const parseTimestamp = require('postgres-date') const parseInterval = require('postgres-interval') const parseByteA = require('postgres-bytea') const range = require('postgres-range') @@ -40,22 +40,10 @@ const parseStringArray = function (value) { return array.parse(value, undefined) } -const parseTimestamp = function (value) { - const utc = value.endsWith(' BC') - ? value.slice(0, -3) + 'Z BC' - : value + 'Z' - - return parseTimestampTz(utc) -} - const parseTimestampArray = function (value) { return array.parse(value, parseTimestamp) } -const parseTimestampTzArray = function (value) { - return array.parse(value, parseTimestampTz) -} - const parseIntervalArray = function (value) { return array.parse(value, parseInterval) } @@ -131,10 +119,6 @@ function parseTimestampRange (raw) { return range.parse(raw, parseTimestamp) } -function parseTimestampTzRange (raw) { - return range.parse(raw, parseTimestampTz) -} - const init = function (register) { register(20, parseBigInteger) // int8 register(21, Number) // int2 @@ -143,8 +127,9 @@ const init = function (register) { register(700, parseFloat) // float4/real register(701, parseFloat) // float8/double register(16, parseBool) + register(1082, parseTimestamp) // date register(1114, parseTimestamp) // timestamp without time zone - register(1184, parseTimestampTz) // timestamp with time zone + register(1184, parseTimestamp) // timestamp with time zone register(600, parsePoint) // point register(651, parseStringArray) // cidr[] register(718, parseCircle) // circle @@ -165,8 +150,8 @@ const init = function (register) { register(1040, parseStringArray) // macaddr[] register(1041, parseStringArray) // inet[] register(1115, parseTimestampArray) // timestamp without time zone[] - register(1182, parseStringArray) // date[] - register(1185, parseTimestampTzArray) // timestamp with time zone[] + register(1182, parseTimestampArray) // date[] + register(1185, parseTimestampArray) // timestamp with time zone[] register(1186, parseInterval) register(1187, parseIntervalArray) register(17, parseByteA) @@ -178,7 +163,7 @@ const init = function (register) { register(3906, parseNumRange) // numrange register(3907, parseStringArray) // numrange[] register(3908, parseTimestampRange) // tsrange - register(3910, parseTimestampTzRange) // tstzrange + register(3910, parseTimestampRange) // tstzrange register(3912, range.parse) // daterange register(3926, parseInt8Range) // int8range register(2951, parseStringArray) // uuid[] diff --git a/test/index.js b/test/index.js index d6d8863..9cade01 100644 --- a/test/index.js +++ b/test/index.js @@ -1,8 +1,10 @@ const test = require('tape') -const { getTypeParser, setTypeParser } = require('../') +const getTypeParser = require('../').getTypeParser const types = require('./types') +process.env.TZ = 'Asia/Riyadh' + test('types', function (t) { Object.keys(types).forEach(function (typeName) { const type = types[typeName] @@ -64,14 +66,4 @@ test('types', function (t) { t.equal(correct, 300) t.end() }) - - t.test('setTypeParser should throw when oid is not an integer', function (t) { - t.throws(function () { - setTypeParser(null, function () {}) - }, /^TypeError: oid must be an integer/) - t.throws(function () { - setTypeParser('a', function () {}) - }, /^TypeError: oid must be an integer/) - t.end() - }) }) diff --git a/test/types.js b/test/types.js index 143e3d3..ca2dcf1 100644 --- a/test/types.js +++ b/test/types.js @@ -109,10 +109,6 @@ exports.timestamptz = { [ '2010-10-30 13:10:01+05', dateEquals(2010, 9, 30, 8, 10, 1, 0) - ], - [ - '1000-01-01 00:00:00+00 BC', - dateEquals(-999, 0, 1, 0, 0, 0, 0) ] ] } @@ -125,17 +121,8 @@ exports.timestamp = { '2010-10-31 00:00:00', function (t, value) { t.equal( - value.toISOString(), - '2010-10-31T00:00:00.000Z' - ) - } - ], - [ - '1000-01-01 00:00:00 BC', - function (t, value) { - t.equal( - value.toISOString(), - '-000999-01-01T00:00:00.000Z' + value.toUTCString(), + new Date(2010, 9, 31, 0, 0, 0, 0).toUTCString() ) } ] @@ -146,8 +133,15 @@ exports.date = { format: 'text', id: 1082, tests: [ - ['2010-10-31', '2010-10-31'], - ['2010-10-31 BC', '2010-10-31 BC'] + ['2010-10-31', function (t, value) { + const now = new Date(2010, 9, 31) + dateEquals( + 2010, + now.getUTCMonth(), + now.getUTCDate(), + now.getUTCHours(), 0, 0, 0)(t, value) + t.equal(value.getHours(), now.getHours()) + }] ] } @@ -322,16 +316,16 @@ exports.tsrange = { format: 'text', id: 3908, tests: [ - ['(2010-10-31 14:54:13.74,)', tsrangeEquals([[2010, 9, 31, 14, 54, 13, 74], null])], - ['(2010-10-31 14:54:13.74,infinity)', tsrangeEquals([[2010, 9, 31, 14, 54, 13, 74], null])], - ['(,2010-10-31 14:54:13.74)', tsrangeEquals([null, [2010, 9, 31, 14, 54, 13, 74]])], - ['(-infinity,2010-10-31 14:54:13.74)', tsrangeEquals([null, [2010, 9, 31, 14, 54, 13, 74]])], - ['(2010-10-30 10:54:13.74,2010-10-31 14:54:13.74)', tsrangeEquals([[2010, 9, 30, 10, 54, 13, 74], [2010, 9, 31, 14, 54, 13, 74]])], - ['("2010-10-31 14:54:13.74",)', tsrangeEquals([[2010, 9, 31, 14, 54, 13, 74], null])], - ['("2010-10-31 14:54:13.74",infinity)', tsrangeEquals([[2010, 9, 31, 14, 54, 13, 74], null])], - ['(,"2010-10-31 14:54:13.74")', tsrangeEquals([null, [2010, 9, 31, 14, 54, 13, 74]])], - ['(-infinity,"2010-10-31 14:54:13.74")', tsrangeEquals([null, [2010, 9, 31, 14, 54, 13, 74]])], - ['("2010-10-30 10:54:13.74","2010-10-31 14:54:13.74")', tsrangeEquals([[2010, 9, 30, 10, 54, 13, 74], [2010, 9, 31, 14, 54, 13, 74]])] + ['(2010-10-31 14:54:13.74,)', tsrangeEquals([[2010, 9, 31, 11, 54, 13, 74], null])], + ['(2010-10-31 14:54:13.74,infinity)', tsrangeEquals([[2010, 9, 31, 11, 54, 13, 74], null])], + ['(,2010-10-31 14:54:13.74)', tsrangeEquals([null, [2010, 9, 31, 11, 54, 13, 74]])], + ['(-infinity,2010-10-31 14:54:13.74)', tsrangeEquals([null, [2010, 9, 31, 11, 54, 13, 74]])], + ['(2010-10-30 10:54:13.74,2010-10-31 14:54:13.74)', tsrangeEquals([[2010, 9, 30, 7, 54, 13, 74], [2010, 9, 31, 11, 54, 13, 74]])], + ['("2010-10-31 14:54:13.74",)', tsrangeEquals([[2010, 9, 31, 11, 54, 13, 74], null])], + ['("2010-10-31 14:54:13.74",infinity)', tsrangeEquals([[2010, 9, 31, 11, 54, 13, 74], null])], + ['(,"2010-10-31 14:54:13.74")', tsrangeEquals([null, [2010, 9, 31, 11, 54, 13, 74]])], + ['(-infinity,"2010-10-31 14:54:13.74")', tsrangeEquals([null, [2010, 9, 31, 11, 54, 13, 74]])], + ['("2010-10-30 10:54:13.74","2010-10-31 14:54:13.74")', tsrangeEquals([[2010, 9, 30, 7, 54, 13, 74], [2010, 9, 31, 11, 54, 13, 74]])] ] } exports.daterange = { @@ -567,7 +561,16 @@ exports['array/date'] = { id: 1182, tests: [ ['{2014-01-01,2015-12-31}', function (t, value) { - t.deepEqual(value, ['2014-01-01', '2015-12-31']) + const expecteds = [new Date(2014, 0, 1), new Date(2015, 11, 31)] + t.equal(value.length, 2) + value.forEach(function (date, index) { + const expected = expecteds[index] + dateEquals( + expected.getUTCFullYear(), + expected.getUTCMonth(), + expected.getUTCDate(), + expected.getUTCHours(), 0, 0, 0)(t, date) + }) }] ] }