/*
* Copyright 2004-2011 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.test.synth.sql;
import java.util.ArrayList;
import org.h2.util.New;
/**
* Represents a table.
*/
class Table {
private TestSynth config;
private String name;
private boolean temporary;
private boolean globalTemporary;
private Column[] columns;
private Column[] primaryKeys;
private ArrayList<Index> indexes = New.arrayList();
Table(TestSynth config) {
this.config = config;
}
/**
* Create a new random table.
*
* @param config the configuration
* @return the table
*/
static Table newRandomTable(TestSynth config) {
Table table = new Table(config);
table.name = "T_" + config.randomIdentifier();
// there is a difference between local temp tables for persistent and
// in-memory mode
// table.temporary = config.random().getBoolean(10);
// if(table.temporary) {
// if(config.getMode() == TestSynth.H2_MEM) {
// table.globalTemporary = false;
// } else {
// table.globalTemporary = config.random().getBoolean(50);
// }
// }
int len = config.random().getLog(10) + 1;
table.columns = new Column[len];
for (int i = 0; i < len; i++) {
Column col = Column.getRandomColumn(config);
table.columns[i] = col;
}
if (config.random().getBoolean(90)) {
int pkLen = config.random().getLog(len);
table.primaryKeys = new Column[pkLen];
for (int i = 0; i < pkLen; i++) {
Column pk = null;
do {
pk = table.columns[config.random().getInt(len)];
} while (pk.getPrimaryKey());
table.primaryKeys[i] = pk;
pk.setPrimaryKey(true);
pk.setNullable(false);
}
}
return table;
}
/**
* Create a new random index.
*
* @return the index
*/
Index newRandomIndex() {
String indexName = "I_" + config.randomIdentifier();
int len = config.random().getLog(getColumnCount() - 1) + 1;
boolean unique = config.random().getBoolean(50);
Column[] cols = getRandomColumns(len);
Index index = new Index(this, indexName, cols, unique);
return index;
}
/**
* Get the DROP TABLE statement for this table.
*
* @return the SQL statement
*/
String getDropSQL() {
return "DROP TABLE " + name;
}
/**
* Get the CREATE TABLE statement for this table.
*
* @return the SQL statement
*/
String getCreateSQL() {
String sql = "CREATE ";
if (temporary) {
if (globalTemporary) {
sql += "GLOBAL ";
} else {
sql += "LOCAL ";
}
sql += "TEMPORARY ";
}
sql += "TABLE " + name + "(";
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
sql += ", ";
}
Column column = columns[i];
sql += column.getCreateSQL();
if (primaryKeys != null && primaryKeys.length == 1 && primaryKeys[0] == column) {
sql += " PRIMARY KEY";
}
}
if (primaryKeys != null && primaryKeys.length > 1) {
sql += ", ";
sql += "PRIMARY KEY(";
for (int i = 0; i < primaryKeys.length; i++) {
if (i > 0) {
sql += ", ";
}
Column column = primaryKeys[i];
sql += column.getName();
}
sql += ")";
}
sql += ")";
return sql;
}
/**
* Get the INSERT statement for this table.
*
* @param c the column list
* @param v the value list
* @return the SQL statement
*/
String getInsertSQL(Column[] c, Value[] v) {
String sql = "INSERT INTO " + name;
if (c != null) {
sql += "(";
for (int i = 0; i < c.length; i++) {
if (i > 0) {
sql += ", ";
}
sql += c[i].getName();
}
sql += ")";
}
sql += " VALUES(";
for (int i = 0; i < v.length; i++) {
if (i > 0) {
sql += ", ";
}
sql += v[i].getSQL();
}
sql += ")";
return sql;
}
/**
* Get the table name.
*
* @return the name
*/
String getName() {
return name;
}
/**
* Get a random column that can be used in a condition.
*
* @return the column
*/
Column getRandomConditionColumn() {
ArrayList<Column> list = New.arrayList();
for (Column col : columns) {
if (Column.isConditionType(config, col.getType())) {
list.add(col);
}
}
if (list.size() == 0) {
return null;
}
return list.get(config.random().getInt(list.size()));
}
Column getRandomColumn() {
return columns[config.random().getInt(columns.length)];
}
int getColumnCount() {
return columns.length;
}
/**
* Get a random column of the specified type.
*
* @param type the type
* @return the column or null if no such column was found
*/
Column getRandomColumnOfType(int type) {
ArrayList<Column> list = New.arrayList();
for (Column col : columns) {
if (col.getType() == type) {
list.add(col);
}
}
if (list.size() == 0) {
return null;
}
return list.get(config.random().getInt(list.size()));
}
/**
* Get a number of random column from this table.
*
* @param len the column count
* @return the columns
*/
Column[] getRandomColumns(int len) {
int[] index = new int[columns.length];
for (int i = 0; i < columns.length; i++) {
index[i] = i;
}
for (int i = 0; i < columns.length; i++) {
int temp = index[i];
int r = index[config.random().getInt(columns.length)];
index[i] = index[r];
index[r] = temp;
}
Column[] c = new Column[len];
for (int i = 0; i < len; i++) {
c[i] = columns[index[i]];
}
return c;
}
Column[] getColumns() {
return columns;
}
/**
* Add this index to the table.
*
* @param index the index to add
*/
void addIndex(Index index) {
indexes.add(index);
}
/**
* Remove an index from the table.
*
* @param index the index to remove
*/
void removeIndex(Index index) {
indexes.remove(index);
}
}