package com.utopiaindustries.querybuilder; import com.utopiaindustries.util.MySQLUtils; import com.utopiaindustries.util.StringUtils; import java.util.List; public class QueryBuilder { private StringBuilder query; private String table; private boolean previousCondition; public QueryBuilder() { this.query = new StringBuilder(); this.previousCondition = false; } // setTable public QueryBuilder setTable( String table ) { this.table = table; return this; } // selectColumns public QueryBuilder setColumns( String[] columns ) { String formattedColumns = formatColumns( columns ); this.query.append( String.format( "SELECT %s FROM %s", formattedColumns, this.table ) ); this.query.append( " " ); return this; } public QueryBuilder setColumnsWithoutFormat( String[] columns ) { this.query.append( String.format( "SELECT %s FROM %s", String.join( ",", columns ), this.table ) ); this.query.append( " " ); return this; } // selectColumns public QueryBuilder setJoinColumns( String[] columns ) { String formattedColumns = formatJoinColumns( columns ); this.query.append( String.format( "SELECT %s FROM %s", formattedColumns, this.table ) ); this.query.append( " " ); return this; } public QueryBuilder setColumns( String column ) { String formattedColumn = column.equals( "*" ) ? "*" : String.format( "`%s`", column ); this.query.append( String.format( "SELECT %s FROM %s", formattedColumn, this.table ) ); this.query.append( " " ); return this; } // set columns without formatting public QueryBuilder setColumnsWithoutFormat( String columns ) { this.query.append( String.format( "SELECT %s FROM %s", columns, this.table ) ); this.query.append( " " ); return this; } // set column for count public QueryBuilder setColumnForCount( String column ) { String formattedColumn = column.equals( "*" ) ? "*" : String.format( "`%s`", column ); this.query.append( String.format( "SELECT COUNT( %s ) FROM %s", formattedColumn, this.table ) ); this.query.append( " " ); return this; } // where public QueryBuilder where() { this.query.append( "WHERE" ); this.query.append( " " ); return this; } // columns are Equal public QueryBuilder columnsAreEqual( String col1, String col2 ) { this.query.append( String.format( "`%s` = `%s`", col1, col2 ) ); this.query.append( " " ); this.previousCondition = true; return this; } // columnEquals public QueryBuilder columnEquals( String col, Integer val ) { if ( val != null ) { this.query.append( String.format( "`%s` = %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEquals( String col, Long val ) { if ( val != null ) { this.query.append( String.format( "`%s` = %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEquals( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` = \"%s\"", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEqualsWithoutBackTicks( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "%s = \"%s\"", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnJoinEquals( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { String[] parts = col.split( "\\." ); this.query.append( String.format( "`%s`.`%s` = \"%s\"", parts[0], parts[1], MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEquals( String col, Boolean val ) { if ( isNotNull( val ) ) { this.query.append( String.format( "`%s` = %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateEquals( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` = '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnJoinDateEquals( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { String[] parts = col.split( "\\." ); this.query.append( String.format( "`%s`.`%s` = %s", parts[0], parts[1], MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnNotEquals public QueryBuilder columnNotEquals( String col, Long val ) { if ( val != null ) { this.query.append( String.format( "%s != %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnNotEquals public QueryBuilder columnNotEquals( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` != \"%s\"", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnEqualsAnd public QueryBuilder columnEqualsAnd( String col, String[] vals ) { int index = 1; for ( String val : vals ) { if ( index == 1 ) { this.query.append( "(" ); } this.query.append( String.format( "`%s` = \"%s\"", col, MySQLUtils.escapeString( val ) ) ); if ( index != vals.length ) { this.query.append( " " ); this.query.append( "AND" ); this.query.append( " " ); } if ( index == vals.length ) { this.query.append( ")" ); } index++; } return this; } // columnEqualsOr public QueryBuilder columnEqualsOr( String col, String[] vals ) { int index = 1; for ( String val : vals ) { if ( index == 1 ) { this.query.append( "(" ); } this.query.append( String.format( "`%s` = \"%s\"", col, MySQLUtils.escapeString( val ) ) ); if ( index != vals.length ) { this.query.append( " " ); this.query.append( "OR" ); this.query.append( " " ); } if ( index == vals.length ) { this.query.append( ")" ); } index++; } return this; } // columnGreaterThan public QueryBuilder columnGreaterThan( String col, Integer val ) { if ( val != null ) { this.query.append( String.format( "`%s` > %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnGreaterThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` > %s", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnEqualToOrGreaterThan public QueryBuilder columnEqualToOrGreaterThan( String col, Integer val ) { if ( val != null ) { this.query.append( String.format( "`%s` >= %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEqualToOrGreaterThan( String col, Long val ) { if ( val != null ) { this.query.append( String.format( "`%s` >= %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEqualToOrGreaterThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` >= %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateEqualToOrGreaterThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` >= '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateGreaterThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` > '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateWthoutBackTicksEqualToOrGreaterThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "%s >= '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnJoinDateEqualToOrGreaterThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { String[] parts = col.split( "\\." ); this.query.append( String.format( "`%s`.`%s` >= '%s'", parts[0], parts[1], MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnLessThan public QueryBuilder columnLessThan( String col, Integer val ) { if ( val != null ) { this.query.append( String.format( "`%s` < %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnLessThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` < %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnEqualToOrLessThan public QueryBuilder columnEqualToOrLessThan( String col, Integer val ) { if ( val != null ) { this.query.append( String.format( "`%s` <= %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEqualToOrLessThan( String col, Long val ) { if ( val != null ) { this.query.append( String.format( "`%s` <= %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnEqualToOrLessThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` <= %s", col, val ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateEqualToOrLessThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` <= '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateLessThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` < '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnDateWithoutBackTicksEqualToOrLessThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "%s <= '%s'", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnJoinDateEqualToOrLessThan( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { String[] parts = col.split( "\\." ); this.query.append( String.format( "`%s`.`%s` <= '%s'", parts[0], parts[1], MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnBetween public QueryBuilder columnBetween( String col, int val1, int val2 ) { this.query.append( String.format( "`%s` BETWEEN %s AND %s", col, val1, val2 ) ); this.query.append( " " ); this.previousCondition = true; return this; } public QueryBuilder columnBetweenDate( String col, String val1, String val2 ) { if ( isNotNullOrEmpty( val1 ) && isNotNullOrEmpty( val2 ) ) { this.query.append( String.format( "%s BETWEEN %s AND %s", col, MySQLUtils.escapeString( val1 ), MySQLUtils.escapeString( val2 ) ) ); this.query.append( " " ); } setPreviousCondition( val1 ); return this; } public QueryBuilder columnBetween( String col, String val1, String val2 ) { if ( isNotNullOrEmpty( val1 ) && isNotNullOrEmpty( val2 ) ) { this.query.append( String.format( "%s BETWEEN \"%s\" AND \"%s\"", col, MySQLUtils.escapeString( val1 ), MySQLUtils.escapeString( val2 ) ) ); this.query.append( " " ); } setPreviousCondition( val1 ); return this; } // columnLike public QueryBuilder columnLike( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` LIKE \"%s\"", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnLikeJoin public QueryBuilder columnLikeJoin( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "%s LIKE \"%s\"", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } //for stock report column like join sku public QueryBuilder columnLikeSku( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { String modifiedVal = val.replace("'", "%"); this.query.append( String.format( "%s LIKE '%s'", col, ( modifiedVal ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } //for stock report column like join title public QueryBuilder columnLikeTitle(String col, String val) { if (isNotNullOrEmpty(val)) { String modifiedVal = val.replace("'", "%"); this.query.append(String.format("`%s` LIKE '%s'", col, modifiedVal)); this.query.append(" "); } setPreviousCondition(val); return this; } // columnNotLike public QueryBuilder columnNotLike( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "`%s` NOT LIKE \"%s\"", col, MySQLUtils.escapeString( val ) ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // full text search public QueryBuilder columnFullText( String[] cols, String val, String operator ) { if ( isNotNullOrEmpty( val ) ) { // match phrase String matchPhrase = String.format( "MATCH (%s) ", String.join( ",", cols ) ); this.query.append( matchPhrase ); // against phrase String againstPhrase = String.format( "AGAINST ('%s' IN BOOLEAN MODE)", StringUtils.formatAgainstPhraseValues( val, operator ) ); this.query.append( againstPhrase ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder columnFullText( String[] cols, String val ) { if ( isNotNullOrEmpty( val ) ) { // match phrase String matchPhrase = String.format( "MATCH (%s) ", String.join( ",", cols ) ); this.query.append( matchPhrase ); // against phrase String againstPhrase = String.format( "AGAINST ('%s' IN BOOLEAN MODE)", StringUtils.formatAgainstPhraseValues( val, "+" ) ); this.query.append( againstPhrase ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // columnIsNull public QueryBuilder columnIsNull( String col ) { this.query.append( String.format( "`%s` IS NULL", col ) ); this.query.append( " " ); this.previousCondition = true; return this; } // columnIsNotNull public QueryBuilder columnIsNotNull( String col ) { this.query.append( String.format( "`%s` IS NOT NULL", col ) ); this.query.append( " " ); this.previousCondition = true; return this; } // columnIn public QueryBuilder columnIn( String col, String[] val ) { if ( val == null || val.length == 0 ) { this.previousCondition = false; return this; } String formattedValues = formatInValues( val ); this.query.append( String.format( "`%s` IN %s", col, formattedValues ) ); this.query.append( " " ); this.previousCondition = true; return this; } public QueryBuilder columnIn( String col, Long[] val ) { if ( val == null || val.length == 0 ) { this.previousCondition = false; return this; } String formattedValues = formatInValues( val ); this.query.append( String.format( "`%s` IN %s", col, formattedValues ) ); this.query.append( " " ); this.previousCondition = true; return this; } public QueryBuilder columnNotIn( String col, Long[] val ) { if ( val == null || val.length == 0 ) { this.previousCondition = false; return this; } String formattedValues = formatInValues( val ); this.query.append( String.format( "`%s` NOT IN %s", col, formattedValues ) ); this.query.append( " " ); this.previousCondition = true; return this; } // columnIn public QueryBuilder columnNotIn( String col, String[] val ) { if ( val == null || val.length == 0 ) { this.previousCondition = false; return this; } String formattedValues = formatInValues( val ); this.query.append( String.format( "`%s` NOT IN %s", col, formattedValues ) ); this.query.append( " " ); this.previousCondition = true; return this; } // comma separated column contains public QueryBuilder commaSeparatedColumnContains( String col, Long val ) { if ( val != null ) { this.query.append( String.format( "find_in_set( %s , `%s` )", val, col ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } public QueryBuilder commaSeparatedColumnContains( String col, String val ) { if ( isNotNullOrEmpty( val ) ) { this.query.append( String.format( "find_in_set( \"%s\" , `%s` )", MySQLUtils.escapeString( val ), col ) ); this.query.append( " " ); } setPreviousCondition( val ); return this; } // orderBy public QueryBuilder orderBy( String col, String sort ) { this.query.append( String.format( "ORDER BY `%s` %s", col, sort ) ); this.query.append( " " ); return this; } // orderByJoin public QueryBuilder orderByJoin( String col, String sort ) { String[] parts = col.split( "\\." ); this.query.append( String.format( "ORDER BY `%s`.`%s` %s", parts[0], parts[1], sort ) ); this.query.append( " " ); return this; } // orderByCastValue public QueryBuilder orderByCastColumn( String col, String dataType, String sort ) { this.query.append( String.format( "ORDER BY CAST( `%s` AS %s ) %s", col, dataType, sort ) ); this.query.append( " " ); return this; } // orderBy public QueryBuilder orderByColumnCondition( String columnCondition, String sort ) { this.query.append( String.format( "ORDER BY %s %s", columnCondition, sort ) ); this.query.append( " " ); return this; } // groupBy public QueryBuilder groupBy( String col ) { this.query.append( String.format( "GROUP BY `%s`", col ) ); this.query.append( " " ); return this; } // limit public QueryBuilder limit( Integer val ) { if( val != null ) { this.query.append( String.format( "LIMIT %s", val ) ); this.query.append( " " ); } return this; } public QueryBuilder limit( Long val ) { if ( val != null ) { this.query.append( String.format( "LIMIT %s", val ) ); this.query.append( " " ); } return this; } // not public QueryBuilder not() { this.query.append( "NOT" ); this.query.append( " " ); return this; } // and public QueryBuilder and() { if ( this.previousCondition ) { this.query.append( "AND" ); this.query.append( " " ); } return this; } // or public QueryBuilder or() { if ( this.previousCondition ) { this.query.append( "OR" ); this.query.append( " " ); } return this; } //bracket open public QueryBuilder bracketOpen() { this.query.append( "(" ); this.query.append( " " ); return this; } // bracket close public QueryBuilder bracketClose() { this.query.append( ")" ); this.query.append( " " ); return this; } // build public String build() { String queryStr = this.query.toString().trim(); // check for AND ORDER if ( queryStr.contains( " AND ORDER BY " ) ) { queryStr = queryStr.replaceAll( " AND ORDER BY ", " ORDER BY " ); } // check for AND LIMIT if ( queryStr.contains( " AND LIMIT" ) ) { queryStr = queryStr.replaceAll( " AND LIMIT", " LIMIT" ); } // check for AND GROUP BY if ( queryStr.contains( " AND GROUP BY" ) ) { queryStr = queryStr.replaceAll( " AND GROUP BY", " GROUP BY" ); } // check for ending OR if ( queryStr.endsWith( " OR" ) ) { queryStr = queryStr.substring( 0, queryStr.lastIndexOf( " OR" ) ); } // check for ending AND if ( queryStr.endsWith( " AND" ) ) { queryStr = queryStr.substring( 0, queryStr.lastIndexOf( " AND" ) ); } // checking for ending WHERE if ( queryStr.endsWith( " WHERE" ) ) { queryStr = queryStr.substring( 0, queryStr.lastIndexOf( " WHERE" ) ); } // checking for WHERE ORDER if ( queryStr.contains( " WHERE ORDER" ) ) { queryStr = queryStr.replaceAll( "WHERE ORDER BY", "ORDER BY" ); } // checking for WHERE LIMIT if ( queryStr.contains( " WHERE LIMIT" ) ) { queryStr = queryStr.replaceAll( "WHERE LIMIT", "LIMIT" ); } return queryStr; } // isNotNullOrEmpty private boolean isNotNullOrEmpty( String str ) { return !( ( str == null ) || str.isEmpty() ); } private boolean isNotNull( Boolean val ) { return !( val == null ); } // format columns private String formatColumns( String[] columns ) { StringBuilder stringBuilder = new StringBuilder(); for ( String column : columns ) { stringBuilder.append( String.format( "`%s`,", column ) ); } String str = stringBuilder.toString(); if ( str.endsWith( "," ) ) { str = str.substring( 0, str.lastIndexOf( "," ) ); } return str; } // format columns private String formatJoinColumns( String[] columns ) { StringBuilder stringBuilder = new StringBuilder(); for ( String column : columns ) { int intIndex = column.indexOf( "(" ); if ( intIndex != -1 ) { String[] partsRound = column.split( "\\(" ); String result = column.substring( column.indexOf( "(" ) + 1, column.indexOf( ")" ) ); String[] partsPoint = result.split( "\\." ); System.out.println( result ); stringBuilder.append( String.format( "%s(", partsRound[0] ) ); stringBuilder.append( String.format( "`%s`.", partsPoint[0] ) ); stringBuilder.append( String.format( "`%s`),", partsPoint[1] ) ); } else { String[] parts = column.split( "\\." ); stringBuilder.append( String.format( "`%s`.", parts[0] ) ); stringBuilder.append( String.format( "`%s`,", parts[1] ) ); } } String str = stringBuilder.toString(); if ( str.endsWith( "," ) ) { str = str.substring( 0, str.lastIndexOf( "," ) ); } return str; } // format in values private String formatInValues( String[] vals ) { if ( vals.length == 0 ) { return "(\"\")"; } StringBuilder strBuilder = new StringBuilder(); strBuilder.append( "(" ); for ( String val : vals ) { strBuilder.append( String.format( "\"%s\",", MySQLUtils.escapeString( val ) ) ); } strBuilder.append( ")" ); String str = strBuilder.toString(); // check for ending comma if ( str.endsWith( ",)" ) ) { str = str.substring( 0, str.lastIndexOf( ",)" ) ); str += ")"; } return str; } private String formatInValues( Long[] vals ) { if ( vals.length == 0 ) { return "(\"\")"; } StringBuilder strBuilder = new StringBuilder(); strBuilder.append( "(" ); for ( long val : vals ) { strBuilder.append( String.format( "%s,", val ) ); } strBuilder.append( ")" ); String str = strBuilder.toString(); // check for ending comma if ( str.endsWith( ",)" ) ) { str = str.substring( 0, str.lastIndexOf( ",)" ) ); str += ")"; } return str; } public QueryBuilder setInnerJoin( String table, String columnLeft, String columnRight ) { this.query.append( " INNER JOIN " ).append( table ).append( " ON " ).append( columnLeft ).append( " = " ).append( columnRight ).append( " " ); return this; } public QueryBuilder setLeftJoin( String table, String columnLeft, String columnRight ) { this.query.append( " LEFT JOIN " ).append( table ).append( " ON " ).append( columnLeft ).append( " = " ).append( columnRight ).append( " " ); return this; } // set previous condition private void setPreviousCondition( String val ) { this.previousCondition = isNotNullOrEmpty( val ); } private void setPreviousCondition( Long val ) { this.previousCondition = ( val != null ); } private void setPreviousCondition( Integer val ) { this.previousCondition = ( val != null ); } private void setPreviousCondition( Boolean val ) { this.previousCondition = isNotNull( val ); } public QueryBuilder append(String sqlFragment) { this.query.append(sqlFragment); return this; } }