| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 | // CodeMirror, copyright (c) by Marijn Haverbeke and others// Distributed under an MIT license: http://codemirror.net/LICENSE(function(mod) {  if (typeof exports == "object" && typeof module == "object") // CommonJS    mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));  else if (typeof define == "function" && define.amd) // AMD    define(["../../lib/codemirror", "../../mode/sql/sql"], mod);  else // Plain browser env    mod(CodeMirror);})(function(CodeMirror) {  "use strict";  var tables;  var defaultTable;  var keywords;  var CONS = {    QUERY_DIV: ";",    ALIAS_KEYWORD: "AS"  };  var Pos = CodeMirror.Pos;  function getKeywords(editor) {    var mode = editor.doc.modeOption;    if (mode === "sql") mode = "text/x-sql";    return CodeMirror.resolveMode(mode).keywords;  }  function getText(item) {    return typeof item == "string" ? item : item.text;  }  function getItem(list, item) {    if (!list.slice) return list[item];    for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item)      return list[i];  }  function shallowClone(object) {    var result = {};    for (var key in object) if (object.hasOwnProperty(key))      result[key] = object[key];    return result;  }  function match(string, word) {    var len = string.length;    var sub = getText(word).substr(0, len);    return string.toUpperCase() === sub.toUpperCase();  }  function addMatches(result, search, wordlist, formatter) {    for (var word in wordlist) {      if (!wordlist.hasOwnProperty(word)) continue;      if (Array.isArray(wordlist)) {        word = wordlist[word];      }      if (match(search, word)) {        result.push(formatter(word));      }    }  }  function cleanName(name) {    // Get rid name from backticks(`) and preceding dot(.)    if (name.charAt(0) == ".") {      name = name.substr(1);    }    return name.replace(/`/g, "");  }  function insertBackticks(name) {    var nameParts = getText(name).split(".");    for (var i = 0; i < nameParts.length; i++)      nameParts[i] = "`" + nameParts[i] + "`";    var escaped = nameParts.join(".");    if (typeof name == "string") return escaped;    name = shallowClone(name);    name.text = escaped;    return name;  }  function nameCompletion(cur, token, result, editor) {    // Try to complete table, colunm names and return start position of completion    var useBacktick = false;    var nameParts = [];    var start = token.start;    var cont = true;    while (cont) {      cont = (token.string.charAt(0) == ".");      useBacktick = useBacktick || (token.string.charAt(0) == "`");      start = token.start;      nameParts.unshift(cleanName(token.string));      token = editor.getTokenAt(Pos(cur.line, token.start));      if (token.string == ".") {        cont = true;        token = editor.getTokenAt(Pos(cur.line, token.start));      }    }    // Try to complete table names    var string = nameParts.join(".");    addMatches(result, string, tables, function(w) {      return useBacktick ? insertBackticks(w) : w;    });    // Try to complete columns from defaultTable    addMatches(result, string, defaultTable, function(w) {      return useBacktick ? insertBackticks(w) : w;    });    // Try to complete columns    string = nameParts.pop();    var table = nameParts.join(".");    // Check if table is available. If not, find table by Alias    if (!getItem(tables, table))      table = findTableByAlias(table, editor);    var columns = getItem(tables, table);    if (columns && Array.isArray(tables) && columns.columns)      columns = columns.columns;    if (columns) {      addMatches(result, string, columns, function(w) {        if (typeof w == "string") {          w = table + "." + w;        } else {          w = shallowClone(w);          w.text = table + "." + w.text;        }        return useBacktick ? insertBackticks(w) : w;      });    }    return start;  }  function eachWord(lineText, f) {    if (!lineText) return;    var excepted = /[,;]/g;    var words = lineText.split(" ");    for (var i = 0; i < words.length; i++) {      f(words[i]?words[i].replace(excepted, '') : '');    }  }  function convertCurToNumber(cur) {    // max characters of a line is 999,999.    return cur.line + cur.ch / Math.pow(10, 6);  }  function convertNumberToCur(num) {    return Pos(Math.floor(num), +num.toString().split('.').pop());  }  function findTableByAlias(alias, editor) {    var doc = editor.doc;    var fullQuery = doc.getValue();    var aliasUpperCase = alias.toUpperCase();    var previousWord = "";    var table = "";    var separator = [];    var validRange = {      start: Pos(0, 0),      end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)    };    //add separator    var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);    while(indexOfSeparator != -1) {      separator.push(doc.posFromIndex(indexOfSeparator));      indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);    }    separator.unshift(Pos(0, 0));    separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));    //find valid range    var prevItem = 0;    var current = convertCurToNumber(editor.getCursor());    for (var i=0; i< separator.length; i++) {      var _v = convertCurToNumber(separator[i]);      if (current > prevItem && current <= _v) {        validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) };        break;      }      prevItem = _v;    }    var query = doc.getRange(validRange.start, validRange.end, false);    for (var i = 0; i < query.length; i++) {      var lineText = query[i];      eachWord(lineText, function(word) {        var wordUpperCase = word.toUpperCase();        if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord))          table = previousWord;        if (wordUpperCase !== CONS.ALIAS_KEYWORD)          previousWord = word;      });      if (table) break;    }    return table;  }  CodeMirror.registerHelper("hint", "sql", function(editor, options) {    tables = (options && options.tables) || {};    var defaultTableName = options && options.defaultTable;    defaultTable = (defaultTableName && getItem(tables, defaultTableName)) || [];    keywords = keywords || getKeywords(editor);    var cur = editor.getCursor();    var result = [];    var token = editor.getTokenAt(cur), start, end, search;    if (token.end > cur.ch) {      token.end = cur.ch;      token.string = token.string.slice(0, cur.ch - token.start);    }    if (token.string.match(/^[.`\w@]\w*$/)) {      search = token.string;      start = token.start;      end = token.end;    } else {      start = end = cur.ch;      search = "";    }    if (search.charAt(0) == "." || search.charAt(0) == "`") {      start = nameCompletion(cur, token, result, editor);    } else {      addMatches(result, search, tables, function(w) {return w;});      addMatches(result, search, defaultTable, function(w) {return w;});      addMatches(result, search, keywords, function(w) {return w.toUpperCase();});    }    return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};  });});
 |