Skip to content
This repository has been archived by the owner on Jul 14, 2023. It is now read-only.

Commit

Permalink
fix: timestamp conversion issue (#243)
Browse files Browse the repository at this point in the history
* fix: timestamp conversion issue
* enhance timestamp test case
  • Loading branch information
rbhuva authored Dec 8, 2021
1 parent cf77352 commit ed83ae4
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 21 deletions.
12 changes: 6 additions & 6 deletions __tests__/__assets__/beershop-admin-service.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ CREATE TABLE BeershopAdminService_UserScopes (

CREATE TABLE csw_Beers (
ID VARCHAR(36) NOT NULL,
createdAt TIMESTAMP,
createdAt TIMESTAMPTZ,
createdBy VARCHAR(255),
modifiedAt TIMESTAMP,
modifiedAt TIMESTAMPTZ,
modifiedBy VARCHAR(255),
name VARCHAR(100),
abv DECIMAL(3, 1),
Expand All @@ -19,9 +19,9 @@ CREATE TABLE csw_Beers (

CREATE TABLE csw_Brewery (
ID VARCHAR(36) NOT NULL,
createdAt TIMESTAMP,
createdAt TIMESTAMPTZ,
createdBy VARCHAR(255),
modifiedAt TIMESTAMP,
modifiedAt TIMESTAMPTZ,
modifiedBy VARCHAR(255),
name VARCHAR(150),
PRIMARY KEY(ID)
Expand All @@ -36,8 +36,8 @@ CREATE TABLE csw_TypeChecks (
type_Double NUMERIC(30, 15),
type_Date DATE,
type_Time TIME,
type_DateTime TIMESTAMP,
type_Timestamp TIMESTAMP,
type_DateTime TIMESTAMPTZ,
type_Timestamp TIMESTAMPTZ,
type_String VARCHAR(5000),
type_Binary CHAR(100),
type_LargeBinary BYTEA,
Expand Down
20 changes: 10 additions & 10 deletions __tests__/__assets__/test.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
CREATE TABLE csw_Beers (
ID VARCHAR(36) NOT NULL,
createdAt TIMESTAMP,
createdAt TIMESTAMPTZ,
createdBy VARCHAR(255),
modifiedAt TIMESTAMP,
modifiedAt TIMESTAMPTZ,
modifiedBy VARCHAR(255),
name VARCHAR(100),
abv DECIMAL(3, 1),
Expand All @@ -13,9 +13,9 @@ CREATE TABLE csw_Beers (

CREATE TABLE csw_Brewery (
ID VARCHAR(36) NOT NULL,
createdAt TIMESTAMP,
createdAt TIMESTAMPTZ,
createdBy VARCHAR(255),
modifiedAt TIMESTAMP,
modifiedAt TIMESTAMPTZ,
modifiedBy VARCHAR(255),
name VARCHAR(150),
PRIMARY KEY(ID)
Expand All @@ -30,8 +30,8 @@ CREATE TABLE csw_TypeChecks (
type_Double NUMERIC(30, 15),
type_Date DATE,
type_Time TIME,
type_DateTime TIMESTAMP,
type_Timestamp TIMESTAMP,
type_DateTime TIMESTAMPTZ,
type_Timestamp TIMESTAMPTZ,
type_String VARCHAR(5000),
type_Binary CHAR(100),
type_LargeBinary BYTEA,
Expand All @@ -41,10 +41,10 @@ CREATE TABLE csw_TypeChecks (

CREATE TABLE DRAFT_DraftAdministrativeData (
DraftUUID VARCHAR(36) NOT NULL,
CreationDateTime TIMESTAMP,
CreationDateTime TIMESTAMPTZ,
CreatedByUser VARCHAR(256),
DraftIsCreatedByMe BOOLEAN,
LastChangeDateTime TIMESTAMP,
LastChangeDateTime TIMESTAMPTZ,
LastChangedByUser VARCHAR(256),
InProcessByUser VARCHAR(256),
DraftIsProcessedByMe BOOLEAN,
Expand All @@ -60,8 +60,8 @@ CREATE TABLE BeershopService_TypeChecksWithDraft_drafts (
type_Double NUMERIC(30, 15) NULL,
type_Date DATE NULL,
type_Time TIME NULL,
type_DateTime TIMESTAMP NULL,
type_Timestamp TIMESTAMP NULL,
type_DateTime TIMESTAMPTZ NULL,
type_Timestamp TIMESTAMPTZ NULL,
type_String VARCHAR(5000) NULL,
type_Binary CHAR(100) NULL,
type_LargeBinary BYTEA NULL,
Expand Down
5 changes: 4 additions & 1 deletion __tests__/lib/pg/service-types.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,13 @@ describe.each(suiteEnvironments)(
})

test(' -> Timestamp', async () => {
const value = '2012-12-03T07:16:23.574Z';
const response = await request.post('/beershop/TypeChecks').send({
type_Timestamp: '2012-12-03T07:16:23.574Z',
type_Timestamp: value,
})
expect(response.status).toStrictEqual(201)
const verify = await request.get(`/beershop/TypeChecks(${response.body.ID})`).send()
expect(verify.body.type_Timestamp).toStrictEqual(value);
})

test(' -> String', async () => {
Expand Down
65 changes: 65 additions & 0 deletions __tests__/lib/pg/timestamp.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const cds = require('@sap/cds')
const deploy = require('@sap/cds/lib/deploy')

// mock (package|.cdsrc).json entries
cds.env.requires.db = { kind: 'postgres' }
cds.env.requires.postgres = {
dialect: 'plain',
impl: './cds-pg', // hint: not really sure as to why this is, but...
}

// default (single) test environment is local,
// so running against a dockerized postgres with a local cap bootstrap service.
// when there's a .env in /__tests__/__assets__/cap-proj/
// with a scpServiceURL (see .env.example in that dir)
// tests are also run against a deployed service url (cf hyperscaler postgres)
const { suiteEnvironments, app } = require('./_buildSuiteEnvironments')

describe.each(suiteEnvironments)(
'[%s] OData to Postgres dialect',
(_suitename /* translates to %s via printf */, credentials, model, request) => {
beforeAll(async () => {
this._model = model
this._dbProperties = {
kind: 'postgres',
model: this._model,
credentials: credentials,
}

// only bootstrap in local mode as scp app is deployed and running
if (_suitename.startsWith('local')) {
await require('./_runLocal')(model, credentials, app, false) // don't deploy content initially
}
})

beforeEach(async () => {
// "reset" aka re-deploy static content
if (_suitename.startsWith('local')) {
await deploy(this._model, {}).to(this._dbProperties)
} else if (_suitename === 'scp') {
await request.post(`/beershop/reset`).send({}).set('content-type', 'application/json')
}
})

describe('Timestamp TEST', () => {

test(' -> Check modifiedAt', async () => {
//Set Different TimeZone
await cds.run(`alter user postgres set timezone = 'EST'`, [])//UTC,EST
const beforeTimestamp = new Date()
beforeTimestamp.setMilliseconds(0);
await request.put('/beershop/Beers/9e1704e3-6fd0-4a5d-bfb1-13ac47f7976b')
.send({
name: 'Changed name',
ibu: 10,
})
.set('content-type', 'application/json;charset=UTF-8;IEEE754Compatible=true')
await cds.run(`alter user postgres set timezone = 'UTC'`, [])
const response = await request.get('/beershop/Beers/9e1704e3-6fd0-4a5d-bfb1-13ac47f7976b')
const afterTimestamp = new Date()
const modifiedAt = new Date(response.body.modifiedAt)
expect((beforeTimestamp <= modifiedAt) && (modifiedAt <= afterTimestamp)).toBe(true)
})
})
}
)
4 changes: 2 additions & 2 deletions lib/pg/Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ module.exports = class PostgresDatabase extends cds.DatabaseService {
* BINARY_BLOB -> CHAR
* BLOB -> BYTEA
* NCLOB -> TEXT
* TIMESTAMP_TEXT -> TIMESTAMP
* TIMESTAMP_TEXT -> TIMESTAMPTZ
* TIME_TEXT -> TIME
* DATE_TEXT -> DATE
*
Expand All @@ -74,7 +74,7 @@ module.exports = class PostgresDatabase extends cds.DatabaseService {
pgsql = pgsql.replace(/BINARY_BLOB/g, 'CHAR')
pgsql = pgsql.replace(/BLOB/g, 'BYTEA')
pgsql = pgsql.replace(/NCLOB/g, 'TEXT')
pgsql = pgsql.replace(/TIMESTAMP_TEXT/g, 'TIMESTAMP')
pgsql = pgsql.replace(/TIMESTAMP_TEXT/g, 'TIMESTAMPTZ')
pgsql = pgsql.replace(/TIME_TEXT/g, 'TIME')
pgsql = pgsql.replace(/DATE_TEXT/g, 'DATE')
return pgsql
Expand Down
4 changes: 2 additions & 2 deletions lib/pg/converters/conversion.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ const convertInt64ToString = (int64) => {

const convertToISO = (element) => {
if (element) {
return new Date(element + 'Z').toISOString()
return element.toISOString ? element.toISOString() : new Date(element + 'Z').toISOString()
}

return null
}

const convertToISONoMillis = (element) => {
if (element) {
const dateTime = new Date(element + 'Z').toISOString()
const dateTime = element.toISOString ? element.toISOString() : new Date(element + 'Z').toISOString()
return dateTime.slice(0, 19) + dateTime.slice(23)
}

Expand Down

0 comments on commit ed83ae4

Please sign in to comment.