| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- (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 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 match(string, word) {
- var len = string.length;
- var sub = 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 columnCompletion(result, editor) {
- var cur = editor.getCursor();
- var token = editor.getTokenAt(cur);
- var string = token.string.substr(1);
- var prevCur = Pos(cur.line, token.start);
- var table = editor.getTokenAt(prevCur).string;
- if( !tables.hasOwnProperty( table ) ){
- table = findTableByAlias(table, editor);
- }
- var columns = tables[table];
- if(!columns) {
- return;
- }
- addMatches(result, string, columns,
- function(w) {return "." + w;});
- }
- 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 valieRange
- 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 && tables.hasOwnProperty( previousWord ) ){
- table = previousWord;
- }
- if( wordUpperCase !== CONS.ALIAS_KEYWORD ){
- previousWord = word;
- }
- });
- if( table ){ break; }
- }
- return table;
- }
- function sqlHint(editor, options) {
- tables = (options && options.tables) || {};
- keywords = keywords || getKeywords(editor);
- var cur = editor.getCursor();
- var token = editor.getTokenAt(cur), end = token.end;
- var result = [];
- var search = token.string.trim();
- if (search.charAt(0) == ".") {
- columnCompletion(result, editor);
- if (!result.length) {
- while (token.start && search.charAt(0) == ".") {
- token = editor.getTokenAt(Pos(cur.line, token.start - 1));
- search = token.string + search;
- }
- addMatches(result, search, tables,
- function(w) {return w;});
- }
- } else {
- addMatches(result, search, keywords,
- function(w) {return w.toUpperCase();});
- addMatches(result, search, tables,
- function(w) {return w;});
- }
- return {
- list: result,
- from: Pos(cur.line, token.start),
- to: Pos(cur.line, end)
- };
- }
- CodeMirror.registerHelper("hint", "sql", sqlHint);
- });
|