bug fixed for mapping

This commit is contained in:
温少
2012-05-08 19:32:39 +08:00
parent 55a673218e
commit bb0a557b81
7 changed files with 204 additions and 33 deletions
@@ -98,6 +98,7 @@ public class MappingEngine {
MappingVisitor visitor = this.createMappingVisitor(parameters);
query.accept(visitor);
visitor.afterResolve();
afterResole(visitor);
return toSQL(query);
@@ -116,6 +117,7 @@ public class MappingEngine {
MappingVisitor visitor = this.createMappingVisitor(Collections.emptyList());
stmt.accept(visitor);
visitor.afterResolve();
afterResole(visitor);
return toSQL(stmt);
@@ -138,6 +140,7 @@ public class MappingEngine {
MappingVisitor visitor = this.createMappingVisitor(Collections.emptyList());
stmt.accept(visitor);
visitor.afterResolve();
afterResole(visitor);
return toSQL(stmt);
@@ -152,6 +155,7 @@ public class MappingEngine {
MappingVisitor visitor = this.createMappingVisitor(Collections.emptyList());
stmt.accept(visitor);
visitor.afterResolve();
afterResole(visitor);
return toSQL(stmt);
@@ -9,6 +9,7 @@ import java.util.Map;
import com.alibaba.druid.mapping.Entity;
import com.alibaba.druid.mapping.MappingEngine;
import com.alibaba.druid.mapping.Property;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
@@ -30,6 +31,7 @@ public class MSSQLServerMappingVisitor extends SQLServerASTVisitorAdapter implem
private final List<Object> parameters;
private final List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
private int variantIndex = 0;
private final List<SQLExpr> unresolveList = new ArrayList<SQLExpr>();
public MSSQLServerMappingVisitor(MappingEngine engine){
this(engine, Collections.emptyList());
@@ -81,8 +83,7 @@ public class MSSQLServerMappingVisitor extends SQLServerASTVisitorAdapter implem
@Override
public boolean visit(SQLSelectItem x) {
x.getExpr().setParent(x);
return true;
return MappingVisitorUtils.visit(this, x);
}
@Override
@@ -129,13 +130,23 @@ public class MSSQLServerMappingVisitor extends SQLServerASTVisitorAdapter implem
public boolean visit(SQLExprTableSource x) {
return MappingVisitorUtils.visit(this, x);
}
@Override
public int getAndIncrementVariantIndex() {
return variantIndex++;
}
public int getVariantIndex() {
return variantIndex;
}
public List<SQLExpr> getUnresolveList() {
return unresolveList;
}
@Override
public void afterResolve() {
MappingVisitorUtils.afterResolve(this);
}
}
@@ -6,6 +6,7 @@ import java.util.Map;
import com.alibaba.druid.mapping.Entity;
import com.alibaba.druid.mapping.MappingEngine;
import com.alibaba.druid.mapping.Property;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.visitor.SQLASTVisitor;
@@ -29,4 +30,8 @@ public interface MappingVisitor extends SQLASTVisitor {
List<PropertyValue> getPropertyValues();
int getAndIncrementVariantIndex();
List<SQLExpr> getUnresolveList();
void afterResolve();
}
@@ -1,5 +1,6 @@
package com.alibaba.druid.mapping.spi;
import java.util.Iterator;
import java.util.Map;
import com.alibaba.druid.mapping.DruidMappingException;
@@ -74,6 +75,11 @@ public class MappingVisitorUtils {
Property property = null;
Entity entity = visitor.getEntity(ownerName);
if (entity == null) {
visitor.getUnresolveList().add(x);
return false;
}
property = entity.getProperty(propertyName);
if (property == null) {
@@ -100,16 +106,21 @@ public class MappingVisitorUtils {
Property property = null;
Entity propertyEntity = null;
for (Entity entity : visitor.getEntities().values()) {
property = entity.getProperty(propertyName);
if (property != null) {
propertyEntity = entity;
break;
for (SQLTableSource tableSource : visitor.getTableSources().values()) {
Entity entity = (Entity) tableSource.getAttribute("mapping.entity");
if (entity != null) {
property = entity.getProperty(propertyName);
if (property != null) {
propertyEntity = entity;
break;
}
}
}
if (property == null) {
throw new DruidMappingException("property not found : " + propertyName);
visitor.getUnresolveList().add(x);
return false;
}
String dbColumName = visitor.resovleColumnName(propertyEntity, property);
@@ -128,6 +139,11 @@ public class MappingVisitorUtils {
return false;
}
public static boolean visit(MappingVisitor visitor, SQLSelectItem x) {
x.getExpr().setParent(x);
return true;
}
public static boolean visit(MappingVisitor visitor, SQLBinaryOpExpr x) {
if (x.getOperator() == SQLBinaryOperator.Equality) {
if (x.getLeft() instanceof SQLIdentifierExpr && isSimpleValue(visitor, x.getRight())) {
@@ -190,6 +206,71 @@ public class MappingVisitorUtils {
return false;
}
public static void afterResolve(MappingVisitor visitor) {
for (Iterator<SQLExpr> iter = visitor.getUnresolveList().iterator();iter.hasNext();) {
SQLExpr expr = iter.next();
if (expr instanceof SQLIdentifierExpr) {
if (resolve(visitor, (SQLIdentifierExpr) expr)) {
iter.remove();
}
} else if (expr instanceof SQLPropertyExpr) {
if (resolve(visitor, (SQLPropertyExpr) expr)) {
iter.remove();
}
}
}
}
public static boolean resolve(MappingVisitor visitor, SQLIdentifierExpr x) {
String propertyName = x.getName();
for (SQLTableSource tableSource : visitor.getTableSources().values()) {
Entity entity = (Entity) tableSource.getAttribute("mapping.entity");
if (entity != null) {
Property property = entity.getProperty(propertyName);
if (property != null) {
String columnName = visitor.resovleColumnName(entity, property);
x.setName(columnName);
x.putAttribute("mapping.entity", entity);
x.putAttribute("mapping.property", property);
return true;
}
}
}
return false;
}
public static boolean resolve(MappingVisitor visitor, SQLPropertyExpr x) {
if (x.getOwner() instanceof SQLIdentifierExpr) {
String ownerName = ((SQLIdentifierExpr) x.getOwner()).getName();
SQLTableSource tableSource = visitor.getTableSources().get(ownerName);
Entity entity = (Entity) tableSource.getAttribute("mapping.entity");
if (entity != null) {
Property property = entity.getProperty(x.getName());
if (property != null) {
String columnName = visitor.resovleColumnName(entity, property);
x.setName(columnName);
x.putAttribute("mapping.entity", entity);
x.putAttribute("mapping.property", property);
if (x.getParent() instanceof SQLSelectItem) {
SQLSelectItem selectItem = (SQLSelectItem) x.getParent();
if (selectItem.getAlias() == null) {
selectItem.setAlias('"' + property.getName() + '"');
}
}
return true;
}
}
}
return false;
}
public static boolean visit(MappingVisitor visitor, SQLVariantRefExpr x) {
Map<String, Object> attributes = x.getAttributes();
Integer varIndex = (Integer) attributes.get("mapping.varIndex");
@@ -9,6 +9,7 @@ import java.util.Map;
import com.alibaba.druid.mapping.Entity;
import com.alibaba.druid.mapping.MappingEngine;
import com.alibaba.druid.mapping.Property;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
@@ -30,6 +31,7 @@ public class MySqlMappingVisitor extends MySqlASTVisitorAdapter implements Mappi
private final List<Object> parameters;
private final List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
private int variantIndex = 0;
private final List<SQLExpr> unresolveList = new ArrayList<SQLExpr>();
public MySqlMappingVisitor(MappingEngine engine){
this(engine, Collections.emptyList());
@@ -80,8 +82,7 @@ public class MySqlMappingVisitor extends MySqlASTVisitorAdapter implements Mappi
@Override
public boolean visit(SQLSelectItem x) {
x.getExpr().setParent(x);
return true;
return MappingVisitorUtils.visit(this, x);
}
@Override
@@ -137,4 +138,13 @@ public class MySqlMappingVisitor extends MySqlASTVisitorAdapter implements Mappi
public int getVariantIndex() {
return variantIndex;
}
public List<SQLExpr> getUnresolveList() {
return unresolveList;
}
@Override
public void afterResolve() {
MappingVisitorUtils.afterResolve(this);
}
}
@@ -9,6 +9,7 @@ import java.util.Map;
import com.alibaba.druid.mapping.Entity;
import com.alibaba.druid.mapping.MappingEngine;
import com.alibaba.druid.mapping.Property;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLPropertyExpr;
@@ -32,6 +33,7 @@ public class OracleMappingVisitor extends OracleASTVisitorAdapter implements Map
private final List<Object> parameters;
private final List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();
private int variantIndex = 0;
private final List<SQLExpr> unresolveList = new ArrayList<SQLExpr>();
public OracleMappingVisitor(MappingEngine engine){
this(engine, Collections.emptyList());
@@ -82,8 +84,7 @@ public class OracleMappingVisitor extends OracleASTVisitorAdapter implements Map
@Override
public boolean visit(SQLSelectItem x) {
x.getExpr().setParent(x);
return true;
return MappingVisitorUtils.visit(this, x);
}
@Override
@@ -150,4 +151,13 @@ public class OracleMappingVisitor extends OracleASTVisitorAdapter implements Map
public int getVariantIndex() {
return variantIndex;
}
public List<SQLExpr> getUnresolveList() {
return unresolveList;
}
@Override
public void afterResolve() {
MappingVisitorUtils.afterResolve(this);
}
}
@@ -19,14 +19,26 @@ public class MySqlMappingShardingTest extends TestCase {
MappingEngine engine = new ShardingMappingEngine();
protected void setUp() throws Exception {
Entity entity = new Entity();
entity.setName("用户");
entity.setTableName("user");
{
Entity entity = new Entity();
entity.setName("用户");
entity.setTableName("user");
entity.addProperty(new Property("名称", "", "uid"));
entity.addProperty(new Property("昵称", "", "name"));
entity.addProperty(new Property("名称", "", "uid"));
entity.addProperty(new Property("昵称", "", "name"));
engine.addEntity(entity);
}
{
Entity entity = new Entity();
entity.setName("英雄");
entity.setTableName("hero");
engine.addEntity(entity);
entity.addProperty(new Property("用户名", "", "uid"));
entity.addProperty(new Property("称号", "", "name"));
engine.addEntity(entity);
}
}
public void test_0() throws Exception {
@@ -35,33 +47,71 @@ public class MySqlMappingShardingTest extends TestCase {
String sql = engine.explainToSelectSQL(oql);
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
"FROM user_a u\n" + //
"WHERE u.uid = 'a'";
"FROM user_a u\n" + //
"WHERE u.uid = 'a'";
Assert.assertEquals(expected, sql);
}
public void test_1() throws Exception {
String oql = "select * from 用户 u where u.名称 = ?";
String sql = engine.explainToSelectSQL(oql, Collections.<Object>singletonList("a"));
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("a"));
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
"FROM user_a u\n" + //
"WHERE u.uid = ?";
"FROM user_a u\n" + //
"WHERE u.uid = ?";
Assert.assertEquals(expected, sql);
}
public void test_2() throws Exception {
String oql = "select * from 用户 u where u.名称 = ?";
String sql = engine.explainToSelectSQL(oql, Collections.<Object>singletonList("b"));
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
"FROM user_x u\n" + //
"WHERE u.uid = ?";
"FROM user_x u\n" + //
"WHERE u.uid = ?";
Assert.assertEquals(expected, sql);
}
public void test_3() throws Exception {
String oql = "select h.用户名, u.昵称 from 用户 u left join 英雄 h on h.用户名 = u.名称 where u.名称 = 2";
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
String expected = "SELECT h.uid AS \"用户名\", u.name AS \"昵称\"\n" + //
"FROM user_x u LEFT JOIN hero h ON h.uid = u.uid\n" + //
"WHERE u.uid = 2";
System.out.println(sql);
Assert.assertEquals(expected, sql);
}
public void test_4() throws Exception {
String oql = "select * from 用户 u where 名称 = ?";
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
String expected = "SELECT uid AS \"名称\", name AS \"昵称\"\n" + //
"FROM user_x u\n" + //
"WHERE uid = ?";
Assert.assertEquals(expected, sql);
}
public void test_5() throws Exception {
String oql = "select h.用户名, u.昵称 from 用户 u left join 英雄 h on h.用户名 = u.名称 where 名称 = 2";
String sql = engine.explainToSelectSQL(oql, Collections.<Object> singletonList("b"));
String expected = "SELECT h.uid AS \"用户名\", u.name AS \"昵称\"\n" + //
"FROM user_x u LEFT JOIN hero h ON h.uid = u.uid\n" + //
"WHERE uid = 2";
System.out.println(sql);
Assert.assertEquals(expected, sql);
}