/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/AbstractMappingTest.java |
---|
New file |
0,0 → 1,203 |
package org.mentabean.jdbc; |
import java.util.List; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.util.OrderBy; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLUtils; |
public class AbstractMappingTest extends AbstractBeanSessionTest { |
public static abstract class Conta { |
private int id; |
public Conta(int id) { |
this.id = id; |
} |
public Conta() {} |
public abstract String realizaOperacao(); |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
} |
public static class ContaReceber extends Conta { |
public ContaReceber() {} |
public ContaReceber(int id) { |
super(id); |
} |
@Override |
public String realizaOperacao() { |
return "Conta a Receber"; |
} |
} |
public static class ContaPagar extends Conta { |
public ContaPagar() {} |
public ContaPagar(int id) { |
super(id); |
} |
@Override |
public String realizaOperacao() { |
return "Conta a Pagar"; |
} |
} |
public static abstract class Parcela { |
private int numero; |
private double valor; |
private Conta conta; |
public int getNumero() { |
return numero; |
} |
public void setNumero(int numero) { |
this.numero = numero; |
} |
public double getValor() { |
return valor; |
} |
public void setValor(double valor) { |
this.valor = valor; |
} |
public Conta getConta() { |
return conta; |
} |
public void setConta(Conta conta) { |
this.conta = conta; |
} |
public Parcela conta(Conta conta) { |
this.conta = conta; |
return this; |
} |
public Parcela numero(int numero) { |
this.numero = numero; |
return this; |
} |
public Parcela valor(double valor) { |
this.valor = valor; |
return this; |
} |
} |
public static class ParcelaReceber extends Parcela { |
} |
public static class ParcelaPagar extends Parcela { |
} |
public BeanManager configure() { |
BeanManager manager = new BeanManager(); |
ParcelaPagar ppPxy = PropertiesProxy.create(ParcelaPagar.class); |
BeanConfig ppCfg = new BeanConfig(ParcelaPagar.class, "parcelas_pagar") |
.pk(ppPxy.getNumero(), DBTypes.INTEGER) |
.field(ppPxy.getConta().getId(), "idcontas_pagar", DBTypes.INTEGER) |
.field(ppPxy.getValor(), DBTypes.DOUBLE) |
.abstractInstance(ppPxy.getConta(), ContaPagar.class); |
ParcelaReceber prPxy = PropertiesProxy.create(ParcelaReceber.class); |
BeanConfig prCfg = new BeanConfig(ParcelaReceber.class, "parcelas_receber") |
.pk(prPxy.getNumero(), DBTypes.INTEGER) |
.field(prPxy.getConta().getId(), "idcontas_receber", DBTypes.INTEGER) |
.field(prPxy.getValor(), DBTypes.DOUBLE) |
.abstractInstance(prPxy.getConta(), ContaReceber.class) |
; |
manager.addBeanConfig(prCfg); |
manager.addBeanConfig(ppCfg); |
return manager; |
} |
@Test |
public void test() { |
BeanSession session = new H2BeanSession(configure(), getConnection()); |
session.createTables(); |
Parcela pr = new ParcelaReceber() |
.numero(1) |
.conta(new ContaReceber(1)) |
.valor(300); |
session.insert(pr); |
Parcela prDB = new ParcelaReceber().numero(1); |
session.load(prDB); |
Assert.assertNotNull(prDB.getConta()); |
Assert.assertTrue(prDB.getConta().realizaOperacao().equals("Conta a Receber")); |
Assert.assertEquals(ContaReceber.class, prDB.getConta().getClass()); |
Assert.assertEquals(pr.getNumero(), prDB.getNumero()); |
prDB.getConta().setId(4); |
session.update(prDB); |
prDB = new ParcelaReceber().numero(1); |
session.load(prDB); |
Assert.assertEquals(4, prDB.getConta().getId()); |
ContaPagar cp = new ContaPagar(20); |
Parcela pp1 = new ParcelaPagar() |
.numero(1) |
.conta(cp) |
.valor(100); |
Parcela pp2 = new ParcelaPagar() |
.numero(2) |
.conta(cp) |
.valor(150); |
Parcela pp3 = new ParcelaPagar() |
.numero(3) |
.conta(cp) |
.valor(175); |
session.insert(pp1); |
session.insert(pp2); |
session.insert(pp3); |
Parcela ppProto = new ParcelaPagar().conta(cp); |
List<Parcela> list = session.loadList(ppProto, new OrderBy().orderByAsc("numero")); |
Assert.assertEquals(3, list.size()); |
Assert.assertEquals(1, list.get(0).getNumero()); |
Assert.assertEquals(2, list.get(1).getNumero()); |
Assert.assertEquals(3, list.get(2).getNumero()); |
Assert.assertEquals(175d, list.get(2).getValor()); |
Assert.assertNotNull(list.get(2).getConta()); |
SQLUtils.close(session.getConnection()); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/AdvancedQueryBuilderTest.java |
---|
New file |
0,0 → 1,295 |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.util.List; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.jdbc.QueryBuilder.Alias; |
import org.mentabean.jdbc.QueryBuilder.Query; |
import org.mentabean.sql.Sentence; |
import org.mentabean.sql.conditions.Equals; |
import org.mentabean.sql.conditions.GreaterThan; |
import org.mentabean.sql.conditions.GreaterThanEquals; |
import org.mentabean.sql.conditions.In; |
import org.mentabean.sql.conditions.Like; |
import org.mentabean.sql.functions.Count; |
import org.mentabean.sql.functions.Lower; |
import org.mentabean.sql.param.ParamField; |
import org.mentabean.sql.param.ParamFunction; |
import org.mentabean.sql.param.ParamSubQuery; |
import org.mentabean.sql.param.ParamValue; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLUtils; |
public class AdvancedQueryBuilderTest extends AbstractBeanSessionTest { |
public static class Company { |
private String id; |
private long number; |
private String name; |
private int employeeCount; |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public String getId() { |
return id; |
} |
public void setId(String id) { |
this.id = id; |
} |
public long getNumber() { |
return number; |
} |
public void setNumber(long number) { |
this.number = number; |
} |
public int getEmployeeCount() { |
return employeeCount; |
} |
public void setEmployeeCount(int employeeCount) { |
this.employeeCount = employeeCount; |
} |
@Override |
public String toString() { |
return "Company [id=" + id + ", number=" + number + ", name=" |
+ name + ", employeeCount=" + employeeCount + "]"; |
} |
} |
public static class Employee { |
private Company company; |
private long number; |
private String name; |
private double salary; |
public Company getCompany() { |
return company; |
} |
public void setCompany(Company company) { |
this.company = company; |
} |
public long getNumber() { |
return number; |
} |
public void setNumber(long number) { |
this.number = number; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public double getSalary() { |
return salary; |
} |
public void setSalary(double salary) { |
this.salary = salary; |
} |
@Override |
public String toString() { |
return "Employee [company=" + company + ", number=" + number |
+ ", name=" + name + ", salary=" + salary + "]"; |
} |
} |
public static class Post { |
private Employee employee; |
private Company company; |
private String description; |
public Employee getEmployee() { |
return employee; |
} |
public void setEmployee(Employee employee) { |
this.employee = employee; |
} |
public Company getCompany() { |
return company; |
} |
public void setCompany(Company company) { |
this.company = company; |
} |
public String getDescription() { |
return description; |
} |
public void setDescription(String description) { |
this.description = description; |
} |
@Override |
public String toString() { |
return "=== POST "+description+" ===\n"+ |
company+"\n"+employee; |
} |
} |
private BeanManager configure() { |
BeanManager manager = new BeanManager(); |
Company comPxy = PropertiesProxy.create(Company.class); |
BeanConfig comConf = new BeanConfig(Company.class, "company") |
.pk(comPxy.getId(), DBTypes.STRING) |
.pk(comPxy.getNumber(), DBTypes.LONG) |
.field(comPxy.getName(), DBTypes.STRING); |
manager.addBeanConfig(comConf); |
Employee empPxy = PropertiesProxy.create(Employee.class); |
BeanConfig employeeConf = new BeanConfig(Employee.class, "employee") |
.pk(empPxy.getNumber(), DBTypes.LONG) |
.pk(empPxy.getCompany().getId(), "idcompany", DBTypes.STRING) |
.pk(empPxy.getCompany().getNumber(), "ncompany", DBTypes.LONG) |
.field(empPxy.getName(), DBTypes.STRING) |
.field(empPxy.getSalary(), DBTypes.DOUBLE); |
manager.addBeanConfig(employeeConf); |
Post postPxy = PropertiesProxy.create(Post.class); |
BeanConfig postConf = new BeanConfig(Post.class, "post") |
.pk(postPxy.getEmployee().getNumber(), "number_employee", DBTypes.LONG) |
.pk(postPxy.getEmployee().getCompany().getId(), "idcompany_employee", DBTypes.STRING) |
.pk(postPxy.getEmployee().getCompany().getNumber(), "ncompany_employee", DBTypes.LONG) |
.pk(postPxy.getCompany().getId(), "idcompany", DBTypes.STRING) |
.pk(postPxy.getCompany().getNumber(), "ncompany", DBTypes.LONG) |
.field(postPxy.getDescription(), DBTypes.STRING); |
manager.addBeanConfig(postConf); |
return manager; |
} |
@Test |
public void test() { |
final BeanManager manager = configure(); |
final Connection conn = getConnection(); |
try { |
AnsiSQLBeanSession.DEBUG = false; |
AnsiSQLBeanSession.DEBUG_NATIVE = false; |
BeanSession session = new H2BeanSession(manager, conn); |
session.createTables(); |
Company comp = new Company(); |
comp.setId("4356136"); |
comp.setName("W3C"); |
comp.setNumber(1); |
session.insert(comp); |
Company basicComp = session.createBasicInstance(comp); |
Assert.assertFalse(comp == basicComp); |
Assert.assertNotNull(basicComp.getId()); |
Assert.assertNotNull(basicComp.getNumber()); |
Assert.assertNull(basicComp.getName()); |
if (AnsiSQLBeanSession.DEBUG) { |
System.out.println("Company: " + comp); |
System.out.println("Company (only pks): " + basicComp); |
} |
Employee emp = new Employee(); |
emp.setCompany(comp); |
emp.setName("Érico"); |
emp.setNumber(391); |
emp.setSalary(9999); |
session.insert(emp); |
Employee basicEmp = session.createBasicInstance(emp); |
Assert.assertNull(basicEmp.getName()); |
Assert.assertNotNull(basicEmp.getCompany()); |
Assert.assertEquals(0d, basicEmp.getSalary()); |
Assert.assertEquals(emp.getNumber(), basicEmp.getNumber()); |
Assert.assertEquals(emp.getCompany().getId(), basicEmp.getCompany().getId()); |
Assert.assertEquals(emp.getCompany().getNumber(), basicEmp.getCompany().getNumber()); |
Post post = new Post(); |
post.setCompany(comp); |
post.setEmployee(emp); |
post.setDescription("Programmer"); |
session.insert(post); |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Company> c = builder.aliasTo(Company.class, "com"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Alias<Employee> e2 = builder.aliasTo(Employee.class, "emp2"); |
e2.setReturns(e2.pxy().getNumber()); |
Sentence sum = new Sentence( |
new ParamFunction(new Count(new ParamField(e, e.pxy().getNumber())))) |
.returnType(DBTypes.LONG).fromProperty(p.pxy().getCompany().getEmployeeCount()); |
Query query = builder.select(p, c, e).add(sum) |
.from(p) |
.join(c) |
.on(c.pxy().getId()) |
.eq(p.pxy().getCompany().getId()) |
.and(c.pxy().getNumber()) |
.eq(p.pxy().getCompany().getNumber()) |
.eqProperty(p.pxy().getCompany()) |
.join(e) |
.on(e.pxy().getNumber()) |
.eq(p.pxy().getEmployee().getNumber()) |
.and(e.pxy().getCompany().getId()) |
.eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getEmployee()) |
.and(e.pxy().getCompany().getNumber()) |
.eq(p.pxy().getCompany().getNumber()) |
.where() |
.clauseIf(true, e.pxy().getName()) |
.condition(new Like(new ParamValue("%o"))).and() |
.clauseIf(false, new Lower(new ParamField(c, c.pxy().getName()))).condition(new Equals(new ParamValue(null))).and() |
.clauseIf(false, e.pxy().getNumber()).condition( |
new In(new ParamSubQuery(builder.subQuery().select(e2).from(e2) |
.where().clause(e.pxy().getNumber()).condition( |
new GreaterThan(new ParamValue(391)))))).and() |
.clause(new Sentence(builder.subQuery().select(e2).from(e2).limit(1))).condition(new GreaterThan(1)) |
.groupBy() |
.having().clause(sum).condition(new GreaterThanEquals(1)) |
.orderBy().asc(p, p.pxy().getDescription()) |
.limit(10); |
List<Post> list = query.executeQuery(); |
for (Post reg : list) { |
Assert.assertNotNull(reg.getCompany()); |
Assert.assertNotNull(reg.getCompany().getName()); |
Assert.assertNotNull(reg.getEmployee().getName()); |
} |
}catch (Exception e) { |
throw new BeanException(e); |
}finally { |
SQLUtils.close(conn); |
} |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/AnotherProxyTest.java |
---|
New file |
0,0 → 1,250 |
package org.mentabean.jdbc; |
import static junit.framework.Assert.assertEquals; |
import static junit.framework.Assert.assertNotNull; |
import static junit.framework.Assert.assertNull; |
import static org.mentabean.jdbc.AnsiSQLBeanSession.DEBUG; |
import java.math.BigDecimal; |
import java.sql.Connection; |
import java.util.LinkedList; |
import java.util.List; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.util.PropertiesProxy; |
public class AnotherProxyTest extends AbstractBeanSessionTest { |
public static class Person { |
private String name; |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
} |
public static class Customer extends Person { |
private int code; |
private Boolean active; |
private BigDecimal height; |
private int age; |
private Type type; |
private TypeTwo typeTwo; |
public Customer() { |
} |
public Customer(int code, String name, Boolean active) { |
this.code = code; |
setName(name); |
this.active = active; |
} |
public Customer(int code) { |
this.code = code; |
} |
public Customer(String name, Boolean active, BigDecimal height) { |
setName(name); |
this.active = active; |
this.height = height; |
} |
public int getCode() { |
return code; |
} |
public void setCode(int code) { |
this.code = code; |
} |
public Boolean getActive() { |
return active; |
} |
public void setActive(Boolean active) { |
this.active = active; |
} |
public BigDecimal getHeight() { |
return height; |
} |
public void setHeight(BigDecimal height) { |
this.height = height; |
} |
public int getAge() { |
return age; |
} |
public void setAge(int age) { |
this.age = age; |
} |
public Type getType() { |
return type; |
} |
public void setType(Type type) { |
this.type = type; |
} |
public TypeTwo getTypeTwo() { |
return typeTwo; |
} |
public void setTypeTwo(TypeTwo typeTwo) { |
this.typeTwo = typeTwo; |
} |
} |
public enum Type { |
A, B, C; |
} |
public enum TypeTwo { |
A {}, B {}, C {}; |
} |
private BeanManager getBeanManagerCustomer() { |
BeanManager beanManager = new BeanManager(); |
Customer customerProxy = PropertiesProxy.create(Customer.class); |
BeanConfig customerConfig = new BeanConfig(Customer.class, "customers") |
.pk(customerProxy.getCode(), "idcustomers", DBTypes.AUTOINCREMENT) |
.field(customerProxy.getName(), "name_db", DBTypes.STRING.size(-1)) |
.field(customerProxy.getActive(), "active_db", DBTypes.BOOLEAN) |
.field(customerProxy.getHeight(), "height_db", DBTypes.BIGDECIMAL) |
.field(customerProxy.getAge(), "age_db", DBTypes.INTEGER) |
.field(customerProxy.getType(), DBTypes.ENUMVALUE.from(Type.class).nullable(true)) |
.field(customerProxy.getTypeTwo(), DBTypes.ENUMVALUE.from(TypeTwo.class).nullable(true)); |
//add configurations in beanManager |
beanManager.addBeanConfig(customerConfig); |
return beanManager; |
} |
@Test |
public void test() { |
DEBUG = false; |
final Connection conn = getConnection(); |
try { |
BeanSession session = new H2BeanSession(getBeanManagerCustomer(), conn); |
session.createTables(); |
//let's play... |
Customer c1 = new Customer("Erico", true, new BigDecimal("3.5")); |
c1.setAge(22); |
c1.setType(Type.A); |
c1.setTypeTwo(TypeTwo.B); |
Customer c2 = new Customer("Jessica", true, new BigDecimal("692.894")); |
Customer c3 = new Customer("Inactive customer", false, null); |
session.insert(c1); |
session.insert(c2); |
session.insert(c3); |
Customer pxy = PropertiesProxy.create(Customer.class); |
Customer cDB = new Customer(c3.getCode()); |
session.loadMinus(cDB, pxy.getActive()); |
session.loadList(new Customer(), pxy.getName(), pxy.getActive()); |
c1 = new Customer(c1.getCode()); |
session.load(c1); |
assertEquals(22, c1.getAge()); |
assertEquals(Type.A, c1.getType()); |
assertEquals(TypeTwo.B, c1.getTypeTwo()); |
Customer upd = new Customer(c1.getCode()); |
upd.setName("Erico KL"); |
session.update(upd, pxy.getHeight(), "age"); |
session.load(upd); |
assertNull(upd.getHeight()); |
assertEquals(0, upd.getAge()); |
assertNotNull(upd.getActive()); |
c1 = new Customer(1, "Test", true); |
c2 = new Customer(2, "Test", true); |
List<String> nullProps = new LinkedList<String>(); |
Customer merged = session.compareDifferences(c1, c2, nullProps); |
assertNull(merged); |
assertEquals(0, nullProps.size()); |
c1 = new Customer(1, "John", null); |
c1.setAge(20); |
c2 = new Customer(1, "Test", true); |
c2.setAge(20); |
merged = session.compareDifferences(c1, c2, nullProps); |
assertEquals(1, merged.getCode()); |
assertEquals("John", merged.getName()); |
assertNull(merged.getActive()); |
assertEquals(0, merged.getAge()); |
assertEquals(1, nullProps.size()); |
assertEquals("active", nullProps.get(0)); |
c1 = new Customer(1, "John", null); |
c1.setAge(0); |
session.insert(c1); |
c2 = new Customer(1, "John", true); |
c2.setAge(20); |
nullProps.clear(); |
merged = session.compareDifferences(c1, c2, nullProps); |
assertEquals(c1.getCode(), merged.getCode()); |
assertNull(merged.getName()); |
assertNull(merged.getActive()); |
assertEquals(0, merged.getAge()); |
assertEquals(2, nullProps.size()); |
assertEquals("active", nullProps.get(0)); |
assertEquals("age", nullProps.get(1)); |
assertEquals(1, session.updateDiff(c1, c2)); |
Customer db = session.loadUnique(new Customer(c1.getCode())); |
assertEquals(null, db.getActive()); |
assertEquals(0, db.getAge()); |
assertEquals(c1.getCode(), db.getCode()); |
assertEquals(null, merged.getHeight()); |
assertEquals("John", db.getName()); |
c1 = new Customer(1, "John", true); |
c1.setAge(20); |
c2 = new Customer(1, "John", true); |
c2.setAge(0); |
nullProps.clear(); |
merged = session.compareDifferences(c1, c2, nullProps); |
assertEquals(1, merged.getCode()); |
assertNull(merged.getName()); |
assertNull(merged.getActive()); |
assertEquals(20, merged.getAge()); |
assertEquals(0, nullProps.size()); |
assertEquals(1, session.updateDiff(c1, c2)); |
c1 = new Customer(1, "John", true); |
c1.setAge(20); |
c2 = new Customer(1, "John", true); |
c2.setAge(20); |
nullProps.clear(); |
merged = session.compareDifferences(c1, c2, nullProps); |
assertNull(merged); |
assertEquals(0, nullProps.size()); |
} catch (Exception e) { |
throw new RuntimeException(e); |
}finally { |
close(conn); |
} |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/TriggerTest.java |
---|
New file |
0,0 → 1,250 |
package org.mentabean.jdbc; |
import static junit.framework.Assert.assertEquals; |
import static junit.framework.Assert.assertNotNull; |
import static junit.framework.Assert.assertNull; |
import static org.mentabean.jdbc.AnsiSQLBeanSession.DEBUG; |
import java.math.BigDecimal; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.event.TriggerAdapter; |
import org.mentabean.event.TriggerEvent; |
import org.mentabean.util.PropertiesProxy; |
public class TriggerTest extends AbstractBeanSessionTest { |
public static class Person { |
private String name; |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
} |
public static class Customer extends Person { |
private Long code; |
private Boolean active; |
private BigDecimal height; |
private int age; |
private byte[] picture; |
public Customer() { |
} |
public Customer(Long code, String name, Boolean active) { |
this.code = code; |
setName(name); |
this.active = active; |
} |
public Customer(Long code) { |
this.code = code; |
} |
public Customer(String name, Boolean active, BigDecimal height) { |
setName(name); |
this.active = active; |
this.height = height; |
} |
public Long getCode() { |
return code; |
} |
public void setCode(Long code) { |
this.code = code; |
} |
public Boolean getActive() { |
return active; |
} |
public void setActive(Boolean active) { |
this.active = active; |
} |
public BigDecimal getHeight() { |
return height; |
} |
public void setHeight(BigDecimal height) { |
this.height = height; |
} |
public int getAge() { |
return age; |
} |
public void setAge(int age) { |
this.age = age; |
} |
public byte[] getPicture() { |
return picture; |
} |
public void setPicture(byte[] picture) { |
this.picture = picture; |
} |
@Override |
public String toString() { |
return "Customer [code=" + code + ", active=" + active |
+ ", height=" + height + ", age=" + age + "]"; |
} |
} |
private BeanManager getBeanManagerCustomer() { |
BeanManager beanManager = new BeanManager(); |
Customer customerProxy = PropertiesProxy.create(Customer.class); |
BeanConfig customerConfig = new BeanConfig(Customer.class, "customers") |
.pk(customerProxy.getCode(), "idcustomers", DBTypes.AUTOINCREMENT) |
.field(customerProxy.getName(), "name_db", DBTypes.STRING) |
.field(customerProxy.getActive(), "active_db", DBTypes.BOOLEAN) |
.field(customerProxy.getHeight(), "height_db", DBTypes.BIGDECIMAL) |
.field(customerProxy.getPicture(), "picture_db", DBTypes.BYTE_ARRAY) |
.field(customerProxy.getAge(), "age_db", DBTypes.INTEGER); |
customerConfig.trigger(new TriggerAdapter() { |
@Override |
public void beforeInsert(TriggerEvent evt) { |
Customer c = evt.getBean(); |
showMsg("===> BeanConfig trigger => Before insert for: "+c); |
assertNull(c.getCode()); |
} |
@Override |
public void afterInsert(TriggerEvent evt) { |
Customer c = evt.getBean(); |
showMsg("===> BeanConfig trigger => After insert for: "+c); |
assertNotNull(c.getCode()); |
} |
}); |
//add configurations in beanManager |
beanManager.addBeanConfig(customerConfig); |
return beanManager; |
} |
@Test |
public void test() { |
DEBUG = false; |
final Connection conn = getConnection(); |
PreparedStatement stmt = null; |
try { |
BeanSession session = new H2BeanSession(getBeanManagerCustomer(), conn); |
session.createTables(); |
session.addTrigger(new TriggerAdapter() { |
@Override |
public void beforeInsert(TriggerEvent evt) { |
showMsg("Before insert for: "+evt.getBean()); |
Customer c = evt.getBean(); |
assertNull(c.getCode()); |
} |
@Override |
public void afterInsert(TriggerEvent evt) { |
showMsg("After insert for: "+evt.getBean()); |
Customer c = evt.getBean(); |
assertNotNull(c.getCode()); |
} |
@Override |
public void beforeUpdate(TriggerEvent evt) { |
showMsg("Before update for: "+evt.getBean()); |
} |
@Override |
public void afterUpdate(TriggerEvent evt) { |
showMsg("After update for: "+evt.getBean()); |
} |
@Override |
public void beforeDelete(TriggerEvent evt) { |
showMsg("Before delete for: "+evt.getBean()); |
assertNotNull(evt.getSession().loadUnique(evt.getBean())); |
} |
@Override |
public void afterDelete(TriggerEvent evt) { |
showMsg("After delete for: "+evt.getBean()); |
assertNull(evt.getSession().loadUnique(evt.getBean())); |
} |
}); |
//let's play... |
Customer c1 = new Customer("Erico", true, new BigDecimal("3.5")); |
c1.setAge(22); |
c1.setPicture(new byte[1024]); |
Customer c2 = new Customer("Jessica", true, new BigDecimal("692.894")); |
Customer c3 = new Customer("Inactive customer", false, null); |
session.insert(c1); |
session.insert(c2); |
session.insert(c3); |
session.load(c1); |
Customer basic = session.createBasicInstance(c1); |
Assert.assertNotNull(basic.getCode()); |
Assert.assertNull(basic.getName()); |
Assert.assertNull(basic.getActive()); |
Assert.assertNull(basic.getHeight()); |
Assert.assertNull(basic.getPicture()); |
Assert.assertEquals(0, basic.getAge()); |
session.load(c2); |
assertNotNull(c1.getPicture()); |
assertNull(c2.getPicture()); |
Customer pxy = PropertiesProxy.create(Customer.class); |
Customer cDB = new Customer(c3.getCode()); |
session.loadMinus(cDB, pxy.getActive()); |
session.loadList(new Customer(), pxy.getName(), pxy.getActive()); |
session.load(c1); |
assertEquals(22, c1.getAge()); |
Customer upd = new Customer(c1.getCode()); |
upd.setName("Erico KL"); |
session.update(upd, pxy.getHeight(), "age"); |
session.load(upd); |
assertNull(upd.getHeight()); |
assertEquals(0, upd.getAge()); |
assertNotNull(upd.getActive()); |
session.delete(upd); |
} catch (Exception e) { |
throw new RuntimeException(e); |
}finally { |
close(stmt); |
close(conn); |
} |
} |
private void showMsg(String msg) { |
if (DEBUG) { |
showMsg(msg); |
} |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/AnsiSQLBeanSessionTest.java |
---|
New file |
0,0 → 1,2015 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.text.SimpleDateFormat; |
import java.util.Date; |
import java.util.List; |
import junit.framework.Assert; |
import org.junit.BeforeClass; |
import org.junit.Test; |
import org.mentabean.AutoBeanConfig; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.sql.TableAlias; |
import org.mentabean.type.EnumIdType; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLBuilder; |
import org.mentabean.util.SQLUtils; |
public class AnsiSQLBeanSessionTest extends AbstractBeanSessionTest { |
private static final SimpleDateFormat BD_FORMATTER = new SimpleDateFormat("yyyy-MM-dd"); |
@BeforeClass |
public static void setup() { |
AnsiSQLBeanSession.DEBUG = false; // turn on to see SQL generated |
} |
private static class User { |
public static enum Status { |
BASIC, PREMIUM, GOLD |
} |
private long id; |
private String username; |
private Date birthdate; |
private Status status; |
private boolean deleted; |
private Date insertTime; |
public User() { |
} |
public User(long id) { |
this.id = id; |
} |
public User(String username, String birthdate) { |
this.username = username; |
this.birthdate = fromString(birthdate); |
this.status = Status.BASIC; |
} |
private static Date fromString(String date) { |
try { |
return BD_FORMATTER.parse(date); |
} catch (Exception e) { |
throw new IllegalArgumentException("Cannot parse date: " + date); |
} |
} |
public void setBirthdate(String date) { |
setBirthdate(fromString(date)); |
} |
public long getId() { |
return id; |
} |
public void setId(long id) { |
this.id = id; |
} |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this.username = username; |
} |
public Date getBirthdate() { |
return birthdate; |
} |
public void setBirthdate(Date birthdate) { |
this.birthdate = birthdate; |
} |
public boolean isDeleted() { |
return deleted; |
} |
public void setDeleted(boolean deleted) { |
this.deleted = deleted; |
} |
public Date getInsertTime() { |
return insertTime; |
} |
public void setInsertTime(Date insertTime) { |
this.insertTime = insertTime; |
} |
public void setStatus(Status status) { |
this.status = status; |
} |
public Status getStatus() { |
return status; |
} |
} |
private void createTables(Connection conn) throws SQLException { |
execUpdate(conn, "create table Users(id integer primary key auto_increment, username varchar(25), bd datetime, status varchar(20), deleted tinyint, insert_time timestamp)"); |
execUpdate(conn, "create table Posts(id integer primary key auto_increment, user_id integer, title varchar(200), body text, insert_time timestamp)"); |
} |
private BeanConfig getUserBeanConfig() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanConfig config = new BeanConfig(User.class, "Users"); |
User userProps = PropertiesProxy.create(User.class); |
config.pk(userProps.getId(), DBTypes.AUTOINCREMENT) |
.field(userProps.getUsername(), DBTypes.STRING) |
.field(userProps.getBirthdate(), "bd", DBTypes.DATE) // note that the database column name is different |
.field(userProps.getStatus(), DBTypes.ENUMVALUE.from(User.Status.class)) |
.field(userProps.isDeleted(), DBTypes.BOOLEANINT) |
.field(userProps.getInsertTime(), "insert_time", DBTypes.NOW_ON_INSERT_TIMESTAMP); |
return config; |
} |
@Test |
public void testCRUD() throws SQLException { // CRUD = ISUD = Insert, Select, Update, Delete |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
// INSERT: |
User u = new User("saoj", "1980-03-01"); |
u.setStatus(User.Status.GOLD); |
session.insert(u); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", u.getUsername()); |
Assert.assertEquals("1980-03-01", BD_FORMATTER.format(u.getBirthdate())); |
Assert.assertEquals(false, u.isDeleted()); |
Assert.assertEquals(User.Status.GOLD, u.getStatus()); |
// SELECT: |
u = new User(1); |
boolean loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", u.getUsername()); |
Assert.assertEquals("1980-03-01", BD_FORMATTER.format(u.getBirthdate())); |
Assert.assertEquals(false, u.isDeleted()); |
Assert.assertEquals(User.Status.GOLD, u.getStatus()); |
Assert.assertTrue((new Date()).getTime() >= u.getInsertTime().getTime()); |
// UPDATE: |
u.setUsername("soliveira"); |
int modified = session.update(u); |
Assert.assertEquals(1, modified); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("soliveira", u.getUsername()); |
Assert.assertEquals("1980-03-01", BD_FORMATTER.format(u.getBirthdate())); |
Assert.assertEquals(false, u.isDeleted()); |
Assert.assertEquals(User.Status.GOLD, u.getStatus()); |
Assert.assertTrue((new Date()).getTime() >= u.getInsertTime().getTime()); |
// make sure the new username was saved in the database |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("soliveira", u.getUsername()); |
Assert.assertEquals("1980-03-01", BD_FORMATTER.format(u.getBirthdate())); |
Assert.assertEquals(false, u.isDeleted()); |
Assert.assertEquals(User.Status.GOLD, u.getStatus()); |
Assert.assertTrue((new Date()).getTime() >= u.getInsertTime().getTime()); |
// DELETE: |
boolean deleted = session.delete(u); |
Assert.assertEquals(true, deleted); |
// make sure the bean is deleted from the database... |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(false, loaded); |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testDynUpdate() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
// First insert, so we can test the update after... |
User u = new User("saoj", "1980-03-01"); |
session.insert(u); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", u.getUsername()); |
Assert.assertEquals("1980-03-01", BD_FORMATTER.format(u.getBirthdate())); |
Assert.assertEquals(false, u.isDeleted()); |
// UNATTACHED UPDATE: |
u = new User(1); // note that bean was NOT loaded, in other words, |
// it was NOT attached to session |
u.setUsername("soliveira"); |
int modified = session.update(u); // only properties that are |
// considered SET will be |
// updated |
Assert.assertEquals(1, modified); |
// make sure it was written to the database |
u = new User(1); |
boolean loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals("soliveira", u.getUsername()); |
// ATTACHED UPDATE: |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
u.setUsername(u.getUsername()); // setting, but nothing is |
// changing... |
modified = session.update(u); // nothing should happen here... |
Assert.assertEquals(0, modified); |
// UNATTACHED UPDATED ALL: |
u = new User(1); // note that bean was NOT loaded, in other words, |
// it was NOT attached to session |
u.setUsername("julia"); |
modified = session.updateAll(u); |
Assert.assertEquals(1, modified); |
// everything was written to the database, even the fields that were |
// NOT set |
// as a result, some fields were nullified |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals("julia", u.getUsername()); |
Assert.assertNull(u.getBirthdate()); |
Assert.assertNull(u.getInsertTime()); |
// ATTACHED UPDATE ALL: |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
u.setBirthdate("1980-02-02"); |
modified = session.updateAll(u); |
Assert.assertEquals(1, modified); |
// everything was written to the database, even the fields that were |
// NOT set |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals("julia", u.getUsername()); |
Assert.assertEquals("1980-02-02", BD_FORMATTER.format(u.getBirthdate())); |
Assert.assertNull(u.getInsertTime()); |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testMultipleInserts() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
for (int i = 0; i < 10; i++) { |
User u = new User(); |
u.setUsername("saoj" + (i + 1)); |
u.setBirthdate("1990-01-1" + i); |
session.insert(u); |
Assert.assertEquals(i + 1, u.getId()); |
} |
} finally { |
close(conn); |
} |
} |
@Test |
public void testLoadList() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
for (int i = 0; i < 10; i++) { |
User u = new User(); |
u.setUsername("saoj" + (i + 1)); |
u.setBirthdate("1990-01-1" + i); |
u.setStatus(User.Status.BASIC); |
session.insert(u); |
Assert.assertEquals(i + 1, u.getId()); |
} |
// now set one user to GOLD |
User u = new User(5); |
boolean loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
u.setStatus(User.Status.GOLD); |
int modified = session.update(u); |
Assert.assertEquals(1, modified); |
// first count to see if we are excluding the golad... |
u = new User(); |
u.setStatus(User.Status.BASIC); |
int total = session.countList(u); |
Assert.assertEquals(9, total); |
// now load a list of all BASIC users |
u = new User(); |
u.setStatus(User.Status.BASIC); |
List<User> users = session.loadList(u); |
Assert.assertEquals(9, users.size()); |
// check that the GOLD user was not loaded... |
for (User user : users) { |
Assert.assertTrue(user.getId() != 5); |
} |
} finally { |
close(conn); |
} |
} |
private static class Post { |
private int id; |
private User user; |
private String title; |
private String body; |
private Date insertTime; |
public Post() { |
} |
public Post(int id) { |
this.id = id; |
} |
public Post(User user, String title, String text) { |
this.user = user; |
this.title = title; |
this.body = text; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public User getUser() { |
return user; |
} |
public void setUser(User user) { |
this.user = user; |
} |
public String getTitle() { |
return title; |
} |
public void setTitle(String title) { |
this.title = title; |
} |
public String getBody() { |
return body; |
} |
public void setBody(String body) { |
this.body = body; |
} |
public Date getInsertTime() { |
return insertTime; |
} |
public void setInsertTime(Date insertTime) { |
this.insertTime = insertTime; |
} |
} |
private void getPostBeanConfig(BeanManager beanManager) { |
// Fluent API |
beanManager |
.bean(Post.class, "Posts") |
.pk("id", DBTypes.AUTOINCREMENT) |
.field("user.id", "user_id", DBTypes.LONG) |
.field("title", DBTypes.STRING).field("body", DBTypes.STRING) |
.field("insertTime", "insert_time", DBTypes.NOW_ON_INSERT_TIMESTAMP); |
} |
@Test |
public void testOneToOneRelationshipCRUD() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
getPostBeanConfig(beanManager); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User u = new User("saoj", "1980-01-02"); |
session.insert(u); |
Assert.assertEquals(1, u.getId()); |
// Now insert a post for this user... |
Post p = new Post(new User(1), "Test", "This is a test!"); |
session.insert(p); |
Assert.assertEquals(1, p.getId()); |
// Load from the database... |
p = new Post(1); |
boolean loaded = session.load(p); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNotNull(p.getUser()); // loads user with id only |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNull(p.getUser().getUsername()); |
// Load user for this post... (let's do our manual lazy loading) |
u = new User(p.getUser().getId()); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
p.setUser(u); // manual lazy loading (forget about automatic lazy loading, you want control!) |
// Use JOIN to load all dependencies with a single query... (you know how to make a join, right?) |
p = new Post(1); |
StringBuilder query = new StringBuilder(256); |
query.append("select "); |
query.append(session.buildSelect(Post.class, "p")); |
query.append(", "); |
query.append(session.buildSelect(User.class, "u")); |
query.append(" from Posts p join Users u on p.user_id = u.id"); |
query.append(" where p.id = ?"); |
stmt = SQLUtils.prepare(conn, query.toString(), p.getId()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
session.populateBean(rset, p, "p"); |
u = new User(); |
session.populateBean(rset, u, "u"); |
p.setUser(u); // manual lazy loading (we prefer to have control!) |
} |
Assert.assertEquals(1, p.getId()); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", p.getUser().getUsername()); |
Assert.assertTrue((new Date()).getTime() >= p.getInsertTime().getTime()); |
rset.close(); |
stmt.close(); |
// Deleting => No cascade deletes, if you want that implement in the database level... |
u = new User(1); |
boolean deleted = session.delete(u); |
Assert.assertEquals(true, deleted); |
// Post of course is still there... |
p = new Post(1); |
loaded = session.load(p); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(1, p.getUser().getId()); // of course this user is gone! |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(false, loaded); // use was deleted above... |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testOneToOneRelationshipCRUDWithTableAlias() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
getPostBeanConfig(beanManager); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User u = new User("saoj", "1980-01-02"); |
session.insert(u); |
Assert.assertEquals(1, u.getId()); |
// Now insert a post for this user... |
Post p = new Post(new User(1), "Test", "This is a test!"); |
session.insert(p); |
Assert.assertEquals(1, p.getId()); |
// Load from the database... |
p = new Post(1); |
boolean loaded = session.load(p); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNotNull(p.getUser()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNull(p.getUser().getUsername()); |
// Load user for this post... (let's do our manual lazy loading) |
u = new User(p.getUser().getId()); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
p.setUser(u); // manual lazy loading (forget about automatic lazy loading, you want control!) |
// Use JOIN to load all dependencies with a single query... (you know how to make a join, right?) |
p = new Post(1); |
TableAlias<Post> postAlias = session.createTableAlias(Post.class, "p"); |
TableAlias<User> userAlias = session.createTableAlias(User.class, "u"); |
StringBuilder query = new StringBuilder(256); |
query.append("select "); |
query.append(postAlias.columns()); |
query.append(", "); |
query.append(userAlias.columns()); |
query.append(" from ").append(postAlias.tableName()); |
query.append(" join ").append(userAlias.tableName()); |
query.append(" on "); |
query.append(postAlias.column(postAlias.pxy().getUser().getId())).append(" = ").append(userAlias.column(userAlias.pxy().getId())); |
query.append(" where "); |
query.append(postAlias.column(postAlias.pxy().getId())); |
query.append(" = ?"); |
stmt = SQLUtils.prepare(conn, query.toString(), p.getId()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
session.populateBean(rset, p, "p"); |
u = new User(); |
session.populateBean(rset, u, "u"); |
p.setUser(u); // manual lazy loading (we prefer to have control!) |
} |
Assert.assertEquals(1, p.getId()); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", p.getUser().getUsername()); |
Assert.assertTrue((new Date()).getTime() >= p.getInsertTime().getTime()); |
rset.close(); |
stmt.close(); |
// Deleting => No cascade deletes, if you want that implement in the database level... |
u = new User(1); |
boolean deleted = session.delete(u); |
Assert.assertEquals(true, deleted); |
// Post of course is still there... |
p = new Post(1); |
loaded = session.load(p); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(1, p.getUser().getId()); // of course this user is gone! |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(false, loaded); // use was deleted above... |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testSQLBuilder() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
getPostBeanConfig(beanManager); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User u = new User("saoj", "1980-01-02"); |
session.insert(u); |
Assert.assertEquals(1, u.getId()); |
// Now insert a post for this user... |
Post p = new Post(new User(1), "Test", "This is a test!"); |
session.insert(p); |
Assert.assertEquals(1, p.getId()); |
// Load from the database... |
p = new Post(1); |
boolean loaded = session.load(p); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNotNull(p.getUser()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNull(p.getUser().getUsername()); |
// Load user for this post... (let's do our manual lazy loading) |
u = new User(p.getUser().getId()); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
p.setUser(u); // manual lazy loading (forget about automatic lazy loading, you want control!) |
// Use JOIN to load all dependencies with a single query... (you know how to make a join, right?) |
p = new Post(1); |
TableAlias<Post> postAlias = session.createTableAlias(Post.class, "p"); |
TableAlias<User> userAlias = session.createTableAlias(User.class, "u"); |
Post post = postAlias.pxy(); |
User user = userAlias.pxy(); |
SQLBuilder query = new SQLBuilder(256, postAlias, userAlias); |
query.append("select "); |
query.append(postAlias.columns()); |
query.append(", "); |
query.append(userAlias.columns()); |
query.append(" from ").append(postAlias.tableName()); |
query.append(" join ").append(userAlias.tableName()); |
query.append(" on "); |
// query.append(postAlias.column(postAlias.pxy().getUser().getId())).append(" = ").append(userAlias.column(userAlias.pxy().getId())); |
query.column(post.getUser().getId()).append(" = ").column(user.getId()); |
query.append(" where "); |
// query.append(postAlias.column(postAlias.pxy().getId())); |
query.column(post.getId()); |
query.append(" = ?"); |
stmt = SQLUtils.prepare(conn, query.toString(), p.getId()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
session.populateBean(rset, p, "p"); |
u = new User(); |
session.populateBean(rset, u, "u"); |
p.setUser(u); // manual lazy loading (we prefer to have control!) |
} |
Assert.assertEquals(1, p.getId()); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", p.getUser().getUsername()); |
Assert.assertTrue((new Date()).getTime() >= p.getInsertTime().getTime()); |
rset.close(); |
stmt.close(); |
// Deleting => No cascade deletes, if you want that implement in the database level... |
u = new User(1); |
boolean deleted = session.delete(u); |
Assert.assertEquals(true, deleted); |
// Post of course is still there... |
p = new Post(1); |
loaded = session.load(p); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(1, p.getUser().getId()); // of course this user is gone! |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(false, loaded); // use was deleted above... |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testSQLBuilder2() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
getPostBeanConfig(beanManager); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User u = new User("saoj", "1980-01-02"); |
session.insert(u); |
Assert.assertEquals(1, u.getId()); |
// Now insert a post for this user... |
Post p = new Post(new User(1), "Test", "This is a test!"); |
session.insert(p); |
Assert.assertEquals(1, p.getId()); |
// Load from the database... |
p = new Post(1); |
boolean loaded = session.load(p); |
Assert.assertEquals("Test", p.getTitle()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNotNull(p.getUser()); |
Assert.assertEquals(1, p.getUser().getId()); |
Assert.assertNull(p.getUser().getUsername()); |
// Load user for this post... (let's do our manual lazy loading) |
u = new User(p.getUser().getId()); |
loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
p.setUser(u); // manual lazy loading (forget about automatic lazy loading, you want control!) |
// Use JOIN to load all dependencies with a single query... (you know how to make a join, right?) |
p = new Post(1); |
TableAlias<Post> postAlias = session.createTableAlias(Post.class, "p"); |
TableAlias<User> userAlias = session.createTableAlias(User.class, "u"); |
Post post = postAlias.pxy(); |
User user = userAlias.pxy(); |
SQLBuilder query = new SQLBuilder(256, postAlias, userAlias); |
query.append("select "); |
query.append(postAlias.columnsMinus(post.getTitle())); |
query.append(", "); |
query.append(userAlias.columns()); |
query.append(" from ").append(postAlias.tableName()); |
query.append(" join ").append(userAlias.tableName()); |
query.append(" on "); |
// query.append(postAlias.column(postAlias.pxy().getUser().getId())).append(" = ").append(userAlias.column(userAlias.pxy().getId())); |
query.column(post.getUser().getId()).append(" = ").column(user.getId()); |
query.append(" where "); |
// query.append(postAlias.column(postAlias.pxy().getId())); |
query.column(post.getId()); |
query.append(" = ?"); |
stmt = SQLUtils.prepare(conn, query.toString(), p.getId()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
//XXX aqui daria erro pois a session não vai conseguir popular p_title |
//É por isso que o Alias do QueryBuilder tem o seu próprio populateBean, |
//pois ele já sabe quais propriedades foram informadas.. |
//session.populateBean(rset, p, "p"); |
//XXX "minus" repetitivo... |
session.populateBeanMinus(rset, p, "p", post.getTitle()); |
//possível solução.. fazer um populateBean no TableAlias que já pegasse |
//o prefix e também as properties que devem retornar |
//algo como: |
//postAlias.populateBean(rset, p); |
u = new User(); |
session.populateBean(rset, u, "u"); |
p.setUser(u); // manual lazy loading (we prefer to have control!) |
} |
Assert.assertEquals(1, p.getId()); |
Assert.assertNull(p.getTitle()); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", p.getUser().getUsername()); |
Assert.assertTrue((new Date()).getTime() >= p.getInsertTime().getTime()); |
rset.close(); |
stmt.close(); |
// Deleting => No cascade deletes, if you want that implement in the database level... |
u = new User(1); |
boolean deleted = session.delete(u); |
Assert.assertEquals(true, deleted); |
// Post of course is still there... |
p = new Post(1); |
loaded = session.load(p); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(1, p.getUser().getId()); // of course this user is gone! |
u = new User(1); |
loaded = session.load(u); |
Assert.assertEquals(false, loaded); // use was deleted above... |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testSQLBuilder3() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
getPostBeanConfig(beanManager); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User u = new User("erico", "1991-01-31"); |
session.insert(u); |
TableAlias<User> userAlias1 = session.createTableAlias(User.class, "u"); |
TableAlias<User> userAlias2 = session.createTableAlias(User.class, "u2"); |
User user1 = userAlias1.pxy(); |
User user2 = userAlias2.pxy(); |
SQLBuilder query = new SQLBuilder(userAlias1, userAlias2); |
query.append("select "); |
query.append(userAlias1.columns()); |
query.append(" from ").append(userAlias1.tableName()); |
query.append(" where ").column(user1.getId()); |
query.append(" in (select ").column(user2.getId()); |
query.append(" from ").append(userAlias2.tableName()); |
query.append(")"); |
Assert.assertTrue(query.toString().contains("(select u2.id")); |
stmt = SQLUtils.prepare(conn, query.toString()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
u = new User(); |
session.populateBean(rset, u, "u"); |
} |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("erico", u.getUsername()); |
} finally { |
close(stmt); |
close(conn); |
} |
} |
@Test |
public void testLoadUnique() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User u1 = new User("saoj", "1983-01-02"); |
session.insert(u1); |
User u = new User(); |
u.setUsername("saoj"); |
u = session.loadUnique(u); |
Assert.assertEquals(1, u.getId()); |
Assert.assertEquals("saoj", u.getUsername()); |
// now add another one and try again... |
User u2 = new User("saoj", "1967-01-03"); |
session.insert(u2); |
u = new User(); |
u.setUsername("saoj"); |
boolean ok = false; |
try { |
u = session.loadUnique(u); |
ok = true; // cannot come here... |
} catch (BeanException e) { |
ok = false; |
} |
Assert.assertEquals(false, ok); |
//loadUnique specifying properties |
u = new User(); |
u.setBirthdate("1967-01-03"); |
User proxy = PropertiesProxy.create(User.class); |
u = session.loadUnique(u, proxy.getUsername()); //only username |
Assert.assertNull(u.getBirthdate()); |
Assert.assertNull(u.getInsertTime()); |
Assert.assertNull(u.getStatus()); |
Assert.assertEquals(2, u.getId()); //always load the pk |
Assert.assertNotNull(u.getUsername()); |
//loadUnique specifying 'minus' properties |
u = new User(); |
u.setBirthdate("1967-01-03"); |
u = session.loadUniqueMinus(u, proxy.getUsername(), proxy.getId()); //not load username nor pk (mentabean must ignore this) |
Assert.assertNotNull(u.getBirthdate()); |
Assert.assertNotNull(u.getInsertTime()); |
Assert.assertNotNull(u.getStatus()); |
Assert.assertEquals(2, u.getId()); //always load the pk... I mean, always |
Assert.assertNull(u.getUsername()); |
} finally { |
close(conn); |
} |
} |
@Test |
public void testSettingProperties() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUserBeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
createTables(conn); |
User saoj = new User("saoj", "1980-01-01"); |
session.insert(saoj); |
User julia = new User("julia", "1980-03-03"); |
session.insert(julia); |
// delete "saoj" by making deleted equals to false |
saoj.setDeleted(true); |
int modified = session.update(saoj); |
Assert.assertEquals(1, modified); |
// load all non-deleted users... |
User u = new User(); |
u.setStatus(User.Status.BASIC); |
u.setDeleted(false); |
List<User> nonDeletedUsers = session.loadList(u); |
Assert.assertFalse(nonDeletedUsers.size() == 1); // THIS DOES NOT WORK because isDeleted() returns a boolean primitive |
Assert.assertEquals(2, nonDeletedUsers.size()); // it will return everything because the deleted = false condition was never detected |
// to fix, let's change the property to return a Boolean |
beanManager.addBeanConfig(getUser2BeanConfig()); |
// now try again |
User2 u2 = new User2(); |
u2.setDeleted(false); |
List<User2> nonDeletedUsers2 = session.loadList(u2); |
Assert.assertEquals(1, nonDeletedUsers2.size()); // now only ONE is returned, the non-deleted one... |
} finally { |
close(conn); |
} |
} |
private static class User2 { |
public static enum Status { |
BASIC, PREMIUM, GOLD |
} |
private int id; |
private String username; |
private Date birthdate; |
private Status status = Status.BASIC; |
private boolean deleted; |
private Date insertTime; |
public User2() { |
} |
public User2(int id) { |
this.id = id; |
} |
public User2(String username, String birthdate) { |
this.username = username; |
this.birthdate = fromString(birthdate); |
} |
private static Date fromString(String date) { |
try { |
return BD_FORMATTER.parse(date); |
} catch (Exception e) { |
throw new IllegalArgumentException("Cannot parse date: " + date); |
} |
} |
public void setBirthdate(String date) { |
setBirthdate(fromString(date)); |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this.username = username; |
} |
public Date getBirthdate() { |
return birthdate; |
} |
public void setBirthdate(Date birthdate) { |
this.birthdate = birthdate; |
} |
public Boolean isDeleted() { |
return deleted; |
} |
public void setDeleted(boolean deleted) { |
this.deleted = deleted; |
} |
public Date getInsertTime() { |
return insertTime; |
} |
public void setInsertTime(Date insertTime) { |
this.insertTime = insertTime; |
} |
public void setStatus(Status status) { |
this.status = status; |
} |
public Status getStatus() { |
return status; |
} |
} |
private BeanConfig getUser2BeanConfig() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanConfig config = new BeanConfig(User2.class, "Users"); |
config.pk("id", DBTypes.AUTOINCREMENT); |
config.field("username", DBTypes.STRING); |
config.field("birthdate", "bd", DBTypes.DATE); // note that the database column name is different |
config.field("status", DBTypes.ENUMVALUE.from(User2.Status.class)); |
config.field("deleted", DBTypes.BOOLEANINT); |
config.field("insertTime", "insert_time", DBTypes.NOW_ON_INSERT_TIMESTAMP); |
return config; |
} |
@Test |
public void testEnumIdType() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUser3BeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
execUpdate(conn, "create table Users(id integer primary key auto_increment, username varchar(25), bd datetime, status integer, deleted tinyint, insert_time timestamp)"); |
User3 u = new User3("saoj", "1980-03-03"); |
u.setStatus(User3.Status.GOLD); |
session.insert(u); |
// now load and see if we get the same status... |
u = new User3(1); |
boolean loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(User3.Status.GOLD, u.getStatus()); |
} finally { |
close(conn); |
} |
} |
private static class User3 { |
public static enum Status { |
BASIC(1), PREMIUM(2), GOLD(3); |
private final int id; |
private Status(int id) { |
this.id = id; |
} |
public int getId() { |
return id; |
} |
public static Status fromId(int id) { |
for (Status s : Status.values()) { |
if (s.getId() == id) { |
return s; |
} |
} |
return null; |
} |
} |
private int id; |
private String username; |
private Date birthdate; |
private Status status = Status.BASIC; |
private boolean deleted; |
private Date insertTime; |
public User3() { |
} |
public User3(int id) { |
this.id = id; |
} |
public User3(String username, String birthdate) { |
this.username = username; |
this.birthdate = fromString(birthdate); |
} |
private static Date fromString(String date) { |
try { |
return BD_FORMATTER.parse(date); |
} catch (Exception e) { |
throw new IllegalArgumentException("Cannot parse date: " + date); |
} |
} |
public void setBirthdate(String date) { |
setBirthdate(fromString(date)); |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this.username = username; |
} |
public Date getBirthdate() { |
return birthdate; |
} |
public void setBirthdate(Date birthdate) { |
this.birthdate = birthdate; |
} |
public Boolean isDeleted() { |
return deleted; |
} |
public void setDeleted(boolean deleted) { |
this.deleted = deleted; |
} |
public Date getInsertTime() { |
return insertTime; |
} |
public void setInsertTime(Date insertTime) { |
this.insertTime = insertTime; |
} |
public void setStatus(Status status) { |
this.status = status; |
} |
public Status getStatus() { |
return status; |
} |
} |
private BeanConfig getUser3BeanConfig() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanConfig config = new BeanConfig(User3.class, "Users"); |
config.pk("id", DBTypes.AUTOINCREMENT); |
config.field("username", DBTypes.STRING); |
config.field("birthdate", "bd", DBTypes.DATE); // note that the database column name is different |
config.field("status", new EnumIdType(User3.Status.class)); |
config.field("deleted", DBTypes.BOOLEANINT); |
config.field("insertTime", "insert_time", DBTypes.NOW_ON_INSERT_TIMESTAMP); |
return config; |
} |
@Test |
public void testCreateTable() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUser4BeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
Assert.assertFalse(SQLUtils.checkIfTableExists(conn, "Users")); |
session.createTables(); |
Assert.assertTrue(SQLUtils.checkIfTableExists(conn, "Users")); |
} finally { |
close(conn); |
} |
} |
@Test |
public void testAutoBeanConfig() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = new AutoBeanConfig(User4.class, "Users"); |
beanManager.addBeanConfig(userConfig); |
userConfig.pk("id", DBTypes.AUTOINCREMENT); // override since PK and autoincrement cannot be discovered by reflection... |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
// execUpdate(conn, "create table Users(id integer primary key auto_increment, username varchar(25), birthdate datetime, status integer, deleted tinyint, insert_time timestamp, update_time timestamp)"); |
session.createTables(); |
User4 u = new User4("saoj", "1980-03-03"); |
u.setStatus(User4.Status.GOLD); |
session.insert(u); |
// now load and see if we get the same status... |
u = new User4(1); |
boolean loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(User4.Status.GOLD, u.getStatus()); |
// update_time must be null |
Assert.assertNull(u.getUpdateTime()); |
} finally { |
close(conn); |
} |
} |
@Test |
public void testNowOnUpdate() throws SQLException { |
BeanManager beanManager = new BeanManager(); |
BeanConfig userConfig = getUser4BeanConfig(); |
beanManager.addBeanConfig(userConfig); |
Connection conn = null; |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
execUpdate(conn, "create table Users(id integer primary key auto_increment, username varchar(25), bd datetime, status integer, deleted tinyint, insert_time timestamp, update_time timestamp)"); |
User4 u = new User4("saoj", "1980-03-03"); |
u.setStatus(User4.Status.GOLD); |
session.insert(u); |
// now load and see if we get the same status... |
u = new User4(1); |
boolean loaded = session.load(u); |
Assert.assertEquals(true, loaded); |
Assert.assertEquals(User4.Status.GOLD, u.getStatus()); |
// update_time must be null |
Assert.assertNull(u.getUpdateTime()); |
// now update.. |
u.setUsername("saoj1"); |
session.update(u); |
// update_time is still null, you need to load !!! |
Assert.assertNull(u.getUpdateTime()); |
session.load(u); |
Assert.assertNotNull(u.getUpdateTime()); |
} finally { |
close(conn); |
} |
} |
private static class User4 { |
public static enum Status { |
BASIC(1), PREMIUM(2), GOLD(3); |
private final int id; |
private Status(int id) { |
this.id = id; |
} |
public int getId() { |
return id; |
} |
public static Status fromId(int id) { |
for (Status s : Status.values()) { |
if (s.getId() == id) { |
return s; |
} |
} |
return null; |
} |
} |
private int id; |
private String username; |
private Date birthdate; |
private Status status = Status.BASIC; |
private boolean deleted; |
private Date insertTime; |
private Date updateTime; |
public Date getUpdateTime() { |
return updateTime; |
} |
public void setUpdateTime(Date updateTime) { |
this.updateTime = updateTime; |
} |
public User4() { |
} |
public User4(int id) { |
this.id = id; |
} |
public User4(String username, String birthdate) { |
this.username = username; |
this.birthdate = fromString(birthdate); |
} |
private static Date fromString(String date) { |
try { |
return BD_FORMATTER.parse(date); |
} catch (Exception e) { |
throw new IllegalArgumentException("Cannot parse date: " + date); |
} |
} |
public void setBirthdate(String date) { |
setBirthdate(fromString(date)); |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this.username = username; |
} |
public Date getBirthdate() { |
return birthdate; |
} |
public void setBirthdate(Date birthdate) { |
this.birthdate = birthdate; |
} |
public Boolean isDeleted() { |
return deleted; |
} |
public void setDeleted(boolean deleted) { |
this.deleted = deleted; |
} |
public Date getInsertTime() { |
return insertTime; |
} |
public void setInsertTime(Date insertTime) { |
this.insertTime = insertTime; |
} |
public void setStatus(Status status) { |
this.status = status; |
} |
public Status getStatus() { |
return status; |
} |
} |
private BeanConfig getUser4BeanConfig() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanConfig config = new BeanConfig(User4.class, "Users"); |
config.pk("id", DBTypes.AUTOINCREMENT); |
config.field("username", DBTypes.STRING.size(50).nullable(false)); |
config.field("birthdate", "bd", DBTypes.DATE); // note that the database column name is different |
config.field("status", new EnumIdType(User4.Status.class)); |
config.field("deleted", DBTypes.BOOLEANINT); |
config.field("insertTime", "insert_time", DBTypes.NOW_ON_INSERT_TIMESTAMP); |
config.field("updateTime", "update_time", DBTypes.NOW_ON_UPDATE_TIMESTAMP); |
return config; |
} |
/* |
* Testing sublevels |
*/ |
public static class Foo { |
private long id; |
private Bar bar; |
private String test; |
private Bean bean; |
public Foo() {} |
public Foo(long id, String test, Bean bean) { |
super(); |
this.id = id; |
this.test = test; |
this.bean = bean; |
} |
public Foo(long id) { |
this.id = id; |
} |
public long getId() { |
return id; |
} |
public void setId(long id) { |
this.id = id; |
} |
public Bar getBar() { |
return bar; |
} |
public void setBar(Bar bar) { |
this.bar = bar; |
} |
public String getTest() { |
return test; |
} |
public void setTest(String test) { |
this.test = test; |
} |
public Bean getBean() { |
return bean; |
} |
public void setBean(Bean bean) { |
this.bean = bean; |
} |
} |
public static class Bean { |
private long id; |
public Bean(long id) { |
this.id = id; |
} |
public Bean() {} |
public long getId() { |
return id; |
} |
public void setId(long id) { |
this.id = id; |
} |
@Override |
public String toString() { |
return "Bean: "+id; |
} |
} |
public static class Bar { |
private String name; |
private Item item; |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public Item getItem() { |
return item; |
} |
public void setItem(Item item) { |
this.item = item; |
} |
} |
public static class Item { |
private SubItem subItem; |
public SubItem getSubItem() { |
return subItem; |
} |
public void setSubItem(SubItem subItem) { |
this.subItem = subItem; |
} |
} |
public static class SubItem { |
private String name; |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
} |
private BeanConfig getSublevelsBeanConfig() { |
Foo foo = PropertiesProxy.create(Foo.class); |
BeanConfig config = new BeanConfig(Foo.class, "foo") |
.pk(foo.getId(), "idfoo", DBTypes.LONG) |
.field(foo.getTest(), DBTypes.STRING) |
.field(foo.getBean().getId(), "idbean", DBTypes.LONG) |
.field(foo.getBar().getItem().getSubItem().getName(), "namebar", DBTypes.STRING); |
return config; |
} |
private Foo createEmptyFoo() { |
Foo foo = new Foo(); |
foo.setBar(new Bar()); |
foo.getBar().setItem(new Item()); |
foo.getBar().getItem().setSubItem(new SubItem()); |
return foo; |
} |
@Test |
public void testSublevels() { |
Connection conn = null; |
BeanManager beanManager = new BeanManager(); |
beanManager.addBeanConfig(getSublevelsBeanConfig()); |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
session.createTables(); |
Foo foo = createEmptyFoo(); |
foo.getBar().getItem().getSubItem().setName("Test one"); |
foo.setId(1); |
foo.setTest("Test one"); |
session.insert(foo); |
foo.getBar().getItem().getSubItem().setName("Test two"); |
foo.setId(2); |
foo.setTest("Test two"); |
session.insert(foo); |
foo.setId(0); |
foo.setTest(null); |
int count = session.countList(foo); |
Assert.assertEquals(1, count); |
//here, if we don't force the creation of instances, a NPE will thrown |
//getDeepestBean(bean, chain, true); --> findMethodToGet |
count = session.countList(new Foo()); |
Assert.assertEquals(2, count); |
foo = createEmptyFoo(); |
foo.setId(1); |
foo.setTest("Test three"); |
session.update(foo); |
Foo fooBD = new Foo(); |
fooBD.setId(1); |
session.load(fooBD); |
Assert.assertEquals("Test one", fooBD.getBar().getItem().getSubItem().getName()); |
Assert.assertEquals("Test three", fooBD.getTest()); |
foo = new Foo(); |
foo.setId(1); |
foo.setTest("Test four"); |
session.update(foo); |
fooBD = new Foo(); |
fooBD.setId(1); |
session.load(fooBD); |
Assert.assertEquals("Test one", fooBD.getBar().getItem().getSubItem().getName()); |
Assert.assertEquals("Test four", fooBD.getTest()); |
Foo proto = new Foo(); |
List<Foo> listBD = session.loadList(proto); |
Assert.assertEquals(2, listBD.size()); |
Assert.assertNull(listBD.get(0).getBean()); |
Assert.assertNull(listBD.get(1).getBean()); |
Foo proxy = PropertiesProxy.create(Foo.class); |
foo = new Foo(1); |
foo.setTest("Test five"); |
foo.setBean(new Bean()); |
foo.getBean().setId(3); |
session.update(foo, proxy.getBean().getId()); |
session.load(fooBD = new Foo(1)); |
Assert.assertEquals("Test five", fooBD.getTest()); |
Assert.assertEquals(3, fooBD.getBean().getId()); |
foo = new Foo(1); |
//forcing bean to null |
session.update(foo, proxy.getBean().getId()); |
session.load(fooBD = new Foo(1)); |
Assert.assertNull(fooBD.getBean()); |
Assert.assertNotNull(fooBD.getBar().getItem().getSubItem().getName()); |
foo = new Foo(1); |
session.update(foo, proxy.getBean().getId(), proxy.getBar().getItem().getSubItem().getName()); |
session.load(fooBD = new Foo(1)); |
Assert.assertNull(fooBD.getBean()); |
Assert.assertNull(fooBD.getBar()); |
foo = createEmptyFoo(); |
foo.setId(1); |
foo.getBar().getItem().getSubItem().setName("Not null"); |
session.update(foo, proxy.getBar().getItem().getSubItem().getName()); |
session.load(fooBD = new Foo(1)); |
Assert.assertNull(fooBD.getBean()); |
Assert.assertEquals("Not null", fooBD.getBar().getItem().getSubItem().getName()); |
foo = createEmptyFoo(); |
foo.setId(1); |
session.update(foo, proxy.getBar().getItem().getSubItem().getName()); |
session.load(fooBD = new Foo(1)); |
Assert.assertNull(fooBD.getBar()); |
/* |
* testing using attached update |
*/ |
foo = createEmptyFoo(); |
foo.setId(5); |
foo.setTest("Attached test"); |
foo.setBean(new Bean()); |
foo.getBean().setId(5); |
foo.getBar().getItem().getSubItem().setName("Anything"); |
session.insert(foo); |
fooBD = new Foo(foo.getId()); |
session.load(fooBD); |
fooBD.setTest("Attached test - updated"); |
session.update(fooBD); |
session.load(fooBD); |
Assert.assertEquals("Attached test - updated", fooBD.getTest()); |
Assert.assertNotNull(fooBD.getBean()); |
Assert.assertNotNull(fooBD.getBar()); |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(conn); |
} |
} |
private BeanManager getNullFKsManager() { |
BeanManager manager = new BeanManager(); |
Foo fooPxy = PropertiesProxy.create(Foo.class); |
BeanConfig fooConfig = new BeanConfig(Foo.class, "foo") |
.pk(fooPxy.getId(), "idfoo", DBTypes.LONG) |
.field(fooPxy.getBean().getId(), "idbean", DBTypes.LONG) |
.field(fooPxy.getTest(), DBTypes.STRING); |
manager.addBeanConfig(fooConfig); |
Bean barPxy = PropertiesProxy.create(Bean.class); |
BeanConfig beanConfig = new BeanConfig(Bean.class, "bean") |
.pk(barPxy.getId(), DBTypes.LONG); |
manager.addBeanConfig(beanConfig); |
return manager; |
} |
@Test |
public void testNullFKs() { |
Connection conn = null; |
BeanManager beanManager = getNullFKsManager(); |
try { |
conn = getConnection(); |
BeanSession session = new H2BeanSession(beanManager, conn); |
session.createTables(); |
SQLUtils.prepare(conn, "alter table foo add foreign key(idbean) references bean"); |
Bean bean = new Bean(1); |
session.insert(bean); |
Foo foo = new Foo(1, "Foo UM", bean); |
session.insert(foo); |
foo = new Foo(2, "Foo DOIS", null); |
session.insert(foo); |
Foo fooBD = new Foo(2); |
session.load(fooBD); |
Assert.assertNull(fooBD.getBean()); |
fooBD.setTest("Foo DOIS - updated"); |
session.update(fooBD); |
session.load(fooBD = new Foo(2)); |
Assert.assertEquals("Foo DOIS - updated", fooBD.getTest()); |
Assert.assertNull(fooBD.getBean()); |
fooBD = new Foo(1); |
session.load(fooBD); |
Assert.assertNotNull(fooBD.getBean()); |
Assert.assertEquals(1, fooBD.getBean().getId()); |
fooBD.setTest(null); |
session.update(fooBD); |
session.load(fooBD = new Foo(1)); |
Assert.assertNull(fooBD.getTest()); |
fooBD.setBean(null); |
fooBD.setTest("Foo UM"); |
session.update(fooBD); |
session.load(fooBD = new Foo(1)); |
Assert.assertEquals("Foo UM", fooBD.getTest()); |
Assert.assertNull(fooBD.getBean()); |
fooBD.setTest("Foo UM - alterado"); |
session.update(fooBD); |
session.load(fooBD = new Foo(1)); |
Assert.assertEquals("Foo UM - alterado", fooBD.getTest()); |
Assert.assertNull(fooBD.getBean()); |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(conn); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/RecursivePropertiesTest.java |
---|
New file |
0,0 → 1,1026 |
package org.mentabean.jdbc; |
import static org.mentabean.jdbc.AnsiSQLBeanSession.DEBUG; |
import static org.mentabean.util.SQLUtils.lim; |
import static org.mentabean.util.SQLUtils.orderByAsc; |
import java.math.BigDecimal; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.List; |
import junit.framework.Assert; |
import org.junit.BeforeClass; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.jdbc.QueryBuilder.Alias; |
import org.mentabean.jdbc.QueryBuilder.Query; |
import org.mentabean.sql.conditions.GreaterThan; |
import org.mentabean.sql.conditions.Like; |
import org.mentabean.sql.functions.Coalesce; |
import org.mentabean.sql.functions.Lower; |
import org.mentabean.sql.param.ParamField; |
import org.mentabean.sql.param.ParamFunction; |
import org.mentabean.sql.param.ParamValue; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLUtils; |
public class RecursivePropertiesTest extends AbstractBeanSessionTest { |
public static class Post { |
private int id; |
private String title; |
private User user; |
public Post() { |
} |
public Post(int id) { |
this.id = id; |
} |
public Post(String title, User user) { |
this.title = title; |
this.user = user; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getTitle() { |
return title; |
} |
public void setTitle(String title) { |
this.title = title; |
} |
public User getUser() { |
return user; |
} |
public void setUser(User user) { |
this.user = user; |
} |
} |
public static class User { |
private int id; |
private String username; |
private Address address; |
public User() { |
} |
public User(int id) { |
this.id = id; |
} |
public User(String username, Address addr) { |
this.username = username; |
this.address = addr; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public Address getAddress() { |
return address; |
} |
public void setAddress(Address address) { |
this.address = address; |
} |
public String getUsername() { |
return username; |
} |
public void setUsername(String username) { |
this.username = username; |
} |
} |
public static class Address { |
private int id; |
private City city; |
public Address() { |
} |
public Address(int id) { |
this.id = id; |
} |
public Address(City city) { |
this.city = city; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public City getCity() { |
return city; |
} |
public void setCity(City city) { |
this.city = city; |
} |
} |
public static class City { |
private int id; |
private String name; |
public City() { |
} |
public City(int id) { |
this.id = id; |
} |
public City(int id, String name) { |
this.id = id; |
this.name = name; |
} |
public City(String name) { |
this.name = name; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
} |
@BeforeClass |
public static void setup() { |
DEBUG = false; // turn on to see SQL generated |
} |
private BeanManager getBeanManager1() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanManager beanManager = new BeanManager(); |
BeanConfig postConfig = new BeanConfig(Post.class, "Posts"); |
postConfig.pk("id", DBTypes.AUTOINCREMENT); |
postConfig.field("title", DBTypes.STRING); |
postConfig.field("user.id", "user_id", DBTypes.INTEGER); // note that the database column name is different |
beanManager.addBeanConfig(postConfig); |
BeanConfig userConfig = new BeanConfig(User.class, "Users"); |
userConfig.pk("id", DBTypes.AUTOINCREMENT); |
userConfig.field("username", DBTypes.STRING); |
userConfig.field("address.id", "address_id", DBTypes.INTEGER); |
beanManager.addBeanConfig(userConfig); |
BeanConfig addressConfig = new BeanConfig(Address.class, "Addresses"); |
addressConfig.pk("id", DBTypes.AUTOINCREMENT); |
addressConfig.field("city.id", "city_id", DBTypes.INTEGER); |
beanManager.addBeanConfig(addressConfig); |
BeanConfig cityConfig = new BeanConfig(City.class, "Cities"); |
cityConfig.pk("id", DBTypes.INTEGER); |
cityConfig.field("name", DBTypes.STRING); |
beanManager.addBeanConfig(cityConfig); |
return beanManager; |
} |
@Test |
public void testTwoLevels() throws SQLException { |
BeanManager beanManager = getBeanManager1(); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
// createTables1(conn); |
BeanSession session = new H2BeanSession(beanManager, conn); |
session.createTables(); |
// first insert... |
City rj = new City(1, "Rio de Janeiro"); |
City chi = new City(2, "Chicago"); |
session.insert(rj); |
session.insert(chi); |
Address addr1 = new Address(rj); |
Address addr2 = new Address(chi); |
session.insert(addr1); |
session.insert(addr2); |
User user1 = new User("saoj", addr1); |
User user2 = new User("julia", addr2); |
session.insert(user1); |
session.insert(user2); |
Post post1 = new Post("Title1", user1); |
session.insert(post1); |
// now load and test; |
City c1 = new City(1); |
session.load(c1); |
Assert.assertEquals(c1.getId(), rj.getId()); |
Assert.assertEquals(c1.getName(), rj.getName()); |
Address a1 = new Address(1); |
session.load(a1); |
Assert.assertEquals(a1.getId(), addr1.getId()); |
Assert.assertEquals(a1.getCity().getId(), addr1.getCity().getId()); |
User u1 = new User(1); |
session.load(u1); |
Assert.assertEquals(u1.getId(), user1.getId()); |
Assert.assertEquals(u1.getUsername(), user1.getUsername()); |
Assert.assertEquals(u1.getAddress().getId(), user1.getAddress().getId()); |
// now above the second level will be null due to lazy loading: |
Assert.assertEquals(u1.getAddress().getCity(), null); |
// let's test this again: |
Post p1 = new Post(1); |
session.load(p1); |
Assert.assertEquals(p1.getId(), post1.getId()); |
Assert.assertEquals(p1.getUser().getId(), post1.getUser().getId()); |
// but the only thing the user object has is the ID... everything else is null (lazy loading) |
Assert.assertEquals(p1.getUser().getUsername(), null); |
// when you need the user of the post, you can manually load it: |
session.load(p1.getUser()); // manual lazy loading! |
Assert.assertEquals(p1.getUser().getUsername(), post1.getUser().getUsername()); |
// now update! |
// change the user of post1 |
post1.setUser(user2); |
session.update(post1); |
Post updatedPost = new Post(1); |
session.load(updatedPost); |
Assert.assertEquals(post1.getId(), updatedPost.getId()); |
Assert.assertEquals(post1.getTitle(), updatedPost.getTitle()); |
Assert.assertEquals(post1.getUser().getId(), updatedPost.getUser().getId()); |
// load list: |
Post post2 = new Post("Title2", user1); |
session.insert(post2); |
Post post3 = new Post("Title3", user2); |
session.insert(post3); |
// we should have two posts for user2 now: (remember the first one was updated to user2) |
Post p = new Post(); |
p.setUser(user2); |
List<Post> posts = session.loadList(p); |
Assert.assertEquals(posts.size(), 2); |
int beansDeleted = session.deleteAll(p); |
Assert.assertEquals(2, beansDeleted); |
p.setUser(user1); |
posts = session.loadList(p); |
Assert.assertEquals(posts.size(), 1); |
beansDeleted = session.deleteAll(p); |
Assert.assertEquals(1, beansDeleted); |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
private BeanManager getBeanManager2() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanManager beanManager = new BeanManager(); |
Post postProps = PropertiesProxy.create(Post.class); |
BeanConfig postConfig = new BeanConfig(Post.class, "Posts"); |
postConfig.pk(postProps.getId(), DBTypes.AUTOINCREMENT); |
postConfig.field(postProps.getTitle(), DBTypes.STRING); |
postConfig.field(postProps.getUser().getId(), "user_id", DBTypes.INTEGER); // note that the database column name is different |
postConfig.field(postProps.getUser().getAddress().getId(), "address_id", DBTypes.INTEGER); |
beanManager.addBeanConfig(postConfig); |
User userProps = PropertiesProxy.create(User.class); |
BeanConfig userConfig = new BeanConfig(User.class, "Users"); |
userConfig.pk(userProps.getId(), DBTypes.AUTOINCREMENT); |
userConfig.field("username", DBTypes.STRING); |
userConfig.field("address.id", "address_id", DBTypes.INTEGER); |
beanManager.addBeanConfig(userConfig); |
Address addressProps = PropertiesProxy.create(Address.class); |
BeanConfig addressConfig = new BeanConfig(Address.class, "Addresses"); |
addressConfig.pk("id", DBTypes.AUTOINCREMENT); |
addressConfig.field(addressProps.getCity().getId(), "city_id", DBTypes.INTEGER); |
beanManager.addBeanConfig(addressConfig); |
BeanConfig cityConfig = new BeanConfig(City.class, "Cities"); |
cityConfig.pk("id", DBTypes.INTEGER); |
cityConfig.field("name", DBTypes.STRING); |
beanManager.addBeanConfig(cityConfig); |
return beanManager; |
} |
@Test |
public void testThreeLevels() throws SQLException { |
BeanManager beanManager = getBeanManager2(); |
Connection conn = null; |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
conn = getConnection(); |
// createTables2(conn); |
BeanSession session = new H2BeanSession(beanManager, conn); |
session.createTables(); |
// first insert... |
City rj = new City(1, "Rio de Janeiro"); |
City chi = new City(2, "Chicago"); |
session.insert(rj); |
session.insert(chi); |
Address addr1 = new Address(rj); |
Address addr2 = new Address(chi); |
session.insert(addr1); |
session.insert(addr2); |
User user1 = new User("saoj", addr1); |
User user2 = new User("julia", addr2); |
session.insert(user1); |
session.insert(user2); |
Post post1 = new Post("Title1", user1); |
session.insert(post1); |
// now load and test; |
Post p1 = new Post(1); |
session.load(p1); |
// check if we have the address id |
Assert.assertEquals(p1.getUser().getAddress().getId(), post1.getUser().getAddress().getId()); |
// and everything from user and from address must be NULL except the ids (remember the Posts also have user_id, so the id of the user will NOT be null) |
Assert.assertEquals(p1.getUser().getId(), post1.getUser().getId()); |
Assert.assertEquals(p1.getUser().getUsername(), null); |
Assert.assertEquals(p1.getUser().getAddress().getCity(), null); |
// change the address of the post (i.e. of its user) |
p1.getUser().setAddress(addr2); |
session.update(p1); |
Post updatedPost = new Post(1); |
session.load(updatedPost); |
Assert.assertEquals(updatedPost.getUser().getAddress().getId(), addr2.getId()); |
// NOTE: This will create an inconsistency in the database because we did NOT update the user, only the address_id in the Post table... |
// the correct way of doing it: |
session.load(p1.getUser()); |
Assert.assertEquals(p1.getUser().getAddress().getId(), addr1.getId()); // still address 1 because we never updated user... |
// now update: |
p1.getUser().setAddress(addr2); |
session.update(p1.getUser()); |
// now just call update on the post and its address_id will be updated correctly: |
session.update(p1); |
Post p = new Post(1); |
session.load(p); |
Assert.assertEquals(p.getUser().getAddress().getId(), addr2.getId()); |
// and now the user is also correct: |
User u = new User(1); |
session.load(u); |
Assert.assertEquals(u.getAddress().getId(), addr2.getId()); |
Assert.assertEquals(1, session.deleteAll(new Post())); |
Assert.assertEquals(2, session.deleteAll(new User())); |
Assert.assertEquals(2, session.deleteAll(new Address())); |
Assert.assertEquals(2, session.deleteAll(new City())); |
} finally { |
close(stmt, rset); |
close(conn); |
} |
} |
@Test |
public void testAnotherOperations() throws SQLException { |
final Connection conn = getConnection(); |
try { |
BeanSession beanSession = new H2BeanSession(getBeanManager1(), conn); |
beanSession.createTables(); |
//let's play |
City c1 = new City(1, "Santa Rosa"); |
Address a1 = new Address(c1); |
User u1 = new User("erico", a1); |
User u2 = new User("jessica", a1); |
beanSession.insert(c1); |
beanSession.insert(a1); |
beanSession.insert(u1); |
beanSession.insert(u2); |
//simple check |
City c1DB = new City(c1.getId()); |
beanSession.load(c1DB); |
Assert.assertEquals(c1.getName(), c1DB.getName()); |
User u1DB = new User(u1.getId()); |
beanSession.load(u1DB); |
Assert.assertEquals(u1.getId(), u1DB.getId()); |
Assert.assertEquals(u1.getAddress().getId(), u1DB.getAddress().getId()); |
beanSession.insert(u2); |
//retrieving all users in base WITHOUT address |
List<User> list = beanSession.loadListMinus(new User(), orderByAsc("username"), "address.id"); |
for (User userDB : list) { |
Assert.assertEquals(null, userDB.getAddress()); |
} |
User userProps = PropertiesProxy.create(User.class); |
list = beanSession.loadListMinus(new User(), orderByAsc("username"), userProps.getAddress().getId()); |
for (User userDB : list) { |
Assert.assertEquals(null, userDB.getAddress()); |
} |
//another way to get the list above |
list = beanSession.loadList(new User(), orderByAsc("username"), "id", "username"); |
for (User userDB : list) { |
Assert.assertNull(userDB.getAddress()); |
Assert.assertNotNull(userDB.getId()); |
Assert.assertNotNull(userDB.getUsername()); |
} |
// test proxy for list of properties |
list = beanSession.loadList(new User(), orderByAsc("username"), userProps.getId(), userProps.getUsername()); |
for (User userDB : list) { |
Assert.assertNull(userDB.getAddress()); |
Assert.assertNotNull(userDB.getId()); |
Assert.assertNotNull(userDB.getUsername()); |
} |
list = beanSession.loadList(new User(), orderByAsc("username"), userProps.getId() ); |
for (User userDB : list) { |
Assert.assertNull(userDB.getAddress()); |
Assert.assertNotNull(userDB.getId()); |
Assert.assertNull(userDB.getUsername()); |
} |
list = beanSession.loadList(new User(), orderByAsc(userProps.getUsername()), userProps.getId()); |
for (User userDB : list) { |
Assert.assertNull(userDB.getAddress()); |
Assert.assertNotNull(userDB.getId()); |
Assert.assertNull(userDB.getUsername()); |
} |
list = beanSession.loadList(new User(), orderByAsc(userProps.getUsername()), lim(1), userProps.getId()); |
Assert.assertEquals(1, list.size()); |
Assert.assertEquals(2, beanSession.deleteAll(new User("jessica", null))); |
list = beanSession.loadList(new User()); |
Assert.assertEquals(1, list.size()); |
Assert.assertNotNull(list.get(0).getAddress()); |
Assert.assertNotNull(list.get(0).getId()); |
Assert.assertEquals("erico", list.get(0).getUsername()); |
}finally { |
close(conn); |
} |
} |
/* |
* Another situation |
*/ |
public static class Customer { |
private int code; |
private String name; |
private Boolean active; |
public Customer() { |
} |
public Customer(int code, String name, Boolean active) { |
this.code = code; |
this.name = name; |
this.active = active; |
} |
public Customer(int code) { |
this.code = code; |
} |
public Customer(String name, Boolean active) { |
this.name = name; |
this.active = active; |
} |
public int getCode() { |
return code; |
} |
public void setCode(int code) { |
this.code = code; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public Boolean getActive() { |
return active; |
} |
public void setActive(Boolean active) { |
this.active = active; |
} |
} |
public static class Sale { |
private long id; |
private Customer customer; |
private List<Item> items = new ArrayList<Item>(); |
public Sale() {} |
public Sale(Customer customer) { |
this.customer = customer; |
} |
public Sale(long id) { |
this.id = id; |
} |
public Sale(Customer customer, List<Item> items) { |
this.customer = customer; |
this.items = items; |
} |
public Sale(long id, Customer customer, List<Item> items) { |
this.id = id; |
this.customer = customer; |
this.items = items; |
} |
public long getId() { |
return id; |
} |
public void setId(long id) { |
this.id = id; |
} |
public Customer getCustomer() { |
return customer; |
} |
public void setCustomer(Customer customer) { |
this.customer = customer; |
} |
public BigDecimal getTotalPrice() { |
BigDecimal totalPrice = BigDecimal.ZERO; |
for (Item item : items) |
totalPrice = totalPrice.add(item.getTotalPrice()); |
return totalPrice; |
} |
public List<Item> getItems() { |
return items; |
} |
public void setItems(List<Item> items) { |
this.items = items; |
} |
public void addItem(Item item) { |
item.setSale(this); |
this.items.add(item); |
} |
@Override |
public boolean equals(Object obj) { |
if (obj instanceof Sale) |
return ((Sale)obj).id == id; |
return false; |
} |
@Override |
public int hashCode() { |
return (int) id; |
} |
} |
public static class Item { |
private Sale sale; |
private Product product; |
private BigDecimal amount; |
private Double actualPrice; |
public Item() {} |
public Item(Sale sale, Product product, BigDecimal amount, |
Double actualPrice) { |
this.actualPrice = actualPrice; |
this.sale = sale; |
this.product = product; |
this.amount = amount; |
} |
public Item(Sale sale, Product product, BigDecimal amount) { |
this.sale = sale; |
this.product = product; |
this.amount = amount; |
this.actualPrice = product.getPrice(); |
} |
public Item(Product product, BigDecimal amount) { |
this.product = product; |
this.amount = amount; |
this.actualPrice = product.getPrice(); |
} |
public Item(Sale sale, Product product) { |
this.product = product; |
this.sale = sale; |
this.actualPrice = product.getPrice(); |
} |
public Item(Sale sale) { |
this.sale = sale; |
} |
public Sale getSale() { |
return sale; |
} |
public void setSale(Sale sale) { |
this.sale = sale; |
} |
public Product getProduct() { |
return product; |
} |
public void setProduct(Product product) { |
this.product = product; |
} |
public BigDecimal getAmount() { |
return amount; |
} |
public void setAmount(BigDecimal amount) { |
this.amount = amount; |
} |
public Double getActualPrice() { |
return actualPrice; |
} |
public void setActualPrice(Double actualPrice) { |
this.actualPrice = actualPrice; |
} |
public BigDecimal getTotalPrice() { |
if (actualPrice <=0) |
throw new IllegalArgumentException("Invalid price"); |
if (amount.signum() <= 0) |
throw new IllegalArgumentException("Invalid amount"); |
return BigDecimal.valueOf(actualPrice).multiply(amount); |
} |
} |
public static class Product { |
private int id; |
private String description; |
private double price; |
public Product() {} |
public Product(String description, double price) { |
this.description = description; |
this.price = price; |
} |
public Product(int id, String description, double price) { |
this.id = id; |
this.description = description; |
this.price = price; |
} |
public Product(int id) { |
this.id = id; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getDescription() { |
return description; |
} |
public void setDescription(String description) { |
this.description = description; |
} |
public double getPrice() { |
return price; |
} |
public void setPrice(double price) { |
this.price = price; |
} |
@Override |
public boolean equals(Object obj) { |
if (obj instanceof Product) |
return ((Product)obj).id == id; |
return false; |
} |
@Override |
public int hashCode() { |
return (int) id; |
} |
} |
//fluent mode |
private BeanManager getBeanManagerCustomer() { |
// programmatic configuration for the bean... (no annotation or XML) |
BeanManager beanManager = new BeanManager(); |
// BeanConfig customerConfig = new BeanConfig(Customer.class, "customers") |
// .pk("code", "idcustomers", DBTypes.AUTOINCREMENT) |
// .field("name", DBTypes.STRING); |
// |
// BeanConfig saleConfig = new BeanConfig(Sale.class, "sales") |
// .pk("id", "idsales", DBTypes.AUTOINCREMENT) |
// .field("customer.code", "idcustomers", DBTypes.INTEGER); |
// |
// BeanConfig itemConfig = new BeanConfig(Item.class, "items") |
// |
// // the "sale.id" is a reference for field "id" in object "sale" |
// .pk("sale.id", "idsales", DBTypes.LONG) |
// |
// // same as above, the "product.id" is a reference for field "id" in object "product" |
// // note that it's a composite primary key with no sequence or autoincrement field |
// .pk("product.id", "idproducts", DBTypes.INTEGER) |
// |
// .field("amount", "amount_db", DBTypes.DOUBLE) |
// .field("actualPrice", "actual_price_db", DBTypes.DOUBLE); |
// |
// BeanConfig productConfig = new BeanConfig(Product.class, "products") |
// .pk("id", "idproducts", DBTypes.AUTOINCREMENT) |
// .field("description", DBTypes.STRING) |
// .field("price", DBTypes.DOUBLE); |
Customer customerProxy = PropertiesProxy.create(Customer.class); |
BeanConfig customerConfig = new BeanConfig(Customer.class, "customers") |
.pk(customerProxy.getCode(), "idcustomers", DBTypes.AUTOINCREMENT) |
.field(customerProxy.getName(), DBTypes.STRING.size(-1)) |
.field(customerProxy.getActive(), DBTypes.BOOLEAN); |
Sale saleProxy = PropertiesProxy.create(Sale.class); |
BeanConfig saleConfig = new BeanConfig(Sale.class, "sales") |
.pk(saleProxy.getId(), "idsales", DBTypes.AUTOINCREMENT) |
.field(saleProxy.getCustomer().getCode(), "idcustomers", DBTypes.INTEGER); |
Item itemProxy = PropertiesProxy.create(Item.class); |
BeanConfig itemConfig = new BeanConfig(Item.class, "items") |
// the "sale.id" is a reference for field "id" in object "sale" |
.pk(itemProxy.getSale().getId(), "idsales", DBTypes.LONG) |
// same as above, the "product.id" is a reference for field "id" in object "product" |
// note that it's a composite primary key with no sequence or autoincrement field |
.pk(itemProxy.getProduct().getId(), "idproducts", DBTypes.INTEGER) |
.field(itemProxy.getAmount(), "amount_db", DBTypes.BIGDECIMAL) |
.field(itemProxy.getActualPrice(), "actual_price_db", DBTypes.DOUBLE); |
Product productProxy = PropertiesProxy.create(Product.class); |
BeanConfig productConfig = new BeanConfig(Product.class, "products") |
.pk(productProxy.getId(), "idproducts", DBTypes.AUTOINCREMENT) |
.field(productProxy.getDescription(), DBTypes.STRING.size(-1)) |
.field(productProxy.getPrice(), DBTypes.DOUBLE); |
//add configurations in beanManager |
beanManager.addBeanConfig(customerConfig); |
beanManager.addBeanConfig(saleConfig); |
beanManager.addBeanConfig(itemConfig); |
beanManager.addBeanConfig(productConfig); |
return beanManager; |
} |
@Test |
public void testCustomer() { |
final Connection conn = getConnection(); |
PreparedStatement stmt = null; |
try { |
AnsiSQLBeanSession session = new H2BeanSession(getBeanManagerCustomer(), conn); |
session.createTables(); |
//let's play... |
Customer c1 = new Customer("Erico", true); |
Customer c2 = new Customer("Jessica", true); |
Customer c3 = new Customer("Inactive customer", false); |
session.insert(c1); |
session.insert(c2); |
session.insert(c3); |
Customer c3DB = new Customer(c3.getCode()); |
session.load(c3DB); |
Assert.assertEquals(c3.getActive(), c3DB.getActive()); |
Product p1 = new Product("Bean", 5.50); |
Product p2 = new Product("Rice", 4.32); |
Product p3 = new Product("Bread", 0.15); |
session.insert(p1); |
session.insert(p2); |
session.insert(p3); |
Sale s1 = new Sale(c1); |
// note that addItem method will set the respective sale in the given item |
s1.addItem(new Item(p1, BigDecimal.valueOf(1.0))); |
s1.addItem(new Item(p2, BigDecimal.valueOf(3))); |
s1.addItem(new Item(p3, BigDecimal.valueOf(0.175))); |
// we don't want magic here, so we have to insert the sale and the items separately |
session.insert(s1); |
for (Item item : s1.getItems()) |
session.insert(item); |
//retrieving the stored sale |
Sale s1DB = new Sale(s1.getId()); |
session.load(s1DB); |
// note that the s1DB sale has a costumer ONLY with code |
Assert.assertEquals(s1.getCustomer().getCode(), s1DB.getCustomer().getCode()); |
// loading the customer |
session.load(s1DB.getCustomer()); |
// now we have a sale with the full customer |
Assert.assertEquals(s1.getCustomer().getName(), s1DB.getCustomer().getName()); |
// again, we have to load sale and items if we want to retrieve both of them |
Item itemProto = new Item(s1DB); |
Item itemProxy = PropertiesProxy.create(Item.class); |
s1DB.setItems(session.loadList(itemProto, orderByAsc(itemProxy.getProduct().getId()))); //ordering by idproducts |
// let's check |
Assert.assertEquals(s1.getId(), s1DB.getId()); |
for (int i=0; i<s1.getItems().size(); i++) { |
// we're comparing the items in index order, so the s1 and s1DB's items order need to be equals |
Assert.assertEquals(s1.getItems().get(i).getActualPrice(), s1DB.getItems().get(i).getActualPrice()); |
Assert.assertEquals(s1.getItems().get(i).getAmount().doubleValue(), s1DB.getItems().get(i).getAmount().doubleValue()); |
} |
// updating the sale's customer |
s1DB.setCustomer(c2); |
session.update(s1DB); |
Sale updatedSale = new Sale(s1DB.getId()); |
session.load(updatedSale); |
Assert.assertEquals(c2.getCode(), updatedSale.getCustomer().getCode()); |
// let's do a more specific query |
// loading sales and customers with one query |
// first we'll insert a sale WITHOUT a customer |
Sale s2 = new Sale(); |
session.insert(s2); |
Sale s2DB = new Sale(s2.getId()); |
session.load(s2DB); |
//we don't have a customer |
Assert.assertNull(s2DB.getCustomer()); |
List<Sale> sales = new ArrayList<Sale>(); |
// Manual query using QueryBuilder |
QueryBuilder builder = session.buildQuery(); |
// set the Alias just once |
Alias<Sale> s = builder.aliasTo(Sale.class, "s"); |
Alias<Customer> c = builder.aliasTo(Customer.class, "c"); |
// returns (will be removed from buildSelect and populateBean) |
c.setReturnMinus(c.pxy().getActive()); |
Query query = builder.select(s, c) |
.from(s) |
.leftJoin(c).pkOf(c).in(s) |
.where().clause(s.pxy().getId()).condition(new GreaterThan(new ParamValue(0))).and() |
.clause(new Coalesce() |
.addParam(new ParamField(s, s.pxy().getId())) |
.addParam(new ParamValue(0))) |
.condition(new GreaterThan(new ParamValue(0))).and() |
.clause(new Coalesce() |
.addParam(new ParamFunction(new Lower(new ParamField(c, c.pxy().getName())))) |
.addParam(new ParamValue("i"))) |
.condition(new Like(new ParamValue("%i%"))) |
.orderBy().asc(s, s.pxy().getId()) |
.desc(s, s.pxy().getCustomer().getCode()) |
.limit(2).offset(0); |
stmt = query.prepare(); |
ResultSet rs = stmt.executeQuery(); |
Sale saleObj = null; |
while (rs.next()) { |
saleObj = new Sale(); |
s.populateBean(rs, saleObj); |
if (saleObj.getCustomer() != null) { // left join might not return any customer... |
c.populateBean(rs, saleObj.getCustomer()); |
} |
sales.add(saleObj); |
} |
Assert.assertNotNull(sales.get(0).getCustomer()); |
Assert.assertNull(sales.get(1).getCustomer()); |
// update or insert |
int result = -1; |
// must be updated |
saleObj.setCustomer(c1); |
result = session.save(saleObj); |
Assert.assertEquals(BeanSession.UPDATE, result); |
//must be inserted |
saleObj.setId(0); |
result = session.save(saleObj); |
Assert.assertEquals(BeanSession.INSERT, result); |
} catch (Exception e) { |
throw new RuntimeException(e); |
}finally { |
SQLUtils.close(stmt, conn); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/UpdateDiffTest.java |
---|
New file |
0,0 → 1,419 |
package org.mentabean.jdbc; |
import static org.junit.Assert.*; |
import java.sql.Connection; |
import java.util.LinkedList; |
import java.util.List; |
import junit.framework.Assert; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLUtils; |
public class UpdateDiffTest extends AbstractBeanSessionTest { |
static class User implements Cloneable { |
private int id; |
private String name; |
private Integer age; |
private boolean active; |
private Group group; |
public User() {} |
public User(int id) { |
this.id = id; |
} |
public User(String name, Integer age, boolean active, Group group) { |
super(); |
this.name = name; |
this.age = age; |
this.group = group; |
} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public Group getGroup() { |
return group; |
} |
public void setGroup(Group group) { |
this.group = group; |
} |
public Integer getAge() { |
return age; |
} |
public void setAge(Integer age) { |
this.age = age; |
} |
public boolean isActive() { |
return active; |
} |
public void setActive(boolean active) { |
this.active = active; |
} |
@Override |
public Object clone() throws CloneNotSupportedException { |
return super.clone(); |
} |
} |
static class Group implements Cloneable { |
private int id; |
private String name; |
public Group(String name) { |
this.name = name; |
} |
public Group(int id) { |
this.id = id;; |
} |
public Group(int id, String name) { |
this.id = id;; |
this.name = name; |
} |
public Group() {} |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
@Override |
public boolean equals(Object obj) { |
if (obj instanceof Group) { |
return id == ((Group) obj).id; |
} |
return false; |
} |
@Override |
public int hashCode() { |
return id; |
} |
@Override |
public Object clone() throws CloneNotSupportedException { |
return super.clone(); |
} |
} |
static class TypeTest { |
private long id; |
private int intPrimitive; |
private double doublePrimitive; |
private Double doubleWrapper; |
private Integer intWrapper; |
private String string; |
private Group group; |
public long getId() { |
return id; |
} |
public TypeTest setId(long id) { |
this.id = id; |
return this; |
} |
public int getIntPrimitive() { |
return intPrimitive; |
} |
public TypeTest setIntPrimitive(int intPrimitive) { |
this.intPrimitive = intPrimitive; |
return this; |
} |
public double getDoublePrimitive() { |
return doublePrimitive; |
} |
public TypeTest setDoublePrimitive(double doublePrimitive) { |
this.doublePrimitive = doublePrimitive; |
return this; |
} |
public Double getDoubleWrapper() { |
return doubleWrapper; |
} |
public TypeTest setDoubleWrapper(Double doubleWrapper) { |
this.doubleWrapper = doubleWrapper; |
return this; |
} |
public Integer getIntWrapper() { |
return intWrapper; |
} |
public TypeTest setIntWrapper(Integer intWrapper) { |
this.intWrapper = intWrapper; |
return this; |
} |
public String getString() { |
return string; |
} |
public TypeTest setString(String string) { |
this.string = string; |
return this; |
} |
public Group getGroup() { |
return group; |
} |
public TypeTest setGroup(Group group) { |
this.group = group; |
return this; |
} |
} |
private BeanManager configureManager1() { |
BeanManager manager = new BeanManager(); |
User userProxy = PropertiesProxy.create(User.class); |
BeanConfig userCfg = new BeanConfig(User.class, "users") |
.pk(userProxy.getId(), DBTypes.AUTOINCREMENT) |
.field(userProxy.getGroup().getId(), "idgroups", DBTypes.INTEGER) |
.field(userProxy.getName(), DBTypes.STRING.size(0)) |
.field(userProxy.getAge(), DBTypes.INTEGER) |
.field(userProxy.isActive(), DBTypes.BOOLEAN); |
manager.addBeanConfig(userCfg); |
Group groupProxy = PropertiesProxy.create(Group.class); |
BeanConfig groupCfg = new BeanConfig(Group.class, "groups") |
.pk(groupProxy.getId(), DBTypes.AUTOINCREMENT) |
.field(groupProxy.getName(), DBTypes.STRING.size(0)); |
manager.addBeanConfig(groupCfg); |
return manager; |
} |
private BeanManager configureManager2() { |
BeanManager manager = new BeanManager(); |
TypeTest t = PropertiesProxy.create(TypeTest.class); |
BeanConfig conf = new BeanConfig(TypeTest.class, "test") |
.pk(t.getId(), DBTypes.AUTOINCREMENT) |
.field(t.getIntPrimitive(), DBTypes.INTEGER) |
.field(t.getIntWrapper(), DBTypes.INTEGER) |
.field(t.getDoublePrimitive(), DBTypes.DOUBLE) |
.field(t.getDoubleWrapper(), DBTypes.DOUBLE) |
.field(t.getGroup().getId(), "idgroups", DBTypes.INTEGER) |
.field(t.getString(), DBTypes.STRING); |
manager.addBeanConfig(conf); |
return manager; |
} |
@Test |
public void test() throws Exception { |
Connection conn = getConnection(); |
try { |
BeanSession session = new H2BeanSession(configureManager1(), conn); |
session.createTables(); |
Group g1 = new Group("Common"); |
Group g2 = new Group("Super"); |
Group g3 = new Group("Admin"); |
session.insert(g1); |
session.insert(g2); |
session.insert(g3); |
User u1 = new User("John", 40, true, g1); |
User u2 = new User("Ralph", 30, false, g2); |
User u3 = new User("Matt", 20, true, g3); |
session.insert(u1); |
session.insert(u2); |
session.insert(u3); |
User ralph = new User(2); |
session.load(ralph); |
assertEquals("Ralph", ralph.getName()); |
User clone = (User) ralph.clone(); |
assertNotNull(clone.getGroup()); |
assertEquals(2, clone.getGroup().getId()); |
int updated = session.updateDiff(clone, ralph); |
assertEquals(0, updated); |
clone.setGroup(null); |
updated = session.updateDiff(clone, ralph); |
assertEquals(1, updated); |
clone = session.createBasicInstance(clone); |
session.load(clone); |
assertNull(clone.getGroup()); |
assertEquals("Ralph", clone.getName()); |
assertFalse(clone.isActive()); |
User old = (User) clone.clone(); |
clone.setGroup(g3); |
updated = session.updateDiff(clone, old); |
assertEquals(1, updated); |
clone = session.createBasicInstance(clone); |
session.load(clone); |
assertNotNull(clone.getGroup()); |
assertEquals("Ralph", clone.getName()); |
old = (User) clone.clone(); |
clone.setGroup(new Group()); |
clone.setAge(0); |
clone.setActive(true); |
updated = session.updateDiff(clone, old); |
assertEquals(1, updated); |
clone = session.createBasicInstance(clone); |
session.load(clone); |
assertNull(clone.getGroup()); |
assertEquals(new Integer(0), clone.getAge()); |
assertTrue(clone.isActive()); |
old = (User) clone.clone(); |
clone.setAge(null); |
updated = session.updateDiff(clone, old); |
assertEquals(1, updated); |
clone = session.loadUnique(clone); |
assertNull(clone.getAge()); |
old = (User) clone.clone(); |
clone.setAge(10); |
clone.setActive(false); |
updated = session.updateDiff(clone, old); |
assertEquals(1, updated); |
clone = session.createBasicInstance(clone); |
session.load(clone); |
assertEquals(new Integer(10), clone.getAge()); |
assertFalse(clone.isActive()); |
} finally { |
SQLUtils.close(conn); |
} |
} |
@Test |
public void testDifferences() throws Exception { |
Connection conn = getConnection(); |
try { |
BeanSession session = new H2BeanSession(configureManager2(), conn); |
session.createTables(); |
Group g1 = new Group(1, "Group one"); |
Group g2 = new Group(2, "Group two"); |
TypeTest newObj = new TypeTest() |
.setDoublePrimitive(0.6) |
.setDoubleWrapper(0.6) |
.setIntPrimitive(1) |
.setIntWrapper(1) |
.setGroup(g1) |
.setString("Test one"); |
TypeTest oldObj = new TypeTest() |
.setDoublePrimitive(0.7) |
.setDoubleWrapper(0.6) |
.setIntPrimitive(1) |
.setIntWrapper(1) |
.setGroup(g1) |
.setString("Test one"); |
List<String> diffs = new LinkedList<String>(); |
TypeTest diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertNotNull(diff); |
Assert.assertEquals(diff.getDoublePrimitive(), newObj.getDoublePrimitive()); |
Assert.assertEquals(0, diffs.size()); |
diffs.clear(); |
oldObj.setDoublePrimitive(0.6); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertNull(diff); |
Assert.assertEquals(0, diffs.size()); |
diffs.clear(); |
newObj.setGroup(g2); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertNotNull(diff); |
Assert.assertEquals(0, diffs.size()); |
Assert.assertEquals(g2, diff.getGroup()); |
diffs.clear(); |
newObj.setGroup(null); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertEquals(1, diffs.size()); |
Assert.assertEquals("group.id", diffs.get(0)); |
diffs.clear(); |
newObj.setGroup(g2); |
newObj.setDoublePrimitive(0); |
newObj.setString(null); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertEquals(g2, diff.getGroup()); |
Assert.assertEquals(2, diffs.size()); |
Assert.assertEquals("doublePrimitive", diffs.get(0)); |
Assert.assertEquals("string", diffs.get(1)); |
diffs.clear(); |
newObj.setGroup(oldObj.getGroup()); |
newObj.setDoublePrimitive(0.000000001d); |
oldObj.setDoublePrimitive(0.000000001d); |
newObj.setString(oldObj.getString()); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertEquals(0, diffs.size()); |
Assert.assertNull(diff); |
diffs.clear(); |
oldObj.setDoublePrimitive(0); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertNotNull(diff); |
Assert.assertEquals(newObj.getDoublePrimitive(), diff.getDoublePrimitive()); |
diffs.clear(); |
newObj.setDoublePrimitive(0); |
oldObj.setDoublePrimitive(0); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertNull(diff); |
diffs.clear(); |
newObj.setIntPrimitive(0); |
diff = session.compareDifferences(newObj, oldObj, diffs); |
Assert.assertNotNull(diff); |
Assert.assertEquals(0, diff.getIntPrimitive()); |
Assert.assertEquals(1, diffs.size()); |
Assert.assertEquals("intPrimitive", diffs.get(0)); |
} finally { |
SQLUtils.close(conn); |
} |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/QueryBuilderTest.java |
---|
New file |
0,0 → 1,1622 |
package org.mentabean.jdbc; |
import static org.junit.Assert.assertEquals; |
import static org.junit.Assert.assertFalse; |
import static org.junit.Assert.assertNotNull; |
import static org.junit.Assert.assertNull; |
import static org.junit.Assert.assertTrue; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.util.ArrayList; |
import java.util.List; |
import junit.framework.Assert; |
import org.junit.After; |
import org.junit.Before; |
import org.junit.Test; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBTypes; |
import org.mentabean.jdbc.QueryBuilder.Alias; |
import org.mentabean.jdbc.QueryBuilder.Query; |
import org.mentabean.sql.Sentence; |
import org.mentabean.sql.conditions.Between; |
import org.mentabean.sql.conditions.Equals; |
import org.mentabean.sql.conditions.GreaterThan; |
import org.mentabean.sql.conditions.In; |
import org.mentabean.sql.conditions.LessThan; |
import org.mentabean.sql.conditions.Like; |
import org.mentabean.sql.conditions.NotEquals; |
import org.mentabean.sql.conditions.NotIn; |
import org.mentabean.sql.functions.Avg; |
import org.mentabean.sql.functions.Count; |
import org.mentabean.sql.functions.Length; |
import org.mentabean.sql.functions.Lower; |
import org.mentabean.sql.functions.Substring; |
import org.mentabean.sql.functions.Upper; |
import org.mentabean.sql.operations.Add; |
import org.mentabean.sql.param.DefaultParamHandler; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamField; |
import org.mentabean.sql.param.ParamFunction; |
import org.mentabean.sql.param.ParamHandler; |
import org.mentabean.sql.param.ParamSubQuery; |
import org.mentabean.sql.param.ParamValue; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLUtils; |
public class QueryBuilderTest extends AbstractBeanSessionTest { |
public static class Country { |
private String name; |
public Country(String name) { |
this.name = name; |
} |
public Country() { |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
} |
public static class City { |
private int code; |
private String name; |
private Country country; |
public City(int code, String name, Country country) { |
this.code = code; |
this.name = name; |
this.country = country; |
} |
public City() { |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public int getCode() { |
return code; |
} |
public void setCode(int code) { |
this.code = code; |
} |
public Country getCountry() { |
return country; |
} |
public void setCountry(Country country) { |
this.country = country; |
} |
} |
public static class Company { |
private String id; |
private String name; |
private City city; |
private int employeesCount; |
public Company(String name) { |
this.name = name; |
} |
public Company() { |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public String getId() { |
return id; |
} |
public void setId(String id) { |
this.id = id; |
} |
public City getCity() { |
return city; |
} |
public void setCity(City city) { |
this.city = city; |
} |
public int getEmployeesCount() { |
return employeesCount; |
} |
public void setEmployeesCount(int employeesCount) { |
this.employeesCount = employeesCount; |
} |
@Override |
public String toString() { |
return "Company [id=" + id + ", name=" + name + ", city=" + city |
+ "]"; |
} |
} |
public static class Employee { |
private long number; |
private String name; |
private double salary; |
public Employee(long number, String name, double salary) { |
this.number = number; |
this.name = name; |
this.salary = salary; |
} |
public Employee() { |
} |
public long getNumber() { |
return number; |
} |
public void setNumber(long number) { |
this.number = number; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
public double getSalary() { |
return salary; |
} |
public void setSalary(double salary) { |
this.salary = salary; |
} |
@Override |
public String toString() { |
return "\n"+number + " - " + name + " - " + salary; |
} |
} |
public static class Post { |
private Employee employee; |
private Company company; |
private String description; |
public Post(Employee employee, Company company, String description) { |
this.employee = employee; |
this.company = company; |
this.description = description; |
} |
public Post() { |
} |
public Employee getEmployee() { |
return employee; |
} |
public void setEmployee(Employee employee) { |
this.employee = employee; |
} |
public Company getCompany() { |
return company; |
} |
public void setCompany(Company company) { |
this.company = company; |
} |
public String getDescription() { |
return description; |
} |
public void setDescription(String description) { |
this.description = description; |
} |
@Override |
public String toString() { |
return "Post [employee=" + employee + ", company=" + company |
+ ", description=" + description + "]"; |
} |
} |
private BeanManager configure() { |
BeanManager manager = new BeanManager(); |
Company comPxy = PropertiesProxy.create(Company.class); |
BeanConfig comConf = new BeanConfig(Company.class, "company") |
.pk(comPxy.getId(), "idcompany", DBTypes.STRING) |
.field(comPxy.getCity().getCode(), "c_code", DBTypes.INTEGER) |
.field(comPxy.getName(), DBTypes.STRING); |
manager.addBeanConfig(comConf); |
Employee empPxy = PropertiesProxy.create(Employee.class); |
BeanConfig employeeConf = new BeanConfig(Employee.class, "employee") |
.pk(empPxy.getNumber(), "idemployee", DBTypes.LONG) |
.field(empPxy.getName(), DBTypes.STRING) |
.field(empPxy.getSalary(), DBTypes.DOUBLE); |
manager.addBeanConfig(employeeConf); |
Post postPxy = PropertiesProxy.create(Post.class); |
BeanConfig postConf = new BeanConfig(Post.class, "post") |
.pk(postPxy.getEmployee().getNumber(), "idemployee", DBTypes.LONG) |
.pk(postPxy.getCompany().getId(), "idcompany", DBTypes.STRING) |
.field(postPxy.getDescription(), DBTypes.STRING); |
manager.addBeanConfig(postConf); |
City cityPxy = PropertiesProxy.create(City.class); |
BeanConfig cityConf = new BeanConfig(City.class, "cities") |
.pk(cityPxy.getCode(), "city_code", DBTypes.INTEGER) |
.field(cityPxy.getCountry().getName(), "country_name", DBTypes.STRING) |
.field(cityPxy.getName(), "city_name", DBTypes.STRING); |
manager.addBeanConfig(cityConf); |
Country countryPxy = PropertiesProxy.create(Country.class); |
BeanConfig countryConf = new BeanConfig(Country.class, "countries") |
.pk(countryPxy.getName(), "country_ident", DBTypes.STRING); |
manager.addBeanConfig(countryConf); |
return manager; |
} |
@Test |
public void test() { |
PreparedStatement ppst = null; |
try { |
Company comp = new Company(); |
comp.setId("4356136"); |
comp.setName("W3C"); |
session.insert(comp); |
Company basicComp = session.createBasicInstance(comp); |
assertFalse(comp == basicComp); |
assertNotNull(basicComp.getId()); |
assertNull(basicComp.getName()); |
if (AnsiSQLBeanSession.DEBUG) { |
System.out.println("Company: " + comp); |
System.out.println("Company (only pks): " + basicComp); |
} |
Employee emp = new Employee(); |
emp.setName("Érico"); |
emp.setNumber(391); |
emp.setSalary(9999); |
session.insert(emp); |
Employee basicEmp = session.createBasicInstance(emp); |
assertNull(basicEmp.getName()); |
assertEquals(0d, basicEmp.getSalary(), 0); |
assertEquals(emp.getNumber(), basicEmp.getNumber()); |
Post post = new Post(); |
post.setCompany(comp); |
post.setEmployee(emp); |
post.setDescription("Programmer"); |
session.insert(post); |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Company> c = builder.aliasTo(Company.class, "com"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Alias<Employee> e2 = builder.aliasTo(Employee.class, "emp2"); |
e2.setReturns(e2.pxy().getNumber()); |
Query query = builder.select(p, c, e) |
.from(p) |
.join(c).pkOf(c).in(p) |
.join(e).pkOf(e).in(p) |
.where() |
.clause(new Substring(new ParamField(e, e.pxy().getName())) |
/* |
* it's joke (only for showing that's possible to do that) |
*/ |
.beginIndex(new ParamFunction(new Length( |
new ParamFunction(new Lower( |
new ParamFunction(new Upper( |
new ParamValue("c")))))))) |
.endIndex(new ParamFunction(new Length( |
new ParamFunction(new Lower( |
new ParamField(e, e.pxy().getName()))))))) |
.condition(new Like(new ParamValue("%o"))).and() |
.clause(e.pxy().getNumber()).condition( |
new In(new ParamSubQuery(builder.subQuery() |
.select(e2) |
.from(e2) |
.where() |
.clause(new Substring(new ParamValue("teste")).endIndex( |
new ParamFunction(new Length(new ParamValue("CA"))))) |
.condition(new Equals(new ParamValue("te"))) |
))).and() |
.clause(new Lower(new ParamField(c, c.pxy().getName()))).condition( |
new Equals(new ParamFunction(new Lower(new ParamValue("W3c"))))) |
.orderBy().asc(p, p.pxy().getDescription()) |
.limit(10); |
ppst = query.prepare(); |
if (AnsiSQLBeanSession.DEBUG_NATIVE) { |
System.out.println("CUSTOM: "+ppst); |
} |
ResultSet rs = ppst.executeQuery(); |
List<Post> list = new ArrayList<Post>(); |
while (rs.next()) { |
Post pObj = new Post(); |
p.populateBean(rs, pObj); |
c.populateBean(rs, pObj.getCompany()); |
e.populateBean(rs, pObj.getEmployee()); |
list.add(pObj); |
} |
assertEquals(1, list.size()); |
assertNotNull(list.get(0)); |
assertNotNull(list.get(0).getCompany()); |
assertNotNull(list.get(0).getEmployee()); |
}catch (Exception e) { |
throw new BeanException(e); |
}finally { |
SQLUtils.close(ppst); |
} |
} |
private BeanSession session; |
@Before |
public void setUp() { |
AnsiSQLBeanSession.DEBUG = false; |
AnsiSQLBeanSession.DEBUG_NATIVE = false; |
session = new H2BeanSession(configure(), getConnection()); |
session.createTables(); |
prepareData(); |
} |
@After |
public void tearDown() { |
SQLUtils.close(session.getConnection()); |
} |
public void prepareData() { |
Company comp; |
Employee emp; |
Post post; |
Country usa = new Country("United States"); |
session.insert(usa); |
City ny = new City(123, "New York", usa); |
session.insert(ny); |
City sf = new City(1020, "San Francisco", usa); |
session.insert(sf); |
/* |
* Companies |
*/ |
comp = new Company(); |
comp.setId("1"); |
comp.setName("Google"); |
comp.setCity(ny); |
session.insert(comp); |
comp = new Company(); |
comp.setId("2"); |
comp.setName("IBM"); |
session.insert(comp); |
comp = new Company(); |
comp.setId("3"); |
comp.setName("Oracle"); |
comp.setCity(sf); |
session.insert(comp); |
/* |
* Google employees |
*/ |
comp = session.loadList(new Company("Google")).get(0); |
emp = new Employee(19, "Maile Ohye", 19750); |
session.insert(emp); |
post = new Post(emp, comp, "Developer Programs Tech Lead"); |
session.insert(post); |
emp = new Employee(12, "Ilya Grigorik", 10000); |
session.insert(emp); |
post = new Post(emp, comp, "Developer Advocate"); |
session.insert(post); |
emp = new Employee(15, "Michael Manoochehri", 18100); |
session.insert(emp); |
post = new Post(emp, comp, "Developer Programs Engineer"); |
session.insert(post); |
emp = new Employee(18, "Brian Cairns", 12500); |
session.insert(emp); |
post = new Post(emp, comp, "Software Engineer"); |
session.insert(post); |
/* |
* Oracle employees |
*/ |
comp = session.loadList(new Company("Oracle")).get(0); |
emp = new Employee(2, "Lawrence J. Ellison", 38900); |
session.insert(emp); |
post = new Post(emp, comp, "Chief Executive Officer"); |
session.insert(post); |
emp = new Employee(1, "Mark V. Hurd", 63250); |
session.insert(emp); |
post = new Post(emp, comp, "President"); |
session.insert(post); |
/* |
* No company employee |
*/ |
emp = new Employee(); |
emp.setName("No company"); |
emp.setNumber(999); |
session.insert(emp); |
} |
/** |
* Retrieve all employees |
*/ |
@Test |
public void query01() throws Exception { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Query query = builder |
.select(e) |
.from(e); |
List<Employee> list = query.executeQuery(); |
assertEquals(7, list.size()); |
} |
/** |
* Retrieve all employees which salary is greater then $15000 sorting by name |
*/ |
@Test |
public void query02() throws Exception { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Query query = builder |
.select(e) |
.from(e) |
.where() |
.clause(e.pxy().getSalary()) |
.condition(new GreaterThan(15000)) |
.orderBy().asc(e, e.pxy().getName()); |
List<Employee> list = query.executeQuery(); |
assertEquals(4, list.size()); |
assertEquals(list.get(0).getName(), "Lawrence J. Ellison"); //first |
assertEquals(list.get(3).getName(), "Michael Manoochehri"); //last |
} |
/** |
* Retrieve all Google employees which name starts with "M" sorting by name |
*/ |
@Test |
public void query03() throws Exception { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Company> c = builder.aliasTo(Company.class, "com"); |
Alias<Post> p = builder.aliasTo(Post.class); |
Query query = builder |
.select(e) |
.from(e) |
.join(p).pkOf(e).in(p) |
.join(c).pkOf(c).in(p) |
.where() |
.clause(c.pxy().getName()) |
.condition(new Equals("Google")) |
.and() |
.clause(e.pxy().getName()) |
.condition(new Like("M%")) |
.orderBy().asc(e, e.pxy().getName()); |
List<Employee> list = query.executeQuery(); |
assertEquals(2, list.size()); |
assertEquals(list.get(0).getName(), "Maile Ohye"); //first |
assertEquals(list.get(1).getName(), "Michael Manoochehri"); //last |
} |
/** |
* Retrieve all Google employees which salary between 10000 and 15000 sorting by salary |
*/ |
@Test |
public void query04() throws Exception { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Company> c = builder.aliasTo(Company.class, "com"); |
Alias<Post> p = builder.aliasTo(Post.class); |
Query query = builder |
.select(e) |
.from(e) |
.join(p).pkOf(e).in(p) |
.join(c).pkOf(c).in(p) |
.where() |
.clause(c.pxy().getId()) |
.condition(new Equals("1")) |
.and() |
.clause(e.pxy().getSalary()) |
.condition(new Between(10000, 15000)) |
.orderBy().asc(e, e.pxy().getSalary()); |
List<Employee> list = query.executeQuery(); |
assertEquals(2, list.size()); |
assertEquals(list.get(0).getName(), "Ilya Grigorik"); //first |
assertEquals(list.get(1).getName(), "Brian Cairns"); //last |
} |
/** |
* Retrieve all posts (with employees and companies) sorting by company name ASC and employee name DESC |
*/ |
@Test |
public void query05() throws Exception { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Company> c = builder.aliasTo(Company.class, "com"); |
Alias<Post> p = builder.aliasTo(Post.class); |
Query query = builder |
.select(p, e, c) |
.from(p) |
.join(e).pkOf(e).in(p) |
//here we set the bean where 'e' alias (employee) will be populate |
.inProperty(p.pxy().getEmployee()) |
.join(c).pkOf(c).in(p) |
//here we set the bean where 'c' alias (company) will be populate |
.inProperty(p.pxy().getCompany()) |
.orderBy() |
.asc(c, c.pxy().getName()) |
.desc(e, e.pxy().getName()); |
List<Post> list = query.executeQuery(); |
assertNotNull(list.get(0).getCompany().getName()); |
assertEquals(6, list.size()); |
assertEquals(list.get(0).getEmployee().getName(), "Michael Manoochehri"); //first |
assertEquals(list.get(0).getCompany().getName(), "Google"); //first |
assertEquals(list.get(5).getEmployee().getName(), "Lawrence J. Ellison"); //last |
assertEquals(list.get(5).getCompany().getName(), "Oracle"); //last |
} |
/** |
* Retrieve all employees that have no company |
*/ |
@Test |
public void query06() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Employee> eSub = builder.aliasTo(Employee.class, "emp_sub"); |
eSub.setReturns(eSub.pxy().getNumber()); |
Alias<Post> p = builder.aliasTo(Post.class); |
Query query = builder |
.select(e) |
.from(e) |
.where() |
.clause(e.pxy().getNumber()) |
//sub query in 'NOT IN' condition |
.condition(new NotIn(new ParamSubQuery( |
builder.subQuery() |
.select(eSub) |
.from(eSub) |
.join(p).pkOf(eSub).in(p)) |
)); |
List<Employee> list = query.executeQuery(); |
assertEquals(1, list.size()); |
assertEquals(list.get(0).getName(), "No company"); |
} |
/** |
* Retrieve all employees that have no company (same as above, just another way to build the SQL query) |
*/ |
@Test |
public void query07() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Post> p = builder.aliasTo(Post.class); |
Query query = builder |
.select(e) |
.from(e) |
.leftJoin(p).pkOf(e).in(p) |
.where() |
.clause(p.pxy().getDescription()) |
//this will be converted to 'IS NULL' in query. See the Equals condition |
.condition(new Equals(null)); |
List<Employee> list = query.executeQuery(); |
assertEquals(1, list.size()); |
assertEquals(list.get(0).getName(), "No company"); |
} |
/** |
* Retrieve all employees which name length is greater then 15 sorting by length ASC, name DESC |
*/ |
@Test |
public void query08() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Query query = builder |
.select(e) |
.from(e) |
.where() |
.clause(new Length(new ParamField(e, e.pxy().getName()))) |
.condition(new GreaterThan(15)) |
.orderBy() |
.asc(new ParamFunction(new Length(new ParamField(e, e.pxy().getName())))) |
.desc(e, e.pxy().getName()); |
List<Employee> list = query.executeQuery(); |
assertEquals(2, list.size()); |
assertEquals(list.get(0).getName(), "Michael Manoochehri"); |
assertEquals(list.get(1).getName(), "Lawrence J. Ellison"); |
} |
/** |
* Retrieve all companies with a count of employees sorting by company name ASC |
*/ |
@Test |
public void query09() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Sentence count = new Sentence(new Count(new ParamField(e, e.pxy().getNumber()))) |
.fromProperty(c.pxy().getEmployeesCount()); |
Query query = builder |
.select(c) |
.add(count) |
.from(c) |
.leftJoin(p).pkOf(c).in(p) |
.leftJoin(e).pkOf(e).in(p) |
.groupBy(c) |
.orderBy() |
.asc(c, c.pxy().getName()); |
List<Company> list = query.executeQuery(); |
assertEquals(3, list.size()); |
assertEquals(list.get(0).getName(), "Google"); |
assertEquals(list.get(0).getEmployeesCount(), 4); |
assertEquals(list.get(1).getName(), "IBM"); |
assertEquals(list.get(1).getEmployeesCount(), 0); |
assertEquals(list.get(2).getName(), "Oracle"); |
assertEquals(list.get(2).getEmployeesCount(), 2); |
} |
/** |
* Retrieve all companies having count of employees greater than 0 (zero) sorting by number of employees ASC |
*/ |
@Test |
public void query10() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Sentence count = new Sentence(new Count(new ParamField(e, e.pxy().getNumber()))) |
.fromProperty(c.pxy().getEmployeesCount()); |
Query query = builder |
.select(c) |
.add(count) |
.from(c) |
.leftJoin(p).pkOf(c).in(p) |
.leftJoin(e).pkOf(e).in(p) |
.groupBy(c) |
.having() |
.clause(count) |
.condition(new GreaterThan(0)) |
.orderBy() |
.asc(new ParamFunction(count)); |
List<Company> list = query.executeQuery(); |
assertEquals(2, list.size()); |
assertEquals(list.get(0).getName(), "Oracle"); |
assertEquals(list.get(0).getEmployeesCount(), 2); |
assertEquals(list.get(1).getName(), "Google"); |
assertEquals(list.get(1).getEmployeesCount(), 4); |
} |
/** |
* Retrieve all companies with a count of employees sorting by company name ASC |
*/ |
@Test |
public void query11() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "com"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "emp"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Alias<Post> p2 = builder.aliasTo(Post.class, "p2"); |
Query sub = builder.subQuery() |
.select(new Sentence(new Count(new ParamField(p2, p2.pxy().getDescription()))).name("count_sub")) |
.from(p2) |
.where() |
.clause(p2.pxy().getCompany().getId()) |
.condition(new Equals(new ParamField(c, c.pxy().getId()))); |
Query query = builder |
.select(p, c) |
.add(new Sentence(sub) |
.fromProperty(p.pxy().getCompany().getEmployeesCount())) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.orderBy() |
.asc(c, c.pxy().getName()); |
List<Post> list = query.executeQuery(); |
assertEquals(6, list.size()); |
assertEquals(list.get(0).getCompany().getName(), "Google"); |
assertEquals(list.get(0).getCompany().getEmployeesCount(), 4); |
assertEquals(list.get(5).getCompany().getName(), "Oracle"); |
assertEquals(list.get(5).getCompany().getEmployeesCount(), 2); |
} |
/** |
* Retrieve all companies with name upper case |
*/ |
@Test |
public void query12() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Sentence nameUpper = new Sentence(new Upper(new ParamField(c, c.pxy().getName()))) |
.fromProperty(c.pxy().getName()); |
Query query = builder |
.select(c) |
.add(nameUpper) |
.from(c) |
.orderBy() |
.asc(c, c.pxy().getName()); |
List<Company> list = query.executeQuery(); |
assertEquals(3, list.size()); |
assertEquals(list.get(0).getName(), "GOOGLE"); |
assertEquals(list.get(1).getName(), "IBM"); |
assertEquals(list.get(2).getName(), "ORACLE"); |
} |
/** |
* Retrieve all companies with name upper case and a count of employees |
*/ |
@Test |
public void query13() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
c.setReturnMinus(c.pxy().getName()); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Sentence nameUpper = new Sentence(new Upper(new ParamField(c, c.pxy().getName()))) |
.fromProperty(c.pxy().getName()); |
Sentence count = new Sentence(new Count(new ParamField(e, e.pxy().getNumber()))) |
.fromProperty(c.pxy().getEmployeesCount()); |
Query query = builder |
.select(c) |
.add(count) |
.add(nameUpper) |
.from(c) |
.leftJoin(p).pkOf(c).in(p) |
.leftJoin(e).pkOf(e).in(p) |
.groupBy(); |
List<Company> list = query.executeQuery(); |
assertEquals(3, list.size()); |
assertEquals("ORACLE", list.get(0).getName()); |
assertEquals(2, list.get(0).getEmployeesCount()); |
assertEquals("GOOGLE", list.get(1).getName()); |
assertEquals(4, list.get(1).getEmployeesCount()); |
assertEquals("IBM", list.get(2).getName()); |
assertEquals(0, list.get(2).getEmployeesCount()); |
} |
/** |
* Retrieve all posts |
*/ |
@Test |
public void query14() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Query query = builder.selectFrom(p); |
List<Post> list = query.executeQuery(); |
assertEquals(6, list.size()); |
for (Post post : list) { |
assertNotNull(post.getCompany()); |
assertNotNull(post.getEmployee()); |
assertNotNull(post.getCompany().getId()); |
assertTrue(post.getEmployee().getNumber() > 0); |
assertNull(post.getCompany().getName()); |
assertNull(post.getEmployee().getName()); |
} |
} |
/** |
* Retrieve all posts with company and employee using <code>executeQuery()</code> method |
*/ |
@Test |
public void queryExecuteQuery() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Query query = builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()); |
List<Post> list = query.executeQuery(); |
assertEquals(6, list.size()); |
for (Post post : list) { |
assertNotNull(post.getCompany()); |
assertNotNull(post.getEmployee()); |
assertNotNull(post.getCompany().getId()); |
assertTrue(post.getEmployee().getNumber() > 0); |
assertNotNull(post.getCompany().getName()); |
assertNotNull(post.getEmployee().getName()); |
} |
} |
/** |
* Retrieve all posts using <code>prepare()</code> and <code>populateBean</code> methods. |
*/ |
@Test |
public void queryPrepare() { |
PreparedStatement ppst = null; |
try { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Query query = builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.leftJoin(e).pkOf(e).in(p); |
List<Post> list = new ArrayList<Post>(); |
ppst = query.prepare(); |
ResultSet rs = ppst.executeQuery(); |
Post obj; |
while (rs.next()) { |
obj = new Post(); |
p.populateBean(rs, obj); |
if (obj.getCompany() != null) { |
c.populateBean(rs, obj.getCompany()); |
} |
if (obj.getEmployee() != null) { |
e.populateBean(rs, obj.getEmployee()); |
} |
list.add(obj); |
} |
assertEquals(6, list.size()); |
for (Post post : list) { |
assertNotNull(post.getCompany()); |
assertNotNull(post.getEmployee()); |
assertNotNull(post.getCompany().getId()); |
assertTrue(post.getEmployee().getNumber() > 0); |
assertNotNull(post.getCompany().getName()); |
assertNotNull(post.getEmployee().getName()); |
} |
}catch (Exception e) { |
throw new BeanException(e); |
}finally { |
SQLUtils.close(ppst); |
} |
} |
/** |
* Retrieve all companies with a count of employees (manual way) |
*/ |
@Test |
public void query15() { |
PreparedStatement ppst = null; |
try { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Sentence count = new Sentence(new Count( |
new ParamField(e, e.pxy().getNumber()))) |
.returnType(DBTypes.INTEGER) |
.name("count"); |
Query query = builder |
.select(c) |
.add(count) |
.from(c) |
.leftJoin(p).pkOf(c).in(p) |
.leftJoin(e).pkOf(e).in(p) |
.groupBy(); |
List<Company> list = new ArrayList<Company>(); |
ppst = query.prepare(); |
ResultSet rs = ppst.executeQuery(); |
Company obj; |
while (rs.next()) { |
obj = new Company(); |
c.populateBean(rs, obj); |
Integer employeesCount = query.getValueFromResultSet(rs, "count"); |
obj.setEmployeesCount(employeesCount); |
list.add(obj); |
} |
assertEquals(3, list.size()); |
assertEquals("Oracle", list.get(0).getName()); |
assertEquals(2, list.get(0).getEmployeesCount()); |
assertEquals("IBM", list.get(1).getName()); |
assertEquals(0, list.get(1).getEmployeesCount()); |
assertEquals("Google", list.get(2).getName()); |
assertEquals(4, list.get(2).getEmployeesCount()); |
}catch (Exception e) { |
throw new BeanException(e); |
}finally { |
SQLUtils.close(ppst); |
} |
} |
/** |
* Returns only the count of posts in database |
*/ |
@Test |
public void queryCount() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Sentence count = new Sentence( |
new Add() |
.param(new Count(new ParamField(p, p.pxy().getDescription()))) |
.param(4)) |
.name("count") |
.returnType(DBTypes.INTEGER); |
Query query = builder |
.select(count) |
.from(p); |
Integer postCount = query.executeSentence(); |
assertEquals(6 + 4, (int)postCount); |
} |
/** |
* Throws an exception because there are no sentences in query |
*/ |
@Test (expected = BeanException.class) |
public void queryCountWithNoSentence() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Query query = builder |
.selectFrom(p); |
query.executeSentence(); |
} |
/** |
* Retrieve all posts where company or employe name contains 'O' and salary less than 50000, |
* order by post description |
*/ |
@Test |
public void query16() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Query query = builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clause(c.pxy().getName()) |
.condition(new Like("%O%")) |
.or() |
.clause(e.pxy().getName()) |
.condition(new Like("%O%")) |
.closePar() |
.and() |
.clause(e.pxy().getSalary()) |
.condition(new LessThan(50000)) |
.orderBy() |
.asc(p, p.pxy().getDescription()); |
List<Post> list = query.executeQuery(); |
assertEquals(2, list.size()); |
assertEquals("Lawrence J. Ellison", list.get(0).getEmployee().getName()); |
assertEquals("Maile Ohye", list.get(1).getEmployee().getName()); |
} |
/** |
* Retrieve posts using parenthesis |
*/ |
@Test |
public void queryParenthesis() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
assertEquals(6, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(6, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("%")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(4, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.and() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(4, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.and() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.and() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.closePar() |
.executeQuery().size()); |
assertEquals(4, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.and() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.and() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.closePar() |
.executeQuery().size()); |
assertEquals(2, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.or() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.and() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.closePar() |
.executeQuery().size()); |
assertEquals(6, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.or() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.and() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.closePar() |
.executeQuery().size()); |
assertEquals(0, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).on(c.pxy().getId()).eq(p.pxy().getCompany().getId()) |
.eqProperty(p.pxy().getCompany()) |
.leftJoin(e).on(e.pxy().getNumber()).eq(p.pxy().getEmployee().getNumber()) |
.eqProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.and() |
.clause(c.pxy().getName()) |
.condition(new Like("Oracle")) |
.executeQuery().size()); |
assertEquals(4, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(2, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(0, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.and() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(6, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.and() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.or() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.executeQuery().size()); |
assertEquals(0, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.and() |
.openPar() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.or() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.executeQuery().size()); |
assertEquals(6, builder |
.selectDistinct(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.and() |
.clauseIf(false, e.pxy().getName()) |
.condition(new Like("%")) |
.executeQuery().size()); |
assertEquals(6, builder |
.selectDistinct(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.and() |
.clauseIf(true, e.pxy().getName()) |
.condition(new Like("%")) |
.executeQuery().size()); |
assertEquals(4, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.openPar() |
.clauseIf(true, c.pxy().getName()) |
.condition(new Like("Google")) |
.closePar() |
.and() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.or() |
.openPar() |
.clauseIf(true, c.pxy().getId()) |
.condition(new NotEquals(null)) |
.closePar() |
.closePar() |
.closePar() |
.and() |
.clauseIf(false, e.pxy().getName()) |
.condition(new Like("%")) |
.limit(6) |
.executeQuery().size()); |
} |
@Test |
public void limitNumberTest() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Employee> e = builder.aliasTo(Employee.class, "e"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
assertEquals(6, builder |
.selectDistinct(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.limit(0) |
.executeQuery().size()); |
assertEquals(3, builder |
.select(p, e, c) |
.from(p) |
.leftJoin(c).pkOf(c).in(p) |
.inProperty(p.pxy().getCompany()) |
.leftJoin(e).pkOf(e).in(p) |
.inProperty(p.pxy().getEmployee()) |
.where() |
.openPar() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Google")) |
.or() |
.clauseIf(false, c.pxy().getName()) |
.condition(new Like("Oracle")) |
.closePar() |
.limit(3) |
.executeQuery().size()); |
} |
@Test |
public void paramHandlerTest() { |
QueryBuilder builder = session.buildQuery(); |
Alias<Company> c = builder.aliasTo(Company.class, "c"); |
Alias<Post> p = builder.aliasTo(Post.class, "p"); |
ParamHandler paramHandler = new DefaultParamHandler(); |
Param found; |
found = paramHandler.findBetter(builder, 3); |
Assert.assertTrue(found instanceof ParamValue); |
found = paramHandler.findBetter(builder, null); |
Assert.assertTrue(found instanceof ParamValue); |
found = paramHandler.findBetter(builder, builder.subQuery().selectFrom(c)); |
Assert.assertTrue(found instanceof ParamSubQuery); |
builder.selectFrom(c).where().clause(c.pxy().getName()).condition(new NotEquals(null)).executeQuery(); |
found = paramHandler.findBetter(builder, c.pxy().getName()); |
Assert.assertTrue(found instanceof ParamField); |
builder = builder.subQuery(); |
builder.select(c, p) |
.from(c) |
.join(p).pkOf(c).in(p) |
.where().clause(p.pxy().getDescription()) |
.condition(new NotEquals("aaaaaaaa")) |
.and() |
.clause(c.pxy().getName()) |
.condition(new NotEquals("aaaaaaaaa")) |
.executeQuery(); |
found = paramHandler.findBetter(builder, p.pxy().getDescription()); |
Assert.assertTrue(found instanceof ParamField); |
found = paramHandler.findBetter(builder, c.pxy().getId()); |
Assert.assertTrue(found instanceof ParamField); |
found = paramHandler.findBetter(builder, new Avg(null)); |
Assert.assertTrue(found instanceof ParamFunction); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/AbstractBeanSessionTest.java |
---|
New file |
0,0 → 1,111 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.sql.DriverManager; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.sql.Statement; |
public abstract class AbstractBeanSessionTest { |
protected static Connection getConnection() { |
try { |
Class.forName("org.h2.Driver"); |
return DriverManager.getConnection("jdbc:h2:mem:MentaBean", "sa", ""); |
} catch (Exception e) { |
throw new IllegalStateException("Cannot connect to H2 database!", e); |
} |
} |
protected static void execUpdate(Connection conn, String query) throws SQLException { |
Statement stmt = null; |
try { |
stmt = conn.createStatement(); |
stmt.executeUpdate(query); |
} finally { |
close(stmt); |
} |
} |
static void close(PreparedStatement stmt) { |
close(stmt, null); |
} |
static void close(PreparedStatement stmt, ResultSet rset) { |
if (rset != null) { |
try { |
rset.close(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
if (stmt != null) { |
try { |
stmt.close(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
} |
static void close(Statement stmt) { |
close(stmt, null); |
} |
static void close(Statement stmt, ResultSet rset) { |
if (rset != null) { |
try { |
rset.close(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
if (stmt != null) { |
try { |
stmt.close(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
} |
static void close(Connection conn) { |
if (conn != null) { |
try { |
conn.close(); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
} |
} |
/tags/menta-bean-2.2.2/src/test/java/org/mentabean/jdbc/PropertiesProxyTest.java |
---|
New file |
0,0 → 1,282 |
package org.mentabean.jdbc; |
import junit.framework.Assert; |
import org.junit.Before; |
import org.junit.Test; |
import org.mentabean.util.DefaultProxy; |
import org.mentabean.util.PropertiesProxy; |
public class PropertiesProxyTest { |
public static class User { |
private String blah1; |
private int blah2; |
private Integer blah3; |
private Address address; |
public String getBlah1() { |
return blah1; |
} |
public void setBlah1(String blah1) { |
this.blah1 = blah1; |
} |
public int getBlah2() { |
return blah2; |
} |
public void setBlah2(int blah2) { |
this.blah2 = blah2; |
} |
public Integer getBlah3() { |
return blah3; |
} |
public void setBlah3(Integer blah3) { |
this.blah3 = blah3; |
} |
public Address getAddress() { |
return address; |
} |
public void setAddress(Address address) { |
this.address = address; |
} |
} |
public static class Address { |
private int foo1; |
private String foo2; |
private City city; |
public int getFoo1() { |
return foo1; |
} |
public void setFoo1(int foo1) { |
this.foo1 = foo1; |
} |
public String getFoo2() { |
return foo2; |
} |
public void setFoo2(String foo2) { |
this.foo2 = foo2; |
} |
public City getCity() { |
return city; |
} |
public void setCity(City city) { |
this.city = city; |
} |
} |
public static class City { |
private int id; |
private String name; |
public int getId() { |
return id; |
} |
public void setId(int id) { |
this.id = id; |
} |
public String getName() { |
return name; |
} |
public void setName(String name) { |
this.name = name; |
} |
} |
private static boolean check(String[] array, String s) { |
for(String x : array) { |
if (s.equals(x)) return true; |
} |
return false; |
} |
@Before |
public void setUp() { |
PropertiesProxy.INSTANCE = new DefaultProxy(); |
} |
@Test |
public void testRegular() { |
User userProp = PropertiesProxy.create(User.class); |
userProp.getBlah1(); |
Assert.assertEquals("blah1", PropertiesProxy.getPropertyName()); |
userProp.getBlah3(); |
Assert.assertEquals("blah3", PropertiesProxy.getPropertyName()); |
userProp.getBlah1(); |
userProp.getBlah2(); |
String[] array = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "blah1")); |
Assert.assertTrue(check(array, "blah2")); |
} |
@Test |
public void testNonFinal() { |
User userProp = PropertiesProxy.create(User.class); |
userProp.getBlah1(); |
Assert.assertEquals("blah1", PropertiesProxy.getPropertyName()); |
userProp.getAddress(); |
Assert.assertEquals("address", PropertiesProxy.getPropertyName()); |
userProp.getAddress(); |
userProp.getBlah3(); |
String[] array = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "address")); |
Assert.assertTrue(check(array, "blah3")); |
} |
@Test |
public void testNestedProperties() { |
User userProp = PropertiesProxy.create(User.class); |
userProp.getBlah1(); |
userProp.getAddress().getFoo1(); |
String[] array = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "blah1")); |
Assert.assertTrue(check(array, "address.foo1")); |
userProp.getAddress().getFoo2(); |
userProp.getBlah3(); |
array = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "address.foo2")); |
Assert.assertTrue(check(array, "blah3")); |
} |
@Test |
public void testThreeLevels() { |
User userProp = PropertiesProxy.create(User.class); |
userProp.getBlah2(); |
userProp.getAddress().getCity().getId(); |
userProp.getBlah1(); |
String[] array = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(3, array.length); |
Assert.assertTrue(check(array, "blah2")); |
Assert.assertTrue(check(array, "address.city.id")); |
Assert.assertTrue(check(array, "blah1")); |
userProp.getAddress().getFoo2(); |
userProp.getBlah3(); |
userProp.getAddress().getCity().getId(); |
userProp.getBlah1(); |
array = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(4, array.length); |
Assert.assertTrue(check(array, "address.foo2")); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "address.city.id")); |
Assert.assertTrue(check(array, "blah1")); |
} |
@Test |
public void testVarargs() { |
User userProp = PropertiesProxy.create(User.class); |
Object[] obj = new Object[] { "blah1", "blah2" }; |
String[] array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "blah1")); |
Assert.assertTrue(check(array, "blah2")); |
obj = new Object[] { "blah1", userProp.getBlah3(), "blah2" }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(3, array.length); |
Assert.assertTrue(check(array, "blah1")); |
Assert.assertTrue(check(array, "blah2")); |
Assert.assertTrue(check(array, "blah3")); |
obj = new Object[] { userProp.getBlah3() }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(1, array.length); |
Assert.assertTrue(check(array, "blah3")); |
obj = new Object[] { userProp.getBlah2(), userProp.getBlah3() }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "blah2")); |
Assert.assertTrue(check(array, "blah3")); |
obj = new Object[] { userProp.getBlah3(), userProp.getAddress() }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "address")); |
obj = new Object[] { userProp.getBlah3(), userProp.getAddress().getCity(), "blah1" }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(3, array.length); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "blah1")); |
Assert.assertTrue(check(array, "address.city")); |
obj = new Object[] { userProp.getBlah3(), userProp.getAddress().getFoo1(), "blah1" }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(3, array.length); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "blah1")); |
Assert.assertTrue(check(array, "address.foo1")); |
obj = new Object[] { userProp.getBlah3(), userProp.getAddress().getCity().getId() }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(2, array.length); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "address.city.id")); |
obj = new Object[] { "blah3", userProp.getAddress().getCity().getId(), userProp.getAddress().getFoo2() }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(3, array.length); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "address.city.id")); |
Assert.assertTrue(check(array, "address.foo2")); |
obj = new Object[] { "blah3", userProp.getAddress().getFoo2(), userProp.getAddress().getCity().getId() }; |
array = AnsiSQLBeanSession.getProperties(obj); |
Assert.assertEquals(3, array.length); |
Assert.assertTrue(check(array, "blah3")); |
Assert.assertTrue(check(array, "address.city.id")); |
Assert.assertTrue(check(array, "address.foo2")); |
} |
@Test |
public void testProxyInstances() { |
Address address = PropertiesProxy.create(Address.class); |
City city = PropertiesProxy.create(City.class); |
address.getFoo1(); |
city.getId(); |
address.getFoo2(); |
city.getName(); |
//first we have to get the proxy instances, cause getPropertyNames will clear them |
Object instances[] = PropertiesProxy.getBeanInstances(); |
//now we can work with property names... |
String properties[] = PropertiesProxy.getPropertyNames(); |
Assert.assertEquals(properties.length, instances.length); |
Assert.assertEquals("foo1", properties[0]); |
Assert.assertEquals(address, instances[0]); |
Assert.assertEquals("id", properties[1]); |
Assert.assertEquals(city, instances[1]); |
Assert.assertEquals("foo2", properties[2]); |
Assert.assertEquals(address, instances[2]); |
Assert.assertEquals("name", properties[3]); |
Assert.assertEquals(city, instances[3]); |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/HasParams.java |
---|
New file |
0,0 → 1,11 |
package org.mentabean.sql; |
import org.mentabean.sql.param.Param; |
public interface HasParams { |
public Param[] getParams(); |
public String build(); |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/Param.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.param; |
public interface Param { |
/** |
* Represents the parameters in query. In other words, this method returns a String |
* with the expression exactly as will be shown in SQL before its execution. |
* @return String |
*/ |
public String paramInQuery(); |
/** |
* The parameter's values |
* @return Object[] |
*/ |
public Object[] values(); |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/ParamSubQuery.java |
---|
New file |
0,0 → 1,23 |
package org.mentabean.sql.param; |
import org.mentabean.jdbc.QueryBuilder.Query; |
public class ParamSubQuery implements Param { |
private Query query; |
public ParamSubQuery(Query query) { |
this.query = query; |
} |
@Override |
public String paramInQuery() { |
return "("+query.getSQL()+")"; |
} |
@Override |
public Object[] values() { |
return query.getParamValues().toArray(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/DefaultParamHandler.java |
---|
New file |
0,0 → 1,36 |
package org.mentabean.sql.param; |
import org.mentabean.jdbc.QueryBuilder; |
import org.mentabean.jdbc.QueryBuilder.Alias; |
import org.mentabean.jdbc.QueryBuilder.Query; |
import org.mentabean.sql.Function; |
import org.mentabean.util.PropertiesProxy; |
public class DefaultParamHandler implements ParamHandler { |
@Override |
public Param findBetter(QueryBuilder builder, Object property) { |
if (property instanceof Param) |
return (Param) property; |
if (property instanceof Query) |
return new ParamSubQuery((Query) property); |
if (property instanceof Function) |
return new ParamFunction((Function) property); |
if (PropertiesProxy.hasBeanInstance()) { |
Object proxy = PropertiesProxy.getBeanInstances()[0]; |
for (Alias<?> a : builder.getCreatedAliases()) { |
if (a.pxy() == proxy) { |
return new ParamField(a, property); |
} |
} |
} |
return new ParamValue(property); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/ParamField.java |
---|
New file |
0,0 → 1,23 |
package org.mentabean.sql.param; |
import org.mentabean.jdbc.QueryBuilder.Alias; |
public class ParamField implements Param { |
private String column; |
public ParamField(Alias<?> alias, Object property) { |
column = alias.toColumn(property); |
} |
@Override |
public String paramInQuery() { |
return column; |
} |
@Override |
public Object[] values() { |
return null; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/ParamFunction.java |
---|
New file |
0,0 → 1,40 |
package org.mentabean.sql.param; |
import java.util.ArrayList; |
import java.util.Arrays; |
import java.util.List; |
import org.mentabean.sql.Function; |
public class ParamFunction implements Param { |
private Function function; |
public ParamFunction(Function function) { |
this.function = function; |
} |
@Override |
public String paramInQuery() { |
return function.build(); |
} |
@Override |
public Object[] values() { |
List<Object> values = new ArrayList<Object>(); |
Param[] params = function.getParams(); |
if (params != null && params.length > 0) { |
for (Param p : params) { |
if (p.values() != null && p.values().length > 0) { |
values.addAll(Arrays.asList(p.values())); |
} |
} |
} |
return values.toArray(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/ParamNative.java |
---|
New file |
0,0 → 1,21 |
package org.mentabean.sql.param; |
public class ParamNative implements Param { |
private Object param; |
public ParamNative(Object param) { |
this.param = param; |
} |
@Override |
public String paramInQuery() { |
return param.toString(); |
} |
@Override |
public Object[] values() { |
return null; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/ParamValue.java |
---|
New file |
0,0 → 1,21 |
package org.mentabean.sql.param; |
public class ParamValue implements Param { |
private Object value; |
public ParamValue(Object value) { |
this.value = value; |
} |
@Override |
public String paramInQuery() { |
return "?"; |
} |
@Override |
public Object[] values() { |
return new Object[] {value}; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/param/ParamHandler.java |
---|
New file |
0,0 → 1,9 |
package org.mentabean.sql.param; |
import org.mentabean.jdbc.QueryBuilder; |
public interface ParamHandler { |
public Param findBetter(QueryBuilder builder, Object property); |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/TableAlias.java |
---|
New file |
0,0 → 1,112 |
package org.mentabean.sql; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanSession; |
import org.mentabean.DBField; |
import org.mentabean.util.PropertiesProxy; |
/** |
* |
* This class encapsulates a proxy to help construct queries that are fully refactorable. |
* |
* @author Sergio Oliveira Jr. |
* |
* @param <E> |
*/ |
public class TableAlias<E> { |
private final Class<? extends E> beanClass; |
private final String prefix; |
private final BeanSession session; |
private final BeanConfig config; |
private final E proxy; |
public TableAlias(BeanSession session, BeanConfig config, Class<? extends E> beanClass) { |
this(session, config, beanClass, null); |
} |
public TableAlias(BeanSession session, BeanConfig config, Class<? extends E> beanClass, String prefix) { |
this.beanClass = beanClass; |
this.prefix = prefix; |
this.session = session; |
this.config = config; |
this.proxy = PropertiesProxy.create(beanClass); |
} |
@Override |
public String toString() { |
return "TableAlias [beanClass=" + beanClass.getSimpleName() + ", prefix=" + prefix + "]"; |
} |
/** |
* Return the db columns of a select statements. |
* |
* @return the columns to build a select statement |
*/ |
public String columns(Object... props) { |
if (prefix != null) { |
return session.buildSelect(beanClass, prefix, props); |
} else { |
return session.buildSelect(beanClass, props); |
} |
} |
public String columnsMinus(Object... props) { |
if (prefix != null) { |
return session.buildSelectMinus(beanClass, prefix, props); |
} else { |
return session.buildSelectMinus(beanClass, props); |
} |
} |
/** |
* Return the table name. |
* |
* @return the table name |
*/ |
public String tableName() { |
if (prefix != null) { |
return config.getTableName() + " " + prefix; |
} else { |
return config.getTableName(); |
} |
} |
/** |
* Return the db column name for this bean property. |
* |
* @param prop this is a filler parameter because a proxy call will be performed! |
* @return the db column name of this property |
*/ |
public String column(Object prop) { |
String propName = PropertiesProxy.getPropertyName(); |
DBField field = config.getField(propName); |
if (field == null) throw new IllegalStateException("Cannot find field for property \"" + propName + "\" on beanconfig: " + config); |
if (prefix != null) { |
return prefix + "." + field.getDbName(); |
} else { |
return field.getDbName(); |
} |
} |
public E pxy() { |
return proxy; |
} |
public E proxy() { |
return proxy; |
} |
public String prefix() { |
return prefix; |
} |
public Class<? extends E> beanClass() { |
return beanClass; |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/Parametrizable.java |
---|
New file |
0,0 → 1,40 |
package org.mentabean.sql; |
import java.util.ArrayList; |
import java.util.List; |
import org.mentabean.sql.param.Param; |
public abstract class Parametrizable implements HasParams { |
protected List<Param> params = new ArrayList<Param>(); |
public abstract String name(); |
@Override |
public Param[] getParams() { |
return params.toArray(new Param[0]); |
} |
protected Parametrizable addParam(Param param) { |
params.add(param); |
return this; |
} |
@Override |
public String build() { |
StringBuilder sb = new StringBuilder(name()); |
sb.append(" ("); |
for (Param param : getParams()) { |
sb.append(param.paramInQuery()).append(','); |
} |
sb.setCharAt(sb.length()-1, ')'); |
return sb.toString(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/operations/Multiply.java |
---|
New file |
0,0 → 1,11 |
package org.mentabean.sql.operations; |
public class Multiply extends Operation { |
@Override |
public String operationSignal() { |
return "*"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/operations/Operation.java |
---|
New file |
0,0 → 1,69 |
package org.mentabean.sql.operations; |
import java.util.ArrayList; |
import java.util.List; |
import org.mentabean.BeanException; |
import org.mentabean.jdbc.QueryBuilder.Alias; |
import org.mentabean.jdbc.QueryBuilder.Query; |
import org.mentabean.sql.Condition; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamField; |
import org.mentabean.sql.param.ParamFunction; |
import org.mentabean.sql.param.ParamSubQuery; |
import org.mentabean.sql.param.ParamValue; |
public abstract class Operation implements Function, Condition { |
private List<Param> params = new ArrayList<Param>(); |
public abstract String operationSignal(); |
public Operation param(Param p) { |
this.params.add(p); |
return this; |
} |
public Operation param(Function function) { |
this.params.add(new ParamFunction(function)); |
return this; |
} |
public Operation param(Object value) { |
this.params.add(new ParamValue(value)); |
return this; |
} |
public Operation param(Query query) { |
this.params.add(new ParamSubQuery(query)); |
return this; |
} |
public Operation param(Alias<?> alias, Object property) { |
this.params.add(new ParamField(alias, property)); |
return this; |
} |
@Override |
public Param[] getParams() { |
return params.toArray(new Param[0]); |
} |
@Override |
public String build() { |
if (params.size() < 2) |
throw new BeanException("An operation needs 2 (two) or more parameters"); |
StringBuilder sb = new StringBuilder(); |
sb.append("(").append(params.get(0).paramInQuery()); |
for (int i=1; i < params.size(); i++) { |
sb.append(operationSignal()).append(params.get(i).paramInQuery()); |
} |
return sb.append(")").toString(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/operations/Divide.java |
---|
New file |
0,0 → 1,11 |
package org.mentabean.sql.operations; |
public class Divide extends Operation { |
@Override |
public String operationSignal() { |
return "/"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/operations/Subtract.java |
---|
New file |
0,0 → 1,11 |
package org.mentabean.sql.operations; |
public class Subtract extends Operation { |
@Override |
public String operationSignal() { |
return "-"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/operations/Add.java |
---|
New file |
0,0 → 1,11 |
package org.mentabean.sql.operations; |
public class Add extends Operation { |
@Override |
public String operationSignal() { |
return "+"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/Sentence.java |
---|
New file |
0,0 → 1,84 |
package org.mentabean.sql; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
import org.mentabean.jdbc.AnsiSQLBeanSession; |
import org.mentabean.jdbc.QueryBuilder.Query; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamFunction; |
import org.mentabean.sql.param.ParamSubQuery; |
import org.mentabean.type.GenericType; |
public class Sentence implements Function, Condition { |
private Param param; |
private String name, property; |
private DBType<?> returnType = new GenericType(); |
public Sentence(Param param) { |
this.param = param; |
} |
public Sentence(Query query) { |
this.param = new ParamSubQuery(query); |
} |
public Sentence(Function function) { |
this.param = new ParamFunction(function); |
} |
/** |
* Specify the property of <code>FROM</code> alias that will be populated with this sentence |
* @param property |
* @return this |
*/ |
public Sentence fromProperty(Object property) { |
this.property = AnsiSQLBeanSession.getProperties(new Object[] {property})[0]; |
if (name == null) { |
name = this.property.replace('.', '_'); |
} |
return this; |
} |
public Sentence name(String name) { |
this.name = name; |
return this; |
} |
public Sentence returnType(DBType<?> type) { |
this.returnType = type; |
return this; |
} |
@SuppressWarnings("unchecked") |
public <T> T getValue(ResultSet rset) throws SQLException { |
return (T) returnType.getFromResultSet(rset, name); |
} |
public DBType<?> getReturnType() { |
return returnType; |
} |
public String getProperty() { |
return property; |
} |
public String getName() { |
return name; |
} |
@Override |
public Param[] getParams() { |
return new Param[] {param}; |
} |
@Override |
public String build() { |
return "("+param.paramInQuery()+")"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/Function.java |
---|
New file |
0,0 → 1,5 |
package org.mentabean.sql; |
public interface Function extends HasParams { |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/Condition.java |
---|
New file |
0,0 → 1,5 |
package org.mentabean.sql; |
public interface Condition extends HasParams { |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Substring.java |
---|
New file |
0,0 → 1,43 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamFunction; |
import org.mentabean.sql.param.ParamValue; |
public class Substring extends Parametrizable implements Function { |
private Param str, beginIndex, endIndex; |
public Substring(Param str) { |
this.str = str; |
} |
public Substring endIndex(Param param) { |
endIndex = param; |
return this; |
} |
public Substring beginIndex(Param param) { |
beginIndex = param; |
return this; |
} |
@Override |
public Param[] getParams() { |
if (beginIndex == null) |
beginIndex = new ParamValue(0); |
if (endIndex == null) |
endIndex = new ParamFunction(new Length(str)); |
return new Param[] {str, beginIndex, endIndex}; |
} |
@Override |
public String name() { |
return "SUBSTRING"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Length.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Length extends Parametrizable implements Function { |
public Length(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "LENGTH"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Min.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Min extends Parametrizable implements Function { |
public Min(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "MIN"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Sum.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Sum extends Parametrizable implements Function { |
public Sum(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "SUM"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Max.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Max extends Parametrizable implements Function { |
public Max(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "MAX"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Count.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Count extends Parametrizable implements Function { |
public Count(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "COUNT"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Lower.java |
---|
New file |
0,0 → 1,25 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Lower extends Parametrizable implements Function { |
private Param param; |
public Lower(Param param) { |
this.param = param; |
} |
@Override |
public Param[] getParams() { |
return new Param[] {param}; |
} |
@Override |
public String name() { |
return "LOWER"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Nullif.java |
---|
New file |
0,0 → 1,32 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamValue; |
public class Nullif extends Parametrizable implements Function { |
private Param p1, p2; |
public Nullif(Param p1, Param p2) { |
this.p1 = p1; |
this.p2 = p2; |
} |
public Nullif(Object p1, Object p2) { |
this.p1 = new ParamValue(p1); |
this.p2 = new ParamValue(p2); |
} |
@Override |
public Param[] getParams() { |
return new Param[] {p1, p2}; |
} |
@Override |
public String name() { |
return "NULLIF"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Upper.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Upper extends Parametrizable implements Function { |
public Upper(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "UPPER"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Avg.java |
---|
New file |
0,0 → 1,18 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Avg extends Parametrizable implements Function { |
public Avg(Param param) { |
addParam(param); |
} |
@Override |
public String name() { |
return "AVG"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/functions/Coalesce.java |
---|
New file |
0,0 → 1,20 |
package org.mentabean.sql.functions; |
import org.mentabean.sql.Function; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class Coalesce extends Parametrizable implements Function { |
@Override |
public String name() { |
return "COALESCE"; |
} |
@Override |
public Coalesce addParam(Param param) { |
super.addParam(param); |
return this; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/GreaterThanEquals.java |
---|
New file |
0,0 → 1,20 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class GreaterThanEquals extends SimpleComparison { |
public GreaterThanEquals(Param param) { |
super(param); |
} |
public GreaterThanEquals(Object param) { |
super(param); |
} |
@Override |
public String comparisonSignal() { |
return ">="; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/LessThan.java |
---|
New file |
0,0 → 1,20 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class LessThan extends SimpleComparison { |
public LessThan(Param param) { |
super(param); |
} |
public LessThan(Object param) { |
super(param); |
} |
@Override |
public String comparisonSignal() { |
return "<"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/GreaterThan.java |
---|
New file |
0,0 → 1,20 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class GreaterThan extends SimpleComparison { |
public GreaterThan(Param param) { |
super(param); |
} |
public GreaterThan(Object param) { |
super(param); |
} |
@Override |
public String comparisonSignal() { |
return ">"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/Like.java |
---|
New file |
0,0 → 1,21 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class Like extends SimpleComparison { |
public Like(Param param) { |
super(param); |
} |
public Like(Object value) { |
super(value); |
} |
@Override |
public String comparisonSignal() { |
return "LIKE"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/SimpleComparison.java |
---|
New file |
0,0 → 1,31 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.Condition; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamValue; |
public abstract class SimpleComparison implements Condition { |
private Param param; |
public abstract String comparisonSignal(); |
public SimpleComparison(Param param) { |
this.param = param; |
} |
public SimpleComparison(Object value) { |
this.param = new ParamValue(value); |
} |
@Override |
public Param[] getParams() { |
return new Param[] {param}; |
} |
@Override |
public String build() { |
return comparisonSignal()+" "+param.paramInQuery(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/NotLike.java |
---|
New file |
0,0 → 1,21 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class NotLike extends SimpleComparison { |
public NotLike(Param param) { |
super(param); |
} |
public NotLike(Object value) { |
super(value); |
} |
@Override |
public String comparisonSignal() { |
return "NOT LIKE"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/In.java |
---|
New file |
0,0 → 1,23 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.Condition; |
import org.mentabean.sql.Parametrizable; |
import org.mentabean.sql.param.Param; |
public class In extends Parametrizable implements Condition { |
@Override |
public String name() { |
return "IN"; |
} |
public In (Param param) { |
addParam(param); |
} |
@Override |
public Parametrizable addParam(Param param) { |
return super.addParam(param); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/NotIn.java |
---|
New file |
0,0 → 1,16 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class NotIn extends In { |
public NotIn(Param param) { |
super(param); |
} |
@Override |
public String name() { |
return "NOT IN"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/Between.java |
---|
New file |
0,0 → 1,54 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class Between extends AbstractBetween { |
private boolean not; |
public Between(Param begin, Param end) { |
super(begin, end); |
} |
public Between(Object beginValue, Object endValue) { |
super(beginValue, endValue); |
} |
public Between not() { |
not = true; |
return this; |
} |
@Override |
public String build() { |
if (begin == null && end == null) { |
return ""; |
} |
if (begin == null) { |
if (not) { |
return new GreaterThan(end).build(); |
} |
return new LessThanEquals(end).build(); |
} |
if (end == null) { |
if (not) { |
return new LessThan(begin).build(); |
} |
return new GreaterThanEquals(begin).build(); |
} |
String str = "BETWEEN "+begin.paramInQuery()+" AND "+end.paramInQuery(); |
return not ? "NOT "+str : str; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/Equals.java |
---|
New file |
0,0 → 1,35 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.Condition; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamValue; |
public class Equals implements Condition { |
protected Param param; |
public Equals(Object value) { |
if (value != null) { |
this.param = new ParamValue(value); |
} |
} |
public Equals(Param param) { |
this.param = param; |
} |
@Override |
public Param[] getParams() { |
return new Param[] {param}; |
} |
@Override |
public String build() { |
if (param == null) |
return "IS NULL"; |
return "= "+param.paramInQuery(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/NotBetween.java |
---|
New file |
0,0 → 1,31 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class NotBetween extends AbstractBetween { |
public NotBetween(Param begin, Param end) { |
super(begin, end); |
} |
public NotBetween(Object beginValue, Object endValue) { |
super(beginValue, endValue); |
} |
@Override |
public String build() { |
if (begin == null && end == null) |
return ""; |
if (begin == null) { |
return new GreaterThan(end).build(); |
} |
if (end == null) { |
return new LessThan(begin).build(); |
} |
return "NOT BETWEEN "+begin.paramInQuery()+" AND "+end.paramInQuery(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/NotEquals.java |
---|
New file |
0,0 → 1,24 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class NotEquals extends Equals { |
public NotEquals(Param param) { |
super(param); |
} |
public NotEquals(Object param) { |
super(param); |
} |
@Override |
public String build() { |
if (param == null) |
return "IS NOT NULL"; |
return "<> "+param.paramInQuery(); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/LessThanEquals.java |
---|
New file |
0,0 → 1,20 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.param.Param; |
public class LessThanEquals extends SimpleComparison { |
public LessThanEquals(Param param) { |
super(param); |
} |
public LessThanEquals(Object param) { |
super(param); |
} |
@Override |
public String comparisonSignal() { |
return "<="; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/sql/conditions/AbstractBetween.java |
---|
New file |
0,0 → 1,28 |
package org.mentabean.sql.conditions; |
import org.mentabean.sql.Condition; |
import org.mentabean.sql.param.Param; |
import org.mentabean.sql.param.ParamValue; |
public abstract class AbstractBetween implements Condition { |
protected Param begin, end; |
public AbstractBetween(Param begin, Param end) { |
this.begin = begin; |
this.end = end; |
} |
public AbstractBetween(Object beginValue, Object endValue) { |
if (beginValue != null) |
begin = new ParamValue(beginValue); |
if (endValue != null) |
end = new ParamValue(endValue); |
} |
@Override |
public Param[] getParams() { |
return new Param[] {begin, end}; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/BeanManager.java |
---|
New file |
0,0 → 1,105 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean; |
import java.util.HashMap; |
import java.util.HashSet; |
import java.util.Map; |
import java.util.Set; |
import org.mentabean.util.DefaultProxy; |
import org.mentabean.util.PropertiesProxy; |
/** |
* The manager that keeps track of the configuration for all beans. |
* |
* @author sergio.oliveira.jr@gmail.com |
*/ |
public class BeanManager { |
private final Map<Class<? extends Object>, BeanConfig> beans = new HashMap<Class<? extends Object>, BeanConfig>(); |
public BeanManager(PropertiesProxy proxy) { |
PropertiesProxy.INSTANCE = proxy == null ? new DefaultProxy() : proxy; |
} |
public BeanManager() { |
this(null); |
} |
/** |
* Add a bean configuration. |
* |
* @param bc |
* The bean configuration to add. |
* @return The BeanConfig added (Fluent API) |
*/ |
public BeanConfig bean(final BeanConfig bc) { |
if (beans.containsKey(bc.getBeanClass())) { |
throw new IllegalStateException("A configuration was already added for this bean ("+bc.getBeanClass()+")"); |
} |
beans.put(bc.getBeanClass(), bc); |
return bc; |
} |
/** |
* Add a bean configuration. |
* |
* @param bc |
* The bean configuration to add. |
*/ |
public void addBeanConfig(final BeanConfig bc) { |
bean(bc); |
} |
/** |
* Creates a bean configuration and add to this manager. |
* |
* @param beanClass |
* The bean class |
* @param tableName |
* The table name where the bean properties will be stored. |
* @return The BeanConfig created (Fluent API) |
*/ |
public BeanConfig bean(final Class<? extends Object> beanClass, final String tableName) { |
return bean(new BeanConfig(beanClass, tableName)); |
} |
/** |
* Get the bean configuration for the given bean class. |
* |
* @param beanClass |
* The bean class |
* @return The bean configuration for this bean or null if it was not defined |
*/ |
public BeanConfig getBeanConfig(final Class<? extends Object> beanClass) { |
return beans.get(beanClass); |
} |
public Set<BeanConfig> getBeanConfigs() { |
Set<BeanConfig> all = new HashSet<BeanConfig>(); |
all.addAll(beans.values()); |
return all; |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/event/TriggerAdapter.java |
---|
New file |
0,0 → 1,35 |
package org.mentabean.event; |
public abstract class TriggerAdapter implements TriggerListener { |
@Override |
public void beforeInsert(TriggerEvent evt) { |
} |
@Override |
public void afterInsert(TriggerEvent evt) { |
} |
@Override |
public void beforeUpdate(TriggerEvent evt) { |
} |
@Override |
public void afterUpdate(TriggerEvent evt) { |
} |
@Override |
public void beforeDelete(TriggerEvent evt) { |
} |
@Override |
public void afterDelete(TriggerEvent evt) { |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/event/TriggerEvent.java |
---|
New file |
0,0 → 1,24 |
package org.mentabean.event; |
import org.mentabean.BeanSession; |
public class TriggerEvent { |
private final BeanSession session; |
private final Object bean; |
public TriggerEvent(final BeanSession session, final Object bean) { |
this.session = session; |
this.bean = bean; |
} |
public BeanSession getSession() { |
return session; |
} |
@SuppressWarnings("unchecked") |
public <E> E getBean() { |
return (E) bean; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/event/TriggerListener.java |
---|
New file |
0,0 → 1,17 |
package org.mentabean.event; |
public interface TriggerListener { |
public void beforeInsert(TriggerEvent evt); |
public void afterInsert(TriggerEvent evt); |
public void beforeUpdate(TriggerEvent evt); |
public void afterUpdate(TriggerEvent evt); |
public void beforeDelete(TriggerEvent evt); |
public void afterDelete(TriggerEvent evt); |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/event/TriggerDispatcher.java |
---|
New file |
0,0 → 1,98 |
package org.mentabean.event; |
import java.util.ArrayList; |
import java.util.List; |
public class TriggerDispatcher { |
private final List<TriggerListener> triggers = new ArrayList<TriggerListener>(); |
public void addTrigger(TriggerListener trigger) { |
synchronized (triggers) { |
if (!triggers.contains(trigger)) { |
triggers.add(trigger); |
} |
} |
} |
public void removeTrigger(TriggerListener trigger) { |
synchronized (triggers) { |
triggers.remove(trigger); |
} |
} |
public void dispatch(Type type, TriggerEvent evt) { |
type.dispatchAll(triggers, evt); |
} |
public enum Type { |
BEFORE_INSERT { |
@Override |
void fire(TriggerListener l, TriggerEvent evt) { |
l.beforeInsert(evt); |
} |
}, |
AFTER_INSERT { |
@Override |
void fire(TriggerListener l, TriggerEvent evt) { |
l.afterInsert(evt); |
} |
}, |
BEFORE_UPDATE { |
@Override |
void fire(TriggerListener l, TriggerEvent evt) { |
l.beforeUpdate(evt); |
} |
}, |
AFTER_UPDATE { |
@Override |
void fire(TriggerListener l, TriggerEvent evt) { |
l.afterUpdate(evt); |
} |
}, |
BEFORE_DELETE { |
@Override |
void fire(TriggerListener l, TriggerEvent evt) { |
l.beforeDelete(evt); |
} |
}, |
AFTER_DELETE { |
@Override |
void fire(TriggerListener l, TriggerEvent evt) { |
l.afterDelete(evt); |
} |
}; |
public void dispatchAll(List<TriggerListener> list, TriggerEvent evt) { |
for (TriggerListener l : list) { |
fire(l, evt); |
} |
} |
abstract void fire(TriggerListener l, TriggerEvent evt); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/IntegerType.java |
---|
New file |
0,0 → 1,94 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class IntegerType implements DBType<Integer> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public IntegerType nullable(boolean flag) { |
IntegerType d = new IntegerType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "integer"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Integer getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Integer x = rset.getInt(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Integer getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Integer x = rset.getInt(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Integer.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Integer value) throws SQLException { |
if (value == null) { |
stmt.setNull(index, java.sql.Types.INTEGER); |
} else { |
stmt.setInt(index, value.intValue()); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/TimeType.java |
---|
New file |
0,0 → 1,89 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class TimeType implements DBType<java.util.Date> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public TimeType nullable(boolean flag) { |
TimeType d = new TimeType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "time"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public java.util.Date getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
return rset.getTime(index); |
} |
@Override |
public java.util.Date getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
return rset.getTime(field); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return java.util.Date.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final java.util.Date value) throws SQLException { |
if (value == null) { |
stmt.setTime(index, null); |
} else if (value instanceof java.sql.Time) { |
final java.sql.Time t = (java.sql.Time) value; |
stmt.setTime(index, t); |
} else { |
stmt.setTime(index, new java.sql.Time(value.getTime())); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/NowOnInsertAndUpdateTimestampType.java |
---|
New file |
0,0 → 1,35 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
public class NowOnInsertAndUpdateTimestampType extends TimestampType { |
@Override |
public boolean canBeNull() { |
return false; |
} |
@Override |
public NowOnInsertAndUpdateTimestampType nullable(boolean flag) { |
if (flag) { |
throw new UnsupportedOperationException("NowOnInsertAndUpdateTimestampType can never be null!"); |
} |
return this; |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/LongType.java |
---|
New file |
0,0 → 1,94 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class LongType implements DBType<Long> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public LongType nullable(boolean flag) { |
LongType d = new LongType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "integer"; // most database will not support BIGINT |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Long getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Long x = rset.getLong(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Long getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Long x = rset.getLong(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Long.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Long value) throws SQLException { |
if (value == null) { |
stmt.setNull(index, java.sql.Types.BIGINT); |
} else { |
stmt.setLong(index, value.longValue()); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/EnumValueType.java |
---|
New file |
0,0 → 1,131 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class EnumValueType implements DBType<Enum<?>>, SizedType { |
private final Class<? extends Enum<?>> enumType; |
private final int size; |
private boolean canBeNull = false; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public EnumValueType nullable(boolean flag) { |
EnumValueType d = new EnumValueType(enumType); |
d.canBeNull = flag; |
return d; |
} |
public EnumValueType(final Class<? extends Enum<?>> enumType) { |
this.enumType = enumType; |
this.size = calcSize(); |
} |
@Override |
public String getAnsiType() { |
return "varchar"; |
} |
public EnumValueType size(int size) { |
throw new UnsupportedOperationException("Cannot set the size on a " + this); |
} |
@Override |
public int getSize() { |
return size; |
} |
private int calcSize() { |
Enum<?>[] all = enumType.getEnumConstants(); |
int max = 0; |
for (Enum<?> o : all) { |
max = Math.max(max, o.name().length()); |
} |
return max; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + ": " + enumType.getSimpleName(); |
} |
@Override |
public Enum<?> getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
final String s = rset.getString(index); |
if (s == null) { |
return null; |
} |
return Enum.valueOf((Class) enumType, s); |
} |
@Override |
public Enum<?> getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
final String s = rset.getString(field); |
if (s == null) { |
return null; |
} |
return Enum.valueOf((Class) enumType, s); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return enumType; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Enum<?> value) throws SQLException { |
if (value == null) { |
stmt.setString(index, null); |
//Support for overwritten enums (superclass on left) |
} else if (enumType.isAssignableFrom(value.getClass())) { |
final String s = value.name(); |
stmt.setString(index, s); |
} else { |
throw new IllegalArgumentException("Value '"+value+"' from '"+value.getClass()+"' is not an enum!"); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/ByteArrayType.java |
---|
New file |
0,0 → 1,76 |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
/** |
* ByteArrayType that uses a get/setBytes from ResultSet/PreparedStatement respectively |
* |
* @author erico |
* |
*/ |
public class ByteArrayType implements DBType<byte[]> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public ByteArrayType nullable(boolean flag) { |
ByteArrayType d = new ByteArrayType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "blob"; |
} |
@Override |
public String toString() { |
return ByteArrayType.class.getSimpleName(); |
} |
@Override |
public byte[] getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
byte[] x = rset.getBytes(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public byte[] getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
byte[] x = rset.getBytes(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return byte[].class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final byte[] value) throws SQLException { |
stmt.setBytes(index, value); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/TimestampType.java |
---|
New file |
0,0 → 1,89 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class TimestampType implements DBType<java.util.Date> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public TimestampType nullable(boolean flag) { |
TimestampType d = new TimestampType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "timestamp"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public java.util.Date getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
return rset.getTimestamp(index); |
} |
@Override |
public java.util.Date getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
return rset.getTimestamp(field); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return java.util.Date.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final java.util.Date value) throws SQLException { |
if (value == null) { |
stmt.setTimestamp(index, null); |
} else if (value instanceof java.sql.Timestamp) { |
final java.sql.Timestamp t = (java.sql.Timestamp) value; |
stmt.setTimestamp(index, t); |
} else { |
stmt.setTimestamp(index, new java.sql.Timestamp(value.getTime())); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/FloatType.java |
---|
New file |
0,0 → 1,95 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class FloatType implements DBType<Float> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public FloatType nullable(boolean flag) { |
FloatType d = new FloatType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "float"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Float getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Float x = rset.getFloat(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Float getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Float x = rset.getFloat(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Float.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Float value) throws SQLException { |
if (value == null || value.isNaN() || value.isInfinite()) { |
stmt.setNull(index, java.sql.Types.FLOAT); |
} else { |
stmt.setFloat(index, value.floatValue()); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/StringType.java |
---|
New file |
0,0 → 1,97 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class StringType implements DBType<String>, SizedType { |
private int size = DEFAULT_SIZE; |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public StringType nullable(boolean flag) { |
StringType d = new StringType(); |
d.canBeNull = flag; |
d.size = this.size; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "varchar"; // if your database do not support that you are in trouble !!! |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
public StringType size(int size) { |
// clone so we can use this with DBTypes (cleaner API) |
StringType clone = new StringType(); |
clone.size = size; |
return clone; |
} |
@Override |
public int getSize() { |
return size; |
} |
@Override |
public String getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
return rset.getString(index); |
} |
@Override |
public String getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
return rset.getString(field); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return String.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final String value) throws SQLException { |
if (value == null) { |
stmt.setString(index, null); |
} else { |
stmt.setString(index, value); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/BooleanStringType.java |
---|
New file |
0,0 → 1,172 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.BeanException; |
import org.mentabean.DBType; |
public class BooleanStringType implements DBType<Boolean>, SizedType { |
private final String sTrue; |
private final String sFalse; |
private boolean canBeNull = true; |
public BooleanStringType() { |
this("T", "F"); |
} |
public BooleanStringType(final String sTrue, final String sFalse) { |
this.sTrue = sTrue; |
this.sFalse = sFalse; |
} |
public static BooleanStringType values(String sTrue, String sFalse) { |
return new BooleanStringType(sTrue, sFalse); |
} |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
@Override |
public String getAnsiType() { |
return "varchar"; |
} |
public BooleanStringType nullable(boolean flag) { |
// clone: |
BooleanStringType b = new BooleanStringType(this.sTrue, this.sFalse); |
b.canBeNull = flag; |
return b; |
} |
public BooleanStringType size(int size) { |
throw new UnsupportedOperationException("Cannot set size of a " + this); |
} |
@Override |
public int getSize() { |
return Math.max(sTrue.length(), sFalse.length()); |
} |
@Override |
public boolean equals(final Object obj) { |
if (obj instanceof BooleanStringType) { |
final BooleanStringType bt = (BooleanStringType) obj; |
if (bt.sTrue.equals(this.sTrue) && bt.sFalse.equals(this.sFalse)) { |
return true; |
} |
} |
return false; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
protected Boolean getBooleanValue(final String s) { |
if (s.equals(sTrue)) { |
return true; |
} |
if (s.equals(sFalse)) { |
return false; |
} |
return null; |
} |
private static Boolean getBoolValue(final boolean b) { |
if (b) { |
return Boolean.TRUE; |
} |
return Boolean.FALSE; |
} |
@Override |
public Boolean getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
final String s = rset.getString(index); |
if (rset.wasNull() || s == null) { |
return null; |
} |
final Boolean b = getBooleanValue(s); |
if (b == null) { |
throw new BeanException("Don't know how to convert String to boolean:" + s); |
} |
return getBoolValue(b); |
} |
@Override |
public Boolean getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
final String s = rset.getString(field); |
if (rset.wasNull() || s == null) { |
return null; |
} |
final Boolean b = getBooleanValue(s); |
if (b == null) { |
throw new BeanException("Don't know how to convert String to boolean: " + s); |
} |
return getBoolValue(b); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Boolean.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Boolean value) throws SQLException { |
if (value == null) { |
stmt.setString(index, null); |
} else { |
final String s = value ? sTrue : sFalse; |
stmt.setString(index, s); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/SequenceType.java |
---|
New file |
0,0 → 1,86 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class SequenceType implements DBType<Number> { |
@Override |
public boolean canBeNull() { |
return false; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public String getAnsiType() { |
return "integer"; |
} |
@Override |
public Long getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Long x = rset.getLong(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Long getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Long x = rset.getLong(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Long.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Number value) throws SQLException { |
if (value == null) { |
stmt.setNull(index, java.sql.Types.INTEGER); |
} else { |
stmt.setLong(index, value.longValue()); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/NowOnInsertTimestampType.java |
---|
New file |
0,0 → 1,36 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
public class NowOnInsertTimestampType extends TimestampType { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
@Override |
public NowOnInsertTimestampType nullable(boolean flag) { |
NowOnInsertTimestampType d = new NowOnInsertTimestampType(); |
d.canBeNull = flag; |
return d; |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/EnumIdTypeFactory.java |
---|
New file |
0,0 → 1,21 |
package org.mentabean.type; |
public class EnumIdTypeFactory { |
private static EnumIdTypeFactory instance = null; |
private EnumIdTypeFactory() { |
} |
public static EnumIdTypeFactory getInstance() { |
if (instance == null) { |
instance = new EnumIdTypeFactory(); |
} |
return instance; |
} |
public EnumIdType from(final Class<? extends Enum<?>> enumType) { |
return new EnumIdType(enumType); |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/DoubleType.java |
---|
New file |
0,0 → 1,94 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class DoubleType implements DBType<Double> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public DoubleType nullable(boolean flag) { |
DoubleType d = new DoubleType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "double precision"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Double getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Double x = rset.getDouble(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Double getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Double x = rset.getDouble(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Double.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Double value) throws SQLException { |
if (value == null || value.isNaN() || value.isInfinite()) { |
stmt.setNull(index, java.sql.Types.DOUBLE); |
} else { |
stmt.setDouble(index, value.doubleValue()); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/GenericType.java |
---|
New file |
0,0 → 1,76 |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
/** |
* Generic type that uses a get/setObject from ResultSet/PreparedStatement respectively |
* <br><br><i>Note this class must NOT be used to create tables. Databases doesn't have a generic type</i> |
* @author erico |
* |
*/ |
public class GenericType implements DBType<Object> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public GenericType nullable(boolean flag) { |
GenericType d = new GenericType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return null; // we don't have generic types in database level |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Object getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Object x = rset.getObject(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Object getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Object x = rset.getObject(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Object.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Object value) throws SQLException { |
stmt.setObject(index, value); |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/DateType.java |
---|
New file |
0,0 → 1,89 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class DateType implements DBType<java.util.Date> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public DateType nullable(boolean flag) { |
DateType d = new DateType(); |
d.canBeNull = flag; |
return d; |
} |
@Override |
public String getAnsiType() { |
return "date"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public java.util.Date getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
return rset.getDate(index); |
} |
@Override |
public java.util.Date getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
return rset.getDate(field); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return java.util.Date.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final java.util.Date value) throws SQLException { |
if (value == null) { |
stmt.setDate(index, null); |
} else if (value instanceof java.sql.Date) { |
final java.sql.Date d = (java.sql.Date) value; |
stmt.setDate(index, d); |
} else { |
stmt.setDate(index, new java.sql.Date(value.getTime())); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/AutoIncrementType.java |
---|
New file |
0,0 → 1,86 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class AutoIncrementType implements DBType<Number> { |
@Override |
public String getAnsiType() { |
return "integer"; |
} |
@Override |
public boolean canBeNull() { |
return false; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Long getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
Long x = rset.getLong(index); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Long getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
Long x = rset.getLong(field); |
if (rset.wasNull()) { |
return null; |
} |
return x; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Long.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Number value) throws SQLException { |
if (value == null) { |
stmt.setNull(index, java.sql.Types.INTEGER); |
} else { |
stmt.setLong(index, value.longValue()); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/SizedType.java |
---|
New file |
0,0 → 1,26 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
public interface SizedType { |
public static int DEFAULT_SIZE = 200; |
public int getSize(); |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/BooleanType.java |
---|
New file |
0,0 → 1,76 |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.sql.Types; |
import org.mentabean.DBType; |
public class BooleanType implements DBType<Boolean> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public BooleanType nullable(boolean flag) { |
BooleanType bt = new BooleanType(); |
bt.canBeNull = flag; |
return bt; |
} |
@Override |
public Boolean getFromResultSet(ResultSet rset, int index) throws SQLException { |
Boolean b = rset.getBoolean(index); |
if (rset.wasNull()) { |
return null; |
} |
return b; |
} |
@Override |
public void bindToStmt(PreparedStatement stmt, int index, Boolean value)throws SQLException { |
if (value == null) { |
stmt.setNull(index, Types.BOOLEAN); |
}else { |
stmt.setBoolean(index, value); |
} |
} |
@Override |
public Boolean getFromResultSet(ResultSet rset, String field) throws SQLException { |
Boolean b = rset.getBoolean(field); |
if (rset.wasNull()) { |
return null; |
} |
return b; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Boolean.class; |
} |
@Override |
public String getAnsiType() { |
return "boolean"; |
} |
} |
Property changes: |
Added: svn:mime-type |
+ text/plain |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/BigDecimalType.java |
---|
New file |
0,0 → 1,96 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.math.BigDecimal; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class BigDecimalType implements DBType<BigDecimal> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public BigDecimalType nullable(boolean flag) { |
// clone: |
BigDecimalType b = new BigDecimalType(); |
canBeNull = flag; |
return b; |
} |
@Override |
public String getAnsiType() { |
return "double precision"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public BigDecimal getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
BigDecimal bd = rset.getBigDecimal(index); |
if (rset.wasNull()) { |
return null; |
} |
return bd; |
} |
@Override |
public BigDecimal getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
BigDecimal bd = rset.getBigDecimal(field); |
if (rset.wasNull()) { |
return null; |
} |
return bd; |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return BigDecimal.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final BigDecimal value) throws SQLException { |
if (value == null) { |
stmt.setNull(index, java.sql.Types.DECIMAL); |
} else { |
stmt.setBigDecimal(index, value); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/EnumIdType.java |
---|
New file |
0,0 → 1,186 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.lang.reflect.Method; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.sql.Types; |
import org.mentabean.BeanException; |
import org.mentabean.DBType; |
public class EnumIdType implements DBType<Enum<?>> { |
private final Class<? extends Enum<?>> enumType; |
private final Method fromIdMethod; |
private final Method getIdMethod; |
private boolean canBeNull = false; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public EnumIdType nullable(boolean flag) { |
EnumIdType d = new EnumIdType(enumType); |
d.canBeNull = flag; |
return d; |
} |
public EnumIdType(final Class<? extends Enum<?>> enumType) { |
this.enumType = enumType; |
this.fromIdMethod = getFromIdMethod(enumType); |
this.getIdMethod = getGetIdMethod(enumType); |
} |
@Override |
public String getAnsiType() { |
return "smallint"; |
} |
private static Method getFromIdMethod(Class<? extends Enum<?>> enumType) { |
try { |
return enumType.getMethod("fromId", int.class); |
} catch (Exception e) { |
throw new BeanException("Cannot find fromId(int) method from enum class: " + enumType, e); |
} |
} |
private static Method getGetIdMethod(Class<? extends Enum<?>> enumType) { |
try { |
return enumType.getMethod("getId", (Class[]) null); |
} catch (Exception e) { |
throw new BeanException("Cannot find getId() method from enum class: " + enumType, e); |
} |
} |
private Enum<?> fromId(int id) { |
try { |
return (Enum<?>) fromIdMethod.invoke(null, id); |
} catch (Exception e) { |
throw new BeanException(e); |
} |
} |
private int getId(Enum<?> theEnum) { |
try { |
return (Integer) getIdMethod.invoke(theEnum, (Object[]) null); |
} catch (Exception e) { |
throw new BeanException(e); |
} |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName() + ": " + enumType.getSimpleName(); |
} |
@Override |
public Enum<?> getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
final int id = rset.getInt(index); |
if (rset.wasNull()) { |
return null; |
} |
return fromId(id); |
} |
@Override |
public Enum<?> getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
final int id = rset.getInt(field); |
if (rset.wasNull()) { |
return null; |
} |
return fromId(id); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return enumType; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Enum<?> value) throws SQLException { |
if (value == null) { |
stmt.setNull(index, Types.INTEGER); |
//Support for overwritten enums (superclass on left) |
} else if (enumType.isAssignableFrom(value.getClass())) { |
final int id = getId(value); |
stmt.setInt(index, id); |
} else { |
throw new IllegalArgumentException("Value '"+value+"' from '"+value.getClass()+"' is not an enum!"); |
} |
} |
public static enum Test { |
T1(1), T2(2), T3(3); |
private final int id; |
private Test(int id) { |
this.id = id; |
} |
public int getId() { |
return id; |
} |
public static Test fromId(int id) { |
for (Test t : Test.values()) { |
if (t.getId() == id) { |
return t; |
} |
} |
return null; |
} |
} |
public static void main(String[] args) throws Exception { |
EnumIdType eit = new EnumIdType(Test.class); |
System.out.println(eit.fromId(2)); |
System.out.println(eit.getId(Test.T3)); |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/NowOnUpdateTimestampType.java |
---|
New file |
0,0 → 1,36 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
public class NowOnUpdateTimestampType extends TimestampType { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
@Override |
public NowOnUpdateTimestampType nullable(boolean flag) { |
NowOnUpdateTimestampType d = new NowOnUpdateTimestampType(); |
d.canBeNull = flag; |
return d; |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/EnumValueTypeFactory.java |
---|
New file |
0,0 → 1,21 |
package org.mentabean.type; |
public class EnumValueTypeFactory { |
private static EnumValueTypeFactory instance = null; |
private EnumValueTypeFactory() { |
} |
public static EnumValueTypeFactory getInstance() { |
if (instance == null) { |
instance = new EnumValueTypeFactory(); |
} |
return instance; |
} |
public EnumValueType from(final Class<? extends Enum<?>> enumType) { |
return new EnumValueType(enumType); |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/BooleanIntType.java |
---|
New file |
0,0 → 1,111 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import org.mentabean.DBType; |
public class BooleanIntType implements DBType<Boolean> { |
private boolean canBeNull = true; |
@Override |
public boolean canBeNull() { |
return canBeNull; |
} |
public BooleanIntType nullable(boolean flag) { |
// clone |
BooleanIntType b = new BooleanIntType(); |
b.canBeNull = flag; |
return b; |
} |
@Override |
public String getAnsiType() { |
return "smallint"; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
private static Boolean getBoolValue(final int x) throws SQLException { |
if (x == 1) { |
return Boolean.TRUE; |
} |
if (x == 0) { |
return Boolean.FALSE; |
} |
throw new SQLException("integer is not 0 or 1: " + x); |
} |
@Override |
public Boolean getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
final int x = rset.getInt(index); |
if (rset.wasNull()) { |
return null; |
} |
return getBoolValue(x); |
} |
@Override |
public Boolean getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
final int x = rset.getInt(field); |
if (rset.wasNull()) { |
return null; |
} |
return getBoolValue(x); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Boolean.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Boolean value) throws SQLException { |
if (value == null) { |
stmt.setInt(index, 0); |
} else if (value instanceof Boolean) { |
final int x = value ? 1 : 0; |
stmt.setInt(index, x); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/type/AutoTimestampType.java |
---|
New file |
0,0 → 1,82 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.type; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.util.Date; |
import org.mentabean.DBType; |
public class AutoTimestampType implements DBType<Date> { |
@Override |
public String getAnsiType() { |
return "timestamp"; |
} |
@Override |
public boolean canBeNull() { |
return false; |
} |
@Override |
public String toString() { |
return this.getClass().getSimpleName(); |
} |
@Override |
public Date getFromResultSet(final ResultSet rset, final int index) throws SQLException { |
return rset.getTimestamp(index); |
} |
@Override |
public Date getFromResultSet(final ResultSet rset, final String field) throws SQLException { |
return rset.getTimestamp(field); |
} |
@Override |
public Class<? extends Object> getTypeClass() { |
return Date.class; |
} |
@Override |
public void bindToStmt(final PreparedStatement stmt, final int index, final Date value) throws SQLException { |
if (value == null) { |
stmt.setTimestamp(index, null); |
} else if (value instanceof java.sql.Timestamp) { |
final java.sql.Timestamp t = (java.sql.Timestamp) value; |
stmt.setTimestamp(index, t); |
} else { |
stmt.setTimestamp(index, new java.sql.Timestamp(value.getTime())); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/jdbc/MySQLBeanSession.java |
---|
New file |
0,0 → 1,138 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.DBField; |
import org.mentabean.DBType; |
import org.mentabean.type.AutoIncrementType; |
import org.mentabean.util.Limit; |
import org.mentabean.util.OrderBy; |
/** |
* MySQL only supports auto-increment. |
* |
* Now in mysql is 'now()' |
* |
* @author soliveira |
* |
*/ |
public class MySQLBeanSession extends AnsiSQLBeanSession { |
public MySQLBeanSession(final BeanManager beanManager, final Connection conn) { |
super(beanManager, conn); |
} |
@Override |
protected String getCurrentTimestampCommand() { |
return "now()"; |
} |
@Override |
protected String getDatabaseType(DBType<?> dbType) { |
if (dbType instanceof AutoIncrementType) { |
return "integer AUTO_INCREMENT"; |
} |
return super.getDatabaseType(dbType); |
} |
/** |
* MySQL is not like Oracle. It will SORT everything first and then apply LIMIT. |
*/ |
@Override |
protected StringBuilder handleLimit(final StringBuilder sb, final OrderBy orderBy, final Limit limit) { |
if (limit == null || limit.intValue() <= 0) { |
return sb; |
} |
final StringBuilder sbLimit = new StringBuilder(sb.length() + 32); |
sbLimit.append(sb.toString()).append(" LIMIT ").append(limit); |
return sbLimit; |
} |
@Override |
public void insert(final Object bean) { |
super.insert(bean); |
// find autoincrement field... |
final BeanConfig bc = beanManager.getBeanConfig(bean.getClass()); |
final DBField autoIncrement = bc.getAutoIncrementField(); |
if (autoIncrement == null) { |
dispatchAfterInsert(bean); |
return; |
} |
PreparedStatement stmt = null; |
ResultSet rset = null; |
final StringBuilder sb = new StringBuilder("select last_insert_id() from "); |
sb.append(bc.getTableName()); |
try { |
stmt = conn.prepareStatement(sb.toString()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
final long id = rset.getLong(1); |
try { |
injectValue(bean, autoIncrement.getName(), id, Integer.class); |
} catch(Exception e) { |
// try long as well: |
injectValue(bean, autoIncrement.getName(), id, Long.class); |
} |
dispatchAfterInsert(bean); |
} |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/jdbc/OracleBeanSession.java |
---|
New file |
0,0 → 1,155 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.DBField; |
import org.mentabean.util.Limit; |
import org.mentabean.util.OrderBy; |
/** |
* When using limit, Oracle will NOT sort first before limiting, so a trick must be used. |
* |
* Now in Oracle is 'sysdate'. |
* |
* Oracle only supports sequences for primary keys. |
* |
* @author soliveira |
* |
*/ |
public class OracleBeanSession extends AnsiSQLBeanSession { |
public OracleBeanSession(final BeanManager beanManager, final Connection conn) { |
super(beanManager, conn); |
} |
@Override |
protected String getCurrentTimestampCommand() { |
return "sysdate"; |
} |
/** |
* Oracle will not SORT first then apply LIMIT. |
*/ |
@Override |
protected StringBuilder handleLimit(final StringBuilder sb, final OrderBy orderBy, final Limit limit) { |
if (limit == null || limit.intValue() <= 0) { |
return sb; |
} |
final StringBuilder sbLimit = new StringBuilder(sb.length() + 32); |
if (orderBy != null && !orderBy.isEmpty()) { |
sbLimit.append("SELECT * FROM (").append(sb.toString()).append(") where rowcount <= ").append(limit); |
} else { |
sbLimit.append(sb.toString()).append(" AND rownum <= ").append(limit); |
} |
return sbLimit; |
} |
@Override |
public void insert(final Object bean) { |
// find sequence field... |
final BeanConfig bc = beanManager.getBeanConfig(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
final DBField seqField = bc.getSequenceField(); |
if (seqField == null) { |
super.insert(bean); |
dispatchAfterInsert(bean); |
return; |
} |
PreparedStatement stmt = null; |
ResultSet rset = null; |
final StringBuilder sb = new StringBuilder(128); |
sb.append("select "); |
String seqName = bc.getSequenceName(); |
if (seqName != null) { |
// sequence name was defined defined |
sb.append(seqName); |
} else { |
// use the convention for sequence name |
sb.append("seq_").append(seqField.getDbName()).append("_").append(bc.getTableName()); |
} |
sb.append(".nextval from ").append(bc.getTableName()); |
try { |
stmt = conn.prepareStatement(sb.toString()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
final long id = rset.getLong(1); |
try { |
injectValue(bean, seqField.getName(), id, Integer.class); |
} catch(Exception e) { |
// try long as well: |
injectValue(bean, seqField.getName(), id, Long.class); |
} |
} |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
super.insert(bean); |
dispatchAfterInsert(bean); |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/jdbc/FirebirdBeanSession.java |
---|
New file |
0,0 → 1,143 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.util.List; |
import java.util.Map; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.DBField; |
import org.mentabean.util.Limit; |
import org.mentabean.util.OrderBy; |
/** |
* Firebird support. |
* |
* @author soliveira |
*/ |
public class FirebirdBeanSession extends AnsiSQLBeanSession { |
public FirebirdBeanSession(final BeanManager beanManager, final Connection conn) { |
super(beanManager, conn); |
} |
@Override |
protected String getCurrentTimestampCommand() { |
return "current_timestamp"; |
} |
/** |
* MySQL is not like Oracle. It will SORT everything first and then apply LIMIT. |
*/ |
@Override |
protected StringBuilder handleLimit(final StringBuilder sb, final OrderBy orderBy, final Limit limit) { |
if (limit == null || limit.intValue() <= 0) { |
return sb; |
} |
String query = sb.toString(); |
if (query.toLowerCase().startsWith("select ")) { |
throw new BeanException("Got a limit query that does not start with select: " + query); |
} |
String withoutSelect = query.substring("select".length()); |
final StringBuilder sbLimit = new StringBuilder(withoutSelect.length() + 64); |
sbLimit.append("SELECT first(").append(limit).append(")").append(withoutSelect); |
return sbLimit; |
} |
@Override |
public void insert(final Object bean) { |
// find autoincrement field... |
final BeanConfig bc = beanManager.getBeanConfig(bean.getClass()); |
final DBField autoIncrement = bc.getAutoIncrementField(); |
if (autoIncrement == null) { |
super.insert(bean); |
dispatchAfterInsert(bean); |
return; |
} |
QueryAndValues qav = prepareInsertQuery(bean); |
StringBuilder sb = qav.sb; |
List<Value> values = qav.values; |
if (conn == null) { |
throw new BeanException("Connection is null!"); |
} |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
// add the returning... |
sb.append(" returning ").append(autoIncrement.getDbName()); |
if (DEBUG) { |
System.out.println("INSERT SQL: " + sb.toString()); |
} |
stmt = conn.prepareStatement(sb.toString()); |
Map<String, Value> fieldsLoaded = bindToInsertStatement(stmt, values); |
rset = stmt.executeQuery(); |
if (!rset.next()) { |
throw new BeanException("Nothing was inserted! Insert returned no result set!"); |
} |
int id = rset.getInt(autoIncrement.getDbName()); |
injectValue(bean, autoIncrement.getName(), id, Integer.class); |
loaded.put(bean, fieldsLoaded); |
dispatchAfterInsert(bean); |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/jdbc/H2BeanSession.java |
---|
New file |
0,0 → 1,201 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.DBField; |
import org.mentabean.DBType; |
import org.mentabean.type.AutoIncrementType; |
import org.mentabean.util.Limit; |
import org.mentabean.util.OrderBy; |
/** |
* H2 supports AUTOINCREMENT and SEQUENCE fields. |
* |
* Now has the value 'sysdate', like Oracle. |
* |
* @author Sergio Oliveira Jr. |
*/ |
public class H2BeanSession extends AnsiSQLBeanSession { |
public H2BeanSession(final BeanManager beanManager, final Connection conn) { |
super(beanManager, conn); |
} |
@Override |
protected String getCurrentTimestampCommand() { |
return "sysdate"; |
} |
@Override |
protected StringBuilder handleLimit(final StringBuilder sb, final OrderBy orderBy, final Limit limit) { |
if (limit == null || limit.intValue() <= 0) { |
return sb; |
} |
final StringBuilder sbLimit = new StringBuilder(sb.length() + 32); |
sbLimit.append(sb.toString()).append(" LIMIT ").append(limit); |
return sbLimit; |
} |
@Override |
protected String getDatabaseType(DBType<?> dbType) { |
if (dbType instanceof AutoIncrementType) { |
return "integer AUTO_INCREMENT"; |
} |
return super.getDatabaseType(dbType); |
} |
@Override |
public void insert(final Object bean) { |
// find sequence... (if any)... |
final BeanConfig bc = beanManager.getBeanConfig(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
final DBField seqField = bc.getSequenceField(); |
if (seqField != null) { |
PreparedStatement stmt = null; |
ResultSet rset = null; |
final StringBuilder sb = new StringBuilder(128); |
sb.append("select NEXTVAL("); |
String seqName = bc.getSequenceName(); |
if (seqName != null) { |
// sequence name was defined |
sb.append(seqName); |
} else { |
// use convention |
sb.append("seq_").append(seqField.getDbName()).append("_").append(bc.getTableName()); |
} |
sb.append(") from ").append(bc.getTableName()); |
try { |
stmt = conn.prepareStatement(sb.toString()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
final long id = rset.getLong(1); |
try { |
injectValue(bean, seqField.getName(), id, Integer.class); |
} catch(Exception e) { |
// try long as well... |
injectValue(bean, seqField.getName(), id, Long.class); |
} |
} |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
super.insert(bean); |
// find autoincrement field... |
final DBField autoIncrement = bc.getAutoIncrementField(); |
if (autoIncrement == null) { |
dispatchAfterInsert(bean); |
return; |
} |
PreparedStatement stmt = null; |
ResultSet rset = null; |
final StringBuilder sb = new StringBuilder("select identity() from "); |
sb.append(bc.getTableName()); |
try { |
stmt = conn.prepareStatement(sb.toString()); |
rset = stmt.executeQuery(); |
if (rset.next()) { |
final long id = rset.getLong(1); |
try { |
injectValue(bean, autoIncrement.getName(), id, Integer.class); |
} catch(Exception e) { |
// try long as well: |
injectValue(bean, autoIncrement.getName(), id, Long.class); |
} |
dispatchAfterInsert(bean); |
} |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
@Override |
protected boolean isVarcharUnlimitedSupported() { |
return true; |
} |
} |
/tags/menta-bean-2.2.2/src/main/java/org/mentabean/jdbc/AnsiSQLBeanSession.java |
---|
New file |
0,0 → 1,2641 |
/* |
* This program is free software: you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation, either version 3 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
* |
* MentaBean => http://www.mentabean.org |
* Author: Sergio Oliveira Jr. (sergio.oliveira.jr@gmail.com) |
*/ |
package org.mentabean.jdbc; |
import java.lang.reflect.Field; |
import java.lang.reflect.Method; |
import java.sql.Connection; |
import java.sql.PreparedStatement; |
import java.sql.ResultSet; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.HashMap; |
import java.util.IdentityHashMap; |
import java.util.Iterator; |
import java.util.LinkedList; |
import java.util.List; |
import java.util.Map; |
import java.util.Set; |
import org.mentabean.BeanConfig; |
import org.mentabean.BeanException; |
import org.mentabean.BeanManager; |
import org.mentabean.BeanSession; |
import org.mentabean.DBField; |
import org.mentabean.DBType; |
import org.mentabean.event.TriggerDispatcher; |
import org.mentabean.event.TriggerDispatcher.Type; |
import org.mentabean.event.TriggerEvent; |
import org.mentabean.event.TriggerListener; |
import org.mentabean.sql.TableAlias; |
import org.mentabean.type.AutoIncrementType; |
import org.mentabean.type.AutoTimestampType; |
import org.mentabean.type.NowOnInsertAndUpdateTimestampType; |
import org.mentabean.type.NowOnInsertTimestampType; |
import org.mentabean.type.NowOnUpdateTimestampType; |
import org.mentabean.type.SizedType; |
import org.mentabean.util.InjectionUtils; |
import org.mentabean.util.Limit; |
import org.mentabean.util.OrderBy; |
import org.mentabean.util.PropertiesProxy; |
import org.mentabean.util.SQLUtils; |
/** |
* The bean session implementation based on JDBC and SQL. |
* |
* @author soliveira |
*/ |
public class AnsiSQLBeanSession implements BeanSession { |
protected static boolean DEBUG = false; |
protected static boolean DEBUG_NATIVE = false; |
/* The loaded map will be cleared when the session dies */ |
protected IdentityHashMap<Object, Map<String, Value>> loaded = new IdentityHashMap<Object, Map<String, Value>>(); |
protected Connection conn; |
protected final BeanManager beanManager; |
protected final TriggerDispatcher dispatcher = new TriggerDispatcher(); |
/** |
* Creates a JdbcBeanSession with a BeanManager and a Connection. |
* |
* @param beanManager |
* The bean manager |
* @param conn |
* The database connection |
*/ |
public AnsiSQLBeanSession(final BeanManager beanManager, final Connection conn) { |
this.beanManager = beanManager; |
this.conn = conn; |
} |
/** |
* Turn SQL debugging on and off. |
* |
* @param b |
* true if it should be debugged |
*/ |
public static void debugSql(boolean b) { |
DEBUG = b; |
} |
/** |
* Turn SQL native queries debugging on and off. |
* |
* @param b |
* true if it should be debugged |
*/ |
public static void debugNativeSql(boolean b) { |
DEBUG_NATIVE = b; |
} |
/** |
* Get the connection associated with this JdbcBeanSession. |
* |
* @return the database connection |
*/ |
@Override |
public Connection getConnection() { |
return conn; |
} |
/** |
* Get the command representing 'now' in this database. This base implementation returns null, in other words, no now command will be used. |
* |
* @return the command for now in this database (now(), sysdate, etc) |
*/ |
protected String getCurrentTimestampCommand() { |
return null; |
} |
/** |
* Get a value from a bean through reflection. |
* |
* @param bean |
* @param fieldName |
* @return The value of a bean property |
*/ |
protected Object getValueFromBean(final Object bean, final String fieldName) { |
return getValueFromBean(bean, fieldName, null); |
} |
public static String[] getProperties(Object[] names) { |
if (names != null) { |
for(Object o : names) { |
if (o instanceof String) { |
PropertiesProxy.addPropertyName((String) o); |
} |
} |
} |
if (PropertiesProxy.hasProperties()) { |
return PropertiesProxy.getPropertyNames(); |
} else { |
return null; |
} |
} |
/** |
* Get a value from a bean through reflection. |
* |
* @param bean |
* @param fieldName |
* @param m |
* @return The value of a bean property |
*/ |
protected Object getValueFromBean(final Object bean, final String fieldName, Method m) { |
int index; |
if ((index = fieldName.lastIndexOf(".")) > 0) { |
String chain = fieldName.substring(0, index); |
String lastField = fieldName.substring(index + 1); |
Object deepestBean = getDeepestBean(bean, chain, false); |
if (deepestBean == null) return null; |
return getValueFromBean(deepestBean, lastField, m); |
} |
if (bean == null) { |
return null; |
} |
if (m == null) { |
m = InjectionUtils.findMethodToGet(bean.getClass(), fieldName); |
} |
if (m == null) { |
throw new BeanException("Cannot find method to get field from bean: " + |
"Class: " + bean.getClass() + ", field: " + fieldName); |
} |
Object value = null; |
try { |
value = m.invoke(bean, (Object[]) null); |
return value; |
} catch (Exception e) { |
throw new BeanException(e); |
} |
} |
private static void checkPK(final Object value, final DBField dbField) { |
if (value == null) { |
throw new BeanException("pk is missing: " + dbField); |
} else if (value instanceof Number) { |
final Number n = (Number) value; |
if (n.doubleValue() <= 0) { |
throw new BeanException("Number pk is missing: " + dbField); |
} |
} |
} |
@Override |
public boolean load(Object bean) { |
return loadImpl(bean, null, null); |
} |
@Override |
public boolean load(Object bean, Object... properties) { |
return loadImpl(bean, getProperties(properties), null); |
} |
@Override |
public boolean loadMinus(Object bean, Object... minus) { |
return loadImpl(bean, null, getProperties(minus)); |
} |
protected boolean loadImpl(final Object bean, String[] properties, String[] minus) { |
final BeanConfig bc = getConfigFor(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
if (bc.getNumberOfFields() == 0) { |
throw new BeanException("BeanConfig has zero fields: " + bc); |
} |
final StringBuilder sb = new StringBuilder(32 * bc.getNumberOfFields()); |
sb.append("SELECT "); |
Iterator<DBField> iter = bc.fields(); |
int count = 0; |
while (iter.hasNext()) { |
DBField field = iter.next(); |
final String fieldName = field.getDbName(); |
if (!field.isPK()) { // always load the PK... |
if (properties != null && !checkArray(fieldName, properties, bc)) { |
continue; |
} |
if (minus != null && checkArray(fieldName, minus, bc)) { |
continue; |
} |
} |
if (count++ > 0) { |
sb.append(','); |
} |
sb.append(fieldName); |
} |
sb.append(" FROM ").append(bc.getTableName()).append(" WHERE "); |
if (!bc.hasPK()) { |
throw new BeanException("Cannot load bean without a PK!"); |
} |
iter = bc.pks(); |
count = 0; |
final List<Value> values = new LinkedList<Value>(); |
while (iter.hasNext()) { |
final DBField dbField = iter.next(); |
final String fieldName = dbField.getName(); |
final String dbFieldName = dbField.getDbName(); |
final Object value = getValueFromBean(bean, fieldName); |
checkPK(value, dbField); |
if (count++ > 0) { |
sb.append(" AND "); |
} |
sb.append(dbFieldName).append("=?"); |
values.add(new Value(dbField, value)); |
} |
if (values.isEmpty()) { |
throw new BeanException("Bean is empty: " + bean + " / " + bc); |
} |
if (conn == null) { |
throw new BeanException("Connection is null!"); |
} |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
if (DEBUG) { |
System.out.println("LOAD SQL: " + sb.toString()); |
} |
stmt = conn.prepareStatement(sb.toString()); |
final Iterator<Value> iter2 = values.iterator(); |
int index = 0; |
while (iter2.hasNext()) { |
final Value v = iter2.next(); |
v.field.getType().bindToStmt(stmt, ++index, v.value); |
} |
rset = stmt.executeQuery(); |
if (DEBUG_NATIVE) { |
System.out.println("LOAD SQL (NATIVE): " + stmt); |
} |
index = 0; |
final Map<String, Value> fieldsLoaded = new HashMap<String, Value>(); |
if (rset.next()) { |
iter = bc.fields(); |
while (iter.hasNext()) { |
final DBField f = iter.next(); |
final String fieldName = f.getName(); |
if (!f.isPK()) { |
if (properties != null && !checkArray(fieldName, properties, bc)) { |
continue; |
} |
if (minus != null && checkArray(fieldName, minus, bc)) { |
continue; |
} |
} |
final DBType type = f.getType(); |
final Object value = type.getFromResultSet(rset, ++index); |
injectValue(bean, fieldName, value, type.getTypeClass()); |
fieldsLoaded.put(fieldName, new Value(f, value)); |
} |
} else { |
return false; |
} |
if (rset.next()) { |
throw new BeanException("Load returned more than one row!"); |
} |
loaded.put(bean, fieldsLoaded); |
return true; |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
private Object getDeepestBean(Object target, String name, boolean create) { |
int index; |
if ((index = name.indexOf('.')) > 0) { |
String fieldName = name.substring(0, index); |
String remainingName = name.substring(index + 1); |
Object bean = getPropertyBean(target, fieldName, create); |
return getDeepestBean(bean, remainingName, create); |
} |
return getPropertyBean(target, name, create); |
} |
/** |
* Get a value from target through reflection and tries to create a new instance if create parameter is true |
* @param target |
* @param name |
* @param create |
* @return The value from bean |
*/ |
protected Object getPropertyBean(Object target, String name, boolean create) { |
Object value = getValueFromBean(target, name); |
if (value == null && create) { |
// try to instantiate, must have a default constructor! |
Class<?> beanClass = InjectionUtils.findPropertyType(target.getClass(), name); |
if (beanClass == null) { |
throw new BeanException("Cannot find property type: " + target.getClass() + " " + name); |
} |
try { |
value = beanClass.newInstance(); |
} catch(Exception e) { |
value = getAbstractValue(target.getClass(), name); |
} |
// don't forget to inject in the target so next time it is there... |
injectValue(target, name, value, beanClass); |
} |
return value; |
} |
private Object getAbstractValue(Class<? extends Object> clazz, String name) { |
try { |
BeanConfig bc = getConfigFor(clazz); |
if (bc != null) { |
Class<? extends Object> instanceClass = bc.getAbstractProperty(name); |
if (instanceClass != null) { |
return instanceClass.newInstance(); |
} |
} |
throw new BeanException("Cannot instantiate property name: " + name + " from "+clazz); |
} catch (Exception e) { |
throw new BeanException("Cannot instantiate abstract value for "+clazz+" (field "+name+")", e); |
} |
} |
/** |
* Inject a value in a bean through reflection. |
* |
* @param bean |
* @param fieldName |
* @param value |
* @param valueType |
*/ |
protected void injectValue(final Object bean, final String fieldName, Object value, final Class<? extends Object> valueType) { |
// first check if we have a chain of fields... |
int index; |
if ((index = fieldName.lastIndexOf(".")) > 0) { |
if (value == null) { |
// there is nothing to do here, as we don't want to create any object since the id is null... |
return; |
} |
String chain = fieldName.substring(0, index); |
String lastField = fieldName.substring(index + 1); |
Object deepestBean = getDeepestBean(bean, chain, true); |
injectValue(deepestBean, lastField, value, valueType); |
return; |
} |
final Method m = InjectionUtils.findMethodToInject(bean.getClass(), fieldName, value == null ? valueType : value.getClass()); |
if (m == null) { |
// try field... |
final Field field = InjectionUtils.findFieldToInject(bean.getClass(), fieldName, value == null ? valueType : value.getClass()); |
if (field != null) { |
// if field is a primitive (not a wrapper or void), convert a null to its default value |
if (field.getType().isPrimitive() && value == null) { |
value = InjectionUtils.getDefaultValueForPrimitive(field.getType()); |
} |
try { |
field.set(bean, value); |
} catch (final Exception e) { |
e.printStackTrace(); |
throw new BeanException(e); |
} |
} else { |
// if Long and can be expressed as integer, try integer... |
if (value instanceof Long) { |
Long l = (Long) value; |
if (l.longValue() <= Integer.MAX_VALUE && l.longValue() >= Integer.MIN_VALUE) { |
injectValue(bean, fieldName, l.intValue(), Integer.class); // recursion... |
return; |
} |
} |
// Field can be a GenericType (Object). If value is null nothing will be injected.. |
if (value != null) |
throw new BeanException("Cannot find field or method to inject: " + bean + " / " + fieldName); |
} |
} else { |
// if field is a primitive (not a wrapper or void), convert a null to its default value |
Class<?> paramType = m.getParameterTypes()[0]; |
if (paramType.isPrimitive() && value == null) { |
value = InjectionUtils.getDefaultValueForPrimitive(paramType); |
} |
try { |
m.invoke(bean, value); |
} catch (final Exception e) { |
e.printStackTrace(); |
throw new BeanException(e); |
} |
} |
} |
/** |
* Some databases will sort before applying the limit (MySql), others will not (Oracle). Handle each one accordingly. |
* |
* Note: This base implementation does nothing. |
* |
* @param sb |
* @param orderBy |
* @param limit |
* @return A string builder with the the SQL modified for the limit operation |
*/ |
protected StringBuilder handleLimit(final StringBuilder sb, final OrderBy orderBy, final Limit limit) { |
return sb; |
} |
/** |
* Build the column/field list for a SQL SELECT statement based on the bean configuration. Very useful to create select statements. |
* |
* @param beanClass |
* the bean class |
* @return the column/field list for a select |
*/ |
@Override |
public String buildSelect(final Class<? extends Object> beanClass) { |
return buildSelectImpl(beanClass, null, null, null, true, true); |
} |
@Override |
public String buildSelect(final Class<? extends Object> beanClass, Object... properties) { |
return buildSelectImpl(beanClass, null, getProperties(properties), null, true, true); |
} |
/** |
* Build a column/field list for a SQL SELECT statement based on the bean configuration. A table prefix will be used on each field. Very useful to create select statements on multiple tables (joins). |
* |
* @param beanClass |
* the bean class |
* @param tablePrefix |
* the table prefix to use before each field |
* @return the column/field list for a select |
*/ |
@Override |
public String buildSelect(final Class<? extends Object> beanClass, final String tablePrefix) { |
return buildSelectImpl(beanClass, tablePrefix, null, null, true, true); |
} |
@Override |
public String buildSelect(final Class<? extends Object> beanClass, final String tablePrefix, Object... properties) { |
return buildSelectImpl(beanClass, tablePrefix, getProperties(properties), null, true, true); |
} |
/** |
* Like buildSelect but you can exclude some properties from the resulting list. Useful when you have a bean with too many properties and you just want to fetch a few. |
* |
* Note: The list of properties to exclude contains 'property names' and NOT database column names. |
* |
* @param beanClass |
* the bean class |
* @param minus |
* a list for property names to exclude |
* @return the column/field list for a select |
*/ |
@Override |
public String buildSelectMinus(final Class<? extends Object> beanClass, final Object... minus) { |
return buildSelectImpl(beanClass, null, null, getProperties(minus), true, true); |
} |
/** |
* Same as buildSelectMinus with support for a database table prefix that will be applied on each field. |
* |
* @param beanClass |
* the bean class |
* @param tablePrefix |
* the database table prefix |
* @param minus |
* a list of property names to exclude |
* @return the column/field list for a select |
*/ |
@Override |
public String buildSelectMinus(final Class<? extends Object> beanClass, final String tablePrefix, final Object... minus) { |
return buildSelectImpl(beanClass, tablePrefix, null, getProperties(minus), true, true); |
} |
protected String buildSelectImpl(final Class<? extends Object> beanClass, final String tablePrefix, |
final String[] properties, final String[] minus, final boolean includePK, final boolean addSuffix) { |
final BeanConfig bc = getConfigFor(beanClass); |
if (bc == null) { |
return null; |
} |
final StringBuilder sb = new StringBuilder(32 * bc.getNumberOfFields()); |
final Iterator<DBField> iter = bc.fields(); |
int count = 0; |
while (iter.hasNext()) { |
final DBField field = iter.next(); |
final String dbField = field.getDbName(); |
final String name = field.getName(); |
if (!field.isPK() || !includePK) { // always include PK |
if (properties != null && !checkArray(name, properties, bc)) { |
continue; |
} |
if (minus != null && checkArray(name, minus, bc)) { |
continue; |
} |
} |
if (count++ > 0) { |
sb.append(","); |
} |
if (tablePrefix != null) { |
sb.append(tablePrefix).append('.').append(dbField); |
if (addSuffix) { |
sb.append(' '); |
sb.append(tablePrefix).append('_').append(dbField); |
} |
} else { |
sb.append(dbField); |
} |
} |
return sb.toString(); |
} |
private boolean checkArray(final String value, final String[] array, final BeanConfig bc) { |
String column = propertyToColumn(bc, value); |
for (int i = 0; i < array.length; i++) { |
if (propertyToColumn(bc, array[i]).equals(column)) { |
return true; |
} |
} |
return false; |
} |
/** |
* Populate a bean (insert all its properties) from the results in a result set, based on the bean configuration. |
* |
* @param rset |
* the result set from where to get the property values |
* @param bean |
* the bean to be populated |
* @throws Exception |
*/ |
@Override |
public void populateBean(final ResultSet rset, final Object bean) { |
populateBeanImpl(rset, bean, null, null, null, true); |
} |
@Override |
public void populateBean(final ResultSet rset, final Object bean, Object... properties) { |
populateBeanImpl(rset, bean, null, getProperties(properties), null, true); |
} |
/** |
* Same as populateBean, but use a table prefix before fetching the values from the result set. Useful when there are multiple tables involved and you want to avoid field name clashing. |
* |
* @param rset |
* the result set |
* @param bean |
* the bean to be populated |
* @param tablePrefix |
* the table prefix |
*/ |
@Override |
public void populateBean(final ResultSet rset, final Object bean, final String tablePrefix) { |
populateBeanImpl(rset, bean, tablePrefix, null, null, true); |
} |
@Override |
public void populateBean(final ResultSet rset, final Object bean, final String tablePrefix, Object... properties) { |
populateBeanImpl(rset, bean, tablePrefix, getProperties(properties), null, true); |
} |
/** |
* Same as populateBean, but exclude some fields when populating. |
* |
* @param rset |
* @param bean |
* @param minus |
*/ |
@Override |
public void populateBeanMinus(final ResultSet rset, final Object bean, final Object... minus) { |
populateBeanImpl(rset, bean, null, null, getProperties(minus), true); |
} |
/** |
* Same as populateBean, but exclude some fields when populating and use a table prefix in front of the field names. |
* |
* @param rset |
* @param bean |
* @param tablePrefix |
* @param minus |
*/ |
@Override |
public void populateBeanMinus(final ResultSet rset, final Object bean, final String tablePrefix, final Object... minus) { |
populateBeanImpl(rset, bean, tablePrefix, null, getProperties(minus), true); |
} |
protected void populateBeanImpl(final ResultSet rset, final Object bean, final String tablePrefix, final String[] properties, final String[] minus, boolean includePK) { |
final BeanConfig bc = getConfigFor(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
final Iterator<DBField> iter = bc.fields(); |
final StringBuilder sbField = new StringBuilder(32); |
while (iter.hasNext()) { |
final DBField f = iter.next(); |
final String fieldName = f.getName(); |
if (!f.isPK() || !includePK) { // always populate PK |
if (properties != null && !checkArray(fieldName, properties, bc)) { |
continue; |
} |
if (minus != null && checkArray(fieldName, minus, bc)) { |
continue; |
} |
} |
final String dbFieldName = f.getDbName(); |
final DBType type = f.getType(); |
sbField.setLength(0); |
if (tablePrefix != null) { |
sbField.append(tablePrefix).append('_').append(dbFieldName); |
} else { |
sbField.append(dbFieldName); |
} |
try { |
final Object value = type.getFromResultSet(rset, sbField.toString()); |
injectValue(bean, fieldName, value, type.getTypeClass()); |
} catch (Exception e) { |
throw new BeanException(e); |
} |
} |
} |
/** |
* Load a list of beans, but exclude some fields. |
* |
* @param <E> |
* @param bean |
* @param minus |
* @param orderBy |
* @param limit |
* @return A list of beans |
*/ |
@Override |
public <E> List<E> loadListMinus(final E bean, final OrderBy orderBy, final Limit limit, final Object... minus) { |
return loadListImpl(bean, orderBy, limit, null, getProperties(minus)); |
} |
private <E> E checkUnique(final List<E> list) { |
if (list == null || list.size() == 0) { |
return null; |
} else if (list.size() > 1) { |
throw new BeanException("Query returned more than one bean!"); |
} else { |
return list.get(0); |
} |
} |
@Override |
public <E> List<E> loadList(final E bean, final OrderBy orderBy, final Limit limit) { |
return loadListImpl(bean, orderBy, limit, null, null); |
} |
@Override |
public <E> List<E> loadList(final E bean, final OrderBy orderBy, final Limit limit, Object... properties) { |
return loadListImpl(bean, orderBy, limit, getProperties(properties), null); |
} |
private <E> StringBuilder prepareListQuery(StringBuilder sb, BeanConfig bc, E bean, OrderBy orderBy, Limit limit, List<Value> values) { |
sb.append(" FROM ").append(bc.getTableName()).append(" "); |
Iterator<DBField> iter = bc.fields(); |
int count = 0; |
while (iter.hasNext()) { |
final DBField field = iter.next(); |
final String dbField = field.getDbName(); |
final Method m = findMethodToGet(bean, field.getName()); |
boolean isNestedProperty = field.getName().contains("."); |
if (m == null) { |
if (!isNestedProperty) { |
throw new BeanException("Cannot find method to get field from bean: " + field.getName()); |
} else { |
continue; // nested property not set! |
} |
} |
final Class<? extends Object> returnType = m.getReturnType(); |
final Object value = getValueFromBean(bean, field.getName(), m); |
if (!isSet(value, returnType)) { |
continue; |
} |
if (count++ > 0) { |
sb.append(" AND "); |
} else { |
sb.append(" WHERE "); |
} |
sb.append(dbField).append("=?"); |
values.add(new Value(field, value)); |
} |
sb.append(buildOrderBy(orderBy, bc)); |
sb = handleLimit(sb, orderBy, limit); |
return sb; |
} |
private String buildOrderBy(OrderBy orderBy, BeanConfig bc) { |
if (orderBy != null && !orderBy.isEmpty()) { |
String orderByString = orderBy.toString(); |
String[] orders = orderByString.trim().split("\\s*,\\s*"); |
for (String order : orders) { |
if (order.contains(" ")) { |
order = order.substring(0, order.indexOf(" ")); |
} |
orderByString = orderByString.replace(order, propertyToColumn(bc, order)); |
} |
StringBuilder sb = new StringBuilder(); |
sb.append(" order by ").append(orderByString).append(" "); |
return sb.toString(); |
} |
return " "; |
} |
/** |
* Returns a database column name for a bean attribute. |
* @param bc - The <code>BeanConfig</code> object |
* @param property - A bean property |
* @return The database column name found if exists, otherwise will return the |
* given bean <code>property</code> |
*/ |
public String propertyToColumn(BeanConfig bc, Object property) { |
Iterator<DBField> it = bc.fields(); |
String propertyName = getProperties(new Object[] {property})[0]; |
while (it.hasNext()) { |
DBField field = it.next(); |
if (propertyName.equalsIgnoreCase(field.getName())) |
return field.getDbName(); |
} |
return propertyName; |
} |
@Override |
public String propertyToColumn(Class<? extends Object> clazz, Object property) { |
return propertyToColumn(clazz, property, null); |
} |
@Override |
public String propertyToColumn(Class<? extends Object> clazz, Object property, String alias) { |
BeanConfig bc = getConfigFor(clazz); |
if (alias == null) |
return propertyToColumn(bc, property); |
return alias+"."+propertyToColumn(bc, property); |
} |
@Override |
public String buildTableName(Class<? extends Object> clazz) { |
return getConfigFor(clazz).getTableName(); |
} |
@Override |
public QueryBuilder buildQuery() { |
return new QueryBuilder(this); |
} |
@Override |
public int countList(Object bean) { |
return countListImpl(bean, null, null); |
} |
private int countListImpl(final Object bean, final OrderBy orderBy, final Limit limit) { |
if (limit != null && limit.intValue() == 0) { |
return 0; |
} |
final BeanConfig bc = getConfigFor(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
StringBuilder sb = new StringBuilder(32 * bc.getNumberOfFields()); |
sb.append("SELECT count(1)"); |
final List<Value> values = new LinkedList<Value>(); |
sb = prepareListQuery(sb, bc, bean, orderBy, limit, values); |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
final String sql = sb.toString(); |
if (DEBUG) { |
System.out.println("COUNT LIST: " + sql); |
} |
stmt = conn.prepareStatement(sql); |
final Iterator<Value> iter2 = values.iterator(); |
int index = 0; |
while (iter2.hasNext()) { |
final Value v = iter2.next(); |
v.field.getType().bindToStmt(stmt, ++index, v.value); |
} |
rset = stmt.executeQuery(); |
if (DEBUG_NATIVE) { |
System.out.println("COUNT LIST (NATIVE): "+stmt); |
} |
rset.next(); |
return rset.getInt(1); |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
private <E> List<E> loadListImpl(final E bean, final OrderBy orderBy, final Limit limit, final String[] properties, final String[] minus) { |
if (limit != null && limit.intValue() == 0) { |
return new ArrayList<E>(); |
} |
final BeanConfig bc = getConfigFor(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
StringBuilder sb = new StringBuilder(32 * bc.getNumberOfFields()); |
Iterator<DBField> iter = bc.fields(); |
sb.append("SELECT "); |
int count = 0; |
while (iter.hasNext()) { |
final DBField field = iter.next(); |
final String dbField = field.getDbName(); |
final String name = field.getName(); |
if (!field.isPK()) { |
if (properties != null && !checkArray(name, properties, bc)) { |
continue; |
} |
if (minus != null && checkArray(name, minus, bc)) { |
continue; |
} |
} |
if (count++ > 0) { |
sb.append(","); |
} |
sb.append(dbField); |
} |
final List<Value> values = new LinkedList<Value>(); |
sb = prepareListQuery(sb, bc, bean, orderBy, limit, values); |
PreparedStatement stmt = null; |
ResultSet rset = null; |
try { |
final String sql = sb.toString(); |
if (DEBUG) { |
System.out.println("LOAD LIST: "+sql); |
} |
stmt = conn.prepareStatement(sql); |
final Iterator<Value> iter2 = values.iterator(); |
int index = 0; |
while (iter2.hasNext()) { |
final Value v = iter2.next(); |
v.field.getType().bindToStmt(stmt, ++index, v.value); |
} |
rset = stmt.executeQuery(); |
if (DEBUG_NATIVE) { |
System.out.println("LOAD LIST (NATIVE): " + stmt); |
} |
final List<E> results = new LinkedList<E>(); |
final Class<? extends Object> beanKlass = bean.getClass(); |
int total = 0; |
while (rset.next()) { |
iter = bc.fields(); |
index = 0; |
final E item = (E) beanKlass.newInstance(); // not sure how to |
// handle generics |
// here... |
while (iter.hasNext()) { |
final DBField f = iter.next(); |
final String fieldName = f.getName(); |
if (!f.isPK()) { |
if (properties != null && !checkArray(fieldName, properties, bc)) { |
continue; |
} |
if (minus != null && checkArray(fieldName, minus, bc)) { |
continue; |
} |
} |
final DBType type = f.getType(); |
final Object value = type.getFromResultSet(rset, ++index); |
injectValue(item, fieldName, value, type.getTypeClass()); |
} |
results.add(item); |
total++; |
if (limit != null && limit.intValue() > 0 && total == limit.intValue()) { |
return results; |
} |
} |
return results; |
} catch (Exception e) { |
throw new BeanException(e); |
} finally { |
close(stmt, rset); |
} |
} |
/** |
* if Boolean consider TRUE to be set and FALSE to be not set. |
* |
* if Character, cast to integer and assume it is set if different than 0 |
* |
* if Number consider everything different than zero to be set. |
* |
* Otherwise returns TRUE for anything different than null and FALSE for null. |
* |
* @param value |
* @param returnType |
* @return true if is set |
*/ |
protected boolean isSet(final Object value, final Class<? extends Object> returnType) { |
if (value != null) { |
if (returnType.equals(boolean.class) && value instanceof Boolean) { |
// if Boolean consider TRUE to be set and FALSE to be not set |
// (false = default value) |
final boolean b = ((Boolean) value).booleanValue(); |
return b; |
} else if (returnType.equals(char.class) && value instanceof Character) { |
// if Character, cast to int and assume set if different than |
// 0... |
final int c = ((Character) value).charValue(); |
return c != 0; |
} else if (returnType.isPrimitive() && !returnType.equals(boolean.class) && !returnType.equals(char.class) && value instanceof Number) { |
// if number consider everything different than zero to be set... |
final Number n = (Number) value; |
if (n.doubleValue() != 0d) { |
return true; |
} |
} else { |
return true; |
} |
} |
return false; |
} |
@Override |
public int update(final Object bean, Object... forceNull) { |
return update(bean, true, getProperties(forceNull)); |
} |
@Override |
public int updateAll(final Object bean) { |
return update(bean, false, null); |
} |
private int update(final Object bean, final boolean dynUpdate, String[] nullProps) { |
final Map<String, Value> fieldsLoaded = loaded.get(bean); |
final BeanConfig bc = getConfigFor(bean.getClass()); |
if (bc == null) { |
throw new BeanException("Cannot find bean config: " + bean.getClass()); |
} |
if (bc.getNumberOfFields() == 0) { |
throw new BeanException("BeanConfig has zero fields: " + bc); |
} |
final StringBuilder sb = new StringBuilder(32 * bc.getNumberOfFields()); |
sb.append("UPDATE ").append(bc.getTableName()).append(" SET "); |
Iterator<DBField> iter = bc.fields(); |
int count = 0; |
final List<Value> values = new LinkedList<Value>(); |
while (iter.hasNext()) { |
final DBField dbField = iter.next(); |
if (dbField.isPK()) { |
continue; |
} |
final DBType type = dbField.getType(); |
if (type instanceof AutoIncrementType) { |
continue; |
} |
if (type instanceof AutoTimestampType) { |
continue; |
} |
boolean isNowOnUpdate = type instanceof NowOnUpdateTimestampType || type instanceof NowOnInsertAndUpdateTimestampType; |
final String fieldName = dbField.getName(); |
final String dbFieldName = dbField.getDbName(); |
if (!isNowOnUpdate) { |
Method m = findMethodToGet(bean, fieldName); |
Object value = null; |
Class<? extends Object> returnType = null; |
boolean isNestedProperty = fieldName.contains("."); |
if (m == null && !isNestedProperty) { |
throw new BeanException("Cannot find method to get field from bean: " + fieldName); |
} |
if (m != null) { |
returnType = m.getReturnType(); |
value = getValueFromBean(bean, fieldName, m); |
} |
boolean update = false; |
if (!dynUpdate) { |
// if this is NOT a dynUpdate then update all properties with |
// whatever value they have |
update = true; |
} else if (fieldsLoaded != null) { |
// this is a dynUpdate, check if value is dirty, in other words, |
// if it has changed since it was loaded... |
final Value v = fieldsLoaded.get(fieldName); |
if (v != null) { |
if (value == null && v.value != null) { |
update = true; |
} else if (value != null && v.value == null) { |
update = true; |
} else if (value == null && v.value == null) { |
update = false; |
} else { |
update = !value.equals(v.value); |
} |
} |
} else { |
// this is a dynUpdate, but bean was not previously loaded from |
// the database... |
// in this case only update if the property is considered to be |
// SET... |
update = isSet(value, returnType); |
if (!update && nullProps != null) { |
update = checkArray(fieldName, nullProps, bc); |
//null in database column |
value = null; |
} |
} |
if (update) { |
if (count++ > 0) { |
sb.append(','); |
} |
sb.append(dbFieldName).append("=?"); |
values.add(new Value(dbField, value)); |
} |
} else { |
if (count++ > 0) { |
sb.append(','); |
} |
sb.append(dbFieldName).append("="); |
String nowCommand = getCurrentTimestampCommand(); |
if (nowCommand == null) { |
sb.append("?"); |
values.add(new Value(dbField, new java.util.Date())); |
} else { |
sb.append(nowCommand); |
} |
} |
} |
if (count == 0) { |
return 0; |
} |
sb.append(" WHERE "); |
if (!bc.hasPK()) { |
throw new BeanException("Cannot update bean without a PK!"); |
} |
iter = bc.pks(); |
count = 0; |
while (iter.hasNext()) { |
final DBField dbField = iter.next(); |
final String fieldName = dbField.getName(); |
final String dbFieldName = dbField.getDbName(); |
final Object value = getValueFromBean(bean, fieldName); |
if (value == null) { |
throw new BeanException("pk is missing: " + dbField); |
} else if (value instanceof Number) { |
final Number n = (Number) value; |
if (n.doubleValue() <= 0) { |
throw new BeanException("Number pk is missing: " + dbField); |
} |
} |
if (count++ > 0) { |
sb.append(" AND "); |
} |
sb.append(dbFieldName).append("=?"); |
values.add(new Value(dbField, value)); |
} |
if (values.isEmpty()) { |
throw new BeanException("Bean is empty: " + bean + " / " + bc); |
} |
if (conn == null) { |
throw new BeanException("Connection is null!"); |
} |
PreparedStatement stmt = null; |
try { |
if (DEBUG) { |
System.out.println("UPDATE SQL: " + sb.toString()); |
} |
dispatchBeforeUpdate(bean); |
stmt = conn.prepareStatement(sb.toString()); |
Iterator<Value> iter2 = values.iterator(); |
int index = 0; |
while (iter2.hasNext()) { |
final Value v = iter2.next(); |