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

Cleanup:

- Rename 'Validation' to what it actually is: a 'ValidationRemark'.
- No need to check for null
- Don't use exclamation marks in error messages or warnings
- Don't use line comments for methods - use Javadoc comments
- Don't document private methods if the documentation just copies the method name
- Don't document parameter names if there is not actual documentation
- Don't use <p> and other HTML tags within Javadoc comments unless really necessary
- Don't use all uppercase (caps) method names
- Don't use empty lines (just '*') within Javadoc comments, except where necessary
 
上级 58468abb
......@@ -13,7 +13,7 @@ import org.h2.jaqu.DbInspector;
import org.h2.jaqu.DbUpgrader;
import org.h2.jaqu.DbVersion;
import org.h2.jaqu.Table.JQDatabase;
import org.h2.jaqu.Validation;
import org.h2.jaqu.ValidationRemark;
import org.h2.test.TestBase;
import org.h2.test.jaqu.SupportedTypes.SupportedTypes2;
......@@ -65,15 +65,15 @@ public class ModelsTest extends TestBase {
}
private void validateModel(DbInspector inspector, Object o) {
List<Validation> remarks = inspector.validateModel(o, false);
List<ValidationRemark> remarks = inspector.validateModel(o, false);
if (config.traceTest && remarks.size() > 0) {
trace("Validation remarks for " + o.getClass().getName());
for (Validation remark : remarks) {
for (ValidationRemark remark : remarks) {
trace(remark.toString());
}
trace("");
}
for (Validation remark : remarks) {
for (ValidationRemark remark : remarks) {
assertFalse(remark.toString(), remark.isError());
}
}
......
......@@ -246,11 +246,10 @@ public class Db {
}
public synchronized void setDbUpgrader(DbUpgrader upgrader) {
if (upgrader == null)
throw new RuntimeException("DbUpgrader may not be NULL!");
if (!upgrader.getClass().isAnnotationPresent(JQDatabase.class))
if (!upgrader.getClass().isAnnotationPresent(JQDatabase.class)) {
throw new RuntimeException("DbUpgrader must be annotated with "
+ JQDatabase.class.getSimpleName() + "!");
+ JQDatabase.class.getSimpleName());
}
this.dbUpgrader = upgrader;
upgradeChecked.clear();
}
......
......@@ -82,7 +82,7 @@ public class DbInspector {
* @param throwOnError
* @return
*/
public <T> List<Validation> validateModel(T model, boolean throwOnError) {
public <T> List<ValidationRemark> validateModel(T model, boolean throwOnError) {
try {
TableInspector inspector = findTable(model);
inspector.read(metaData);
......
......@@ -10,7 +10,7 @@ import org.h2.jaqu.Table.JQColumn;
import org.h2.jaqu.Table.JQTable;
/**
* A JaQu system table to track database and table versions.
* A system table to track database and table versions.
*/
@JQTable(name = "_jq_versions", primaryKey = "schemaName tableName", memoryTable = true)
public class DbVersion {
......@@ -24,8 +24,6 @@ public class DbVersion {
@JQColumn(name = "version")
Integer version;
private int todoReviewWholeClass;
public DbVersion() {
// nothing to do
}
......
......@@ -132,8 +132,9 @@ public class Query<T> {
}
public int update() {
if (declarations.size() == 0)
throw new RuntimeException("Please specify SET or INCREMENT before calling Update!");
if (declarations.size() == 0) {
throw new RuntimeException("Missing set or increment call.");
}
SQLStatement stat = new SQLStatement(db);
stat.appendSQL("UPDATE ");
from.appendSQL(stat);
......@@ -201,8 +202,9 @@ public class Query<T> {
int convertHereIsProbablyWrong;
if (Clob.class.isAssignableFrom(o.getClass())) {
value = (X) Utils.convert(o, String.class);
} else
} else {
value = (X) o;
}
result.add(value);
} catch (Exception e) {
throw new RuntimeException(e);
......@@ -328,7 +330,7 @@ public class Query<T> {
}
void addDeclarationToken(Declaration declaration) {
int todoWhatIsDeclaration;
int todoWhatIsDeclaration;
declarations.add(declaration);
}
......@@ -380,10 +382,12 @@ public class Query<T> {
stat.appendSQL(" ");
}
}
if (limit > 0)
if (limit > 0) {
db.getDialect().appendLimit(stat, limit);
if (offset > 0)
}
if (offset > 0) {
db.getDialect().appendOffset(stat, offset);
}
StatementLogger.select(stat.getSQL());
return stat;
}
......
......@@ -274,21 +274,24 @@ class TableDefinition<T> {
}
}
// Optionally truncates strings to maxLength
/**
* Optionally truncates strings to maxLength
*/
private Object getValue(Object obj, FieldDefinition field) {
Object value = field.getValue(obj);
if (field.trimString && field.maxLength > 0) {
if (value instanceof String) {
// Clip Strings
String s = (String) value;
if (s.length() > field.maxLength)
if (s.length() > field.maxLength) {
return s.substring(0, field.maxLength);
}
return s;
}
return value;
} else
// Standard JaQu behavior
return value;
}
// standard behavior
return value;
}
long insert(Db db, Object obj, boolean returnKey) {
......@@ -310,8 +313,9 @@ class TableDefinition<T> {
buff.append(')');
stat.setSQL(buff.toString());
StatementLogger.insert(stat.getSQL());
if (returnKey)
if (returnKey) {
return stat.executeInsert();
}
return stat.executeUpdate();
}
......@@ -434,10 +438,11 @@ class TableDefinition<T> {
StatementBuilder buff;
if (memoryTable &&
db.getConnection().getClass()
.getCanonicalName().equals("org.h2.jdbc.JdbcConnection"))
.getCanonicalName().equals("org.h2.jdbc.JdbcConnection")) {
buff = new StatementBuilder("CREATE MEMORY TABLE IF NOT EXISTS ");
else
} else {
buff = new StatementBuilder("CREATE TABLE IF NOT EXISTS ");
}
int todoChangeToGetTableNameChangeAllMethodsInDialectInterface;
buff.append(db.getDialect().tableName(schemaName, tableName)).append('(');
......@@ -503,17 +508,26 @@ class TableDefinition<T> {
return this;
}
// Retrieve list of columns from CSV whitespace notated index
/**
* Retrieve list of columns from CSV whitespace notated index
*
* @param index the index columns
* @return the column list
*/
private List<String> getColumns(String index) {
List<String> cols = Utils.newArrayList();
if (index == null || index.length() == 0)
if (index == null || index.length() == 0) {
return null;
}
String[] cs = index.split("(,|\\s)");
for (String c : cs)
if (c != null && c.trim().length() > 0)
for (String c : cs) {
if (c != null && c.trim().length() > 0) {
cols.add(c.trim());
if (cols.size() == 0)
}
}
if (cols.size() == 0) {
return null;
}
return cols;
}
......@@ -523,29 +537,33 @@ class TableDefinition<T> {
if (clazz.isAnnotationPresent(JQSchema.class)) {
JQSchema schemaAnnotation = clazz.getAnnotation(JQSchema.class);
// Setup Schema name mapping, if properly annotated
if (!StringUtils.isNullOrEmpty(schemaAnnotation.name()))
// setup schema name mapping, if properly annotated
if (!StringUtils.isNullOrEmpty(schemaAnnotation.name())) {
schemaName = schemaAnnotation.name();
}
}
if (clazz.isAnnotationPresent(JQTable.class)) {
JQTable tableAnnotation = clazz.getAnnotation(JQTable.class);
// Setup Table name mapping, if properly annotated
if (!StringUtils.isNullOrEmpty(tableAnnotation.name()))
// setup table name mapping, if properly annotated
if (!StringUtils.isNullOrEmpty(tableAnnotation.name())) {
tableName = tableAnnotation.name();
}
// Allow control over createTableIfRequired()
// allow control over createTableIfRequired()
createTableIfRequired = tableAnnotation.createIfRequired();
// Model Version
if (tableAnnotation.version() > 0)
// model version
if (tableAnnotation.version() > 0) {
tableVersion = tableAnnotation.version();
}
// Setup the Primary Index, if properly annotated
// setup the primary index, if properly annotated
List<String> primaryKey = getColumns(tableAnnotation.primaryKey());
if (primaryKey != null)
if (primaryKey != null) {
setPrimaryKey(primaryKey);
}
}
if (clazz.isAnnotationPresent(JQIndex.class)) {
......@@ -562,17 +580,20 @@ class TableDefinition<T> {
void addIndexes(IndexType type, String [] indexes) {
for (String index:indexes) {
List<String> validatedColumns = getColumns(index);
if (validatedColumns == null)
if (validatedColumns == null) {
return;
}
addIndex(type, validatedColumns);
}
}
List<IndexDefinition> getIndexes(IndexType type) {
List<IndexDefinition> list = Utils.newArrayList();
for (IndexDefinition def:indexes)
if (def.type.equals(type))
for (IndexDefinition def:indexes) {
if (def.type.equals(type)) {
list.add(def);
}
}
return list;
}
......
......@@ -7,9 +7,9 @@
package org.h2.jaqu;
import static java.text.MessageFormat.format;
import static org.h2.jaqu.Validation.CONSIDER;
import static org.h2.jaqu.Validation.ERROR;
import static org.h2.jaqu.Validation.WARN;
import static org.h2.jaqu.ValidationRemark.consider;
import static org.h2.jaqu.ValidationRemark.error;
import static org.h2.jaqu.ValidationRemark.warn;
import static org.h2.jaqu.util.JdbcUtils.closeSilently;
import static org.h2.jaqu.util.StringUtils.isNullOrEmpty;
import java.lang.reflect.Modifier;
......@@ -147,7 +147,7 @@ public class TableInspector {
* and allowNull information.
* <p>
* The caller may optionally set a destination package name, whether or not
* ot include the schema name (setting schema can be a problem when using
* to include the schema name (setting schema can be a problem when using
* the model between databases), and if to automatically trim strings for
* those that have a maximum length.
* <p>
......@@ -274,13 +274,7 @@ public class TableInspector {
}
/**
* Returns indexes of a specific type from the map.
* <p>
* @param type
* @return
*/
List<IndexInspector> getIndexes(IndexType type) {
private List<IndexInspector> getIndexes(IndexType type) {
List<IndexInspector> list = Utils.newArrayList();
for (IndexInspector index:indexes.values()) {
if (index.type.equals(type)) {
......@@ -290,16 +284,7 @@ public class TableInspector {
return list;
}
/**
* Generates a column field definition with annotations.
* <p>
* @param imports
* @param col
* @param trimStrings
* @return
*/
StatementBuilder generateColumn(Set<String> imports, ColumnInspector col,
private StatementBuilder generateColumn(Set<String> imports, ColumnInspector col,
boolean trimStrings) {
StatementBuilder sb = new StatementBuilder();
Class<?> clazz = col.clazz;
......@@ -375,27 +360,24 @@ public class TableInspector {
/**
* Validates that a table definition (annotated, interface, or both) matches
* the current state of the table and indexes in the database.
* <p>
* Results are returned as a List&lt;Validation&gt; which includes
* recommendations, warnings, and errors about the model.
* <p>
* The caller may choose to have validate throw an exception on any
* validation ERROR.
* <p>
* the current state of the table and indexes in the database. Results are
* returned as a list of validation remarks which includes recommendations,
* warnings, and errors about the model. The caller may choose to have
* validate throw an exception on any validation ERROR.
*
* @param <T>
* @param def
* @param throwError
* @return List&lt;Validation&gt;
* @param throwError whether or not to throw an exception if an error was
* found
* @return a list if validation remarks
*/
<T> List<Validation> validate(TableDefinition<T> def,
<T> List<ValidationRemark> validate(TableDefinition<T> def,
boolean throwError) {
List<Validation> remarks = Utils.newArrayList();
List<ValidationRemark> remarks = Utils.newArrayList();
// model class definition validation
if (!Modifier.isPublic(def.getModelClass().getModifiers())) {
remarks.add(ERROR(table, "SCHEMA",
remarks.add(error(table, "SCHEMA",
format("Class {0} MUST BE PUBLIC!",
def.getModelClass().getCanonicalName())).throwError(throwError));
}
......@@ -403,11 +385,11 @@ public class TableInspector {
// Schema Validation
if (!isNullOrEmpty(schema)) {
if (isNullOrEmpty(def.schemaName)) {
remarks.add(CONSIDER(table, "SCHEMA",
remarks.add(consider(table, "SCHEMA",
format("@{0}(name={1})",
JQSchema.class.getSimpleName(), schema)));
} else if (!schema.equalsIgnoreCase(def.schemaName)) {
remarks.add(ERROR(table, "SCHEMA",
remarks.add(error(table, "SCHEMA",
format("@{0}(name={1}) != {2}",
JQSchema.class.getSimpleName(), def.schemaName,
schema)).throwError(throwError));
......@@ -429,46 +411,33 @@ public class TableInspector {
/**
* Validates an inspected index from the database against the IndexDefinition
* within the TableDefinition.
* <p>
* <b>TODO</b>: Complete index validation
* <p>
* @param <T>
* @param remarks
* @param def
* @param index
* @param throwError
*/
<T> void validate(List<Validation> remarks, TableDefinition<T> def,
private <T> void validate(List<ValidationRemark> remarks, TableDefinition<T> def,
IndexInspector index, boolean throwError) {
List<IndexDefinition> defIndexes = def.getIndexes(IndexType.STANDARD);
List<IndexInspector> dbIndexes = getIndexes(IndexType.STANDARD);
if (defIndexes.size() > dbIndexes.size()) {
remarks.add(WARN(table, IndexType.STANDARD.name(), "# of Model Indexes > DB Indexes!"));
remarks.add(warn(table, IndexType.STANDARD.name(), "More model indexes than database indexes"));
} else if (defIndexes.size() < dbIndexes.size()) {
remarks.add(WARN(table, IndexType.STANDARD.name(), "Model class is missing indexes!"));
remarks.add(warn(table, IndexType.STANDARD.name(), "Model class is missing indexes"));
}
// TODO complete index validation.
// Need to actually compare index types and columns within each index.
// At this point my head was starting to hurt.
// need to actually compare index types and columns within each index.
}
/**
* Validates a column against the model's field definition. Checks for
* existence, supported type, type mapping, default value, defined lengths,
* primary key, autoincrement.
* <p>
* @param remarks
* @param fieldDef
* @param throwError
*/
void validate(List<Validation> remarks, FieldDefinition fieldDef,
private void validate(List<ValidationRemark> remarks, FieldDefinition fieldDef,
boolean throwError) {
// unknown field
String field = forceUpperCase ?
fieldDef.columnName.toUpperCase() : fieldDef.columnName;
if (!columns.containsKey(field)) {
// unknown column mapping
remarks.add(ERROR(table, fieldDef,
remarks.add(error(table, fieldDef,
"Does not exist in database!").throwError(throwError));
return;
}
......@@ -480,19 +449,19 @@ public class TableInspector {
// JaQu maps to VARCHAR for unsupported types.
if (fieldDef.dataType.equals("VARCHAR")
&& (fieldClazz != String.class)) {
remarks.add(ERROR(table, fieldDef,
remarks.add(error(table, fieldDef,
"JaQu does not currently implement support for "
+ fieldClazz.getName()).throwError(throwError));
}
// number types
if (!fieldClazz.equals(jdbcClazz)) {
if (Number.class.isAssignableFrom(fieldClazz)) {
remarks.add(WARN(table, col,
format("Precision Mismatch: ModelObject={0}, ColumnObject={1}",
remarks.add(warn(table, col,
format("Precision mismatch: ModelObject={0}, ColumnObject={1}",
fieldClazz.getSimpleName(), jdbcClazz.getSimpleName())));
} else {
if (!Date.class.isAssignableFrom(jdbcClazz)) {
remarks.add(WARN(table, col,
remarks.add(warn(table, col,
format("Object Mismatch: ModelObject={0}, ColumnObject={1}",
fieldClazz.getSimpleName(), jdbcClazz.getSimpleName())));
}
......@@ -503,13 +472,13 @@ public class TableInspector {
if (fieldClazz == String.class) {
if ((fieldDef.maxLength != col.size)
&& (col.size < Integer.MAX_VALUE)) {
remarks.add(WARN(table, col,
remarks.add(warn(table, col,
format("{0}.maxLength={1}, ColumnMaxLength={2}",
JQColumn.class.getSimpleName(),
fieldDef.maxLength, col.size)));
}
if (fieldDef.maxLength > 0 && !fieldDef.trimString) {
remarks.add(CONSIDER(table, col,
remarks.add(consider(table, col,
format("{0}.truncateToMaxLength=true"
+ " will prevent RuntimeExceptions on"
+ " INSERT or UPDATE, but will clip data!",
......@@ -519,7 +488,7 @@ public class TableInspector {
// numeric autoIncrement
if (fieldDef.isAutoIncrement != col.isAutoIncrement) {
remarks.add(WARN(table, col, format("{0}.isAutoIncrement={1}"
remarks.add(warn(table, col, format("{0}.isAutoIncrement={1}"
+ " while Column autoIncrement={2}",
JQColumn.class.getSimpleName(), fieldDef.isAutoIncrement,
col.isAutoIncrement)));
......@@ -529,7 +498,7 @@ public class TableInspector {
if (!col.isAutoIncrement && !col.isPrimaryKey) {
// check Model.defaultValue format
if (!ModelUtils.isProperlyFormattedDefaultValue(fieldDef.defaultValue)) {
remarks.add(ERROR(table, col, format("{0}.defaultValue=\"{1}\""
remarks.add(error(table, col, format("{0}.defaultValue=\"{1}\""
+ " is improperly formatted!",
JQColumn.class.getSimpleName(),
fieldDef.defaultValue)).throwError(throwError));
......@@ -540,20 +509,20 @@ public class TableInspector {
if (isNullOrEmpty(fieldDef.defaultValue)
&& !isNullOrEmpty(col.defaultValue)) {
// Model.defaultValue is NULL, Column.defaultValue is NOT NULL
remarks.add(WARN(table, col, format("{0}.defaultValue=\"\""
remarks.add(warn(table, col, format("{0}.defaultValue=\"\""
+ " while Column default=\"{1}\"",
JQColumn.class.getSimpleName(), col.defaultValue)));
} else if (!isNullOrEmpty(fieldDef.defaultValue)
&& isNullOrEmpty(col.defaultValue)) {
// Column.defaultValue is NULL, Model.defaultValue is NOT NULL
remarks.add(WARN(table, col, format("{0}.defaultValue=\"{1}\""
remarks.add(warn(table, col, format("{0}.defaultValue=\"{1}\""
+ " while Column default=\"\"",
JQColumn.class.getSimpleName(), fieldDef.defaultValue)));
} else if (!isNullOrEmpty(fieldDef.defaultValue)
&& !isNullOrEmpty(col.defaultValue)) {
if (!fieldDef.defaultValue.equals(col.defaultValue)) {
// Model.defaultValue != Column.defaultValue
remarks.add(WARN(table, col, format("{0}.defaultValue=\"{1}\""
remarks.add(warn(table, col, format("{0}.defaultValue=\"{1}\""
+ " while Column default=\"{2}\"",
JQColumn.class.getSimpleName(), fieldDef.defaultValue,
col.defaultValue)));
......@@ -563,7 +532,7 @@ public class TableInspector {
// sanity check Model.defaultValue literal value
if (!ModelUtils.isValidDefaultValue(fieldDef.field.getType(),
fieldDef.defaultValue)) {
remarks.add(ERROR(table, col,
remarks.add(error(table, col,
format("{0}.defaultValue=\"{1}\" is invalid!!",
JQColumn.class.getSimpleName(),
fieldDef.defaultValue)));
......@@ -574,11 +543,10 @@ public class TableInspector {
/**
* Represents an index as it exists in the database.
*/
public static class IndexInspector {
String name;
private static class IndexInspector {
String name;
IndexType type;
private List<String> columns = new ArrayList<String>();
public IndexInspector(ResultSet rs) throws SQLException {
......@@ -616,9 +584,8 @@ public class TableInspector {
/**
* Represents a column as it exists in the database.
*
*/
public static class ColumnInspector implements Comparable<ColumnInspector> {
static class ColumnInspector implements Comparable<ColumnInspector> {
String name;
String type;
int size;
......@@ -648,7 +615,6 @@ public class TableInspector {
/**
* Convenience class based on StatementBuilder for creating the
* annotation parameter list.
*
*/
private static class AnnotationBuilder extends StatementBuilder {
AnnotationBuilder() {
......
......@@ -11,55 +11,26 @@ import org.h2.jaqu.TableInspector.ColumnInspector;
import org.h2.jaqu.util.StringUtils;
/**
* A Validation Remark is a result of running a model validation.
* <p>
* Each remark has a level, associated component (schema, table, column, index),
* and a message.
*
* A validation remark is a result of running a model validation. Each remark
* has a level, associated component (schema, table, column, index), and a
* message.
*/
public class Validation {
private int todoReviewWholeClass;
public static Validation CONSIDER(String table, String type, String message) {
return new Validation(Level.CONSIDER, table, type, message);
}
public static Validation CONSIDER(String table, ColumnInspector col, String message) {
return new Validation(Level.CONSIDER, table, col, message);
}
public static Validation WARN(String table, ColumnInspector col, String message) {
return new Validation(Level.WARN, table, col, message);
}
public static Validation WARN(String table, String type, String message) {
return new Validation(Level.WARN, table, type, message);
}
public static Validation ERROR(String table, ColumnInspector col, String message) {
return new Validation(Level.ERROR, table, col, message);
}
public static Validation ERROR(String table, String type, String message) {
return new Validation(Level.ERROR, table, type, message);
}
public static Validation ERROR(String table, FieldDefinition field, String message) {
return new Validation(Level.ERROR, table, field, message);
}
public class ValidationRemark {
/**
* The validation message level.
*/
public static enum Level {
CONSIDER, WARN, ERROR;
}
Level level;
String table;
String fieldType;
String fieldName;
String message;
private Level level;
private String table;
private String fieldType;
private String fieldName;
private String message;
private Validation(Level level, String table, String type, String message) {
private ValidationRemark(Level level, String table, String type, String message) {
this.level = level;
this.table = table;
this.fieldType = type;
......@@ -67,7 +38,7 @@ public class Validation {
this.message = message;
}
private Validation(Level level, String table, FieldDefinition field, String message) {
private ValidationRemark(Level level, String table, FieldDefinition field, String message) {
this.level = level;
this.table = table;
this.fieldType = field.dataType;
......@@ -75,7 +46,7 @@ public class Validation {
this.message = message;
}
private Validation(Level level, String table, ColumnInspector col, String message) {
private ValidationRemark(Level level, String table, ColumnInspector col, String message) {
this.level = level;
this.table = table;
this.fieldType = col.type;
......@@ -83,9 +54,38 @@ public class Validation {
this.message = message;
}
public Validation throwError(boolean throwOnError) {
if (throwOnError && isError())
public static ValidationRemark consider(String table, String type, String message) {
return new ValidationRemark(Level.CONSIDER, table, type, message);
}
public static ValidationRemark consider(String table, ColumnInspector col, String message) {
return new ValidationRemark(Level.CONSIDER, table, col, message);
}
public static ValidationRemark warn(String table, ColumnInspector col, String message) {
return new ValidationRemark(Level.WARN, table, col, message);
}
public static ValidationRemark warn(String table, String type, String message) {
return new ValidationRemark(Level.WARN, table, type, message);
}
public static ValidationRemark error(String table, ColumnInspector col, String message) {
return new ValidationRemark(Level.ERROR, table, col, message);
}
public static ValidationRemark error(String table, String type, String message) {
return new ValidationRemark(Level.ERROR, table, type, message);
}
public static ValidationRemark error(String table, FieldDefinition field, String message) {
return new ValidationRemark(Level.ERROR, table, field, message);
}
public ValidationRemark throwError(boolean throwOnError) {
if (throwOnError && isError()) {
throw new RuntimeException(toString());
}
return this;
}
......@@ -112,4 +112,5 @@ public class Validation {
sb.append(message);
return sb.toString();
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论