sqlpad
Version:
Web app. Write SQL and visualize the results. Supports Postgres, MySQL, SQL Server, Crate, Vertica and SAP HANA.
141 lines (129 loc) • 3.85 kB
JavaScript
const db = require('../lib/db.js');
const config = require('../lib/config');
const Joi = require('joi');
const request = require('request');
/*
"chartConfiguration": {
"chartType": "line",
"fields": {
"x": "created_month",
"y": "package_count",
"split": "keyword",
"xFacet": "",
"yFacet": "keyword",
"trendline": "true"
}
}
*/
const schema = {
_id: Joi.string().optional(), // generated by nedb
name: Joi.string().required(),
tags: Joi.array()
.items(Joi.string().empty(''))
.sparse()
.optional(),
connectionId: Joi.string()
.optional()
.empty(''),
queryText: Joi.string()
.optional()
.empty(''),
chartConfiguration: Joi.object({
chartType: Joi.string()
.optional()
.empty(''),
// key value pairings. key=chart property, value=field mapped to property
fields: Joi.object()
.unknown(true)
.optional()
}).optional(),
createdDate: Joi.date().default(new Date(), 'time of creation'),
modifiedDate: Joi.date().default(new Date(), 'time of modification'),
createdBy: Joi.string().required(),
modifiedBy: Joi.string().required(),
lastAccessDate: Joi.date().default(new Date(), 'time of last access')
};
function Query(data) {
this._id = data._id;
this.name = data.name;
this.tags = data.tags;
this.connectionId = data.connectionId;
this.queryText = data.queryText;
this.chartConfiguration = data.chartConfiguration;
this.createdDate = data.createdDate;
this.createdBy = data.createdBy;
this.modifiedDate = data.modifiedDate;
this.modifiedBy = data.modifiedBy;
this.lastAccessDate = data.lastAccessedDate;
}
Query.prototype.save = function save() {
const self = this;
this.modifiedDate = new Date();
this.lastAccessDate = new Date();
// clean tags if present
// sqlpad v1 saved a lot of bad inputs
if (Array.isArray(self.tags)) {
self.tags = self.tags
.filter(tag => {
return typeof tag === 'string' && tag.trim() !== '';
})
.map(tag => {
return tag.trim();
});
}
const joiResult = Joi.validate(self, schema);
if (joiResult.error) {
return Promise.reject(joiResult.error);
}
if (self._id) {
return db.queries
.update({ _id: self._id }, joiResult.value, { upsert: true })
.then(() => Query.findOneById(self._id));
}
return db.queries.insert(joiResult.value).then(doc => new Query(doc));
};
Query.prototype.pushQueryToSlackIfSetup = function() {
const SLACK_WEBHOOK = config.get('slackWebhook');
if (SLACK_WEBHOOK) {
const PUBLIC_URL = config.get('publicUrl');
const BASE_URL = config.get('baseUrl');
const options = {
method: 'post',
body: {
text: `New Query <${PUBLIC_URL}${BASE_URL}/queries/${this._id}|${
this.name
}>
saved by ${this.modifiedBy} on SQLPad
${'```'}
${this.queryText}
${'```'}`
},
json: true,
url: SLACK_WEBHOOK
};
request(options, function(err) {
if (err) {
console.error('Something went wrong while sending to Slack.');
console.error(err);
}
});
}
};
/* Query methods
============================================================================== */
Query.findOneById = id =>
db.queries.findOne({ _id: id }).then(doc => new Query(doc));
Query.findAll = () =>
db.queries.find({}).then(docs => docs.map(doc => new Query(doc)));
Query.findByFilter = filter =>
db.queries.find(filter).then(docs => docs.map(doc => new Query(doc)));
Query.prototype.logAccess = function logAccess() {
const self = this;
return db.queries.update(
{ _id: self._id },
{ $set: { lastAccessedDate: new Date() } },
{}
);
};
Query.removeOneById = id => db.queries.remove({ _id: id });
module.exports = Query;