source: OpenRLabs-Git/deploy/rlabs-docker/web2py-rlabs/applications/admin/static/codemirror/addon/hint/sql-hint.js

main
Last change on this file was 42bd667, checked in by David Fuertes <dfuertes@…>, 4 years ago

Historial Limpio

  • Property mode set to 100755
File size: 7.1 KB
Line 
1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: http://codemirror.net/LICENSE
3
4(function(mod) {
5  if (typeof exports == "object" && typeof module == "object") // CommonJS
6    mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
7  else if (typeof define == "function" && define.amd) // AMD
8    define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
9  else // Plain browser env
10    mod(CodeMirror);
11})(function(CodeMirror) {
12  "use strict";
13
14  var tables;
15  var defaultTable;
16  var keywords;
17  var CONS = {
18    QUERY_DIV: ";",
19    ALIAS_KEYWORD: "AS"
20  };
21  var Pos = CodeMirror.Pos;
22
23  function getKeywords(editor) {
24    var mode = editor.doc.modeOption;
25    if (mode === "sql") mode = "text/x-sql";
26    return CodeMirror.resolveMode(mode).keywords;
27  }
28
29  function getText(item) {
30    return typeof item == "string" ? item : item.text;
31  }
32
33  function getItem(list, item) {
34    if (!list.slice) return list[item];
35    for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item)
36      return list[i];
37  }
38
39  function shallowClone(object) {
40    var result = {};
41    for (var key in object) if (object.hasOwnProperty(key))
42      result[key] = object[key];
43    return result;
44  }
45
46  function match(string, word) {
47    var len = string.length;
48    var sub = getText(word).substr(0, len);
49    return string.toUpperCase() === sub.toUpperCase();
50  }
51
52  function addMatches(result, search, wordlist, formatter) {
53    for (var word in wordlist) {
54      if (!wordlist.hasOwnProperty(word)) continue;
55      if (Array.isArray(wordlist)) {
56        word = wordlist[word];
57      }
58      if (match(search, word)) {
59        result.push(formatter(word));
60      }
61    }
62  }
63
64  function cleanName(name) {
65    // Get rid name from backticks(`) and preceding dot(.)
66    if (name.charAt(0) == ".") {
67      name = name.substr(1);
68    }
69    return name.replace(/`/g, "");
70  }
71
72  function insertBackticks(name) {
73    var nameParts = getText(name).split(".");
74    for (var i = 0; i < nameParts.length; i++)
75      nameParts[i] = "`" + nameParts[i] + "`";
76    var escaped = nameParts.join(".");
77    if (typeof name == "string") return escaped;
78    name = shallowClone(name);
79    name.text = escaped;
80    return name;
81  }
82
83  function nameCompletion(cur, token, result, editor) {
84    // Try to complete table, colunm names and return start position of completion
85    var useBacktick = false;
86    var nameParts = [];
87    var start = token.start;
88    var cont = true;
89    while (cont) {
90      cont = (token.string.charAt(0) == ".");
91      useBacktick = useBacktick || (token.string.charAt(0) == "`");
92
93      start = token.start;
94      nameParts.unshift(cleanName(token.string));
95
96      token = editor.getTokenAt(Pos(cur.line, token.start));
97      if (token.string == ".") {
98        cont = true;
99        token = editor.getTokenAt(Pos(cur.line, token.start));
100      }
101    }
102
103    // Try to complete table names
104    var string = nameParts.join(".");
105    addMatches(result, string, tables, function(w) {
106      return useBacktick ? insertBackticks(w) : w;
107    });
108
109    // Try to complete columns from defaultTable
110    addMatches(result, string, defaultTable, function(w) {
111      return useBacktick ? insertBackticks(w) : w;
112    });
113
114    // Try to complete columns
115    string = nameParts.pop();
116    var table = nameParts.join(".");
117
118    // Check if table is available. If not, find table by Alias
119    if (!getItem(tables, table))
120      table = findTableByAlias(table, editor);
121
122    var columns = getItem(tables, table);
123    if (columns && Array.isArray(tables) && columns.columns)
124      columns = columns.columns;
125
126    if (columns) {
127      addMatches(result, string, columns, function(w) {
128        if (typeof w == "string") {
129          w = table + "." + w;
130        } else {
131          w = shallowClone(w);
132          w.text = table + "." + w.text;
133        }
134        return useBacktick ? insertBackticks(w) : w;
135      });
136    }
137
138    return start;
139  }
140
141  function eachWord(lineText, f) {
142    if (!lineText) return;
143    var excepted = /[,;]/g;
144    var words = lineText.split(" ");
145    for (var i = 0; i < words.length; i++) {
146      f(words[i]?words[i].replace(excepted, '') : '');
147    }
148  }
149
150  function convertCurToNumber(cur) {
151    // max characters of a line is 999,999.
152    return cur.line + cur.ch / Math.pow(10, 6);
153  }
154
155  function convertNumberToCur(num) {
156    return Pos(Math.floor(num), +num.toString().split('.').pop());
157  }
158
159  function findTableByAlias(alias, editor) {
160    var doc = editor.doc;
161    var fullQuery = doc.getValue();
162    var aliasUpperCase = alias.toUpperCase();
163    var previousWord = "";
164    var table = "";
165    var separator = [];
166    var validRange = {
167      start: Pos(0, 0),
168      end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
169    };
170
171    //add separator
172    var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
173    while(indexOfSeparator != -1) {
174      separator.push(doc.posFromIndex(indexOfSeparator));
175      indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
176    }
177    separator.unshift(Pos(0, 0));
178    separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
179
180    //find valid range
181    var prevItem = 0;
182    var current = convertCurToNumber(editor.getCursor());
183    for (var i=0; i< separator.length; i++) {
184      var _v = convertCurToNumber(separator[i]);
185      if (current > prevItem && current <= _v) {
186        validRange = { start: convertNumberToCur(prevItem), end: convertNumberToCur(_v) };
187        break;
188      }
189      prevItem = _v;
190    }
191
192    var query = doc.getRange(validRange.start, validRange.end, false);
193
194    for (var i = 0; i < query.length; i++) {
195      var lineText = query[i];
196      eachWord(lineText, function(word) {
197        var wordUpperCase = word.toUpperCase();
198        if (wordUpperCase === aliasUpperCase && getItem(tables, previousWord))
199          table = previousWord;
200        if (wordUpperCase !== CONS.ALIAS_KEYWORD)
201          previousWord = word;
202      });
203      if (table) break;
204    }
205    return table;
206  }
207
208  CodeMirror.registerHelper("hint", "sql", function(editor, options) {
209    tables = (options && options.tables) || {};
210    var defaultTableName = options && options.defaultTable;
211    defaultTable = (defaultTableName && getItem(tables, defaultTableName)) || [];
212    keywords = keywords || getKeywords(editor);
213
214    var cur = editor.getCursor();
215    var result = [];
216    var token = editor.getTokenAt(cur), start, end, search;
217    if (token.end > cur.ch) {
218      token.end = cur.ch;
219      token.string = token.string.slice(0, cur.ch - token.start);
220    }
221
222    if (token.string.match(/^[.`\w@]\w*$/)) {
223      search = token.string;
224      start = token.start;
225      end = token.end;
226    } else {
227      start = end = cur.ch;
228      search = "";
229    }
230    if (search.charAt(0) == "." || search.charAt(0) == "`") {
231      start = nameCompletion(cur, token, result, editor);
232    } else {
233      addMatches(result, search, tables, function(w) {return w;});
234      addMatches(result, search, defaultTable, function(w) {return w;});
235      addMatches(result, search, keywords, function(w) {return w.toUpperCase();});
236    }
237
238    return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
239  });
240});
Note: See TracBrowser for help on using the repository browser.