/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* 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 li.strolch.persistence.postgresql;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import li.strolch.model.audit.AccessType;
import li.strolch.model.audit.ActionSelection;
import li.strolch.model.audit.AuditQuery;
import li.strolch.model.audit.AuditQueryVisitor;
import li.strolch.model.audit.ElementSelection;
import li.strolch.model.audit.IdentitySelection;
import li.strolch.model.query.StringSelection;
import li.strolch.utils.StringMatchMode;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*/
public class PostgreSqlAuditQueryVisitor implements AuditQueryVisitor {
protected StringBuilder sql;
protected StringBuilder sb;
protected List<Object> values;
protected long limit;
protected String indent;
private String sqlAsString;
/**
* @param fields
*/
public PostgreSqlAuditQueryVisitor(String fields) {
this.indent = "";
this.sql = new StringBuilder();
this.sb = new StringBuilder();
this.values = new ArrayList<>();
this.sql.append("select ");
this.sql.append(fields);
this.sql.append("\nfrom\n");
this.sql.append(" ");
this.sql.append(PostgreSqlAuditDao.TABLE_NAME);
this.indent = " ";
}
public String getSql() {
if (this.sqlAsString != null)
return this.sqlAsString;
this.sql.append("\nwhere\n");
this.sql.append(this.sb.toString());
this.sql.append("ORDER BY date DESC\n");
if (limit != 0)
this.sql.append("LIMIT " + limit + "\n");
this.sqlAsString = this.sql.toString();
return this.sqlAsString;
}
@Override
public void visit(AuditQuery<?> auditQuery) {
ensureAnd();
this.sb.append(this.indent);
this.sb.append(PostgreSqlAuditDao.ELEMENT_TYPE);
this.sb.append(" = ?\n");
this.limit = auditQuery.getLimit();
ensureAnd();
this.values.add(auditQuery.getElementTypeSelection());
PostgreSqlHelper.toSql(this.indent, this.sb, this.values, PostgreSqlAuditDao.DATE, auditQuery.getDateRange());
}
@Override
public void visit(ElementSelection selection) {
if (!selection.isElementSubTypesWildcard()) {
StringSelection sel = selection.getElementSubTypeSelection();
toSql(PostgreSqlAuditDao.ELEMENT_SUB_TYPE, sel.getMatchMode(), sel.getValues());
}
if (!selection.isElementAccessedWildcard()) {
StringSelection sel = selection.getElementAccessedSelection();
toSql(PostgreSqlAuditDao.ELEMENT_ACCESSED, sel.getMatchMode(), sel.getValues());
}
}
@Override
public void visit(IdentitySelection selection) {
if (selection.isWildcard())
return;
if (!selection.isFirstnameWildcard()) {
StringSelection sel = selection.getFirstnameSelection();
toSql(PostgreSqlAuditDao.FIRSTNAME, sel.getMatchMode(), sel.getValues());
}
if (!selection.isLastnameWildcard()) {
StringSelection sel = selection.getLastnameSelection();
toSql(PostgreSqlAuditDao.LASTNAME, sel.getMatchMode(), sel.getValues());
}
if (!selection.isUsernameWildcard()) {
StringSelection sel = selection.getUsernameSelection();
toSql(PostgreSqlAuditDao.USERNAME, sel.getMatchMode(), sel.getValues());
}
}
@Override
public void visit(ActionSelection selection) {
if (!selection.isWildcardAction()) {
StringSelection sel = selection.getActionSelection();
toSql(PostgreSqlAuditDao.ACTION, sel.getMatchMode(), sel.getValues());
}
if (!selection.isWildcardActionType()) {
AccessType[] accessTypes = selection.getAccessTypes();
ensureAnd();
this.sb.append(this.indent);
if (accessTypes.length == 1) {
this.sb.append(PostgreSqlAuditDao.ACCESS_TYPE + " = ?");
this.sb.append(PostgreSqlAuditDao.ACCESS_TYPE_TYPE);
this.sb.append("\n");
this.values.add(accessTypes[0].name());
} else {
this.sb.append(PostgreSqlAuditDao.ACCESS_TYPE + " in (");
for (int i = 0; i < accessTypes.length; i++) {
this.sb.append("?");
this.sb.append(PostgreSqlAuditDao.ACCESS_TYPE_TYPE);
this.values.add(accessTypes[i].name());
if (i < accessTypes.length - 1)
this.sb.append(", ");
}
this.sb.append(" )\n");
this.sb.append("\n");
}
}
}
private void toSql(String column, StringMatchMode mm, String[] values) {
ensureAnd();
this.sb.append(this.indent);
this.sb.append(PostgreSqlHelper.toSql(column, this.indent, mm, this.values, values));
}
public void setValues(PreparedStatement ps) throws SQLException {
for (int i = 0; i < this.values.size(); i++) {
ps.setObject(i + 1, this.values.get(i));
}
}
private void ensureAnd() {
if (this.sb.length() > 0) {
this.sb.append(this.indent);
this.sb.append("and \n");
}
}
}