|
|
@@ -42,7 +42,7 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
|
|
|
</style>
|
|
|
|
|
|
<!-- ko foreach: editors -->
|
|
|
- <div class="editor" data-bind="attr: {id: UUID()}, aceEditor: {value: snippet, ace: ace, mode: mode, onChange: changeEditor, onAfterExec: textInputHandler, extraCompleters: completers, errors: errors }">
|
|
|
+ <div class="editor" data-bind="attr: {id: UUID()}, aceEditor: {value: snippet, aceInstance: ace, mode: mode, onChange: onChangeHandler, onAfterExec: onAfterExecHandler, extraCompleters: completers, errors: errors }">
|
|
|
</div>
|
|
|
<!-- /ko -->
|
|
|
|
|
|
@@ -59,22 +59,20 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
|
|
|
<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }" type="text/javascript" charset="utf-8"></script>
|
|
|
<script src="${ static('desktop/ext/js/knockout-deferred-updates.min.js') }" type="text/javascript" charset="utf-8"></script>
|
|
|
<script src="${ static('desktop/js/ko.hue-bindings.js') }" type="text/javascript" charset="utf-8"></script>
|
|
|
-<script src="${ static('beeswax/js/autocomplete.utils.js') }" type="text/javascript" charset="utf-8"></script>
|
|
|
+
|
|
|
+<script src="${ static('spark/js/ace.autocomplete.js') }" type="text/javascript" charset="utf-8"></script>
|
|
|
|
|
|
<script>
|
|
|
|
|
|
- var HIVE_AUTOCOMPLETE_BASE_URL = "/beeswax/api/autocomplete/";
|
|
|
- var HIVE_AUTOCOMPLETE_FAILS_QUIETLY_ON = [500]; // error codes from beeswax/views.py - autocomplete
|
|
|
- var HIVE_AUTOCOMPLETE_USER = "hue";
|
|
|
- var HIVE_AUTOCOMPLETE_APP = "beeswax";
|
|
|
|
|
|
- var STATS_PROBLEMS = "${ _('There was a problem loading the stats.') }";
|
|
|
+ var AceAutocomplete = new Autocomplete({
|
|
|
+ autocompleteBaseURL: "/beeswax/api/autocomplete/",
|
|
|
+ autocompleteApp: "beeswax",
|
|
|
+ autocompleteUser: "hue",
|
|
|
+ autocompleteFailsQuietlyOn: [500] // error codes from beeswax/views.py - autocomplete
|
|
|
+ });
|
|
|
|
|
|
- var HIVE_AUTOCOMPLETE_GLOBAL_CALLBACK = function (data) {
|
|
|
- if (data != null && data.error && typeof resetNavigator != "undefined") {
|
|
|
- resetNavigator();
|
|
|
- }
|
|
|
- };
|
|
|
+ var DEFAULT_DB = "default";
|
|
|
|
|
|
function newCompleter(items) {
|
|
|
return {
|
|
|
@@ -84,44 +82,138 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- function textInputHandler(event, editor, valueAccessor) {
|
|
|
-
|
|
|
- }
|
|
|
+ function fieldsAutocomplete(editor, valueAccessor) {
|
|
|
+ try {
|
|
|
+ var _before = editor.getTextBeforeCursor(";");
|
|
|
+ var _after = editor.getTextAfterCursor(";");
|
|
|
+ var _statement = _before + _after;
|
|
|
+ var _foundTable = "";
|
|
|
+ if (_before.substr(-1) == "."){ // gets the table alias
|
|
|
+ _foundTable = _before.split(" ").pop().slice(0, -1);
|
|
|
+ }
|
|
|
+ else { // gets the standard table
|
|
|
+ var _from = _statement.toUpperCase().indexOf("FROM");
|
|
|
+ if (_from > -1) {
|
|
|
+ var _match = _statement.toUpperCase().substring(_from).match(/ ON| LIMIT| WHERE| GROUP| SORT| ORDER BY|;/);
|
|
|
+ var _to = _statement.length;
|
|
|
+ if (_match) {
|
|
|
+ _to = _match.index;
|
|
|
+ }
|
|
|
+ var _found = _statement.substr(_from, _to).replace(/(\r\n|\n|\r)/gm, "").replace(/from/gi, "").replace(/join/gi, ",").split(",");
|
|
|
+ }
|
|
|
|
|
|
- function changeEditor(event, editor, valueAccessor) {
|
|
|
- // if it's pig and before it's LOAD ' we disable the autocomplete and show a filechooser btn
|
|
|
- if (editor.session.getMode().$id = "ace/mode/pig") {
|
|
|
+ for (var i = 0; i < _found.length; i++) {
|
|
|
+ if ($.trim(_found[i]) != "" && _foundTable == "") {
|
|
|
+ _foundTable = $.trim(_found[i]).split(" ")[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ if (_foundTable != "") {
|
|
|
+ editor.showSpinner();
|
|
|
+ // fill up with fields
|
|
|
+ AceAutocomplete.getTableColumns(DEFAULT_DB, _foundTable, _statement, function(data){
|
|
|
+ var _fieldNames = data.split(" ");
|
|
|
+ var _fields = [];
|
|
|
+ _fieldNames.forEach(function(fld){
|
|
|
+ _fields.push({value: fld, score: (fld == "*") ? 1001: 1000, meta: "column"});
|
|
|
+ });
|
|
|
+ valueAccessor().extraCompleters([newCompleter(_fields)]);
|
|
|
+ editor.hideSpinner();
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
- else {
|
|
|
-
|
|
|
- if (event.data.text == "."){
|
|
|
- editor.showSpinner();
|
|
|
- // fill up with fields
|
|
|
- hac_getTableColumns("default", "sample_07", editor.getValue(), function(data){
|
|
|
- var _fieldNames = data.split(" ");
|
|
|
- var _fields = [];
|
|
|
- _fieldNames.forEach(function(fld){
|
|
|
- _fields.push({value: fld, score: 1000, meta: "column"});
|
|
|
- });
|
|
|
- valueAccessor().extraCompleters([newCompleter(_fields)]);
|
|
|
- editor.hideSpinner();
|
|
|
- })
|
|
|
+ catch (e) {
|
|
|
}
|
|
|
- else {
|
|
|
- editor.showSpinner();
|
|
|
- valueAccessor().extraCompleters([]);
|
|
|
- hac_getTables("default", function(data){
|
|
|
- var _tableNames = data.split(" ");
|
|
|
- var _tables = [];
|
|
|
- _tableNames.forEach(function(tbl){
|
|
|
- _tables.push({value: tbl, score: 1000, meta: "table"});
|
|
|
+ }
|
|
|
+
|
|
|
+ function onAfterExecHandler(e, editor, valueAccessor) {
|
|
|
+ editor.session.getMode().$id = valueAccessor().mode(); // forces the id again because of Ace command internals
|
|
|
+ if ((editor.session.getMode().$id == "ace/mode/hivesql" || editor.session.getMode().$id == "ace/mode/impalasql") && e.args == "."){
|
|
|
+ fieldsAutocomplete(editor, valueAccessor);
|
|
|
+ }
|
|
|
+ // if it's pig and before it's LOAD ' we disable the autocomplete and show a filechooser btn
|
|
|
+ if (editor.session.getMode().$id = "ace/mode/pig" && e.args) {
|
|
|
+ var _textBefore = editor.getTextBeforeCursor();
|
|
|
+ if ((e.args == "'" && _textBefore.toUpperCase().indexOf("LOAD ") > -1 && _textBefore.toUpperCase().indexOf("LOAD ") == _textBefore.toUpperCase().length - 5)
|
|
|
+ || _textBefore.toUpperCase().indexOf("LOAD '") > -1 && _textBefore.toUpperCase().indexOf("LOAD '") == _textBefore.toUpperCase().length - 6){
|
|
|
+ editor.disableAutocomplete();
|
|
|
+ var _btn = editor.showFileButton();
|
|
|
+ _btn.on("click", function(ie){
|
|
|
+ ie.preventDefault();
|
|
|
+ if ($(".filechooser-content").data("spinner") == null){
|
|
|
+ $(".filechooser-content").data("spinner", $(".filechooser-content").html());
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ $(".filechooser-content").html($(".filechooser-content").data("spinner"));
|
|
|
+ }
|
|
|
+ $(".filechooser-content").jHueFileChooser({
|
|
|
+ onFileChoose: function (filePath) {
|
|
|
+ editor.session.insert(editor.getCursorPosition(), filePath + "'");
|
|
|
+ editor.hideFileButton();
|
|
|
+ editor.enableAutocomplete();
|
|
|
+ $(".filechooser").hide();
|
|
|
+ },
|
|
|
+ selectFolder: false,
|
|
|
+ createFolder: false
|
|
|
+ });
|
|
|
+ $(".filechooser").css({ "top": $(ie.currentTarget).position().top, "left": $(ie.currentTarget).position().left}).show();
|
|
|
});
|
|
|
- valueAccessor().extraCompleters([newCompleter(_tables)]);
|
|
|
- editor.hideSpinner();
|
|
|
- });
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ editor.hideFileButton();
|
|
|
+ editor.enableAutocomplete();
|
|
|
+ }
|
|
|
+ if (e.args != "'" && _textBefore.toUpperCase().indexOf("LOAD '") > -1 && _textBefore.toUpperCase().indexOf("LOAD '") == _textBefore.toUpperCase().length - 6) {
|
|
|
+ editor.hideFileButton();
|
|
|
+ editor.enableAutocomplete();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ function onChangeHandler(event, editor, valueAccessor) {
|
|
|
+ valueAccessor().extraCompleters([]);
|
|
|
+ editor.session.getMode().$id = valueAccessor().mode();
|
|
|
+
|
|
|
+ var _before = editor.getTextBeforeCursor(";");
|
|
|
+ var _beforeU = _before.toUpperCase();
|
|
|
+ var _after = editor.getTextAfterCursor(";");
|
|
|
+ var _afterU = _after.toUpperCase();
|
|
|
+ if (editor.session.getMode().$id == "ace/mode/hivesql" || editor.session.getMode().$id == "ace/mode/impalasql") {
|
|
|
+ if ($.trim(_before).substr(-1) != ".") {
|
|
|
+ if ((_beforeU.indexOf(" FROM ") > -1 || _beforeU.indexOf(" TABLE ") > -1 || _beforeU.indexOf(" STATS ") > -1) && _beforeU.indexOf(" ON ") == -1 && _beforeU.indexOf(" ORDER BY ") == -1 && _beforeU.indexOf(" WHERE ") == -1 ||
|
|
|
+ _beforeU.indexOf("REFRESH") > -1 || _beforeU.indexOf("METADATA") > -1 || _beforeU.indexOf("DESCRIBE") > -1) {
|
|
|
+ editor.showSpinner();
|
|
|
+ valueAccessor().extraCompleters([]);
|
|
|
+ AceAutocomplete.getTables(DEFAULT_DB, function (data) {
|
|
|
+ var _tableNames = data.split(" ");
|
|
|
+ var _tables = [];
|
|
|
+ _tableNames.forEach(function (tbl) {
|
|
|
+ _tables.push({value: tbl, score: 1000, meta: "table"});
|
|
|
+ });
|
|
|
+ valueAccessor().extraCompleters([newCompleter(_tables)]);
|
|
|
+ editor.hideSpinner();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (_beforeU.indexOf("SELECT ") > -1 && _beforeU.indexOf(" FROM ") == -1) { // && !CodeMirror.fromDot
|
|
|
+ if (_afterU.indexOf("FROM ") > -1) {
|
|
|
+ fieldsAutocomplete(editor, valueAccessor);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ console.log("table magic")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if ((_beforeU.indexOf("WHERE") > -1 || _beforeU.indexOf("ORDER BY") > -1) && _beforeU.match(/ ON| LIMIT| GROUP| SORT/) == null) {
|
|
|
+ fieldsAutocomplete(editor, valueAccessor);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ console.log("do other stuff")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -143,9 +235,9 @@ ${ commonheader(_("Notebooks"), "spark", user, "60px") | n,unicode }
|
|
|
## var snippy2 = new Snip("ace/mode/python");
|
|
|
## snippy2.snippet("def nano:");
|
|
|
## viewModel.editors.push(snippy2);
|
|
|
-## var snippy3 = new Snip("ace/mode/hivesql");
|
|
|
-## snippy3.snippet("SELECT * FROM sample_07");
|
|
|
-## viewModel.editors.push(snippy3);
|
|
|
+ var snippy3 = new Snip("ace/mode/hivesql");
|
|
|
+ snippy3.snippet("SELECT * FROM sample_07 sa, web_logs w");
|
|
|
+ viewModel.editors.push(snippy3);
|
|
|
var snippy = new Snip("ace/mode/pig");
|
|
|
snippy.snippet("A = LOAD ''");
|
|
|
viewModel.editors.push(snippy);
|