[Core] [AI] Support chatgpt for query (#284)

This commit is contained in:
qianmoQ 2023-03-14 23:00:39 +08:00 committed by GitHub
commit a8e9f20db8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 1075 additions and 775 deletions

1
.gitignore vendored
View File

@ -41,3 +41,4 @@ tmp/
.vscode
dist/datacap/
list
*.configure

View File

@ -50,6 +50,7 @@ STRING
IDENTIFIER
: (LETTER | DIGIT | '_')+
;
BACKQUOTED_IDENTIFIER
: '`' ( ~'`' | '``' )* '`'
;

View File

@ -48,4 +48,4 @@ quotedIdentifier
atn:
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 16, 86, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 3, 2, 7, 2, 28, 10, 2, 12, 2, 14, 2, 31, 11, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 40, 10, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 50, 10, 5, 3, 6, 3, 6, 5, 6, 54, 10, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 5, 8, 61, 10, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 7, 11, 71, 10, 11, 12, 11, 14, 11, 74, 11, 11, 3, 12, 3, 12, 3, 12, 7, 12, 79, 10, 12, 12, 12, 14, 12, 82, 11, 12, 3, 13, 3, 13, 3, 13, 2, 2, 14, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 2, 2, 2, 83, 2, 29, 3, 2, 2, 2, 4, 39, 3, 2, 2, 2, 6, 41, 3, 2, 2, 2, 8, 49, 3, 2, 2, 2, 10, 53, 3, 2, 2, 2, 12, 55, 3, 2, 2, 2, 14, 60, 3, 2, 2, 2, 16, 62, 3, 2, 2, 2, 18, 64, 3, 2, 2, 2, 20, 67, 3, 2, 2, 2, 22, 80, 3, 2, 2, 2, 24, 83, 3, 2, 2, 2, 26, 28, 5, 4, 3, 2, 27, 26, 3, 2, 2, 2, 28, 31, 3, 2, 2, 2, 29, 27, 3, 2, 2, 2, 29, 30, 3, 2, 2, 2, 30, 3, 3, 2, 2, 2, 31, 29, 3, 2, 2, 2, 32, 33, 7, 4, 2, 2, 33, 40, 5, 14, 8, 2, 34, 35, 7, 8, 2, 2, 35, 36, 5, 16, 9, 2, 36, 37, 5, 18, 10, 2, 37, 40, 3, 2, 2, 2, 38, 40, 5, 12, 7, 2, 39, 32, 3, 2, 2, 2, 39, 34, 3, 2, 2, 2, 39, 38, 3, 2, 2, 2, 40, 5, 3, 2, 2, 2, 41, 42, 7, 4, 2, 2, 42, 43, 7, 6, 2, 2, 43, 7, 3, 2, 2, 2, 44, 45, 7, 4, 2, 2, 45, 50, 7, 7, 2, 2, 46, 47, 7, 4, 2, 2, 47, 48, 7, 7, 2, 2, 48, 50, 5, 18, 10, 2, 49, 44, 3, 2, 2, 2, 49, 46, 3, 2, 2, 2, 50, 9, 3, 2, 2, 2, 51, 54, 5, 6, 4, 2, 52, 54, 5, 8, 5, 2, 53, 51, 3, 2, 2, 2, 53, 52, 3, 2, 2, 2, 54, 11, 3, 2, 2, 2, 55, 56, 5, 10, 6, 2, 56, 13, 3, 2, 2, 2, 57, 61, 7, 5, 2, 2, 58, 59, 7, 5, 2, 2, 59, 61, 5, 18, 10, 2, 60, 57, 3, 2, 2, 2, 60, 58, 3, 2, 2, 2, 61, 15, 3, 2, 2, 2, 62, 63, 5, 22, 12, 2, 63, 17, 3, 2, 2, 2, 64, 65, 7, 9, 2, 2, 65, 66, 5, 20, 11, 2, 66, 19, 3, 2, 2, 2, 67, 72, 5, 22, 12, 2, 68, 69, 7, 3, 2, 2, 69, 71, 5, 22, 12, 2, 70, 68, 3, 2, 2, 2, 71, 74, 3, 2, 2, 2, 72, 70, 3, 2, 2, 2, 72, 73, 3, 2, 2, 2, 73, 21, 3, 2, 2, 2, 74, 72, 3, 2, 2, 2, 75, 79, 7, 11, 2, 2, 76, 79, 7, 10, 2, 2, 77, 79, 5, 24, 13, 2, 78, 75, 3, 2, 2, 2, 78, 76, 3, 2, 2, 2, 78, 77, 3, 2, 2, 2, 79, 82, 3, 2, 2, 2, 80, 78, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 23, 3, 2, 2, 2, 82, 80, 3, 2, 2, 2, 83, 84, 7, 12, 2, 2, 84, 25, 3, 2, 2, 2, 10, 29, 39, 49, 53, 60, 72, 78, 80]
[4, 1, 14, 84, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 1, 0, 5, 0, 26, 8, 0, 10, 0, 12, 0, 29, 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 38, 8, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 48, 8, 3, 1, 4, 1, 4, 3, 4, 52, 8, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 3, 6, 59, 8, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 5, 9, 69, 8, 9, 10, 9, 12, 9, 72, 9, 9, 1, 10, 1, 10, 1, 10, 5, 10, 77, 8, 10, 10, 10, 12, 10, 80, 9, 10, 1, 11, 1, 11, 1, 11, 0, 0, 12, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 0, 0, 81, 0, 27, 1, 0, 0, 0, 2, 37, 1, 0, 0, 0, 4, 39, 1, 0, 0, 0, 6, 47, 1, 0, 0, 0, 8, 51, 1, 0, 0, 0, 10, 53, 1, 0, 0, 0, 12, 58, 1, 0, 0, 0, 14, 60, 1, 0, 0, 0, 16, 62, 1, 0, 0, 0, 18, 65, 1, 0, 0, 0, 20, 78, 1, 0, 0, 0, 22, 81, 1, 0, 0, 0, 24, 26, 3, 2, 1, 0, 25, 24, 1, 0, 0, 0, 26, 29, 1, 0, 0, 0, 27, 25, 1, 0, 0, 0, 27, 28, 1, 0, 0, 0, 28, 1, 1, 0, 0, 0, 29, 27, 1, 0, 0, 0, 30, 31, 5, 2, 0, 0, 31, 38, 3, 12, 6, 0, 32, 33, 5, 6, 0, 0, 33, 34, 3, 14, 7, 0, 34, 35, 3, 16, 8, 0, 35, 38, 1, 0, 0, 0, 36, 38, 3, 10, 5, 0, 37, 30, 1, 0, 0, 0, 37, 32, 1, 0, 0, 0, 37, 36, 1, 0, 0, 0, 38, 3, 1, 0, 0, 0, 39, 40, 5, 2, 0, 0, 40, 41, 5, 4, 0, 0, 41, 5, 1, 0, 0, 0, 42, 43, 5, 2, 0, 0, 43, 48, 5, 5, 0, 0, 44, 45, 5, 2, 0, 0, 45, 46, 5, 5, 0, 0, 46, 48, 3, 16, 8, 0, 47, 42, 1, 0, 0, 0, 47, 44, 1, 0, 0, 0, 48, 7, 1, 0, 0, 0, 49, 52, 3, 4, 2, 0, 50, 52, 3, 6, 3, 0, 51, 49, 1, 0, 0, 0, 51, 50, 1, 0, 0, 0, 52, 9, 1, 0, 0, 0, 53, 54, 3, 8, 4, 0, 54, 11, 1, 0, 0, 0, 55, 59, 5, 3, 0, 0, 56, 57, 5, 3, 0, 0, 57, 59, 3, 16, 8, 0, 58, 55, 1, 0, 0, 0, 58, 56, 1, 0, 0, 0, 59, 13, 1, 0, 0, 0, 60, 61, 3, 20, 10, 0, 61, 15, 1, 0, 0, 0, 62, 63, 5, 7, 0, 0, 63, 64, 3, 18, 9, 0, 64, 17, 1, 0, 0, 0, 65, 70, 3, 20, 10, 0, 66, 67, 5, 1, 0, 0, 67, 69, 3, 20, 10, 0, 68, 66, 1, 0, 0, 0, 69, 72, 1, 0, 0, 0, 70, 68, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 19, 1, 0, 0, 0, 72, 70, 1, 0, 0, 0, 73, 77, 5, 9, 0, 0, 74, 77, 5, 8, 0, 0, 75, 77, 3, 22, 11, 0, 76, 73, 1, 0, 0, 0, 76, 74, 1, 0, 0, 0, 76, 75, 1, 0, 0, 0, 77, 80, 1, 0, 0, 0, 78, 76, 1, 0, 0, 0, 78, 79, 1, 0, 0, 0, 79, 21, 1, 0, 0, 0, 80, 78, 1, 0, 0, 0, 81, 82, 5, 10, 0, 0, 82, 23, 1, 0, 0, 0, 8, 27, 37, 47, 51, 58, 70, 76, 78]

View File

