#604726 : added basic sketch and test

This commit is contained in:
Timo Westkämper 2010-07-13 01:11:24 +00:00
parent dc35c783ab
commit 7816bb3884
30 changed files with 471 additions and 24 deletions

View File

@ -112,20 +112,19 @@ public class MetaDataSerializer extends EntitySerializer {
String foreignType = namingStrategy.getClassName(namePrefix, foreignKey.getTable());
StringBuilder value = new StringBuilder();
value.append("new ForeignKey<"+foreignType+">(this, ");
if (foreignKey.getColumns().size() == 1){
Pair<String,String> pair = foreignKey.getColumns().get(0);
value.append(namingStrategy.getPropertyName(pair.getFirst(), namePrefix, model));
value.append(", \"" + pair.getSecond() + "\"");
if (foreignKey.getForeignColumns().size() == 1){
value.append(namingStrategy.getPropertyName(foreignKey.getForeignColumns().get(0), namePrefix, model));
value.append(", \"" + foreignKey.getParentColumns().get(0) + "\"");
}else{
StringBuilder local = new StringBuilder();
StringBuilder foreign = new StringBuilder();
for (Pair<String,String> pair : foreignKey.getColumns()){
if (local.length() > 0){
for (int i = 0; i < foreignKey.getForeignColumns().size(); i++){
if (i > 0){
local.append(", ");
foreign.append(", ");
}
local.append(namingStrategy.getPropertyName(pair.getFirst(), namePrefix, model));
foreign.append("\"" + pair.getSecond() + "\"");
local.append(namingStrategy.getPropertyName(foreignKey.getForeignColumns().get(0), namePrefix, model));
foreign.append("\"" +foreignKey.getParentColumns().get(0) + "\"");
}
value.append("Arrays.asList("+local+"), Arrays.asList("+foreign+")");
}

View File

@ -165,7 +165,10 @@ public class SQLTemplates extends Templates {
class2type.put(Byte.class, "tinyint");
class2type.put(Long.class, "bigint");
class2type.put(Short.class, "smallint");
class2type.put(String.class, "varchar");
class2type.put(String.class, "varchar");
class2type.put(java.sql.Date.class, "date");
class2type.put(java.sql.Time.class, "time");
class2type.put(java.sql.Timestamp.class, "timestamp");
}
public void addClass2TypeMappings(String type, Class<?>... classes) {

View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.ddl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mysema.commons.lang.Assert;
import com.mysema.query.QueryException;
import com.mysema.query.sql.SQLTemplates;
import com.mysema.query.sql.dml.SQLDeleteClause;
import com.mysema.query.sql.support.ColumnData;
import com.mysema.query.sql.support.ForeignKeyData;
import com.mysema.query.sql.support.PrimaryKeyData;
/**
* @author tiwe
*
*/
public class CreateTableClause {
private static final Logger logger = LoggerFactory.getLogger(CreateTableClause.class);
private final Connection connection;
private final SQLTemplates templates;
private final String table;
private final List<ColumnData> columns = new ArrayList<ColumnData>();
private PrimaryKeyData primaryKey;
private final List<ForeignKeyData> foreignKeys = new ArrayList<ForeignKeyData>();
public CreateTableClause(Connection conn, SQLTemplates templates, String table) {
this.connection = conn;
this.templates = templates;
this.table = table;
}
public CreateTableClause column(String name, Class<?> type) {
Assert.notNull(name,"name");
Assert.notNull(type,"type");
columns.add(new ColumnData(name, templates.getTypeForClass(type)));
return this;
}
private ColumnData lastColumn(){
return columns.get(columns.size()-1);
}
public CreateTableClause notNull() {
lastColumn().setNullAllowed(false);
return this;
}
public CreateTableClause size(int size) {
lastColumn().setSize(size);
return this;
}
public CreateTableClause primaryKey(String name, String... columns) {
Assert.notNull(name,"name");
Assert.notEmpty(columns,"columns");
primaryKey = new PrimaryKeyData(name, columns);
return this;
}
public ForeignKeyBuilder foreignKey(String name, String... columns) {
Assert.notNull(name,"name");
Assert.notEmpty(columns,"columns");
return new ForeignKeyBuilder(this, foreignKeys, name, columns);
}
public void execute() {
StringBuilder builder = new StringBuilder();
builder.append("CREATE TABLE " + table + " (\n");
List<String> lines = new ArrayList<String>(columns.size() + foreignKeys.size() + 1);
// columns
for (ColumnData column : columns){
StringBuilder line = new StringBuilder();
line.append(column.getName() + " " + column.getType().toUpperCase());
if (column.getSize() != null){
line.append("(" + column.getSize() + ")");
}
line.append(column.isNullAllowed() ? " NULL" : " NOT NULL");
lines.add(line.toString());
}
// primary key
if (primaryKey != null){
StringBuilder line = new StringBuilder();
line.append("CONSTRAINT " + primaryKey.getName()+ " ");
line.append("PRIMARY KEY(" + StringUtils.join(primaryKey.getColumns(), ", ") +")");
lines.add(line.toString());
}
// foreign keys
for (ForeignKeyData foreignKey : foreignKeys){
StringBuilder line = new StringBuilder();
line.append("CONSTRAINT " + foreignKey.getName()+ " ");
line.append("FOREIGN KEY(" + StringUtils.join(foreignKey.getForeignColumns(), ", ")+ ") ");
line.append("REFERENCES " + foreignKey.getTable() + "(" + StringUtils.join(foreignKey.getParentColumns(),", ")+ ")");
lines.add(line.toString());
}
builder.append(" " + StringUtils.join(lines, ",\n "));
builder.append("\n)\n");
logger.info(builder.toString());
Statement stmt = null;
try{
stmt = connection.createStatement();
stmt.execute(builder.toString());
} catch (SQLException e) {
throw new QueryException(e.getMessage(), e);
}finally{
if (stmt != null){
close(stmt);
}
}
}
protected void close(Statement stmt) {
try {
stmt.close();
} catch (SQLException e) {
throw new QueryException(e);
}
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.ddl;
import java.util.List;
import com.mysema.query.sql.support.ForeignKeyData;
/**
* @author tiwe
*
*/
public class ForeignKeyBuilder {
private final List<ForeignKeyData> foreignKeys;
private final CreateTableClause clause;
private final String name;
private final String[] foreignColumns;
public ForeignKeyBuilder(CreateTableClause clause, List<ForeignKeyData> foreignKeys, String name, String[] columns) {
this.clause = clause;
this.foreignKeys = foreignKeys;
this.name = name;
this.foreignColumns = columns;
}
public CreateTableClause references(String table, String... parentColumns) {
ForeignKeyData foreignKey = new ForeignKeyData(name, table);
for (int i = 0; i < parentColumns.length; i++){
foreignKey.add(foreignColumns[i], parentColumns[i]);
}
foreignKeys.add(foreignKey);
return clause;
}
}

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.mysql;
import java.io.File;

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.support;
/**
* @author tiwe
*
*/
public class ColumnData {
private final String name;
private final String type;
private boolean nullAllowed = true;
private Integer size;
public ColumnData(String name, String type) {
this.name = name;
this.type = type;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public boolean isNullAllowed() {
return nullAllowed;
}
public void setNullAllowed(boolean nullAllowed) {
this.nullAllowed = nullAllowed;
}
public void setSize(Integer size) {
this.size = size;
}
public Integer getSize() {
return size;
}
}

View File

@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List;
import com.mysema.commons.lang.Assert;
import com.mysema.commons.lang.Pair;
/**
* @author tiwe
@ -20,8 +19,10 @@ public class ForeignKeyData implements KeyData {
private final String name;
private final String table;
private final List<Pair<String,String>> columns = new ArrayList<Pair<String,String>>();
private final List<String> foreignColumns = new ArrayList<String>();
private final List<String> parentColumns = new ArrayList<String>();
public ForeignKeyData(String name, String parentTable) {
this.name = Assert.hasLength(name,"name");
@ -29,7 +30,8 @@ public class ForeignKeyData implements KeyData {
}
public void add(String foreignColumn, String parentColumn){
columns.add(Pair.of(foreignColumn, parentColumn));
foreignColumns.add(foreignColumn);
parentColumns.add(parentColumn);
}
public String getName() {
@ -40,8 +42,13 @@ public class ForeignKeyData implements KeyData {
return table;
}
public List<Pair<String, String>> getColumns() {
return columns;
public List<String> getForeignColumns() {
return foreignColumns;
}
public List<String> getParentColumns() {
return parentColumns;
}
}

View File

@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List;
import com.mysema.commons.lang.Assert;
import com.mysema.commons.lang.Pair;
/**
* @author tiwe
@ -20,8 +19,10 @@ public class InverseForeignKeyData implements KeyData{
private final String name;
private final String table;
private final List<Pair<String,String>> columns = new ArrayList<Pair<String,String>>();
private final List<String> foreignColumns = new ArrayList<String>();
private final List<String> parentColumns = new ArrayList<String>();
public InverseForeignKeyData(String name, String parentTable) {
this.name = Assert.hasLength(name,"name");
@ -29,7 +30,8 @@ public class InverseForeignKeyData implements KeyData{
}
public void add(String foreignColumn, String parentColumn){
columns.add(Pair.of(foreignColumn, parentColumn));
foreignColumns.add(foreignColumn);
parentColumns.add(parentColumn);
}
public String getName() {
@ -40,8 +42,12 @@ public class InverseForeignKeyData implements KeyData{
return table;
}
public List<Pair<String, String>> getColumns() {
return columns;
public List<String> getForeignColumns() {
return foreignColumns;
}
public List<String> getParentColumns() {
return parentColumns;
}
}

View File

@ -5,8 +5,6 @@ package com.mysema.query.sql.support;
import java.util.List;
import com.mysema.commons.lang.Pair;
/**
* Common interface for ForeignKeyData and InverseForeignKeyData
*
@ -18,7 +16,9 @@ public interface KeyData {
String getName();
String getTable();
List<String> getForeignColumns();
List<Pair<String, String>> getColumns();
List<String> getParentColumns();
}

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.support;
import java.sql.DatabaseMetaData;

View File

@ -23,6 +23,13 @@ public class PrimaryKeyData {
public PrimaryKeyData(String name) {
this.name = Assert.notNull(name,"name");
}
public PrimaryKeyData(String name, String[] c){
this.name = name;
for (String column : c){
columns.add(column);
}
}
public void add(String column){
columns.add(column);

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query;
import java.sql.Connection;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query;
import java.io.File;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query._derby;
import org.junit.BeforeClass;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query._h2;
import org.junit.BeforeClass;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query._hsqldb;
import org.junit.BeforeClass;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query._mssql;
import org.junit.BeforeClass;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query._mysql;
import org.junit.BeforeClass;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query._oracle;
import org.junit.BeforeClass;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;
import static org.junit.Assert.assertEquals;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;
public class H2TemplatesTest extends AbstractSQLTemplatesTest{

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;
import static org.junit.Assert.assertEquals;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;
import static org.junit.Assert.assertEquals;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql;
import static org.junit.Assert.assertEquals;

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.ddl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.mysema.query.sql.H2Templates;
import com.mysema.query.sql.SQLTemplates;
public class CreateTableClauseTest {
private Connection conn;
private SQLTemplates templates = new H2Templates();
@Before
public void setUp() throws ClassNotFoundException, SQLException{
Class.forName("org.h2.Driver");
String url = "jdbc:h2:target/h2";
conn = DriverManager.getConnection(url, "sa", "");
Statement stmt = conn.createStatement();
try {
stmt.execute("drop table language if exists");
stmt.execute("drop table symbol if exists");
stmt.execute("drop table statement if exists");
}finally{
stmt.close();
}
}
@After
public void tearDown() throws SQLException{
conn.close();
}
@Test
public void test() throws SQLException{
new CreateTableClause(conn, templates, "language")
.column("id", Integer.class).notNull()
.column("text", String.class).size(256).notNull()
.primaryKey("PK_LANGUAGE","id")
.execute();
new CreateTableClause(conn, templates, "symbol")
.column("id", Long.class).notNull()
.column("lexical", String.class).size(1024).notNull()
.column("datatype", String.class)
.column("lang", Integer.class)
.column("integer",Long.class)
.column("floating",Double.class)
.column("datetime",Timestamp.class)
.primaryKey("PK_SYMBOL","id")
.foreignKey("FK_LANG","lang").references("language","id")
.execute();
new CreateTableClause(conn, templates, "statement")
.column("model", Long.class)
.column("subject", Long.class).notNull()
.column("predicate", Long.class).notNull()
.column("object", Long.class).notNull()
.foreignKey("FK_MODEL","model").references("symbol","id")
.foreignKey("FK_SUBJECT","subject").references("symbol","id")
.foreignKey("FK_PREDICATE","predicate").references("symbol","id")
.foreignKey("FK_OBJECT","object").references("symbol","id")
.execute();
Statement stmt = conn.createStatement();
try{
stmt.execute("select id, text from language");
stmt.execute("select id, lexical, datatype, lang, integer, floating, datetime from symbol");
stmt.execute("select model, subject, predicate, object from statement");
}finally{
stmt.close();
}
}
}

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.mysql;
import static org.junit.Assert.assertEquals;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.oracle;
import static org.junit.Assert.assertEquals;

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2010 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.sql.support;
import static org.junit.Assert.assertFalse;