[Refactor] Remove unused help module (#33367)

Signed-off-by: imay <buaa.zhaoc@gmail.com>
This commit is contained in:
imay 2023-10-23 09:44:12 -07:00 committed by GitHub
parent bc7bb0587a
commit 802d3624d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1 additions and 894 deletions

View File

@ -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 }}

View File

@ -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);

View File

@ -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>");
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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()));
}
}

View File

@ -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);