From be0f059f01a08c37a9481d39de9dbfd9ba175632 Mon Sep 17 00:00:00 2001 From: Raul Ochoa Date: Thu, 30 Jun 2016 17:41:02 +0200 Subject: [PATCH] Add `<%= job_id %>` template support for onerror and onsuccess fallback queries --- NEWS.md | 7 ++ batch/models/query/fallback.js | 7 +- npm-shrinkwrap.json | 2 +- package.json | 2 +- ....test.js => job.callback-template.test.js} | 71 +++++++++++++++++-- 5 files changed, 80 insertions(+), 9 deletions(-) rename test/acceptance/{job.error-template.test.js => job.callback-template.test.js} (65%) diff --git a/NEWS.md b/NEWS.md index 4a892bc1..d4905119 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +1.33.0 - 2016-mm-dd +------------------- + +New features: + * Add `<%= job_id %>` template support for onerror and onsuccess fallback queries. + + 1.32.0 - 2016-06-30 ------------------- diff --git a/batch/models/query/fallback.js b/batch/models/query/fallback.js index d65055c0..1ce5f22f 100644 --- a/batch/models/query/fallback.js +++ b/batch/models/query/fallback.js @@ -30,7 +30,11 @@ Fallback.prototype.getNextQuery = function (job) { Fallback.prototype.getOnSuccess = function (job) { if (job.query.query[this.index].status === jobStatus.DONE && job.query.query[this.index].fallback_status === jobStatus.PENDING) { - return job.query.query[this.index].onsuccess; + var onsuccessQuery = job.query.query[this.index].onsuccess; + if (onsuccessQuery) { + onsuccessQuery = onsuccessQuery.replace(/<%=\s*job_id\s*%>/g, job.job_id); + } + return onsuccessQuery; } }; @@ -43,6 +47,7 @@ Fallback.prototype.getOnError = function (job) { job.query.query[this.index].fallback_status === jobStatus.PENDING) { var onerrorQuery = job.query.query[this.index].onerror; if (onerrorQuery) { + onerrorQuery = onerrorQuery.replace(/<%=\s*job_id\s*%>/g, job.job_id); onerrorQuery = onerrorQuery.replace(/<%=\s*error_message\s*%>/g, job.query.query[this.index].failed_reason); } return onerrorQuery; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 7e86d26b..8027d14c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "cartodb_sql_api", - "version": "1.31.1", + "version": "1.33.0", "dependencies": { "cartodb-psql": { "version": "0.6.1", diff --git a/package.json b/package.json index baf91454..f132c007 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "keywords": [ "cartodb" ], - "version": "1.32.0", + "version": "1.33.0", "repository": { "type": "git", "url": "git://github.com/CartoDB/CartoDB-SQL-API.git" diff --git a/test/acceptance/job.error-template.test.js b/test/acceptance/job.callback-template.test.js similarity index 65% rename from test/acceptance/job.error-template.test.js rename to test/acceptance/job.callback-template.test.js index 0da67d90..3e709e80 100644 --- a/test/acceptance/job.error-template.test.js +++ b/test/acceptance/job.callback-template.test.js @@ -13,7 +13,7 @@ var metadataBackend = require('cartodb-redis')({ var batchFactory = require('../../batch'); var jobStatus = require('../../batch/job_status'); -describe('Batch API query timing', function () { +describe('Batch API callback templates', function () { function createJob(jobDefinition, callback) { assert.response(app, { @@ -100,18 +100,18 @@ describe('Batch API query timing', function () { }); }); - describe('should report start and end time for each query with fallback queries', function () { + describe('should use templates for error_message and job_id onerror callback', function () { var jobResponse; before(function(done) { createJob({ "query": { "query": [ { - "query": "create table batch_errors (error_message text)" + "query": "create table batch_errors (job_id text, error_message text)" }, { "query": "SELECT * FROM invalid_table", - "onerror": "INSERT INTO batch_errors values ('<%= error_message %>')" + "onerror": "INSERT INTO batch_errors values ('<%= job_id %>', '<%= error_message %>')" } ] } @@ -125,12 +125,12 @@ describe('Batch API query timing', function () { var expectedQuery = { query: [ { - "query": "create table batch_errors (error_message text)", + "query": "create table batch_errors (job_id text, error_message text)", status: 'done' }, { "query": "SELECT * FROM invalid_table", - "onerror": "INSERT INTO batch_errors values ('<%= error_message %>')", + "onerror": "INSERT INTO batch_errors values ('<%= job_id %>', '<%= error_message %>')", status: 'failed', fallback_status: 'done' } @@ -146,6 +146,7 @@ describe('Batch API query timing', function () { if (err) { return done(err); } + assert.equal(result.rows[0].job_id, jobResponse.job_id); assert.equal(result.rows[0].error_message, 'relation "invalid_table" does not exist'); getQueryResult('drop table batch_errors', done); }); @@ -158,4 +159,62 @@ describe('Batch API query timing', function () { }); }); + describe('should use template for job_id onsuccess callback', function () { + var jobResponse; + before(function(done) { + createJob({ + "query": { + "query": [ + { + query: "create table batch_jobs (job_id text)" + }, + { + "query": "SELECT 1", + "onsuccess": "INSERT INTO batch_jobs values ('<%= job_id %>')" + } + ] + } + }, function(err, job) { + jobResponse = job; + return done(err); + }); + }); + + it('should keep the original templated query but use the job_id', function (done) { + var expectedQuery = { + query: [ + { + query: "create table batch_jobs (job_id text)", + status: 'done' + }, + { + query: "SELECT 1", + onsuccess: "INSERT INTO batch_jobs values ('<%= job_id %>')", + status: 'done', + fallback_status: 'done' + } + ] + }; + + var interval = setInterval(function () { + getJobStatus(jobResponse.job_id, function(err, job) { + if (job.status === jobStatus.DONE) { + clearInterval(interval); + validateExpectedResponse(job.query, expectedQuery); + getQueryResult('select * from batch_jobs', function(err, result) { + if (err) { + return done(err); + } + assert.equal(result.rows[0].job_id, jobResponse.job_id); + getQueryResult('drop table batch_jobs', done); + }); + } else if (job.status === jobStatus.FAILED || job.status === jobStatus.CANCELLED) { + clearInterval(interval); + done(new Error('Job ' + job.job_id + ' is ' + job.status + ', expected to be "done"')); + } + }); + }, 50); + }); + }); + });