Audit query extension: Search for audited data of any type

- Pulled out some of the query joins in favour of more cache hits


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@16359 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-09-18 03:16:40 +00:00
parent 0fe6dee8bc
commit 818791d88a
12 changed files with 153 additions and 104 deletions

View File

@@ -41,9 +41,9 @@
<result property="auditValuesId" column="audit_values_id" jdbcType="BIGINT" javaType="long"/>
</resultMap>
<resultMap id="result_AuditQueryNoValues" class="AuditQueryResult">
<result property="auditEntryId" column="audit_entry_id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="auditAppName" column="audit_app_name" jdbcType="VARCHAR" javaType="string"/>
<result property="auditUser" column="audit_user" jdbcType="VARCHAR" javaType="string"/>
<result property="auditAppNameId" column="audit_app_name_id" jdbcType="BIGINT" javaType="long"/>
<result property="auditEntryId" column="audit_entry_id" jdbcType="BIGINT" javaType="long"/>
<result property="auditUserId" column="audit_user_id" jdbcType="BIGINT" javaType="long"/>
<result property="auditTime" column="audit_time" jdbcType="BIGINT" javaType="long"/>
<result property="auditValuesId" column="audit_values_id" jdbcType="BIGINT" javaType="long"/>
</resultMap>
@@ -60,14 +60,6 @@
<parameterMap id="parameter_IdMap" class="map">
<parameter property="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
</parameterMap>
<parameterMap id="parameter_AuditQuery" class="AuditQueryParameters">
<parameter property="auditAppNameShort" jdbcType="VARCHAR" javaType="string"/>
<parameter property="auditAppNameCrc" jdbcType="BIGINT" javaType="long"/>
<parameter property="auditUserShort" jdbcType="VARCHAR" javaType="string"/>
<parameter property="auditUserCrc" jdbcType="BIGINT" javaType="long"/>
<parameter property="auditFromTime" jdbcType="BIGINT" javaType="long"/>
<parameter property="auditToTime" jdbcType="BIGINT" javaType="long"/>
</parameterMap>
<!-- -->
<!-- SQL Snippets -->
@@ -156,9 +148,9 @@
<!-- Get audit entries -->
<select id="select_AuditEntriesWithValues" parameterClass="AuditQueryParameters" resultMap="result_AuditQueryAllValues">
select
app.app_name_id as audit_app_name_id,
entry.id as audit_entry_id,
user_sv.string_value as audit_user,
app_sv.string_value as audit_app_name,
entry.audit_user_id as audit_user_id,
entry.audit_time as audit_time,
entry.audit_values_id as audit_values_id,
@@ -175,21 +167,13 @@
serv.serializable_value as prop_serializable_value
from
alf_audit_app app
join alf_prop_value app_pv on (app_pv.id = app.app_name_id)
join alf_prop_string_value app_sv on (app_sv.id = app_pv.long_value and app_pv.persisted_type = 3)
join alf_audit_entry entry on (entry.audit_app_id = app.id)
join alf_prop_value user_pv on (user_pv.id = entry.audit_user_id)
join alf_prop_string_value user_sv on (user_sv.id = user_pv.long_value and user_pv.persisted_type = 3)
<isNotNull property="searchKey">
<isNotNull property="searchKeyId">
join alf_prop_link sp_kpl on (sp_kpl.root_prop_id = entry.audit_values_id)
join alf_prop_value sp_kpv on (sp_kpl.key_prop_id = sp_kpv.id)
join alf_prop_string_value sp_ksv on (sp_ksv.id = sp_kpv.long_value and sp_kpv.persisted_type = 3)
</isNotNull>
<isNotNull property="searchValueString">
<isNotNull property="searchValueId">
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
join alf_prop_value sp_mpv on (sp_mpl.value_prop_id = sp_mpv.id)
join alf_prop_string_value sp_msv on (sp_msv.id = sp_mpv.long_value and sp_mpv.persisted_type = 3)
</isNotNull>
join alf_prop_link pl on (pl.root_prop_id = entry.audit_values_id)
@@ -198,13 +182,11 @@
left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 || pv.persisted_type = 5))
left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4)
<dynamic prepend="where">
<isNotNull prepend="and" property="auditAppNameShort">
app_sv.string_end_lower = #auditAppNameShort# and
app_sv.string_crc = #auditAppNameCrc#
<isNotNull prepend="and" property="auditAppNameId">
app.app_name_id = #auditAppNameId#
</isNotNull>
<isNotNull prepend="and" property="auditUserShort">
user_sv.string_end_lower = #auditUserShort# and
user_sv.string_crc = #auditUserCrc#
<isNotNull prepend="and" property="auditUserId">
entry.audit_user_id = #auditUserId#
</isNotNull>
<isNotNull prepend="and" property="auditFromTime">
<![CDATA[entry.audit_time >= #auditFromTime#]]>
@@ -212,11 +194,11 @@
<isNotNull prepend="and" property="auditToTime">
<![CDATA[entry.audit_time < #auditToTime#]]>
</isNotNull>
<isNotNull prepend="and" property="searchKey">
sp_ksv.string_value = #searchKey#
<isNotNull prepend="and" property="searchKeyId">
sp_kpl.key_prop_id = #searchKeyId#
</isNotNull>
<isNotNull prepend="and" property="searchValueString">
sp_msv.string_value = #searchValueString#
<isNotNull prepend="and" property="searchValueId">
sp_mpl.value_prop_id = #searchValueId#
</isNotNull>
</dynamic>
</select>

View File

@@ -209,7 +209,7 @@ public interface AuditComponent
* @param from the start search time (<tt>null</tt> to start at the beginning)
* @param to the end search time (<tt>null</tt> for no limit)
* @param searchKey the audit key path that must exist (<tt>null</tt> to ignore)
* @param searchString an audit value string that must exist (<tt>null</tt> to ignore)
* @param searchValue an audit value that must exist (<tt>null</tt> to ignore)
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
*
* @since 3.2
@@ -217,6 +217,6 @@ public interface AuditComponent
void auditQuery(
AuditQueryCallback callback,
String applicationName, String user, Long from, Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults);
}

View File

@@ -1315,7 +1315,7 @@ public class AuditComponentImpl implements AuditComponent
String user,
Long from,
Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults)
{
ParameterCheck.mandatory("callback", callback);
@@ -1327,6 +1327,6 @@ public class AuditComponentImpl implements AuditComponent
return;
}
auditDAO.findAuditEntries(callback, applicationName, user, from, to, searchKey, searchString, maxResults);
auditDAO.findAuditEntries(callback, applicationName, user, from, to, searchKey, searchValue, maxResults);
}
}

