mirror of
https://github.com/apache/superset.git
synced 2026-06-07 00:29:17 +00:00
[sqllab] run only the part of the query that is selected (#1479)
This commit is contained in:
committed by
GitHub
parent
4f49cb555b
commit
4023f328f7
@@ -4,13 +4,16 @@ import 'brace/mode/sql';
|
||||
import 'brace/theme/github';
|
||||
import 'brace/ext/language_tools';
|
||||
import ace from 'brace';
|
||||
import { areArraysShallowEqual } from '../../reduxUtils';
|
||||
|
||||
const langTools = ace.acequire('ace/ext/language_tools');
|
||||
|
||||
const propTypes = {
|
||||
actions: React.PropTypes.object.isRequired,
|
||||
onBlur: React.PropTypes.func,
|
||||
sql: React.PropTypes.string.isRequired,
|
||||
tables: React.PropTypes.array,
|
||||
queryEditor: React.PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
@@ -25,6 +28,16 @@ class AceEditorWrapper extends React.PureComponent {
|
||||
sql: props.sql,
|
||||
};
|
||||
}
|
||||
componentDidMount() {
|
||||
// Making sure no text is selected from previous mount
|
||||
this.props.actions.queryEditorSetSelectedText(this.props.queryEditor, null);
|
||||
this.setAutoCompleter();
|
||||
}
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (!areArraysShallowEqual(this.props.tables, nextProps.tables)) {
|
||||
this.setAutoCompleter();
|
||||
}
|
||||
}
|
||||
textChange(text) {
|
||||
this.setState({ sql: text });
|
||||
}
|
||||
@@ -32,22 +45,31 @@ class AceEditorWrapper extends React.PureComponent {
|
||||
this.props.onBlur(this.state.sql);
|
||||
}
|
||||
getCompletions(aceEditor, session, pos, prefix, callback) {
|
||||
callback(null, this.state.words);
|
||||
}
|
||||
onEditorLoad(editor) {
|
||||
editor.$blockScrolling = Infinity; // eslint-disable-line no-param-reassign
|
||||
editor.selection.on('changeSelection', () => {
|
||||
this.props.actions.queryEditorSetSelectedText(
|
||||
this.props.queryEditor, editor.getSelectedText());
|
||||
});
|
||||
}
|
||||
setAutoCompleter() {
|
||||
// Loading table and column names as auto-completable words
|
||||
let words = [];
|
||||
const columns = {};
|
||||
const tables = this.props.tables || [];
|
||||
tables.forEach(t => {
|
||||
words.push({ name: t.name, value: t.name, score: 55, meta: 'table' });
|
||||
t.columns.forEach(col => {
|
||||
const cols = t.columns || [];
|
||||
cols.forEach(col => {
|
||||
columns[col.name] = null; // using an object as a unique set
|
||||
});
|
||||
});
|
||||
words = words.concat(Object.keys(columns).map(col => (
|
||||
{ name: col, value: col, score: 50, meta: 'column' }
|
||||
)));
|
||||
callback(null, words);
|
||||
}
|
||||
setAutoCompleter() {
|
||||
// Loading table and column names as auto-completable words
|
||||
this.setState({ words });
|
||||
const completer = {
|
||||
getCompletions: this.getCompletions.bind(this),
|
||||
};
|
||||
@@ -56,11 +78,11 @@ class AceEditorWrapper extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
render() {
|
||||
this.setAutoCompleter();
|
||||
return (
|
||||
<AceEditor
|
||||
mode="sql"
|
||||
theme="github"
|
||||
onLoad={this.onEditorLoad.bind(this)}
|
||||
onBlur={this.onBlur.bind(this)}
|
||||
minLines={8}
|
||||
maxLines={30}
|
||||
@@ -68,7 +90,7 @@ class AceEditorWrapper extends React.PureComponent {
|
||||
height="200px"
|
||||
width="100%"
|
||||
editorProps={{ $blockScrolling: true }}
|
||||
enableBasicAutocompletion
|
||||
enableLiveAutocompletion
|
||||
value={this.state.sql}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -58,12 +58,13 @@ class SqlEditor extends React.PureComponent {
|
||||
this.startQuery(runAsync);
|
||||
}
|
||||
startQuery(runAsync = false, ctas = false) {
|
||||
const qe = this.props.queryEditor;
|
||||
const query = {
|
||||
dbId: this.props.queryEditor.dbId,
|
||||
sql: this.props.queryEditor.sql,
|
||||
sqlEditorId: this.props.queryEditor.id,
|
||||
tab: this.props.queryEditor.title,
|
||||
schema: this.props.queryEditor.schema,
|
||||
dbId: qe.dbId,
|
||||
sql: qe.selectedText ? qe.selectedText : qe.sql,
|
||||
sqlEditorId: qe.id,
|
||||
tab: qe.title,
|
||||
schema: qe.schema,
|
||||
tempTableName: this.state.ctas,
|
||||
runAsync,
|
||||
ctas,
|
||||
@@ -92,17 +93,23 @@ class SqlEditor extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
let runButtons = [];
|
||||
let runText = 'Run Query';
|
||||
let btnStyle = 'primary';
|
||||
if (this.props.queryEditor.selectedText) {
|
||||
runText = 'Run Selection';
|
||||
btnStyle = 'warning';
|
||||
}
|
||||
if (this.props.database && this.props.database.allow_run_sync) {
|
||||
runButtons.push(
|
||||
<Button
|
||||
bsSize="small"
|
||||
bsStyle="primary"
|
||||
bsStyle={btnStyle}
|
||||
style={{ width: '100px' }}
|
||||
onClick={this.runQuery.bind(this, false)}
|
||||
disabled={!(this.props.queryEditor.dbId)}
|
||||
key="run-btn"
|
||||
>
|
||||
<i className="fa fa-table" /> Run Query
|
||||
<i className="fa fa-table" /> {runText}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@@ -110,7 +117,7 @@ class SqlEditor extends React.PureComponent {
|
||||
runButtons.push(
|
||||
<Button
|
||||
bsSize="small"
|
||||
bsStyle="primary"
|
||||
bsStyle={btnStyle}
|
||||
style={{ width: '100px' }}
|
||||
onClick={this.runQuery.bind(this, true)}
|
||||
disabled={!(this.props.queryEditor.dbId)}
|
||||
@@ -209,6 +216,8 @@ class SqlEditor extends React.PureComponent {
|
||||
<Col md={9}>
|
||||
<AceEditorWrapper
|
||||
tables={this.props.tables}
|
||||
actions={this.props.actions}
|
||||
queryEditor={this.props.queryEditor}
|
||||
sql={this.props.queryEditor.sql}
|
||||
onBlur={this.setQueryEditorSql.bind(this)}
|
||||
/>
|
||||
|
||||
@@ -10,7 +10,7 @@ import ModalTrigger from '../../components/ModalTrigger';
|
||||
const propTypes = {
|
||||
table: React.PropTypes.object,
|
||||
actions: React.PropTypes.object,
|
||||
timeout: React.PropTypes.integer, // used for tests
|
||||
timeout: React.PropTypes.number, // used for tests
|
||||
};
|
||||
|
||||
const defaultProps = {
|
||||
|
||||
Reference in New Issue
Block a user