mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
Merge pull request #3158 from ebean-orm/feature/tidy-idBinderEmbedded
Followup for #3133 - "Embedded id expansion on parentIds" for SQLServer and DB2
This commit is contained in:
+87
-67
@@ -21,13 +21,15 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
private final String deleteByParentIdSql;
|
||||
private final String deleteByParentIdInSql;
|
||||
private final String elementCollectionInsertSql;
|
||||
private final boolean idInExpandedForm;
|
||||
|
||||
BeanPropertyAssocManySqlHelp(BeanPropertyAssocMany<T> many, ExportedProperty[] exportedProperties) {
|
||||
this.many = many;
|
||||
this.exportedProperties = exportedProperties;
|
||||
this.hasJoinTable = many.hasJoinTable();
|
||||
this.descriptor = many.descriptor();
|
||||
this.exportedPropertyBindProto = deriveExportedPropertyBindProto();
|
||||
this.exportedPropertyBindProto = initExportedBindProto();
|
||||
this.idInExpandedForm = descriptor.idBinder().isIdInExpandedForm();
|
||||
|
||||
String delStmt;
|
||||
if (hasJoinTable) {
|
||||
@@ -35,8 +37,8 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
} else {
|
||||
delStmt = "delete from " + many.targetTable() + " where ";
|
||||
}
|
||||
deleteByParentIdSql = delStmt + deriveWhereParentIdSql(false, "");
|
||||
deleteByParentIdInSql = delStmt + deriveWhereParentIdSql(true, "");
|
||||
deleteByParentIdSql = delStmt + rawParentIdEQ("");
|
||||
deleteByParentIdInSql = delStmt;
|
||||
if (many.isElementCollection()) {
|
||||
elementCollectionInsertSql = elementCollectionInsert();
|
||||
} else {
|
||||
@@ -45,7 +47,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
}
|
||||
|
||||
private String elementCollectionInsert() {
|
||||
StringBuilder sb = new StringBuilder(200);
|
||||
final StringBuilder sb = new StringBuilder(200);
|
||||
sb.append("insert into ").append(many.targetTable()).append(" (");
|
||||
append(sb);
|
||||
|
||||
@@ -54,7 +56,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
sb.append(") values (");
|
||||
appendBind(sb, exportedProperties.length, true);
|
||||
appendBind(sb, cols.colCount, false);
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -73,7 +75,7 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
|
||||
@Override
|
||||
public void visitEmbeddedScalar(BeanProperty p, BeanPropertyAssocOne<?> embedded) {
|
||||
sb.append(",").append(p.dbColumn());
|
||||
sb.append(',').append(p.dbColumn());
|
||||
colCount++;
|
||||
}
|
||||
|
||||
@@ -96,14 +98,14 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
|
||||
String lazyFetchOrderBy(String fetchOrderBy) {
|
||||
// derive lazyFetchOrderBy
|
||||
StringBuilder sb = new StringBuilder(50);
|
||||
final String fkTableAlias = hasJoinTable ? "int_" : "t0";
|
||||
final var sb = new StringBuilder(50);
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
// these fk columns are either on the intersection (int_) or base table (t0)
|
||||
String fkTableAlias = hasJoinTable ? "int_" : "t0";
|
||||
sb.append(fkTableAlias).append(".").append(exportedProperties[i].getForeignDbColumn());
|
||||
sb.append(fkTableAlias).append('.').append(exportedProperties[i].getForeignDbColumn());
|
||||
}
|
||||
sb.append(", ").append(fetchOrderBy);
|
||||
return sb.toString().trim();
|
||||
@@ -113,56 +115,50 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
* Add a where clause to the query for a given list of parent Id's.
|
||||
*/
|
||||
void addWhereParentIdIn(SpiQuery<?> query, List<Object> parentIds) {
|
||||
String tableAlias = hasJoinTable ? "int_." : "t0.";
|
||||
final String tableAlias = hasJoinTable ? "int_." : "t0.";
|
||||
if (hasJoinTable) {
|
||||
query.setM2MIncludeJoin(many.inverseJoin);
|
||||
}
|
||||
String rawWhere = deriveWhereParentIdSql(true, tableAlias);
|
||||
String expr = descriptor.parentIdInExpr(parentIds.size(), rawWhere);
|
||||
many.bindParentIdsIn(expr, parentIds, query);
|
||||
final String rawWhere = rawParentIdIN(tableAlias, parentIds.size());
|
||||
many.bindParentIdsIn(rawWhere, parentIds, query);
|
||||
}
|
||||
|
||||
List<Object> findIdsByParentId(Object parentId, Transaction t, List<Object> excludeDetailIds, boolean hard) {
|
||||
String rawWhere = deriveWhereParentIdSql(false, "");
|
||||
SpiEbeanServer server = descriptor.ebeanServer();
|
||||
SpiQuery<?> q = many.newQuery(server);
|
||||
many.bindParentIdEq(rawWhere, parentId, q);
|
||||
final SpiEbeanServer server = descriptor.ebeanServer();
|
||||
final SpiQuery<?> query = many.newQuery(server);
|
||||
many.bindParentIdEq(rawParentIdEQ(""), parentId, query);
|
||||
if (hard) {
|
||||
q.setIncludeSoftDeletes();
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
|
||||
q.where().not(q.getExpressionFactory().idIn(excludeDetailIds));
|
||||
query.where().not(query.getExpressionFactory().idIn(excludeDetailIds));
|
||||
}
|
||||
return server.findIds(q, t);
|
||||
return server.findIds(query, t);
|
||||
}
|
||||
|
||||
List<Object> findIdsByParentIdList(List<Object> parentIds, Transaction t, List<Object> excludeDetailIds, boolean hard) {
|
||||
String rawWhere = deriveWhereParentIdSql(true, "");
|
||||
String inClause = buildInClauseBinding(parentIds.size(), exportedPropertyBindProto);
|
||||
String expr = rawWhere + inClause;
|
||||
|
||||
SpiEbeanServer server = descriptor.ebeanServer();
|
||||
SpiQuery<?> q = many.newQuery(server);
|
||||
//Query<?> q = server.find(propertyType);
|
||||
many.bindParentIdsIn(expr, parentIds, q);
|
||||
final SpiEbeanServer server = descriptor.ebeanServer();
|
||||
final SpiQuery<?> query = many.newQuery(server);
|
||||
many.bindParentIdsIn(rawParentIdIN("", parentIds.size()), parentIds, query);
|
||||
if (hard) {
|
||||
q.setIncludeSoftDeletes();
|
||||
query.setIncludeSoftDeletes();
|
||||
}
|
||||
if (excludeDetailIds != null && !excludeDetailIds.isEmpty()) {
|
||||
q.where().not(q.getExpressionFactory().idIn(excludeDetailIds));
|
||||
query.where().not(query.getExpressionFactory().idIn(excludeDetailIds));
|
||||
}
|
||||
return server.findIds(q, t);
|
||||
return server.findIds(query, t);
|
||||
}
|
||||
|
||||
SpiSqlUpdate deleteByParentId(Object parentId) {
|
||||
DefaultSqlUpdate sqlDelete = new DefaultSqlUpdate(deleteByParentIdSql);
|
||||
final var sqlDelete = new DefaultSqlUpdate(deleteByParentIdSql);
|
||||
many.bindParentId(sqlDelete, parentId);
|
||||
return sqlDelete;
|
||||
}
|
||||
|
||||
SpiSqlUpdate deleteByParentIdList(List<Object> parentIds) {
|
||||
String sql = Str.add(deleteByParentIdInSql, buildInClauseBinding(parentIds.size(), exportedPropertyBindProto));
|
||||
DefaultSqlUpdate delete = new DefaultSqlUpdate(sql);
|
||||
final String rawWhere = rawParentIdIN("", parentIds.size());
|
||||
final String sql = Str.add(deleteByParentIdInSql, rawWhere);
|
||||
final var delete = new DefaultSqlUpdate(sql);
|
||||
many.bindParentIds(delete, parentIds);
|
||||
return delete;
|
||||
}
|
||||
@@ -172,71 +168,95 @@ class BeanPropertyAssocManySqlHelp<T> {
|
||||
if (!skipComma || i > 0) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
}
|
||||
|
||||
private void append(StringBuilder sb) {
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
String fkColumn = exportedProperties[i].getForeignDbColumn();
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(fkColumn);
|
||||
sb.append(exportedProperties[i].getForeignDbColumn());
|
||||
}
|
||||
}
|
||||
|
||||
private String deriveWhereParentIdSql(boolean inClause, String tableAlias) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (inClause) {
|
||||
sb.append("(");
|
||||
private String rawParentIdIN(String tableAlias, int size) {
|
||||
if (idInExpandedForm) {
|
||||
return rawParentIdExpanded(tableAlias, size);
|
||||
} else {
|
||||
return rawParentIdStandard(tableAlias, size);
|
||||
}
|
||||
}
|
||||
|
||||
private String rawParentIdStandard(String tableAlias, int size) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append('(');
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
String fkColumn = exportedProperties[i].getForeignDbColumn();
|
||||
if (i > 0) {
|
||||
sb.append(inClause ? "," : " and ");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(tableAlias).append(fkColumn);
|
||||
if (!inClause) {
|
||||
sb.append("=? ");
|
||||
}
|
||||
}
|
||||
if (inClause) {
|
||||
sb.append(")");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String buildInClauseBinding(int size, String bindProto) {
|
||||
if (descriptor.isSimpleId()) {
|
||||
return descriptor.idBinder().getIdInValueExpr(false, size);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(10 + (size * (bindProto.length() + 1)));
|
||||
sb.append(" in");
|
||||
sb.append(" (");
|
||||
sb.append(") in (");
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(bindProto);
|
||||
sb.append(exportedPropertyBindProto);
|
||||
}
|
||||
sb.append(") ");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String deriveExportedPropertyBindProto() {
|
||||
private String rawParentIdExpanded(String tableAlias, int size) {
|
||||
final String proto = parentIdExpandedProto(tableAlias);
|
||||
final var result = new StringBuilder(size * (proto.length() + 2) + 10).append('(');
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i > 0) {
|
||||
result.append(" or ");
|
||||
}
|
||||
result.append(proto);
|
||||
}
|
||||
return result.append(')').toString();
|
||||
}
|
||||
|
||||
private String parentIdExpandedProto(String tableAlias) {
|
||||
final var sb = new StringBuilder(60).append('(');
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(tableAlias).append(exportedProperties[i].getForeignDbColumn()).append("=?");
|
||||
}
|
||||
return sb.append(')').toString();
|
||||
}
|
||||
|
||||
private String rawParentIdEQ(String tableAlias) {
|
||||
final var sb = new StringBuilder(80);
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
sb.append(tableAlias).append(exportedProperties[i].getForeignDbColumn()).append("=?");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String initExportedBindProto() {
|
||||
if (exportedProperties.length == 1) {
|
||||
return "?";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final var sb = new StringBuilder(exportedProperties.length * 2 + 2);
|
||||
sb.append("(");
|
||||
for (int i = 0; i < exportedProperties.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(",");
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append("?");
|
||||
sb.append('?');
|
||||
}
|
||||
sb.append(")");
|
||||
sb.append(')');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
-1
@@ -14,7 +14,6 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class TestCompositeForeignKey extends BaseTestCase {
|
||||
|
||||
@IgnorePlatform({Platform.SQLSERVER, Platform.DB2}) // FIXME for DB2 and SQLServer
|
||||
@Test
|
||||
void createConnectionWithCompositeForeignKey() {
|
||||
String networkId = "test-network";
|
||||
|
||||
Reference in New Issue
Block a user