View File

@@ -24,6 +24,7 @@
*/
package org.alfresco.repo.audit;
import java.io.Serializable;
import java.util.List;
import javax.transaction.UserTransaction;
@@ -188,12 +189,12 @@ public class AuditServiceImpl implements AuditService
public void auditQuery(
AuditQueryCallback callback,
String applicationName, String user, Long from, Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults)
{
ParameterCheck.mandatory("callback", callback);
auditComponent.auditQuery(callback, applicationName, user, from, to, searchKey, searchString, maxResults);
auditComponent.auditQuery(callback, applicationName, user, from, to, searchKey, searchValue, maxResults);
}
}

View File

@@ -755,7 +755,7 @@ public class HibernateAuditDAO extends HibernateDaoSupport implements AuditDAO,
public void findAuditEntries(
AuditQueryCallback callback,
String applicationName, String user, Long from, Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults)
{
throw new UnsupportedOperationException();

View File

@@ -404,10 +404,14 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
return;
}
}
// Resolve the application and username
String auditAppName = (String) propertyValueDAO.getPropertyValueById(row.getAuditAppNameId()).getSecond();
String auditUser = (String) propertyValueDAO.getPropertyValueById(row.getAuditUserId()).getSecond();
more = callback.handleAuditEntry(
row.getAuditEntryId(),
row.getAuditAppName(),
row.getAuditUser(),
auditAppName,
auditUser,
row.getAuditTime(),
auditValues);
}
@@ -425,15 +429,15 @@ public abstract class AbstractAuditDAOImpl implements AuditDAO
public void findAuditEntries(
AuditQueryCallback callback,
String applicationName, String user, Long from, Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults)
{
AuditQueryRowHandler rowHandler = new AuditQueryRowHandler(callback);
findAuditEntries(rowHandler, applicationName, user, from, to, maxResults, searchKey, searchString);
findAuditEntries(rowHandler, applicationName, user, from, to, maxResults, searchKey, searchValue);
}
protected abstract void findAuditEntries(
AuditQueryRowHandler rowHandler,
String applicationName, String user, Long from, Long to, int maxResults,
String searchKey, String searchString);
String searchKey, Serializable searchValue);
}

