Skip to content

Commit

Permalink
Support for "extraWhere"
Browse files Browse the repository at this point in the history
  • Loading branch information
rPraml authored and nPraml committed Oct 18, 2024
1 parent 2104d34 commit fdd6e79
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public SpiSqlUpdate createInsert(SpiEbeanServer server) {
return new DefaultSqlUpdate(server, sb.toString(), bindParams);
}

public SpiSqlUpdate createDelete(SpiEbeanServer server, DeleteMode deleteMode) {
public SpiSqlUpdate createDelete(SpiEbeanServer server, DeleteMode deleteMode, String extraWhere) {
BindParams bindParams = new BindParams();
StringBuilder sb = new StringBuilder();
if (deleteMode.isHard()) {
Expand All @@ -90,17 +90,34 @@ public SpiSqlUpdate createDelete(SpiEbeanServer server, DeleteMode deleteMode) {
bindParams.setParameter(++count, bindValue);
}
}
addExtraWhere(sb, extraWhere);

return new DefaultSqlUpdate(server, sb.toString(), bindParams);
}

public SpiSqlUpdate createDeleteChildren(SpiEbeanServer server) {

public SpiSqlUpdate createDeleteChildren(SpiEbeanServer server, String extraWhere) {
BindParams bindParams = new BindParams();
StringBuilder sb = new StringBuilder();
sb.append("delete from ").append(tableName).append(" where ");
setBindParams(bindParams, sb);
addExtraWhere(sb, extraWhere);
return new DefaultSqlUpdate(server, sb.toString(), bindParams);
}

private void addExtraWhere(StringBuilder sb, String extraWhere) {
if (extraWhere != null) {
if (extraWhere.indexOf("${ta}") == -1) {
// no table alias append ${mta} to query.
sb.append(" and ").append(extraWhere.replace("${mta}", tableName));
} else if (extraWhere.indexOf("${mta}") != -1) {
// we have a table alias - this is not interesting for deletion.
// but if have also a m2m table alias - this is a problem now!
throw new UnsupportedOperationException("extraWhere \'" + extraWhere + "\' has both ${ta} and ${mta} - this is not yet supported");
}
}
}

private int setBindParams(BindParams bindParams, StringBuilder sb) {
int count = 0;
for (Map.Entry<String, Object> entry : values.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ void deleteManyIntersection(EntityBean bean, BeanPropertyAssocMany<?> many, SpiT

private SpiSqlUpdate deleteAllIntersection(EntityBean bean, BeanPropertyAssocMany<?> many, boolean publish) {
IntersectionRow intRow = many.buildManyToManyDeleteChildren(bean, publish);
return intRow.createDeleteChildren(server);
return intRow.createDeleteChildren(server, many.extraWhere());
}

/**
Expand Down Expand Up @@ -1100,7 +1100,7 @@ void deleteManyDetails(SpiTransaction t, BeanDescriptor<?> desc, EntityBean pare
&& (excludeDetailIds == null || excludeDetailIds.size() <= batch)) {
// Just delete all the children with one statement
IntersectionRow intRow = many.buildManyDeleteChildren(parentBean, excludeDetailIds);
SqlUpdate sqlDelete = intRow.createDelete(server, deleteMode);
SqlUpdate sqlDelete = intRow.createDelete(server, deleteMode, many.extraWhere());
executeSqlUpdate(sqlDelete, t);

} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ private void saveAssocManyIntersection(boolean queue) {
// the object from the 'other' side of the ManyToMany
// build a intersection row for 'delete'
IntersectionRow intRow = many.buildManyToManyMapBean(parentBean, otherDelete, publish);
SpiSqlUpdate sqlDelete = intRow.createDelete(server, DeleteMode.HARD);
SpiSqlUpdate sqlDelete = intRow.createDelete(server, DeleteMode.HARD, many.extraWhere());
persister.executeOrQueue(sqlDelete, transaction, queue, BatchControl.DELETE_QUEUE);
}
}
Expand Down
16 changes: 16 additions & 0 deletions ebean-test/src/test/java/org/tests/model/m2m/MnyEdge.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ public class MnyEdge {
@ManyToOne
private MnyNode to;


public MnyEdge() {
// default
}

public MnyEdge(Object from, Object to) {
this.from = (MnyNode) from;
this.to = (MnyNode) to;
this.id = this.from.id * 10000 + this.to.id;
this.flags = this.from.id + this.to.id;
}

public static MnyEdge createReverseRelation(Object to, MnyNode from) {
return new MnyEdge(from, to);
}

private int flags;

public Integer getId() {
Expand Down
5 changes: 3 additions & 2 deletions ebean-test/src/test/java/org/tests/model/m2m/MnyNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@ public class MnyNode {

String name;

@ManyToMany
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "mny_edge",
joinColumns = @JoinColumn(name = "from_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "to_id", referencedColumnName = "id"))
@Where(clause = "${mta}.flags != 12345 and '${dbTableName}' = 'mny_node'")
List<MnyNode> allRelations;

@ManyToMany
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "mny_edge",
joinColumns = @JoinColumn(name = "to_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "from_id", referencedColumnName = "id"))
Expand Down
74 changes: 74 additions & 0 deletions ebean-test/src/test/java/org/tests/model/m2m/TestM2MWithWhere.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.ebean.DB;
import io.ebean.test.LoggedSql;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.util.List;
Expand All @@ -18,6 +19,79 @@
*/
public class TestM2MWithWhere extends BaseTestCase {

@Test
@Disabled
public void testModify() throws Exception {

MnyNode node1 = new MnyNode();
node1.setName("node1");
node1.setId(111);
MnyNode node2 = new MnyNode();
node2.setName("node2");
node2.setId(222);
MnyNode node3 = new MnyNode();
node3.setName("node3");
node3.setId(333);
MnyNode node4 = new MnyNode();
node4.setName("node4");
node4.setId(444);

node1.getAllReverseRelations().add(node2);
node1.getAllRelations().add(node2);
node2.getAllRelations().add(node3);
node3.getAllRelations().add(node4);
DB.save(node1);
DB.save(node1);

DB.refresh(node2);
DB.refresh(node3);
assertThat(node2.getAllRelations()).containsExactlyInAnyOrder(node1, node3);
assertThat(node3.getAllReverseRelations()).containsExactlyInAnyOrder(node2);

DB.refresh(node1);
node1.getAllReverseRelations().clear();
System.out.println("Clearing");
DB.save(node1);
DB.refresh(node2);
assertThat(node2.getAllRelations()).containsExactlyInAnyOrder(node3);

node2.getAllRelations().clear();
node2.getAllRelations().add(node3);
LoggedSql.start();
DB.save(node2);
LoggedSql.stop().forEach(System.out::println);

}

@Test
@Disabled
public void testAccessAndModify() throws Exception {
createTestData();

MnyNode node = DB.find(MnyNode.class, 1);
node.setName("fooBarBaz");
MnyNode removed = node.getAllRelations().remove(0);

LoggedSql.start();
DB.save(node);
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(4);
assertThat(sql.get(0)).contains("update mny_node set name=? where id=?; -- bind(fooBarBaz");
assertThat(sql.get(1)).contains("delete from mny_edge where from_id = ? and to_id = ? and mny_edge.flags != 12345 and 'mny_node' = 'mny_node'");
assertThat(sql.get(2)).contains("-- bind");
assertThat(sql.get(3)).contains("executeBatch() size:1 sql:delete from mny_edge where from_id = ? and to_id = ? and mny_edge.flags != 12345 and 'mny_node' = 'mny_node'");

node.getAllRelations().add(removed);
LoggedSql.start();
DB.save(node);
sql = LoggedSql.stop();
assertThat(sql).hasSize(3);
assertThat(sql.get(0)).contains("insert into mny_edge (id, flags, from_id, to_id) values (?,?,?,?)");
assertThat(sql.get(1)).contains("-- bind");
assertThat(sql.get(2)).contains("-- executeBatch() size:1 sql:insert into mny_edge (id, flags, from_id, to_id) values (?,?,?,?)");

}

@Test
public void testQuery() throws Exception {
createTestData();
Expand Down

0 comments on commit fdd6e79

Please sign in to comment.