Skip to content

Commit

Permalink
binder
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaeluchoa committed Nov 11, 2017
1 parent cb84569 commit a547351
Show file tree
Hide file tree
Showing 15 changed files with 368 additions and 59 deletions.
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Create Queries, Inserts, Updates e Deletes using only POJO classes.
* Glue code: it’s only a small and simple classes set;
* Fluent Builder: code complete is your friend!
* Check compiler: Refactory ? No problem. Do the compiler to work to you.
* Performance-based: if you are paranoid by performance, use binder parameters to create Queries, Insert, Update and Deletes.

## Examples

Expand Down Expand Up @@ -98,6 +99,12 @@ public void testTwoEntities() {
Assert.assertEquals(result.params().get("p1"), 0.0);
}
```


### Insert, Update and Delete

```
@Test
public void testInsert() {
String expected = "insert into Customer (id, name, minBalance) values (:p0, :p1, :p2)";
Expand Down Expand Up @@ -151,6 +158,44 @@ public void testDelete() {
Assert.assertEquals(expected, actual);
Assert.assertEquals(result.params().get("p0"), 1L);
}
```


### Binder Parameters

```
@Test
public void testMultipleInsert() {
String expected = "insert into Customer (name) values (:p0)";
BinderSQL<Customer> binder = binderBuilder
.from(Customer.class);
binder.configure(new InsertBuilder()
.into(Customer.class)
.value(i -> i.getName()).set(binder.get(i -> i.getName()))
.to(new NativeSQLInsertInto())
);
Customer customer1 = new Customer();
customer1.setName("teste");
Customer customer2 = new Customer();
customer2.setName("rafael");
NativeSQLResult result1 = binder.bind(customer1);
NativeSQLResult result2 = binder.bind(customer2);
String actual1 = result1.sql();
String actual2 = result2.sql();
Assert.assertEquals(expected, actual1);
Assert.assertEquals(expected, actual2);
Assert.assertEquals(result1.params().get("p0"), customer1.getName());
Assert.assertEquals(result2.params().get("p0"), customer2.getName());
}
```

Expand All @@ -175,6 +220,9 @@ public void testDelete() {

## Releases

### 0.2.0
- Use Binder parameters to create caches for queries, inserts, updates and delete sqls.

### 0.1.0
- Insert, Update and Delete included.

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.naskar</groupId>
<artifactId>fluent-query</artifactId>
<packaging>jar</packaging>
<version>0.1.0</version>
<version>0.2.0</version>
<name>fluent-query</name>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/naskar/fluentquery/binder/Binder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.naskar.fluentquery.binder;

public interface Binder<T, R> {

R bind(T t);

}
15 changes: 15 additions & 0 deletions src/main/java/com/naskar/fluentquery/binder/BinderSQL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.naskar.fluentquery.binder;

import java.util.function.Function;

import com.naskar.fluentquery.converters.NativeSQLResult;

public interface BinderSQL<T> extends Binder<T, NativeSQLResult> {

void configure(NativeSQLResult result);

<R> R get(Function<T, R> getter);

NativeSQLResult bind(T t);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.naskar.fluentquery.binder;

public class BinderSQLBuilder {

public <T> BinderSQL<T> from(Class<T> clazz) {
return new BinderSQLImpl<T>(clazz);
}

}
81 changes: 81 additions & 0 deletions src/main/java/com/naskar/fluentquery/binder/BinderSQLImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.naskar.fluentquery.binder;

import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;

import com.naskar.fluentquery.converters.NativeSQLResult;
import com.naskar.fluentquery.impl.MethodRecordProxy;

public class BinderSQLImpl<T> implements BinderSQL<T> {

private NativeSQLResult result;

private Map<Object, Function<T, ?>> maps;
private MethodRecordProxy<T> proxy;

public BinderSQLImpl(Class<T> clazz) {
this.maps = new IdentityHashMap<Object, Function<T, ?>>();
this.proxy = new MethodRecordProxy<T>(clazz);
this.proxy.setExecute(false);
}

@Override
public void configure(NativeSQLResult result) {
this.result = result;
}

@Override
public <R> R get(Function<T, R> getter) {
proxy.clear();
getter.apply(proxy.getProxy());

R r = createInstance(proxy.getCalledMethod().getReturnType());

maps.put(r, getter);

return r;
}

@SuppressWarnings("unchecked")
private <R, E> R createInstance(Class<E> returnType) {
if(Long.class.equals(returnType)) {
return (R) new Long(0L);

} else if(Double.class.equals(returnType)) {
return (R) new Double(0L);

} else {
return (R)MethodRecordProxy.createInstance(returnType);
}
}

@Override
public NativeSQLResult bind(T t) {

NativeSQLResult newResult = new NativeSQLResult();
newResult.sql(result.sql());

Map<String, Object> params = newResult.params();
List<Object> values = newResult.values();

for(Entry<String, Object> e : result.params().entrySet()) {

Object v = e.getValue();

Function<T, ?> f = maps.get(e.getValue());
if(f != null) {
v = f.apply(t);

}

params.put(e.getKey(), v);
values.add(v);
}

return newResult;
}

}
11 changes: 1 addition & 10 deletions src/main/java/com/naskar/fluentquery/converters/NativeSQL.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ public <T> NativeSQLResult convert(QueryImpl<T> queryImpl) {
}

private <T> void convert(QueryImpl<T> queryImpl, QueryParts parts, final HolderInt level, NativeSQLResult result, List<String> parents) {
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(
createInstance(queryImpl.getClazz()));
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(queryImpl.getClazz());

String alias = "e" + level + ".";

Expand Down Expand Up @@ -145,14 +144,6 @@ private <T> void convertFroms(
});
}

private <T> T createInstance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private <T> void convertSelect(
StringBuilder sb, String alias,
MethodRecordProxy<T> proxy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,15 @@ public <T> NativeSQLResult convert(DeleteImpl<T> deleteImpl) {

private <T> void convert(DeleteImpl<T> deleteImpl, DeleteParts parts,
final HolderInt level, NativeSQLResult result, List<String> parents) {
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(createInstance(deleteImpl.getClazz()));
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(deleteImpl.getClazz());

String alias = "e" + level + ".";

convertTable(parts.getTable(), alias, deleteImpl.getClazz());

nativeWhereImpl.convertWhere(parts.getWhere(), alias, proxy, parents, deleteImpl.getPredicates(), result);
}

private <T> T createInstance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}


private <T> void convertTable(StringBuilder sb, String alias, Class<T> clazz) {
sb.append(convention.getNameFromClass(clazz) + " " +
alias.substring(0, alias.length()-1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,12 @@ public <T> NativeSQLResult convert(IntoImpl<T> intoImpl) {
}

private <T> void convert(IntoImpl<T> intoImpl, InsertParts parts, NativeSQLResult result) {
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(createInstance(intoImpl.getClazz()));
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(intoImpl.getClazz());
convertInto(parts.getInto(), intoImpl.getClazz());
convertColumns(parts.getColumns(), proxy, intoImpl.getValues());
convertValues(parts.getValues(), proxy, intoImpl.getValues(), result);
}

private <T> T createInstance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private <T> void convertInto(StringBuilder sb, Class<T> clazz) {
sb.append(convention.getNameFromClass(clazz));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public <T> NativeSQLResult convert(UpdateImpl<T> updateImpl) {

private <T> void convert(UpdateImpl<T> updateImpl, UpdateParts parts,
final HolderInt level, NativeSQLResult result, List<String> parents) {
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(createInstance(updateImpl.getClazz()));
MethodRecordProxy<T> proxy = new MethodRecordProxy<T>(updateImpl.getClazz());

String alias = "e" + level + ".";

Expand All @@ -77,14 +77,6 @@ private <T> void convert(UpdateImpl<T> updateImpl, UpdateParts parts,
nativeWhereImpl.convertWhere(parts.getWhere(), alias, proxy, parents, updateImpl.getPredicates(), result);
}

private <T> T createInstance(Class<T> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private <T> void convertTable(StringBuilder sb, String alias, Class<T> clazz) {
sb.append(convention.getNameFromClass(clazz) + " " +
alias.substring(0, alias.length()-1));
Expand Down
46 changes: 34 additions & 12 deletions src/main/java/com/naskar/fluentquery/impl/MethodRecordProxy.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ public class MethodRecordProxy<T> implements MethodInterceptor {
private T target;
private List<Method> methods;
private MethodRecordProxy<?> parent;
private boolean execute;

@SuppressWarnings("unchecked")
public MethodRecordProxy(T target) {
this.target = target;
this.methods = new ArrayList<Method>();
this.execute = true;

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
Expand All @@ -27,6 +29,22 @@ public MethodRecordProxy(T target) {
this.proxy = (T) enhancer.create();
}

public void setExecute(boolean execute) {
this.execute = execute;
}

public MethodRecordProxy(Class<T> clazz) {
this(createInstance(clazz));
}

public static <E> E createInstance(Class<E> clazz) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private <E> MethodRecordProxy(T target, MethodRecordProxy<E> parent) {
this(target);
this.parent = parent;
Expand All @@ -42,20 +60,24 @@ public Object intercept(Object object, Method method, Object[] args, MethodProxy
this.methods.add(method);
}

Object result = methodProxy.invoke(target, args);

if(result == null && !TypeUtils.isValueType(method.getReturnType())) {
try {
Object o = method.getReturnType().newInstance();
MethodRecordProxy proxyTmp =
new MethodRecordProxy(o, parent != null ? parent : this);
result = proxyTmp.getProxy();
} catch(Exception e) {
result = null;
if(execute) {
Object result = methodProxy.invoke(target, args);

if(result == null && !TypeUtils.isValueType(method.getReturnType())) {
try {
Object o = method.getReturnType().newInstance();
MethodRecordProxy proxyTmp =
new MethodRecordProxy(o, parent != null ? parent : this);
result = proxyTmp.getProxy();
} catch(Exception e) {
result = null;
}
}

return result;
} else {
return null;
}

return result;
}

public Method getCalledMethod() {
Expand Down
9 changes: 1 addition & 8 deletions src/main/java/com/naskar/fluentquery/mapping/Mapping.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,8 @@ public class Mapping<T> {
public Mapping<T> to(Class<T> clazz, String tableName) {
this.clazz = clazz;
this.tableName = tableName;

try {
this.proxy = new MethodRecordProxy<T>(clazz.newInstance());
} catch(Exception e) {
throw new RuntimeException(e);
}

this.proxy = new MethodRecordProxy<T>(clazz);
this.columns = new HashMap<List<Method>, String>();

return this;
}

Expand Down
Loading

0 comments on commit a547351

Please sign in to comment.