View File

@@ -221,7 +221,8 @@ public interface AuditDAO
* Find audit entries using the given parameters, any of which may be null.
*
* @param searchKey the audit path key to search for (optional)
* @param searchString the audit string value to search for (optional)
* @param searchValue the audit value to search for (optional). This can be
* of any type that is supported by the <b>alf_prop_xxx</b> tables.
*
* @see #findAuditEntries(AuditQueryCallback, String, String, Long, Long, int)
*
@@ -230,6 +231,6 @@ public interface AuditDAO
void findAuditEntries(
AuditQueryCallback callback,
String applicationName, String user, Long from, Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults);
}

View File

@@ -26,8 +26,6 @@ package org.alfresco.repo.domain.audit;
import java.util.Date;
import org.alfresco.util.Pair;
/**
* Query parameters for <b>alf_audit_entry</b> table.
*
@@ -37,12 +35,12 @@ import org.alfresco.util.Pair;
public class AuditQueryParameters
{
private Long auditEntryId;
private Pair<String, Long> auditAppNameCrcPair;
private Pair<String, Long> auditUserCrcPair;
private Long auditAppNameId;
private Long auditUserId;
private Long auditFromTime;
private Long auditToTime;
private String searchKey;
private String searchValueString;
private Long searchKeyId;
private Long searchValueId;
public AuditQueryParameters()
{
@@ -54,12 +52,12 @@ public class AuditQueryParameters
StringBuilder sb = new StringBuilder(512);
sb.append("AuditEntryParameters")
.append("[ auditEntryId=").append(auditEntryId)
.append(", auditAppNameCrcPair=").append(auditAppNameCrcPair)
.append(", auditUserCrcPair=").append(auditUserCrcPair)
.append(", auditAppNameId=").append(auditAppNameId)
.append(", auditUserId=").append(auditUserId)
.append(", auditFromTime").append(auditFromTime == null ? null : new Date(auditFromTime))
.append(", auditToTime").append(auditToTime == null ? null : new Date(auditToTime))
.append(", searchKey").append(searchKey)
.append(", searchValueString").append(searchValueString)
.append(", searchKeyId").append(searchKeyId)
.append(", searchValueId").append(searchValueId)
.append("]");
return sb.toString();
}
@@ -74,34 +72,24 @@ public class AuditQueryParameters
this.auditEntryId = entryId;
}
public String getAuditAppNameShort()
public Long getAuditAppNameId()
{
return auditAppNameCrcPair == null ? null : auditAppNameCrcPair.getFirst();
return auditAppNameId;
}
public Long getAuditAppNameCrc()
public void setAuditAppNameId(Long auditAppNameId)
{
return auditAppNameCrcPair == null ? null : auditAppNameCrcPair.getSecond();
this.auditAppNameId = auditAppNameId;
}
public void setAuditAppNameCrcPair(Pair<String, Long> appNameCrcPair)
public Long getAuditUserId()
{
this.auditAppNameCrcPair = appNameCrcPair;
return auditUserId;
}
public String getAuditUserShort()
public void setAuditUserId(Long auditUserId)
{
return auditUserCrcPair == null ? null : auditUserCrcPair.getFirst();
}
public Long getAuditUserCrc()
{
return auditUserCrcPair == null ? null : auditUserCrcPair.getSecond();
}
public void setAuditUserCrcPair(Pair<String, Long> userCrcPair)
{
this.auditUserCrcPair = userCrcPair;
this.auditUserId = auditUserId;
}
public Long getAuditFromTime()
@@ -124,23 +112,23 @@ public class AuditQueryParameters
this.auditToTime = to;
}
public String getSearchKey()
public Long getSearchKeyId()
{
return searchKey;
return searchKeyId;
}
public void setSearchKey(String searchKey)
public void setSearchKeyId(Long searchKeyId)
{
this.searchKey = searchKey;
this.searchKeyId = searchKeyId;
}
public String getSearchValueString()
public Long getSearchValueId()
{
return searchValueString;
return searchValueId;
}
public void setSearchValueString(String searchValueString)
public void setSearchValueId(Long searchValueId)
{
this.searchValueString = searchValueString;
this.searchValueId = searchValueId;
}
}

View File

@@ -38,8 +38,8 @@ import org.alfresco.repo.domain.propval.PropertyIdSearchRow;
public class AuditQueryResult
{
private Long auditEntryId;
private String auditAppName;
private String auditUser;
private Long auditAppNameId;
private Long auditUserId;
private long auditTime;
private Long auditValuesId;
private List<PropertyIdSearchRow> auditValues;
@@ -54,8 +54,8 @@ public class AuditQueryResult
StringBuilder sb = new StringBuilder(512);
sb.append("AuditEntryResult")
.append("[ auditEntryId=").append(auditEntryId)
.append(", auditAppName=").append(auditAppName)
.append(", auditUser=").append(auditUser)
.append(", auditAppNameId=").append(auditAppNameId)
.append(", auditUserId=").append(auditUserId)
.append(", auditTime").append(new Date(auditTime))
.append(", auditValuesId=").append(auditValuesId)
.append(", auditValues=").append(auditValues.size())
@@ -73,24 +73,24 @@ public class AuditQueryResult
this.auditEntryId = entryId;
}
public String getAuditAppName()
public Long getAuditAppNameId()
{
return auditAppName;
return auditAppNameId;
}
public void setAuditAppName(String appName)
public void setAuditAppNameId(Long auditAppNameId)
{
this.auditAppName = appName;
this.auditAppNameId = auditAppNameId;
}
public String getAuditUser()
public Long getAuditUserId()
{
return auditUser;
return auditUserId;
}
public void setAuditUser(String user)
public void setAuditUserId(Long auditUserId)
{
this.auditUser = user;
this.auditUserId = auditUserId;
}
public long getAuditTime()

View File

@@ -191,24 +191,55 @@ public class AuditDAOImpl extends AbstractAuditDAOImpl
protected void findAuditEntries(
final AuditQueryRowHandler rowHandler,
String appName, String user, Long from, Long to, int maxResults,
String searchKey, String searchString)
String searchKey, Serializable searchValue)
{
AuditQueryParameters params = new AuditQueryParameters();
if (appName != null)
{
// Look up the application's ID (this is unique)
Pair<String, Long> appNameCrcPair = propertyValueDAO.getPropertyStringCaseSensitiveSearchParameters(appName);
params.setAuditAppNameCrcPair(appNameCrcPair);
Pair<Long, Serializable> appNamePair = propertyValueDAO.getPropertyValue(appName);
if (appNamePair == null)
{
// No such value
return;
}
params.setAuditAppNameId(appNamePair.getFirst());
}
if (user != null)
{
Pair<String, Long> userCrcPair = propertyValueDAO.getPropertyStringCaseSensitiveSearchParameters(user);
params.setAuditUserCrcPair(userCrcPair);
// Look up the application's ID (this is unique)
Pair<Long, Serializable> userPair = propertyValueDAO.getPropertyValue(user);
if (userPair == null)
{
// No such value
return;
}
params.setAuditUserId(userPair.getFirst());
}
params.setAuditFromTime(from);
params.setAuditToTime(to);
params.setSearchKey(searchKey);
params.setSearchValueString(searchString);
if (searchKey != null)
{
// Look up the ID of the search key
Pair<Long, Serializable> searchKeyPair = propertyValueDAO.getPropertyValue(searchKey);
if (searchKeyPair == null)
{
// No such value
return;
}
params.setSearchKeyId(searchKeyPair.getFirst());
}
if (searchValue != null)
{
// Look up the ID of the search key
Pair<Long, Serializable> searchValuePair = propertyValueDAO.getPropertyValue(searchValue);
if (searchValuePair == null)
{
// No such value
return;
}
params.setSearchValueId(searchValuePair.getFirst());
}
// RowHandlers in RowHandlers: See 'groupBy' issue https://issues.apache.org/jira/browse/IBATIS-503
RowHandler shreddedRowHandler = new RowHandler()

View File

@@ -44,18 +44,24 @@ public interface PropertyValueDAO
// 'alf_prop_class' accessors
//================================
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_class</b> accessor
*
* @param id the ID (may not be <tt>null</tt>)
*/
Pair<Long, Class<?>> getPropertyClassById(Long id);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_class</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
*/
Pair<Long, Class<?>> getPropertyClass(Class<?> value);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_class</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
@@ -66,18 +72,24 @@ public interface PropertyValueDAO
// 'alf_prop_date_value' accessors
//================================
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_date_value</b> accessor
*
* @param id the ID (may not be <tt>null</tt>)
*/
Pair<Long, Date> getPropertyDateValueById(Long id);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_date_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
*/
Pair<Long, Date> getPropertyDateValue(Date value);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_date_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
@@ -93,18 +105,24 @@ public interface PropertyValueDAO
*/
Pair<String, Long> getPropertyStringCaseSensitiveSearchParameters(String value);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_string_value</b> accessor
*
* @param id the ID (may not be <tt>null</tt>)
*/
Pair<Long, String> getPropertyStringValueById(Long id);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_string_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
*/
Pair<Long, String> getPropertyStringValue(String value);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_string_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
@@ -115,18 +133,24 @@ public interface PropertyValueDAO
// 'alf_prop_double_value' accessors
//================================
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_double_value</b> accessor
*
* @param id the ID (may not be <tt>null</tt>)
*/
Pair<Long, Double> getPropertyDoubleValueById(Long id);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_double_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
*/
Pair<Long, Double> getPropertyDoubleValue(Double value);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_double_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
@@ -137,12 +161,16 @@ public interface PropertyValueDAO
// 'alf_prop_serializable_value' accessors
//================================
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_serializable_value</b> accessor
*
* @param id the ID (may not be <tt>null</tt>)
*/
Pair<Long, Serializable> getPropertySerializableValueById(Long id);
/**
* <b>FOR INTERNAL USE ONLY</b>: Do not use directly; see interface comments.
* <p/>
* <b>alf_prop_serializable_value</b> accessor
*
* @param value the value to find the ID for (may not be <tt>null</tt>)
@@ -153,18 +181,24 @@ public interface PropertyValueDAO
// 'alf_prop_value' accessors
//================================
/**
* Use for accessing unique properties; see interface comments.
* <p/>
* <b>alf_prop_value</b> accessor: get a property based on the database ID
*
* @param id the ID (may not be <tt>null</tt>)
*/
Pair<Long, Serializable> getPropertyValueById(Long id);
/**
* Use for accessing unique properties; see interface comments.
* <p/>
* <b>alf_prop_value</b> accessor: find a property based on the value
*
* @param value the value to find the ID for (may be <tt>null</tt>)
*/
Pair<Long, Serializable> getPropertyValue(Serializable value);
/**
* Use for accessing unique properties; see interface comments.
* <p/>
* <b>alf_prop_value</b> accessor: find or create a property based on the value.
* <b>Note:</b> This method will not recurse into maps or collections. Use the
* dedicated methods if you want recursion; otherwise maps and collections will
@@ -181,6 +215,8 @@ public interface PropertyValueDAO
// 'alf_prop_root' accessors
//================================
/**
* Use for accessing non-unique, exploded properties; see interface comments.
* <p/>
* <b>alf_prop_root</b> accessor: get a property based on the database ID
*
* @param id the ID (may not be <tt>null</tt>)
@@ -189,6 +225,8 @@ public interface PropertyValueDAO
*/
Serializable getPropertyById(Long id);
/**
* Use for accessing non-unique, exploded properties; see interface comments.
* <p/>
* <b>alf_prop_root</b> accessor: find or create a property based on the value.
* <p/>
* All collections and maps will be opened up to any depth.
@@ -199,6 +237,8 @@ public interface PropertyValueDAO
Long createProperty(Serializable value);
/**
* Use for accessing non-unique, exploded properties; see interface comments.
* <p/>
* <b>alf_prop_root</b> accessor: update the property root to contain a new value.
*
* @param id the ID of the root property to change
@@ -207,6 +247,8 @@ public interface PropertyValueDAO
void updateProperty(Long id, Serializable value);
/**
* Use for accessing non-unique, exploded properties; see interface comments.
* <p/>
* <b>alf_prop_root</b> accessor: delete a property root completely
*
* @param id the ID of the root property to delete

View File

@@ -196,7 +196,7 @@ public interface AuditService
* @param from the start search time (<tt>null</tt> to start at the beginning)
* @param to the end search time (<tt>null</tt> for no limit)
* @param searchKey the audit key path that must exist (<tt>null</tt> to ignore)
* @param searchString an audit value string that must exist (<tt>null</tt> to ignore)
* @param searchValue an audit value that must exist (<tt>null</tt> to ignore)
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
*
* @since 3.2
@@ -204,6 +204,6 @@ public interface AuditService
void auditQuery(
AuditQueryCallback callback,
String applicationName, String user, Long from, Long to,
String searchKey, String searchString,
String searchKey, Serializable searchValue,
int maxResults);
}