Extract base class in order to share createAffectedTables and getAffectedTables methods

This commit is contained in:
Daniel García Aubert
2018-05-31 14:57:34 +02:00
parent c32dba1ecb
commit ea95050d43
4 changed files with 87 additions and 221 deletions
@@ -0,0 +1,65 @@
const QueryTables = require('cartodb-query-tables');
module.exports = class BaseMapConfigProvider {
createAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
const queries = [];
this.mapConfig.getLayers().forEach(layer => {
queries.push(layer.options.sql);
if (layer.options.affected_tables) {
layer.options.affected_tables.map(table => {
queries.push(`SELECT * FROM ${table} LIMIT 0`);
});
}
});
const sql = queries.length ? queries.join(';') : null;
if (!sql) {
return callback();
}
this.pgConnection.getConnection(this.user, (err, connection) => {
if (err) {
return callback(err);
}
QueryTables.getAffectedTablesFromQuery(connection, sql, (err, affectedTables) => {
if (err) {
return callback(err);
}
this.affectedTablesCache.set(dbname, token, affectedTables);
callback(null, affectedTables);
});
});
});
}
getAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
if (this.affectedTablesCache.hasAffectedTables(dbname, token)) {
const affectedTables = this.affectedTablesCache.get(dbname, token);
return callback(null, affectedTables);
}
return this.createAffectedTables(callback);
});
}
};
@@ -1,24 +1,9 @@
const MapStoreMapConfigProvider = require('./map-store-provider');
const QueryTables = require('cartodb-query-tables');
module.exports = class CreateLayergroupMapConfigProvider extends MapStoreMapConfigProvider {
/**
* @param {MapConfig} mapConfig
* @param {String} user
* @param {UserLimitsBackend} userLimitsBackend
* @param {Object} params
* @constructor
* @type {CreateLayergroupMapConfigProvider}
*/
constructor (mapConfig, user, userLimitsBackend, pgConnection, affectedTablesCache, params) {
super(mapConfig, user, userLimitsBackend, pgConnection, affectedTablesCache, params);
super(null, user, userLimitsBackend, pgConnection, affectedTablesCache, params);
this.mapConfig = mapConfig;
this.user = user;
this.userLimitsBackend = userLimitsBackend;
this.pgConnection = pgConnection;
this.affectedTablesCache = affectedTablesCache;
this.params = params;
this.cacheBuster = params.cache_buster || 0;
}
getMapConfig (callback) {
@@ -39,66 +24,4 @@ module.exports = class CreateLayergroupMapConfigProvider extends MapStoreMapConf
return callback(null, this.mapConfig, this.params, context);
});
}
createAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
const queries = [];
this.mapConfig.getLayers().forEach(layer => {
queries.push(layer.options.sql);
if (layer.options.affected_tables) {
layer.options.affected_tables.map(table => {
queries.push(`SELECT * FROM ${table} LIMIT 0`);
});
}
});
const sql = queries.length ? queries.join(';') : null;
if (!sql) {
return callback();
}
this.pgConnection.getConnection(this.user, (err, connection) => {
if (err) {
return callback(err);
}
QueryTables.getAffectedTablesFromQuery(connection, sql, (err, affectedTables) => {
if (err) {
return callback(err);
}
this.affectedTablesCache.set(dbname, token, affectedTables);
callback(null, affectedTables);
});
});
});
}
getAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
if (this.affectedTablesCache.hasAffectedTables(dbname, token)) {
const affectedTables = this.affectedTablesCache.get(dbname, token);
return callback(null, affectedTables);
}
return this.createAffectedTables(callback);
});
}
};
@@ -1,5 +1,5 @@
const BaseMapConfigProvider = require('./base-mapconfig-adapter');
const dot = require('dot');
const QueryTables = require('cartodb-query-tables');
// Configure bases for cache keys suitable for string interpolation
const baseKey = '{{=it.dbname}}:{{=it.token}}';
@@ -8,7 +8,7 @@ const rendererKey = baseKey + ':{{=it.dbuser}}:{{=it.format}}:{{=it.layer}}:{{=i
const baseKeyTpl = dot.template(baseKey);
const rendererKeyTpl = dot.template(rendererKey);
module.exports = class MapStoreMapConfigProvider {
module.exports = class MapStoreMapConfigProvider extends BaseMapConfigProvider {
/**
* @param {MapStore} mapStore
* @param {String} user
@@ -18,15 +18,16 @@ module.exports = class MapStoreMapConfigProvider {
* @type {MapStoreMapConfigProvider}
*/
constructor (mapStore, user, userLimitsBackend, pgConnection, affectedTablesCache, params) {
super();
this.mapStore = mapStore;
this.user = user;
this.userLimitsBackend = userLimitsBackend;
this.pgConnection = pgConnection;
this.affectedTablesCache = affectedTablesCache;
this.params = params;
this.token = params.token;
this.cacheBuster = params.cache_buster || 0;
this.mapConfig = null;
this.params = params;
this.context = null;
}
@@ -82,66 +83,4 @@ module.exports = class MapStoreMapConfigProvider {
return (base) ? baseKeyTpl(tplValues) : rendererKeyTpl(tplValues);
}
createAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
const queries = [];
mapConfig.getLayers().forEach(layer => {
queries.push(layer.options.sql);
if (layer.options.affected_tables) {
layer.options.affected_tables.map(table => {
queries.push(`SELECT * FROM ${table} LIMIT 0`);
});
}
});
const sql = queries.length ? queries.join(';') : null;
if (!sql) {
return callback();
}
this.pgConnection.getConnection(this.user, (err, connection) => {
if (err) {
return callback(err);
}
QueryTables.getAffectedTablesFromQuery(connection, sql, (err, affectedTables) => {
if (err) {
return callback(err);
}
this.affectedTablesCache.set(dbname, token, affectedTables);
callback(err, affectedTables);
});
});
});
}
getAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
if (this.affectedTablesCache.hasAffectedTables(dbname, token)) {
const affectedTables = this.affectedTablesCache.get(dbname, token);
return callback(null, affectedTables);
}
return this.createAffectedTables(callback);
});
}
};
@@ -1,17 +1,17 @@
const BaseMapConfigProvider = require('./base-mapconfig-adapter');
const crypto = require('crypto');
const dot = require('dot');
const MapConfig = require('windshaft').model.MapConfig;
const templateName = require('../../../backends/template_maps').templateName;
const QueryTables = require('cartodb-query-tables');
// Configure bases for cache keys suitable for string interpolation
const baseKey = '{{=it.dbname}}:{{=it.owner}}:{{=it.templateName}}';
const baseKey = '{{=it.dbname}}:{{=it.user}}:{{=it.templateName}}';
const rendererKey = baseKey + ':{{=it.authToken}}:{{=it.configHash}}:{{=it.format}}:{{=it.layer}}:{{=it.scale_factor}}';
const baseKeyTpl = dot.template(baseKey);
const rendererKeyTpl = dot.template(rendererKey);
module.exports = class NamedMapMapConfigProvider {
module.exports = class NamedMapMapConfigProvider extends BaseMapConfigProvider {
constructor (
templateMaps,
pgConnection,
@@ -19,19 +19,20 @@ module.exports = class NamedMapMapConfigProvider {
userLimitsBackend,
mapConfigAdapter,
affectedTablesCache,
owner,
user,
templateId,
config,
authToken,
params
) {
super();
this.templateMaps = templateMaps;
this.pgConnection = pgConnection;
this.metadataBackend = metadataBackend;
this.userLimitsBackend = userLimitsBackend;
this.mapConfigAdapter = mapConfigAdapter;
this.owner = owner;
this.user = user;
this.templateName = templateName(templateId);
this.config = config;
this.authToken = authToken;
@@ -95,10 +96,10 @@ module.exports = class NamedMapMapConfigProvider {
return callback(err);
}
const { owner, rendererParams } = this;
const { user, rendererParams } = this;
this.mapConfigAdapter.getMapConfig(
owner, requestMapConfig, rendererParams, context, (err, mapConfig) => {
user, requestMapConfig, rendererParams, context, (err, mapConfig) => {
if (err) {
this.err = err;
return callback(err);
@@ -114,14 +115,14 @@ module.exports = class NamedMapMapConfigProvider {
}
getContext (callback) {
this.getDBParams(this.owner, (err, rendererParams) => {
this.getDBParams(this.user, (err, rendererParams) => {
if (err) {
return callback(err);
}
this.rendererParams = rendererParams;
this.metadataBackend.getUserMapKey(this.owner, (err, apiKey) => {
this.metadataBackend.getUserMapKey(this.user, (err, apiKey) => {
if (err) {
return callback(err);
}
@@ -129,7 +130,7 @@ module.exports = class NamedMapMapConfigProvider {
const context = {};
context.analysisConfiguration = {
user: this.owner,
user: this.user,
db: {
host: rendererParams.dbhost,
port: rendererParams.dbport,
@@ -138,12 +139,12 @@ module.exports = class NamedMapMapConfigProvider {
pass: rendererParams.dbpassword
},
batch: {
username: this.owner,
username: this.user,
apiKey: apiKey
}
};
this.userLimitsBackend.getRenderLimits(this.owner, this.params.api_key, (err, renderLimits) => {
this.userLimitsBackend.getRenderLimits(this.user, this.params.api_key, (err, renderLimits) => {
if (err) {
this.err = err;
return callback(err);
@@ -164,14 +165,14 @@ module.exports = class NamedMapMapConfigProvider {
return callback(this.err, this.template);
}
this.templateMaps.getTemplate(this.owner, this.templateName, (err, tpl) => {
this.templateMaps.getTemplate(this.user, this.templateName, (err, tpl) => {
if (err) {
this.err = err;
return callback(err);
}
if (!tpl) {
const error = new Error(`Template '${this.templateName}' of user '${this.owner}' not found`);
const error = new Error(`Template '${this.templateName}' of user '${this.user}' not found`);
error.http_status = 404;
this.err = error;
@@ -233,7 +234,7 @@ module.exports = class NamedMapMapConfigProvider {
createKey (base) {
const tplValues = Object.assign({
dbname: '',
owner: this.owner,
user: this.user,
templateName: this.templateName,
authToken: this.authToken || '',
configHash: configHash(this.config),
@@ -245,7 +246,7 @@ module.exports = class NamedMapMapConfigProvider {
}
getDBParams (cdbuser, callback) {
const dbParams = Object.assign({ user: this.owner }, this.params);
const dbParams = Object.assign({ user: this.user }, this.params);
this.pgConnection.getDatabaseParams(cdbuser, (err, databaseParams) => {
if (err) {
@@ -265,68 +266,6 @@ module.exports = class NamedMapMapConfigProvider {
getTemplateName () {
return this.templateName;
}
createAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.rendererParams;
const token = mapConfig.id();
const queries = [];
mapConfig.getLayers().forEach(layer => {
queries.push(layer.options.sql);
if (layer.options.affected_tables) {
layer.options.affected_tables.map(table => {
queries.push(`SELECT * FROM ${table} LIMIT 0`);
});
}
});
const sql = queries.length ? queries.join(';') : null;
if (!sql) {
return callback();
}
this.pgConnection.getConnection(this.owner, (err, connection) => {
if (err) {
return callback(err);
}
QueryTables.getAffectedTablesFromQuery(connection, sql, (err, affectedTables) => {
if (err) {
return callback(err);
}
this.affectedTablesCache.set(dbname, token, affectedTables);
callback(err, affectedTables);
});
});
});
}
getAffectedTables (callback) {
this.getMapConfig((err, mapConfig) => {
if (err) {
return callback(err);
}
const { dbname } = this.params;
const token = mapConfig.id();
if (this.affectedTablesCache.hasAffectedTables(dbname, token)) {
const affectedTables = this.affectedTablesCache.get(dbname, token);
return callback(null, affectedTables);
}
return this.createAffectedTables(callback);
});
}
};
function configHash(config) {