/*
* SqlBuilder
*
* Copyright (C) 2010 Jaroslav Merxbauer
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package notwa.sql;
import java.util.ArrayList;
import notwa.dal.WorkItemDal;
/**
* <code>SqlBuilder</code> provides the power to transform a SQL template into the
* final SQL statement which can be exectuted againts the database.
* <p>The main purpose is to provide a parametrized SQL where the parameters will
* be replaced with the real values with the proper relations againts the coresponding
* columns</p>
* @see WorkItemDal#getSqlTemplate()
*
* @author Jaroslav Merxbauer
* @version %I% %G%
*/
public class SqlBuilder {
private StringBuilder sqltemplate;
private SqlFilter filter;
private ArrayList<SqlStatement> statements;
/**
* The sole constructor expecting the actual sql template and the parameters
* that are going to be factored into the template.
*
* @param template The SQL template.
* @param parameters The SQL parameters.
*/
public SqlBuilder(String template, SqlParameterSet parameters) {
this(template, new SimpleSqlFilter(parameters, Sql.Logical.CONJUNCTION));
}
/**
* The sole constructor expecting the actual sql template and the parameters
* that are going to be factored into the template.
*
* @param template The SQL template.
* @param parameters The SQL parameters.
*/
public SqlBuilder(String template, SqlFilter filter) {
this.sqltemplate = new StringBuilder(template);
this.filter = filter;
this.statements = new ArrayList<SqlStatement>();
}
/**
* Compiles the resulting SQL Query based on the given SQL Parameters through
* the constructor.
*
* @return The final SQL Query.
*/
public String compileSql() {
parseTemplate();
for (SqlStatement s : statements) {
s.applyFilter(filter);
}
for (SqlStatement s : statements) {
String statementIdentifier = String.format("<s#%d>", statements.indexOf(s));
int statementStart = sqltemplate.indexOf(statementIdentifier);
sqltemplate.replace(statementStart, statementStart + statementIdentifier.length(), s.compileStatement());
}
return sqltemplate.toString();
}
/**
* Parses the given SQL template which actually means that it pulls out the
* STATEMENT sections and puts their object representation into the collection.
*/
private void parseTemplate() {
int statementStart = sqltemplate.indexOf("/** STATEMENT");
int statementEnd = 0;
while (statementStart != -1) {
statementEnd = sqltemplate.indexOf("**/", statementStart) + 3;
if (statementEnd != -1) {
SqlStatement s = new SqlStatement();
if (s.parse(sqltemplate.substring(statementStart, statementEnd))) {
statements.add(s);
sqltemplate.replace(statementStart, statementEnd, String.format("<s#%d>", statements.indexOf(s)));
}
}
statementStart = sqltemplate.indexOf("/** STATEMENT", statementEnd);
}
}
}