提交 c2b7d146 authored 作者: Thomas Mueller's avatar Thomas Mueller

Cleanup:

- Mainly Javadoc changes.
上级 6216db17
/*
* 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: James Moger
*/
package org.h2.jaqu;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.h2.jaqu.Table.JQTable;
import org.h2.jaqu.util.JdbcUtils;
import org.h2.jaqu.util.StringUtils;
import org.h2.jaqu.util.Utils;
/**
* Class to inspect a model and a database for the purposes of model validation
* and automatic model generation. This class finds the available schemas and
* tables and serves as the entry point for model generation and validation.
*/
public class DbInspector {
private Db db;
private DatabaseMetaData metaData;
private Class<? extends java.util.Date> dateClass = java.util.Date.class;
private int todoReviewWholeClass;
public DbInspector(Db db) {
this.db = db;
}
/**
* Set the preferred Date class.
* Possible values are: java.util.Date (default) and java.sql.Timestamp.
*
* @param dateClass the new date class
*/
public void setPreferredDateClass(Class<? extends java.util.Date> dateClass) {
this.dateClass = dateClass;
}
/**
* Generates models class skeletons for schemas and tables. If the table
* name is undefined, models will be generated for every table within the
* specified schema. Additionally, if no schema is defined, models will be
* generated for all schemas and all tables.
*
* @param schema the schema name (optional)
* @param table the table name (optional)
* @param packageName the package name (optional)
* @param annotateSchema (includes schema name in annotation)
* @param trimStrings (trims strings to maxLength of column)
* @return a list of complete model classes as strings, each element a class
*/
public List<String> generateModel(String schema, String table,
String packageName, boolean annotateSchema, boolean trimStrings) {
try {
List<String> models = Utils.newArrayList();
List<TableInspector> tables = findTables(schema, table);
for (TableInspector t : tables) {
t.read(metaData);
String model = t.generateModel(packageName, annotateSchema,
trimStrings);
models.add(model);
}
return models;
} catch (SQLException s) {
throw new RuntimeException(s);
}
}
/**
* Validates a model.
*
* @param <T> the model class
* @param model and instance of the model class
* @param throwOnError
* @return
*/
public <T> List<Validation> validateModel(T model, boolean throwOnError) {
try {
TableInspector inspector = findTable(model);
inspector.read(metaData);
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) model.getClass();
TableDefinition<T> def = db.define(clazz);
return inspector.validate(def, throwOnError);
} catch (SQLException s) {
throw new RuntimeException(s);
}
}
private DatabaseMetaData getMetaData() throws SQLException {
if (metaData == null) {
metaData = db.getConnection().getMetaData();
}
return metaData;
}
/**
* Attempts to find a table in the database based on the model definition.
*
* @param <T>
* @param model
* @return
* @throws SQLException
*/
private <T> TableInspector findTable(T model) throws SQLException {
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) model.getClass();
TableDefinition<T> def = db.define(clazz);
boolean forceUpperCase = getMetaData().storesUpperCaseIdentifiers();
String sname = (forceUpperCase && def.schemaName != null) ?
def.schemaName.toUpperCase() : def.schemaName;
String tname = forceUpperCase ? def.tableName.toUpperCase() : def.tableName;
List<TableInspector> tables = findTables(sname, tname);
return tables.get(0);
}
/**
* Returns a list of tables
*
* @param schema the schema name
* @param table the table name
* @return a list of table inspectors
*/
private List<TableInspector> findTables(String schema, String table) throws SQLException {
ResultSet rs = null;
try {
rs = getMetaData().getSchemas();
ArrayList<String> schemaList = Utils.newArrayList();
while (rs.next()) {
schemaList.add(rs.getString("TABLE_SCHEM"));
}
JdbcUtils.closeSilently(rs);
// get JaQu Tables table name.
String jaquTables = DbVersion.class.getAnnotation(JQTable.class).name();
List<TableInspector> tables = Utils.newArrayList();
if (schemaList.size() == 0) {
schemaList.add(null);
}
for (String s : schemaList) {
rs = getMetaData().getTables(null, s, null, new String[] { "TABLE" });
while (rs.next()) {
String t = rs.getString("TABLE_NAME");
if (!t.equalsIgnoreCase(jaquTables)) {
// Ignore JaQu versions table
tables.add(new TableInspector(s, t,
getMetaData().storesUpperCaseIdentifiers(), dateClass));
}
}
}
if (StringUtils.isNullOrEmpty(schema) && StringUtils.isNullOrEmpty(table)) {
// all schemas and tables
return tables;
}
// schema subset OR table subset OR exact match
List<TableInspector> matches = Utils.newArrayList();
for (TableInspector t : tables) {
if (t.matches(schema, table)) {
matches.add(t);
}
}
if (matches.size() == 0) {
throw new RuntimeException(
MessageFormat.format("Failed to find schema={0} table={1}",
schema == null ? "" : schema, table == null ? "" : table));
}
return matches;
} finally {
JdbcUtils.closeSilently(rs);
}
}
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.h2.jaqu.Table.JQTable;
import org.h2.jaqu.util.JdbcUtils;
import org.h2.jaqu.util.StringUtils;
import org.h2.jaqu.util.Utils;
/**
* Class to inspect a model and a database for the purposes of model validation
* and automatic model generation. This class finds the available schemas and
* tables and serves as the entry point for model generation and validation.
*/
public class DbInspector {
private Db db;
private DatabaseMetaData metaData;
private Class<? extends java.util.Date> dateClass = java.util.Date.class;
private int todoReviewWholeClass;
public DbInspector(Db db) {
this.db = db;
}
/**
* Set the preferred Date class. Possible values are: java.util.Date
* (default), java.sql.Date, java.sql.Timestamp.
*
* @param dateClass the new date class
*/
public void setPreferredDateClass(Class<? extends java.util.Date> dateClass) {
this.dateClass = dateClass;
}
/**
* Generates models class skeletons for schemas and tables. If the table
* name is undefined, models will be generated for every table within the
* specified schema. Additionally, if no schema is defined, models will be
* generated for all schemas and all tables.
*
* @param schema the schema name (optional)
* @param table the table name (optional)
* @param packageName the package name (optional)
* @param annotateSchema (includes schema name in annotation)
* @param trimStrings (trims strings to maxLength of column)
* @return a list of complete model classes as strings, each element a class
*/
public List<String> generateModel(String schema, String table,
String packageName, boolean annotateSchema, boolean trimStrings) {
try {
List<String> models = Utils.newArrayList();
List<TableInspector> tables = findTables(schema, table);
for (TableInspector t : tables) {
t.read(metaData);
String model = t.generateModel(packageName, annotateSchema,
trimStrings);
models.add(model);
}
return models;
} catch (SQLException s) {
throw new RuntimeException(s);
}
}
/**
* Validates a model.
*
* @param <T> the model class
* @param model and instance of the model class
* @param throwOnError
* @return
*/
public <T> List<Validation> validateModel(T model, boolean throwOnError) {
try {
TableInspector inspector = findTable(model);
inspector.read(metaData);
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) model.getClass();
TableDefinition<T> def = db.define(clazz);
return inspector.validate(def, throwOnError);
} catch (SQLException s) {
throw new RuntimeException(s);
}
}
private DatabaseMetaData getMetaData() throws SQLException {
if (metaData == null) {
metaData = db.getConnection().getMetaData();
}
return metaData;
}
/**
* Attempts to find a table in the database based on the model definition.
*
* @param <T>
* @param model
* @return
* @throws SQLException
*/
private <T> TableInspector findTable(T model) throws SQLException {
@SuppressWarnings("unchecked")
Class<T> clazz = (Class<T>) model.getClass();
TableDefinition<T> def = db.define(clazz);
boolean forceUpperCase = getMetaData().storesUpperCaseIdentifiers();
String schema = (forceUpperCase && def.schemaName != null) ?
def.schemaName.toUpperCase() : def.schemaName;
String table = forceUpperCase ? def.tableName.toUpperCase() : def.tableName;
List<TableInspector> tables = findTables(schema, table);
return tables.get(0);
}
/**
* Returns a list of tables
*
* @param schema the schema name
* @param table the table name
* @return a list of table inspectors
*/
private List<TableInspector> findTables(String schema, String table) throws SQLException {
ResultSet rs = null;
try {
rs = getMetaData().getSchemas();
ArrayList<String> schemaList = Utils.newArrayList();
while (rs.next()) {
schemaList.add(rs.getString("TABLE_SCHEM"));
}
JdbcUtils.closeSilently(rs);
// get JaQu Tables table name.
String jaquTables = DbVersion.class.getAnnotation(JQTable.class).name();
List<TableInspector> tables = Utils.newArrayList();
if (schemaList.size() == 0) {
schemaList.add(null);
}
for (String s : schemaList) {
rs = getMetaData().getTables(null, s, null, new String[] { "TABLE" });
while (rs.next()) {
String t = rs.getString("TABLE_NAME");
if (!t.equalsIgnoreCase(jaquTables)) {
// Ignore JaQu versions table
tables.add(new TableInspector(s, t,
getMetaData().storesUpperCaseIdentifiers(), dateClass));
}
}
}
if (StringUtils.isNullOrEmpty(schema) && StringUtils.isNullOrEmpty(table)) {
// all schemas and tables
return tables;
}
// schema subset OR table subset OR exact match
List<TableInspector> matches = Utils.newArrayList();
for (TableInspector t : tables) {
if (t.matches(schema, table)) {
matches.add(t);
}
}
if (matches.size() == 0) {
throw new RuntimeException(
MessageFormat.format("Failed to find schema={0} table={1}",
schema == null ? "" : schema, table == null ? "" : table));
}
return matches;
} finally {
JdbcUtils.closeSilently(rs);
}
}
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
import org.h2.jaqu.Table.JQDatabase;
/**
* Interface which defines a class to handle table changes based on model
* versions. An implementation of <i>DbUpgrader</i> must be annotated with the
* <i>JQDatabase</i> annotation, which defines the expected database version
* number.
*/
public interface DbUpgrader {
/**
* Defines method interface to handle database upgrades. This method is only
* called if your <i>DbUpgrader</i> implementation is annotated with
* JQDatabase.
*
* @param db the database
* @param fromVersion the old version
* @param toVersion the new version
* @return true for successful upgrade. If the upgrade is successful, the
* version registry is automatically updated.
*/
boolean upgradeDatabase(Db db, int fromVersion, int toVersion);
/**
* Defines method interface to handle table upgrades.
*
* @param db the database
* @param schema the schema
* @param table the table
* @param fromVersion the old version
* @param toVersion the new version
* @return true for successful upgrade. If the upgrade is successful, the
* version registry is automatically updated.
*/
boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion);
/**
* The default database upgrader. It throws runtime exception instead of
* handling upgrade requests.
*/
@JQDatabase(version = 0)
public static class DefaultDbUpgrader implements DbUpgrader {
public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) {
throw new RuntimeException("Please provide your own DbUpgrader implementation.");
}
public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) {
throw new RuntimeException("Please provide your own DbUpgrader implementation.");
}
}
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
import org.h2.jaqu.Table.JQDatabase;
/**
* Interface which defines a class to handle table changes based on model
* versions. An implementation of <i>DbUpgrader</i> must be annotated with the
* <i>JQDatabase</i> annotation, which defines the expected database version
* number.
*/
public interface DbUpgrader {
/**
* Defines method interface to handle database upgrades. This method is only
* called if your <i>DbUpgrader</i> implementation is annotated with
* JQDatabase.
*
* @param db the database
* @param fromVersion the old version
* @param toVersion the new version
* @return true for successful upgrade. If the upgrade is successful, the
* version registry is automatically updated.
*/
boolean upgradeDatabase(Db db, int fromVersion, int toVersion);
/**
* Defines method interface to handle table upgrades.
*
* @param db the database
* @param schema the schema
* @param table the table
* @param fromVersion the old version
* @param toVersion the new version
* @return true for successful upgrade. If the upgrade is successful, the
* version registry is automatically updated.
*/
boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion);
/**
* The default database upgrader. It throws runtime exception instead of
* handling upgrade requests.
*/
@JQDatabase(version = 0)
public static class DefaultDbUpgrader implements DbUpgrader {
public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) {
throw new RuntimeException("Please provide your own DbUpgrader implementation.");
}
public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) {
throw new RuntimeException("Please provide your own DbUpgrader implementation.");
}
}
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
import org.h2.jaqu.Table.JQColumn;
import org.h2.jaqu.Table.JQTable;
/**
* Model class for JaQu to track db and table versions.
*
*/
@JQTable(name = "_jq_versions", primaryKey = "schemaName tableName", memoryTable = true)
public class DbVersion {
@JQColumn(name = "schemaName", allowNull = false)
String schema;
@JQColumn(name = "tableName", allowNull = false)
String table;
@JQColumn(name = "version")
Integer version;
public DbVersion() {
}
/**
* Constructor for defining a version entry.
* (SCHEMA="" && TABLE="") == DATABASE
*
* @param version
*/
public DbVersion(int version) {
this.schema = "";
this.table = "";
this.version = version;
}
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
import org.h2.jaqu.Table.JQColumn;
import org.h2.jaqu.Table.JQTable;
/**
* A JaQu system table to track database and table versions.
*/
@JQTable(name = "_jq_versions", primaryKey = "schemaName tableName", memoryTable = true)
public class DbVersion {
@JQColumn(name = "schemaName", allowNull = false)
String schema = "";
@JQColumn(name = "tableName", allowNull = false)
String table = "";
@JQColumn(name = "version")
Integer version;
private int todoReviewWholeClass;
public DbVersion() {
// nothing to do
}
/**
* Constructor for defining a version entry. Both the schema and the table
* are empty strings, which means this is the row for the 'database'.
*
* @param version the database version
*/
public DbVersion(int version) {
this.schema = "";
this.table = "";
this.version = version;
}
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
/**
* Classes implementing this interface can be used as a declaration in an
* update statement.
*/
public interface Declaration {
/**
* Append the SQL to the given statement using the given query.
*
* @param stat the statement to append the SQL to
*/
//## Java 1.5 begin ##
void appendSQL(SQLStatement stat);
//## Java 1.5 end ##
}
/*
* 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: James Moger
*/
package org.h2.jaqu;
/**
* Classes implementing this interface can be used as a declaration in an
* update statement.
*/
public interface Declaration {
final static int renameClassToUpdateDeclaration = 0;
/**
* Append the SQL to the given statement using the given query.
*
* @param stat the statement to append the SQL to
*/
//## Java 1.5 begin ##
void appendSQL(SQLStatement stat);
//## Java 1.5 end ##
}
......@@ -27,17 +27,17 @@ public class Define {
checkInDefine();
currentTableDefinition.addIndex(IndexType.STANDARD, columns);
}
public static void uniqueIndex(Object... columns) {
checkInDefine();
currentTableDefinition.addIndex(IndexType.UNIQUE, columns);
}
public static void hashIndex(Object column) {
checkInDefine();
currentTableDefinition.addIndex(IndexType.HASH, new Object [] { column });
}
public static void uniqueHashIndex(Object column) {
checkInDefine();
currentTableDefinition.addIndex(IndexType.UNIQUE_HASH, new Object [] { column });
......
/*
* 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: James Moger
*/
package org.h2.jaqu;
/**
* This class represents "SET column = (column + 1)" in an UPDATE statement.
*
* @param <T> the query type
* @param <A> the new value data type
*/
//## Java 1.5 begin ##
public class IncrementColumn<T, A> implements Declaration {
private Query<T> query;
private A x;
private A y;
IncrementColumn(Query<T> query, A x) {
this.query = query;
this.x = x;
}
public Query<T> by(A y) {
query.addDeclarationToken(this);
this.y = y;
return query;
}
public void appendSQL(SQLStatement stat) {
query.appendSQL(stat, x);
stat.appendSQL("=(");
query.appendSQL(stat, x);
int todoSomethingWrongHere;
if (y instanceof Number) {
Number n = (Number) y;
if (n.doubleValue() > 0) {
stat.appendSQL("+");
}
}
stat.appendSQL(y.toString());
stat.appendSQL(")");
}
}
//## Java 1.5 end ##
/*
* 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: James Moger
*/
package org.h2.jaqu;
/**
* This class represents "SET column = (column + 1)" in an UPDATE statement.
*
* @param <T> the query type
* @param <A> the new value data type
*/
//## Java 1.5 begin ##
public class IncrementColumn<T, A> implements Declaration {
private Query<T> query;
private A x;
private A y;
IncrementColumn(Query<T> query, A x) {
this.query = query;
this.x = x;
}
public Query<T> by(A y) {
query.addDeclarationToken(this);
this.y = y;
return query;
}
public void appendSQL(SQLStatement stat) {
query.appendSQL(stat, x);
stat.appendSQL("=(");
query.appendSQL(stat, x);
int todoSomethingWrongHere;
if (y instanceof Number) {
Number n = (Number) y;
if (n.doubleValue() > 0) {
stat.appendSQL("+");
}
}
stat.appendSQL(y.toString());
stat.appendSQL(")");
}
}
//## Java 1.5 end ##
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论