/* * ==================== * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of the Common Development * and Distribution License("CDDL") (the "License"). You may not use this file * except in compliance with the License. * * You can obtain a copy of the License at * http://opensource.org/licenses/cddl1.php * See the License for the specific language governing permissions and limitations * under the License. * * When distributing the Covered Code, include this CDDL Header Notice in each file * and include the License file at http://opensource.org/licenses/cddl1.php. * If applicable, add the following below this CDDL Header, with the fields * enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * ==================== */ package org.identityconnectors.dbcommon; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.identityconnectors.common.Pair; import org.identityconnectors.common.StringUtil; /** * The Database Query builder creates the database query. * <p> * The main functionality of this helper class is create SQL query statement * with bundled object references * </p> * * @since 1.0 */ public class DatabaseQueryBuilder { private String selectFrom = null; // Mandatory selectFrom clause private String tableName = null; // Mandatory selectFrom clause private FilterWhereBuilder where = null; private Set<String> columns = new HashSet<String>(); private List<OrderBy> orderBy = null; /** * Set the columnNames to get. * * @param columns * the required columns in SQL query */ public void setColumns(Set<String> columns) { this.columns = columns; } /** * Set selectFrom and from clause. * * @param selectFrom * the selectFrom part including the from table */ public void setSelectFrom(String selectFrom) { this.selectFrom = selectFrom; } /** * Set the table name. * * @param tableName * name of the table */ public void setTableName(String tableName) { this.tableName = tableName; } /** * set the where builder. * * @param whereBuilder * {@link FilterWhereBuilder} the where filer builder */ public void setWhere(FilterWhereBuilder whereBuilder) { this.where = whereBuilder; } /** * Set the order by clause. * * @param orderBy * a list of {@link Pair} pair as columnName and sort order */ public void setOrderBy(List<OrderBy> orderBy) { this.orderBy = orderBy; } /** * DatabaseQuery Constructor, construct selectFrom from table name, columns * and where clause. * * @param tableName * The name of the database table to selectFrom from * @param columns * the names of the column to be in the result */ public DatabaseQueryBuilder(String tableName, Set<String> columns) { if (StringUtil.isBlank(tableName)) { throw new IllegalArgumentException("the tableName must not be null or empty"); } if (columns == null || columns.size() == 0) { throw new IllegalArgumentException("CoulmnNamesToGet must not be empty"); } this.tableName = tableName; this.columns = columns; } /** * DatabaseQuery Constructor which takes advantage of prepared selectFrom * SQL clause. * * @param selectFrom * mandatory selectFrom clause */ public DatabaseQueryBuilder(final String selectFrom) { if (StringUtil.isBlank(selectFrom)) { throw new IllegalArgumentException("the selectFrom clause must not be empty"); } this.selectFrom = selectFrom; } /** * Return full sql statement string. * * @return Sql query statement to execute */ public String getSQL() { if (StringUtil.isBlank(selectFrom)) { if (StringUtil.isBlank(tableName)) { throw new IllegalArgumentException("the tableName must not be null or empty"); } if (columns != null) { selectFrom = createSelect(columns); } if (StringUtil.isBlank(selectFrom)) { throw new IllegalArgumentException("the selectFrom clause must not be empty"); } } else { if (!selectFrom.toUpperCase().contains("SELECT")) { throw new IllegalArgumentException("the required SELECt clause is missing"); } if (!selectFrom.toUpperCase().contains("FROM")) { throw new IllegalArgumentException("the required FROM clause is missing"); } } String ret = selectFrom; if (where != null) { final String whereSql = where.getWhereClause(); if (!StringUtil.isBlank(whereSql)) { ret = whereAnd(selectFrom, whereSql); } } if (this.orderBy != null) { StringBuilder obld = new StringBuilder(" ORDER BY "); boolean first = true; for (OrderBy ord : orderBy) { if (!first) { obld.append(", "); } first = false; obld.append(ord.getColumnName()); obld.append(ord.isAscendent() ? " ASC" : " DESC"); } if (obld.length() != 0) { ret += obld.toString(); } } return ret; } /** * @param sqlSelect * @param whereAnd * @return */ private String whereAnd(String sqlSelect, String whereAnd) { int iofw = sqlSelect.indexOf("WHERE"); return (iofw == -1) ? sqlSelect + " WHERE " + whereAnd : sqlSelect.substring(0, iofw) + "WHERE (" + sqlSelect.substring(iofw + 5) + ") AND ( " + whereAnd + " )"; } /** * @param columnNamesToGet * @return the selectFrom statement */ private String createSelect(final Set<String> columnNamesToGet) { if (columnNamesToGet.size() == 0) { throw new IllegalStateException("No coulmnNamesToGet"); } StringBuilder ret = new StringBuilder("SELECT "); boolean first = true; for (String name : columnNamesToGet) { if (!first) { ret.append(", "); } ret.append(name); ret.append(" "); first = false; } ret.append("FROM "); ret.append(tableName); return ret.toString(); } /** * Values in wrapped object. * * @return the where values */ public List<SQLParam> getParams() { if (where == null) { return new ArrayList<SQLParam>(); } return where.getParams(); } /** * The Required order by data subclass. */ public static class OrderBy extends Pair<String, Boolean> { /** * One order by column. * * @param columnName * column name * @param asc * true/false for ascendent/descendent */ public OrderBy(String columnName, Boolean asc) { super(columnName, asc); } /** * The column name. * * @return a name */ public String getColumnName() { return this.first; } /** * The ascendent flag. * * @return a boolean true/false as ascendent/descendent */ public boolean isAscendent() { return this.second; } } }