[New] Extended OrderDao to allow a DateRange on queries
This commit is contained in:
parent
c4af73b1e3
commit
8f181a0d88
|
@ -15,12 +15,98 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.persistence.api;
|
package li.strolch.persistence.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import li.strolch.model.Order;
|
import li.strolch.model.Order;
|
||||||
|
import li.strolch.utils.collections.DateRange;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Robert von Burg <eitch@eitchnet.ch>
|
* @author Robert von Burg <eitch@eitchnet.ch>
|
||||||
*/
|
*/
|
||||||
public interface OrderDao extends StrolchDao<Order> {
|
public interface OrderDao extends StrolchDao<Order> {
|
||||||
|
|
||||||
// marker interface
|
/**
|
||||||
|
* Returns the number of elements in the underlying persistence layer, regardless of type
|
||||||
|
*
|
||||||
|
* @return the number of elements in the underlying persistence layer
|
||||||
|
*/
|
||||||
|
long querySize(DateRange dateRange);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of elements in the underlying persistence layer for the given type(s)
|
||||||
|
*
|
||||||
|
* @param dateRange
|
||||||
|
* the date range filter
|
||||||
|
* @param types
|
||||||
|
* the type(s) to query the size for
|
||||||
|
*
|
||||||
|
* @return the number of elements in the underlying persistence layer for the given type(s)
|
||||||
|
*/
|
||||||
|
long querySize(DateRange dateRange, String... types);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries and returns all elements regardless of type
|
||||||
|
*
|
||||||
|
* @param dateRange
|
||||||
|
* the date range filter
|
||||||
|
*
|
||||||
|
* @return all elements regardless of type
|
||||||
|
*
|
||||||
|
* @throws StrolchPersistenceException
|
||||||
|
* if something goes wrong
|
||||||
|
*/
|
||||||
|
List<Order> queryAll(DateRange dateRange) throws StrolchPersistenceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries and returns all elements regardless of type
|
||||||
|
*
|
||||||
|
* @param dateRange
|
||||||
|
* the date range filter
|
||||||
|
* @param limit
|
||||||
|
* the max amount, or @{@link Integer#MAX_VALUE} for all
|
||||||
|
* @param offset
|
||||||
|
* if max amount defined, then the offset to start from
|
||||||
|
*
|
||||||
|
* @return all elements regardless of type
|
||||||
|
*
|
||||||
|
* @throws StrolchPersistenceException
|
||||||
|
* if something goes wrong
|
||||||
|
*/
|
||||||
|
List<Order> queryAll(DateRange dateRange, long limit, long offset) throws StrolchPersistenceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries and returns all elements of the given type
|
||||||
|
*
|
||||||
|
* @param dateRange
|
||||||
|
* the date range filter
|
||||||
|
* @param types
|
||||||
|
* the type(s) of element(s) to return
|
||||||
|
*
|
||||||
|
* @return all elements of the given type
|
||||||
|
*
|
||||||
|
* @throws StrolchPersistenceException
|
||||||
|
* if something goes wrong
|
||||||
|
*/
|
||||||
|
List<Order> queryAll(DateRange dateRange, String... types) throws StrolchPersistenceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries and returns all elements of the given type
|
||||||
|
*
|
||||||
|
* @param dateRange
|
||||||
|
* the date range filter
|
||||||
|
* @param limit
|
||||||
|
* the max amount, or @{@link Integer#MAX_VALUE} for all
|
||||||
|
* @param offset
|
||||||
|
* if max amount defined, then the offset to start from
|
||||||
|
* @param types
|
||||||
|
* the type(s) of element(s) to return
|
||||||
|
*
|
||||||
|
* @return all elements of the given type
|
||||||
|
*
|
||||||
|
* @throws StrolchPersistenceException
|
||||||
|
* if something goes wrong
|
||||||
|
*/
|
||||||
|
List<Order> queryAll(DateRange dateRange, long limit, long offset, String... types)
|
||||||
|
throws StrolchPersistenceException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
|
@ -34,6 +36,8 @@ import li.strolch.model.xml.XmlModelSaxReader;
|
||||||
import li.strolch.persistence.api.OrderDao;
|
import li.strolch.persistence.api.OrderDao;
|
||||||
import li.strolch.persistence.api.StrolchPersistenceException;
|
import li.strolch.persistence.api.StrolchPersistenceException;
|
||||||
import li.strolch.persistence.api.TransactionResult;
|
import li.strolch.persistence.api.TransactionResult;
|
||||||
|
import li.strolch.utils.collections.DateRange;
|
||||||
|
import li.strolch.utils.iso8601.ISO8601;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
@SuppressWarnings("nls")
|
@SuppressWarnings("nls")
|
||||||
|
@ -41,6 +45,19 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
|
||||||
|
|
||||||
public static final String ORDERS = "orders";
|
public static final String ORDERS = "orders";
|
||||||
|
|
||||||
|
private static final String querySizeDrSqlS = "select count(*) from {0} where latest = true {1}";
|
||||||
|
private static final String querySizeOfTypeDrSqlS = "select count(*) from {0} where type = ANY(?) and latest = true {1}";
|
||||||
|
|
||||||
|
private static final String queryAllDrAsXmlSqlS = "select id, type, asxml from {0} where latest = true {1}";
|
||||||
|
private static final String queryAllDrAsXmlLimitSqlS = "select id, type, asxml from {0} where latest = true {1} order by id limit {2} offset {3}";
|
||||||
|
private static final String queryAllDrAsJsonSqlS = "select id, type, asjson from {0} where latest = true {1}";
|
||||||
|
private static final String queryAllDrAsJsonLimitSqlS = "select id, type, asjson from {0} where latest = true {1} order by id limit {2} offset {3}";
|
||||||
|
|
||||||
|
private static final String queryAllByTypeDrAsXmlSqlS = "select id, type, asxml from {0} where type = ANY(?) and latest = true {1}";
|
||||||
|
private static final String queryAllByTypeDrAsXmlLimitSqlS = "select id, type, asxml from {0} where type = ANY(?) and latest = true {1} order by id limit {2,number,#} offset {3,number,#}";
|
||||||
|
private static final String queryAllByTypeDrAsJsonSqlS = "select id, type, asjson from {0} where type = ANY(?) and latest = true {1}";
|
||||||
|
private static final String queryAllByTypeDrAsJsonLimitSqlS = "select id, type, asjson from {0} where type = ANY(?) and latest = true {1} order by id limit {2,number,#} offset {3,number,#}";
|
||||||
|
|
||||||
private static final String insertAsXmlSqlS = "insert into {0} (id, version, created_by, created_at, updated_at, deleted, latest, name, type, state, date, asxml) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?::order_state, ?, ?)";
|
private static final String insertAsXmlSqlS = "insert into {0} (id, version, created_by, created_at, updated_at, deleted, latest, name, type, state, date, asxml) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?::order_state, ?, ?)";
|
||||||
private static final String insertAsJsonSqlS = "insert into {0} (id, version, created_by, created_at, updated_at, deleted, latest, name, type, state, date, asjson) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?::order_state, ?, ?)";
|
private static final String insertAsJsonSqlS = "insert into {0} (id, version, created_by, created_at, updated_at, deleted, latest, name, type, state, date, asjson) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?::order_state, ?, ?)";
|
||||||
|
|
||||||
|
@ -230,4 +247,178 @@ public class PostgreSqlOrderDao extends PostgresqlDao<Order> implements OrderDao
|
||||||
.format("Failed to update Order {0} due to {1}", order.getLocator(), e.getLocalizedMessage()), e);
|
.format("Failed to update Order {0} due to {1}", order.getLocator(), e.getLocalizedMessage()), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long querySize(DateRange dateRange) {
|
||||||
|
String sql = MessageFormat.format(querySizeDrSqlS, getTableName(), buildDateRangeClaus(dateRange));
|
||||||
|
try (PreparedStatement statement = this.connection.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
try (ResultSet result = statement.executeQuery()) {
|
||||||
|
result.next();
|
||||||
|
return result.getLong(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long querySize(DateRange dateRange, String... types) {
|
||||||
|
if (types.length == 0)
|
||||||
|
return querySize();
|
||||||
|
|
||||||
|
String sql = MessageFormat.format(querySizeOfTypeDrSqlS, getTableName(), buildDateRangeClaus(dateRange));
|
||||||
|
|
||||||
|
try (PreparedStatement statement = this.connection.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
Array typesArray = statement.getConnection().createArrayOf("varchar", types);
|
||||||
|
statement.setArray(1, typesArray);
|
||||||
|
|
||||||
|
try (ResultSet result = statement.executeQuery()) {
|
||||||
|
result.next();
|
||||||
|
return result.getLong(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange) throws StrolchPersistenceException {
|
||||||
|
return queryAll(dateRange, Integer.MAX_VALUE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange, long limit, long offset) throws StrolchPersistenceException {
|
||||||
|
|
||||||
|
List<Order> list = new ArrayList<>();
|
||||||
|
|
||||||
|
String sql = getLimitSql(dateRange, limit, offset, queryAllDrAsXmlSqlS, queryAllDrAsJsonSqlS,
|
||||||
|
queryAllDrAsXmlLimitSqlS, queryAllDrAsJsonLimitSqlS);
|
||||||
|
|
||||||
|
try (PreparedStatement statement = this.connection.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
try (ResultSet result = statement.executeQuery()) {
|
||||||
|
while (result.next()) {
|
||||||
|
String id = result.getString("id");
|
||||||
|
String type = result.getString("type");
|
||||||
|
list.add(parseDbObject(result, id, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new StrolchPersistenceException("Failed to query types due to: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange, String... types) throws StrolchPersistenceException {
|
||||||
|
return queryAll(dateRange, Integer.MAX_VALUE, 0, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange, long limit, long offset, String... types)
|
||||||
|
throws StrolchPersistenceException {
|
||||||
|
if (types.length == 0)
|
||||||
|
return queryAll(limit, offset);
|
||||||
|
|
||||||
|
List<Order> list = new ArrayList<>();
|
||||||
|
|
||||||
|
String sql = getLimitSql(dateRange, limit, offset, queryAllByTypeDrAsXmlSqlS, queryAllByTypeDrAsJsonSqlS,
|
||||||
|
queryAllByTypeDrAsXmlLimitSqlS, queryAllByTypeDrAsJsonLimitSqlS);
|
||||||
|
|
||||||
|
try (PreparedStatement statement = this.connection.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
Array typesArray = statement.getConnection().createArrayOf("varchar", types);
|
||||||
|
statement.setArray(1, typesArray);
|
||||||
|
|
||||||
|
try (ResultSet result = statement.executeQuery()) {
|
||||||
|
while (result.next()) {
|
||||||
|
String id = result.getString("id");
|
||||||
|
String type = result.getString("type");
|
||||||
|
list.add(parseDbObject(result, id, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new StrolchPersistenceException("Failed to query types due to: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getLimitSql(DateRange dateRange, long limit, long offset, String xmlSql, String jsonSql,
|
||||||
|
String xmlLimitSql, String jsonLimitSql) {
|
||||||
|
|
||||||
|
String sql;
|
||||||
|
if (limit == Integer.MAX_VALUE) {
|
||||||
|
return getSql(dateRange, xmlSql, jsonSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.dataType == DataType.xml)
|
||||||
|
sql = xmlLimitSql;
|
||||||
|
else if (this.dataType == DataType.json)
|
||||||
|
sql = jsonLimitSql;
|
||||||
|
else
|
||||||
|
throw new IllegalStateException("Unhandled DataType " + this.dataType);
|
||||||
|
|
||||||
|
String dateRangeClause = buildDateRangeClaus(dateRange);
|
||||||
|
return MessageFormat.format(sql, getTableName(), dateRangeClause, limit, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getSql(DateRange dateRange, String xmlSql, String jsonSql) {
|
||||||
|
|
||||||
|
String sql;
|
||||||
|
if (this.dataType == DataType.xml)
|
||||||
|
sql = xmlSql;
|
||||||
|
else if (this.dataType == DataType.json)
|
||||||
|
sql = jsonSql;
|
||||||
|
else
|
||||||
|
throw new IllegalStateException("Unhandled DataType " + this.dataType);
|
||||||
|
|
||||||
|
String dateRangeClause = buildDateRangeClaus(dateRange);
|
||||||
|
return MessageFormat.format(sql, getTableName(), dateRangeClause);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String buildDateRangeClaus(DateRange dateRange) {
|
||||||
|
|
||||||
|
if (dateRange.isFromBounded() && dateRange.isToBounded()) {
|
||||||
|
|
||||||
|
String from = ISO8601.toString(dateRange.getFromDate());
|
||||||
|
String to = ISO8601.toString(dateRange.getToDate());
|
||||||
|
|
||||||
|
if (dateRange.isFromInclusive() && dateRange.isToInclusive())
|
||||||
|
return "and date >= '" + from + "' and date <= '" + to + "'";
|
||||||
|
|
||||||
|
if (dateRange.isFromInclusive())
|
||||||
|
return "and date >= '" + from + "' and date < '" + to + "'";
|
||||||
|
|
||||||
|
if (dateRange.isToInclusive())
|
||||||
|
return "and date > '" + from + "' and date <= '" + to + "'";
|
||||||
|
|
||||||
|
return "and date > '" + from + "' and date < '" + to + "'";
|
||||||
|
|
||||||
|
} else if (dateRange.isFromBounded()) {
|
||||||
|
|
||||||
|
String from = ISO8601.toString(dateRange.getFromDate());
|
||||||
|
|
||||||
|
if (dateRange.isFromInclusive())
|
||||||
|
return "and date >= '" + from + "'";
|
||||||
|
|
||||||
|
return "and date > '" + from + "'";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String to = ISO8601.toString(dateRange.getToDate());
|
||||||
|
|
||||||
|
if (dateRange.isToInclusive())
|
||||||
|
return "and date <= '" + to + "'";
|
||||||
|
|
||||||
|
return "and date < '" + to + "'";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
|
||||||
return this.tx.getManager().getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id);
|
return this.tx.getManager().getObjectRefCache().getIdOfSubTypeRef(getClassType(), type, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SubTypeRef getTypeRef(String type) {
|
protected SubTypeRef getTypeRef(String type) {
|
||||||
return this.tx.getManager().getObjectRefCache().getSubTypeRef(getClassType(), type);
|
return this.tx.getManager().getObjectRefCache().getSubTypeRef(getClassType(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
|
||||||
Set<String> types = queryTypes();
|
Set<String> types = queryTypes();
|
||||||
for (String type : types) {
|
for (String type : types) {
|
||||||
SubTypeRef subTypeRef = getTypeRef(type);
|
SubTypeRef subTypeRef = getTypeRef(type);
|
||||||
size += this.tx.getMetadataDao().querySize(subTypeRef);
|
size += this.tx.getMetadataDao().querySize(subTypeRef, file -> true);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
@ -71,13 +71,13 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
|
||||||
|
|
||||||
if (types.length == 1) {
|
if (types.length == 1) {
|
||||||
SubTypeRef subTypeRef = getTypeRef(types[0]);
|
SubTypeRef subTypeRef = getTypeRef(types[0]);
|
||||||
return this.tx.getMetadataDao().querySize(subTypeRef);
|
return this.tx.getMetadataDao().querySize(subTypeRef, file -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (String type : types) {
|
for (String type : types) {
|
||||||
SubTypeRef subTypeRef = getTypeRef(type);
|
SubTypeRef subTypeRef = getTypeRef(type);
|
||||||
size += this.tx.getMetadataDao().querySize(subTypeRef);
|
size += this.tx.getMetadataDao().querySize(subTypeRef, file -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
@ -94,7 +94,7 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
|
||||||
List<T> objects = new ArrayList<>();
|
List<T> objects = new ArrayList<>();
|
||||||
Set<String> types = queryTypes();
|
Set<String> types = queryTypes();
|
||||||
for (String type : types) {
|
for (String type : types) {
|
||||||
List<T> objectsByType = this.tx.getObjectDao().queryAll(getTypeRef(type));
|
List<T> objectsByType = this.tx.getObjectDao().queryAll(getTypeRef(type), file -> true);
|
||||||
objects.addAll(objectsByType);
|
objects.addAll(objectsByType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,12 +107,12 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
|
||||||
return queryAll();
|
return queryAll();
|
||||||
|
|
||||||
if (types.length == 1) {
|
if (types.length == 1) {
|
||||||
return this.tx.getObjectDao().queryAll(getTypeRef(types[0]));
|
return this.tx.getObjectDao().queryAll(getTypeRef(types[0]), file -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<T> objects = new ArrayList<>();
|
List<T> objects = new ArrayList<>();
|
||||||
for (String type : types) {
|
for (String type : types) {
|
||||||
objects.addAll(this.tx.getObjectDao().queryAll(getTypeRef(type)));
|
objects.addAll(this.tx.getObjectDao().queryAll(getTypeRef(type), file -> true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return objects;
|
return objects;
|
||||||
|
@ -151,13 +151,13 @@ public abstract class AbstractDao<T extends StrolchRootElement> implements Strol
|
||||||
@Override
|
@Override
|
||||||
public long removeAll() {
|
public long removeAll() {
|
||||||
TypeRef typeRef = this.tx.getManager().getObjectRefCache().getTypeRef(getClassType());
|
TypeRef typeRef = this.tx.getManager().getObjectRefCache().getTypeRef(getClassType());
|
||||||
return this.tx.getObjectDao().removeAllBy(typeRef);
|
return this.tx.getObjectDao().removeAllBy(typeRef, file -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long removeAllBy(String type) {
|
public long removeAllBy(String type) {
|
||||||
SubTypeRef typeRef = getTypeRef(type);
|
SubTypeRef typeRef = getTypeRef(type);
|
||||||
return this.tx.getObjectDao().removeAllBy(typeRef);
|
return this.tx.getObjectDao().removeAllBy(typeRef, file -> true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,9 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.persistence.xml;
|
package li.strolch.persistence.xml;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.File;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import li.strolch.model.Tags;
|
import li.strolch.model.Tags;
|
||||||
import li.strolch.model.audit.Audit;
|
import li.strolch.model.audit.Audit;
|
||||||
|
@ -28,7 +30,6 @@ import li.strolch.utils.collections.DateRange;
|
||||||
import li.strolch.xmlpers.api.PersistenceContext;
|
import li.strolch.xmlpers.api.PersistenceContext;
|
||||||
import li.strolch.xmlpers.api.PersistenceTransaction;
|
import li.strolch.xmlpers.api.PersistenceTransaction;
|
||||||
import li.strolch.xmlpers.objref.IdOfSubTypeRef;
|
import li.strolch.xmlpers.objref.IdOfSubTypeRef;
|
||||||
import li.strolch.xmlpers.objref.ObjectRef;
|
|
||||||
import li.strolch.xmlpers.objref.SubTypeRef;
|
import li.strolch.xmlpers.objref.SubTypeRef;
|
||||||
import li.strolch.xmlpers.objref.TypeRef;
|
import li.strolch.xmlpers.objref.TypeRef;
|
||||||
|
|
||||||
|
@ -77,20 +78,8 @@ public class XmlAuditDao implements AuditDao {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long querySize(String type, DateRange dateRange) {
|
public long querySize(String type, DateRange dateRange) {
|
||||||
long size = 0;
|
Predicate<File> predicate = file -> dateRange.contains(new Date(file.lastModified()));
|
||||||
|
return this.tx.getMetadataDao().querySize(getTypeRef(type), predicate);
|
||||||
// TODO re-think this nonsense... this might have a huge performance penalty
|
|
||||||
SubTypeRef subTypeRef = getTypeRef(type);
|
|
||||||
Set<String> keySet = this.tx.getMetadataDao().queryKeySet(subTypeRef);
|
|
||||||
for (String key : keySet) {
|
|
||||||
ObjectRef objectRef = subTypeRef.getChildIdRef(this.tx, key);
|
|
||||||
Audit audit = this.tx.getObjectDao().queryById(objectRef);
|
|
||||||
if (dateRange.contains(audit.getDate()))
|
|
||||||
size++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return this.tx.getMetadataDao().querySize(subTypeRef);
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -106,82 +95,56 @@ public class XmlAuditDao implements AuditDao {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Audit> queryAll(String type, DateRange dateRange) {
|
public List<Audit> queryAll(String type, DateRange dateRange) {
|
||||||
|
Predicate<File> predicate = file -> dateRange.contains(new Date(file.lastModified()));
|
||||||
List<Audit> audits = new ArrayList<>();
|
return this.tx.getObjectDao().queryAll(getTypeRef(type), predicate);
|
||||||
|
|
||||||
SubTypeRef subTypeRef = getTypeRef(type);
|
|
||||||
Set<String> keySet = this.tx.getMetadataDao().queryKeySet(subTypeRef);
|
|
||||||
for (String key : keySet) {
|
|
||||||
ObjectRef objectRef = subTypeRef.getChildIdRef(this.tx, key);
|
|
||||||
Audit audit = this.tx.getObjectDao().queryById(objectRef);
|
|
||||||
if (dateRange.contains(audit.getDate()))
|
|
||||||
audits.add(audit);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this.tx.getObjectDao().queryAll(getTypeRef(type));
|
|
||||||
return audits;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(Audit audit) {
|
public void save(Audit audit) {
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
|
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit, -1L);
|
||||||
this.tx.getFileDao().performCreate(ctx);
|
this.tx.getFileDao().performCreate(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveAll(List<Audit> audits) {
|
public void saveAll(List<Audit> audits) {
|
||||||
for (Audit audit : audits) {
|
for (Audit audit : audits) {
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
|
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit, -1L);
|
||||||
this.tx.getFileDao().performCreate(ctx);
|
this.tx.getFileDao().performCreate(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Audit audit) {
|
public void update(Audit audit) {
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
|
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit, -1L);
|
||||||
this.tx.getFileDao().performUpdate(ctx);
|
this.tx.getFileDao().performUpdate(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateAll(List<Audit> audits) {
|
public void updateAll(List<Audit> audits) {
|
||||||
for (Audit audit : audits) {
|
for (Audit audit : audits) {
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
|
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit, -1L);
|
||||||
this.tx.getFileDao().performUpdate(ctx);
|
this.tx.getFileDao().performUpdate(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove(Audit audit) {
|
public void remove(Audit audit) {
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
|
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit, -1L);
|
||||||
this.tx.getFileDao().performDelete(ctx);
|
this.tx.getFileDao().performDelete(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAll(List<Audit> audits) {
|
public void removeAll(List<Audit> audits) {
|
||||||
for (Audit audit : audits) {
|
for (Audit audit : audits) {
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit);
|
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(audit, -1L);
|
||||||
this.tx.getFileDao().performDelete(ctx);
|
this.tx.getFileDao().performDelete(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long removeAll(String type, DateRange dateRange) {
|
public long removeAll(String type, DateRange dateRange) {
|
||||||
|
Predicate<File> predicate = file -> dateRange.contains(new Date(file.lastModified()));
|
||||||
long removed = 0L;
|
return this.tx.getObjectDao().removeAllBy(getTypeRef(type), predicate);
|
||||||
|
|
||||||
SubTypeRef subTypeRef = getTypeRef(type);
|
|
||||||
Set<String> keySet = this.tx.getMetadataDao().queryKeySet(subTypeRef);
|
|
||||||
for (String key : keySet) {
|
|
||||||
ObjectRef objectRef = subTypeRef.getChildIdRef(this.tx, key);
|
|
||||||
Audit audit = this.tx.getObjectDao().queryById(objectRef);
|
|
||||||
if (dateRange.contains(audit.getDate())) {
|
|
||||||
PersistenceContext<Audit> ctx = this.tx.getObjectDao().createCtx(objectRef);
|
|
||||||
this.tx.getFileDao().performDelete(ctx);
|
|
||||||
removed++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return removed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class XmlLogMessageDao implements LogMessageDao {
|
||||||
@Override
|
@Override
|
||||||
public List<LogMessage> queryLatest(String realm, int maxNr) {
|
public List<LogMessage> queryLatest(String realm, int maxNr) {
|
||||||
SubTypeRef subTypeRef = this.tx.getManager().getObjectRefCache().getSubTypeRef(getClassType(), realm);
|
SubTypeRef subTypeRef = this.tx.getManager().getObjectRefCache().getSubTypeRef(getClassType(), realm);
|
||||||
return this.tx.getObjectDao().queryAll(subTypeRef, maxNr, true);
|
return this.tx.getObjectDao().queryAll(subTypeRef, true, file -> true, maxNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -15,10 +15,20 @@
|
||||||
*/
|
*/
|
||||||
package li.strolch.persistence.xml;
|
package li.strolch.persistence.xml;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import li.strolch.model.Order;
|
import li.strolch.model.Order;
|
||||||
import li.strolch.model.Tags;
|
import li.strolch.model.Tags;
|
||||||
import li.strolch.persistence.api.OrderDao;
|
import li.strolch.persistence.api.OrderDao;
|
||||||
|
import li.strolch.persistence.api.StrolchPersistenceException;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
|
import li.strolch.utils.collections.DateRange;
|
||||||
|
import li.strolch.xmlpers.objref.SubTypeRef;
|
||||||
|
|
||||||
public class XmlOrderDao extends AbstractDao<Order> implements OrderDao {
|
public class XmlOrderDao extends AbstractDao<Order> implements OrderDao {
|
||||||
|
|
||||||
|
@ -30,4 +40,92 @@ public class XmlOrderDao extends AbstractDao<Order> implements OrderDao {
|
||||||
protected String getClassType() {
|
protected String getClassType() {
|
||||||
return Tags.ORDER;
|
return Tags.ORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(Order object) {
|
||||||
|
this.tx.getObjectDao().add(object, object.getDate().getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveAll(List<Order> objects) {
|
||||||
|
for (Order object : objects) {
|
||||||
|
save(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Order object) {
|
||||||
|
this.tx.getObjectDao().update(object, object.getDate().getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateAll(List<Order> objects) {
|
||||||
|
for (Order object : objects) {
|
||||||
|
update(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Predicate<File> getDateRangePredicate(DateRange dateRange) {
|
||||||
|
return file -> dateRange.contains(new Date(file.lastModified()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long querySize(DateRange dateRange) {
|
||||||
|
long size = 0;
|
||||||
|
Set<String> types = queryTypes();
|
||||||
|
for (String type : types) {
|
||||||
|
SubTypeRef subTypeRef = getTypeRef(type);
|
||||||
|
size += this.tx.getMetadataDao().querySize(subTypeRef, getDateRangePredicate(dateRange));
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long querySize(DateRange dateRange, String... types) {
|
||||||
|
|
||||||
|
if (types.length == 0)
|
||||||
|
return querySize();
|
||||||
|
|
||||||
|
if (types.length == 1) {
|
||||||
|
SubTypeRef subTypeRef = getTypeRef(types[0]);
|
||||||
|
return this.tx.getMetadataDao().querySize(subTypeRef, getDateRangePredicate(dateRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
for (String type : types) {
|
||||||
|
SubTypeRef subTypeRef = getTypeRef(type);
|
||||||
|
size += this.tx.getMetadataDao().querySize(subTypeRef, getDateRangePredicate(dateRange));
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange) throws StrolchPersistenceException {
|
||||||
|
List<Order> objects = new ArrayList<>();
|
||||||
|
Set<String> types = queryTypes();
|
||||||
|
for (String type : types) {
|
||||||
|
List<Order> objectsByType = this.tx.getObjectDao()
|
||||||
|
.queryAll(getTypeRef(type), getDateRangePredicate(dateRange));
|
||||||
|
objects.addAll(objectsByType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objects;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange, long limit, long offset) throws StrolchPersistenceException {
|
||||||
|
throw new UnsupportedOperationException("Paging not supported! Check first with supportsPaging()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange, String... types) throws StrolchPersistenceException {
|
||||||
|
throw new UnsupportedOperationException("Paging not supported! Check first with supportsPaging()");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Order> queryAll(DateRange dateRange, long limit, long offset, String... types)
|
||||||
|
throws StrolchPersistenceException {
|
||||||
|
throw new UnsupportedOperationException("Paging not supported! Check first with supportsPaging()");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package li.strolch.testbase.runtime;
|
||||||
import static li.strolch.model.ModelGenerator.*;
|
import static li.strolch.model.ModelGenerator.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import li.strolch.agent.api.OrderMap;
|
import li.strolch.agent.api.OrderMap;
|
||||||
|
@ -25,9 +26,12 @@ import li.strolch.agent.impl.DataStoreMode;
|
||||||
import li.strolch.model.Order;
|
import li.strolch.model.Order;
|
||||||
import li.strolch.model.StrolchElement;
|
import li.strolch.model.StrolchElement;
|
||||||
import li.strolch.model.parameter.StringParameter;
|
import li.strolch.model.parameter.StringParameter;
|
||||||
|
import li.strolch.persistence.api.OrderDao;
|
||||||
|
import li.strolch.persistence.api.PersistenceHandler;
|
||||||
import li.strolch.persistence.api.StrolchTransaction;
|
import li.strolch.persistence.api.StrolchTransaction;
|
||||||
import li.strolch.privilege.model.Certificate;
|
import li.strolch.privilege.model.Certificate;
|
||||||
import li.strolch.runtime.privilege.PrivilegeHandler;
|
import li.strolch.runtime.privilege.PrivilegeHandler;
|
||||||
|
import li.strolch.utils.collections.DateRange;
|
||||||
|
|
||||||
@SuppressWarnings("nls")
|
@SuppressWarnings("nls")
|
||||||
public class OrderModelTestRunner {
|
public class OrderModelTestRunner {
|
||||||
|
@ -76,6 +80,11 @@ public class OrderModelTestRunner {
|
||||||
Order order1 = createOrder("myTestOrder1", "Test Name", "QTestType1"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
Order order1 = createOrder("myTestOrder1", "Test Name", "QTestType1"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
Order order2 = createOrder("myTestOrder2", "Test Name", "QTestType2"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
Order order2 = createOrder("myTestOrder2", "Test Name", "QTestType2"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
Order order3 = createOrder("myTestOrder3", "Test Name", "QTestType3"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
Order order3 = createOrder("myTestOrder3", "Test Name", "QTestType3"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
|
||||||
|
order1.setDate(LocalDate.of(2018, 3, 1));
|
||||||
|
order2.setDate(LocalDate.of(2019, 4, 1));
|
||||||
|
order3.setDate(LocalDate.of(2019, 5, 1));
|
||||||
|
|
||||||
try (StrolchTransaction tx = this.runtimeMock.getRealm(this.realmName)
|
try (StrolchTransaction tx = this.runtimeMock.getRealm(this.realmName)
|
||||||
.openTx(this.certificate, "test", false)) {
|
.openTx(this.certificate, "test", false)) {
|
||||||
tx.add(order1);
|
tx.add(order1);
|
||||||
|
@ -101,6 +110,66 @@ public class OrderModelTestRunner {
|
||||||
size = tx.getOrderMap().querySize(tx, "NonExistingType");
|
size = tx.getOrderMap().querySize(tx, "NonExistingType");
|
||||||
assertEquals("Should have zero objects of type 'NonExistingType'", 0, size);
|
assertEquals("Should have zero objects of type 'NonExistingType'", 0, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try (StrolchTransaction tx = this.runtimeMock.getRealm(this.realmName).openTx(this.certificate, "test", true)) {
|
||||||
|
PersistenceHandler persistenceHandler = this.runtimeMock.getComponent(PersistenceHandler.class);
|
||||||
|
OrderDao dao = persistenceHandler.getOrderDao(tx);
|
||||||
|
|
||||||
|
LocalDate _2017 = LocalDate.of(2017, 1, 1);
|
||||||
|
LocalDate _2018 = LocalDate.of(2018, 1, 1);
|
||||||
|
LocalDate _20180301 = LocalDate.of(2018, 3, 1);
|
||||||
|
LocalDate _20190401 = LocalDate.of(2019, 4, 1);
|
||||||
|
LocalDate _20190501 = LocalDate.of(2019, 5, 1);
|
||||||
|
LocalDate _2020 = LocalDate.of(2020, 1, 1);
|
||||||
|
|
||||||
|
long size;
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().to(_2017, true));
|
||||||
|
assertEquals("Expect 0 Orders before 2017 inc", 0, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_2017, true).to(_2018, true));
|
||||||
|
assertEquals("Expect 0 Orders between _2017 inc and _2018 inc", 0, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_2018, true).to(_20180301, false));
|
||||||
|
assertEquals("Expect 0 Orders between _2018 inc and _20180301 exc", 0, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_2018, true).to(_20180301, true));
|
||||||
|
assertEquals("Expect 1 Orders between 2018 inc and _20180301 inc", 1, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_20180301, false).to(_20190401, false));
|
||||||
|
assertEquals("Expect 0 Orders between _20180301 exc and _20190401 exc", 0, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_2017, true));
|
||||||
|
assertEquals("Expect 3 Orders from _2017 inc", 3, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_2020, true));
|
||||||
|
assertEquals("Expect 0 Orders from _2020 inc", 0, size);
|
||||||
|
|
||||||
|
size = dao.querySize(new DateRange().from(_20190501, true).to(_2020, true));
|
||||||
|
assertEquals("Expect 1 Orders from _20190501 inc to _2020 inc", 1, size);
|
||||||
|
|
||||||
|
DateRange dateRange = new DateRange().from(_2017, true).to(_20190401, true);
|
||||||
|
String[] types = { "QTestType1", "QTestType2", "QTestType3" };
|
||||||
|
|
||||||
|
size = dao.querySize(dateRange, types);
|
||||||
|
assertEquals("Expect 2 Orders from _2017 inc to _20190401 inc by types", 2, size);
|
||||||
|
|
||||||
|
List<Order> orders;
|
||||||
|
|
||||||
|
orders = dao.queryAll(dateRange);
|
||||||
|
assertEquals("Expect 2 Orders from _2017 inc to _20190401 inc", 2, orders.size());
|
||||||
|
|
||||||
|
if (dao.supportsPaging()) {
|
||||||
|
orders = dao.queryAll(dateRange, 2, 1);
|
||||||
|
assertEquals("Expect 1 Orders from _2017 inc to _20190401 inc offset 1 limit 2", 1, orders.size());
|
||||||
|
assertEquals("Expect order myTestOrder2", "myTestOrder2", orders.get(0).getId());
|
||||||
|
|
||||||
|
orders = dao.queryAll(new DateRange().from(_2017, true).to(_2020, true), 2, 1);
|
||||||
|
assertEquals("Expect 2 Orders from _2017 inc to _2020 inc offset 1 limit 2", 2, orders.size());
|
||||||
|
assertEquals("Expect order myTestOrder2", "myTestOrder2", orders.get(0).getId());
|
||||||
|
assertEquals("Expect order myTestOrder3", "myTestOrder3", orders.get(1).getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runCrudTests() {
|
public void runCrudTests() {
|
||||||
|
|
Loading…
Reference in New Issue