FINERACT-1910 Support Pagination, sorting and filtering for Datatable

This commit is contained in:
jmarta
2023-08-28 16:58:06 +02:00
committed by Adam Saghy
parent 498e81a734
commit f1e70111b4
20 changed files with 1182 additions and 176 deletions
@@ -0,0 +1,41 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.fineract.infrastructure.core.service;
import java.util.Locale;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
@Getter
@Setter
@RequiredArgsConstructor
public class PagedLocalRequest<T> extends PagedRequest<T> {
private String dateFormat;
private String dateTimeFormat;
private String locale;
public Locale getLocaleObject() {
return locale == null ? null : JsonParserHelper.localeFromString(locale);
}
}
@@ -30,14 +30,14 @@ public enum JdbcJavaType {
@Override
public Object toJdbcValueImpl(@NotNull DatabaseType dialect, Object value) {
return Boolean.TRUE.equals(value) ? 1 : 0;
return value == null ? null : (Boolean.TRUE.equals(value) ? 1 : 0);
}
},
BOOLEAN(JavaType.BOOLEAN, new DialectType(JDBCType.BIT), new DialectType(JDBCType.BOOLEAN, null, "BOOL")) { //
@Override
public Object toJdbcValueImpl(@NotNull DatabaseType dialect, Object value) {
return dialect.isMySql() ? (Boolean.TRUE.equals(value) ? 1 : 0) : super.toJdbcValueImpl(dialect, value);
return (value != null && dialect.isMySql()) ? (Boolean.TRUE.equals(value) ? 1 : 0) : super.toJdbcValueImpl(dialect, value);
}
},
SMALLINT(JavaType.SHORT, new DialectType(JDBCType.SMALLINT, true), new DialectType(JDBCType.SMALLINT, null, "INT2")), //
@@ -47,7 +47,7 @@ public enum SqlOperator {
}
@Override
public String formatPlaceholderImpl(String definition, String placeholder) {
public String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return format("%s %s CONCAT('%%', %s, '%%')", definition, getSymbol(), placeholder);
}
},
@@ -60,7 +60,7 @@ public enum SqlOperator {
}
@Override
public String formatPlaceholderImpl(String definition, String placeholder) {
public String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return format("%s %s CONCAT('%%', %s, '%%')", definition, getSymbol(), placeholder);
}
},
@@ -74,7 +74,7 @@ public enum SqlOperator {
}
@Override
public String formatPlaceholderImpl(String definition, String placeholder) {
public String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return format("%s %s %s AND %s", definition, getSymbol(), placeholder, placeholder);
}
},
@@ -88,7 +88,7 @@ public enum SqlOperator {
}
@Override
public String formatPlaceholderImpl(String definition, String placeholder) {
public String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return format("%s %s %s AND %s", definition, getSymbol(), placeholder, placeholder);
}
},
@@ -102,8 +102,13 @@ public enum SqlOperator {
}
@Override
public boolean isPlaceholderSupported() {
return false;
protected String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return format("%s %s (%s)", definition, getSymbol(), placeholder + (", " + placeholder).repeat(paramCount - 1));
}
@Override
protected String formatNamedParamImpl(String definition, int paramCount, String namedParam) {
return format("%s %s (%s)", definition, getSymbol(), namedParam);
}
},
NIN("NOT IN", -1) { //
@@ -116,8 +121,13 @@ public enum SqlOperator {
}
@Override
public boolean isPlaceholderSupported() {
return false;
protected String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return format("%s %s (%s)", definition, getSymbol(), placeholder + (", " + placeholder).repeat(paramCount - 1));
}
@Override
protected String formatNamedParamImpl(String definition, int paramCount, String namedParam) {
return format("%s %s (%s)", definition, getSymbol(), namedParam);
}
},
NULL("IS NULL", 0), //
@@ -160,38 +170,45 @@ public enum SqlOperator {
: format("%s %s %s", definition, symbol, sqlGenerator.formatValue(columnType, values[0]));
}
public boolean isPlaceholderSupported() {
return true;
}
public String formatPlaceholder(@NotNull DatabaseSpecificSQLGenerator sqlGenerator, String definition, String alias) {
return formatPlaceholder(sqlGenerator, definition, alias, "?");
}
public String formatPlaceholder(@NotNull DatabaseSpecificSQLGenerator sqlGenerator, String definition, String alias,
String placeholder) {
return formatPlaceholderImpl(sqlGenerator.alias(sqlGenerator.escape(definition), alias), placeholder);
}
protected String formatPlaceholderImpl(String definition, String placeholder) {
if (!isPlaceholderSupported()) {
throw new UnsupportedOperationException("Placeholder is not supported for this operator");
public String formatNamedParam(@NotNull DatabaseSpecificSQLGenerator sqlGenerator, String definition, int paramCount, String alias) {
validateParamCount(paramCount);
if (paramCount > 1) {
throw new PlatformServiceUnavailableException("error.msg.database.operator.named.invalid",
"Named parameter is not allowed on " + this);
}
return formatNamedParamImpl(sqlGenerator.alias(sqlGenerator.escape(definition), alias), paramCount, ":" + definition);
}
protected String formatNamedParamImpl(String definition, int paramCount, String namedParam) {
return formatPlaceholderImpl(definition, paramCount, namedParam);
}
public String formatPlaceholder(@NotNull DatabaseSpecificSQLGenerator sqlGenerator, String definition, int paramCount, String alias) {
return formatPlaceholder(sqlGenerator, definition, paramCount, alias, "?");
}
public String formatPlaceholder(@NotNull DatabaseSpecificSQLGenerator sqlGenerator, String definition, int paramCount, String alias,
String placeholder) {
validateParamCount(paramCount);
return formatPlaceholderImpl(sqlGenerator.alias(sqlGenerator.escape(definition), alias), paramCount, placeholder);
}
protected String formatPlaceholderImpl(String definition, int paramCount, String placeholder) {
return paramCount == 0 ? format("%s %s", definition, symbol) : format("%s %s %s", definition, symbol, placeholder);
}
public void validateValues(String... values) {
if (values == null ? paramCount != 0 : (paramCount < 0 ? values.length < -paramCount : values.length != paramCount)) {
throw new PlatformServiceUnavailableException("error.msg.database.operator.invalid",
"Number of parameters " + Arrays.toString(values) + " must be " + Math.abs(paramCount) + " on " + this);
}
validateParamCount(values == null ? 0 : values.length);
}
public void validateValues(List<?> values) {
int size = values == null ? 0 : values.size();
if (paramCount < 0 ? size < -paramCount : size != paramCount) {
validateParamCount(values == null ? 0 : values.size());
}
public void validateParamCount(int paramCount) {
if (this.paramCount < 0 ? paramCount < -this.paramCount : paramCount != this.paramCount) {
throw new PlatformServiceUnavailableException("error.msg.database.operator.invalid",
"Number of parameters " + size + " must be " + Math.abs(paramCount) + " on " + this);
"Number of parameters " + paramCount + " must be " + Math.abs(this.paramCount) + " on " + this);
}
}
@@ -0,0 +1,39 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.fineract.infrastructure.dataqueries.data;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Immutable data object representing datatable data.
*/
@Data
@NoArgsConstructor
public final class DatatableSearchRequest implements Serializable {
private List<ColumnFilter> columnFilters;
private List<String> resultColumns;
private String datatable;
}