diff --git a/lib/cartodb/api/middlewares/layergroup-metadata.js b/lib/cartodb/api/middlewares/layergroup-metadata.js index 301089df..bbb1fbe4 100644 --- a/lib/cartodb/api/middlewares/layergroup-metadata.js +++ b/lib/cartodb/api/middlewares/layergroup-metadata.js @@ -7,6 +7,7 @@ module.exports = function setMetadataToLayergroup (layergroupMetadata, includeQu layergroupMetadata.addAnalysesMetadata(user, layergroup, analysesResults, includeQuery); layergroupMetadata.addTurboCartoContextMetadata(layergroup, mapConfig.obj(), context); layergroupMetadata.addAggregationContextMetadata(layergroup, mapConfig.obj(), context); + layergroupMetadata.addDateWrappingMetadata (layergroup, mapConfig.obj()); layergroupMetadata.addTileJsonMetadata(layergroup, user, mapConfig); next(); diff --git a/lib/cartodb/utils/date-wrapper.js b/lib/cartodb/utils/date-wrapper.js index dfbf52dd..3c0907f1 100644 --- a/lib/cartodb/utils/date-wrapper.js +++ b/lib/cartodb/utils/date-wrapper.js @@ -8,19 +8,19 @@ const DATE_OIDS = Object.freeze({ /** * Wrap a query transforming all date columns into a unix epoch - * @param {*} originalQuery - * @param {*} fields + * @param {*} originalQuery + * @param {*} fields */ function wrapDates(originalQuery, fields) { return ` - SELECT - ${fields.map(field => _isDateType(field) ? _castColumnToEpoch(field.name) : `${field.name}`).join(',')} - FROM + SELECT + ${fields.map(field => _isDateType(field) ? _castColumnToEpoch(field.name) : `${field.name}`).join(',')} + FROM (${originalQuery}) _cdb_epoch_transformation `; } /** - * @param {object} field + * @param {object} field */ function _isDateType(field) { return DATE_OIDS.hasOwnProperty(field.dataTypeID); @@ -31,9 +31,25 @@ function _isDateType(field) { * @param {string} column - The name of the date column */ function _castColumnToEpoch(columnName) { - return `date_part('epoch', ${columnName}) as "${columnName}"`; + return `date_part('epoch', "${columnName}") as "${columnName}"`; +} + +function wrappedDates(query) { + if (query.match(/\b_cdb_epoch_transformation\b/)) { + const columns = []; + const fieldMatcher = /\bdate_part\('epoch', "([^"]+)"\) as "([^"]+)"/gmi; + let match; + do { + match = fieldMatcher.exec(query); + if (match && match[1] === match[2]) { + columns.push(match[1]); + } + } while (match); + return columns; + } } module.exports = { - wrapDates + wrapDates, + wrappedDates }; \ No newline at end of file diff --git a/lib/cartodb/utils/layergroup-metadata.js b/lib/cartodb/utils/layergroup-metadata.js index 0e5d702a..62a3cd73 100644 --- a/lib/cartodb/utils/layergroup-metadata.js +++ b/lib/cartodb/utils/layergroup-metadata.js @@ -1,3 +1,5 @@ +const dateWrapper = require('./date-wrapper'); + module.exports = class LayergroupMetadata { constructor (resourceLocator) { this.resourceLocator = resourceLocator; @@ -165,4 +167,18 @@ module.exports = class LayergroupMetadata { }); } } + + addDateWrappingMetadata (layergroup, mapConfig) { + if (layergroup.metadata && Array.isArray(layergroup.metadata.layers) && Array.isArray(mapConfig.layers)) { + layergroup.metadata.layers = layergroup.metadata.layers.map(function(layer, layerIndex) { + const mapConfigLayer = mapConfig.layers[layerIndex]; + const wrappedColumns = dateWrapper.wrappedDates(mapConfigLayer.options.sql); + if (wrappedColumns) { + layer.meta.dates_as_numbers = wrappedColumns; + } + return layer; + }); + } + } + };