package zutil.db; import java.util.LinkedList; /** * A class that generates a query by objects, minimizes errors * * @author Ziver */ public class SQLQuery { protected static abstract class SQLQueryItem{ SQLQueryItem root; protected SQLQueryItem(){} protected void setRoot(SQLQueryItem root){ this.root = root; } protected abstract void build(StringBuilder query); public String toString(){ StringBuilder query = new StringBuilder(); root.build(query); return query.toString(); } } //******************************************* // Main Types /** * * SELECT * [ALL | DISTINCT | DISTINCTROW ] * [FROM table_references * [WHERE where_condition] * [GROUP BY {col_name | expr | position} * [ASC | DESC], ... [WITH ROLLUP]] * [HAVING where_condition] * [ORDER BY {col_name | expr | position} * [ASC | DESC], ...] * [LIMIT {[offset,] row_count | row_count OFFSET offset}] * */ public static class SQLSelect extends SQLQueryItem{ String[] params; SQLFrom from; /** * @param params is the columns that you want out of the SELECT query, leave empty for all columns */ protected SQLSelect(String ...params ){ setRoot(this); this.params = params; } protected void build(StringBuilder query) { query.append("SELECT "); if( params == null || params.length <= 0 ) query.append("*"); else{ for(int i=0; i * UPDATE [LOW_PRIORITY] [IGNORE] table_reference * SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ... * [WHERE where_condition] * [ORDER BY ...] * [LIMIT row_count] * */ public static class SQLUpdate extends SQLQueryItem{ protected SQLUpdate(){ setRoot(this); } protected void build(StringBuilder query) { } } /* * * INSERT [INTO] tbl_name * SET col_name={expr | DEFAULT}, ... * * INSERT [INTO] tbl_name [(col_name,...)] * {VALUES | VALUE} ({expr | DEFAULT},...),(...),... * */ public static class SQLInsert extends SQLQueryItem{ protected SQLInsert(){ setRoot(this); } protected void build(StringBuilder query) { } } /* * * DELETE FROM tbl_name * [WHERE where_condition] * [ORDER BY ...] * [LIMIT row_count] * */ public static class SQLDelete extends SQLQueryItem{ protected SQLDelete(){ setRoot(this); } protected void build(StringBuilder query) { } } //******************************************* // Sub Types public static class SQLFrom extends SQLQueryItem{ LinkedList tables = new LinkedList(); SQLQueryItem next; protected SQLFrom(SQLQueryItem root, String ...tables){ setRoot(root); for( String table : tables ) this.tables.add(table); } public SQLFrom NATURAL_JOIN(String table){ return joinLastTable("NATURAL JOIN", table); } public SQLFrom NATURAL_JOIN(String ...tables){ return joinTable("NATURAL JOIN", tables); } public SQLFrom JOIN(String table){ return joinLastTable("JOIN", table); } public SQLFrom JOIN(String ...tables){ return joinTable("JOIN", tables); } public SQLFrom UNION(String table){ return joinLastTable("UNION", table); } public SQLFrom UNION(String ...tables){ return joinTable("UNION", tables); } private SQLFrom joinLastTable(String type, String table){ String last = tables.getLast(); tables.removeLast(); tables.add( new StringBuilder(last).append(" ").append(type).append(" ").append(table).toString()); return this; } private SQLFrom joinTable(String type, String[] tables){ if( tables.length < 2 ) return this; StringBuilder str = new StringBuilder(); for(int i=0; i conds = new LinkedList(); SQLQueryItem next; protected SQLWhere(SQLQueryItem root){ setRoot(root); } /** * Equals (arg1 = arg2) */ public SQLWhere EQ(String arg1, String arg2){ return cond("=", arg1, arg2); } /** * Not Equal (arg1 != arg2) */ public SQLWhere NE(String arg1, String arg2){ return cond("!=", arg1, arg2); } /** * Less than (arg1 < arg2) */ public SQLWhere LT(String arg1, String arg2){ return cond("<", arg1, arg2); } /** * Greater than (arg1 > arg2) */ public SQLWhere GT(String arg1, String arg2){ return cond(">", arg1, arg2); } /** * Less than or equal (arg1 <= arg2) */ public SQLWhere LE(String arg1, String arg2){ return cond("<=", arg1, arg2); } /** * Greater than or equal (arg1 >= arg2) */ public SQLWhere GE(String arg1, String arg2){ return cond(">=", arg1, arg2); } private SQLWhere cond(String cond, String arg1, String arg2){ conds.add( //new StringBuilder(arg1).append(cond).append('\"').append(arg2).append('\"').toString()); new StringBuilder(arg1).append(cond).append(arg2).toString()); return this; } public SQLGroupBy GROUP_BY( String ...cols ){ return (SQLGroupBy) (next = new SQLGroupBy(root, cols)); } public SQLOrderBy ORDER_BY( String ...cols ){ return (SQLOrderBy) (next = new SQLOrderBy(root, cols)); } public SQLLimit LIMIT( long count ){ return (SQLLimit) (next = new SQLLimit(root, count)); } protected void build(StringBuilder query) { query.append(" WHERE "); if( conds.isEmpty() ) throw new RuntimeException("The WHERE query item must hav atleast 1 condition!"); for(int i=0; i extends SQLQueryItem{ protected String[] cols; protected String end; SQLQueryItem next; protected SQLGroupOrderBy(SQLQueryItem root, String ...cols){ setRoot(root); this.cols = cols; } @SuppressWarnings("unchecked") public T ASC(){ end = "ASC"; return (T)this; } @SuppressWarnings("unchecked") public T DESC(){ end = "DESC"; return (T)this; } protected void build(String op, StringBuilder query) { query.append(' ').append(op).append(' '); if( cols == null || cols.length <= 0 ) throw new RuntimeException("The "+op+" query item must hav atleast 1 column!"); for(int i=0; i{ protected SQLGroupBy(SQLQueryItem root, String ...cols){ super( root, cols ); } public SQLOrderBy ORDER_BY( String ...cols ){ return (SQLOrderBy) (next = new SQLOrderBy(root, cols)); } public SQLLimit LIMIT( long count ){ return (SQLLimit) (next = new SQLLimit(root, count)); } protected void build(StringBuilder query) { build("GROUP BY", query); } } public static class SQLOrderBy extends SQLGroupOrderBy{ protected SQLOrderBy(SQLQueryItem root, String ...cols){ super( root, cols ); } public SQLLimit LIMIT( long count ){ return (SQLLimit) (next = new SQLLimit(root, count)); } protected void build(StringBuilder query) { build("ORDER BY", query); } } public static class SQLLimit extends SQLQueryItem{ long start; Long count; protected SQLLimit(SQLQueryItem root, long start){ setRoot( root ); this.start = start; } public SQLLimit TO( long count ){ this.count = count; return this; } protected void build(StringBuilder query) { query.append(" LIMIT ").append( start ); if( count != null ) query.append(' ').append( count ); } } //******************************************* public static SQLSelect SELECT( String ...params ){ return new SQLSelect( params ); } public static SQLUpdate UPDATE(){ return new SQLUpdate(); } public static SQLInsert INSERT(){ return new SQLInsert(); } public static SQLDelete DELETE(){ return new SQLDelete(); } }