/* * Copyright 2012 The Java HandlerSocket Connection Project * * https://github.com/komelgman/Java-HandlerSocket-Connection/ * * The Project 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 kom.handlersocket.query; import kom.handlersocket.core.FilterType; import kom.handlersocket.core.HSProto; import kom.handlersocket.core.ResultType; import kom.handlersocket.core.SafeByteStream; import java.security.InvalidParameterException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class HSFindQuery extends HSQuery { protected CompareOperator operator = null; protected List<String> conditions = null; // extra params // LIM protected int limit = 1; protected int offset = 0; // [IN] protected int INIndexNumber = 0; protected List<String> INIndexValues = null; // [FILTER] protected List<Filter> filters = new ArrayList<Filter>(); public HSFindQuery() { this(CompareOperator.GE, Arrays.asList("")); } public HSFindQuery(CompareOperator operator, List<String> conditions) { super(ResultType.FIND_OPERATION); if (conditions != null) { this.operator = operator; this.conditions = conditions; } } @Override protected void encode(final SafeByteStream output) { if (this.conditions == null) { throw new InvalidParameterException("invalid conditions"); } if (null == indexDescriptor) { throw new InvalidParameterException("indexDescriptor can't be null"); } output.writeString(indexDescriptor.getIndexId(), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeBytes(operator.getValue(), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(String.valueOf(conditions.size()), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeStrings(conditions, HSProto.TOKEN_DELIMITER_AS_BYTES, true); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(String.valueOf(limit), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(String.valueOf(offset), false); if (INIndexValues != null) { output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeBytes(HSProto.OPERATOR_IN, false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(String.valueOf(INIndexNumber), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(String.valueOf(INIndexValues.size()), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeStrings(INIndexValues, HSProto.TOKEN_DELIMITER_AS_BYTES, true); } if (filters.size() > 0) { for (Filter filter : filters) { filter.encode(output); } } // [MOD] modify(output); output.writeBytes(HSProto.PACKET_DELIMITER_AS_BYTES, false); } protected void modify(SafeByteStream output) { // nothing, override in modify operations } public HSFindQuery where(CompareOperator operator, List<String> conditions) { if (conditions == null) { throw new IllegalArgumentException("conditions can't be NULL"); } if (operator == null) { throw new IllegalArgumentException("operator can't be NULL"); } if (conditions.size() == 0) { throw new IllegalArgumentException("conditions can't be EMPTY"); } this.operator = operator; this.conditions = conditions; return this; } public HSFindQuery limit(int limit) { if (limit < 1) { throw new IllegalArgumentException("limit must be ONE or greater"); } this.limit = limit; return this; } public HSFindQuery offset(int offset) { if (limit < 0) { throw new IllegalArgumentException("limit must be ZERO or greater"); } this.offset = offset; return this; } public HSFindQuery in(int indexFieldNumber, List<String> conditions) { INIndexNumber = indexFieldNumber; INIndexValues = conditions; return this; } public HSFindQuery filter(String column, CompareOperator operator, String value) { filters.add(new Filter(FilterType.FILTER, operator, column, value)); return this; } public HSFindQuery till(String column, CompareOperator operator, String value) { filters.add(new Filter(FilterType.WHILE, operator, column, value)); return this; } public void reset() { filters.clear(); INIndexNumber = 0; INIndexValues = null; limit = 1; offset = 0; conditions = null; operator = null; } class Filter { public final FilterType type; public final CompareOperator operator; public final String column; public final String value; public Filter(FilterType type, CompareOperator operator, String column, String value) { this.value = value; this.operator = operator; this.type = type; this.column = column; } public void encode(SafeByteStream output) { validate(); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeBytes(type.getValue(), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeBytes(operator.getValue(), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(String.valueOf(indexDescriptor.getFilterColumnPos(column)), false); output.writeBytes(HSProto.TOKEN_DELIMITER_AS_BYTES, false); output.writeString(value, true); } private void validate() { if (value == null || operator == null || type == null || !indexDescriptor.hasFilterColumn(column)) { throw new IllegalArgumentException("invalid filter"); } } } }