/* * Copyright 2013 Future Systems * * Licensed 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 org.araqne.logdb.query.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.araqne.logdb.AbstractQueryCommandParser; import org.araqne.logdb.QueryCommand; import org.araqne.logdb.QueryContext; import org.araqne.logdb.QueryErrorMessage; import org.araqne.logdb.QueryParseException; import org.araqne.logdb.query.command.Sort; import org.araqne.logdb.query.command.Sort.SortField; public class SortParser extends AbstractQueryCommandParser { private static final String BY = "by"; public SortParser() { setDescriptions( "Sort by specified comma-separated fields. If a hyphen is followed by field name, this command will sort by that field in descending order.", "주어진 필드를 기준으로 정렬합니다. 필드 이름 앞에 - 부호가 붙은 경우 내림차순, 그렇지 않으면 오름차순으로 정렬합니다. limit 옵션이 지정된 경우 정렬된 결과에서 순서대로 N개를 추출합니다."); setOptions("limit", OPTIONAL, "Max output count", "최대 출력 갯수"); } @Override public String getCommandName() { return "sort"; } @Override public Map<String, QueryErrorMessage> getErrorMessages() { Map<String, QueryErrorMessage> m = new HashMap<String, QueryErrorMessage>(); m.put("21600", new QueryErrorMessage("need-column", "정렬할 필드명을 입력하십시오.")); m.put("21601", new QueryErrorMessage("invalid-by-clause", "by절에 필드명들을 콤마로 구분하여 올바르게 입력하십시오. ")); m.put("21602", new QueryErrorMessage("invalid-limit-option", "limit 값이 유효하지 않습니다. ")); return m; } @Override @SuppressWarnings("unchecked") public QueryCommand parse(QueryContext context, String commandString) { ParseResult r = QueryTokenizer.parseOptions(context, commandString, "sort".length(), Arrays.asList("limit"), getFunctionRegistry()); Map<String, String> options = (Map<String, String>) r.value; Integer count = null; if (options.containsKey("limit")) { count = Integer.parseInt(options.get("limit")); if (count <= 0) throw new QueryParseException("21602", "sort".length() + 1, commandString.length() - 1, null); } List<String> partitions = new ArrayList<String>(); int byPos = QueryTokenizer.findKeyword(commandString, BY, 0, true); if (byPos > 0) { String partitionsPart = commandString.substring(byPos + BY.length()); if (partitionsPart.trim().endsWith(",")) throw new QueryParseException("21601", "sort".length() + 1, commandString.length() - 1, null); // trim for (String partition : partitionsPart.split(",")) { partitions.add(partition.trim()); } } try { List<SortField> fields = null; if (partitions.size() == 0) fields = SortField.parseSortFields(commandString, r); else fields = SortField.parseSortFields(commandString.substring(0, byPos), r); return new Sort(count, fields.toArray(new SortField[0]), partitions); } catch (QueryParseException e) { if (e.getType().equals("90004")) throw new QueryParseException("21600", r.next, commandString.length() - 1, null); throw e; } } }