#1348 - ENH: Add support for bitwiseAnd / bitwiseAny / bitwiseAll .. expressions for use with integer/long "Flags" properties

This commit is contained in:
Rob Bygrave
2018-03-14 16:23:16 +13:00
parent 4bc1f2ede4
commit 602a35d0b6
29 changed files with 652 additions and 52 deletions
@@ -0,0 +1,70 @@
package org.tests.expression.bitwise;
import io.ebean.Model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Version;
@Entity
public class BwBean extends Model {
@Id
long id;
String name;
// sqlserver wants integer type for bitwise AND operator
@Column(columnDefinition = "integer")
long flags;
@Version
long version;
public BwBean(String name) {
this.name = name;
}
public BwBean(String name, long flags) {
this.name = name;
this.flags = flags;
}
@Override
public String toString() {
return "nm:" + name;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getFlags() {
return flags;
}
public void setFlags(long flags) {
this.flags = flags;
}
public long getVersion() {
return version;
}
public void setVersion(long version) {
this.version = version;
}
}
@@ -0,0 +1,78 @@
package org.tests.expression.bitwise;
public class BwFlags {
public static final int NOTHING = 0;
/**
* Indicates the bean is being inserted.
*/
public static final int HAS_COLOUR = 0x00000001;
/**
* Indicates persist cascade.
*/
public static final int HAS_SIZE = 0x00000002;
/**
* Indicates Publish mode.
*/
public static final int HAS_BULK = 0x00000004;
/**
* Return true if part of a Merge or Publish.
*/
public static boolean isColour(long state) {
return (state & HAS_COLOUR) != 0;
}
/**
* Return true if the given flag is set.
*/
public static boolean isSet(int state, int flag) {
return (state & flag) == flag;
}
public static int setHasColour(int state) {
return set(state, HAS_COLOUR, true);
}
/**
* Parent was not inserted.
*/
public static int unsetHasColour(int state) {
return set(state, HAS_COLOUR, false);
}
/**
* Set Recurse flag.
*/
public static int setHasSize(int state) {
return set(state, HAS_SIZE, true);
}
public static int unsetHasSize(int state) {
return set(state, HAS_SIZE, false);
}
/**
* Set Publish flag.
*/
public static int setHasBulk(int state) {
return set(state, HAS_BULK, true);
}
public static int unsetHasBulk(int state) {
return set(state, HAS_BULK, false);
}
private static int set(int state, int flag, boolean setFlag) {
if (setFlag) {
return (state |= flag);
} else {
return state &= ~flag;
}
}
}
@@ -0,0 +1,141 @@
package org.tests.expression.bitwise;
import io.ebean.BaseTestCase;
import io.ebean.Ebean;
import org.junit.Test;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
public class TestBitwiseExpressions extends BaseTestCase {
@Test
public void where() {
setup();
bitwiseAnd();
bitwiseAny();
bitwiseAll();
}
private void bitwiseAnd() {
List<BwBean> list = Ebean.find(BwBean.class)
// not bulk set AND size set
.where().bitwiseAnd("flags", BwFlags.HAS_BULK + BwFlags.HAS_SIZE, BwFlags.HAS_SIZE)
.findList();
assertThat(list).hasSize(1);
assertThat(list.get(0).getName()).isEqualTo("SizeOnly");
list = Ebean.find(BwBean.class)
// bulk set AND not size set
.where().bitwiseAnd("flags", BwFlags.HAS_BULK + BwFlags.HAS_SIZE, BwFlags.HAS_BULK)
.findList();
assertThat(list).hasSize(1);
assertThat(list.get(0).getName()).isEqualTo("ColourAndBulk");
list = Ebean.find(BwBean.class)
// bulk set AND not size set
.where().bitwiseAnd("flags", BwFlags.HAS_BULK + BwFlags.HAS_COLOUR, BwFlags.HAS_COLOUR)
.findList();
assertThat(list).hasSize(1);
assertThat(list.get(0).getName()).isEqualTo("ColourOnly");
}
private void bitwiseAny() {
List<BwBean> list = Ebean.find(BwBean.class)
.where().bitwiseAny("flags", BwFlags.HAS_BULK + BwFlags.HAS_SIZE)
.findList();
assertThat(list).hasSize(3);
assertThat(list.get(0).getName()).isEqualTo("SizeOnly");
assertThat(list.get(1).getName()).isEqualTo("ColourAndBulk");
assertThat(list.get(2).getName()).isEqualTo("Everything");
list = Ebean.find(BwBean.class)
.where().bitwiseAny("flags", BwFlags.HAS_BULK + BwFlags.HAS_SIZE + BwFlags.HAS_COLOUR)
.findList();
assertThat(list).hasSize(4);
list = Ebean.find(BwBean.class)
.where().bitwiseAny("flags", BwFlags.HAS_SIZE + BwFlags.HAS_COLOUR)
.findList();
assertThat(list).hasSize(4);
list = Ebean.find(BwBean.class)
.where().bitwiseAny("flags", BwFlags.HAS_SIZE)
.findList();
assertThat(list).hasSize(2);
assertThat(list.get(0).getName()).isEqualTo("SizeOnly");
assertThat(list.get(1).getName()).isEqualTo("Everything");
list = Ebean.find(BwBean.class)
.where().bitwiseAny("flags", BwFlags.HAS_COLOUR)
.findList();
assertThat(list).hasSize(3);
assertThat(list.get(0).getName()).isEqualTo("ColourOnly");
assertThat(list.get(1).getName()).isEqualTo("ColourAndBulk");
assertThat(list.get(2).getName()).isEqualTo("Everything");
}
private void bitwiseAll() {
List<BwBean> list = Ebean.find(BwBean.class)
.where().bitwiseAll("flags", BwFlags.HAS_BULK + BwFlags.HAS_SIZE)
.findList();
assertThat(list).hasSize(1);
assertThat(list.get(0).getName()).isEqualTo("Everything");
list = Ebean.find(BwBean.class)
.where().bitwiseAll("flags", BwFlags.HAS_BULK + BwFlags.HAS_COLOUR)
.orderBy().asc("id")
.findList();
assertThat(list).hasSize(2);
assertThat(list.get(0).getName()).isEqualTo("ColourAndBulk");
assertThat(list.get(1).getName()).isEqualTo("Everything");
list = Ebean.find(BwBean.class)
.where().bitwiseAll("flags", BwFlags.HAS_SIZE)
.orderBy().asc("id")
.findList();
assertThat(list).hasSize(2);
assertThat(list.get(0).getName()).isEqualTo("SizeOnly");
assertThat(list.get(1).getName()).isEqualTo("Everything");
list = Ebean.find(BwBean.class)
.where().bitwiseAll("flags", BwFlags.HAS_COLOUR)
.orderBy().asc("id")
.findList();
assertThat(list).hasSize(3);
assertThat(list.get(0).getName()).isEqualTo("ColourOnly");
assertThat(list.get(1).getName()).isEqualTo("ColourAndBulk");
assertThat(list.get(2).getName()).isEqualTo("Everything");
}
private void setup() {
Ebean.find(BwBean.class).delete();
new BwBean("Nothing", BwFlags.NOTHING).save();
new BwBean("ColourOnly", BwFlags.HAS_COLOUR).save();
new BwBean("SizeOnly", BwFlags.HAS_SIZE).save();
new BwBean("ColourAndBulk", BwFlags.HAS_COLOUR + BwFlags.HAS_BULK).save();
new BwBean("Everything", BwFlags.HAS_COLOUR + BwFlags.HAS_BULK + BwFlags.HAS_SIZE).save();
}
}
@@ -4,12 +4,13 @@ import io.ebean.BeanRepository;
import io.ebean.EbeanServer;
import org.tests.model.basic.Customer;
import javax.inject.Inject;
import java.util.List;
//import javax.inject.Inject;
public class CustomerRepository extends BeanRepository<Integer, Customer> {
@Inject
//@Inject
public CustomerRepository(EbeanServer server) {
super(Customer.class, server);
}