Merge pull request #591 from CartoDB/copyto-post
Implement POST for copyto endpoint
This commit is contained in:
commit
9e5cb0328d
@ -15,6 +15,7 @@ const Throttler = require('../services/throttler-stream');
|
||||
const zlib = require('zlib');
|
||||
const { PassThrough } = require('stream');
|
||||
const handleQueryMiddleware = require('../middlewares/handle-query');
|
||||
const bodyParserMiddleware = require('../middlewares/body-parser');
|
||||
|
||||
function CopyController(metadataBackend, userDatabaseService, userLimitsService, logger) {
|
||||
this.metadataBackend = metadataBackend;
|
||||
@ -44,6 +45,7 @@ CopyController.prototype.route = function (app) {
|
||||
|
||||
const copyToMiddlewares = endpointGroup => {
|
||||
return [
|
||||
bodyParserMiddleware(),
|
||||
initializeProfilerMiddleware('copyto'),
|
||||
userMiddleware(this.metadataBackend),
|
||||
rateLimitsMiddleware(this.userLimitsService, endpointGroup),
|
||||
@ -51,6 +53,7 @@ CopyController.prototype.route = function (app) {
|
||||
connectionParamsMiddleware(this.userDatabaseService),
|
||||
validateCopyQuery(),
|
||||
handleQueryMiddleware(),
|
||||
getFilenameParam(),
|
||||
handleCopyTo(this.logger),
|
||||
errorHandler(this.logger),
|
||||
errorMiddleware()
|
||||
@ -59,13 +62,12 @@ CopyController.prototype.route = function (app) {
|
||||
|
||||
app.post(`${base_url}/sql/copyfrom`, copyFromMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_FROM));
|
||||
app.get(`${base_url}/sql/copyto`, copyToMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_TO));
|
||||
app.post(`${base_url}/sql/copyto`, copyToMiddlewares(RATE_LIMIT_ENDPOINTS_GROUPS.COPY_TO));
|
||||
};
|
||||
|
||||
|
||||
function handleCopyTo (logger) {
|
||||
return function handleCopyToMiddleware (req, res, next) {
|
||||
const { sql, userDbParams, user } = res.locals;
|
||||
const filename = req.query.filename || 'carto-sql-copyto.dmp';
|
||||
const { sql, filename, userDbParams, user } = res.locals;
|
||||
|
||||
// it is not sure, nginx may choose not to compress the body
|
||||
// but we want to know it and save it in the metrics
|
||||
@ -167,9 +169,23 @@ function handleCopyFrom (logger) {
|
||||
};
|
||||
}
|
||||
|
||||
function getFilenameParam () {
|
||||
return function getFilenameParamMiddleware (req, res, next) {
|
||||
let filename = (req.query && req.query.filename) || (req.body && req.body.filename);
|
||||
|
||||
if (!filename) {
|
||||
filename = 'carto-sql-copyto.dmp';
|
||||
}
|
||||
|
||||
res.locals.filename = filename;
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
function validateCopyQuery () {
|
||||
return function validateCopyQueryMiddleware (req, res, next) {
|
||||
const sql = req.query.q;
|
||||
const sql = (req.query && req.query.q) || (req.body && req.body.q);
|
||||
|
||||
if (!sql) {
|
||||
return next(new Error("SQL is missing"));
|
||||
|
@ -170,6 +170,46 @@ describe('copy-endpoints', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should work with copyto endpoint and POST method', function(done){
|
||||
assert.response(server, {
|
||||
url: "/api/v1/sql/copyfrom?" + querystring.stringify({
|
||||
q: "COPY copy_endpoints_test (id, name) FROM STDIN WITH (FORMAT CSV, DELIMITER ',', HEADER true)"
|
||||
}),
|
||||
data: fs.createReadStream(__dirname + '/../support/csv/copy_test_table.csv'),
|
||||
headers: {
|
||||
host: 'vizzuality.cartodb.com'
|
||||
},
|
||||
method: 'POST'
|
||||
}, {}, function(err) {
|
||||
assert.ifError(err);
|
||||
|
||||
assert.response(server, {
|
||||
url: '/api/v1/sql/copyto',
|
||||
data: querystring.stringify({
|
||||
q: 'COPY copy_endpoints_test TO STDOUT',
|
||||
filename: '/tmp/output.dmp'
|
||||
}),
|
||||
headers: {
|
||||
host: 'vizzuality.cartodb.com',
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
method: 'POST'
|
||||
}, {}, function(err, res) {
|
||||
assert.ifError(err);
|
||||
|
||||
assert.strictEqual(
|
||||
res.body,
|
||||
'11\tPaul\t10\n12\tPeter\t10\n13\tMatthew\t10\n14\t\\N\t10\n15\tJames\t10\n16\tJohn\t10\n'
|
||||
);
|
||||
|
||||
assert.equal(res.headers['content-disposition'], 'attachment; filename=%2Ftmp%2Foutput.dmp');
|
||||
assert.equal(res.headers['content-type'], 'application/octet-stream');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail with copyto endpoint and without sql', function(done){
|
||||
assert.response(server, {
|
||||
url: "/api/v1/sql/copyto?" + querystring.stringify({
|
||||
|
Loading…
Reference in New Issue
Block a user