[Major] Implemented PostgreSql AuditQuery
This commit is contained in:
parent
4cdfb9b667
commit
7f5f207214
|
@ -33,13 +33,26 @@ import li.strolch.model.audit.AuditVisitor;
|
|||
import li.strolch.persistence.api.AuditDao;
|
||||
import li.strolch.persistence.api.StrolchPersistenceException;
|
||||
import ch.eitchnet.utils.collections.DateRange;
|
||||
import ch.eitchnet.utils.helper.StringHelper;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PostgreSqlAuditDao implements AuditDao {
|
||||
|
||||
public static final String FIELDS = "id, username, firstname, lastname, date, element_type, element_accessed, new_version, action, access_type";
|
||||
public static final String ID = "id";
|
||||
public static final String ACCESS_TYPE = "access_type";
|
||||
public static final String ACCESS_TYPE_TYPE = "::access_type";
|
||||
public static final String ACTION = "action";
|
||||
public static final String NEW_VERSION = "new_version";
|
||||
public static final String ELEMENT_ACCESSED = "element_accessed";
|
||||
public static final String ELEMENT_TYPE = "element_type";
|
||||
public static final String DATE = "date";
|
||||
public static final String LASTNAME = "lastname";
|
||||
public static final String FIRSTNAME = "firstname";
|
||||
public static final String USERNAME = "username";
|
||||
public static final String FIELDS = StringHelper.commaSeparated(ID, USERNAME, FIRSTNAME, LASTNAME, DATE,
|
||||
ELEMENT_TYPE, ELEMENT_ACCESSED, NEW_VERSION, ACTION, ACCESS_TYPE);
|
||||
public static final String TABLE_NAME = "audits";
|
||||
|
||||
private PostgreSqlStrolchTransaction tx;
|
||||
|
@ -53,7 +66,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
|
||||
@Override
|
||||
public boolean hasElement(String type, Long id) {
|
||||
String sql = "select count(*) from " + TABLE_NAME + " where element_type = ? and id = ?"; //$NON-NLS-1$
|
||||
String sql = "select count(*) from " + TABLE_NAME + " where " + ELEMENT_TYPE + " = ? and " + ID + " = ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, type);
|
||||
|
@ -78,7 +91,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
|
||||
@Override
|
||||
public long querySize(DateRange dateRange) {
|
||||
String sql = "select count(*) from " + TABLE_NAME + " where date between ? and ?"; //$NON-NLS-1$
|
||||
String sql = "select count(*) from " + TABLE_NAME + " where " + DATE + " between ? and ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
statement.setDate(1, new Date(dateRange.getFromDate().getTime()), Calendar.getInstance());
|
||||
|
@ -96,7 +109,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
|
||||
@Override
|
||||
public long querySize(String type, DateRange dateRange) {
|
||||
String sql = "select count(*) from " + TABLE_NAME + " where element_type = ? and date between ? and ?"; //$NON-NLS-1$
|
||||
String sql = "select count(*) from " + TABLE_NAME + " where " + ELEMENT_TYPE + " = ? and " + DATE + " between ? and ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, type);
|
||||
|
@ -117,11 +130,11 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
public Set<String> queryTypes() {
|
||||
Set<String> keySet = new HashSet<>();
|
||||
|
||||
String sql = "select distinct element_type from " + TABLE_NAME; //$NON-NLS-1$
|
||||
String sql = "select distinct " + ELEMENT_TYPE + " from " + TABLE_NAME; //$NON-NLS-1$
|
||||
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
try (ResultSet result = statement.executeQuery()) {
|
||||
while (result.next()) {
|
||||
keySet.add(result.getString("element_type")); //$NON-NLS-1$
|
||||
keySet.add(result.getString(ELEMENT_TYPE)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
@ -134,7 +147,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
@Override
|
||||
public Audit queryBy(String type, Long id) {
|
||||
|
||||
String sql = "select " + FIELDS + " from " + TABLE_NAME + " where element_type = ? and id = ?"; //$NON-NLS-1$
|
||||
String sql = "select " + FIELDS + " from " + TABLE_NAME + " where " + ELEMENT_TYPE + " = ? and " + ID + " = ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, type);
|
||||
|
@ -157,7 +170,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
@Override
|
||||
public List<Audit> queryAll(String type, DateRange dateRange) {
|
||||
List<Audit> list = new ArrayList<>();
|
||||
String sql = "select " + FIELDS + " from " + TABLE_NAME + " where element_type = ? and date between ? and ?"; //$NON-NLS-1$
|
||||
String sql = "select " + FIELDS + " from " + TABLE_NAME + " where " + ELEMENT_TYPE + " = ? and " + DATE + " between ? and ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
statement.setString(1, type);
|
||||
|
@ -205,7 +218,9 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
|
||||
@Override
|
||||
public void update(Audit audit) {
|
||||
String sql = "update " + TABLE_NAME + " set id = ?, username = ?, firstname = ?, lastname = ?, date = ?, element_type = ?, element_accessed = ?, new_version = ?, action = ?, access_type = ?::access_type where id = ?"; //$NON-NLS-1$
|
||||
String sql = "update " + TABLE_NAME + " set " + ID + " = ?, " + USERNAME + " = ?, " + FIRSTNAME + " = ?, "
|
||||
+ LASTNAME + " = ?, " + DATE + " = ?, " + ELEMENT_TYPE + " = ?, " + ELEMENT_ACCESSED + " = ?, "
|
||||
+ NEW_VERSION + " = ?, " + ACTION + " = ?, " + ACCESS_TYPE + " = ?::access_type where " + ID + " = ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
setAuditFields(audit, preparedStatement);
|
||||
|
@ -232,7 +247,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
|
||||
@Override
|
||||
public void remove(Audit audit) {
|
||||
String sql = "delete from " + TABLE_NAME + " where id = ?"; //$NON-NLS-1$
|
||||
String sql = "delete from " + TABLE_NAME + " where " + ID + " = ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
preparedStatement.setLong(1, audit.getId());
|
||||
|
@ -259,7 +274,7 @@ public class PostgreSqlAuditDao implements AuditDao {
|
|||
|
||||
@Override
|
||||
public long removeAll(String type, DateRange dateRange) {
|
||||
String sql = "delete from " + TABLE_NAME + " where element_type = ? and date between ? and ?"; //$NON-NLS-1$
|
||||
String sql = "delete from " + TABLE_NAME + " where " + ELEMENT_TYPE + " = ? and " + DATE + " between ? and ?"; //$NON-NLS-1$
|
||||
try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) {
|
||||
|
||||
preparedStatement.setString(1, type);
|
||||
|
|
|
@ -24,7 +24,6 @@ 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.DateRangeSelection;
|
||||
import li.strolch.model.audit.ElementSelection;
|
||||
import li.strolch.model.audit.IdentitySelection;
|
||||
import li.strolch.model.query.StringSelection;
|
||||
|
@ -63,31 +62,28 @@ public class PostgreSqlAuditQueryVisitor implements AuditQueryVisitor {
|
|||
return sqlAsString;
|
||||
|
||||
this.sql.append("\nwhere\n");
|
||||
this.sql.append(this.indent);
|
||||
this.sql.append(this.sb.toString());
|
||||
sqlAsString = this.sql.toString();
|
||||
return sqlAsString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ElementSelection selection) {
|
||||
if (selection.isWildcard())
|
||||
return;
|
||||
public void visit(AuditQuery auditQuery) {
|
||||
ensureAnd();
|
||||
this.sb.append(this.indent);
|
||||
this.sb.append(PostgreSqlAuditDao.ELEMENT_TYPE);
|
||||
this.sb.append(" = ?\n");
|
||||
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.isElementsAccessedWildcard()) {
|
||||
StringSelection sel = selection.getElementAccessedSelection();
|
||||
toSql(sel.getMatchMode(), sel.getValues());
|
||||
toSql(PostgreSqlAuditDao.ELEMENT_ACCESSED, sel.getMatchMode(), sel.getValues());
|
||||
}
|
||||
|
||||
if (!selection.isElementTypesWildcard()) {
|
||||
StringSelection sel = selection.getElementTypeSelection();
|
||||
toSql(sel.getMatchMode(), sel.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
private void toSql(StringMatchMode mm, String[] values) {
|
||||
this.sb.append(this.indent);
|
||||
this.sb.append(PostgreSqlHelper.toSql(this.indent, mm, this.values, values));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -97,59 +93,68 @@ public class PostgreSqlAuditQueryVisitor implements AuditQueryVisitor {
|
|||
|
||||
if (!selection.isFirstnameWildcard()) {
|
||||
StringSelection sel = selection.getFirstnameSelection();
|
||||
toSql(sel.getMatchMode(), sel.getValues());
|
||||
toSql(PostgreSqlAuditDao.FIRSTNAME, sel.getMatchMode(), sel.getValues());
|
||||
}
|
||||
|
||||
if (!selection.isLastnameWildcard()) {
|
||||
StringSelection sel = selection.getLastnameSelection();
|
||||
toSql(sel.getMatchMode(), sel.getValues());
|
||||
toSql(PostgreSqlAuditDao.LASTNAME, sel.getMatchMode(), sel.getValues());
|
||||
}
|
||||
|
||||
if (!selection.isUsernameWildcard()) {
|
||||
StringSelection sel = selection.getUsernameSelection();
|
||||
toSql(sel.getMatchMode(), sel.getValues());
|
||||
toSql(PostgreSqlAuditDao.USERNAME, sel.getMatchMode(), sel.getValues());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(DateRangeSelection selection) {
|
||||
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(ActionSelection selection) {
|
||||
if (!selection.isWildcardAction()) {
|
||||
StringSelection sel = selection.getActionSelection();
|
||||
toSql(sel.getMatchMode(), sel.getValues());
|
||||
toSql(PostgreSqlAuditDao.ACTION, sel.getMatchMode(), sel.getValues());
|
||||
}
|
||||
|
||||
if (!selection.isWildcardActionType()) {
|
||||
|
||||
AccessType[] accessTypes = selection.getAccessTypes();
|
||||
String[] query = new String[accessTypes.length];
|
||||
ensureAnd();
|
||||
this.sb.append(this.indent);
|
||||
if (accessTypes.length == 1) {
|
||||
sb.append(PostgreSqlAuditDao.ACCESS_TYPE + " = ?");
|
||||
sb.append(PostgreSqlAuditDao.ACCESS_TYPE_TYPE);
|
||||
sb.append("\n");
|
||||
this.values.add(accessTypes[0].name());
|
||||
} else {
|
||||
sb.append(PostgreSqlAuditDao.ACCESS_TYPE + " in (");
|
||||
for (int i = 0; i < accessTypes.length; i++) {
|
||||
query[i] = accessTypes[i].name();
|
||||
sb.append("?");
|
||||
sb.append(PostgreSqlAuditDao.ACCESS_TYPE_TYPE);
|
||||
values.add(accessTypes[i].name());
|
||||
if (i < accessTypes.length - 1)
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(" )\n");
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
toSql(StringMatchMode.EQUALS_CASE_SENSITIVE, query);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(AuditQuery auditQuery) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ps
|
||||
* @throws SQLException
|
||||
*/
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,17 +15,47 @@
|
|||
*/
|
||||
package li.strolch.persistence.postgresql;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ch.eitchnet.utils.StringMatchMode;
|
||||
import ch.eitchnet.utils.collections.DateRange;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class PostgreSqlHelper {
|
||||
|
||||
public static String toSql(String indent, StringMatchMode mm, List<Object> values, String... query) {
|
||||
public static void toSql(String indent, StringBuilder sb, List<Object> values, String column, DateRange dateRange) {
|
||||
|
||||
// TODO handle inclusive/exclusive: between is inclusive
|
||||
|
||||
if (dateRange.isDate()) {
|
||||
sb.append(indent);
|
||||
sb.append(column);
|
||||
sb.append(" = ?\n");
|
||||
values.add(new Date(dateRange.getFromDate().getTime()));
|
||||
} else if (dateRange.isBounded()) {
|
||||
sb.append(indent);
|
||||
sb.append(column);
|
||||
sb.append(" between ? and ?\n");
|
||||
values.add(new Date(dateRange.getFromDate().getTime()));
|
||||
values.add(new Date(dateRange.getToDate().getTime()));
|
||||
} else if (dateRange.isToBounded()) {
|
||||
sb.append(indent);
|
||||
sb.append(column);
|
||||
sb.append(" <= ?\n");
|
||||
values.add(new Date(dateRange.getToDate().getTime()));
|
||||
} else if (dateRange.isFromBounded()) {
|
||||
sb.append(indent);
|
||||
sb.append(column);
|
||||
sb.append(" >= ?\n");
|
||||
values.add(new Date(dateRange.getFromDate().getTime()));
|
||||
}
|
||||
}
|
||||
|
||||
public static String toSql(String column, String indent, StringMatchMode mm, List<Object> values, String... query) {
|
||||
|
||||
// CS EQ
|
||||
// 1. x x
|
||||
|
@ -36,10 +66,10 @@ public class PostgreSqlHelper {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
if (mm.isCaseSensitve() && mm.isEquals()) {
|
||||
if (query.length == 1) {
|
||||
sb.append("name = ?\n");
|
||||
sb.append(column + " = ?\n");
|
||||
values.add(query[0]);
|
||||
} else {
|
||||
sb.append("name in ( ");
|
||||
sb.append(column + " in ( ");
|
||||
for (int i = 0; i < query.length; i++) {
|
||||
sb.append("?");
|
||||
values.add(query[i]);
|
||||
|
@ -50,10 +80,10 @@ public class PostgreSqlHelper {
|
|||
}
|
||||
} else if (!mm.isCaseSensitve() && mm.isEquals()) {
|
||||
if (query.length == 1) {
|
||||
sb.append("lower(name) = ?\n");
|
||||
sb.append("lower(" + column + ") = ?\n");
|
||||
values.add(query[0].toLowerCase());
|
||||
} else {
|
||||
sb.append("lower(name) in ( ");
|
||||
sb.append("lower(" + column + ") in ( ");
|
||||
for (int i = 0; i < query.length; i++) {
|
||||
sb.append("?");
|
||||
values.add(query[i].toLowerCase());
|
||||
|
@ -64,14 +94,14 @@ public class PostgreSqlHelper {
|
|||
}
|
||||
} else if (!mm.isEquals() && mm.isCaseSensitve()) {
|
||||
if (query.length == 1) {
|
||||
sb.append("name like ?\n");
|
||||
sb.append(column + " like ?\n");
|
||||
values.add("%" + query[0] + "%");
|
||||
} else {
|
||||
sb.append("(\n");
|
||||
for (int i = 0; i < query.length; i++) {
|
||||
sb.append(indent);
|
||||
sb.append(" ");
|
||||
sb.append("name like ?");
|
||||
sb.append(column + " like ?");
|
||||
values.add("%" + query[i] + "%");
|
||||
if (i < query.length - 1)
|
||||
sb.append(" or");
|
||||
|
@ -81,14 +111,14 @@ public class PostgreSqlHelper {
|
|||
}
|
||||
} else {
|
||||
if (query.length == 1) {
|
||||
sb.append("lower(name) like ?\n");
|
||||
sb.append("lower(" + column + ") like ?\n");
|
||||
values.add("%" + query[0].toLowerCase() + "%");
|
||||
} else {
|
||||
sb.append("(\n");
|
||||
for (int i = 0; i < query.length; i++) {
|
||||
sb.append(indent);
|
||||
sb.append(" ");
|
||||
sb.append("lower(name) like ?");
|
||||
sb.append("lower(" + column + ") like ?");
|
||||
values.add("%" + query[i].toLowerCase() + "%");
|
||||
if (i < query.length - 1)
|
||||
sb.append(" or");
|
||||
|
@ -103,35 +133,35 @@ public class PostgreSqlHelper {
|
|||
|
||||
public static void main(String[] args) {
|
||||
ArrayList<Object> values = new ArrayList<>();
|
||||
String sql = toSql(" ", StringMatchMode.CONTAINS_CASE_INSENSITIVE, values, "foo", "bar", "fub");
|
||||
String sql = toSql("name", " ", StringMatchMode.CONTAINS_CASE_INSENSITIVE, values, "foo", "bar", "fub");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.CONTAINS_CASE_INSENSITIVE, values, "foo");
|
||||
sql = toSql("name", " ", StringMatchMode.CONTAINS_CASE_INSENSITIVE, values, "foo");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.CONTAINS_CASE_SENSITIVE, values, "foo", "bar", "fub");
|
||||
sql = toSql("name", " ", StringMatchMode.CONTAINS_CASE_SENSITIVE, values, "foo", "bar", "fub");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.CONTAINS_CASE_SENSITIVE, values, "foo");
|
||||
sql = toSql("name", " ", StringMatchMode.CONTAINS_CASE_SENSITIVE, values, "foo");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.EQUALS_CASE_INSENSITIVE, values, "foo", "bar", "fub");
|
||||
sql = toSql("name", " ", StringMatchMode.EQUALS_CASE_INSENSITIVE, values, "foo", "bar", "fub");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.EQUALS_CASE_INSENSITIVE, values, "foo");
|
||||
sql = toSql("name", " ", StringMatchMode.EQUALS_CASE_INSENSITIVE, values, "foo");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.EQUALS_CASE_SENSITIVE, values, "foo", "bar", "fub");
|
||||
sql = toSql("name", " ", StringMatchMode.EQUALS_CASE_SENSITIVE, values, "foo", "bar", "fub");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
|
||||
sql = toSql(" ", StringMatchMode.EQUALS_CASE_SENSITIVE, values, "foo");
|
||||
sql = toSql("name", " ", StringMatchMode.EQUALS_CASE_SENSITIVE, values, "foo");
|
||||
System.out.println(sql);
|
||||
System.out.println();
|
||||
}
|
||||
|
|
|
@ -15,13 +15,10 @@
|
|||
*/
|
||||
package li.strolch.persistence.postgresql;
|
||||
|
||||
import java.sql.Date;
|
||||
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.model.query.DateSelection;
|
||||
import li.strolch.model.query.OrderQueryVisitor;
|
||||
import li.strolch.model.query.StateSelection;
|
||||
import ch.eitchnet.utils.collections.DateRange;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
|
@ -45,28 +42,7 @@ public class PostgreSqlOrderQueryVisitor extends PostgreSqlQueryVisitor implemen
|
|||
|
||||
@Override
|
||||
public void visit(DateSelection selection) {
|
||||
|
||||
// TODO handle inclusive and exclusive date ranges
|
||||
|
||||
DateRange dateRange = selection.getDateRange();
|
||||
if (dateRange.isDate()) {
|
||||
sb.append(indent);
|
||||
sb.append("date = ?\n");
|
||||
values.add(new Date(dateRange.getFromDate().getTime()));
|
||||
} else if (dateRange.isBounded()) {
|
||||
sb.append(indent);
|
||||
sb.append("date between ? and ?\n");
|
||||
values.add(new Date(dateRange.getFromDate().getTime()));
|
||||
values.add(new Date(dateRange.getToDate().getTime()));
|
||||
} else if (dateRange.isToBounded()) {
|
||||
sb.append(indent);
|
||||
sb.append("date < ?\n");
|
||||
values.add(new Date(dateRange.getToDate().getTime()));
|
||||
} else if (dateRange.isFromBounded()) {
|
||||
sb.append(indent);
|
||||
sb.append("date > ?\n");
|
||||
values.add(new Date(dateRange.getFromDate().getTime()));
|
||||
}
|
||||
PostgreSqlHelper.toSql(this.indent, this.sb, this.values, "date", selection.getDateRange());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -144,7 +144,7 @@ public abstract class PostgreSqlQueryVisitor implements StrolchElementSelectionV
|
|||
this.sb.append(this.indent);
|
||||
String name = selection.getName();
|
||||
StringMatchMode mm = selection.getMatchMode();
|
||||
this.sb.append(toSql(this.indent, mm, this.values, name));
|
||||
this.sb.append(toSql("name", this.indent, mm, this.values, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* 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.dao.test;
|
||||
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.CONFIG_SRC;
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_PASSWORD;
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_STORE_PATH_DIR;
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_URL;
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_USERNAME;
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.RUNTIME_PATH;
|
||||
import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.dropSchema;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import li.strolch.agent.api.AuditTrail;
|
||||
import li.strolch.agent.api.StrolchRealm;
|
||||
import li.strolch.model.ModelGenerator;
|
||||
import li.strolch.model.Tags;
|
||||
import li.strolch.model.audit.AccessType;
|
||||
import li.strolch.model.audit.Audit;
|
||||
import li.strolch.model.audit.AuditQuery;
|
||||
import li.strolch.persistence.api.AbstractTransaction;
|
||||
import li.strolch.persistence.api.StrolchTransaction;
|
||||
import li.strolch.persistence.postgresql.PostgreSqlAuditQueryVisitor;
|
||||
import li.strolch.runtime.StrolchConstants;
|
||||
import li.strolch.testbase.runtime.RuntimeMock;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.eitchnet.privilege.model.Certificate;
|
||||
import ch.eitchnet.utils.StringMatchMode;
|
||||
import ch.eitchnet.utils.collections.DateRange;
|
||||
|
||||
/**
|
||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||
*/
|
||||
public class AuditQueryTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuditQueryTest.class);
|
||||
private static RuntimeMock runtimeMock;
|
||||
|
||||
private static Date past;
|
||||
private static Date earlier;
|
||||
private static Date current;
|
||||
private static Date later;
|
||||
private static Date future;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws SQLException {
|
||||
|
||||
dropSchema(DB_URL, DB_USERNAME, DB_PASSWORD);
|
||||
|
||||
File rootPath = new File(RUNTIME_PATH);
|
||||
File configSrc = new File(CONFIG_SRC);
|
||||
runtimeMock = new RuntimeMock();
|
||||
runtimeMock.mockRuntime(rootPath, configSrc);
|
||||
new File(rootPath, DB_STORE_PATH_DIR).mkdir();
|
||||
runtimeMock.startContainer();
|
||||
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.clear();
|
||||
cal.set(2000, 1, 1);
|
||||
past = cal.getTime();
|
||||
cal.set(2000, 4, 1);
|
||||
earlier = cal.getTime();
|
||||
cal.set(2000, 6, 1);
|
||||
current = cal.getTime();
|
||||
cal.set(2000, 8, 1);
|
||||
later = cal.getTime();
|
||||
cal.set(2000, 11, 1);
|
||||
future = cal.getTime();
|
||||
|
||||
Certificate cert = runtimeMock.getPrivilegeHandler().authenticate("test", "test".getBytes());
|
||||
StrolchRealm realm = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM);
|
||||
int i = 0;
|
||||
try (StrolchTransaction tx = realm.openTx(cert, "test")) {
|
||||
((AbstractTransaction) tx).setSuppressAudits(true);
|
||||
AuditTrail auditTrail = tx.getAuditTrail();
|
||||
|
||||
Audit randomAudit;
|
||||
randomAudit = ModelGenerator.randomAudit();
|
||||
randomAudit.setId(i++);
|
||||
randomAudit.setUsername("earlier");
|
||||
randomAudit.setDate(earlier);
|
||||
randomAudit.setAccessType(AccessType.CREATE);
|
||||
randomAudit.setAction("create");
|
||||
randomAudit.setElementAccessed(randomAudit.getAccessType().name());
|
||||
auditTrail.add(tx, randomAudit);
|
||||
|
||||
randomAudit = ModelGenerator.randomAudit();
|
||||
randomAudit.setId(i++);
|
||||
randomAudit.setDate(current);
|
||||
randomAudit.setUsername("current");
|
||||
randomAudit.setAccessType(AccessType.READ);
|
||||
randomAudit.setAction("read");
|
||||
randomAudit.setElementAccessed(randomAudit.getAccessType().name());
|
||||
auditTrail.add(tx, randomAudit);
|
||||
|
||||
randomAudit = ModelGenerator.randomAudit();
|
||||
randomAudit.setId(i++);
|
||||
randomAudit.setDate(later);
|
||||
randomAudit.setUsername("later");
|
||||
randomAudit.setAccessType(AccessType.UPDATE);
|
||||
randomAudit.setAction("update");
|
||||
randomAudit.setElementAccessed(randomAudit.getAccessType().name());
|
||||
auditTrail.add(tx, randomAudit);
|
||||
|
||||
randomAudit = ModelGenerator.randomAudit();
|
||||
randomAudit.setId(i++);
|
||||
randomAudit.setDate(current);
|
||||
randomAudit.setUsername("current");
|
||||
randomAudit.setAccessType(AccessType.DELETE);
|
||||
randomAudit.setAction("delete");
|
||||
randomAudit.setElementAccessed(randomAudit.getAccessType().name());
|
||||
auditTrail.add(tx, randomAudit);
|
||||
|
||||
randomAudit = ModelGenerator.randomAudit();
|
||||
randomAudit.setId(i++);
|
||||
randomAudit.setDate(current);
|
||||
randomAudit.setUsername("current");
|
||||
randomAudit.setAccessType(AccessType.CREATE);
|
||||
randomAudit.setAction("create");
|
||||
randomAudit.setElementAccessed(randomAudit.getAccessType().name());
|
||||
auditTrail.add(tx, randomAudit);
|
||||
}
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
runtimeMock.destroyRuntime();
|
||||
}
|
||||
|
||||
public Connection openConn() throws SQLException {
|
||||
String url = "jdbc:postgresql://localhost/testdb";
|
||||
String username = "testuser";
|
||||
String password = "test";
|
||||
Connection connection = DriverManager.getConnection(url, username, password);
|
||||
connection.setAutoCommit(false);
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldQueryTypeAndDateRange() throws SQLException {
|
||||
AuditQuery query = new AuditQuery(Tags.AUDIT, new DateRange().from(earlier, true).to(later, true));
|
||||
performQuery(query, Arrays.asList("0", "1", "2", "3", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(current, true).to(current, true));
|
||||
performQuery(query, Arrays.asList("1", "3", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(current, true));
|
||||
performQuery(query, Arrays.asList("1", "2", "3", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().to(current, true));
|
||||
performQuery(query, Arrays.asList("0", "1", "3", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.RESOURCE, new DateRange().from(past, true).to(future, true));
|
||||
performQuery(query, Arrays.<String> asList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldQueryAudits() throws SQLException {
|
||||
AuditQuery query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.action().accessTypes(AccessType.CREATE, AccessType.READ);
|
||||
performQuery(query, Arrays.asList("0", "1", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.action().accessTypes(AccessType.CREATE);
|
||||
performQuery(query, Arrays.asList("0", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.action().accessTypes(AccessType.CREATE, AccessType.READ)
|
||||
.actions(StringMatchMode.EQUALS_CASE_SENSITIVE, "create", "read");
|
||||
performQuery(query, Arrays.asList("0", "1", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.action().accessTypes(AccessType.CREATE, AccessType.READ)
|
||||
.actions(StringMatchMode.EQUALS_CASE_SENSITIVE, "read");
|
||||
performQuery(query, Arrays.asList("1"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.element().elementsAccessed(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "crea");
|
||||
performQuery(query, Arrays.asList("0", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.element().elementsAccessed(StringMatchMode.CONTAINS_CASE_SENSITIVE, "crea");
|
||||
performQuery(query, Arrays.<String> asList());
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.element().elementsAccessed(StringMatchMode.EQUALS_CASE_INSENSITIVE, "create");
|
||||
performQuery(query, Arrays.asList("0", "4"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.identity().usernames(StringMatchMode.EQUALS_CASE_INSENSITIVE, "earlier");
|
||||
performQuery(query, Arrays.asList("0"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.identity().usernames(StringMatchMode.EQUALS_CASE_INSENSITIVE, "earlier", "later");
|
||||
performQuery(query, Arrays.asList("0", "2"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.identity().usernames(StringMatchMode.EQUALS_CASE_INSENSITIVE, "earlier")
|
||||
.firstnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "enn");
|
||||
performQuery(query, Arrays.asList("0"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.identity().usernames(StringMatchMode.EQUALS_CASE_INSENSITIVE, "earlier")
|
||||
.firstnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "enn")
|
||||
.lastnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "kennedy");
|
||||
performQuery(query, Arrays.asList("0"));
|
||||
|
||||
query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true));
|
||||
query.identity().firstnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "enn")
|
||||
.lastnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "kennedy");
|
||||
performQuery(query, Arrays.asList("0", "1", "2", "3", "4"));
|
||||
}
|
||||
|
||||
private void performQuery(AuditQuery query, List<String> expected) throws SQLException {
|
||||
PostgreSqlAuditQueryVisitor visitor = new PostgreSqlAuditQueryVisitor("id");
|
||||
query.accept(visitor);
|
||||
List<String> ids = queryIds(visitor);
|
||||
assertEquals(new HashSet<>(expected), new HashSet<>(ids));
|
||||
}
|
||||
|
||||
private List<String> queryIds(PostgreSqlAuditQueryVisitor visitor) throws SQLException {
|
||||
String sql = visitor.getSql();
|
||||
logger.info("\n" + sql);
|
||||
List<String> ids = new ArrayList<>();
|
||||
try (Connection con = openConn()) {
|
||||
try (PreparedStatement ps = con.prepareStatement(sql)) {
|
||||
visitor.setValues(ps);
|
||||
|
||||
ResultSet rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
ids.add(rs.getString(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import java.io.File;
|
|||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import li.strolch.persistence.postgresql.DbSchemaVersionCheck;
|
||||
import li.strolch.testbase.runtime.AbstractModelTest;
|
||||
|
@ -26,6 +27,10 @@ import li.strolch.testbase.runtime.RuntimeMock;
|
|||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ch.eitchnet.utils.helper.StringHelper;
|
||||
|
||||
public class CachedDaoTest extends AbstractModelTest {
|
||||
|
||||
|
@ -37,6 +42,8 @@ public class CachedDaoTest extends AbstractModelTest {
|
|||
public static final String DB_USERNAME = "testuser"; //$NON-NLS-1$
|
||||
public static final String DB_PASSWORD = "test"; //$NON-NLS-1$
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CachedDaoTest.class);
|
||||
|
||||
protected static RuntimeMock runtimeMock;
|
||||
|
||||
@Override
|
||||
|
@ -59,7 +66,9 @@ public class CachedDaoTest extends AbstractModelTest {
|
|||
|
||||
public static void dropSchema(String dbUrl, String dbUsername, String dbPassword) throws SQLException {
|
||||
String dbVersion = DbSchemaVersionCheck.getExpectedDbVersion();
|
||||
logger.info(MessageFormat.format("Dropping schema for expected version {0}", dbVersion));
|
||||
String sql = DbSchemaVersionCheck.getSql(dbVersion, "drop"); //$NON-NLS-1$
|
||||
logger.info(StringHelper.NEW_LINE + sql);
|
||||
try (Connection connection = DriverManager.getConnection(dbUrl, dbUsername, dbPassword)) {
|
||||
connection.prepareStatement(sql).execute();
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ public class QueryTest {
|
|||
PostgreSqlOrderQueryVisitor visitor = new PostgreSqlOrderQueryVisitor("id");
|
||||
query.accept(visitor);
|
||||
List<String> ids = queryIds(visitor);
|
||||
assertEquals(expected, ids);
|
||||
assertEquals(new HashSet<>(expected), new HashSet<>(ids));
|
||||
}
|
||||
|
||||
private void performResourceQuery(ResourceQuery query, List<String> expected) throws SQLException {
|
||||
|
|
Loading…
Reference in New Issue