@ -1,4 +1,4 @@
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.9.3
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.12.0
package io.edurt.datacap.sql.parser;
import org.antlr.v4.runtime.ParserRuleContext;
@ -10,6 +10,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
* which can be extended to create a listener which only needs to handle a subset
* of the available methods.
*/
@SuppressWarnings("CheckReturnValue")
public class SqlBaseBaseListener implements SqlBaseListener {
/**
* {@inheritDoc}

View File

@ -1,4 +1,4 @@
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.9.3
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.12.0
package io.edurt.datacap.sql.parser;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
@ -10,6 +10,7 @@ import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
@SuppressWarnings("CheckReturnValue")
public class SqlBaseBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements SqlBaseVisitor<T> {
/**
* {@inheritDoc}

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.9.3
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.12.0
package io.edurt.datacap.sql.parser;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
@ -9,9 +9,9 @@ import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"})
public class SqlBaseLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); }
static { RuntimeMetaData.checkVersion("4.12.0", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
@ -110,58 +110,110 @@ public class SqlBaseLexer extends Lexer {
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2\20\u00a8\b\1\4\2"+
"\t\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4"+
"\13\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\3\2\3"+
"\2\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5"+
"\3\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3"+
"\7\3\b\3\b\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\13\3\13\3\13\3\13\7\13V\n\13"+
"\f\13\16\13Y\13\13\3\13\3\13\3\13\3\13\3\13\7\13`\n\13\f\13\16\13c\13"+
"\13\3\13\3\13\5\13g\n\13\3\f\3\f\3\f\6\fl\n\f\r\f\16\fm\3\r\3\r\3\r\3"+
"\r\7\rt\n\r\f\r\16\rw\13\r\3\r\3\r\3\16\3\16\3\16\3\16\7\16\177\n\16\f"+
"\16\16\16\u0082\13\16\3\16\5\16\u0085\n\16\3\16\5\16\u0088\n\16\3\16\3"+
"\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\7\20\u0098"+
"\n\20\f\20\16\20\u009b\13\20\3\20\3\20\3\20\3\20\3\20\3\21\6\21\u00a3"+
"\n\21\r\21\16\21\u00a4\3\21\3\21\3\u0099\2\22\3\3\5\4\7\5\t\6\13\7\r\b"+
"\17\t\21\2\23\2\25\n\27\13\31\f\33\r\35\16\37\17!\20\3\2\27\4\2UUuu\4"+
"\2JJjj\4\2QQqq\4\2YYyy\4\2RRrr\4\2CCcc\4\2VVvv\4\2GGgg\4\2NNnn\4\2EEe"+
"e\4\2HHhh\4\2TTtt\4\2OOoo\3\2\62;\4\2C\\c|\4\2))^^\4\2$$^^\3\2bb\4\2\f"+
"\f\17\17\3\2--\5\2\13\f\17\17\"\"\2\u00b5\2\3\3\2\2\2\2\5\3\2\2\2\2\7"+
"\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\25\3\2\2"+
"\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2"+
"!\3\2\2\2\3#\3\2\2\2\5%\3\2\2\2\7*\3\2\2\2\t\60\3\2\2\2\13\67\3\2\2\2"+
"\rA\3\2\2\2\17H\3\2\2\2\21M\3\2\2\2\23O\3\2\2\2\25f\3\2\2\2\27k\3\2\2"+
"\2\31o\3\2\2\2\33z\3\2\2\2\35\u008b\3\2\2\2\37\u0092\3\2\2\2!\u00a2\3"+
"\2\2\2#$\7\60\2\2$\4\3\2\2\2%&\t\2\2\2&\'\t\3\2\2\'(\t\4\2\2()\t\5\2\2"+
")\6\3\2\2\2*+\t\6\2\2+,\t\7\2\2,-\t\b\2\2-.\t\3\2\2./\t\2\2\2/\b\3\2\2"+
"\2\60\61\7V\2\2\61\62\7Q\2\2\62\63\7R\2\2\63\64\7K\2\2\64\65\7E\2\2\65"+
"\66\7U\2\2\66\n\3\2\2\2\678\7E\2\289\7Q\2\29:\7P\2\2:;\7U\2\2;<\7W\2\2"+
"<=\7O\2\2=>\7G\2\2>?\7T\2\2?@\7U\2\2@\f\3\2\2\2AB\t\2\2\2BC\t\t\2\2CD"+
"\t\n\2\2DE\t\t\2\2EF\t\13\2\2FG\t\b\2\2G\16\3\2\2\2HI\t\f\2\2IJ\t\r\2"+
"\2JK\t\4\2\2KL\t\16\2\2L\20\3\2\2\2MN\t\17\2\2N\22\3\2\2\2OP\t\20\2\2"+
"P\24\3\2\2\2QW\7)\2\2RV\n\21\2\2ST\7^\2\2TV\13\2\2\2UR\3\2\2\2US\3\2\2"+
"\2VY\3\2\2\2WU\3\2\2\2WX\3\2\2\2XZ\3\2\2\2YW\3\2\2\2Zg\7)\2\2[a\7$\2\2"+
"\\`\n\22\2\2]^\7^\2\2^`\13\2\2\2_\\\3\2\2\2_]\3\2\2\2`c\3\2\2\2a_\3\2"+
"\2\2ab\3\2\2\2bd\3\2\2\2ca\3\2\2\2dg\7$\2\2eg\7,\2\2fQ\3\2\2\2f[\3\2\2"+
"\2fe\3\2\2\2g\26\3\2\2\2hl\5\23\n\2il\5\21\t\2jl\7a\2\2kh\3\2\2\2ki\3"+
"\2\2\2kj\3\2\2\2lm\3\2\2\2mk\3\2\2\2mn\3\2\2\2n\30\3\2\2\2ou\7b\2\2pt"+
"\n\23\2\2qr\7b\2\2rt\7b\2\2sp\3\2\2\2sq\3\2\2\2tw\3\2\2\2us\3\2\2\2uv"+
"\3\2\2\2vx\3\2\2\2wu\3\2\2\2xy\7b\2\2y\32\3\2\2\2z{\7/\2\2{|\7/\2\2|\u0080"+
"\3\2\2\2}\177\n\24\2\2~}\3\2\2\2\177\u0082\3\2\2\2\u0080~\3\2\2\2\u0080"+
"\u0081\3\2\2\2\u0081\u0084\3\2\2\2\u0082\u0080\3\2\2\2\u0083\u0085\7\17"+
"\2\2\u0084\u0083\3\2\2\2\u0084\u0085\3\2\2\2\u0085\u0087\3\2\2\2\u0086"+
"\u0088\7\f\2\2\u0087\u0086\3\2\2\2\u0087\u0088\3\2\2\2\u0088\u0089\3\2"+
"\2\2\u0089\u008a\b\16\2\2\u008a\34\3\2\2\2\u008b\u008c\7\61\2\2\u008c"+
"\u008d\7,\2\2\u008d\u008e\7,\2\2\u008e\u008f\7\61\2\2\u008f\u0090\3\2"+
"\2\2\u0090\u0091\b\17\2\2\u0091\36\3\2\2\2\u0092\u0093\7\61\2\2\u0093"+
"\u0094\7,\2\2\u0094\u0095\3\2\2\2\u0095\u0099\n\25\2\2\u0096\u0098\13"+
"\2\2\2\u0097\u0096\3\2\2\2\u0098\u009b\3\2\2\2\u0099\u009a\3\2\2\2\u0099"+
"\u0097\3\2\2\2\u009a\u009c\3\2\2\2\u009b\u0099\3\2\2\2\u009c\u009d\7,"+
"\2\2\u009d\u009e\7\61\2\2\u009e\u009f\3\2\2\2\u009f\u00a0\b\20\2\2\u00a0"+
" \3\2\2\2\u00a1\u00a3\t\26\2\2\u00a2\u00a1\3\2\2\2\u00a3\u00a4\3\2\2\2"+
"\u00a4\u00a2\3\2\2\2\u00a4\u00a5\3\2\2\2\u00a5\u00a6\3\2\2\2\u00a6\u00a7"+
"\b\21\2\2\u00a7\"\3\2\2\2\21\2UW_afkmsu\u0080\u0084\u0087\u0099\u00a4"+
"\3\2\3\2";
"\u0004\u0000\u000e\u00a6\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002"+
"\u0001\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002"+
"\u0004\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002"+
"\u0007\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002"+
"\u000b\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e"+
"\u0002\u000f\u0007\u000f\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001"+
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002"+
"\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0003"+
"\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004"+
"\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004\u0001\u0004"+
"\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0005"+
"\u0001\u0005\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0006"+
"\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\b\u0001\b\u0001"+
"\t\u0001\t\u0001\t\u0001\t\u0005\tT\b\t\n\t\f\tW\t\t\u0001\t\u0001\t\u0001"+
"\t\u0001\t\u0001\t\u0005\t^\b\t\n\t\f\ta\t\t\u0001\t\u0001\t\u0003\te"+
"\b\t\u0001\n\u0001\n\u0001\n\u0004\nj\b\n\u000b\n\f\nk\u0001\u000b\u0001"+
"\u000b\u0001\u000b\u0001\u000b\u0005\u000br\b\u000b\n\u000b\f\u000bu\t"+
"\u000b\u0001\u000b\u0001\u000b\u0001\f\u0001\f\u0001\f\u0001\f\u0005\f"+
"}\b\f\n\f\f\f\u0080\t\f\u0001\f\u0003\f\u0083\b\f\u0001\f\u0003\f\u0086"+
"\b\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+
"\r\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0001\u000e\u0005\u000e"+
"\u0096\b\u000e\n\u000e\f\u000e\u0099\t\u000e\u0001\u000e\u0001\u000e\u0001"+
"\u000e\u0001\u000e\u0001\u000e\u0001\u000f\u0004\u000f\u00a1\b\u000f\u000b"+
"\u000f\f\u000f\u00a2\u0001\u000f\u0001\u000f\u0001\u0097\u0000\u0010\u0001"+
"\u0001\u0003\u0002\u0005\u0003\u0007\u0004\t\u0005\u000b\u0006\r\u0007"+
"\u000f\u0000\u0011\u0000\u0013\b\u0015\t\u0017\n\u0019\u000b\u001b\f\u001d"+
"\r\u001f\u000e\u0001\u0000\u0015\u0002\u0000SSss\u0002\u0000HHhh\u0002"+
"\u0000OOoo\u0002\u0000WWww\u0002\u0000PPpp\u0002\u0000AAaa\u0002\u0000"+
"TTtt\u0002\u0000EEee\u0002\u0000LLll\u0002\u0000CCcc\u0002\u0000FFff\u0002"+
"\u0000RRrr\u0002\u0000MMmm\u0001\u000009\u0002\u0000AZaz\u0002\u0000\'"+
"\'\\\\\u0002\u0000\"\"\\\\\u0001\u0000``\u0002\u0000\n\n\r\r\u0001\u0000"+
"++\u0003\u0000\t\n\r\r \u00b3\u0000\u0001\u0001\u0000\u0000\u0000\u0000"+
"\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000"+
"\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b"+
"\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u0013\u0001"+
"\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001"+
"\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001"+
"\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001"+
"\u0000\u0000\u0000\u0001!\u0001\u0000\u0000\u0000\u0003#\u0001\u0000\u0000"+
"\u0000\u0005(\u0001\u0000\u0000\u0000\u0007.\u0001\u0000\u0000\u0000\t"+
"5\u0001\u0000\u0000\u0000\u000b?\u0001\u0000\u0000\u0000\rF\u0001\u0000"+
"\u0000\u0000\u000fK\u0001\u0000\u0000\u0000\u0011M\u0001\u0000\u0000\u0000"+
"\u0013d\u0001\u0000\u0000\u0000\u0015i\u0001\u0000\u0000\u0000\u0017m"+
"\u0001\u0000\u0000\u0000\u0019x\u0001\u0000\u0000\u0000\u001b\u0089\u0001"+
"\u0000\u0000\u0000\u001d\u0090\u0001\u0000\u0000\u0000\u001f\u00a0\u0001"+
"\u0000\u0000\u0000!\"\u0005.\u0000\u0000\"\u0002\u0001\u0000\u0000\u0000"+
"#$\u0007\u0000\u0000\u0000$%\u0007\u0001\u0000\u0000%&\u0007\u0002\u0000"+
"\u0000&\'\u0007\u0003\u0000\u0000\'\u0004\u0001\u0000\u0000\u0000()\u0007"+
"\u0004\u0000\u0000)*\u0007\u0005\u0000\u0000*+\u0007\u0006\u0000\u0000"+
"+,\u0007\u0001\u0000\u0000,-\u0007\u0000\u0000\u0000-\u0006\u0001\u0000"+
"\u0000\u0000./\u0005T\u0000\u0000/0\u0005O\u0000\u000001\u0005P\u0000"+
"\u000012\u0005I\u0000\u000023\u0005C\u0000\u000034\u0005S\u0000\u0000"+
"4\b\u0001\u0000\u0000\u000056\u0005C\u0000\u000067\u0005O\u0000\u0000"+
"78\u0005N\u0000\u000089\u0005S\u0000\u00009:\u0005U\u0000\u0000:;\u0005"+
"M\u0000\u0000;<\u0005E\u0000\u0000<=\u0005R\u0000\u0000=>\u0005S\u0000"+
"\u0000>\n\u0001\u0000\u0000\u0000?@\u0007\u0000\u0000\u0000@A\u0007\u0007"+
"\u0000\u0000AB\u0007\b\u0000\u0000BC\u0007\u0007\u0000\u0000CD\u0007\t"+
"\u0000\u0000DE\u0007\u0006\u0000\u0000E\f\u0001\u0000\u0000\u0000FG\u0007"+
"\n\u0000\u0000GH\u0007\u000b\u0000\u0000HI\u0007\u0002\u0000\u0000IJ\u0007"+
"\f\u0000\u0000J\u000e\u0001\u0000\u0000\u0000KL\u0007\r\u0000\u0000L\u0010"+
"\u0001\u0000\u0000\u0000MN\u0007\u000e\u0000\u0000N\u0012\u0001\u0000"+
"\u0000\u0000OU\u0005\'\u0000\u0000PT\b\u000f\u0000\u0000QR\u0005\\\u0000"+
"\u0000RT\t\u0000\u0000\u0000SP\u0001\u0000\u0000\u0000SQ\u0001\u0000\u0000"+
"\u0000TW\u0001\u0000\u0000\u0000US\u0001\u0000\u0000\u0000UV\u0001\u0000"+
"\u0000\u0000VX\u0001\u0000\u0000\u0000WU\u0001\u0000\u0000\u0000Xe\u0005"+
"\'\u0000\u0000Y_\u0005\"\u0000\u0000Z^\b\u0010\u0000\u0000[\\\u0005\\"+
"\u0000\u0000\\^\t\u0000\u0000\u0000]Z\u0001\u0000\u0000\u0000][\u0001"+
"\u0000\u0000\u0000^a\u0001\u0000\u0000\u0000_]\u0001\u0000\u0000\u0000"+
"_`\u0001\u0000\u0000\u0000`b\u0001\u0000\u0000\u0000a_\u0001\u0000\u0000"+
"\u0000be\u0005\"\u0000\u0000ce\u0005*\u0000\u0000dO\u0001\u0000\u0000"+
"\u0000dY\u0001\u0000\u0000\u0000dc\u0001\u0000\u0000\u0000e\u0014\u0001"+
"\u0000\u0000\u0000fj\u0003\u0011\b\u0000gj\u0003\u000f\u0007\u0000hj\u0005"+
"_\u0000\u0000if\u0001\u0000\u0000\u0000ig\u0001\u0000\u0000\u0000ih\u0001"+
"\u0000\u0000\u0000jk\u0001\u0000\u0000\u0000ki\u0001\u0000\u0000\u0000"+
"kl\u0001\u0000\u0000\u0000l\u0016\u0001\u0000\u0000\u0000ms\u0005`\u0000"+
"\u0000nr\b\u0011\u0000\u0000op\u0005`\u0000\u0000pr\u0005`\u0000\u0000"+
"qn\u0001\u0000\u0000\u0000qo\u0001\u0000\u0000\u0000ru\u0001\u0000\u0000"+
"\u0000sq\u0001\u0000\u0000\u0000st\u0001\u0000\u0000\u0000tv\u0001\u0000"+
"\u0000\u0000us\u0001\u0000\u0000\u0000vw\u0005`\u0000\u0000w\u0018\u0001"+
"\u0000\u0000\u0000xy\u0005-\u0000\u0000yz\u0005-\u0000\u0000z~\u0001\u0000"+
"\u0000\u0000{}\b\u0012\u0000\u0000|{\u0001\u0000\u0000\u0000}\u0080\u0001"+
"\u0000\u0000\u0000~|\u0001\u0000\u0000\u0000~\u007f\u0001\u0000\u0000"+
"\u0000\u007f\u0082\u0001\u0000\u0000\u0000\u0080~\u0001\u0000\u0000\u0000"+
"\u0081\u0083\u0005\r\u0000\u0000\u0082\u0081\u0001\u0000\u0000\u0000\u0082"+
"\u0083\u0001\u0000\u0000\u0000\u0083\u0085\u0001\u0000\u0000\u0000\u0084"+
"\u0086\u0005\n\u0000\u0000\u0085\u0084\u0001\u0000\u0000\u0000\u0085\u0086"+
"\u0001\u0000\u0000\u0000\u0086\u0087\u0001\u0000\u0000\u0000\u0087\u0088"+
"\u0006\f\u0000\u0000\u0088\u001a\u0001\u0000\u0000\u0000\u0089\u008a\u0005"+
"/\u0000\u0000\u008a\u008b\u0005*\u0000\u0000\u008b\u008c\u0005*\u0000"+
"\u0000\u008c\u008d\u0005/\u0000\u0000\u008d\u008e\u0001\u0000\u0000\u0000"+
"\u008e\u008f\u0006\r\u0000\u0000\u008f\u001c\u0001\u0000\u0000\u0000\u0090"+
"\u0091\u0005/\u0000\u0000\u0091\u0092\u0005*\u0000\u0000\u0092\u0093\u0001"+
"\u0000\u0000\u0000\u0093\u0097\b\u0013\u0000\u0000\u0094\u0096\t\u0000"+
"\u0000\u0000\u0095\u0094\u0001\u0000\u0000\u0000\u0096\u0099\u0001\u0000"+
"\u0000\u0000\u0097\u0098\u0001\u0000\u0000\u0000\u0097\u0095\u0001\u0000"+
"\u0000\u0000\u0098\u009a\u0001\u0000\u0000\u0000\u0099\u0097\u0001\u0000"+
"\u0000\u0000\u009a\u009b\u0005*\u0000\u0000\u009b\u009c\u0005/\u0000\u0000"+
"\u009c\u009d\u0001\u0000\u0000\u0000\u009d\u009e\u0006\u000e\u0000\u0000"+
"\u009e\u001e\u0001\u0000\u0000\u0000\u009f\u00a1\u0007\u0014\u0000\u0000"+
"\u00a0\u009f\u0001\u0000\u0000\u0000\u00a1\u00a2\u0001\u0000\u0000\u0000"+
"\u00a2\u00a0\u0001\u0000\u0000\u0000\u00a2\u00a3\u0001\u0000\u0000\u0000"+
"\u00a3\u00a4\u0001\u0000\u0000\u0000\u00a4\u00a5\u0006\u000f\u0000\u0000"+
"\u00a5 \u0001\u0000\u0000\u0000\u000f\u0000SU]_dikqs~\u0082\u0085\u0097"+
"\u00a2\u0001\u0000\u0001\u0000";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -1,4 +1,4 @@
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.9.3
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.12.0
package io.edurt.datacap.sql.parser;
import org.antlr.v4.runtime.tree.ParseTreeListener;

View File

@ -1,4 +1,4 @@
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.9.3
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.12.0
package io.edurt.datacap.sql.parser;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
@ -9,9 +9,9 @@ import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"})
public class SqlBaseParser extends Parser {
static { RuntimeMetaData.checkVersion("4.9.3", RuntimeMetaData.VERSION); }
static { RuntimeMetaData.checkVersion("4.12.0", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
@ -99,6 +99,7 @@ public class SqlBaseParser extends Parser {
_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@SuppressWarnings("CheckReturnValue")
public static class SingleStatementContext extends ParserRuleContext {
public List<StatementContext> statement() {
return getRuleContexts(StatementContext.class);
@ -159,6 +160,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class StatementContext extends ParserRuleContext {
public TerminalNode SHOW() { return getToken(SqlBaseParser.SHOW, 0); }
public ChildPathStatementContext childPathStatement() {
@ -240,6 +242,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class KafkaQueryTopicStatementContext extends ParserRuleContext {
public TerminalNode SHOW() { return getToken(SqlBaseParser.SHOW, 0); }
public TerminalNode TOPICS() { return getToken(SqlBaseParser.TOPICS, 0); }
@ -285,6 +288,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class KafkaQueryConsumerStatementContext extends ParserRuleContext {
public TerminalNode SHOW() { return getToken(SqlBaseParser.SHOW, 0); }
public TerminalNode CONSUMERS() { return getToken(SqlBaseParser.CONSUMERS, 0); }
@ -350,6 +354,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class KafkaQueryStatementContext extends ParserRuleContext {
public KafkaQueryTopicStatementContext kafkaQueryTopicStatement() {
return getRuleContext(KafkaQueryTopicStatementContext.class,0);
@ -410,6 +415,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class KafkaStatementContext extends ParserRuleContext {
public KafkaQueryStatementContext kafkaQueryStatement() {
return getRuleContext(KafkaQueryStatementContext.class,0);
@ -454,6 +460,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class ChildPathStatementContext extends ParserRuleContext {
public TerminalNode PATHS() { return getToken(SqlBaseParser.PATHS, 0); }
public FromClauseContext fromClause() {
@ -514,6 +521,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class ColumnStatementContext extends ParserRuleContext {
public IdentifierContext identifier() {
return getRuleContext(IdentifierContext.class,0);
@ -558,6 +566,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class FromClauseContext extends ParserRuleContext {
public TerminalNode FROM() { return getToken(SqlBaseParser.FROM, 0); }
public TableNameContext tableName() {
@ -605,6 +614,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class TableNameContext extends ParserRuleContext {
public List<IdentifierContext> identifier() {
return getRuleContexts(IdentifierContext.class);
@ -669,6 +679,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class IdentifierContext extends ParserRuleContext {
public List<TerminalNode> IDENTIFIER() { return getTokens(SqlBaseParser.IDENTIFIER); }
public TerminalNode IDENTIFIER(int i) {
@ -713,7 +724,7 @@ public class SqlBaseParser extends Parser {
setState(78);
_errHandler.sync(this);
_la = _input.LA(1);
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << STRING) | (1L << IDENTIFIER) | (1L << BACKQUOTED_IDENTIFIER))) != 0)) {
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 1792L) != 0)) {
{
setState(76);
_errHandler.sync(this);
@ -757,6 +768,7 @@ public class SqlBaseParser extends Parser {
return _localctx;
}
@SuppressWarnings("CheckReturnValue")
public static class QuotedIdentifierContext extends ParserRuleContext {
public TerminalNode BACKQUOTED_IDENTIFIER() { return getToken(SqlBaseParser.BACKQUOTED_IDENTIFIER, 0); }
public QuotedIdentifierContext(ParserRuleContext parent, int invokingState) {
@ -800,27 +812,52 @@ public class SqlBaseParser extends Parser {
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3\20V\4\2\t\2\4\3\t"+
"\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t\13\4"+
"\f\t\f\4\r\t\r\3\2\7\2\34\n\2\f\2\16\2\37\13\2\3\3\3\3\3\3\3\3\3\3\3\3"+
"\3\3\5\3(\n\3\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\5\5\62\n\5\3\6\3\6\5\6\66"+
"\n\6\3\7\3\7\3\b\3\b\3\b\5\b=\n\b\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\7"+
"\13G\n\13\f\13\16\13J\13\13\3\f\3\f\3\f\7\fO\n\f\f\f\16\fR\13\f\3\r\3"+
"\r\3\r\2\2\16\2\4\6\b\n\f\16\20\22\24\26\30\2\2\2S\2\35\3\2\2\2\4\'\3"+
"\2\2\2\6)\3\2\2\2\b\61\3\2\2\2\n\65\3\2\2\2\f\67\3\2\2\2\16<\3\2\2\2\20"+
">\3\2\2\2\22@\3\2\2\2\24C\3\2\2\2\26P\3\2\2\2\30S\3\2\2\2\32\34\5\4\3"+
"\2\33\32\3\2\2\2\34\37\3\2\2\2\35\33\3\2\2\2\35\36\3\2\2\2\36\3\3\2\2"+
"\2\37\35\3\2\2\2 !\7\4\2\2!(\5\16\b\2\"#\7\b\2\2#$\5\20\t\2$%\5\22\n\2"+
"%(\3\2\2\2&(\5\f\7\2\' \3\2\2\2\'\"\3\2\2\2\'&\3\2\2\2(\5\3\2\2\2)*\7"+
"\4\2\2*+\7\6\2\2+\7\3\2\2\2,-\7\4\2\2-\62\7\7\2\2./\7\4\2\2/\60\7\7\2"+
"\2\60\62\5\22\n\2\61,\3\2\2\2\61.\3\2\2\2\62\t\3\2\2\2\63\66\5\6\4\2\64"+
"\66\5\b\5\2\65\63\3\2\2\2\65\64\3\2\2\2\66\13\3\2\2\2\678\5\n\6\28\r\3"+
"\2\2\29=\7\5\2\2:;\7\5\2\2;=\5\22\n\2<9\3\2\2\2<:\3\2\2\2=\17\3\2\2\2"+
">?\5\26\f\2?\21\3\2\2\2@A\7\t\2\2AB\5\24\13\2B\23\3\2\2\2CH\5\26\f\2D"+
"E\7\3\2\2EG\5\26\f\2FD\3\2\2\2GJ\3\2\2\2HF\3\2\2\2HI\3\2\2\2I\25\3\2\2"+
"\2JH\3\2\2\2KO\7\13\2\2LO\7\n\2\2MO\5\30\r\2NK\3\2\2\2NL\3\2\2\2NM\3\2"+
"\2\2OR\3\2\2\2PN\3\2\2\2PQ\3\2\2\2Q\27\3\2\2\2RP\3\2\2\2ST\7\f\2\2T\31"+
"\3\2\2\2\n\35\'\61\65<HNP";
"\u0004\u0001\u000eT\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
"\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+
"\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+
"\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0001"+
"\u0000\u0005\u0000\u001a\b\u0000\n\u0000\f\u0000\u001d\t\u0000\u0001\u0001"+
"\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
"\u0003\u0001&\b\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0003"+
"\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003\u00030\b\u0003"+
"\u0001\u0004\u0001\u0004\u0003\u00044\b\u0004\u0001\u0005\u0001\u0005"+
"\u0001\u0006\u0001\u0006\u0001\u0006\u0003\u0006;\b\u0006\u0001\u0007"+
"\u0001\u0007\u0001\b\u0001\b\u0001\b\u0001\t\u0001\t\u0001\t\u0005\tE"+
"\b\t\n\t\f\tH\t\t\u0001\n\u0001\n\u0001\n\u0005\nM\b\n\n\n\f\nP\t\n\u0001"+
"\u000b\u0001\u000b\u0001\u000b\u0000\u0000\f\u0000\u0002\u0004\u0006\b"+
"\n\f\u000e\u0010\u0012\u0014\u0016\u0000\u0000Q\u0000\u001b\u0001\u0000"+
"\u0000\u0000\u0002%\u0001\u0000\u0000\u0000\u0004\'\u0001\u0000\u0000"+
"\u0000\u0006/\u0001\u0000\u0000\u0000\b3\u0001\u0000\u0000\u0000\n5\u0001"+
"\u0000\u0000\u0000\f:\u0001\u0000\u0000\u0000\u000e<\u0001\u0000\u0000"+
"\u0000\u0010>\u0001\u0000\u0000\u0000\u0012A\u0001\u0000\u0000\u0000\u0014"+
"N\u0001\u0000\u0000\u0000\u0016Q\u0001\u0000\u0000\u0000\u0018\u001a\u0003"+
"\u0002\u0001\u0000\u0019\u0018\u0001\u0000\u0000\u0000\u001a\u001d\u0001"+
"\u0000\u0000\u0000\u001b\u0019\u0001\u0000\u0000\u0000\u001b\u001c\u0001"+
"\u0000\u0000\u0000\u001c\u0001\u0001\u0000\u0000\u0000\u001d\u001b\u0001"+
"\u0000\u0000\u0000\u001e\u001f\u0005\u0002\u0000\u0000\u001f&\u0003\f"+
"\u0006\u0000 !\u0005\u0006\u0000\u0000!\"\u0003\u000e\u0007\u0000\"#\u0003"+
"\u0010\b\u0000#&\u0001\u0000\u0000\u0000$&\u0003\n\u0005\u0000%\u001e"+
"\u0001\u0000\u0000\u0000% \u0001\u0000\u0000\u0000%$\u0001\u0000\u0000"+
"\u0000&\u0003\u0001\u0000\u0000\u0000\'(\u0005\u0002\u0000\u0000()\u0005"+
"\u0004\u0000\u0000)\u0005\u0001\u0000\u0000\u0000*+\u0005\u0002\u0000"+
"\u0000+0\u0005\u0005\u0000\u0000,-\u0005\u0002\u0000\u0000-.\u0005\u0005"+
"\u0000\u0000.0\u0003\u0010\b\u0000/*\u0001\u0000\u0000\u0000/,\u0001\u0000"+
"\u0000\u00000\u0007\u0001\u0000\u0000\u000014\u0003\u0004\u0002\u0000"+
"24\u0003\u0006\u0003\u000031\u0001\u0000\u0000\u000032\u0001\u0000\u0000"+
"\u00004\t\u0001\u0000\u0000\u000056\u0003\b\u0004\u00006\u000b\u0001\u0000"+
"\u0000\u00007;\u0005\u0003\u0000\u000089\u0005\u0003\u0000\u00009;\u0003"+
"\u0010\b\u0000:7\u0001\u0000\u0000\u0000:8\u0001\u0000\u0000\u0000;\r"+
"\u0001\u0000\u0000\u0000<=\u0003\u0014\n\u0000=\u000f\u0001\u0000\u0000"+
"\u0000>?\u0005\u0007\u0000\u0000?@\u0003\u0012\t\u0000@\u0011\u0001\u0000"+
"\u0000\u0000AF\u0003\u0014\n\u0000BC\u0005\u0001\u0000\u0000CE\u0003\u0014"+
"\n\u0000DB\u0001\u0000\u0000\u0000EH\u0001\u0000\u0000\u0000FD\u0001\u0000"+
"\u0000\u0000FG\u0001\u0000\u0000\u0000G\u0013\u0001\u0000\u0000\u0000"+
"HF\u0001\u0000\u0000\u0000IM\u0005\t\u0000\u0000JM\u0005\b\u0000\u0000"+
"KM\u0003\u0016\u000b\u0000LI\u0001\u0000\u0000\u0000LJ\u0001\u0000\u0000"+
"\u0000LK\u0001\u0000\u0000\u0000MP\u0001\u0000\u0000\u0000NL\u0001\u0000"+
"\u0000\u0000NO\u0001\u0000\u0000\u0000O\u0015\u0001\u0000\u0000\u0000"+
"PN\u0001\u0000\u0000\u0000QR\u0005\n\u0000\u0000R\u0017\u0001\u0000\u0000"+
"\u0000\b\u001b%/3:FLN";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {

View File

@ -1,4 +1,4 @@
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.9.3
// Generated from io/edurt/datacap/sql/parser/SqlBase.g4 by ANTLR 4.12.0
package io.edurt.datacap.sql.parser;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;

View File

@ -96,6 +96,11 @@
<artifactId>chatgpt-java</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>io.edurt.datacap</groupId>
<artifactId>datacap-spi</artifactId>

View File

@ -10,4 +10,6 @@ spring.datasource.password=12345678
datacap.security.secret=DataCapSecretKey
datacap.security.expiration=86400000
# Executor
### If this directory is not set, the system will get the project root directory to build the data subdirectory
datacap.executor.data=
datacap.executor.seatunnel.home=/opt/lib/seatunnel

View File

@ -1,50 +0,0 @@
{
"name": "Default",
"supportTime": "2022-09-22",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 1,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"group": "authorization"
},
{
"field": "password",
"type": "String",
"group": "authorization"
},
{
"field": "database",
"type": "String",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
},
{
"field": "configures",
"type": "Array",
"value": [],
"group": "custom"
}
]
}

View File

@ -0,0 +1,33 @@
name: Default
supportTime: '2022-09-22'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 1
message: port is a required field, please be sure to enter
- field: username
type: String
group: authorization
- field: password
type: String
group: authorization
- field: database
type: String
message: database is a required field, please be sure to enter
group: advanced
- field: configures
type: Array
value: [ ]
group: custom

View File

@ -1,28 +0,0 @@
{
"name": "ClickHouse",
"supportTime": "2022-11-09",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 8123,
"message": "port is a required field, please be sure to enter"
}
]
}

View File

@ -0,0 +1,58 @@
name: ClickHouse
supportTime: '2022-11-09'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 9000
message: port is a required field, please be sure to enter
pipelines:
- executor: Seatunnel
type: SOURCE
fields:
- field: host
origin: host
required: true
- field: database
origin: database
required: true
- field: sql
origin: context
required: true
- field: username
origin: username
required: true
- field: password
origin: password
required: true
- executor: Seatunnel
type: SINK
fields:
- field: host
origin: host
required: true
- field: database
origin: database
required: true
- field: sql
origin: context
required: true
- field: username
origin: username
required: true
- field: password
origin: password
required: true

View File

@ -1,77 +0,0 @@
{
"name": "ClickHouse",
"supportTime": "2022-09-22",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 9000,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"group": "authorization"
},
{
"field": "password",
"type": "String",
"group": "authorization"
},
{
"field": "database",
"type": "String",
"group": "advanced"
},
{
"field": "configures",
"type": "Array",
"value": [],
"group": "custom"
}
],
"pipelines": [
{
"executor": "Seatunnel",
"type": "FROM",
"fields": [
{
"field": "host",
"required": true
},
{
"field": "database",
"required": true
},
{
"field": "sql",
"required": true
},
{
"field": "username",
"required": true
},
{
"field": "password",
"required": true
}
]
}
]
}

View File

@ -0,0 +1,71 @@
name: ClickHouse
supportTime: '2022-09-22'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 9000
message: port is a required field, please be sure to enter
- field: username
type: String
group: authorization
- field: password
type: String
group: authorization
- field: database
type: String
group: advanced
- field: configures
type: Array
value: [ ]
group: custom
pipelines:
- executor: Seatunnel
type: SOURCE
fields:
- field: host
required: true
- field: database
required: true
override: true
input: true
- field: sql
origin: context
required: true
override: true
input: true
- field: username
required: true
- field: password
required: false
- executor: Seatunnel
type: SINK
fields:
- field: host
required: true
- field: database
override: true
required: true
- field: table
override: true
required: true
- field: username
required: true
- field: password
required: true
- field: fields
override: true
required: true

View File

@ -1,36 +0,0 @@
{
"name": "DuckDB",
"supportTime": "2023-02-20",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "/root",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 0,
"message": "port is a required field, please be sure to enter"
},
{
"field": "database",
"type": "String",
"required": true,
"value": "local",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
}
]
}

View File

@ -0,0 +1,25 @@
name: DuckDB
supportTime: '2023-02-20'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: "/root"
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 0
message: port is a required field, please be sure to enter
- field: database
type: String
required: true
value: local
message: database is a required field, please be sure to enter
group: advanced

View File

@ -1,62 +0,0 @@
{
"name": "MySQL",
"supportTime": "2022-09-19",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 3306,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"group": "authorization"
},
{
"field": "password",
"type": "String",
"group": "authorization"
},
{
"field": "ssl",
"type": "Boolean",
"group": "authorization"
},
{
"field": "database",
"type": "String",
"required": true,
"value": "default",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
},
{
"field": "configures",
"type": "Array",
"value": [
{
"field": "useOldAliasMetadataBehavior",
"value": true
}
],
"group": "custom"
}
]
}

View File

@ -0,0 +1,40 @@
name: MySQL
supportTime: '2022-09-19'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 3306
message: port is a required field, please be sure to enter
- field: username
type: String
group: authorization
- field: password
type: String
group: authorization
- field: ssl
type: Boolean
group: authorization
- field: database
type: String
required: true
value: default
message: database is a required field, please be sure to enter
group: advanced
- field: configures
type: Array
value:
- field: useOldAliasMetadataBehavior
value: true
group: custom

View File

@ -1,59 +0,0 @@
{
"name": "OceanBase",
"supportTime": "2022-11-30",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 2881,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"required": true,
"group": "authorization"
},
{
"field": "password",
"type": "String",
"required": true,
"group": "authorization"
},
{
"field": "database",
"type": "String",
"required": true,
"value": "default",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
},
{
"field": "configures",
"type": "Array",
"value": [
{
"field": "useOldAliasMetadataBehavior",
"value": true
}
],
"group": "custom"
}
]
}

View File

@ -0,0 +1,39 @@
name: OceanBase
supportTime: '2022-11-30'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 2881
message: port is a required field, please be sure to enter
- field: username
type: String
required: true
group: authorization
- field: password
type: String
required: true
group: authorization
- field: database
type: String
required: true
value: default
message: database is a required field, please be sure to enter
group: advanced
- field: configures
type: Array
value:
- field: useOldAliasMetadataBehavior
value: true
group: custom

View File

@ -1,56 +0,0 @@
{
"name": "Presto",
"supportTime": "2022-09-25",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 8080,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"group": "authorization"
},
{
"field": "password",
"type": "String",
"group": "authorization"
},
{
"field": "database",
"type": "String",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
},
{
"field": "catalog",
"type": "String",
"value": "",
"group": "advanced"
},
{
"field": "configures",
"type": "Array",
"value": [],
"group": "custom"
}
]
}

View File

@ -0,0 +1,37 @@
name: Presto
supportTime: '2022-09-25'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 8080
message: port is a required field, please be sure to enter
- field: username
type: String
group: authorization
- field: password
type: String
group: authorization
- field: database
type: String
message: database is a required field, please be sure to enter
group: advanced
- field: catalog
type: String
value: ''
group: advanced
- field: configures
type: Array
value: [ ]
group: custom

View File

@ -1,33 +0,0 @@
{
"name": "Redis",
"supportTime": "2022-09-26",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 6379,
"message": "port is a required field, please be sure to enter"
},
{
"field": "password",
"type": "String",
"group": "authorization"
}
]
}

View File

@ -0,0 +1,22 @@
name: Redis
supportTime: '2022-09-26'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 6379
message: port is a required field, please be sure to enter
- field: password
type: String
group: authorization

View File

@ -1,52 +0,0 @@
{
"name": "ClickHouse",
"supportTime": "2023-01-29",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 80,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"required": true,
"group": "authorization"
},
{
"field": "password",
"type": "String",
"required": true,
"group": "authorization"
},
{
"field": "database",
"type": "String",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
},
{
"field": "configures",
"type": "Array",
"value": [],
"group": "custom"
}
]
}

View File

@ -0,0 +1,35 @@
name: Snowflake
supportTime: '2023-01-29'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 80
message: port is a required field, please be sure to enter
- field: username
type: String
required: true
group: authorization
- field: password
type: String
required: true
group: authorization
- field: database
type: String
message: database is a required field, please be sure to enter
group: advanced
- field: configures
type: Array
value: [ ]
group: custom

View File

@ -1,46 +0,0 @@
{
"name": "YDB",
"supportTime": "2023-01-30",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 2136,
"message": "port is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"group": "authorization"
},
{
"field": "password",
"type": "String",
"group": "authorization"
},
{
"field": "database",
"type": "String",
"required": true,
"value": "local",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
}
]
}

View File

@ -0,0 +1,31 @@
name: YDB
supportTime: '2023-01-30'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 2136
message: port is a required field, please be sure to enter
- field: username
type: String
group: authorization
- field: password
type: String
group: authorization
- field: database
type: String
required: true
value: local
message: database is a required field, please be sure to enter
group: advanced

View File

@ -1,39 +0,0 @@
{
"name": "Alioss",
"supportTime": "2023-02-23",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "https://oss-cn-regison.aliyuncs.com",
"message": "host is a required field, please be sure to enter"
},
{
"field": "username",
"type": "String",
"required": true,
"group": "authorization"
},
{
"field": "password",
"type": "String",
"required": true,
"group": "authorization"
},
{
"field": "database",
"type": "String",
"required": true,
"value": "default",
"message": "database is a required field, please be sure to enter",
"group": "advanced"
}
]
}

View File

@ -0,0 +1,26 @@
name: Alioss
supportTime: '2023-02-23'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: https://oss-cn-regison.aliyuncs.com
message: host is a required field, please be sure to enter
- field: username
type: String
required: true
group: authorization
- field: password
type: String
required: true
group: authorization
- field: database
type: String
required: true
value: default
message: database is a required field, please be sure to enter
group: advanced

View File

@ -1,19 +0,0 @@
{
"name": "Kafka",
"supportTime": "2023-03-06",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1:9092",
"message": "host is a required field, please be sure to enter"
}
]
}

View File

@ -0,0 +1,12 @@
name: Kafka
supportTime: '2023-03-06'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1:9092
message: host is a required field, please be sure to enter

View File

@ -1,33 +0,0 @@
{
"name": "Redis",
"supportTime": "2022-12-01",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1",
"message": "host is a required field, please be sure to enter"
},
{
"field": "port",
"type": "Number",
"required": true,
"min": 1,
"max": 65535,
"value": 6379,
"message": "port is a required field, please be sure to enter"
},
{
"field": "password",
"type": "String",
"group": "authorization"
}
]
}

View File

@ -0,0 +1,22 @@
name: Redis
supportTime: '2022-12-01'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1
message: host is a required field, please be sure to enter
- field: port
type: Number
required: true
min: 1
max: 65535
value: 6379
message: port is a required field, please be sure to enter
- field: password
type: String
group: authorization

View File

@ -1,19 +0,0 @@
{
"name": "Zookeeper",
"supportTime": "2023-02-07",
"configures": [
{
"field": "name",
"type": "String",
"required": true,
"message": "name is a required field, please be sure to enter"
},
{
"field": "host",
"type": "String",
"required": true,
"value": "127.0.0.1:2181",
"message": "host is a required field, please be sure to enter"
}
]
}

View File

@ -0,0 +1,12 @@
name: Zookeeper
supportTime: '2023-02-07'
configures:
- field: name
type: String
required: true
message: name is a required field, please be sure to enter
- field: host
type: String
required: true
value: 127.0.0.1:2181
message: host is a required field, please be sure to enter

View File

@ -11,8 +11,8 @@ import lombok.ToString;
@AllArgsConstructor
public class PipelineBody
{
private Long from;
private Long to;
private PipelineFieldBody from;
private PipelineFieldBody to;
private String content;
private String executor;
}

View File

@ -0,0 +1,18 @@
package io.edurt.datacap.server.body;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Properties;
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class PipelineFieldBody
{
private Long id;
private Properties configures;
}

View File

@ -1,5 +1,7 @@
package io.edurt.datacap.server.common;
import org.apache.commons.lang3.ObjectUtils;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
@ -19,10 +21,16 @@ public class BeanToPropertiesCommon
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
String propertyName = propertyDescriptor.getName();
if (!propertyName.equals("class")) {
Method readMethod = propertyDescriptor.getReadMethod();
Object value = readMethod.invoke(bean);
properties.setProperty(propertyName, value.toString());
if (!propertyDescriptor.getPropertyType().getName().startsWith("io\\.edurt\\.datacap")) {
if (!propertyName.equals("class")) {
Method readMethod = propertyDescriptor.getReadMethod();
if (!readMethod.getGenericReturnType().getTypeName().contains("io.edurt.datacap")) {
Object value = readMethod.invoke(bean);
if (ObjectUtils.isNotEmpty(value)) {
properties.setProperty(propertyName, value.toString());
}
}
}
}
}
}

View File

@ -1,6 +1,8 @@
package io.edurt.datacap.server.common;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.google.common.base.Preconditions;
import com.google.inject.Injector;
import com.google.inject.Key;
@ -11,12 +13,15 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import java.io.File;
import java.util.Optional;
import java.util.Set;
@Slf4j
public class PluginCommon
{
private static final ObjectMapper yamlFactory = new ObjectMapper(new YAMLFactory());
private PluginCommon() {}
public static Optional<Plugin> getPluginByName(Injector injector, String pluginName)
@ -31,6 +36,7 @@ public class PluginCommon
return pluginOptional;
}
@Deprecated
public static IConfigure loadConfigure(String type, String plugin, String resource, Environment environment)
{
String root = environment.getProperty("spring.config.location");
@ -55,4 +61,31 @@ public class PluginCommon
}
return configure;
}
public static IConfigure loadYamlConfigure(String type, String plugin, String resource, Environment environment)
{
String root = environment.getProperty("spring.config.location");
if (!resource.endsWith(".yaml")) {
resource = resource + ".yaml";
}
String path = root + String.format("plugins/%s/%s", type.toLowerCase(), resource.toLowerCase());
File file = new File(path);
if (!file.exists()) {
log.warn("Plugin {} type {} configuration file {} not found, load default configuration file", plugin, type, resource);
file = new File(root + "plugins/default.yaml");
}
else {
log.info("Load plugin {} type {} resource {} configure file path {}", plugin, type, resource, path);
}
yamlFactory.findAndRegisterModules();
IConfigure configure = null;
try {
configure = yamlFactory.readValue(file, IConfigure.class);
}
catch (Exception e) {
log.error("Format configuration file, it may be a bug, please submit issues to solve it. plugin {} type {} resource {} configure file path {} message ", plugin, type, resource, path, e);
Preconditions.checkArgument(StringUtils.isNotEmpty(path), "Format configuration file, it may be a bug, please submit issues to solve it.");
}
return configure;
}
}

View File

@ -4,6 +4,8 @@ public enum ServiceState
{
SOURCE_NOT_FOUND(1001, "Source does not exist"),
SOURCE_NOT_SUPPORTED(1002, "The current data source is not supported"),
SOURCE_NOT_SUPPORTED_PIPELINE(1003, "The current data source does not support pipeline"),
SOURCE_NOT_SUPPORTED_PIPELINE_TYPE(1004, "The current data source does not support pipeline type"),
PLUGIN_NOT_FOUND(2001, "Plugin dose not exists"),
PLUGIN_EXECUTE_FAILED(2002, "Plugin execute failed"),
PLUGIN_ONLY_ONE_TEMPLATE(2003, "Plug-ins support only templates with the same name"),

View File

@ -4,6 +4,7 @@ import io.edurt.datacap.server.body.PipelineBody;
import io.edurt.datacap.server.common.Response;
import io.edurt.datacap.server.service.PipelineService;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -19,7 +20,7 @@ public class PipelineController
}
@PostMapping(value = "/create")
public Response<Object> create(PipelineBody configure)
public Response<Object> create(@RequestBody PipelineBody configure)
{
return pipelineService.submit(configure);
}

View File

@ -14,6 +14,6 @@ import java.util.List;
public class IConfigureExecutor
{
private String executor;
private String type;
private IConfigurePipelineType type;
private List<IConfigureExecutorField> fields;
}

View File

@ -12,5 +12,12 @@ import lombok.ToString;
public class IConfigureExecutorField
{
private String field;
// The default is equal to the filed value, and the custom column name uses
private String origin;
private boolean required;
/**
* If the flag is true, it means that the field is extracted through user configuration, and the default data will be discarded
*/
private boolean override;
private boolean input; // Is it an input parameter
}

View File

@ -0,0 +1,7 @@
package io.edurt.datacap.server.plugin.configure;
public enum IConfigurePipelineType
{
SOURCE,
SINK
}

View File

@ -11,20 +11,32 @@ import io.edurt.datacap.server.common.ServiceState;
import io.edurt.datacap.server.entity.SourceEntity;
import io.edurt.datacap.server.plugin.configure.IConfigure;
import io.edurt.datacap.server.plugin.configure.IConfigureExecutor;
import io.edurt.datacap.server.plugin.configure.IConfigureExecutorField;
import io.edurt.datacap.server.plugin.configure.IConfigurePipelineType;
import io.edurt.datacap.server.repository.SourceRepository;
import io.edurt.datacap.server.security.UserDetailsService;
import io.edurt.datacap.server.service.PipelineService;
import io.edurt.datacap.spi.executor.Executor;
import io.edurt.datacap.spi.executor.Pipeline;
import io.edurt.datacap.spi.executor.PipelineField;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
@Service
@Slf4j
public class PipelineServiceImpl
implements PipelineService
{
@ -42,28 +54,39 @@ public class PipelineServiceImpl
@Override
public Response<Object> submit(PipelineBody configure)
{
Optional<SourceEntity> fromSourceOptional = repository.findById(configure.getFrom());
Optional<SourceEntity> toSourceOptional = repository.findById(configure.getTo());
Optional<SourceEntity> fromSourceOptional = repository.findById(configure.getFrom().getId());
Optional<SourceEntity> toSourceOptional = repository.findById(configure.getTo().getId());
if (fromSourceOptional.isPresent() && toSourceOptional.isPresent()) {
SourceEntity fromSource = fromSourceOptional.get();
IConfigure fromConfigure = PluginCommon.loadConfigure(fromSource.getProtocol(), fromSource.getType(), fromSource.getType(), environment);
IConfigure fromConfigure = PluginCommon.loadYamlConfigure(fromSource.getProtocol(), fromSource.getType(), fromSource.getType(), environment);
// Check if Pipeline is supported
if (ObjectUtils.isEmpty(fromConfigure.getPipelines())) {
String message = String.format("Source %s is not supported pipeline, type %s", fromSource.getId(), fromSource.getType());
return Response.failure(ServiceState.SOURCE_NOT_SUPPORTED_PIPELINE, message);
}
Optional<IConfigureExecutor> fromConfigureExecutor = fromConfigure.getPipelines()
.stream()
.filter(v -> v.getExecutor().equals(configure.getExecutor()))
.filter(v -> v.getExecutor().equals(configure.getExecutor()) && v.getType().equals(IConfigurePipelineType.SOURCE))
.findFirst();
if (!fromConfigureExecutor.isPresent()) {
return Response.failure(ServiceState.PLUGIN_NOT_FOUND);
String message = String.format("Source %s type %s is not supported pipeline type %s", fromSource.getId(), fromSource.getType(), IConfigurePipelineType.SOURCE);
return Response.failure(ServiceState.SOURCE_NOT_SUPPORTED_PIPELINE_TYPE, message);
}
SourceEntity toSource = toSourceOptional.get();
IConfigure toConfigure = PluginCommon.loadConfigure(toSource.getProtocol(), toSource.getType(), toSource.getType(), environment);
IConfigure toConfigure = PluginCommon.loadYamlConfigure(toSource.getProtocol(), toSource.getType(), toSource.getType(), environment);
if (ObjectUtils.isEmpty(toConfigure.getPipelines())) {
String message = String.format("Source %s is not supported pipeline, type %s", toSource.getId(), toSource.getType());
return Response.failure(ServiceState.SOURCE_NOT_SUPPORTED_PIPELINE, message);
}
Optional<IConfigureExecutor> toConfigureExecutor = toConfigure.getPipelines()
.stream()
.filter(v -> v.getExecutor().equals(configure.getExecutor()))
.filter(v -> v.getExecutor().equals(configure.getExecutor()) && v.getType().equals(IConfigurePipelineType.SINK))
.findFirst();
if (!toConfigureExecutor.isPresent()) {
return Response.failure(ServiceState.PLUGIN_NOT_FOUND);
String message = String.format("Source %s type %s is not supported pipeline type %s", toSource.getId(), toSource.getType(), IConfigurePipelineType.SINK);
return Response.failure(ServiceState.SOURCE_NOT_SUPPORTED_PIPELINE_TYPE, message);
}
Optional<Executor> executorOptional = injector.getInstance(Key.get(new TypeLiteral<Set<Executor>>() {}))
@ -72,32 +95,94 @@ public class PipelineServiceImpl
.findFirst();
// FROM source
Properties fromProperties = new Properties();
Properties fromBeanProperties = BeanToPropertiesCommon.convertBeanToProperties(fromSource);
fromConfigureExecutor.get().getFields().forEach(pipelineField -> fromProperties.put(pipelineField.getField(), fromBeanProperties.get(pipelineField.getField())));
Properties fromOriginProperties = configure.getFrom().getConfigures();
fromOriginProperties.setProperty("context", configure.getContent());
Properties fromProperties = this.merge(fromSource, fromConfigureExecutor.get().getFields(), fromOriginProperties);
Set<String> fromOptions = new HashSet<>();
fromConfigureExecutor.get()
.getFields()
.stream()
.filter(v -> v.isRequired())
.forEach(v -> fromOptions.add(v.getField()));
PipelineField fromField = PipelineField.builder()
.type(fromSource.getType())
.configure(fromProperties)
.supportOptions(fromOptions)
.build();
// TO source
Properties toProperties = new Properties();
Properties toBeanProperties = BeanToPropertiesCommon.convertBeanToProperties(toSource);
toConfigureExecutor.get().getFields().forEach(pipelineField -> toProperties.put(pipelineField.getField(), toBeanProperties.get(pipelineField.getField())));
Properties toOriginProperties = configure.getTo().getConfigures();
Properties toProperties = this.merge(toSource, toConfigureExecutor.get().getFields(), toOriginProperties);
Set<String> toOptions = new HashSet<>();
toConfigureExecutor.get()
.getFields()
.stream()
.filter(v -> v.isRequired())
.forEach(v -> toOptions.add(v.getField()));
PipelineField toField = PipelineField.builder()
.type(toSource.getType())
.configure(toProperties)
.supportOptions(toOptions)
.build();
String executorHome = environment.getProperty("datacap.executor.data");
if (StringUtils.isEmpty(executorHome)) {
executorHome = String.join(File.separator, System.getProperty("user.dir"), "data");
}
String username = UserDetailsService.getUser().getUsername();
String pipelineHome = DateFormatUtils.format(System.currentTimeMillis(), "yyyyMMddHHmmssSSS");
String work = String.join(File.separator, executorHome, username, pipelineHome);
String pipelineName = String.join("_", username, configure.getExecutor().toLowerCase(), pipelineHome);
try {
FileUtils.forceMkdir(new File(work));
}
catch (Exception e) {
log.warn("Failed to create temporary directory", e);
}
Pipeline pipeline = Pipeline.builder()
.work(System.getenv("user.dir") + "/" + UUID.randomUUID().toString())
.home(environment.getProperty("datacap.executor.seatunnel.home"))
.work(work)
.home(environment.getProperty(String.format("datacap.executor.%s.home", configure.getExecutor().toLowerCase(Locale.ROOT))))
.pipelineName(pipelineName)
.username(UserDetailsService.getUser().getUsername())
.from(fromField)
.to(toField)
.timeout(600)
.build();
executorOptional.get().start(pipeline);
return Response.success(null);
}
return Response.failure(ServiceState.SOURCE_NOT_FOUND);
}
private Properties merge(SourceEntity entity, List<IConfigureExecutorField> fields, Properties configure)
{
Properties properties = new Properties();
Properties convertBeanProperties = BeanToPropertiesCommon.convertBeanToProperties(entity);
for (IConfigureExecutorField field : fields) {
if (field.isOverride()) {
this.setProperty(field, properties, configure);
}
else {
this.setProperty(field, properties, convertBeanProperties);
}
}
return properties;
}
private void setProperty(IConfigureExecutorField field, Properties properties, Properties configure)
{
Object value = "";
if (ObjectUtils.isNotEmpty(field.getOrigin())) {
if (ObjectUtils.isNotEmpty(configure.get(field.getOrigin()))) {
value = configure.get(field.getOrigin());
}
}
else {
if (ObjectUtils.isNotEmpty(configure.get(field.getField()))) {
value = configure.get(field.getField());
}
}
properties.put(field.getField(), value);
}
}

