var crypto = require('crypto'), Step = require('step'), fs = require('fs'), _ = require('underscore'), PSQL = require('cartodb-psql'), spawn = require('child_process').spawn; // Keeps track of what's waiting baking for export var bakingExports = {}; function OgrFormat(id) { this.id = id; } OgrFormat.prototype = { id: "ogr", is_file: true, getQuery: function(sql, options) { return null; // dont execute the query }, transform: function(result, options, callback) { throw "should not be called for file formats" }, getContentType: function(){ return this._contentType; }, getFileExtension: function(){ return this._fileExtension; }, getKey: function(options) { return [this.id, options.dbopts.dbname, options.dbopts.user, options.gn, this.generateMD5(options.filename), this.generateMD5(options.sql)].concat(options.skipfields).join(':'); }, generateMD5: function (data){ var hash = crypto.createHash('md5'); hash.update(data); return hash.digest('hex'); } }; // Internal function usable by all OGR-driven outputs OgrFormat.prototype.toOGR = function(options, out_format, out_filename, callback) { var gcol = options.gn; var sql = options.sql; var skipfields = options.skipfields; var out_layername = options.filename; var dbopts = options.dbopts; var ogr2ogr = 'ogr2ogr'; // FIXME: make configurable var dbhost = dbopts.host; var dbport = dbopts.port; var dbuser = dbopts.user; var dbpass = dbopts.pass; var dbname = dbopts.dbname; var that = this; var columns = []; var geocol; var pg; // Drop ending semicolon (ogr doens't like it) sql = sql.replace(/;\s*$/, ''); Step ( function fetchColumns() { var colsql = 'SELECT * FROM (' + sql + ') as _cartodbsqlapi LIMIT 0'; pg = new PSQL(dbopts); pg.query(colsql, this); }, function findSRS(err, result) { if (err) throw err; //if ( ! result.rows.length ) throw new Error("Query returns no rows"); var needSRS = that._needSRS; // Skip system columns, find geom column for (var i=0; i