com.gs.fw.common.mithra.finder.WhereClause Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of reladomo Show documentation
Show all versions of reladomo Show documentation
Reladomo is an object-relational mapping framework.
/*
Copyright 2016 Goldman Sachs.
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 com.gs.fw.common.mithra.finder;
import com.gs.collections.impl.list.mutable.FastList;
import com.gs.collections.impl.set.mutable.UnifiedSet;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.BitSet;
import java.util.List;
import java.util.Set;
public class WhereClause
{
// why is StringBuilder final? This class would extend StringBuilder instead of being a bunch of static junk
private static final char BRACKET_REPLACEMENT_CHAR = '\r';
private static final char AND_REPLACEMENT_CHAR = '\n';
private static final char OR_REPLACEMENT_CHAR = '\t';
private static final String AND_REPLACEMENT_STRING = "\n\n\n\n";
private static final String OR_REPLACEMENT_STRING = "\t\t\t\t";
private StringBuilder whereClause = new StringBuilder(16);
private List sqlParameterSetters = null;
private WhereClauseOwner owner;
private int orCount;
private List tempTableJoins;
private Set reachableColumns;
private BooleanStack booleanStack; // true means boolean operation was added to the where clause
public WhereClause(WhereClauseOwner owner)
{
this.owner = owner;
}
public int setSqlParameters(SqlQuery query, PreparedStatement ps, int count, WhereClauseOwner source) throws SQLException
{
if (source == this.owner && sqlParameterSetters != null)
{
for (int i = 0; i < sqlParameterSetters.size(); i++)
{
SqlParameterSetter sps = sqlParameterSetters.get(i);
count += sps.setSqlParameters(ps, count, query);
}
}
return count;
}
public boolean isInOrClause()
{
return orCount > 0;
}
public void clear()
{
this.whereClause.setLength(0);
if (this.sqlParameterSetters != null)
{
this.sqlParameterSetters.clear();
}
if (tempTableJoins != null)
{
tempTableJoins.clear();
}
if (this.reachableColumns != null)
{
this.reachableColumns.clear();
}
}
public int length()
{
return whereClause.length();
}
public WhereClause insert(int offset, String str)
{
checkOffsetToFill(offset);
if (offset == whereClause.length())
{
whereClause.append(str);
}
else
{
whereClause.insert(offset, str);
}
return this;
}
private void checkOffsetToFill(int offset)
{
int start = offset - 1;
if (start < 0) return;
for(int i=start; i >= 0; i--)
{
switch (this.whereClause.charAt(i))
{
case BRACKET_REPLACEMENT_CHAR:
whereClause.setCharAt(i , '(');
break;
case AND_REPLACEMENT_CHAR:
whereClause.setCharAt(i-3 , ' ');
whereClause.setCharAt(i-2 , 'a');
whereClause.setCharAt(i-1 , 'n');
whereClause.setCharAt(i , 'd');
return;
case OR_REPLACEMENT_CHAR:
whereClause.setCharAt(i-3 , ' ');
whereClause.setCharAt(i-2 , 'o');
whereClause.setCharAt(i-1 , 'r');
whereClause.setCharAt(i , ' ');
return;
default:
return;
}
}
}
public WhereClause insert(int offset, CharSequence s)
{
checkOffsetToFill(offset);
if (offset == whereClause.length())
{
whereClause.append(s);
}
else
{
whereClause.insert(offset, s);
}
return this;
}
public WhereClause insert(int offset, char c)
{
checkOffsetToFill(offset);
if (offset == whereClause.length())
{
whereClause.append(c);
}
else
{
whereClause.insert(offset, c);
}
return this;
}
public WhereClause append(String str)
{
checkOffsetToFill(whereClause.length());
whereClause.append(str);
return this;
}
public WhereClause append(CharSequence s)
{
checkOffsetToFill(whereClause.length());
whereClause.append(s);
return this;
}
public WhereClause append(char c)
{
checkOffsetToFill(whereClause.length());
whereClause.append(c);
return this;
}
public WhereClause append(int i)
{
checkOffsetToFill(whereClause.length());
whereClause.append(i);
return this;
}
private boolean isBlank(int start, int end)
{
for(int i=start;i 1 && this.whereClause.subSequence(start-4, start).equals("and "))
{
start -= 4;
if (this.whereClause.charAt(start - 1) == ' ')
{
start--;
andLength++;
}
}
else
{
// 3) and after this text
if (this.whereClause.charAt(start +length + 4) == ' ')
{
andLength++;
}
}
this.whereClause.delete(start, start + length + andLength);
return -(length + andLength);
}
public void addReachableColumn(String fullyQualifiedColumn)
{
if (this.reachableColumns == null)
{
this.reachableColumns = UnifiedSet.newSet(4);
}
this.reachableColumns.add(fullyQualifiedColumn);
}
public boolean isColumnReachable(String fullyQualifiedColumnName)
{
return this.reachableColumns != null && this.reachableColumns.contains(fullyQualifiedColumnName);
}
private static class BooleanStack
{
private int size;
private BitSet set = new BitSet();
public void push(boolean val)
{
if (val)
{
set.set(size);
}
else
{
set.clear(size);
}
size++;
}
public boolean pop()
{
size--;
return set.get(size);
}
public boolean peek()
{
return set.get(size - 1);
}
}
public interface WhereClauseOwner
{
public WhereClause getWhereClause();
public WhereClause getParentWhereClause(SqlQuery sqlQuery);
}
}