View File

@ -123,7 +123,7 @@ public class SourceServiceImpl
entity.setName(plugin.name());
entity.setDescription(plugin.description());
entity.setType(plugin.type().name());
entity.setConfigure(PluginCommon.loadConfigure(plugin.type().name(), plugin.name(), plugin.name(), environment));
entity.setConfigure(PluginCommon.loadYamlConfigure(plugin.type().name(), plugin.name(), plugin.name(), environment));
List<PluginEntity> plugins = pluginMap.get(plugin.type().name());
if (ObjectUtils.isEmpty(plugins)) {
plugins = new ArrayList<>();
@ -168,7 +168,7 @@ public class SourceServiceImpl
}
// Check configure
IConfigure iConfigure = PluginCommon.loadConfigure(configure.getType(), configure.getName(), configure.getName(), environment);
IConfigure iConfigure = PluginCommon.loadYamlConfigure(configure.getType(), configure.getName(), configure.getName(), environment);
if (ObjectUtils.isEmpty(iConfigure) || iConfigure.getConfigures().size() != configure.getConfigure().getConfigures().size()) {
return Response.failure(ServiceState.PLUGIN_CONFIGURE_MISMATCH);
}
@ -201,7 +201,7 @@ public class SourceServiceImpl
}
// Check configure
IConfigure iConfigure = PluginCommon.loadConfigure(configure.getType(), configure.getName(), configure.getName(), environment);
IConfigure iConfigure = PluginCommon.loadYamlConfigure(configure.getType(), configure.getName(), configure.getName(), environment);
if (ObjectUtils.isEmpty(iConfigure) || iConfigure.getConfigures().size() != configure.getConfigure().getConfigures().size()) {
return Response.failure(ServiceState.PLUGIN_CONFIGURE_MISMATCH);
}
@ -237,7 +237,7 @@ public class SourceServiceImpl
configure.setName(entity.getType());
configure.setType(entity.getProtocol());
// Load default configure
IConfigure iConfigure = PluginCommon.loadConfigure(configure.getType(), configure.getName(), configure.getName(), environment);
IConfigure iConfigure = PluginCommon.loadYamlConfigure(configure.getType(), configure.getName(), configure.getName(), environment);
configure.setConfigure(IConfigureCommon.preparedConfigure(iConfigure, entity));
entity.setSchema(iConfigure);
return Response.success(entity);

