parse date types

This commit is contained in:
Alexandre Bodin 2019-12-04 15:29:17 +01:00
parent 4c784318d8
commit 06b0cc22c8
4 changed files with 57 additions and 53 deletions

View File

@ -283,15 +283,22 @@ module.exports = async ({
// Add created_at and updated_at field if timestamp option is true
if (hasTimestamps) {
definition.attributes[createAtCol] = {
type: 'timestamp',
type: 'currentTimestamp',
};
definition.attributes[updatedAtCol] = {
type: 'timestampUpdate',
};
}
// Save all attributes (with timestamps)
model.allAttributes = _.clone(definition.attributes);
// Save all attributes (with timestamps) and right type
model.allAttributes = _.assign(_.clone(definition.attributes), {
[createAtCol]: {
type: 'timestamp',
},
[updatedAtCol]: {
type: 'timestamp',
},
});
// Equilize tables
if (connection.options && connection.options.autoMigration !== false) {
@ -410,29 +417,34 @@ const getType = ({ definition, attribute, name, tableExists = false }) => {
return client === 'pg' ? 'double precision' : 'double';
case 'decimal':
return 'decimal(10,2)';
// TODO: split time types as they should be different
case 'date':
return 'date';
case 'time':
return 'time';
case 'datetime': {
if (client === 'pg') {
return 'timestamp with time zone';
}
return 'timestamp';
if (client === 'pg') return 'timestampz';
return 'datetime';
}
case 'timestamp': {
if (client === 'pg') {
return 'timestamp with time zone';
return 'timestampz';
}
return 'timestamp';
}
case 'currentTimestamp': {
if (client === 'pg') {
return 'timestamp with time zone DEFAULT CURRENT_TIMESTAMP';
} else if (client === 'sqlite3' && tableExists) {
return 'timestamp DEFAULT NULL';
}
return 'timestamp DEFAULT CURRENT_TIMESTAMP';
}
case 'timestampUpdate':
switch (client) {
case 'pg':
return 'timestamp with time zone';
return 'timestamp with time zone DEFAULT CURRENT_TIMESTAMP';
case 'sqlite3':
if (tableExists) {
return 'timestamp DEFAULT NULL';

View File

@ -1,7 +1,6 @@
'use strict';
const { parseType } = require('strapi-utils');
const { parse, isValid, parseISO } = require('date-fns');
const createParser = () => (type, value) => {
if (value === null) return null;
@ -9,48 +8,9 @@ const createParser = () => (type, value) => {
switch (type) {
case 'json':
return JSON.stringify(value);
case 'time':
return parseType({ type: 'time', value });
case 'date':
return parseDate(value);
case 'timestamp':
case 'datetime':
return parseDateTimeOrTimestamp(value);
default:
return value;
return parseType({ type, value });
}
};
const parseDateOrThrow = format => value => {
try {
let date = parseISO(value);
if (isValid(date)) return date;
date = parse(value, format, new Date());
if (isValid(date)) {
return date;
} else {
throw new Error(`Invalid format, expected a ${format}`);
}
} catch (error) {
throw new Error(`Invalid format, expected a ${format}`);
}
};
const parseDateTimeOrTimestamp = value => {
const date = parseISO(value);
if (isValid(date)) return date;
date.setTime(value);
if (!isValid(date)) {
throw new Error(`Invalid format, expected a timestamp or an ISO date`);
}
return date;
};
const parseDate = parseDateOrThrow('yyyy-MM-dd');
module.exports = { createParser };

View File

@ -203,7 +203,7 @@ module.exports = ({ models, target, plugin = false }, ctx) => {
type: 'timestamp',
};
target[model].allAttributes[updatedAtCol] = {
type: 'timestampUpdate',
type: 'timestamp',
};
} else if (timestampsOption === true) {
schema.set('timestamps', true);
@ -214,7 +214,7 @@ module.exports = ({ models, target, plugin = false }, ctx) => {
type: 'timestamp',
};
target[model].allAttributes.updatedAt = {
type: 'timestampUpdate',
type: 'timestamp',
};
}
schema.set(

View File

@ -1,6 +1,7 @@
'use strict';
const _ = require('lodash');
const dates = require('date-fns');
const timeRegex = new RegExp(
'^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$'
@ -19,6 +20,30 @@ const parseTime = value => {
return `${hours}:${minutes}:${seconds}.${fractionPart}`;
};
const parseDate = value => {
try {
let date = dates.parseISO(value);
if (dates.isValid(date)) return dates.format(date, 'yyyy-MM-dd');
throw new Error(`Invalid format, expected an ISO compatble date`);
} catch (error) {
throw new Error(`Invalid format, expected an ISO compatble date`);
}
};
const parseDateTimeOrTimestamp = value => {
const date = dates.parseISO(value);
if (dates.isValid(date)) return date;
dates.setTime(date, value);
if (!dates.isValid(date)) {
throw new Error(`Invalid format, expected a timestamp or an ISO date`);
}
return date;
};
/**
* Cast basic values based on attribute type
* @param {Object} options - Options
@ -47,6 +72,13 @@ const parseType = ({ type, value }) => {
case 'time': {
return parseTime(value);
}
case 'date': {
return parseDate(value);
}
case 'timestamp':
case 'datetime': {
return parseDateTimeOrTimestamp(value);
}
default:
return value;
}