Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.bixuebihui.r2dbc.db.ActiveRecordImpl Maven / Gradle / Ivy
package com.bixuebihui.r2dbc.db;
import com.bixuebihui.DbException;
import com.bixuebihui.db.*;
import com.bixuebihui.jdbc.SqlFilter;
import com.bixuebihui.jdbc.SqlSort;
import com.bixuebihui.jdbc.entity.CountObject;
import com.bixuebihui.jdbc.entity.CountValue;
import com.bixuebihui.r2dbc.sql.*;
import io.r2dbc.spi.Connection;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import jakarta.validation.constraints.NotNull;
import java.util.*;
import static com.bixuebihui.db.Dialect.*;
/**
* Created with IntelliJ IDEA. User: Administrator Date: 13-4-18 Time: 下午5:57 To
* change this template use File | Settings | File Templates.
*
* @author xingwx
* @version $Id: $Id
*/
public class ActiveRecordImpl implements ActiveRecord {
private static final Logger LOG = LoggerFactory.getLogger(ActiveRecordImpl.class);
/**
* NOTE that: class field make this class can't use in spring as singleton!
*/
SqlSort orderStack;
SqlHelper filterStack;
public SqlLimit getLimit() {
return limit;
}
SqlLimit limit;
BaseDao operator;
Mono cn;
private SqlPocket sqlPocket;
private boolean useLast=false;
private String tableAlias;
private String resultFields =" * ";
private List joins;
private void init(BaseDao operator){
this.operator = operator;
orderStack = new SqlSort();
filterStack = new SqlHelper();
limit = SqlLimit.LIMIT_MAX;
}
/**
* Constructor for ActiveRecordImpl.
*
* @param operator a {@link BaseDao} object.
*/
public ActiveRecordImpl(BaseDao operator) {
init(operator);
}
/**
* Constructor for ActiveRecordImpl.
*
* @param operator a {@link BaseDao} object.
* @param cn a {@link Connection} object.
*/
public ActiveRecordImpl(BaseDao operator, Mono cn) {
this.cn = cn;
init(operator);
}
/** {@inheritDoc} */
@Override
public ActiveRecord in(String field, Object[] values) {
filterStack.in(field, values);
return this;
}
@Override
public ActiveRecord emptyStringAsNullCondition() {
filterStack.setAcceptEmptyStringAsNullObjectInCondition(true);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord in(String field, Object values) {
if(!(values instanceof Collection) && !(values instanceof SqlString)){
throw new IllegalArgumentException("InFilter values must be Collection or SqlString objects");
}
if (values instanceof Collection) {
filterStack.in(field, (Collection) values);
} else {
filterStack.in(field, (SqlString) values);
}
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord like(String field, String value) {
filterStack.like(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord startWith(String field, String value) {
filterStack.startWith(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord eq(String field, Object value) {
filterStack.eq(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord ne(String field, Object value){
filterStack.ne(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord eq(String[] fields, Object[] value) {
filterStack.eq(fields, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord greaterThan(String field, Object value) {
filterStack.greaterThan(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord smallerThan(String field, Object value) {
filterStack.smallerThan(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord greaterOrEqualThan(String field, Object value) {
filterStack.greaterOrEqualThan(field, value);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord smallerOrEqualThan(String field, Object value) {
filterStack.smallerOrEqualThan(field, value);
return this;
}
@Override
public ActiveRecord isNull(String field) {
filterStack.isNull(field);
return this;
}
@Override
public ActiveRecord isNotNull(String field) {
filterStack.isNotNull(field);
return this;
}
/** {@inheritDoc} */
@Override
public SqlHelper getCondStack(){
return filterStack;
}
/** {@inheritDoc} */
@Override
public ActiveRecord or(SqlHelper andStack){
filterStack.or(andStack);
return this;
}
protected ActiveRecord order(String field, int order) {
orderStack.addSort(field, order == ORDER_DESC ? SqlSort.Sort.DESC : SqlSort.Sort.ASC);
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord orderByIn(String field, Object[] order) {
operator.getDbType().flatMap(type -> {
if( type != DERBY) {
orderStack.addSortByIn(field, order);
}
return Mono.empty();
}).subscribe();
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord limit(int begin, int num) {
limit = new SqlLimit(begin, num);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Mono> findAll() throws DbException {
try {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
return operator.selectWithJoin(resultFields, where, params, parseOrder(),
limit.getBegin(), limit.getEnd());
} finally {
clear();
}
}
protected List getParams(){
List res = sqlPocket.getParams();
operator.getDbType().flatMap(type -> {
if(type!= DERBY) {
res.addAll(orderStack.getParams());
}
return Mono.empty();
}).subscribe();
return res;
}
/**
* {@inheritDoc}
*/
@Override
public Mono> findAll(Class clz) throws DbException {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
String select = "select " + resultFields + " from " + operator.getTableName() + " ";
return operator.select(select, where, parseOrder(), params, limit.getBegin(),
limit.getEnd(), clz).doFinally(c -> clear());
}
/**
* formWhereClause.
*
* @return a {@link String} object.
*/
protected String formWhereClause() {
String res = sqlPocket.getCondition().toString();
if(StringUtils.isNotBlank(this.tableAlias) ){
StringBuilder join =new StringBuilder();
if(joins !=null && joins.size()>0){
for(String t : joins) {
join.append(t);
}
}
res = " "+this.tableAlias +" "+join+" "+res;
}
return res;
}
private void clear() {
LOG.debug("do clear");
this.filterStack.clear();
this.orderStack.clear();
this.joins =null;
this.limit = SqlLimit.LIMIT_MAX;
useLast = false;
this.cn = null;
}
/**
* {@inheritDoc}
*/
@Override
public Mono find() throws DbException {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
Mono> res = operator.selectWithJoin(resultFields, where, params, parseOrder(),
SqlLimit.LIMIT_ONE.getBegin(), SqlLimit.LIMIT_ONE.getEnd());
return res.map(list -> list.isEmpty()?null: list.get(0)).doFinally(c -> clear());
}
/**
* {@inheritDoc}
* @return
*/
@Override
public Mono delete() throws DbException {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
if (where.length() < " where ".length()) {
LOG.warn("因 where 条件没有设定,安全原因delete操作不被允许");
clear();
return Mono.just(false);
}
String sql = "delete from " + operator.getTableName() + " " + where;
if (limit != null && limit.getBegin()==0 && limit.getEnd()>0) {
sql +=" limit "+limit.getEnd();
}
if(cn==null) {
return operator.getDbHelper().executeNoQuery(sql, params).map(x -> x>0).doFinally(c -> clear());
}
String finalSql = sql;
return cn.flatMap(connection -> operator.getDbHelper().executeNoQuery(finalSql, params, connection))
.map(x -> x > 0 ).doFinally(c -> clear());
}
/**
* {@inheritDoc}
*/
@Override
public Mono get(String field){
return Mono.usingWhen(getVectorSql(field), sql -> {
Object[] params = getParams().toArray();
if (cn == null) {
return operator.getDbHelper().executeScalar(sql, params);
}
return operator.getDbHelper().executeScalar(sql, params, cn);
}
, sql -> {clear(); return Mono.empty();}
);
}
/**
* {@inheritDoc}
*/
@Override
public Mono> getVector(String field) throws DbException {
return Mono.usingWhen(getVectorSql(field),
sql -> {
Object[] params = getParams().toArray();
RowCallbackHandler handle = result -> Flux.from(result.map((row, meta) -> row.get(0))).collectList();
return operator.getDbHelper().executeQuery(sql, params, handle);
},
sql -> {clear(); return Mono.empty();}
);
}
/**
* {@inheritDoc}
*/
@Override
public Mono> getLongVector(String field) {
return getVectorSql(field).flatMap( sql -> {
Object[] params = getParams().toArray();
IDbHelper dbhelper = operator.getDbHelper();
LongReader reader = new LongReader();
return dbhelper.executeQuery(sql, params, reader);
}).doFinally(c -> clear());
}
public Mono parseLimitSql() {
return operator.getDbType().map(type -> {
if (type == MYSQL || type == H2) {
if (limit == null) {
limit = SqlLimit.LIMIT_ONE;
}
return limit.toString();
} else {
LOG.warn("limit not implemented for this type of BaseDao.getDBTYPE()=" + type);
return "";
}
});
}
private Mono getVectorSql(String field) throws DbException {
String fieldFilter = SqlFilter.transactSQLInjection(field);
sqlPocket = this.getSql();
String where = formWhereClause()+ " " + parseOrder();
return parseLimitSql().map( limit -> {
String whereCondition = where + " " +limit;
return "select " + fieldFilter + " from " + operator.getTableName()
+ " " + whereCondition;
});
}
/**
* {@inheritDoc}
*/
@Override
public SqlPocket getSql() throws DbException {
if (useLast && sqlPocket != null) {
return sqlPocket;
}
sqlPocket = filterStack.build();
return sqlPocket;
}
public String parseOrder() {
return this.orderStack.toString();
}
/**
* {@inheritDoc}
* @return
*/
@Override
public Mono count() throws DbException {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
return operator.countWhere(where, params).doFinally(c -> clear());
}
/**
* {@inheritDoc}
* @return
*/
@Override
public Mono exists() throws DbException {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
return operator.exists(where, params).doFinally(c -> clear());
}
/**
* Constructor for ActiveRecordImpl.
*
* @param src a {@link ActiveRecordImpl} object.
*/
public ActiveRecordImpl(ActiveRecordImpl src) {
this.filterStack = new SqlHelper(src.filterStack);
this.limit = new SqlLimit(src.limit);
this.orderStack = new SqlSort(this.orderStack);
this.resultFields = src.resultFields;
}
/** {@inheritDoc} */
@Override
public Record last() {
if(sqlPocket==null){
LOG.error("ERROR: ActiveRecordImpl.last() - there not conditions set to use last.");
}
useLast = true;
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord asc(String field) {
return this.order(field, ORDER_ASC);
}
/** {@inheritDoc} */
@Override
public ActiveRecord desc(String field) {
return this.order(field, ORDER_DESC);
}
/**
* {@inheritDoc}
*/
@Override
public Mono> getStringVector(String field) throws DbException {
return getVectorSql(field).flatMap( sql -> {
Object[] params = getParams().toArray();
RowCallbackHandler handle = result -> Flux.from(result.map((row, meta) -> Objects.requireNonNull(row.get(0)).toString())).collectList();
return operator.getDbHelper().executeQuery(sql, params, handle).doFinally(c -> clear());
});
}
/** {@inheritDoc} */
@Override
public ActiveRecord alias(String shortName) {
tableAlias = shortName;
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord fields(String resultFields) {
this.resultFields = resultFields;
return this;
}
/** {@inheritDoc} */
@Override
public ActiveRecord join(String joinClause) {
if (joins == null) {
joins = new ArrayList<>();
}
joins.add(joinClause);
return this;
}
/**
* {@inheritDoc}
*/
@Override
@Deprecated
public Mono countSum(String field)throws DbException {
return countValue(field, GroupFunction.SUM);
}
/** {@inheritDoc}
* @return*/
@Override
@Deprecated
public Mono countValue(String field, GroupFunction fun) {
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
Mono> res = operator.countGroupValue(field, fun.toString(), where,
null, null, params);
return res.map(list -> list.size() == 0 ? new CountValue() : list.get(0)).doFinally((c) -> clear());
}
/**
* {@inheritDoc}
*/
@Override
public Mono inc(@NotNull String field){
sqlPocket = this.getSql();
String whereClause = formWhereClause();
Object[] params = getParams().toArray();
String sql = "update " + operator.getTableName()
+ " set " + field + "=" + field + "+1 " + whereClause;
if (cn==null) {
return operator.getDbHelper().executeNoQuery(sql, params);
}
return cn.flatMap(conn ->
operator.getDbHelper().executeNoQuery(sql, params, conn)
).doFinally(c -> clear());
}
/**
* {@inheritDoc}
*/
@Override
public Mono update(@NotNull String[] fields, @NotNull Object[] values) {
if (fields.length != values.length) {
throw new IllegalArgumentException("fields and values must have some length");
}
sqlPocket = this.getSql();
String whereClause = formWhereClause();
List params = new ArrayList<>();
StringBuilder sb = new StringBuilder();
int i=0;
for(String field:fields){
Object val = values[i];
if(val instanceof SqlString){
sb.append(field).append(" = ").append(val);
}else{
sb.append(field).append(" = ? ");
params.add(val);
}
i++;
if(i clear());
}
return cn.flatMap(conn ->
operator.getDbHelper().executeNoQuery(sql, params.toArray(), conn)
).doFinally(c -> clear());
}
/** {@inheritDoc} */
@Override
public Mono update(@NotNull String fields, Object values) {
return update(new String[]{fields}, new Object[]{values});
}
/** {@inheritDoc} */
@Override
public Mono> countObject(String field, GroupFunction fun, Class objectType)
{
sqlPocket = this.getSql();
String where = formWhereClause();
Object[] params = getParams().toArray();
Mono>> res = operator.countGroupObject(field, fun.toString(), where,
null, null, objectType, params).doFinally(c -> clear());
return res.map(list -> list.size() == 0 ? new CountObject<>() : list.get(0));
}
}