View File

@ -9,12 +9,12 @@ import org.junit.Test;
justification = "I prefer to suppress these FindBugs warnings")
public class PluginCommonTest
{
private String resource = "default.json";
private String resource = "default.yaml";
@Test
public void loadConfigure()
{
IConfigure configure = PluginCommon.loadConfigure("JDBC", "MySQL", resource, null);
IConfigure configure = PluginCommon.loadYamlConfigure("JDBC", "MySQL", resource, null);
Assert.assertNotNull(configure);
}
}

View File

@ -5,7 +5,7 @@ import org.junit.Test;
public class ResourceCommonTest
{
private String resource = "default.json";
private String resource = "default.yaml";
private String resource2 = "empty.json";
@Test

View File

@ -1,2 +0,0 @@
{
}

View File

@ -7,8 +7,6 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.UUID;
@Data
@Builder
@ToString
@ -20,14 +18,9 @@ public class Pipeline
{
private String username;
private String home;
private String pipelineName;
private String work;
private String file;
private long timeout = 600;
private PipelineField from;
private PipelineField to;
public String getFile()
{
return String.join("/", this.getWork(), String.format("%s.configure", UUID.randomUUID().toString()));
}
}

View File

@ -5,6 +5,7 @@ import lombok.Data;
import lombok.ToString;
import java.util.Properties;
import java.util.Set;
@Data
@Builder
@ -13,4 +14,5 @@ public class PipelineField
{
private String type;
private Properties configure;
private Set<String> supportOptions;
}

View File

@ -30,6 +30,7 @@
"vue-clipboard3": "^2.0.0",
"vue-i18n": "^9.2.2",
"vue-router": "^4.0.3",
"vue3-markdown": "^1.1.7",
"watermark-dom": "^2.3.0",
"webpack-bundle-analyzer": "^4.6.1"
},

