Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ordering #45

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

group = 'com.fdflib'
version = '1.3.2-SNAPSHOT'
version = '1.3.3-SNAPSHOT'

sourceCompatibility = 1.8
targetCompatibility = 1.8
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/fdflib/model/state/CommonState.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class CommonState implements Serializable {
public long euid;
public long esid;
public long tid; // tenantId
public double order;

public CommonState() {
this.rid = -1;
Expand All @@ -44,5 +45,6 @@ public CommonState() {
this.esid = -1;
this.euid = -1;
this.tid = 1;
this.order = 0;
}
}
24 changes: 20 additions & 4 deletions src/main/java/com/fdflib/model/util/SqlStatement.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.fdflib.model.util;

import com.fdflib.model.state.CommonState;
import com.fdflib.persistence.FdfPersistence;
import com.fdflib.service.impl.FdfCommonServices;

import java.util.ArrayList;
Expand Down Expand Up @@ -105,7 +104,24 @@ public String getSelect() {
if(s > 0) {
sql.append(", ");
}
sql.append(select.get(s));
if(!select.get(s).contains("DISTINCT")
&& !select.get(s).contains("*")
&& !select.get(s).contains("`")) {
if(select.get(s).contains("(")) {
sql
.append(select.get(s).substring(0, select.get(s).indexOf("(") + 1))
.append("`")
.append(select.get(s).substring(select.get(s).indexOf("(") + 1, select.get(s).indexOf(")") + 1))
.append("`")
.append(select.get(s).substring(select.get(s).indexOf(")") + 1, select.get(s).length()));
}
else {
sql.append("`").append(select.get(s)).append("`");
}
}
else {
sql.append(select.get(s));
}
}
} else {
sql.append("*");
Expand All @@ -126,7 +142,7 @@ public String getWhere() {
clause.groupings.stream().filter(grouping -> grouping.equals(WhereClause.GROUPINGS.OPEN_PARENTHESIS)).forEach(openParen -> sql.append("("));
//Format clause by datatype
if(clause.operator != WhereClause.Operators.UNARY) {
sql.append(clause.name).append(" ").append(clause.getOperatorString()).append(" ");
sql.append("`").append(clause.name).append("` ").append(clause.getOperatorString()).append(" ");
if(clause.value.equals(WhereClause.NULL) || Number.class.isAssignableFrom(clause.valueDataType)) {
sql.append(clause.value);
}
Expand All @@ -151,7 +167,7 @@ public String getGroupBy() {
else {
sql.append(",");
}
sql.append(" ").append(group);
sql.append(" `").append(group).append("`");
});
return sql.toString();
}
Expand Down
38 changes: 19 additions & 19 deletions src/main/java/com/fdflib/persistence/queries/CoreMySqlQueries.java
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ public <S> void update(Class<S> c, S state) {
//Start Sql Statement
StringBuilder sql = new StringBuilder("UPDATE ").append(FdfSettings.DB_NAME).append(".")
.append(c.getSimpleName().toLowerCase()).append(" SET");
fields.forEach(field -> sql.append(" ").append(field.getName()).append(" = ?,"));
fields.forEach(field -> sql.append(" `").append(field.getName()).append("` = ?,"));
sql.deleteCharAt(sql.length() - 1).append(" WHERE rid = ").append(c.getField("rid").get(state)).append(";");
//Create Connection
conn = MySqlConnection.getInstance().get4dfDbConnection();
Expand Down Expand Up @@ -435,7 +435,7 @@ public <S> Long insert(Class<S> c, S state) {
.append(c.getSimpleName().toLowerCase()).append(" ("),
val = new StringBuilder();
fields.forEach(field -> {
sql.append(" ").append(field.getName()).append(",");
sql.append(" `").append(field.getName()).append("`,");
val.append(" ?,");
});
sql.deleteCharAt(sql.length()-1).append(") VALUES (")
Expand Down Expand Up @@ -1079,58 +1079,58 @@ else if (pt.getActualTypeArguments().length == 1 &&
static String getFieldNameAndDataType(Field field) {
String sql = "";

fdfLog.debug("checking field: {} of type: {} ", field.getName(), field.getType());
fdfLog.debug("checking field: {} of type: {} ", "`" + field.getName() + "`", field.getType());

if (field.getType() == String.class) {
sql += field.getName() + " TEXT";
sql += "`" + field.getName() + "`" + " TEXT";
} else if (field.getType() == int.class || field.getType() == Integer.class) {
sql += field.getName() + " INT";
sql += "`" + field.getName() + "`" + " INT";
} else if (field.getType() == Long.class || field.getType() == long.class) {
sql += field.getName() + " BIGINT";
sql += "`" + field.getName() + "`" + " BIGINT";
if (field.getName().equals("rid")) {
sql += " PRIMARY KEY AUTO_INCREMENT";
}
} else if (field.getType() == Double.class || field.getType() == double.class) {
sql += field.getName() + " DOUBLE";
sql += "`" + field.getName() + "`" + " DOUBLE";
} else if (field.getType() == Float.class || field.getType() == float.class) {
sql += field.getName() + " FLOAT";
sql += "`" + field.getName() + "`" + " FLOAT";
}
else if (field.getType() == BigDecimal.class) {
sql += field.getName() + " NUMERIC(10,4)";
sql += "`" + field.getName() + "`" + " NUMERIC(10,4)";
} else if (field.getType() == boolean.class || field.getType() == Boolean.class) {
sql += field.getName() + " TINYINT(1)";
sql += "`" + field.getName() + "`" + " TINYINT(1)";
} else if (field.getType() == Date.class) {
sql += field.getName() + " DATETIME";
sql += "`" + field.getName() + "`" + " DATETIME";
if (field.getName().equals("arsd")) {
sql += " DEFAULT CURRENT_TIMESTAMP";
} else {
sql += " NULL";
}
} else if (field.getType() == UUID.class) {
sql += field.getName() + " VARCHAR(132)";
sql += "`" + field.getName() + "`" + " VARCHAR(132)";
} else if (field.getType() == Character.class || field.getType() == char.class) {
sql += field.getName() + " CHAR";
sql += "`" + field.getName() + "`" + " CHAR";
} else if (field.getType() != null && field.getType().isEnum()) {
sql += field.getName() + " VARCHAR(200)";
sql += "`" + field.getName() + "`" + " VARCHAR(200)";
} else if (Class.class.isAssignableFrom(field.getType())) {
sql += field.getName() + " VARCHAR(200)";
sql += "`" + field.getName() + "`" + " VARCHAR(200)";
}
else if (field.getGenericType() instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) field.getGenericType();
if(pt.getActualTypeArguments().length == 1 && pt.getActualTypeArguments()[0].toString()
.matches(".*?((L|l)ong|Integer|int|(D|d)ouble|(F|f)loat|(B|b)oolean|String).*")) {
sql += field.getName() + " TEXT";
sql += "`" + field.getName() + "`" + " TEXT";
}
else {
// unknown create text fields to serialize
fdfLog.debug("Was not able to identify field: {} of type: {} ", field.getName(), field.getType());
sql += field.getName() + " BLOB";
sql += "`" + field.getName() + "`" + " BLOB";
}
}
else {
// unknown create text fields to serialize
fdfLog.debug("Was not able to identify field: {} of type: {} ", field.getName(), field.getType());
sql += field.getName() + " BLOB";
sql += "`" + field.getName() + "`" + " BLOB";
}
return sql;
}
Expand Down Expand Up @@ -1166,7 +1166,7 @@ else if (clause.conditional == WhereClause.CONDITIONALS.NOT) {

// add the claus formatting the sql for the correct datatype
if(clause.operator != WhereClause.Operators.UNARY) {
sql += " " + clause.name + " " + clause.getOperatorString() + " ";
sql += " `" + clause.name + "` " + clause.getOperatorString() + " ";
if(clause.value.equals(WhereClause.NULL)) {
sql += clause.value;
}
Expand Down
126 changes: 123 additions & 3 deletions src/main/java/com/fdflib/service/impl/FdfCommonServices.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ public static <S extends CommonState> S save(S state, Class<S> entityState, long
FdfPersistence.getInstance().update(entityState, lastCurrentEntity);
}
}

if(state.order < 0) {
//this means that order was stored as a position.
state.order = Math.abs(state.order);
getOrderByPosition(state);
}
else if(state.order > 0) {
//this means that order was already set, so check if valid.
validateOrder(state);
}
else {
//this means that order should be set to last.
state.order = getNewOrder(state.getClass(), state.tid);
}

//Set generic fields for new record, save entity, then return it.
state.arsd = Calendar.getInstance().getTime();
state.ared = null;
Expand Down Expand Up @@ -167,6 +182,21 @@ public static <S extends CommonState> FdfEntity<S> save(Class<S> entityState, S
return new FdfEntity<>();
}
}

if(state.order < 0) {
//this means that order was stored as a position.
state.order = Math.abs(state.order);
getOrderByPosition(state);
}
else if(state.order > 0) {
//this means that order was already set, so check if valid.
validateOrder(state);
}
else {
//this means that order should be set to last.
state.order = getNewOrder(state.getClass(), state.tid);
}

// get full entity for state
FdfEntity<S> thisEntity = auditEntityById(entityState, state.id, tenantId);
// check to see if there is an existing entity, if not, create
Expand All @@ -191,6 +221,96 @@ public static <S extends CommonState> FdfEntity<S> save(Class<S> entityState, S
return auditEntityById(entityState, entity.id, tenantId);
}

//Calculates "order" value based on the desired position.
private static <S extends CommonState> void getOrderByPosition(S state) {
SqlStatement statement = SqlStatement.build().select("id").select("order").where(setForCurrent(state.tid)).orderBy("`order`");
if(state.order == 1) {
statement.limit(1,1);
} else {
statement.limit(2, (int)state.order-1);
}
List<S> orderBetween = statement.run((Class<S>) state.getClass());
if(orderBetween.size() == 2) {
if(orderBetween.get(1).id != state.id && orderBetween.get(0).order >= state.order || state.order >= orderBetween.get(1).order) {
if (orderBetween.get(1).order - orderBetween.get(0).order > 1) {
state.order = (orderBetween.get(0).order >= state.order
? Math.floor(orderBetween.get(0).order + 1) : Math.ceil(orderBetween.get(1).order - 1));
}
String orderCurve = Double.toString(state.order = orderBetween.get(1).order + orderBetween.get(0).order);
if (orderCurve.contains(".")) {
double curver = Math.pow(10, (1 + orderCurve.indexOf(".") - orderCurve.length()));
if (curver != orderBetween.get(1).order - orderBetween.get(0).order) {
state.order += curver;
}
}
state.order /= 2;
}

}
else if(!orderBetween.isEmpty() && orderBetween.get(0).id != state.id) {
if(state.order == 1) {
if(orderBetween.get(0).order <= 1) {
String orderCurve = Double.toString(orderBetween.get(0).order);
if(orderCurve.contains(".")) {
double curver = Math.pow(10, (1 + orderCurve.indexOf(".") - orderCurve.length()));
if(curver != orderBetween.get(1).order - orderBetween.get(0).order) {
orderBetween.get(0).order += curver;
}
}
state.order = orderBetween.get(0).order/2;
}
}
else if(orderBetween.get(0).order >= state.order) {
state.order = Math.floor(orderBetween.get(0).order+1);
}
}
}
//Checks if "order" is already taken, and adjusts order if it is.
private static <S extends CommonState> void validateOrder(S state) {
WhereClause whereOrder = new WhereClause();
whereOrder.name = "order";
whereOrder.operator = WhereClause.Operators.LESS_THAN_OR_EQUAL;
whereOrder.value = Double.toString(state.order);
whereOrder.valueDataType = Double.class;
List<S> orderBetween = SqlStatement.build().select("id").select("order").where(whereOrder).where(setForCurrent(state.tid))
.orderBy("`order` DESC").limit(2,1).run((Class<S>) state.getClass());
if(!orderBetween.isEmpty() && orderBetween.get(0).order == state.order && orderBetween.get(0).id != state.id) {
if(orderBetween.size() == 2) {
if(orderBetween.get(0).order - orderBetween.get(1).order > 1) {
state.order = Math.ceil(orderBetween.get(0).order-1);
}
else {
String orderCurb = Double.toString(state.order = orderBetween.get(1).order + orderBetween.get(0).order);
if(orderCurb.contains(".")) {
double curver = Math.pow(10, (1 + orderCurb.indexOf(".") - orderCurb.length()));
if(curver != orderBetween.get(0).order - orderBetween.get(1).order) {
state.order += curver;
}
}
state.order /= 2;
}
}
else if(orderBetween.get(0).order <= 1) {
String orderCurb = Double.toString(orderBetween.get(0).order);
if(orderCurb.contains(".")) {
double curver = Math.pow(10, (1 + orderCurb.indexOf(".") - orderCurb.length()));
if(curver != orderBetween.get(0).order) {
state.order += curver;
}
}
state.order = orderBetween.get(0).order/2;
}
else {
state.order = Math.ceil(orderBetween.get(0).order-1);
}
}
}
//Sets "order" to last possible order.
private static <S extends CommonState> double getNewOrder(Class<S> entityState, long tenantId) {
CommonState returnedState = SqlStatement.build().select("max(`order`) AS `order`").where(setForCurrent(tenantId)).run(entityState).stream().findAny().orElse(null);
return (returnedState != null && returnedState.order > 0 ? Math.floor(returnedState.order+1) : 1);
}

/**
* Sets delete flag for entity. In order to record the date, time, user and system requesting the record be marked
* deleted, a new current record is created to contain this information (arsd contains the date/time, ared is left
Expand Down Expand Up @@ -304,7 +424,7 @@ public static <S extends CommonState> FdfEntity<S> removeDeleteFlag(Class<S> ent
* @return long representing teh number of rows in the table
*/
public static <S extends CommonState> long getRowCount(Class<S> entityState) {
CommonState returnedState = SqlStatement.build().select("max(rid) AS rid").run(entityState).stream().findAny().orElse(null);
CommonState returnedState = SqlStatement.build().select("max(`rid`) AS `rid`").run(entityState).stream().findAny().orElse(null);
return (returnedState != null ? returnedState.rid : 0);

/*List<S> returnedQuery = FdfPersistence.getInstance().selectQuery(entityState, SqlStatement.build().select("rid"));
Expand Down Expand Up @@ -332,7 +452,7 @@ public static <S extends CommonState> long getEntityCount(Class<S> entityState)
* @return
*/
public static <S extends CommonState> List<S> sqlStatementSelect(Class<S> entityState, SqlStatement sqlStatement) {
return FdfPersistence.getInstance().selectQuery(entityState, sqlStatement);
return FdfPersistence.getInstance().selectQuery(entityState, sqlStatement.orderBy("`order`").orderBy("rid"));
}

/**
Expand Down Expand Up @@ -1177,7 +1297,7 @@ public static <S extends CommonState> long getNewEntityId(Class<S> entityState)
* @return Entities of Type passed
*/
public static long getNewEntityId(Class<? extends CommonState> entityState, long tenantId) {
CommonState returnedState = SqlStatement.build().select("max(id) AS id").where(auditForCurrent(tenantId)).run(entityState).stream().findAny().orElse(null);
CommonState returnedState = SqlStatement.build().select("max(`id`) AS `id`").where(auditForCurrent(tenantId)).run(entityState).stream().findAny().orElse(null);
return (returnedState != null && returnedState.id > 0 ? returnedState.id + 1 : 1);
}

Expand Down