/* * Copyright (C) 2014 Divide.io * * 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 io.divide.shared.transitory.query; import io.divide.shared.transitory.TransientObject; public class QueryBuilder{ public static enum QueryAction{ SELECT, DELETE, UPDATE; public boolean is(String str){ return this.name().equals(str.toUpperCase()); } } private Query query; public QueryBuilder(){ query = new Query(); } public SelectBuilder select(SelectOperation... select){ return new SelectBuilder(this,select); } public DeleteBuilder delete(){ return new DeleteBuilder(this); } public UpdateBuilder update(){ return new UpdateBuilder(this); } private void addWhere(String one, OPERAND operand, String two){ query.where.put(query.where.size(),new UserDataClause(one,operand,two)); } private void addWhere(TransientObject.MetaKey one, OPERAND operand, String two){ query.where.put(query.where.size(),new MetaDataClause(one.KEY,operand,two)); } private void addWhere(OPERAND.Conditional conditional,String one, OPERAND operand, String two){ query.where.put(query.where.size(),new UserDataClause(conditional,one,operand,two)); } private void addWhere(OPERAND.Conditional conditional,TransientObject.MetaKey one, OPERAND operand, String two){ query.where.put(query.where.size(),new MetaDataClause(conditional,one.KEY,operand,two)); } private void setFrom(Class from){ query.from = Query.safeTable(from); } private void addSelect(SelectOperation select){ if(select!=null) query.select = select; } private void setLimit(Integer limit){ query.limit = limit; } private void setOffset(Integer offset){ query.offset = offset; } private void setAction(QueryAction action){ query.action = action; } private void setRandom(boolean random){ query.random = random; } private Query getQuery(){ return query; } public class SelectBuilder extends QueryActionBuilder{ private SelectBuilder(QueryBuilder builder, SelectOperation... select){ super(builder,QueryAction.SELECT); if (select!=null) for (SelectOperation s : select) builder.addSelect(s); } } public class DeleteBuilder extends QueryActionBuilder{ private DeleteBuilder(QueryBuilder builder) { super(builder,QueryAction.DELETE); } } public class UpdateBuilder extends QueryActionBuilder{ private UpdateBuilder(QueryBuilder builder) { super(builder,QueryAction.UPDATE); } } public class QueryActionBuilder{ private QueryBuilder builder; private QueryActionBuilder(QueryBuilder builder, QueryAction action){ this.builder = builder; this.builder.setAction(action); } public <T extends TransientObject> WhereBuilder from(Class<T> from){ builder.setFrom(from); return new WhereBuilder(builder); } } public class WhereBuilder{ private QueryBuilder builder; protected WhereBuilder(QueryBuilder builder){ this.builder = builder; } public WhereMoreBuilder where(String one, OPERAND operand, String two){ builder.addWhere(one,operand,two); return new WhereMoreBuilder(builder); } public WhereMoreBuilder where(TransientObject.MetaKey one, OPERAND operand, String two){ builder.addWhere(one,operand,two); return new WhereMoreBuilder(builder); } public LimitConstraintBuilder limit(Integer limit){ return new LimitConstraintBuilder(builder,limit); } public OffsetConstraintBuilder offset(Integer offset){ return new OffsetConstraintBuilder(builder,offset); } public RandomConstraintBuilder random( Integer limit){ return new RandomConstraintBuilder(builder,limit); } public Query build(){ return builder.getQuery(); } } public class WhereMoreBuilder{ private QueryBuilder builder; protected WhereMoreBuilder(QueryBuilder builder){ this.builder = builder; } public WhereMoreBuilder and(String one, OPERAND operand, String two){ builder.addWhere(OPERAND.Conditional.AND,one,operand,two); return this; } public WhereMoreBuilder or(String one, OPERAND operand, String two){ builder.addWhere(OPERAND.Conditional.OR,one,operand,two); return this; } public WhereMoreBuilder and(TransientObject.MetaKey one, OPERAND operand, String two){ builder.addWhere(OPERAND.Conditional.AND,one,operand,two); return this; } public WhereMoreBuilder or(TransientObject.MetaKey one, OPERAND operand, String two){ builder.addWhere(OPERAND.Conditional.OR,one,operand,two); return this; } public LimitConstraintBuilder limit(Integer limit){ return new LimitConstraintBuilder(builder,limit); } public OffsetConstraintBuilder offset(Integer offset){ return new OffsetConstraintBuilder(builder,offset); } public RandomConstraintBuilder random(Integer limit){ return new RandomConstraintBuilder(builder,limit); } public Query build(){ return builder.getQuery(); } } public class LimitConstraintBuilder extends ConstraintBuilder{ private LimitConstraintBuilder(QueryBuilder builder, Integer limit){ super(builder); this.builder.setLimit(limit); } public ConstraintBuilder offset(Integer offset){ if(bothSet()){ return new ConstraintBuilder(builder); }else { return new OffsetConstraintBuilder(builder,offset); } } } public class OffsetConstraintBuilder extends ConstraintBuilder{ private OffsetConstraintBuilder(QueryBuilder builder, Integer offset) { super(builder); builder.setOffset(offset); } public ConstraintBuilder limit(Integer limit){ if(bothSet()){ return new ConstraintBuilder(builder); }else { return new LimitConstraintBuilder(builder,limit); } } } public class RandomConstraintBuilder extends ConstraintBuilder{ private RandomConstraintBuilder(QueryBuilder builder, Integer limit) { super(builder); builder.setRandom(true); builder.setLimit(limit); } } public class ConstraintBuilder{ protected QueryBuilder builder; private ConstraintBuilder(QueryBuilder builder){ this.builder = builder; } public Query build(){ return builder.getQuery(); } protected boolean bothSet(){ return (builder.query.limit != null && builder.query.offset != null); } } }