View File

@ -0,0 +1,6 @@
export default {
optimizeSQL: 'Optimize SQL',
optimizeSQLContent: 'Help me optimize the following SQL, the format is markdown',
analysisSQL: 'Analysis SQL',
analysisSQLContent: 'Help me analyze the following SQL, the format is markdown',
}

View File

@ -8,6 +8,7 @@ import grid from "@/i18n/langs/en/grid";
import signup from "@/i18n/langs/en/signup";
import alert from "@/i18n/langs/en/alert";
import monitor from "@/i18n/langs/en/monitor";
import ai from "@/i18n/langs/en/ai";
export default {
...en,
@ -19,5 +20,6 @@ export default {
grid: grid,
signup: signup,
alert: alert,
monitor: monitor
monitor: monitor,
ai: ai
}

View File

@ -0,0 +1,6 @@
export default {
optimizeSQL: '优化 SQL',
optimizeSQLContent: '帮我优化以下SQL,格式为markdown',
analysisSQL: '解析 SQL',
analysisSQLContent: '帮我解析以下SQL,格式为markdown',
}

View File

@ -8,6 +8,7 @@ import grid from "@/i18n/langs/zhCn/grid";
import signup from "@/i18n/langs/zhCn/signup";
import alert from "@/i18n/langs/zhCn/alert";
import monitor from "@/i18n/langs/zhCn/monitor";
import ai from "@/i18n/langs/zhCn/ai";
export default {
...zh,
@ -19,5 +20,6 @@ export default {
grid: grid,
signup: signup,
alert: alert,
monitor: monitor
monitor: monitor,
ai: ai
}

View File

@ -5,6 +5,7 @@ import router from "./router";
import ViewUIPlus from 'view-ui-plus';
import 'view-ui-plus/dist/styles/viewuiplus.css';
import VMdEditor from '@kangc/v-md-editor';
import VMdPreview from '@kangc/v-md-editor/lib/preview';
import '@kangc/v-md-editor/lib/style/preview.css';
import githubTheme from '@kangc/v-md-editor/lib/theme/github';
@ -18,5 +19,6 @@ const app = createApp(App);
app.use(router);
app.use(ViewUIPlus);
app.use(i18n);
app.use(VMdEditor);
app.use(VMdPreview);
app.mount("#app");

View File

@ -0,0 +1,146 @@
<template>
<div>
<Modal title="AI" width="80%" :closable="false" v-model="visible" :maskClosable="false" :z-index="9">
<div style="height: 350px; max-height: 350px;">
<Tabs v-if="!loading" :animated="false" @on-click="handlerTab($event)">
<TabPane :label="$t('ai.optimizeSQL')" name="OPTIMIZE" :disabled="actionLoading">
<div style="height: 300px; max-height: 350px; overflow: auto;">
<Skeleton v-if="actionLoading" loading :title="false" :animated="true"
:paragraph="{ rows: 5, width: [100, 200, '300px', '50%', '62%'] }"/>
<VMarkdownView v-else :mode="'light'" :content="finalContent"></VMarkdownView>
</div>
</TabPane>
<TabPane :label="$t('ai.analysisSQL')" name="ANALYSIS" :disabled="actionLoading">
<div style="height: 300px; max-height: 350px; overflow: auto;">
<Skeleton v-if="actionLoading" loading :title="false" :animated="true"
:paragraph="{ rows: 5, width: [100, 200, '300px', '50%', '62%'] }"/>
<VMarkdownView v-else :mode="'light'" :content="finalContent"></VMarkdownView>
</div>
</TabPane>
</Tabs>
</div>
<div class="datacap-drawer-footer">
<Button type="error" :disabled="actionLoading" @click="handlerCancel()">{{ $t('common.cancel') }}</Button>
</div>
<Spin size="large" fix :show="loading"></Spin>
</Modal>
</div>
</template>
<script lang="ts">
import {defineComponent} from 'vue';
import UserService from "@/services/UserService";
import {User, UserQuestion} from "@/model/User";
import {VMarkdownView} from 'vue3-markdown'
import 'vue3-markdown/dist/style.css'
import {Skeleton} from "view-ui-plus";
export enum TabType
{
OPTIMIZE = ('OPTIMIZE'),
ANALYSIS = ('ANALYSIS')
}
export default defineComponent({
name: 'QueryAiHelp',
props: {
isVisible: {
type: Boolean,
default: () => false
},
content: {
type: String,
default: () => ''
}
},
components: {Skeleton, VMarkdownView},
data()
{
return {
loading: false,
actionLoading: false,
userInfo: null as User,
finalContent: null
}
},
created()
{
this.handlerInitialize();
},
methods: {
handlerInitialize()
{
this.loading = true;
UserService.getInfo()
.then(response => {
if (response.status) {
this.userInfo = response.data;
this.handlerTab(TabType.OPTIMIZE);
}
})
.finally(() => {
this.loading = false;
});
},
handlerTab(value: TabType)
{
this.finalContent = null;
let message = '';
if (value === TabType.OPTIMIZE) {
message += this.$t('ai.optimizeSQLContent');
message += '\n';
message += this.content;
}
else if (value === TabType.ANALYSIS) {
message += this.$t('ai.analysisSQLContent');
message += '\n';
message += this.content;
}
this.actionLoading = true;
const userQuestion = new UserQuestion();
userQuestion.type = 'ChatGPT';
userQuestion.question = message;
UserService.startChat(userQuestion)
.then(response => {
if (response.status) {
this.finalContent = response.data.toString();
}
else {
this.$Message.error(response.message);
}
})
.finally(() => {
this.actionLoading = false;
});
},
handlerCancel()
{
this.visible = false;
}
},
computed: {
visible: {
get(): boolean
{
return this.isVisible
},
set(value: boolean)
{
this.$emit('close', value)
}
}
},
});
</script>
<style scoped>
.datacap-drawer-footer {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
border-top: 0px solid #e8e8e8;
padding: 10px 16px;
text-align: right;
background: #fff;
}
</style>

View File

@ -14,11 +14,11 @@
<Card style="width:100%">
<template #title>
<Space>
<Button type="primary" size="small" :loading="tableLoading" :disabled="!applySource"
<Button type="primary" size="small" :loading="tableLoading" :disabled="!applySource || !activeEditorValue"
icon="md-arrow-dropright-circle" @click="handlerRun()">
{{ $t('common.run') }}
</Button>
<Button type="dashed" size="small" :disabled="!applySource" icon="md-code" @click="handlerFormat()">
<Button type="dashed" size="small" :disabled="!applySource || !activeEditorValue" icon="md-code" @click="handlerFormat()">
{{ $t('common.format') }}
</Button>
<Button type="error" size="small" :disabled="!applySource || !tableLoading"
@ -54,6 +54,12 @@
</Space>
</template>
</Poptip>
<Badge v-if="applySource && activeEditorValue">
<Button type="primary" size="small" icon="md-ionitron" @click="handlerVisibleHelp(true)"></Button>
<template #count>
<Icon type="md-help-circle" color="#ed4014" size="16"/>
</template>
</Badge>
</Space>
</template>
<div ref="editorContainer">
@ -64,8 +70,8 @@
<TabPane v-for="editor in editors" :key="editor.key" :name="editor.key" :label="editor.title" :closable="editor.closable">
</TabPane>
<MonacoEditor theme="vs" :options="{theme: 'vs-dark', fontSize: 15}" language="sql" :height="300"
:key="activeKey.value" @change="handlerChangeEditorValue" :width="'100%'"
v-model:value="activeEditorValue" @editorDidMount="handlerEditorDidMount($event, 'mysql')">
:key="activeKey.value" @change="handlerChangeEditorValue" :width="'100%'"
v-model:value="activeEditorValue" @editorDidMount="handlerEditorDidMount($event, 'mysql')">
</MonacoEditor>
</Tabs>
</div>
@ -79,6 +85,7 @@
<SnippetDetails v-if="snippetDetails" :isVisible="snippetDetails"
:codeSnippet="activeEditorValue" @close="handlerCloseSnippetDetails($event)">
</SnippetDetails>
<QueryAiHelp v-if="visibleAiHelp" :isVisible="visibleAiHelp" :content="activeEditorValue" @close="handlerVisibleHelp($event)"></QueryAiHelp>
</div>
</template>
@ -100,6 +107,7 @@ import {AuditService} from "@/services/AuditService";
import FunctionsService from "@/services/settings/functions/FunctionsService";
import {useI18n} from "vue-i18n";
import DataLazyTree from "@/components/common/DataLazyTree.vue";
import QueryAiHelp from "@/views/pages/query/QueryAiHelp.vue";
const editors = ref<{ title: string; key: string; closable?: boolean }[]>([
{title: 'Editor', key: '1', closable: false}
@ -110,7 +118,7 @@ const editorValueMap = new Map<string, string>();
export default defineComponent({
name: "QueryHome",
components: {DataLazyTree, BasicTableComponent, SnippetDetails, SourceSelect, MonacoEditor},
components: {QueryAiHelp, DataLazyTree, BasicTableComponent, SnippetDetails, SourceSelect, MonacoEditor},
unmounted()
{
if (this.editorCompletionProvider) {
@ -140,17 +148,19 @@ export default defineComponent({
activeEditorValue: '',
editors,
activeKey,
editorValueMap
editorValueMap,
visibleAiHelp: false
}
},
created()
{
this.handlerInitialize();
},
mounted(){
window.onresize=()=>{
if(editorMap.values().next().value){
editorMap.values().next().value.layout({width: this.$refs.editorContainer.offsetWidth,height:300})
mounted()
{
window.onresize = () => {
if (editorMap.values().next().value) {
editorMap.values().next().value.layout({width: this.$refs.editorContainer.offsetWidth, height: 300})
}
}
},
@ -236,9 +246,9 @@ export default defineComponent({
});
}
});
setTimeout(()=>{
editorMap.values().next().value?.layout({width: this.$refs.editorContainer.offsetWidth,height:300})
},200)
setTimeout(() => {
editorMap.values().next().value?.layout({width: this.$refs.editorContainer.offsetWidth, height: 300})
}, 200)
},
handlerRun()
{
@ -348,6 +358,11 @@ export default defineComponent({
handlerChangeEditorValue(value: string)
{
editorValueMap.set(activeKey.value, value);
},
handlerVisibleHelp(value: boolean)
{
this.visibleAiHelp = value;
console.log(1)
}
},
// Prevents errors from affecting other components

View File

@ -33,7 +33,8 @@ public class SeatunnelExecutor
public void before(Pipeline configure)
{
JsonFactory jsonFactory = new JsonFactory();
try (JsonGenerator jsonGenerator = jsonFactory.createGenerator(new File(configure.getFile()), JsonEncoding.UTF8)) {
String workFile = String.join(File.separator, configure.getWork(), configure.getPipelineName() + ".configure");
try (JsonGenerator jsonGenerator = jsonFactory.createGenerator(new File(workFile), JsonEncoding.UTF8)) {
jsonGenerator.setPrettyPrinter(new DefaultPrettyPrinter());
jsonGenerator.writeStartObject();
this.writeChild("source", jsonGenerator, configure.getFrom());
@ -51,14 +52,16 @@ public class SeatunnelExecutor
before(configure);
SeaTunnelCommander commander = new SeaTunnelCommander(
configure.getHome() + "/bin",
String.join("/", configure.getWork(), configure.getFile()),
configure.getUsername());
LoggerExecutor loggerExecutor = new LogbackExecutor(configure.getWork(), configure.getUsername());
ShellConfigure shellConfigure = new ShellConfigure();
shellConfigure.setDirectory(configure.getWork());
shellConfigure.setLoggerExecutor(loggerExecutor);
shellConfigure.setCommand(Arrays.asList(commander.toCommand()));
shellConfigure.setTimeout(configure.getTimeout());
String.join(File.separator, configure.getWork(), configure.getPipelineName() + ".configure"),
configure.getPipelineName());
LoggerExecutor loggerExecutor = new LogbackExecutor(configure.getWork(), configure.getPipelineName() + ".log");
ShellConfigure shellConfigure = ShellConfigure.builder()
.directory(configure.getWork())
.loggerExecutor(loggerExecutor)
.command(Arrays.asList(commander.toCommand()))
.timeout(configure.getTimeout())
.username(configure.getUsername())
.build();
ShellCommander shellExecutor = new ProcessBuilderCommander(shellConfigure);
ShellResponse response = shellExecutor.execute();
if (!response.getSuccessful()) {
@ -81,5 +84,6 @@ public class SeatunnelExecutor
}
jsonGenerator.writeEndObject();
}
jsonGenerator.writeEndObject();
}
}

View File

@ -2,26 +2,15 @@ package io.edurt.datacap.executor.connector;
import io.edurt.datacap.spi.executor.PipelineField;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ConnectorClickHouse
extends Connector
{
private static final Set<String> supportOptions = new HashSet<String>()
{{
add("host");
add("database");
add("sql");
add("username");
add("password");
}};
public ConnectorClickHouse(ConnectorType type, PipelineField configure)
{
super(type, configure, supportOptions);
super(type, configure, configure.getSupportOptions());
}
@Override

View File

@ -5,10 +5,20 @@ import io.edurt.datacap.spi.executor.PipelineField;
import org.junit.Before;
import org.junit.Test;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
public class SeatunnelExecutorTest
{
private static final Set<String> supportOptions = new HashSet<String>()
{{
add("host");
add("database");
add("sql");
add("username");
add("password");
}};
private Pipeline pipeline;
@Before
@ -22,9 +32,11 @@ public class SeatunnelExecutorTest
properties.put("password", "123456");
properties.put("database", "default");
properties.put("sql", "SHOW DATABASES");
PipelineField from = PipelineField.builder()
.type("ClickHouse")
.configure(properties)
.supportOptions(supportOptions)
.build();
pipeline.setFrom(from);
pipeline.setTo(PipelineField.builder().type("Console").build());

View File

@ -2,6 +2,7 @@ package io.edurt.datacap.lib.shell;
import io.edurt.datacap.lib.logger.LoggerExecutor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@ -9,6 +10,7 @@ import lombok.ToString;
import java.util.List;
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor

View File

@ -34,6 +34,7 @@ public class ProcessBuilderCommander
{
LoggerExecutor loggerExecutor = this.configure.getLoggerExecutor();
Logger logger = (Logger) loggerExecutor.getLogger();
logger.info("Execute pipeline on username {}", configure.getUsername());
ShellResponse shellResponse = new ShellResponse();
shellResponse.setSuccessful(Boolean.TRUE);
List<String> command = new ArrayList<>();
@ -49,8 +50,9 @@ public class ProcessBuilderCommander
logger.info("Work directory {}", configure.getDirectory());
Map<String, String> environment = this.getEnvironment();
builder.environment().putAll(environment);
logger.info("========== container environment loading ==========");
logger.info("========== container environment start ==========");
environment.keySet().forEach(key -> logger.info("Container environment {}={}", key, environment.get(key)));
logger.info("========== container environment end ==========");
Process process = null;
try {
@ -79,6 +81,9 @@ public class ProcessBuilderCommander
}
}
shellResponse.setCode(process.exitValue());
if (process.exitValue() > 0) {
shellResponse.setSuccessful(Boolean.FALSE);
}
}
catch (Exception ex) {
logger.error("Execute failed ", ex);
@ -89,8 +94,8 @@ public class ProcessBuilderCommander
process.destroy();
}
logger.info("Execute response {}", shellResponse);
logger.info("Execute end destroy logger components");
loggerExecutor.destroy();
logger.info("Execute end destroy logger components successful");
}
return shellResponse;
}