[sqllab] run only the part of the query that is selected (#1479)

This commit is contained in:
Maxime Beauchemin
2016-10-31 21:07:46 -07:00
committed by GitHub
parent 4f49cb555b
commit 4023f328f7
7 changed files with 67 additions and 19 deletions

View File

@@ -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}
/>
);

View File

@@ -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)}
/>

View File

@@ -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 = {