codemirror-sql-hint.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. (function () {
  2. "use strict";
  3. var tables;
  4. var keywords;
  5. function getKeywords(editor) {
  6. var mode = editor.doc.modeOption;
  7. if(mode === "sql") mode = "text/x-sql";
  8. return CodeMirror.resolveMode(mode).keywords;
  9. }
  10. function match(string, word) {
  11. var len = string.length;
  12. var sub = word.substr(0, len);
  13. return string.toUpperCase() === sub.toUpperCase();
  14. }
  15. function addMatches(result, search, wordlist, formatter) {
  16. for(var word in wordlist) {
  17. if(!wordlist.hasOwnProperty(word)) continue;
  18. if(Array.isArray(wordlist)) {
  19. word = wordlist[word];
  20. }
  21. if(match(search, word)) {
  22. result.push(formatter(word));
  23. }
  24. }
  25. }
  26. function columnCompletion(result, editor) {
  27. var cur = editor.getCursor();
  28. var token = editor.getTokenAt(cur);
  29. var string = token.string.substr(1);
  30. var prevCur = CodeMirror.Pos(cur.line, token.start);
  31. var table = editor.getTokenAt(prevCur).string;
  32. var columns = tables[table];
  33. if(!columns) {
  34. table = findTableByAlias(table, editor);
  35. }
  36. columns = tables[table];
  37. if(!columns) {
  38. return;
  39. }
  40. addMatches(result, string, columns,
  41. function(w) {return "." + w;});
  42. }
  43. function eachWord(line, f) {
  44. var words = line.text.split(" ");
  45. for(var i = 0; i < words.length; i++) {
  46. f(words[i]);
  47. }
  48. }
  49. // Tries to find possible table name from alias.
  50. function findTableByAlias(alias, editor) {
  51. var aliasUpperCase = alias.toUpperCase();
  52. var previousWord = "";
  53. var table = "";
  54. editor.eachLine(function(line) {
  55. eachWord(line, function(word) {
  56. var wordUpperCase = word.toUpperCase();
  57. if(wordUpperCase === aliasUpperCase) {
  58. if(tables.hasOwnProperty(previousWord)) {
  59. table = previousWord;
  60. }
  61. }
  62. if(wordUpperCase !== "AS") {
  63. previousWord = word;
  64. }
  65. });
  66. });
  67. return table;
  68. }
  69. function sqlHint(editor, options) {
  70. tables = (options && options.tables) || {};
  71. keywords = keywords || getKeywords(editor);
  72. var cur = editor.getCursor();
  73. var token = editor.getTokenAt(cur);
  74. var result = [];
  75. var search = token.string.trim();
  76. addMatches(result, search, keywords,
  77. function(w) {return w.toUpperCase();});
  78. addMatches(result, search, tables,
  79. function(w) {return w;});
  80. if(search.lastIndexOf('.') === 0) {
  81. columnCompletion(result, editor);
  82. }
  83. return {
  84. list: result,
  85. from: CodeMirror.Pos(cur.line, token.start),
  86. to: CodeMirror.Pos(cur.line, token.end)
  87. };
  88. }
  89. CodeMirror.sqlHint = sqlHint;
  90. })();