90 lines
3.2 KiB
JavaScript
90 lines
3.2 KiB
JavaScript
var _ = require('underscore'),
|
|
Varnish = require('node-varnish'),
|
|
request = require('request'),
|
|
crypto = require('crypto'),
|
|
channelCache = {},
|
|
varnish_queue = null;
|
|
|
|
function init(host, port) {
|
|
varnish_queue = new Varnish.VarnishQueue(host, port);
|
|
}
|
|
|
|
function invalidate_db(dbname, table) {
|
|
try{
|
|
varnish_queue.run_cmd('purge obj.http.X-Cache-Channel ~ "^' + dbname + ':(.*'+ table +'.*)|(table)$"');
|
|
console.log('[SUCCESS FLUSHING CACHE]');
|
|
} catch (e) {
|
|
console.log("[ERROR FLUSHING CACHE] Is enable_cache set to true? Failed for: " + 'purge obj.http.X-Cache-Channel ~ "^' + dbname + ':(.*'+ table +'.*)|(table)$"');
|
|
}
|
|
}
|
|
|
|
function generateCacheChannel(req, callback){
|
|
var cacheChannel = "";
|
|
|
|
// use key to call sql api with sql request if present, else just return dbname and table name
|
|
// base key
|
|
var tableNames = req.params.table;
|
|
var dbName = req.params.dbname;
|
|
var username = req.headers.host.split('.')[0];
|
|
|
|
// replace tableNames with the results of the explain if present
|
|
if (_.isString(req.params.sql) && req.params.sql != ''){
|
|
// initialise MD5 key of sql for cache lookups
|
|
var sql_md5 = generateMD5(req.params.sql);
|
|
var api = global.environment.sqlapi;
|
|
var qs = {};
|
|
|
|
// use cache if present
|
|
if (!_.isNull(channelCache[sql_md5]) && !_.isUndefined(channelCache[sql_md5])) {
|
|
callback(channelCache[sql_md5]);
|
|
} else{
|
|
// strip out windshaft/mapnik inserted sql if present
|
|
var sql = req.params.sql.match(/^\((.*)\)\sas\scdbq$/);
|
|
sql = (sql != null) ? sql[1] : req.params.sql;
|
|
|
|
// build up api string
|
|
var sqlapi = api.protocol + '://' + username + '.' + api.host + ':' + api.port + '/api/' + api.version + '/sql'
|
|
|
|
// add query to querystring
|
|
qs.q = 'SELECT CDB_QueryTables($windshaft$' + sql + '$windshaft$)';
|
|
|
|
// add api_key if present in tile request (means table is private)
|
|
if (_.isString(req.params.map_key) && req.params.map_key != ''){
|
|
qs.api_key = req.params.map_key;
|
|
}
|
|
|
|
// call sql api
|
|
request.get({url:sqlapi, qs:qs, json:true}, function(err, response, body){
|
|
if (!err && response.statusCode == 200) {
|
|
tableNames = body.rows[0].cdb_querytables.split(/^\{(.*)\}$/)[1];
|
|
} else {
|
|
//oops, no SQL API. Just cache using fallback 'table' key
|
|
tableNames = 'table';
|
|
}
|
|
cacheChannel = buildCacheChannel(dbName,tableNames);
|
|
channelCache[sql_md5] = cacheChannel; // store for caching
|
|
callback(cacheChannel);
|
|
});
|
|
}
|
|
} else {
|
|
cacheChannel = buildCacheChannel(dbName,tableNames);
|
|
callback(cacheChannel);
|
|
}
|
|
}
|
|
|
|
function buildCacheChannel(dbName, tableNames){
|
|
return dbName + ':' + tableNames;
|
|
}
|
|
|
|
function generateMD5(data){
|
|
var hash = crypto.createHash('md5');
|
|
hash.update(data);
|
|
return hash.digest('hex');
|
|
}
|
|
|
|
module.exports = {
|
|
init: init,
|
|
invalidate_db: invalidate_db,
|
|
generateCacheChannel: generateCacheChannel
|
|
}
|