[sqllab] add support for results backends (#1377)

* [sqllab] add support for results backends

Long running SQL queries (beyond the scope of a web request) can now use
a k/v store to hold their result sets.

* Addressing comments, fixed js tests

* Fixing mysql has gone away

* Adressing more comments

* Touchups
This commit is contained in:
Maxime Beauchemin
2016-10-20 23:40:24 -07:00
committed by GitHub
parent 7dfe891cc1
commit 6fb3b305ad
27 changed files with 788 additions and 365 deletions

View File

@@ -1,17 +1,17 @@
import shortid from 'shortid';
import { now } from '../modules/dates';
const $ = require('jquery');
export const RESET_STATE = 'RESET_STATE';
export const ADD_QUERY_EDITOR = 'ADD_QUERY_EDITOR';
export const CLONE_QUERY_TO_NEW_TAB = 'CLONE_QUERY_TO_NEW_TAB';
export const REMOVE_QUERY_EDITOR = 'REMOVE_QUERY_EDITOR';
export const MERGE_TABLE = 'MERGE_TABLE';
export const REMOVE_TABLE = 'REMOVE_TABLE';
export const START_QUERY = 'START_QUERY';
export const STOP_QUERY = 'STOP_QUERY';
export const END_QUERY = 'END_QUERY';
export const REMOVE_QUERY = 'REMOVE_QUERY';
export const EXPAND_TABLE = 'EXPAND_TABLE';
export const COLLAPSE_TABLE = 'COLLAPSE_TABLE';
export const QUERY_SUCCESS = 'QUERY_SUCCESS';
export const QUERY_FAILED = 'QUERY_FAILED';
export const QUERY_EDITOR_SETDB = 'QUERY_EDITOR_SETDB';
export const QUERY_EDITOR_SET_SCHEMA = 'QUERY_EDITOR_SET_SCHEMA';
export const QUERY_EDITOR_SET_TITLE = 'QUERY_EDITOR_SET_TITLE';
@@ -25,11 +25,117 @@ export const ADD_ALERT = 'ADD_ALERT';
export const REMOVE_ALERT = 'REMOVE_ALERT';
export const REFRESH_QUERIES = 'REFRESH_QUERIES';
export const SET_NETWORK_STATUS = 'SET_NETWORK_STATUS';
export const RUN_QUERY = 'RUN_QUERY';
export const START_QUERY = 'START_QUERY';
export const STOP_QUERY = 'STOP_QUERY';
export const REQUEST_QUERY_RESULTS = 'REQUEST_QUERY_RESULTS';
export const QUERY_SUCCESS = 'QUERY_SUCCESS';
export const QUERY_FAILED = 'QUERY_FAILED';
export const CLEAR_QUERY_RESULTS = 'CLEAR_QUERY_RESULTS';
export const HIDE_DATA_PREVIEW = 'HIDE_DATA_PREVIEW';
export function resetState() {
return { type: RESET_STATE };
}
export function startQuery(query) {
Object.assign(query, {
id: shortid.generate(),
progress: 0,
startDttm: now(),
state: (query.runAsync) ? 'pending' : 'running',
});
return { type: START_QUERY, query };
}
export function querySuccess(query, results) {
return { type: QUERY_SUCCESS, query, results };
}
export function queryFailed(query, msg) {
return { type: QUERY_FAILED, query, msg };
}
export function stopQuery(query) {
return { type: STOP_QUERY, query };
}
export function clearQueryResults(query) {
return { type: CLEAR_QUERY_RESULTS, query };
}
export function hideDataPreview() {
return { type: HIDE_DATA_PREVIEW };
}
export function requestQueryResults(query) {
return { type: REQUEST_QUERY_RESULTS, query };
}
export function fetchQueryResults(query) {
return function (dispatch) {
dispatch(requestQueryResults(query));
const sqlJsonUrl = `/caravel/results/${query.resultsKey}/`;
$.ajax({
type: 'GET',
dataType: 'json',
url: sqlJsonUrl,
success(results) {
dispatch(querySuccess(query, results));
},
error() {
dispatch(queryFailed(query, 'Failed at retrieving results from the results backend'));
},
});
};
}
export function runQuery(query) {
return function (dispatch) {
dispatch(startQuery(query));
const sqlJsonUrl = '/caravel/sql_json/';
const sqlJsonRequest = {
client_id: query.id,
database_id: query.dbId,
json: true,
runAsync: query.runAsync,
schema: query.schema,
sql: query.sql,
sql_editor_id: query.sqlEditorId,
tab: query.tab,
tmp_table_name: query.tempTableName,
select_as_cta: query.ctas,
};
$.ajax({
type: 'POST',
dataType: 'json',
url: sqlJsonUrl,
data: sqlJsonRequest,
success(results) {
if (!query.runAsync) {
dispatch(querySuccess(query, results));
}
},
error(err, textStatus, errorThrown) {
let msg;
try {
msg = err.responseJSON.error;
} catch (e) {
if (err.responseText !== undefined) {
msg = err.responseText;
}
}
if (textStatus === 'error' && errorThrown === '') {
msg = 'Could not connect to server';
} else if (msg === null) {
msg = `[${textStatus}] ${errorThrown}`;
}
dispatch(queryFailed(query, msg));
},
});
};
}
export function setDatabases(databases) {
return { type: SET_DATABASES, databases };
}
@@ -102,22 +208,6 @@ export function removeTable(table) {
return { type: REMOVE_TABLE, table };
}
export function startQuery(query) {
return { type: START_QUERY, query };
}
export function stopQuery(query) {
return { type: STOP_QUERY, query };
}
export function querySuccess(query, results) {
return { type: QUERY_SUCCESS, query, results };
}
export function queryFailed(query, msg) {
return { type: QUERY_FAILED, query, msg };
}
export function addWorkspaceQuery(query) {
return { type: ADD_WORKSPACE_QUERY, query };
}