All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.odysz.transact.sql.parts.condition.Condit Maven / Gradle / Ivy

package io.odysz.transact.sql.parts.condition;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import io.odysz.semantics.ISemantext;
import io.odysz.transact.sql.Query;
import io.odysz.transact.sql.parts.Logic;
import io.odysz.transact.sql.parts.Logic.op;
import io.odysz.transact.sql.parts.Logic.type;
import io.odysz.transact.sql.parts.antlr.ConditVisitor;
import io.odysz.transact.x.TransException;


/**Logical Conditioning, a {@link Predicate} tree.
 * For grammar definition, see {@link ConditVisitor}. 
 * @author ody
 *
 */
public class Condit extends Predicate {

	protected type logitype;
	protected List condts;

	/**When this is not null, this object is representing search_condition_not:
search_condition_not
    : NOT? predicate
    ;
protected Predicate predict; */ public Condit(op op, String lop, String rop) { super(op, lop, rop); // FIXME op = eq, lop = e.pid, rop = ch.entfk, line 1:8 mismatched input '' expecting '.' this.logitype = Logic.type.empty; } public Condit(op op, String lop, ExprPart rop) { super(op, lop, rop); this.logitype = Logic.type.empty; } public Condit(op op, ExprPart lop, ExprPart rop) { super(op, lop, rop); this.logitype = Logic.type.empty; } public Condit(Logic.type type, List condts) { super(); this.logitype = type; this.condts = condts; } public Condit(Predicate predicate) { super(predicate); this.logitype = Logic.type.empty; } public Condit(op op, String lop, Query rop) throws TransException { super(op, lop, rop); this.logitype = Logic.type.empty; } /** * Generate a "in" condition for: lop in ('constr[0]', 'constr[1]', ...) * @param lop * @param constvs * @return Condit instance * @since 1.4.36 public static Condit in(String lop, String[] constr) { if (constr != null) { ArrayList rops = new ArrayList(constr.length); for (String c : constr) rops.add(Funcall.constr(c)); return new Condit(op.in, lop, rops); } return null; } */ public boolean isEmpty() { return (condts == null || condts.size() == 0) && super.empty; } public Condit and(Condit and) { if (logitype == type.or) { // and is prior to the other ors condts.get(condts.size() - 1).and(and); return this; } else if (logitype == type.and) { condts.add(and); return this; }else if (logitype == type.not) { Condit left = new Condit(type.not, condts); condts = new ArrayList(); condts.add(left); logitype = type.and; condts.add(and); return this; } else { // empty logic, AND with it ArrayList ands = new ArrayList(); ands.add(this); ands.add(and); return new Condit(Logic.type.and, ands); } } public Condit or(Condit or) { if (logitype == type.or) { condts.add(or); return this; } else if (logitype == type.and) { condts.get(condts.size() - 1).or(or); return this; }else if (logitype == type.not) { // shouldn't reach here Condit left = new Condit(type.not, condts); condts = new ArrayList(); condts.add(left); logitype = type.or; condts.add(or); return this; } else { // empty logic, OR with it ArrayList ands = new ArrayList(); ands.add(this); ands.add(or); return new Condit(Logic.type.or, ands); } } /** Additional information of left alias for generating sql. */ String lAlias; /** Additional information of right alias for generating sql. */ String rAlias; private int priority = 0; /**Set the priority 1 more higher than parent * - call this only when composing sql(conditions won't changing) * @param parentLogic * @return */ private Condit prio(Logic.type parentLogic) { if (parentLogic == Logic.type.and && logitype == Logic.type.or // call this only when composing sql(conditions won't changing) && condts != null && condts.size() > 1) this.priority = 1; return this; } private String lbrace() { String l = ""; if (condts != null && condts.size() > 0) for (int b = 0; b < priority; b++) l += "("; return l; } private String rbrace() { String r = ""; if (condts != null && condts.size() > 0) for (int b = 0; b < priority; b++) r += ")"; return r; } /**

Sometimes conditions's table name or alias are ignored by client. * This method can be called by {@link io.odysz.transact.sql.parts.JoinTabl} * to supply additional information when generating sql.

*

TODO DESIGN MEMO
* {@link Condit}s are parsed from sometimes from where clause, sometimes from join-on clause, * so it's not have enough information to parse ignored alias.
* Should we implement this fault tolerance? *

@Deprecated * @param lt left operand's alias (table name) * @param rt right operand's alias (table name) * @return this */ public Condit sqlTbl(String lt, String rt) { this.lAlias = lt; this.rAlias = lt; return this; } @Override public String sql(ISemantext sctx) throws TransException { // handling with 3 grammar rule: search_condition, search_condition_and, search_condition_not // 1. search_condition_not // 2. search_condition_and if (logitype == type.empty) { return super.sql(sctx); } else if (logitype == type.and) { if (condts != null && condts.size() > 0) { String sql = condts.stream() .map(cdt -> { try { cdt.prio(logitype); return cdt.sql(sctx); } catch (TransException e) { e.printStackTrace(); return e.getMessage(); } }) .collect(Collectors.joining(" AND ", lbrace(), rbrace())); return sql; } } // 3. search_conditon_not else if (logitype == type.or) { if (condts != null && condts.size() > 0) { String sql = condts.stream() .map(cdt -> { try { return cdt.sql(sctx); } catch (TransException e) { e.printStackTrace(); return e.getMessage(); } }) .collect(Collectors.joining(" OR ", lbrace(), rbrace())); return sql; } } return null; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy