[Refactor] Remove unused help module (#33367)
Signed-off-by: imay <buaa.zhaoc@gmail.com>
This commit is contained in:
parent
bc7bb0587a
commit
802d3624d0
|
|
@ -1,39 +0,0 @@
|
|||
name: Build help documents
|
||||
on:
|
||||
push
|
||||
jobs:
|
||||
build-help-resource:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get current branch name.
|
||||
id: branch-name
|
||||
uses: tj-actions/branch-names@v4.5
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ steps.branch-name.outputs.base_ref_branch }}
|
||||
- name: Remove
|
||||
run: |
|
||||
rm -f help-resource.zip
|
||||
- uses: montudor/action-zip@v1
|
||||
with:
|
||||
args: zip -qq -r help-resource.zip sql-reference
|
||||
- name: Submit
|
||||
run: |
|
||||
git config --global user.name 'StarRocks'
|
||||
git config --global user.email 'open@starrocks.com'
|
||||
repo=$(git remote get-url origin)
|
||||
repoNames=(${repo//\./ })
|
||||
locale=${repoNames[${#repoNames[@]}-1]}
|
||||
if [[ $locale == *\/* ]]
|
||||
then
|
||||
locale="en-us"
|
||||
fi
|
||||
mv help-resource.zip ../
|
||||
cd ..
|
||||
git clone https://${{ secrets.DOCS_HELP_USER }}:${{ secrets.DOCS_HELP_TOKEN }}@github.com/StarRocks/docs-help-resources.git
|
||||
cd docs-help-resources
|
||||
mkdir -p $locale
|
||||
mv -f ../help-resource.zip $locale/
|
||||
git add .
|
||||
git commit -am "Auto built"
|
||||
git push origin ${{ steps.branch-name.outputs.base_ref_branch }}
|
||||
|
|
@ -37,7 +37,6 @@ package com.starrocks.http;
|
|||
import com.starrocks.common.Config;
|
||||
import com.starrocks.http.action.BackendAction;
|
||||
import com.starrocks.http.action.HaAction;
|
||||
import com.starrocks.http.action.HelpAction;
|
||||
import com.starrocks.http.action.IndexAction;
|
||||
import com.starrocks.http.action.LogAction;
|
||||
import com.starrocks.http.action.QueryAction;
|
||||
|
|
@ -157,7 +156,6 @@ public class HttpServer {
|
|||
QueryProfileAction.registerAction(controller);
|
||||
SessionAction.registerAction(controller);
|
||||
VariableAction.registerAction(controller);
|
||||
HelpAction.registerAction(controller);
|
||||
StaticResourceAction.registerAction(controller);
|
||||
HaAction.registerAction(controller);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,221 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.starrocks.http.action;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.starrocks.http.ActionController;
|
||||
import com.starrocks.http.BaseRequest;
|
||||
import com.starrocks.http.BaseResponse;
|
||||
import com.starrocks.http.IllegalArgException;
|
||||
import com.starrocks.qe.HelpModule;
|
||||
import com.starrocks.qe.HelpTopic;
|
||||
import io.netty.handler.codec.http.HttpMethod;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HelpAction extends WebBaseAction {
|
||||
private static final String DIV_BACKGROUND_COLOR = "#FCFCFC";
|
||||
|
||||
String queryString = null;
|
||||
|
||||
public HelpAction(ActionController controller) {
|
||||
super(controller);
|
||||
}
|
||||
|
||||
public static void registerAction(ActionController controller) throws IllegalArgException {
|
||||
controller.registerHandler(HttpMethod.GET, "/help", new HelpAction(controller));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needAdmin() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeGet(BaseRequest request, BaseResponse response) {
|
||||
getPageHeader(request, response.getContent());
|
||||
appendHelpStyle(response.getContent());
|
||||
|
||||
queryString = request.getSingleParameter("query");
|
||||
if (Strings.isNullOrEmpty(queryString)) {
|
||||
// ATTN: according to Mysql protocol, the default query should be "contents"
|
||||
// when you want to get server side help.
|
||||
queryString = "contents";
|
||||
} else {
|
||||
queryString = queryString.trim();
|
||||
}
|
||||
appendHelpInfo(response.getContent());
|
||||
|
||||
getPageFooter(response.getContent());
|
||||
writeResponse(request, response);
|
||||
}
|
||||
|
||||
private void appendHelpInfo(StringBuilder buffer) {
|
||||
buffer.append("<h2>Help Info</h2>");
|
||||
buffer.append("<p>This page lists the help info, "
|
||||
+ "like 'help contents' in Mysql client.</p>");
|
||||
|
||||
appendSearchButton(buffer);
|
||||
appendExactMatchTopic(buffer);
|
||||
appendFuzzyMatchTopic(buffer);
|
||||
appendCategories(buffer);
|
||||
}
|
||||
|
||||
private void appendSearchButton(StringBuilder buffer) {
|
||||
buffer.append("<form class=\"form-search\">"
|
||||
+ "<div class=\"col-lg-3\" style=\"padding-left: 0px;\">"
|
||||
+ " <div class=\"input-group\">"
|
||||
+ " <input name = \"query\" type=\"text\" class=\"form-control\" placeholder=\"input here...\">"
|
||||
+ " <span class=\"input-group-btn\">"
|
||||
+ " <button class=\"btn btn-default\" type=\"submit\">Search</button>"
|
||||
+ " </span>"
|
||||
+ " </div>"
|
||||
+ "</div>"
|
||||
+ "<a href=\"/help\" class=\"btn btn-primary\">Back To Home</a>"
|
||||
+ "</form>");
|
||||
}
|
||||
|
||||
private void appendExactMatchTopic(StringBuilder buffer) {
|
||||
buffer.append("<h3>Exact Matching Topic</h3>");
|
||||
buffer.append("<div style=\"background-color:" + DIV_BACKGROUND_COLOR + ";"
|
||||
+ "padding:0px, 1px, 1px, 0px;"
|
||||
+ "\">");
|
||||
HelpModule module = HelpModule.getInstance();
|
||||
HelpTopic topic = module.getTopic(queryString);
|
||||
if (topic == null) {
|
||||
buffer.append("<pre>No Exact Matching Topic.</pre>");
|
||||
} else {
|
||||
appendOneTopicInfo(buffer, topic);
|
||||
}
|
||||
buffer.append("</div>");
|
||||
}
|
||||
|
||||
private void appendFuzzyMatchTopic(StringBuilder buffer) {
|
||||
buffer.append("<h3>Fuzzy Matching Topic(By Keyword)</h3>");
|
||||
buffer.append("<div style=\"background-color:" + DIV_BACKGROUND_COLOR + ";"
|
||||
+ "padding:0px, 1px, 1px, 0px;"
|
||||
+ "\">");
|
||||
HelpModule module = HelpModule.getInstance();
|
||||
List<String> topics = module.listTopicByKeyword(queryString);
|
||||
if (topics.isEmpty()) {
|
||||
buffer.append("<pre>No Fuzzy Matching Topic.</pre>");
|
||||
} else if (topics.size() == 1) {
|
||||
buffer.append("<p class=\"text-info\"> "
|
||||
+ "Find only one topic, show you the detail info below.</p>");
|
||||
appendOneTopicInfo(buffer, module.getTopic(topics.get(0)));
|
||||
} else {
|
||||
buffer.append("<p class=\"text-info\"> Find " + topics.size() + " topics:</p>");
|
||||
appendNameList(buffer, topics, "Topics");
|
||||
}
|
||||
buffer.append("</div>");
|
||||
}
|
||||
|
||||
private void appendCategories(StringBuilder buffer) {
|
||||
buffer.append("<h3>Category Info</h3>");
|
||||
buffer.append("<div style=\"background-color:" + DIV_BACKGROUND_COLOR + ";"
|
||||
+ "padding:0px, 1px, 1px, 0px;"
|
||||
+ "\">");
|
||||
HelpModule module = HelpModule.getInstance();
|
||||
List<String> categories = module.listCategoryByName(queryString);
|
||||
if (categories.isEmpty()) {
|
||||
buffer.append("<pre>No Matching Category.</pre>");
|
||||
} else if (categories.size() == 1) {
|
||||
buffer.append("<p class=\"text-info\"> "
|
||||
+ "Find only one category, so show you the detail info below. </p>");
|
||||
List<String> topics = module.listTopicByCategory(categories.get(0));
|
||||
if (topics.size() > 0) {
|
||||
buffer.append("<p class=\"text-info\"> Find "
|
||||
+ topics.size()
|
||||
+ " sub topics. </p>");
|
||||
appendNameList(buffer, topics, "Sub Topics");
|
||||
}
|
||||
|
||||
List<String> subCategories = module.listCategoryByCategory(categories.get(0));
|
||||
if (subCategories.size() > 0) {
|
||||
buffer.append("<p class=\"text-info\"> Find "
|
||||
+ subCategories.size()
|
||||
+ " sub categories. </p>");
|
||||
appendNameList(buffer, subCategories, "Sub Categories");
|
||||
}
|
||||
} else {
|
||||
buffer.append("<p> Find " + categories.size() + " category: </p>");
|
||||
appendNameList(buffer, categories, "Categories");
|
||||
}
|
||||
buffer.append("</div>");
|
||||
}
|
||||
|
||||
// The browser will combine continuous whitespace to one, we use <pre> tag to solve this issue.
|
||||
private void appendOneTopicInfo(StringBuilder buffer, HelpTopic topic) {
|
||||
buffer.append("<div style=\""
|
||||
+ "padding:9.5px; "
|
||||
+ "margin: 0 0 10px; "
|
||||
+ "background-color: #f5f5f5;"
|
||||
+ "border: 1px solid rgba(0, 0, 0, 0.15);"
|
||||
+ "-webkit-border-radius: 4px;"
|
||||
+ "-moz-border-radius: 4px;"
|
||||
+ "border-radius: 4px;"
|
||||
+ "font-family: Consolas;"
|
||||
+ "\">");
|
||||
buffer.append("<h4>'" + escapeHtmlInPreTag(topic.getName()) + "'</h4>");
|
||||
|
||||
buffer.append("<strong>Description</strong>");
|
||||
buffer.append("<pre class=\"topic_text\" style=\"border: 0px;\">"
|
||||
+ escapeHtmlInPreTag(topic.getDescription())
|
||||
+ "</pre>");
|
||||
|
||||
buffer.append("<strong>Example</strong>");
|
||||
buffer.append("<pre class=\"topic_text\" style=\"border: 0px\">"
|
||||
+ escapeHtmlInPreTag(topic.getExample())
|
||||
+ "</pre>");
|
||||
|
||||
buffer.append("<strong>Keyword</strong>");
|
||||
buffer.append("<pre class=\"topic_text\" style=\"border: 0px\">"
|
||||
+ escapeHtmlInPreTag(topic.getKeywords().toString())
|
||||
+ "</pre>");
|
||||
|
||||
buffer.append("<strong>Url</strong>");
|
||||
buffer.append("<pre class=\"topic_text\" style=\"border: 0px\">"
|
||||
+ escapeHtmlInPreTag(topic.getUrl())
|
||||
+ "</pre>");
|
||||
buffer.append("</div>");
|
||||
}
|
||||
|
||||
private void appendNameList(StringBuilder buffer, List<String> names, String tableHeadName) {
|
||||
buffer.append("<div style=\"padding:0px, 1px, 1px, 0px\">");
|
||||
buffer.append("<table "
|
||||
+ "class=\"table table-hover table-bordered table-striped table-hover\"><tr>");
|
||||
buffer.append("<th>" + tableHeadName + "</th>");
|
||||
|
||||
final String href = "?query=";
|
||||
for (String name : names) {
|
||||
buffer.append("<tr><td><a href=\"" + href + name + "\">" + name + "</a><br/></td></tr>");
|
||||
}
|
||||
buffer.append("</table>");
|
||||
buffer.append("</div>");
|
||||
}
|
||||
|
||||
private void appendHelpStyle(StringBuilder buffer) {
|
||||
buffer.append("<style type=\"text/css\">"
|
||||
+ ".topic_text {"
|
||||
+ " font-family: \"Consolas\";"
|
||||
+ " margin-left: 5px;"
|
||||
+ "}"
|
||||
+ "</style>");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,9 +307,6 @@ public class WebBaseAction extends BaseAction {
|
|||
.append("ha")
|
||||
.append("</a></li>");
|
||||
}
|
||||
sb.append("<li id=\"nav_help\"><a href=\"/help\">")
|
||||
.append("help")
|
||||
.append("</a></li></tr>");
|
||||
|
||||
sb.append(NAVIGATION_BAR_SUFFIX);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,330 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.starrocks.qe;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.starrocks.common.UserException;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
// Help module, used to get information of help
|
||||
public class HelpModule {
|
||||
private static final Logger LOG = LogManager.getLogger(HelpModule.class);
|
||||
private static volatile HelpModule instance = null;
|
||||
|
||||
private static final ImmutableList<String> EMPTY_LIST = ImmutableList.of();
|
||||
// Map from name to topic
|
||||
private ImmutableMap<String, HelpTopic> topicByName = ImmutableMap.of();
|
||||
|
||||
// Map keyword to topics that have this keyword
|
||||
private ImmutableListMultimap<String, String> topicByKeyword = ImmutableListMultimap.of();
|
||||
|
||||
// Map category to topics that belong to this category.
|
||||
private ImmutableListMultimap<String, String> topicByCategory = ImmutableListMultimap.of();
|
||||
|
||||
// Map parent category to children categories.
|
||||
private ImmutableListMultimap<String, String> categoryByParent = ImmutableListMultimap.of();
|
||||
|
||||
// Category set, case insensitive.
|
||||
private ImmutableMap<String, String> categoryByName = ImmutableMap.of();
|
||||
|
||||
// Temporary used. Used to build immutable map.
|
||||
private ImmutableSortedMap.Builder<String, String> categoryByNameBuilder;
|
||||
private ImmutableListMultimap.Builder<String, String> categoryByParentBuilder;
|
||||
private ImmutableListMultimap.Builder<String, String> topicByCatBuilder;
|
||||
private ImmutableListMultimap.Builder<String, String> topicByKeyBuilder;
|
||||
private ImmutableMap.Builder<String, HelpTopic> topicBuilder;
|
||||
|
||||
private static final String HELP_ZIP_FILE_NAME = "help-resource.zip";
|
||||
private static final long HELP_ZIP_CHECK_INTERVAL_MS = 10 * 60 * 1000L;
|
||||
|
||||
private static Charset CHARSET_UTF_8;
|
||||
|
||||
static {
|
||||
try {
|
||||
CHARSET_UTF_8 = Charset.forName("UTF-8");
|
||||
} catch (Exception e) {
|
||||
CHARSET_UTF_8 = Charset.defaultCharset();
|
||||
LOG.error("charset named UTF-8 in not found. use: {}", CHARSET_UTF_8.displayName());
|
||||
}
|
||||
}
|
||||
|
||||
private static long lastModifyTime = 0L;
|
||||
private static long lastCheckTime = 0L;
|
||||
private boolean isloaded = false;
|
||||
private static String zipFilePath;
|
||||
private static ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
// Files in zip is not recursive, so we only need to traverse it
|
||||
public void setUpByZip(String path) throws IOException, UserException {
|
||||
initBuild();
|
||||
try (ZipFile zf = new ZipFile(path)) {
|
||||
Enumeration<? extends ZipEntry> entries = zf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if (entry.isDirectory()) {
|
||||
setUpDirInZip(entry.getName());
|
||||
} else {
|
||||
long size = entry.getSize();
|
||||
String line;
|
||||
List<String> lines = Lists.newArrayList();
|
||||
if (size > 0) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(zf.getInputStream(entry),
|
||||
CHARSET_UTF_8));
|
||||
while ((line = reader.readLine()) != null) {
|
||||
lines.add(line);
|
||||
}
|
||||
reader.close();
|
||||
|
||||
// note that we only need basename
|
||||
String parentPathStr = null;
|
||||
Path pathObj = Paths.get(entry.getName());
|
||||
if (pathObj.getParent() != null) {
|
||||
parentPathStr = pathObj.getParent().getFileName().toString();
|
||||
}
|
||||
HelpObjectLoader<HelpTopic> topicLoader = HelpObjectLoader.createTopicLoader();
|
||||
List<HelpTopic> topics = topicLoader.loadAll(lines);
|
||||
updateTopic(parentPathStr, topics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
build();
|
||||
isloaded = true;
|
||||
}
|
||||
|
||||
// process dirs in zip file
|
||||
private void setUpDirInZip(String pathInZip) {
|
||||
Path pathObj = Paths.get(pathInZip);
|
||||
// Note: we only need 'basename' here, which is the farthest element from the root in the
|
||||
// directory hierarchy.
|
||||
String pathStr = pathObj.getFileName().toString();
|
||||
String parentPathStr = null;
|
||||
if (pathObj.getParent() != null) {
|
||||
parentPathStr = pathObj.getParent().getFileName().toString();
|
||||
}
|
||||
updateCategory(parentPathStr, pathStr);
|
||||
}
|
||||
|
||||
// for test only
|
||||
public void setUp(String path) throws UserException, IOException {
|
||||
File root = new File(path);
|
||||
if (!root.isDirectory()) {
|
||||
throw new UserException("Need help directory.");
|
||||
}
|
||||
initBuild();
|
||||
for (File file : root.listFiles()) {
|
||||
if (file.getName().startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
setUpDir("", file);
|
||||
}
|
||||
build();
|
||||
}
|
||||
|
||||
// for test only
|
||||
private void setUpDir(String parent, File dir) throws IOException, UserException {
|
||||
updateCategory(parent, dir.getName());
|
||||
for (File file : dir.listFiles()) {
|
||||
if (file.getName().startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
setUpDir(dir.getName(), file);
|
||||
} else {
|
||||
// Load this File
|
||||
HelpObjectLoader<HelpTopic> topicLoader = HelpObjectLoader.createTopicLoader();
|
||||
List<HelpTopic> topics = topicLoader.loadAll(file.getPath());
|
||||
updateTopic(dir.getName(), topics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initBuild() {
|
||||
categoryByNameBuilder = ImmutableSortedMap.orderedBy(String.CASE_INSENSITIVE_ORDER);
|
||||
categoryByParentBuilder = ImmutableListMultimap.builder();
|
||||
categoryByParentBuilder.orderKeysBy(String.CASE_INSENSITIVE_ORDER).orderValuesBy(String.CASE_INSENSITIVE_ORDER);
|
||||
topicByCatBuilder = ImmutableListMultimap.builder();
|
||||
topicByCatBuilder.orderKeysBy(String.CASE_INSENSITIVE_ORDER).orderValuesBy(String.CASE_INSENSITIVE_ORDER);
|
||||
topicByKeyBuilder = ImmutableListMultimap.builder();
|
||||
topicByKeyBuilder.orderKeysBy(String.CASE_INSENSITIVE_ORDER).orderValuesBy(String.CASE_INSENSITIVE_ORDER);
|
||||
topicBuilder = ImmutableSortedMap.orderedBy(String.CASE_INSENSITIVE_ORDER);
|
||||
}
|
||||
|
||||
private void updateCategory(String parent, String category) {
|
||||
if (!Strings.isNullOrEmpty(parent)) {
|
||||
categoryByParentBuilder.put(parent.toLowerCase(), category);
|
||||
}
|
||||
categoryByNameBuilder.put(category, category);
|
||||
}
|
||||
|
||||
private void updateTopic(String category, List<HelpTopic> topics) {
|
||||
for (HelpTopic topic : topics) {
|
||||
if (Strings.isNullOrEmpty(topic.getName())) {
|
||||
continue;
|
||||
}
|
||||
topicBuilder.put(topic.getName(), topic);
|
||||
if (!Strings.isNullOrEmpty(category)) {
|
||||
topicByCatBuilder.put(category.toLowerCase(), topic.getName());
|
||||
}
|
||||
for (String keyword : topic.getKeywords()) {
|
||||
if (!Strings.isNullOrEmpty(keyword)) {
|
||||
topicByKeyBuilder.put(keyword.toLowerCase(), topic.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void build() {
|
||||
categoryByName = categoryByNameBuilder.build();
|
||||
categoryByParent = categoryByParentBuilder.build();
|
||||
topicByName = topicBuilder.build();
|
||||
topicByCategory = topicByCatBuilder.build();
|
||||
topicByKeyword = topicByKeyBuilder.build();
|
||||
|
||||
categoryByNameBuilder = null;
|
||||
categoryByParentBuilder = null;
|
||||
topicBuilder = null;
|
||||
topicByCatBuilder = null;
|
||||
topicByKeyBuilder = null;
|
||||
}
|
||||
|
||||
// Get help information by help name.
|
||||
public HelpTopic getTopic(String name) {
|
||||
return topicByName.get(name);
|
||||
}
|
||||
|
||||
public List<String> listTopicByKeyword(String keyword) {
|
||||
if (Strings.isNullOrEmpty(keyword)) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
return topicByKeyword.get(keyword.toLowerCase());
|
||||
}
|
||||
|
||||
public List<String> listTopicByCategory(String category) {
|
||||
if (Strings.isNullOrEmpty(category)) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
return topicByCategory.get(category.toLowerCase());
|
||||
}
|
||||
|
||||
public List<String> listCategoryByCategory(String category) {
|
||||
if (Strings.isNullOrEmpty(category)) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
return categoryByParent.get(category.toLowerCase());
|
||||
}
|
||||
|
||||
public List<String> listCategoryByName(String name) {
|
||||
if (categoryByName.get(name) != null) {
|
||||
return Lists.newArrayList(categoryByName.get(name));
|
||||
}
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
|
||||
public void setUpModule() throws IOException, UserException {
|
||||
URL helpResource = instance.getClass().getClassLoader()
|
||||
.getResource(HELP_ZIP_FILE_NAME);
|
||||
if (helpResource == null) {
|
||||
//throw new IOException("Can not find help zip file: " + HELP_ZIP_FILE_NAME);
|
||||
return;
|
||||
}
|
||||
zipFilePath = helpResource.getPath();
|
||||
setUpByZip(zipFilePath);
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
lastCheckTime = now;
|
||||
lastModifyTime = now;
|
||||
}
|
||||
|
||||
public boolean needReloadZipFile(String zipPath) throws UserException {
|
||||
if (!isloaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
if ((now - lastCheckTime) < HELP_ZIP_CHECK_INTERVAL_MS) {
|
||||
return false;
|
||||
}
|
||||
lastCheckTime = now;
|
||||
|
||||
// check zip file's last modify time
|
||||
File file = new File(zipPath);
|
||||
if (!file.exists()) {
|
||||
throw new UserException("zipfile of help module is not exist" + zipPath);
|
||||
}
|
||||
long lastModify = file.lastModified();
|
||||
if (lastModifyTime >= lastModify) {
|
||||
return false;
|
||||
} else {
|
||||
lastModifyTime = lastModify;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Every query will begin at this method, so we add check logic here to check
|
||||
// whether need reload ZipFile
|
||||
public static HelpModule getInstance() {
|
||||
synchronized (HelpModule.class) {
|
||||
if (instance == null) {
|
||||
instance = new HelpModule();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// If one thread is reloading zip-file, the other thread use old instance.
|
||||
if (instance.needReloadZipFile(zipFilePath)) {
|
||||
if (lock.tryLock()) {
|
||||
LOG.info("reload help zip file: " + zipFilePath);
|
||||
try {
|
||||
HelpModule newInstance = new HelpModule();
|
||||
newInstance.setUpByZip(zipFilePath);
|
||||
instance = newInstance;
|
||||
} catch (UserException | IOException e) {
|
||||
LOG.warn("Failed to reload help zip file: " + zipFilePath, e);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UserException e) {
|
||||
LOG.warn("Failed to reload help zip file: " + zipFilePath, e);
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -1331,59 +1331,7 @@ public class ShowExecutor {
|
|||
// Handle help statement.
|
||||
private void handleHelp() {
|
||||
HelpStmt helpStmt = (HelpStmt) stmt;
|
||||
String mark = helpStmt.getMask();
|
||||
HelpModule module = HelpModule.getInstance();
|
||||
|
||||
// Get topic
|
||||
HelpTopic topic = module.getTopic(mark);
|
||||
// Get by Keyword
|
||||
if (topic == null) {
|
||||
List<String> topics = module.listTopicByKeyword(mark);
|
||||
if (topics.size() == 0) {
|
||||
// assign to avoid code style problem
|
||||
topic = null;
|
||||
} else if (topics.size() == 1) {
|
||||
topic = module.getTopic(topics.get(0));
|
||||
} else {
|
||||
// Send topic list and category list
|
||||
List<List<String>> rows = Lists.newArrayList();
|
||||
for (String str : topics) {
|
||||
rows.add(Lists.newArrayList(str, "N"));
|
||||
}
|
||||
List<String> categories = module.listCategoryByName(mark);
|
||||
for (String str : categories) {
|
||||
rows.add(Lists.newArrayList(str, "Y"));
|
||||
}
|
||||
resultSet = new ShowResultSet(helpStmt.getKeywordMetaData(), rows);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (topic != null) {
|
||||
resultSet = new ShowResultSet(helpStmt.getMetaData(), Lists.<List<String>>newArrayList(
|
||||
Lists.newArrayList(topic.getName(), topic.getDescription(), topic.getExample())));
|
||||
} else {
|
||||
List<String> categories = module.listCategoryByName(mark);
|
||||
if (categories.isEmpty()) {
|
||||
// If no category match for this name, return
|
||||
resultSet = new ShowResultSet(helpStmt.getKeywordMetaData(), EMPTY_SET);
|
||||
} else if (categories.size() > 1) {
|
||||
// Send category list
|
||||
resultSet = new ShowResultSet(helpStmt.getCategoryMetaData(),
|
||||
Lists.<List<String>>newArrayList(categories));
|
||||
} else {
|
||||
// Send topic list and sub-category list
|
||||
List<List<String>> rows = Lists.newArrayList();
|
||||
List<String> topics = module.listTopicByCategory(categories.get(0));
|
||||
for (String str : topics) {
|
||||
rows.add(Lists.newArrayList(str, "N"));
|
||||
}
|
||||
List<String> subCategories = module.listCategoryByCategory(categories.get(0));
|
||||
for (String str : subCategories) {
|
||||
rows.add(Lists.newArrayList(str, "Y"));
|
||||
}
|
||||
resultSet = new ShowResultSet(helpStmt.getKeywordMetaData(), rows);
|
||||
}
|
||||
}
|
||||
resultSet = new ShowResultSet(helpStmt.getKeywordMetaData(), EMPTY_SET);
|
||||
}
|
||||
|
||||
// Show load statement.
|
||||
|
|
|
|||
|
|
@ -1,179 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package com.starrocks.qe;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.starrocks.common.UserException;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HelpModuleTest {
|
||||
private List<HelpCategory> categories;
|
||||
private List<HelpTopic> topics;
|
||||
|
||||
// Category
|
||||
// Admin
|
||||
// - Show
|
||||
// - Select
|
||||
// Topic
|
||||
// - SHOW TABLES
|
||||
// - SELECT TIME
|
||||
@Before
|
||||
public void setUp() {
|
||||
categories = Lists.newArrayList();
|
||||
topics = Lists.newArrayList();
|
||||
|
||||
HelpCategory category = new HelpCategory();
|
||||
Map<String, String> map = Maps.newHashMap();
|
||||
map.put("parent", "Admin");
|
||||
Map.Entry<String, Map<String, String>> entry = Maps.immutableEntry("Show", map);
|
||||
category.loadFrom(entry);
|
||||
categories.add(category);
|
||||
|
||||
category = new HelpCategory();
|
||||
map = Maps.newHashMap();
|
||||
map.put("parent", "Admin");
|
||||
entry = Maps.immutableEntry("Select", map);
|
||||
category.loadFrom(entry);
|
||||
categories.add(category);
|
||||
|
||||
category = new HelpCategory();
|
||||
map = Maps.newHashMap();
|
||||
entry = Maps.immutableEntry("Admin", map);
|
||||
category.loadFrom(entry);
|
||||
categories.add(category);
|
||||
|
||||
// Topic
|
||||
HelpTopic topic = new HelpTopic();
|
||||
map = Maps.newHashMap();
|
||||
map.put("keyword", "SHOW, TABLES");
|
||||
map.put("category", "Show");
|
||||
entry = Maps.immutableEntry("SHOW TABLES", map);
|
||||
topic.loadFrom(entry);
|
||||
topics.add(topic);
|
||||
|
||||
topic = new HelpTopic();
|
||||
map = Maps.newHashMap();
|
||||
map.put("keyword", "SELECT");
|
||||
map.put("category", "Select");
|
||||
entry = Maps.immutableEntry("SELECT TIME", map);
|
||||
topic.loadFrom(entry);
|
||||
topics.add(topic);
|
||||
|
||||
// emtpy
|
||||
topic = new HelpTopic();
|
||||
map = Maps.newHashMap();
|
||||
entry = Maps.immutableEntry("empty", map);
|
||||
topic.loadFrom(entry);
|
||||
topics.add(topic);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormal() throws IOException, UserException {
|
||||
// Mock
|
||||
// HelpObjectLoader categoryLoader = EasyMock.createMock(HelpObjectLoader.class);
|
||||
// EasyMock.expect(categoryLoader.loadAll(EasyMock.isA(String.class))).andReturn(categories).anyTimes();
|
||||
// EasyMock.replay(categoryLoader);
|
||||
// HelpObjectLoader topicLoader = EasyMock.createMock(HelpObjectLoader.class);
|
||||
// EasyMock.expect(topicLoader.loadAll(EasyMock.isA(String.class))).andReturn(topics).anyTimes();
|
||||
// EasyMock.replay(topicLoader);
|
||||
// PowerMock.mockStatic(HelpObjectLoader.class);
|
||||
// EasyMock.expect(HelpObjectLoader.createCategoryLoader()).andReturn(categoryLoader).anyTimes();
|
||||
// EasyMock.expect(HelpObjectLoader.createTopicLoader()).andReturn(topicLoader).anyTimes();
|
||||
// PowerMock.replay(HelpObjectLoader.class);
|
||||
|
||||
HelpModule module = new HelpModule();
|
||||
URL help = getClass().getClassLoader().getResource("data/help");
|
||||
module.setUp(help.getPath());
|
||||
|
||||
HelpTopic topic = module.getTopic("SELECT TIME");
|
||||
Assert.assertNotNull(topic);
|
||||
|
||||
topic = module.getTopic("select time");
|
||||
Assert.assertNotNull(topic);
|
||||
|
||||
// Must ordered by alpha.
|
||||
List<String> categories = module.listCategoryByCategory("Admin");
|
||||
Assert.assertEquals(2, categories.size());
|
||||
Assert.assertTrue(Arrays.equals(categories.toArray(), Lists.newArrayList("Select", "Show").toArray()));
|
||||
// topics
|
||||
List<String> topics = module.listTopicByKeyword("SHOW");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SHOW TABLES").toArray()));
|
||||
|
||||
topics = module.listTopicByKeyword("SELECT");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SELECT TIME").toArray()));
|
||||
|
||||
topics = module.listTopicByCategory("selEct");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SELECT TIME").toArray()));
|
||||
|
||||
topics = module.listTopicByCategory("show");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SHOW TABLES").toArray()));
|
||||
|
||||
Assert.assertTrue(Arrays.equals(module.listCategoryByName("ADMIN").toArray(),
|
||||
Lists.newArrayList("Admin").toArray()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadFromZip() throws IOException, UserException {
|
||||
HelpModule module = new HelpModule();
|
||||
URL help = getClass().getClassLoader().getResource("test-help-resource.zip");
|
||||
module.setUpByZip(help.getPath());
|
||||
|
||||
HelpTopic topic = module.getTopic("SELECT TIME");
|
||||
Assert.assertNotNull(topic);
|
||||
|
||||
topic = module.getTopic("select time");
|
||||
Assert.assertNotNull(topic);
|
||||
|
||||
// Must ordered by alpha.
|
||||
List<String> categories = module.listCategoryByCategory("Admin");
|
||||
Assert.assertEquals(2, categories.size());
|
||||
Assert.assertTrue(Arrays.equals(categories.toArray(), Lists.newArrayList("Select", "Show").toArray()));
|
||||
// topics
|
||||
List<String> topics = module.listTopicByKeyword("SHOW");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SHOW TABLES").toArray()));
|
||||
|
||||
topics = module.listTopicByKeyword("SELECT");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SELECT TIME").toArray()));
|
||||
|
||||
topics = module.listTopicByCategory("selEct");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SELECT TIME").toArray()));
|
||||
|
||||
topics = module.listTopicByCategory("show");
|
||||
Assert.assertEquals(1, topics.size());
|
||||
Assert.assertTrue(Arrays.equals(topics.toArray(), Lists.newArrayList("SHOW TABLES").toArray()));
|
||||
|
||||
Assert.assertTrue(Arrays.equals(module.listCategoryByName("ADMIN").toArray(),
|
||||
Lists.newArrayList("Admin").toArray()));
|
||||
}
|
||||
}
|
||||
|
|
@ -80,7 +80,6 @@ import com.starrocks.server.GlobalStateMgr;
|
|||
import com.starrocks.server.MetadataMgr;
|
||||
import com.starrocks.server.RunMode;
|
||||
import com.starrocks.sql.ast.DescribeStmt;
|
||||
import com.starrocks.sql.ast.HelpStmt;
|
||||
import com.starrocks.sql.ast.QualifiedName;
|
||||
import com.starrocks.sql.ast.SetType;
|
||||
import com.starrocks.sql.ast.ShowAuthorStmt;
|
||||
|
|
@ -127,8 +126,6 @@ import org.junit.Test;
|
|||
import org.junit.rules.ExpectedException;
|
||||
import org.sparkproject.guava.collect.Maps;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
|
@ -955,70 +952,6 @@ public class ShowExecutorTest {
|
|||
Assert.assertFalse(resultSet.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHelp() throws AnalysisException, IOException, UserException {
|
||||
HelpModule module = new HelpModule();
|
||||
URL help = getClass().getClassLoader().getResource("test-help-resource-show-help.zip");
|
||||
module.setUpByZip(help.getPath());
|
||||
new Expectations(module) {
|
||||
{
|
||||
HelpModule.getInstance();
|
||||
minTimes = 0;
|
||||
result = module;
|
||||
}
|
||||
};
|
||||
|
||||
// topic
|
||||
HelpStmt stmt = new HelpStmt("ADD");
|
||||
ShowExecutor executor = new ShowExecutor(ctx, stmt);
|
||||
ShowResultSet resultSet = executor.execute();
|
||||
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("ADD", resultSet.getString(0));
|
||||
Assert.assertEquals("add function\n", resultSet.getString(1));
|
||||
Assert.assertFalse(resultSet.next());
|
||||
|
||||
// topic
|
||||
stmt = new HelpStmt("logical");
|
||||
executor = new ShowExecutor(ctx, stmt);
|
||||
resultSet = executor.execute();
|
||||
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("OR", resultSet.getString(0));
|
||||
Assert.assertFalse(resultSet.next());
|
||||
|
||||
// keywords
|
||||
stmt = new HelpStmt("MATH");
|
||||
executor = new ShowExecutor(ctx, stmt);
|
||||
resultSet = executor.execute();
|
||||
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("ADD", resultSet.getString(0));
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("MINUS", resultSet.getString(0));
|
||||
Assert.assertFalse(resultSet.next());
|
||||
|
||||
// category
|
||||
stmt = new HelpStmt("functions");
|
||||
executor = new ShowExecutor(ctx, stmt);
|
||||
resultSet = executor.execute();
|
||||
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("HELP", resultSet.getString(0));
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("binary function", resultSet.getString(0));
|
||||
Assert.assertTrue(resultSet.next());
|
||||
Assert.assertEquals("bit function", resultSet.getString(0));
|
||||
Assert.assertFalse(resultSet.next());
|
||||
|
||||
// empty
|
||||
stmt = new HelpStmt("empty");
|
||||
executor = new ShowExecutor(ctx, stmt);
|
||||
resultSet = executor.execute();
|
||||
|
||||
Assert.assertFalse(resultSet.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShowMaterializedView() throws AnalysisException, DdlException {
|
||||
ctx.setCurrentUserIdentity(UserIdentity.ROOT);
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue