mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
Use a key-value store model for sharing long queries (#1951)
* Add KeyValue model for storing id-value pairs use it for storing shared queries * Change string to text and added test * Put getQueryLink in one place * Changed migration down version * Changes based on comments * Update bcf3126872fc_add_keyvalue.py
This commit is contained in:
@@ -298,3 +298,23 @@ export function removeTable(table) {
|
||||
export function refreshQueries(alteredQueries) {
|
||||
return { type: REFRESH_QUERIES, alteredQueries };
|
||||
}
|
||||
|
||||
export function popStoredQuery(urlId) {
|
||||
return function (dispatch) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: `/kv/${urlId}`,
|
||||
success: (data) => {
|
||||
const newQuery = JSON.parse(data);
|
||||
const queryEditorProps = {
|
||||
title: newQuery.title ? newQuery.title : 'shared query',
|
||||
dbId: newQuery.dbId ? parseInt(newQuery.dbId, 10) : null,
|
||||
schema: newQuery.schema ? newQuery.schema : null,
|
||||
autorun: newQuery.autorun ? newQuery.autorun : false,
|
||||
sql: newQuery.sql ? newQuery.sql : 'SELECT ...',
|
||||
};
|
||||
dispatch(addQueryEditor(queryEditorProps));
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import CopyToClipboard from '../../components/CopyToClipboard';
|
||||
import { getShortUrl } from '../../../utils/common';
|
||||
import { storeQuery } from '../../../utils/common';
|
||||
|
||||
const propTypes = {
|
||||
queryEditor: React.PropTypes.object.isRequired,
|
||||
@@ -9,16 +9,14 @@ const propTypes = {
|
||||
export default class CopyQueryTabUrl extends React.PureComponent {
|
||||
getUrl(callback) {
|
||||
const qe = this.props.queryEditor;
|
||||
const params = [];
|
||||
if (qe.dbId) params.push('dbid=' + qe.dbId);
|
||||
if (qe.title) params.push('title=' + encodeURIComponent(qe.title));
|
||||
if (qe.schema) params.push('schema=' + encodeURIComponent(qe.schema));
|
||||
if (qe.autorun) params.push('autorun=' + qe.autorun);
|
||||
if (qe.sql) params.push('sql=' + encodeURIComponent(qe.sql));
|
||||
|
||||
const queryString = params.join('&');
|
||||
const queryLink = window.location.pathname + '?' + queryString;
|
||||
getShortUrl(queryLink, callback);
|
||||
const sharedQuery = {
|
||||
dbId: qe.dbId,
|
||||
title: qe.title,
|
||||
schema: qe.schema,
|
||||
autorun: qe.autorun,
|
||||
sql: qe.sql,
|
||||
};
|
||||
storeQuery(sharedQuery, callback);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import ModalTrigger from '../../components/ModalTrigger';
|
||||
import HighlightedSql from './HighlightedSql';
|
||||
import { STATE_BSSTYLE_MAP } from '../constants';
|
||||
import { fDuration } from '../../modules/dates';
|
||||
import { getLink } from '../../../utils/common';
|
||||
import { storeQuery } from '../../../utils/common';
|
||||
|
||||
const propTypes = {
|
||||
columns: React.PropTypes.array,
|
||||
@@ -38,10 +38,17 @@ class QueryTable extends React.PureComponent {
|
||||
activeQuery: null,
|
||||
};
|
||||
}
|
||||
getQueryLink(dbId, sql) {
|
||||
const params = ['dbid=' + dbId, 'sql=' + sql, 'title=Untitled Query'];
|
||||
const link = getLink(this.state.cleanUri, params);
|
||||
return encodeURI(link);
|
||||
callback(url) {
|
||||
window.open(url);
|
||||
}
|
||||
openQuery(dbId, schema, sql) {
|
||||
const newQuery = {
|
||||
dbId,
|
||||
title: 'Untitled Query',
|
||||
schema,
|
||||
sql,
|
||||
};
|
||||
storeQuery(newQuery, this.callback);
|
||||
}
|
||||
hideVisualizeModal() {
|
||||
this.setState({ showVisualizeModal: false });
|
||||
@@ -98,12 +105,12 @@ class QueryTable extends React.PureComponent {
|
||||
q.started = moment(q.startDttm).format('HH:mm:ss');
|
||||
q.querylink = (
|
||||
<div style={{ width: '100px' }}>
|
||||
<a
|
||||
href={this.getQueryLink(q.dbId, q.sql)}
|
||||
className="btn btn-primary btn-xs"
|
||||
<button
|
||||
className="btn btn-link btn-xs"
|
||||
onClick={this.openQuery.bind(this, q.dbId, q.schema, q.sql)}
|
||||
>
|
||||
<i className="fa fa-external-link" />Open in SQL Editor
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
q.sql = (
|
||||
|
||||
@@ -4,9 +4,9 @@ import { connect } from 'react-redux';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import * as Actions from '../actions';
|
||||
import SqlEditor from './SqlEditor';
|
||||
import { getParamFromQuery } from '../../../utils/common';
|
||||
import CopyQueryTabUrl from './CopyQueryTabUrl';
|
||||
import { areArraysShallowEqual } from '../../reduxUtils';
|
||||
import { getParamFromQuery } from '../../../utils/common';
|
||||
|
||||
const propTypes = {
|
||||
actions: React.PropTypes.object.isRequired,
|
||||
@@ -28,34 +28,39 @@ let queryCount = 1;
|
||||
class TabbedSqlEditors extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const uri = window.location.toString();
|
||||
const search = window.location.search;
|
||||
const cleanUri = search ? uri.substring(0, uri.indexOf('?')) : uri;
|
||||
const query = search.substring(1);
|
||||
const sqlLabUrl = '/superset/sqllab';
|
||||
this.state = {
|
||||
uri,
|
||||
cleanUri,
|
||||
query,
|
||||
sqlLabUrl,
|
||||
queriesArray: [],
|
||||
dataPreviewQueries: [],
|
||||
hideLeftBar: false,
|
||||
};
|
||||
}
|
||||
componentWillMount() {
|
||||
if (this.state.query) {
|
||||
queryCount++;
|
||||
const queryEditorProps = {
|
||||
title: getParamFromQuery(this.state.query, 'title'),
|
||||
dbId: parseInt(getParamFromQuery(this.state.query, 'dbid'), 10),
|
||||
schema: getParamFromQuery(this.state.query, 'schema'),
|
||||
autorun: getParamFromQuery(this.state.query, 'autorun'),
|
||||
sql: getParamFromQuery(this.state.query, 'sql'),
|
||||
};
|
||||
this.props.actions.addQueryEditor(queryEditorProps);
|
||||
// Clean the url in browser history
|
||||
window.history.replaceState({}, document.title, this.state.cleanUri);
|
||||
componentDidMount() {
|
||||
const search = window.location.search;
|
||||
if (search) {
|
||||
const queryString = search.substring(1);
|
||||
const urlId = getParamFromQuery(queryString, 'id');
|
||||
if (urlId) {
|
||||
this.props.actions.popStoredQuery(urlId);
|
||||
} else {
|
||||
const newQueryEditor = {
|
||||
title: getParamFromQuery(queryString, 'title'),
|
||||
dbId: getParamFromQuery(queryString, 'dbid'),
|
||||
schema: getParamFromQuery(queryString, 'schema'),
|
||||
autorun: getParamFromQuery(queryString, 'autorun'),
|
||||
sql: getParamFromQuery(queryString, 'sql'),
|
||||
};
|
||||
this.props.actions.addQueryEditor(newQueryEditor);
|
||||
}
|
||||
this.popNewTab();
|
||||
}
|
||||
}
|
||||
popNewTab() {
|
||||
queryCount++;
|
||||
// Clean the url in browser history
|
||||
window.history.replaceState({}, document.title, this.state.sqlLabUrl);
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const nextActiveQeId = nextProps.tabHistory[nextProps.tabHistory.length - 1];
|
||||
const queriesArray = [];
|
||||
|
||||
Reference in New Issue
Block a user