[Major] Implemented PostgreSql AuditQuery

This commit is contained in:
Robert von Burg 2014-08-28 21:46:44 +02:00
parent 4cdfb9b667
commit 7f5f207214
8 changed files with 402 additions and 97 deletions

View File

@ -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);

View File

@ -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;
if (!selection.isElementsAccessedWildcard()) {
StringSelection sel = selection.getElementAccessedSelection();
toSql(sel.getMatchMode(), sel.getValues());
}
if (!selection.isElementTypesWildcard()) {
StringSelection sel = selection.getElementTypeSelection();
toSql(sel.getMatchMode(), sel.getValues());
}
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());
}
private void toSql(StringMatchMode mm, String[] values) {
this.sb.append(this.indent);
this.sb.append(PostgreSqlHelper.toSql(this.indent, mm, this.values, values));
@Override
public void visit(ElementSelection selection) {
if (!selection.isElementsAccessedWildcard()) {
StringSelection sel = selection.getElementAccessedSelection();
toSql(PostgreSqlAuditDao.ELEMENT_ACCESSED, sel.getMatchMode(), sel.getValues());
}
}
@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];
for (int i = 0; i < accessTypes.length; i++) {
query[i] = accessTypes[i].name();
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++) {
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");
}
}
}

View File

@ -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();
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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 {