feat: 2.26 load *.sql ddl comment | 读取 *.sql ddl 注释
This commit is contained in:
@@ -14,6 +14,7 @@ import io.github.linwancen.plugin.show.bean.LineInfo;
|
||||
import io.github.linwancen.plugin.show.bean.SettingsInfo;
|
||||
import io.github.linwancen.plugin.show.cache.LineEndCacheUtils;
|
||||
import io.github.linwancen.plugin.show.ext.LineExt;
|
||||
import io.github.linwancen.plugin.show.ext.sql.SqlDoc;
|
||||
import io.github.linwancen.plugin.show.lang.base.BaseLangDoc;
|
||||
import io.github.linwancen.plugin.show.line.LineSelect;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -112,10 +113,17 @@ public class LineEnd extends EditorLinePainter {
|
||||
}
|
||||
|
||||
private static @Nullable String lineDocSkipHave(@NotNull LineInfo info) {
|
||||
@Nullable String doc = LineExt.doc(info);
|
||||
int i = info.text.indexOf(info.appSettings.lineEndPrefix);
|
||||
@NotNull String code = i <= 0 ? info.text : info.text.substring(0, i);
|
||||
@Nullable String doc = LineExt.extDoc(info, code);
|
||||
if (doc == null) {
|
||||
// include table and column doc from db
|
||||
doc = BaseLangDoc.langDoc(info);
|
||||
}
|
||||
if (doc == null) {
|
||||
// table and column doc from *.sql ddl
|
||||
doc = SqlDoc.sqlDoc(info, code);
|
||||
}
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class LineEndAdd extends CopyReferenceAction {
|
||||
int startLine = 0;
|
||||
int endLine = info.document.getLineCount() - 1;
|
||||
LineEnd.textWithDoc(info, startLine, endLine, indicator, s ->
|
||||
info.document.replaceString(0, info.document.getTextLength() - 1, s)
|
||||
info.document.replaceString(0, info.document.getTextLength(), s)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -14,20 +14,6 @@ public class LineExt {
|
||||
|
||||
private LineExt() {}
|
||||
|
||||
public static @Nullable String doc(@NotNull LineInfo info) {
|
||||
int i = info.text.indexOf(info.appSettings.lineEndPrefix);
|
||||
@NotNull String code = i <= 0 ? info.text : info.text.substring(0, i);
|
||||
@Nullable String extDoc = LineExt.extDoc(info, code);
|
||||
if (extDoc == null) {
|
||||
return null;
|
||||
}
|
||||
extDoc = extDoc.trim();
|
||||
if (info.text.endsWith(extDoc)) {
|
||||
return null;
|
||||
}
|
||||
return extDoc;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String extDoc(@NotNull LineInfo info, @NotNull String code) {
|
||||
@NotNull String path = info.file.getPath();
|
||||
|
||||
@@ -25,10 +25,7 @@ public abstract class FileLoader {
|
||||
public final Map<VirtualFile, String> fileDoc = new ConcurrentHashMap<>();
|
||||
|
||||
@Nullable
|
||||
public String treeDoc(@Nullable VirtualFile virtualFile) {
|
||||
if (virtualFile == null) {
|
||||
return null;
|
||||
}
|
||||
public String treeDoc(@NotNull VirtualFile virtualFile) {
|
||||
return fileDoc.get(virtualFile);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
package io.github.linwancen.plugin.show.ext.sql;
|
||||
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.search.FilenameIndex;
|
||||
import io.github.linwancen.plugin.show.ext.listener.FileLoader;
|
||||
import io.github.linwancen.plugin.show.lang.base.PsiUnSaveUtils;
|
||||
import io.github.linwancen.plugin.show.settings.GlobalSettingsState;
|
||||
import io.github.linwancen.plugin.show.settings.ProjectSettingsState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SqlCache extends FileLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(SqlCache.class);
|
||||
|
||||
/**
|
||||
* support sql in other project
|
||||
*/
|
||||
public static final Map<String, String> TABLE_DOC_CACHE = new ConcurrentHashMap<>();
|
||||
public static final Map<String, String> COLUMN_DOC_CACHE = new ConcurrentHashMap<>();
|
||||
public static final Map<String, String> INDEX_DOC_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
private SqlCache() {}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String treeDoc(@NotNull VirtualFile virtualFile) {
|
||||
String name = virtualFile.getNameWithoutExtension();
|
||||
return TABLE_DOC_CACHE.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAll() {
|
||||
TABLE_DOC_CACHE.clear();
|
||||
COLUMN_DOC_CACHE.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(@NotNull VirtualFile file, @Nullable String name) {}
|
||||
|
||||
@Override
|
||||
public void copyImpl(@NotNull VirtualFile file, @NotNull VirtualFile newFile) {}
|
||||
|
||||
@Override
|
||||
public void loadAllImpl(@NotNull Project project) {
|
||||
GlobalSettingsState g = GlobalSettingsState.getInstance();
|
||||
ProjectSettingsState p = ProjectSettingsState.getInstance(project);
|
||||
if (!g.sqlSplitEffect && !p.sqlSplitEffect) {
|
||||
return;
|
||||
}
|
||||
@NotNull Collection<VirtualFile> files = FilenameIndex.getAllFilesByExt(project, "sql");
|
||||
@NotNull StringBuilder sb = new StringBuilder();
|
||||
for (@NotNull VirtualFile file : files) {
|
||||
loadFileImpl(file, project);
|
||||
sb.append(file.getName()).append("\n");
|
||||
}
|
||||
if (files.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!project.isDisposed()) {
|
||||
ProjectView.getInstance(project).refresh();
|
||||
}
|
||||
LOG.info("SQL doc load all complete {} files\n{}", files.size(), sb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadFileImpl(@NotNull VirtualFile file, @Nullable Project project) {
|
||||
String code = PsiUnSaveUtils.fileText(project, file);
|
||||
if (code == null) {
|
||||
return;
|
||||
}
|
||||
GlobalSettingsState g = GlobalSettingsState.getInstance();
|
||||
loadSqlDoc(code, TABLE_DOC_CACHE, g.tableDocEffect, g.tableDoc);
|
||||
loadSqlDoc(code, COLUMN_DOC_CACHE, g.columnDocEffect, g.columnDoc);
|
||||
loadSqlDoc(code, INDEX_DOC_CACHE, g.indexDocEffect, g.indexDoc);
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
ProjectSettingsState p = ProjectSettingsState.getInstance(project);
|
||||
loadSqlDoc(code, TABLE_DOC_CACHE, p.tableDocEffect, p.tableDoc);
|
||||
loadSqlDoc(code, COLUMN_DOC_CACHE, p.columnDocEffect, p.columnDoc);
|
||||
loadSqlDoc(code, INDEX_DOC_CACHE, p.indexDocEffect, p.indexDoc);
|
||||
}
|
||||
|
||||
public static final Pattern KEY_PATTERN = Pattern.compile("`?, *`?");
|
||||
|
||||
private static void loadSqlDoc(@NotNull String code, @NotNull Map<String, String> map,
|
||||
boolean effect, Map<String, Pattern[]> patternMap) {
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
for (Pattern[] patterns : patternMap.values()) {
|
||||
for (Pattern pattern : patterns) {
|
||||
Matcher m = pattern.matcher(code);
|
||||
while (m.find()) {
|
||||
String key = m.group(1);
|
||||
String comment = m.group(2);
|
||||
if (!key.contains(",")) {
|
||||
putComment(map, key, comment);
|
||||
continue;
|
||||
}
|
||||
// multi column index seq
|
||||
String[] split = KEY_PATTERN.split(key);
|
||||
for (int i = 0; i < split.length; i++) {
|
||||
String k = split[i];
|
||||
putComment(map, k, String.valueOf(i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern IGNORE_KEY_PATTERN = Pattern.compile("(?i)^(id|name)$");
|
||||
|
||||
private static void putComment(@NotNull Map<String, String> map, @NotNull String k, String comment) {
|
||||
if (IGNORE_KEY_PATTERN.matcher(k).find()) {
|
||||
return;
|
||||
}
|
||||
String s = map.get(k);
|
||||
if (s != null && !s.equalsIgnoreCase(comment) && !s.contains(comment)) {
|
||||
map.put(k, s + " | " + comment);
|
||||
} else {
|
||||
map.put(k, comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package io.github.linwancen.plugin.show.ext.sql;
|
||||
|
||||
import io.github.linwancen.plugin.show.bean.LineInfo;
|
||||
import io.github.linwancen.plugin.show.settings.AbstractSettingsState;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class SqlDoc {
|
||||
|
||||
@Nullable
|
||||
public static String sqlDoc(@NotNull LineInfo info, @NotNull String code) {
|
||||
String extension = info.file.getExtension();
|
||||
if (extension == null) {
|
||||
return null;
|
||||
}
|
||||
String s = sqlDocState(extension, info.projectSettings, code);
|
||||
if (s != null) {
|
||||
return s;
|
||||
}
|
||||
return sqlDocState(extension, info.globalSettings, code);
|
||||
}
|
||||
|
||||
private static String sqlDocState(@NotNull String extension, @NotNull AbstractSettingsState state,
|
||||
@NotNull String code) {
|
||||
if (!state.sqlSplitEffect) {
|
||||
return null;
|
||||
}
|
||||
Pattern[] patterns = state.sqlSplit.get(extension);
|
||||
if (patterns == null) {
|
||||
return null;
|
||||
}
|
||||
for (Pattern pattern : patterns) {
|
||||
return sqlDocPattern(pattern, code);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static String sqlDocPattern(@NotNull Pattern pattern, @NotNull String code) {
|
||||
String[] words = pattern.split(code);
|
||||
@NotNull Matcher matcher = pattern.matcher(code);
|
||||
|
||||
boolean haveDoc = false;
|
||||
boolean haveKey = false;
|
||||
@NotNull StringBuilder sb = new StringBuilder();
|
||||
for (@NotNull String s : words) {
|
||||
haveDoc |= appendDocSQL(sb, s);
|
||||
haveKey = appendKeyDocSQL(sb, matcher);
|
||||
}
|
||||
while (haveKey) {
|
||||
haveKey = appendKeyDocSQL(sb, matcher);
|
||||
}
|
||||
if (!haveDoc) {
|
||||
return null;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static boolean appendDocSQL(@NotNull StringBuilder sb, @NotNull String word) {
|
||||
word = word.trim();
|
||||
if (word.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
@Nullable String tableDoc = SqlCache.TABLE_DOC_CACHE.get(word);
|
||||
if (tableDoc != null) {
|
||||
sb.append(tableDoc);
|
||||
return true;
|
||||
}
|
||||
@Nullable String columnDoc = SqlCache.COLUMN_DOC_CACHE.get(word);
|
||||
if (columnDoc != null) {
|
||||
sb.append(columnDoc);
|
||||
@Nullable String indexDoc = SqlCache.INDEX_DOC_CACHE.get(word);
|
||||
if (indexDoc != null) {
|
||||
sb.append(indexSymbol(indexDoc));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
sb.append(" ");
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String indexSymbol(String indexDoc) {
|
||||
switch (indexDoc) {
|
||||
case "primary":
|
||||
case "PRIMARY":
|
||||
return " √ P";
|
||||
case "UNIQUE":
|
||||
case "unique":
|
||||
return " √ U";
|
||||
case ")":
|
||||
return " √";
|
||||
default:
|
||||
// multi column index seq
|
||||
return " √ " + indexDoc;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean appendKeyDocSQL(@NotNull StringBuilder sb, @NotNull Matcher matcher) {
|
||||
if (!matcher.find()) {
|
||||
return false;
|
||||
}
|
||||
String keyword = matcher.group();
|
||||
keyword = unescape(keyword);
|
||||
sb.append(keyword);
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String unescape(String keyword) {
|
||||
// >|<|&|"|'
|
||||
switch (keyword) {
|
||||
case ">":
|
||||
return ">";
|
||||
case "<":
|
||||
return "<";
|
||||
case "&":
|
||||
return "&";
|
||||
case """:
|
||||
return "\"";
|
||||
case "'":
|
||||
return "'";
|
||||
default:
|
||||
return " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
package io.github.linwancen.plugin.show.lang.base;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiUnSaveUtils {
|
||||
|
||||
@@ -36,4 +42,20 @@ public class PsiUnSaveUtils {
|
||||
return element.getText();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String fileText(@Nullable Project project, @NotNull VirtualFile file) {
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document != null) {
|
||||
return document.getText();
|
||||
}
|
||||
if (project == null) {
|
||||
return null;
|
||||
}
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
if (psiFile != null) {
|
||||
return psiFile.getText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,11 +33,25 @@ public abstract class AbstractSettingsComponent {
|
||||
private final JBTextField docGet = new JBTextField();
|
||||
private final JBCheckBox annoDocEffect = new JBCheckBox("");
|
||||
private final JBTextArea annoDoc = new JBTextArea();
|
||||
|
||||
// region PatternMap: dirDoc fileDoc sqlSplit tableDoc columnDoc indexDoc
|
||||
|
||||
private final JBCheckBox dirDocEffect = new JBCheckBox("");
|
||||
private final JBTextArea dirDoc = new JBTextArea();
|
||||
private final JBCheckBox fileDocEffect = new JBCheckBox("");
|
||||
private final JBTextArea fileDoc = new JBTextArea();
|
||||
|
||||
protected final JBCheckBox sqlSplitEffect = new JBCheckBox("");
|
||||
private final JBTextArea sqlSplit = new JBTextArea();
|
||||
private final JBCheckBox tableDocEffect = new JBCheckBox("");
|
||||
private final JBTextArea tableDoc = new JBTextArea();
|
||||
private final JBCheckBox columnDocEffect = new JBCheckBox("");
|
||||
private final JBTextArea columnDoc = new JBTextArea();
|
||||
private final JBCheckBox indexDocEffect = new JBCheckBox("");
|
||||
private final JBTextArea indexDoc = new JBTextArea();
|
||||
|
||||
// endregion
|
||||
|
||||
@NotNull
|
||||
protected JPanel commonPanel() {
|
||||
return FormBuilder.createFormBuilder()
|
||||
@@ -97,6 +111,24 @@ public abstract class AbstractSettingsComponent {
|
||||
return panel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@NotNull
|
||||
private JPanel sqlPanel() {
|
||||
// sqlSplit tableDoc columnDoc indexDoc
|
||||
@NotNull JPanel sqlLabel = JPanelFactory.of(sqlSplitEffect, new JBLabel(ShowBundle.message("sql.split.regexp")));
|
||||
@NotNull JPanel tableLabel = JPanelFactory.of(tableDocEffect, new JBLabel(ShowBundle.message("table.doc.regexp")));
|
||||
@NotNull JPanel columnLabel = JPanelFactory.of(columnDocEffect, new JBLabel(ShowBundle.message("column.doc.regexp")));
|
||||
@NotNull JPanel indexLabel = JPanelFactory.of(indexDocEffect, new JBLabel(ShowBundle.message("index.doc.regexp")));
|
||||
JPanel panel = FormBuilder.createFormBuilder()
|
||||
.addLabeledComponent(sqlLabel, sqlSplit, 1, true)
|
||||
.addLabeledComponent(tableLabel, tableDoc, 1, true)
|
||||
.addLabeledComponent(columnLabel, columnDoc, 1, true)
|
||||
.addLabeledComponent(indexLabel, indexDoc, 1, true)
|
||||
.getPanel();
|
||||
panel.setBorder(IdeBorderFactory.createTitledBorder(ShowBundle.message("sql.comment")));
|
||||
return panel;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLineEndCount() {
|
||||
return lineEndCount.getText();
|
||||
@@ -223,6 +255,7 @@ public abstract class AbstractSettingsComponent {
|
||||
annoDoc.setText(newText);
|
||||
}
|
||||
|
||||
// region PatternMap
|
||||
|
||||
public boolean getDirDocEffect() {
|
||||
return dirDocEffect.isSelected();
|
||||
@@ -258,4 +291,74 @@ public abstract class AbstractSettingsComponent {
|
||||
public void setFileDoc(@NotNull String newText) {
|
||||
fileDoc.setText(newText);
|
||||
}
|
||||
|
||||
public boolean getSqlSplitEffect() {
|
||||
return sqlSplitEffect.isSelected();
|
||||
}
|
||||
|
||||
public void setSqlSplitEffect(boolean newStatus) {
|
||||
sqlSplitEffect.setSelected(newStatus);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getSqlSplit() {
|
||||
return sqlSplit.getText();
|
||||
}
|
||||
|
||||
public void setSqlSplit(@NotNull String newText) {
|
||||
sqlSplit.setText(newText);
|
||||
}
|
||||
|
||||
public boolean getTableDocEffect() {
|
||||
return tableDocEffect.isSelected();
|
||||
}
|
||||
|
||||
public void setTableDocEffect(boolean newStatus) {
|
||||
tableDocEffect.setSelected(newStatus);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTableDoc() {
|
||||
return tableDoc.getText();
|
||||
}
|
||||
|
||||
public void setTableDoc(@NotNull String newText) {
|
||||
tableDoc.setText(newText);
|
||||
}
|
||||
|
||||
public boolean getColumnDocEffect() {
|
||||
return columnDocEffect.isSelected();
|
||||
}
|
||||
|
||||
public void setColumnDocEffect(boolean newStatus) {
|
||||
columnDocEffect.setSelected(newStatus);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getColumnDoc() {
|
||||
return columnDoc.getText();
|
||||
}
|
||||
|
||||
public void setColumnDoc(@NotNull String newText) {
|
||||
columnDoc.setText(newText);
|
||||
}
|
||||
|
||||
public boolean getIndexDocEffect() {
|
||||
return indexDocEffect.isSelected();
|
||||
}
|
||||
|
||||
public void setIndexDocEffect(boolean newStatus) {
|
||||
indexDocEffect.setSelected(newStatus);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getIndexDoc() {
|
||||
return indexDoc.getText();
|
||||
}
|
||||
|
||||
public void setIndexDoc(@NotNull String newText) {
|
||||
indexDoc.setText(newText);
|
||||
}
|
||||
|
||||
// endregion PatternMap for AI: dirDoc fileDoc sqlSplit tableDoc columnDoc indexDoc
|
||||
}
|
||||
|
||||
@@ -26,6 +26,14 @@ public class AbstractSettingsConfigurable {
|
||||
modified |= !component.getDirDoc().equals(settings.getDirDoc());
|
||||
modified |= component.getFileDocEffect() != settings.fileDocEffect;
|
||||
modified |= !component.getFileDoc().equals(settings.getFileDoc());
|
||||
modified |= component.getSqlSplitEffect() != settings.sqlSplitEffect;
|
||||
modified |= !component.getSqlSplit().equals(settings.getSqlSplit());
|
||||
modified |= component.getTableDocEffect() != settings.tableDocEffect;
|
||||
modified |= !component.getTableDoc().equals(settings.getTableDoc());
|
||||
modified |= component.getColumnDocEffect() != settings.columnDocEffect;
|
||||
modified |= !component.getColumnDoc().equals(settings.getColumnDoc());
|
||||
modified |= component.getIndexDocEffect() != settings.indexDocEffect;
|
||||
modified |= !component.getIndexDoc().equals(settings.getIndexDoc());
|
||||
return modified;
|
||||
}
|
||||
|
||||
@@ -52,6 +60,14 @@ public class AbstractSettingsConfigurable {
|
||||
settings.setDirDoc(component.getDirDoc());
|
||||
settings.fileDocEffect = component.getFileDocEffect();
|
||||
settings.setFileDoc(component.getFileDoc());
|
||||
settings.sqlSplitEffect = component.getSqlSplitEffect();
|
||||
settings.setSqlSplit(component.getSqlSplit());
|
||||
settings.tableDocEffect = component.getTableDocEffect();
|
||||
settings.setTableDoc(component.getTableDoc());
|
||||
settings.columnDocEffect = component.getColumnDocEffect();
|
||||
settings.setColumnDoc(component.getColumnDoc());
|
||||
settings.indexDocEffect = component.getIndexDocEffect();
|
||||
settings.setIndexDoc(component.getIndexDoc());
|
||||
}
|
||||
|
||||
static void reset(@NotNull AbstractSettingsState settings, @NotNull AbstractSettingsComponent component) {
|
||||
@@ -73,5 +89,13 @@ public class AbstractSettingsConfigurable {
|
||||
component.setDirDoc(settings.getDirDoc());
|
||||
component.setFileDocEffect(settings.fileDocEffect);
|
||||
component.setFileDoc(settings.getFileDoc());
|
||||
component.setSqlSplitEffect(settings.sqlSplitEffect);
|
||||
component.setSqlSplit(settings.getSqlSplit());
|
||||
component.setTableDocEffect(settings.tableDocEffect);
|
||||
component.setTableDoc(settings.getTableDoc());
|
||||
component.setColumnDocEffect(settings.columnDocEffect);
|
||||
component.setColumnDoc(settings.getColumnDoc());
|
||||
component.setIndexDocEffect(settings.indexDocEffect);
|
||||
component.setIndexDoc(settings.getIndexDoc());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ public abstract class AbstractSettingsState {
|
||||
{"field", "cn.idev.excel.annotation.ExcelProperty", "value"},
|
||||
};
|
||||
|
||||
// region PatternMap: dirDoc fileDoc sqlSplit tableDoc columnDoc indexDoc
|
||||
|
||||
public boolean dirDocEffect = true;
|
||||
@NotNull
|
||||
public transient Map<String, Pattern[]> dirDoc = new LinkedHashMap<>() {{
|
||||
@@ -68,6 +70,57 @@ public abstract class AbstractSettingsState {
|
||||
put("sh", new Pattern[]{Pattern.compile("(?m)^#++ *([^!].*)")});
|
||||
}};
|
||||
|
||||
public boolean sqlSplitEffect = true;
|
||||
@NotNull
|
||||
public transient Map<String, Pattern[]> sqlSplit = new LinkedHashMap<>() {{
|
||||
put("sql", new Pattern[]{Pattern.compile("\\W")});
|
||||
put("xml", new Pattern[]{Pattern.compile(",|" +
|
||||
"<.+=|" +
|
||||
" ?[!=].*>|" +
|
||||
"[<=>/\"\\s()]|" +
|
||||
"#\\{[^}]++}|" +
|
||||
"\\w++\\.|" +
|
||||
">|<|&|"|'")});
|
||||
}};
|
||||
|
||||
public boolean tableDocEffect = true;
|
||||
@NotNull
|
||||
public transient Map<String, Pattern[]> tableDoc = new LinkedHashMap<>() {{
|
||||
put("Oracle", new Pattern[]{Pattern.compile("(?i)comment\\s++on\\s++table\\s++" +
|
||||
"(?:['\"]?\\w++['\"]?\\s*+\\.\\s*+)?" +
|
||||
"['\"]?(\\w++)['\"]?\\s++" +
|
||||
"is\\s++['\"]([^'\"]++)")});
|
||||
put("MySQL", new Pattern[]{Pattern.compile("(?i)table(?:\\s++if\\s++not\\s++exists)?\\s++" +
|
||||
"(?:`?\\w++`?\\.)?" +
|
||||
"`?(\\w++)[^;]+?" +
|
||||
"comment\\s*+=\\s*+['\"]([^'\"]++)")});
|
||||
}};
|
||||
|
||||
public boolean columnDocEffect = true;
|
||||
@NotNull
|
||||
public transient Map<String, Pattern[]> columnDoc = new LinkedHashMap<>() {{
|
||||
put("Oracle", new Pattern[]{Pattern.compile("(?i)comment\\s++on\\s++column\\s++" +
|
||||
"(?:['\"]?\\w++['\"]?\\s*+\\.\\s*+)?" +
|
||||
"['\"]?\\w++['\"]?\\s*+\\.\\s*+" +
|
||||
"['\"]?(\\w++)['\"]?" +
|
||||
"\\s++is\\s++['\"]([^'\"]++)")});
|
||||
put("MySQL", new Pattern[]{Pattern.compile("(?i)\\W(\\w++)`?\\s++" +
|
||||
"(?:varchar|int|tinyint|char|text|decimal|datetime|timestamp|time|date|float|double|bigint|mediumtext" +
|
||||
"|longtext|tinytext|enum|set|json|boolean|bit|binary|varbinary|blob|mediumblob|longblob|tinyblob).+?" +
|
||||
"comment\\s++['\"]([^'\"]++)")});
|
||||
}};
|
||||
|
||||
public boolean indexDocEffect = true;
|
||||
@NotNull
|
||||
public transient Map<String, Pattern[]> indexDoc = new LinkedHashMap<>() {{
|
||||
put("add", new Pattern[]{Pattern.compile("(?i)(?:index|primary).+?\\(`?([^)]+?)`?(\\))")});
|
||||
put("create", new Pattern[]{Pattern.compile("(?i)\\W(\\w++)`?\\s++" +
|
||||
"(?:varchar|int|tinyint|char|text|decimal|datetime|timestamp|time|date|float|double|bigint|mediumtext" +
|
||||
"|longtext|tinytext|enum|set|json|boolean|bit|binary|varbinary|blob|mediumblob|longblob|tinyblob).+?" +
|
||||
"(primary|unique)")});
|
||||
}};
|
||||
|
||||
// endregion
|
||||
|
||||
public String getLineInclude() {
|
||||
return lineInclude.pattern();
|
||||
@@ -179,4 +232,40 @@ public abstract class AbstractSettingsState {
|
||||
public void setFileDoc(@NotNull String fileDoc) {
|
||||
this.fileDoc = PatternMapUtils.toMap(fileDoc);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getSqlSplit() {
|
||||
return PatternMapUtils.toString(sqlSplit);
|
||||
}
|
||||
|
||||
public void setSqlSplit(@NotNull String sqlSplit) {
|
||||
this.sqlSplit = PatternMapUtils.toMap(sqlSplit);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getTableDoc() {
|
||||
return PatternMapUtils.toString(tableDoc);
|
||||
}
|
||||
|
||||
public void setTableDoc(@NotNull String tableDoc) {
|
||||
this.tableDoc = PatternMapUtils.toMap(tableDoc);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getColumnDoc() {
|
||||
return PatternMapUtils.toString(columnDoc);
|
||||
}
|
||||
|
||||
public void setColumnDoc(@NotNull String columnDoc) {
|
||||
this.columnDoc = PatternMapUtils.toMap(columnDoc);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getIndexDoc() {
|
||||
return PatternMapUtils.toString(indexDoc);
|
||||
}
|
||||
|
||||
public void setIndexDoc(@NotNull String indexDoc) {
|
||||
this.indexDoc = PatternMapUtils.toMap(indexDoc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ public class GlobalSettingsComponent extends AbstractSettingsComponent {
|
||||
resetDefault.addActionListener(e -> GlobalSettingsConfigurable.reset(GlobalSettingsState.DEFAULT_SETTING, this));
|
||||
myMainPanel = FormBuilder.createFormBuilder()
|
||||
.addComponent(JPanelFactory.of(resetDefault,
|
||||
new JBLabel(ShowBundle.message("line.count")), lineEndCount
|
||||
new JBLabel(ShowBundle.message("line.count")), lineEndCount,
|
||||
JPanelFactory.of(sqlSplitEffect, new JBLabel(ShowBundle.message("sql.comment")))
|
||||
), 1)
|
||||
.addComponent(commonPanel(), 1)
|
||||
.addComponentFillVertically(new JPanel(), 0)
|
||||
|
||||
@@ -28,6 +28,12 @@ public class ProjectSettingsState extends AbstractSettingsState implements Persi
|
||||
this.dirDoc = Collections.emptyMap();
|
||||
this.fileDocEffect = false;
|
||||
this.fileDoc = Collections.emptyMap();
|
||||
this.sqlSplitEffect = false;
|
||||
this.sqlSplit = Collections.emptyMap();
|
||||
this.tableDocEffect = false;
|
||||
this.tableDoc = Collections.emptyMap();
|
||||
this.columnDocEffect = false;
|
||||
this.columnDoc = Collections.emptyMap();
|
||||
}
|
||||
|
||||
public static final ProjectSettingsState DEFAULT_SETTING = new ProjectSettingsState();
|
||||
|
||||
@@ -169,6 +169,7 @@ Show doc comment in the Project view Tree, line End, json, other
|
||||
</extensionPoints>
|
||||
<extensions defaultExtensionNs="io.github.linwancen.show-comment">
|
||||
<fileLoader implementation="io.github.linwancen.plugin.show.ext.conf.ConfCache"/>
|
||||
<fileLoader implementation="io.github.linwancen.plugin.show.ext.sql.SqlCache"/>
|
||||
<fileLoader implementation="io.github.linwancen.plugin.show.lang.XmlCache"/>
|
||||
<fileLoader implementation="io.github.linwancen.plugin.show.ext.ollama.OllamaModelsCache"/>
|
||||
</extensions>
|
||||
|
||||
@@ -25,6 +25,7 @@ prefix=prefix:
|
||||
line.end.comment=Line End Comment
|
||||
web.comment=Web Comment
|
||||
tree.comment=Tree Comment
|
||||
sql.comment=SQL Comment From *.sql
|
||||
regexp.tip=Separated by '|' (Regexp), use '' to include all or exclude none.
|
||||
sign.include.regexp=className#memberName include Regexp:
|
||||
sign.exclude.regexp=className#memberName exclude Regexp:
|
||||
@@ -36,8 +37,14 @@ attr.include.regexp=attr include Regexp:
|
||||
attr.exclude.regexp=attr exclude Regexp:
|
||||
get.doc.regexp=get doc Regexp, last () when had, default is first sentence .+?(?:[\u3002\r\n]|. ) :
|
||||
anno.doc=anno doc, class/method/field/!doc/all#AnnoFullName#methodName#methodName2, Separated by \\n:
|
||||
# region PatternMap: dirDoc fileDoc sqlSplit tableDoc columnDoc indexDoc
|
||||
dir.doc.regexp=dir doc, fileName||Regexp1||Regexp2\\n:
|
||||
file.doc.regexp=file doc, fileExtension||Regexp1||Regexp2\\n:
|
||||
sql.split.regexp=sql split, fileExtension||Regexp1||Regexp2\\n:
|
||||
table.doc.regexp=table doc, fileExtension||Regexp1||Regexp2\\n:
|
||||
column.doc.regexp=column doc, fileExtension||Regexp1||Regexp2\\n:
|
||||
index.doc.regexp=index doc, fileExtension||Regexp1||Regexp2\\n:
|
||||
# endregion
|
||||
|
||||
global.settings.effective=Global Settings Effective
|
||||
project.settings.effective=Project Settings Effective
|
||||
|
||||
@@ -25,6 +25,7 @@ prefix=\u524D\u7F00\uFF1A
|
||||
line.end.comment=\u884C\u672B\u6CE8\u91CA
|
||||
web.comment=Web \u6CE8\u91CA
|
||||
tree.comment=\u6811\u6CE8\u91CA
|
||||
sql.comment=SQL\u6CE8\u91CA\u6765\u81EA *.sql
|
||||
regexp.tip=| \u5206\u9694 (\u6B63\u5219), \u7A7A\u5B57\u7B26\u4E32\u4EE3\u8868\u5305\u62EC\u6240\u6709\u6216\u4E0D\u6392\u9664
|
||||
sign.include.regexp=\u7C7B#\u65B9\u6CD5 \u5305\u542B \u6B63\u5219\uFF1A
|
||||
sign.exclude.regexp=\u7C7B#\u65B9\u6CD5 \u6392\u9664 \u6B63\u5219\uFF1A
|
||||
@@ -36,8 +37,14 @@ attr.include.regexp=\u5C5E\u6027 \u5305\u542B \u6B63\u5219\uFF1A
|
||||
attr.exclude.regexp=\u5C5E\u6027 \u6392\u9664 \u6B63\u5219\uFF1A
|
||||
get.doc.regexp=\u6CE8\u91CA\u63D0\u53D6\u6B63\u5219\uFF0C\u82E5\u6709 () \u5219\u53D6\u6700\u540E\u4E00\u4E2A\uFF0C\u9ED8\u8BA4\u6B63\u5219\u662F\u7B2C\u4E00\u53E5 .+?(?:[\u3002\r\n]|. )\uFF1A
|
||||
anno.doc=\u6CE8\u89E3\u6CE8\u91CA\uFF0Cclass/method/field/!doc/all#\u6CE8\u89E3\u5168\u540D#\u65B9\u6CD5\u540D1#\u65B9\u6CD5\u540D2 \u6362\u884C\u5206\u9694\uFF1A
|
||||
# region PatternMap: dirDoc fileDoc sqlSplit tableDoc columnDoc indexDoc
|
||||
dir.doc.regexp=\u76EE\u5F55\u6CE8\u91CA\uFF0C\u6587\u4EF6\u540D||\u6B63\u52191||\u6B63\u52192\\n\uFF1A
|
||||
file.doc.regexp=\u6587\u4EF6\u6CE8\u91CA\uFF0C\u6587\u4EF6\u62D3\u5C55\u540D||\u6B63\u52191||\u6B63\u52192\\n\uFF1A
|
||||
sql.split.regexp=SQL\u5206\u9694\uFF0C\u6587\u4EF6\u62D3\u5C55\u540D||\u6B63\u52191||\u6B63\u52192\\n\uFF1A
|
||||
table.doc.regexp=\u8868\u6CE8\u91CA\uFF0C\u65B9\u6848\u540D||\u6B63\u52191||\u6B63\u52192\\n\uFF1A
|
||||
column.doc.regexp=\u5B57\u6BB5\u6CE8\u91CA\uFF0C\u65B9\u6848\u540D||\u6B63\u52191||\u6B63\u52192\\n\uFF1A
|
||||
index.doc.regexp=\u7D22\u5F15\u6CE8\u91CA\uFF0C\u65B9\u6848\u540D||\u6B63\u52191||\u6B63\u52192\\n\uFF1A
|
||||
# endregion
|
||||
|
||||
global.settings.effective=\u5168\u5C40\u914D\u7F6E\u751F\u6548
|
||||
project.settings.effective=\u9879\u76EE\u914D\u7F6E\u751F\u6548
|
||||
|
||||
@@ -28,4 +28,5 @@ FROM information_schema.`COLUMNS` c
|
||||
ON s.TABLE_SCHEMA = c.TABLE_SCHEMA AND s.TABLE_NAME = c.TABLE_NAME AND s.COLUMN_NAME = c.COLUMN_NAME
|
||||
WHERE c.COLUMN_COMMENT != ''
|
||||
AND c.TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
|
||||
AND c.COLUMN_NAME NOT IN ('id', 'name')
|
||||
GROUP BY c.COLUMN_NAME, c.COLUMN_COMMENT, c.TABLE_NAME, c.TABLE_SCHEMA;
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 来自*.sql的注释示例 -->
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="io.github.linwancen.plugin.show.mapper.FromSqlMapper">
|
||||
<select id="select1">
|
||||
select id,
|
||||
name,
|
||||
from_mysql_column,
|
||||
from_mysql_add_column,
|
||||
from_mysql_mod_column
|
||||
from from_mysql_table
|
||||
</select>
|
||||
<select id="select1">
|
||||
select
|
||||
id,
|
||||
name,
|
||||
from_oracle_column
|
||||
from from_oracle_table
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,21 @@
|
||||
-- MySQL 注释来源 DDL
|
||||
CREATE TABLE from_mysql_table
|
||||
(
|
||||
id INT NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||
from_mysql_column INT NOT NULL COMMENT '创建列',
|
||||
from_mysql_mod_column INT NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4 COMMENT ='表';
|
||||
|
||||
ALTER TABLE from_mysql_table COMMENT = '修改表';
|
||||
|
||||
ALTER TABLE from_mysql_table ADD from_mysql_add_column
|
||||
VARCHAR(255) COMMENT '增加列';
|
||||
|
||||
ALTER TABLE from_mysql_table
|
||||
MODIFY COLUMN from_mysql_mod_column
|
||||
DECIMAL(12, 2) DEFAULT 0 COMMENT '修改列';
|
||||
|
||||
CREATE INDEX idx1 ON from_mysql_table(from_mysql_column);
|
||||
CREATE INDEX idx1 ON from_mysql_table(from_mysql_add_column, from_mysql_mod_column);
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Oracle 注释来源 DDL
|
||||
COMMENT ON TABLE from_oracle_table IS '表';
|
||||
COMMENT ON COLUMN from_oracle_table.id IS '主键';
|
||||
COMMENT ON COLUMN from_oracle_table.name IS '名字';
|
||||
COMMENT ON COLUMN from_oracle_table.from_oracle_column IS '列';
|
||||
COMMENT ON TABLE schema1.from_oracle_table IS '带schema表';
|
||||
COMMENT ON COLUMN schema1.from_oracle_table.from_oracle_column IS '带schema列';
|
||||
Reference in New Issue
Block a user