MentaBean

Compare Revisions

Ignore whitespace Rev 180 → Rev 181

/trunk/src/test/java/org/mentabean/jdbc/AnsiSQLBeanSessionTest.java
863,6 → 863,189
}
@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();
/trunk/src/main/java/org/mentabean/sql/TableAlias.java
43,14 → 43,22
*
* @return the columns to build a select statement
*/
public String columns() {
public String columns(Object... props) {
if (prefix != null) {
return session.buildSelect(beanClass, prefix);
return session.buildSelect(beanClass, prefix, props);
} else {
return session.buildSelect(beanClass);
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.
*
/trunk/src/main/java/org/mentabean/jdbc/QueryBuilder.java
501,6 → 501,11
public GroupBy groupBy() {
return new GroupBy();
}
 
@Override
public GroupBy groupBy(Param... p) {
return new GroupBy(p);
}
}
 
/**
957,6 → 962,11
public GroupBy groupBy(Alias<?>... aliases) {
return new GroupBy(aliases);
}
@Override
public GroupBy groupBy(Param... params) {
return new GroupBy(params);
}
 
@Override
public GroupBy groupByProp(Alias<?> alias, Object... properties) {
1248,6 → 1258,11
add(alias);
}
private GroupBy(Param... params) {
init();
add(params);
}
private GroupBy() {
init();
add(aliases.toArray(new Alias<?>[0]));
1278,6 → 1293,18
return this;
}
public GroupBy add(Param... params) {
for (Param p : params) {
if (!sb.toString().endsWith(" GROUP BY "))
sb.append(',');
append(p);
}
return this;
}
 
public Having having() {
return new Having(true);
1475,6 → 1502,8
public interface CanGroupBy {
 
public GroupBy groupBy(Alias<?>... aliases);
public GroupBy groupBy(Param... p);
 
public GroupBy groupByProp(Alias<?> alias, Object... properties);
1575,7 → 1604,8
} catch (Exception e) {
throw new BeanException("Unable to execute query from QueryBuilder", e);
throw new BeanException("Unable to execute query from QueryBuilder\n"+
e.getMessage(), e);
}finally {
SQLUtils.close(ppst);
1612,7 → 1642,8
 
} catch (Exception e) {
 
throw new BeanException("Unable to execute sentence from QueryBuilder", e);
throw new BeanException("Unable to execute sentence from QueryBuilder\n"+
e.getMessage(), e);
}finally {
 
SQLUtils.close(ppst);
/trunk/src/main/java/org/mentabean/util/SQLBuilder.java
27,12 → 27,12
this.aliases = aliases;
}
private TableAlias<?> findAlias(Class<?> klass) {
private TableAlias<?> findAlias(Object instance) {
if (aliases == null) return null;
for(TableAlias<?> alias : aliases) {
if (alias.beanClass().equals(klass)) {
if (alias.proxy() == instance) {
return alias;
}
}
46,13 → 46,13
// you are really adding a column name:
append((String) obj);
} else {
Class<?>[] klasses = PropertiesProxy.getBeanClasses();
if (klasses == null || klasses.length == 0) throw new IllegalStateException("Cannot find bean class!");
Object[] instances = PropertiesProxy.getBeanInstances();
if (instances == null || instances.length == 0) throw new IllegalStateException("Cannot find bean instance!");
// here we assume the very first klass:
Class<?> klass = klasses[0];
TableAlias<?> alias = findAlias(klass);
if (alias == null) throw new IllegalStateException("Cannot find alias: " + klass);
Object instance = instances[0];
TableAlias<?> alias = findAlias(instance);
if (alias == null) throw new IllegalStateException("Cannot find alias: " + instance);
append(alias.column(null)); // null because it will get from proxy
}
/trunk/src/main/java/org/mentabean/util/PropertiesProxy.java
33,7 → 33,7
}
private static final ThreadLocal<List<String>> propertyNames = new ThreadLocal<List<String>>();
private static final ThreadLocal<List<Class<?>>> klassTypes = new ThreadLocal<List<Class<?>>>();
private static final ThreadLocal<List<Object>> beanInstances = new ThreadLocal<List<Object>>();
public static String getPropertyName() {
47,21 → 47,21
list.clear();
// take this time to also clear the classes:
List<Class<?>> types = klassTypes.get();
if (types != null) types.clear();
List<Object> beans = beanInstances.get();
if (beans != null) beans.clear();
return propName;
}
public static Class<?>[] getBeanClasses() {
public static Object[] getBeanInstances() {
List<Class<?>> list = klassTypes.get();
List<Object> list = beanInstances.get();
if (list == null || list.size() == 0) {
throw new BeanException("Was not able to get bean classes through the proxy!");
throw new BeanException("Was not able to get bean instances through the proxy!");
}
Class<?>[] array = new Class<?>[list.size()];
Object[] array = new Object[list.size()];
array = list.toArray(array);
99,9 → 99,9
list.clear();
// take this time to also clear the classes:
List<Class<?>> types = klassTypes.get();
if (types != null) types.clear();
// take this time to also clear the instances:
List<Object> beans = beanInstances.get();
if (beans != null) beans.clear();
return array;
}
186,14 → 186,14
}
// add the object type for SQLBuilder column( ... ) method
List<Class<?>> types = klassTypes.get();
List<Object> beans = beanInstances.get();
if (types == null) {
types = new LinkedList<Class<?>>();
klassTypes.set(types);
if (beans == null) {
beans = new LinkedList<Object>();
beanInstances.set(beans);
}
types.add(klass);
beans.add(self);
Class<?> propType = thisMethod.getReturnType();