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

Cleanup:

- the dialect detection will most likely be based on the URL, not on the class name
- 'declaration' is a much too generic term for 'set column = value'
- method names should start with a verb (getTableName instead of tableName)
- remove redundancy and unnecessary formatting in Javadocs (keep it as simple as possible)
上级 991c3742
......@@ -56,11 +56,10 @@ public class Db {
public Db(Connection conn) {
this.conn = conn;
dialect = getDialect(conn.getClass().getCanonicalName());
dialect = getDialect(conn);
}
private SQLDialect getDialect(String clazz) {
int todo;
private SQLDialect getDialect(Connection conn) {
// TODO add special cases here
return new DefaultSQLDialect();
}
......@@ -155,7 +154,7 @@ public class Db {
Db upgradeDb() {
if (!upgradeChecked.contains(dbUpgrader.getClass())) {
// Flag as checked immediately because calls are nested.
// flag as checked immediately because calls are nested.
upgradeChecked.add(dbUpgrader.getClass());
JQDatabase model = dbUpgrader.getClass().getAnnotation(JQDatabase.class);
......@@ -165,16 +164,16 @@ public class Db {
// (SCHEMA="" && TABLE="") == DATABASE
from(v).where(v.schema).is("").and(v.table).is("").selectFirst();
if (dbVersion == null) {
// Database has no version registration, but model specifies
// version. Insert DbVersion entry and return.
// database has no version registration, but model specifies
// version: insert DbVersion entry and return.
DbVersion newDb = new DbVersion(model.version());
insert(newDb);
} else {
// Database has a version registration,
// database has a version registration:
// check to see if upgrade is required.
if ((model.version() > dbVersion.version)
&& (dbUpgrader != null)) {
// Database is an older version than model.
// database is an older version than the model
boolean success = dbUpgrader.upgradeDatabase(this,
dbVersion.version, model.version());
if (success) {
......@@ -190,29 +189,29 @@ public class Db {
<T> void upgradeTable(TableDefinition<T> model) {
if (!upgradeChecked.contains(model.getModelClass())) {
// Flag as checked immediately because calls are nested.
// flag is checked immediately because calls are nested
upgradeChecked.add(model.getModelClass());
if (model.tableVersion > 0) {
// Table is using JaQu version tracking.
// table is using JaQu version tracking.
DbVersion v = new DbVersion();
String schema = StringUtils.isNullOrEmpty(model.schemaName) ? "" : model.schemaName;
DbVersion dbVersion =
from(v).where(v.schema).like(schema).and(v.table)
.like(model.tableName).selectFirst();
if (dbVersion == null) {
// Table has no version registration, but model specifies
// version. Insert DbVersion entry and return.
// table has no version registration, but model specifies
// version: insert DbVersion entry
DbVersion newTable = new DbVersion(model.tableVersion);
newTable.schema = schema;
newTable.table = model.tableName;
insert(newTable);
} else {
// Table has a version registration.
// Check to see if upgrade is required.
// table has a version registration:
// check if upgrade is required
if ((model.tableVersion > dbVersion.version)
&& (dbUpgrader != null)) {
// Table is an older version than model.
// table is an older version than model
boolean success = dbUpgrader.upgradeTable(this, schema,
model.tableName, dbVersion.version, model.tableVersion);
if (success) {
......@@ -237,7 +236,7 @@ public class Db {
Table table = (Table) t;
Define.define(def, table);
} else if (clazz.isAnnotationPresent(JQTable.class)) {
// Annotated Class skips Define().define() static initializer
// annotated classes skip the Define().define() static initializer
T t = instance(clazz);
def.mapObject(t);
}
......
......@@ -32,7 +32,7 @@ public class Query<T> {
private Db db;
private SelectTable<T> from;
private ArrayList<Token> conditions = Utils.newArrayList();
private ArrayList<UpdateColumn> declarations = Utils.newArrayList();
private ArrayList<UpdateColumn> updateColumnDeclarations = Utils.newArrayList();
private ArrayList<SelectTable<?>> joins = Utils.newArrayList();
private final IdentityHashMap<Object, SelectColumn<T>> aliasMap = Utils.newIdentityHashMap();
private ArrayList<OrderExpression<T>> orderByList = Utils.newArrayList();
......@@ -122,17 +122,15 @@ public class Query<T> {
}
public <A> UpdateColumnSet<T, A> set(A field) {
int renameSetColumnClassToUpdateSetColumn;
return new UpdateColumnSet<T, A>(this, field);
}
public <A> UpdateColumnIncrement<T, A> increment(A field) {
int renameIncrementColumnClassToUpdateIncrementColumn;
return new UpdateColumnIncrement<T, A>(this, field);
}
public int update() {
if (declarations.size() == 0) {
if (updateColumnDeclarations.size() == 0) {
throw new RuntimeException("Missing set or increment call.");
}
SQLStatement stat = new SQLStatement(db);
......@@ -140,7 +138,7 @@ public class Query<T> {
from.appendSQL(stat);
stat.appendSQL(" SET ");
int i = 0;
for (UpdateColumn declaration : declarations) {
for (UpdateColumn declaration : updateColumnDeclarations) {
if (i++ > 0) {
stat.appendSQL(", ");
}
......@@ -329,9 +327,8 @@ public class Query<T> {
conditions.add(condition);
}
void addDeclarationToken(UpdateColumn declaration) {
int todoWhatIsDeclaration;
declarations.add(declaration);
void addUpdateColumnDeclaration(UpdateColumn declaration) {
updateColumnDeclarations.add(declaration);
}
void appendWhere(SQLStatement stat) {
......
......@@ -23,7 +23,7 @@ public interface SQLDialect {
* @param table the table name
* @return the SQL snippet
*/
String tableName(String schema, String table);
String getTableName(String schema, String table);
/**
* Get the CREATE INDEX statement.
......@@ -33,7 +33,7 @@ public interface SQLDialect {
* @param index the index definition
* @return the SQL statement
*/
String createIndex(String schema, String table, IndexDefinition index);
String getCreateIndex(String schema, String table, IndexDefinition index);
/**
* Append "LIMIT limit" to the SQL statement.
......@@ -51,20 +51,31 @@ public interface SQLDialect {
*/
void appendOffset(SQLStatement stat, long offset);
/**
* Whether memory tables are supported.
*
* @return true if they are
*/
boolean supportsMemoryTables();
/**
* Default implementation of an SQL dialect.
* Designed for an H2 database. May be suitable for others.
*/
public static class DefaultSQLDialect implements SQLDialect {
public String tableName(String schema, String table) {
public String getTableName(String schema, String table) {
if (StringUtils.isNullOrEmpty(schema)) {
return table;
}
return schema + "." + table;
}
public String createIndex(String schema, String table, IndexDefinition index) {
public boolean supportsMemoryTables() {
return true;
}
public String getCreateIndex(String schema, String table, IndexDefinition index) {
StatementBuilder buff = new StatementBuilder();
buff.append("CREATE ");
switch(index.type) {
......
......@@ -40,7 +40,7 @@ public class SQLStatement {
}
public SQLStatement appendTable(String schema, String table) {
return appendSQL(db.getDialect().tableName(schema, table));
return appendSQL(db.getDialect().getTableName(schema, table));
}
String getSQL() {
......
......@@ -13,110 +13,75 @@ import java.lang.annotation.Target;
/**
* A class that implements this interface can be used as a database table.
*/
/**
* A class that implements the JaQu model mapping options.
* <p>
* You may implement the Table interface on your model object and optionally use
* JQColumn annotations.<br>
* <i>This imposes a compile-time and runtime-dependency on JaQu.</i>
* <p>
* <u>OR</u>
* <p>
* You may choose to use the JQTable and JQColumn annotations only.<br>
* <i>This imposes a compile-time and runtime-dependency on this file only.</i>
* JQColumn annotations (which imposes a compile-time and runtime-dependency on
* JaQu), or may choose to use the JQTable and JQColumn annotations only (which
* imposes a compile-time and runtime-dependency on this file only).
* <p>
* <b>NOTE</b><br>
* Classes that are annotated with JQTable <b>and</b> implement Table will NOT
* call the define() method.
* If a class is annotated with JQTable and at the same time implements Table,
* the define() method is not called.
* <p>
* <b>Supported Data Types</b>
* Supported data types:
* <table>
* <tr>
* <td>java.lang.String</td>
* <td>VARCHAR (maxLength > 0) / TEXT (maxLength == 0)</td>
* </tr>
* <tr>
* <td>java.lang.Boolean</td>
* <td>BIT</td>
* <td>java.lang.Boolean</td><td>BIT</td>
* </tr>
* <tr>
* <td>java.lang.Byte</td>
* <td>TINYINT</td>
* <td>java.lang.Byte</td><td>TINYINT</td>
* </tr>
* <tr>
* <td>java.lang.Short</td>
* <td>SMALLINT</td>
* <td>java.lang.Short</td><td>SMALLINT</td>
* </tr>
* <tr>
* <td>java.lang.Integer</td>
* <td>INT</td>
* <td>java.lang.Integer</td><td>INT</td>
* </tr>
* <tr>
* <td>java.lang.Long</td>
* <td>BIGINT</td>
* <td>java.lang.Long</td><td>BIGINT</td>
* </tr>
* <tr>
* <td>java.lang.Float</td>
* <td>REAL</td>
* <td>java.lang.Float</td><td>REAL</td>
* </tr>
* <tr>
* <td>java.lang.Double</td>
* <td>DOUBLE</td>
* <td>java.lang.Double</td><td>DOUBLE</td>
* </tr>
* <tr>
* <td>java.math.BigDecimal</td>
* <td>DECIMAL</td>
* <td>java.math.BigDecimal</td><td>DECIMAL</td>
* </tr>
* <tr>
* <td>java.util.Date</td>
* <td>TIMESTAMP</td>
* <td>java.util.Date</td><td>TIMESTAMP</td>
* </tr>
* <tr>
* <td>java.sql.Date</td>
* <td>DATE</td>
* <td>java.sql.Date</td><td>DATE</td>
* </tr>
* <tr>
* <td>java.sql.Time</td>
* <td>TIME</td>
* <td>java.sql.Time</td><td>TIME</td>
* </tr>
* <tr>
* <td>java.sql.Timestamp</td>
* <td>TIMESTAMP</td>
* <td>java.sql.Timestamp</td><td>TIMESTAMP</td>
* </tr>
* </table>
* <p>
* <b>Unsupported Data Types</b>
* <ul>
* <li>Binary types (BLOB, etc)
* <li>Custom types
* </ul>
* Unsupported data types: binary types (BLOB, etc), and custom types.
* <p>
* <b>Table and Field Mapping</b>
* <p>
* By default, the mapped table name is the class name and the <i>public</i>
* fields are reflectively mapped, by their name, to columns.
* <p>
* As an alternative, you may specify both the table and column definition by
* Table and field mapping: by default, the mapped table name is the class name
* and the public fields are reflectively mapped, by their name, to columns. As
* an alternative, you may specify both the table and column definition by
* annotations.
* <p>
* <b>Table Interface</b>
* <p>
* You may set additional parameters such as table name, primary key, and
* indexes in the <i>define()</i> method.
* <p>
* <b>Annotations</b>
* Table Interface: you may set additional parameters such as table name,
* primary key, and indexes in the define() method.
* <p>
* You may use the annotations with or without implementing the Table interface.
* <br>
* The annotations allow you to decouple your model completely from JaQu other
* than this file.
* Annotations: you may use the annotations with or without implementing the
* Table interface. The annotations allow you to decouple your model completely
* from JaQu other than this file.
* <p>
* <b>Automatic Model Generation</b>
* <p>
* You may automatically generate model classes as strings with the <i>Db</i>
* and <i>DbInspector</i> objects.
*
* Automatic model generation: you may automatically generate model classes as
* strings with the Db and DbInspector objects:
* <pre>
* Db db = Db.open(&quot;jdbc:h2:mem:&quot;, &quot;sa&quot;, &quot;sa&quot;);
* DbInspector inspector = new DbInspector(db);
......@@ -124,10 +89,8 @@ import java.lang.annotation.Target;
* inspector.generateModel(schema, table, packageName,
* annotateSchema, trimStrings)
* </pre>
*
* OR you may use the <i>GenerateModels</i> tool to generate and save your
* classes to the filesystem.
*
* Or you may use the GenerateModels tool to generate and save your classes to
* the file system:
* <pre>
* java -cp h2jaqu.jar org.h2.jaqu.util.GenerateModels
* -url &quot;jdbc:h2:mem:&quot;
......@@ -136,18 +99,12 @@ import java.lang.annotation.Target;
* -annotateSchema false -trimStrings true
* </pre>
*
* <b>Model Validation</b>
* <p>
* You may validate your model class with <i>DbInspector</i> object.<br>
* The DbInspector will report ERRORS, WARNINGS, and
* SUGGESTIONS to help you.
*
* Model validation: you may validate your model class with DbInspector object.
* The DbInspector will report errors, warnings, and suggestions:
* <pre>
* Db db = Db.open(&quot;jdbc:h2:mem:&quot;,
* &quot;sa&quot;, &quot;sa&quot;);
* Db db = Db.open(&quot;jdbc:h2:mem:&quot;, &quot;sa&quot;, &quot;sa&quot;);
* DbInspector inspector = new DbInspector(db);
* List&lt;Validation&gt; remarks =
* inspector.validateModel(new MyModel(), throwOnError);
* List&lt;Validation&gt; remarks = inspector.validateModel(new MyModel(), throwOnError);
* for (Validation remark : remarks) {
* System.out.println(remark);
* }
......@@ -155,31 +112,39 @@ import java.lang.annotation.Target;
*/
public interface Table {
static final int reviewWholeClassAndJavadocs = 0;
/**
* An annotation for a database.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JQDatabase {
/**
* If version is set to a non-zero value, JaQu will
* maintain a "_jq_versions" table within your database. The
* version number will be used to call to a registered
* If set to a non-zero value, JaQu
* maintains a "_jq_versions" table within your database. The
* version number is used to call to a registered
* DbUpgrader implementation to perform relevant ALTER statements.
* Default: 0.
* You must specify a DbUpgrader on your Db object to
* use this parameter.
*/
int version() default 0;
}
/**
* An annotation for a schema.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JQSchema {
/**
* The schema may be optionally specified. If it is not specified the
* schema will be ignored. Default: Unspecified.
* The schema may be optionally specified.
* Default: unspecified.
*/
String name() default "";
}
/**
......@@ -189,66 +154,64 @@ public interface Table {
STANDARD, UNIQUE, HASH, UNIQUE_HASH;
}
/**
* An index annotation.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JQIndex {
/**
* Standard indexes may be optionally specified. If not specified,
* these values will be ignored.
* Standard indexes may be optionally specified.
* <ul>
* <li>standard = "id, name"
* <li>standard = "id name"
* <li>standard = { "id name", "date" }
* <li>standard = "id, name"</li>
* <li>standard = "id name"</li>
* <li>standard = { "id name", "date" }</li>
* </ul>
* Standard indexes may still be added in the define() method if
* the model class is not annotated with JQTable.
* Default: Unspecified.
* Default: unspecified.
*/
String[] standard() default {};
/**
* <b>unique</b> indexes may be optionally specified. If not specified,
* these values will be ignored.
* Unique indexes may be optionally specified.
* <ul>
* <li>unique = "id, name"
* <li>unique = "id name"
* <li>unique = { "id name", "date" }
* <li>unique = "id, name"</li>
* <li>unique = "id name"</li>
* <li>unique = { "id name", "date" }</li>
* </ul>
* Unique indexes may still be added in the <i>define()</i> method if
* Unique indexes may still be added in the define() method if
* the model class is not annotated with JQTable.
* <p>
* <b>Default: <i>Unspecified</i></b>
* Default: unspecified.
*/
String[] unique() default {};
/**
* <b>hash</b> indexes may be optionally specified. If not specified,
* these values will be ignored.
* Hash indexes may be optionally specified.
* <ul>
* <li>hash = "name"
* <li>hash = { "name", "date" }
* </ul>
* Hash indexes may still be added in the <i>define()</i> method if
* Hash indexes may still be added in the define() method if
* the model class is not annotated with JQTable.
* <p>
* <b>Default: <i>Unspecified</i></b>
* Default: unspecified.
*/
String[] hash() default {};
/**
* <b>uniqueHash</b> indexes may be optionally specified. If not specified,
* these values will be ignored.
* Unique hash indexes may be optionally specified.
* <ul>
* <li>uniqueHash = "id"
* <li>uniqueHash = "name"
* <li>uniqueHash = { "id", "name" }
* </ul>
* UniqueHash indexes may still be added in the <i>define()</i> method if
* Unique hash indexes may still be added in the define() method if
* the model class is not annotated with JQTable.
* <p>
* <b>Default: <i>Unspecified</i></b>
* Default: unspecified.
*/
String[] uniqueHash() default {};
}
/**
......@@ -259,189 +222,151 @@ public interface Table {
public @interface JQTable {
/**
* <b>name</b> may be optionally specified. If it is not specified the
* class name will be used as the table name.
* The table name. If not specified the
* class name is used as the table name.
* <p>
* The table name may still be overridden in the <i>define()</i> method
* The table name may still be overridden in the define() method
* if the model class is not annotated with JQTable.
* <p>
* <b>Default: <i>Unspecified</i></b>
* Default: unspecified.
*/
String name() default "";
/**
* <b>primaryKey</b> may be optionally specified. If it is not
* specified, then no primary key will be set by the JQTable annotation.
* The primary key may be optionally specified. If it is not
* specified, then no primary key is set by the JQTable annotation.
* You may specify a composite primary key.
* <ul>
* <li>primaryKey = "id, name"
* <li>primaryKey = "id name"
* </ul>
* The primaryKey may still be overridden in the <i>define()</i> method
* The primary key may still be overridden in the define() method
* if the model class is not annotated with JQTable.
* <p>
* <b>Default: <i>Unspecified</i></b>
* Default: unspecified.
*/
String primaryKey() default "";
/**
* <b>inheritColumns</b> allows this model class to inherit columns from
* The inherit columns allows this model class to inherit columns from
* its super class. Any JQTable annotation present on the super class is
* ignored.<br>
* <p>
* <b>Default: <i>false</i></b>
* ignored.
* Default: false.
*/
boolean inheritColumns() default false;
/**
* <b>createIfRequired</b> allows user to control whether or not
* JaQu tries to create the table and indexes.
* <p>
* <b>Default: <i>true</i></b>
* Whether or not JaQu tries to create the table and indexes. Default:
* true.
*/
boolean createIfRequired() default true;
/**
* <b>strictTypeMapping</b> allows user to specify that only supported
* types are mapped.<br>
* If set <i>true</i>, unsupported mapped types will throw a
* RuntimeException.<br>
* If set <i>false</i>, unsupported mapped types will default to
* VARCHAR.
* <p>
* <b>Default: <i>true</i></b>
* Whether only supported types are mapped.
* If true, unsupported mapped types will throw a RuntimeException.
* If false, unsupported mapped types will default to VARCHAR.
* Default: true.
*/
boolean strictTypeMapping() default true;
/**
* <b>annotationsOnly</b> controls reflective field mapping on your
* model object. If set <i>true</i>, only fields that are explicitly
* If true, only fields that are explicitly
* annotated as JQColumn are mapped.
* <p>
* <b>Default: <i>true</i></b>
* Default: true.
*/
boolean annotationsOnly() default true;
/**
* If <b>memoryTable</b> is set <i>true</i>, this table is created as a
* memory table where data is persistent, but index data is kept in main
* memory.<br>
* The JDBC Connection class is verified before applying this property
* in the CREATE phase.
* <p>
* <b>Default: <i>false</i></b>
* <p>
* <u>Valid only for H2 databases.</u>
* If true, this table is created as a memory table where data is persistent,
* but index data is kept in main memory.
* Valid only for H2 databases.
* Default: false.
*/
boolean memoryTable() default false;
/**
* If <b>version</b> is set to a <i>non-zero</i> value, JaQu will
* If non-zero, JaQu will
* maintain a "_jq_versions" table within your database. The
* <i>version</i> number will be used to call to a registered
* <i>DbUpgrader</i> implementation to perform relevant ALTER
* version number is used to call to a registered
* DbUpgrader implementation to perform relevant ALTER
* statements.
* <p>
* <b>Default: <i>0</i></b>
* <p>
* <bNOTE:</b><br>
* You must specify a <i>DbUpgrader</i> on your <i>Db</i> object to
* Default: 0.
* You must specify a DbUpgrader on your Db object to
* use this parameter.
*/
int version() default 0;
}
/**
* Annotation to define a Column. Annotated fields may have any Scope with
* the understanding that under some circumstances, the JVM may raise a
* SecurityException.
* Annotation to define a column. Annotated fields may have any scope
* (however, the JVM may raise a SecurityException if the SecurityManager
* doesn't allow JaQu to access the field.)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JQColumn {
/**
* If <b>name</b> is not specified the instance variable field name will
* be used as the column name.
* <p>
* <b>Default: <i>reflective field name mapping</i></b>
* If not specified, the field name is used as the column name.
* Default: the field name.
*/
String name() default "";
/**
* If <b>primaryKey</b> is true, this column will be the PrimaryKey.
* <p>
* <b>Default: <i>false</i></b>
* This column is the primary key.
* Default: false.
*/
boolean primaryKey() default false;
/**
* If <b>autoIncrement</b> is true, the column will be created with a
* The column is created with a
* sequence as the default value.
* <p>
* <b>Default: <i>false</i></b>
* Default: false.
*/
boolean autoIncrement() default false;
/**
* If <b>maxLength</b> > 0 it is used during the CREATE TABLE phase. It
* may also be optionally used to prevent database exceptions on INSERT
* and UPDATE statements (see <i>trimString</i>).
* If larger than zero, it is used during the CREATE TABLE phase. It
* may also be used to prevent database exceptions on INSERT
* and UPDATE statements (see trimString).
* <p>
* Any maxLength set in <i>define()</i> may override this annotation
* Any maxLength set in define() may override this annotation
* setting if the model class is not annotated with JQTable.
* <p>
* <b>Default: <i>0</i></b>
* Default: 0.
*/
int maxLength() default 0;
/**
* If <b>trimString</b> is <i>true</i> JaQu will automatically trim the
* string if it exceeds <b>maxLength</b>.
* <p>
* e.g. stringValue = stringValue.substring(0, maxLength)
* <p>
* <b>Default: <i>false</i></b>
* If true, JaQu will automatically trim the
* string if it exceeds maxLength
* (value.substring(0, maxLength)).
* Default: false.
*/
boolean trimString() default false;
/**
* If <b>allowNull</b> is <i>false</i> then JaQu will set
* If false, JaQu will set
* the column NOT NULL during the CREATE TABLE phase.
* <p>
* <b>Default: <i>false</i></b>
* Default: false.
*/
boolean allowNull() default false;
/**
* <b>defaultValue</b> is the value assigned to the column during the
* CREATE TABLE phase.
* <p>
* To set <b>null</b>, defaultValue="" (default)
* <p>
* This field could contain a literal <u>single-quoted value</u>.<br>
* Or a function call.<br>
* Empty strings will be considered NULL.
* The default value assigned to the column during the CREATE TABLE
* phase. This field could contain a literal single-quoted value, or a
* function call. Empty strings are considered NULL. Examples:
* <ul>
* <li>defaultValue="" (null)
* <li>defaultValue="CURRENT_TIMESTAMP" (H2 current_timestamp())
* <li>defaultValue="''" (default empty string)
* <li>defaultValue="'0'" (default number)
* <li>defaultValue="'1970-01-01 00:00:01'" (default date)
* </ul>
* if (
* <ul>
* <li>defaultValue is properly specified
* <li>AND <i>autoIncrement</i> == false
* <li>AND <i>primaryKey</i> == false
* <li>defaultValue="CURRENT_TIMESTAMP"
* <li>defaultValue="''" (empty string)
* <li>defaultValue="'0'"
* <li>defaultValue="'1970-01-01 00:00:01'"
* </ul>
* )<br>
* then this value will be included in the "DEFAULT ..." phrase of a
* column during the CREATE TABLE process.
* <p>
* <b>Default: <i>unspecified, null</i></b>
* if the default value is specified, and auto increment is disabled,
* and primary key is disabled, then this value is included in the
* "DEFAULT ..." phrase of a column during the CREATE TABLE process.
* Default: unspecified (null).
*/
String defaultValue() default "";
}
/**
......@@ -449,4 +374,5 @@ public interface Table {
* and the table name.
*/
void define();
}
......@@ -79,7 +79,6 @@ class TableDefinition<T> {
void setValue(Object obj, Object o) {
try {
int setAccessibleShouldNotBeRequiredHere;
if (!field.isAccessible()) {
field.setAccessible(true);
}
......@@ -101,6 +100,7 @@ class TableDefinition<T> {
String schemaName;
String tableName;
int tableVersion;
private boolean createTableIfRequired = true;
private Class<T> clazz;
private ArrayList<FieldDefinition> fields = Utils.newArrayList();
......@@ -111,8 +111,6 @@ class TableDefinition<T> {
private ArrayList<IndexDefinition> indexes = Utils.newArrayList();
private boolean memoryTable;
int tableVersion;
TableDefinition(Class<T> clazz) {
this.clazz = clazz;
schemaName = null;
......@@ -275,13 +273,13 @@ class TableDefinition<T> {
}
/**
* Optionally truncates strings to maxLength
* Optionally truncates strings to the maximum length
*/
private Object getValue(Object obj, FieldDefinition field) {
Object value = field.getValue(obj);
if (field.trimString && field.maxLength > 0) {
if (value instanceof String) {
// Clip Strings
// clip strings
String s = (String) value;
if (s.length() > field.maxLength) {
return s.substring(0, field.maxLength);
......@@ -297,7 +295,7 @@ class TableDefinition<T> {
long insert(Db db, Object obj, boolean returnKey) {
SQLStatement stat = new SQLStatement(db);
StatementBuilder buff = new StatementBuilder("INSERT INTO ");
buff.append(db.getDialect().tableName(schemaName, tableName)).append('(');
buff.append(db.getDialect().getTableName(schemaName, tableName)).append('(');
for (FieldDefinition field : fields) {
buff.appendExceptFirst(", ");
buff.append(field.columnName);
......@@ -326,7 +324,7 @@ class TableDefinition<T> {
}
SQLStatement stat = new SQLStatement(db);
StatementBuilder buff = new StatementBuilder("MERGE INTO ");
buff.append(db.getDialect().tableName(schemaName, tableName)).append(" (");
buff.append(db.getDialect().getTableName(schemaName, tableName)).append(" (");
buff.resetCount();
for (FieldDefinition field : fields) {
buff.appendExceptFirst(", ");
......@@ -362,7 +360,7 @@ class TableDefinition<T> {
}
SQLStatement stat = new SQLStatement(db);
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(db.getDialect().tableName(schemaName, tableName)).append(" SET ");
buff.append(db.getDialect().getTableName(schemaName, tableName)).append(" SET ");
buff.resetCount();
for (FieldDefinition field : fields) {
......@@ -403,7 +401,7 @@ class TableDefinition<T> {
}
SQLStatement stat = new SQLStatement(db);
StatementBuilder buff = new StatementBuilder("DELETE FROM ");
buff.append(db.getDialect().tableName(schemaName, tableName));
buff.append(db.getDialect().getTableName(schemaName, tableName));
buff.resetCount();
Object alias = Utils.newObject(obj.getClass());
Query<Object> query = Query.from(db, alias);
......@@ -429,44 +427,38 @@ class TableDefinition<T> {
TableDefinition<T> createTableIfRequired(Db db) {
if (!createTableIfRequired) {
// Skip table and index creation
// But still check for upgrades
// skip table and index creation
// but still check for upgrades
db.upgradeTable(this);
return this;
}
SQLDialect dialect = db.getDialect();
SQLStatement stat = new SQLStatement(db);
StatementBuilder buff;
if (memoryTable &&
db.getConnection().getClass()
.getCanonicalName().equals("org.h2.jdbc.JdbcConnection")) {
if (memoryTable && dialect.supportsMemoryTables()) {
buff = new StatementBuilder("CREATE MEMORY TABLE IF NOT EXISTS ");
} else {
buff = new StatementBuilder("CREATE TABLE IF NOT EXISTS ");
}
int todoChangeToGetTableNameChangeAllMethodsInDialectInterface;
buff.append(db.getDialect().tableName(schemaName, tableName)).append('(');
buff.append(dialect.getTableName(schemaName, tableName)).append('(');
for (FieldDefinition field : fields) {
buff.appendExceptFirst(", ");
buff.append(field.columnName).append(' ').append(field.dataType);
// FIELD LENGTH
if (field.maxLength > 0) {
buff.append('(').append(field.maxLength).append(')');
}
// AUTO_INCREMENT
if (field.isAutoIncrement) {
buff.append(" AUTO_INCREMENT");
}
// NOT NULL
if (!field.allowNull) {
buff.append(" NOT NULL");
}
// DEFAULT...
// default values
if (!field.isAutoIncrement && !field.isPrimaryKey) {
String dv = field.defaultValue;
if (!StringUtils.isNullOrEmpty(dv)) {
......@@ -478,8 +470,7 @@ class TableDefinition<T> {
}
}
int reviewJavadoc;
// PRIMARY KEY...
// primary key
if (primaryKeyColumnNames != null && primaryKeyColumnNames.size() > 0) {
buff.append(", PRIMARY KEY(");
buff.resetCount();
......@@ -494,24 +485,24 @@ class TableDefinition<T> {
StatementLogger.create(stat.getSQL());
stat.executeUpdate();
// Create Indexes
// create indexes
for (IndexDefinition index:indexes) {
String sql = db.getDialect().createIndex(schemaName, tableName, index);
String sql = db.getDialect().getCreateIndex(schemaName, tableName, index);
stat.setSQL(sql);
StatementLogger.create(stat.getSQL());
stat.executeUpdate();
}
// Table is created IF NOT EXISTS, otherwise statement is ignored
// But we still need to process potential Upgrade
// tables are created using IF NOT EXISTS
// but we may still need to upgrade
db.upgradeTable(this);
return this;
}
/**
* Retrieve list of columns from CSV whitespace notated index
* Retrieve list of columns from index definition.
*
* @param index the index columns
* @param index the index columns, separated by space
* @return the column list
*/
private List<String> getColumns(String index) {
......@@ -569,7 +560,7 @@ class TableDefinition<T> {
if (clazz.isAnnotationPresent(JQIndex.class)) {
JQIndex indexAnnotation = clazz.getAnnotation(JQIndex.class);
// Setup the indexes, if properly annotated
// setup the indexes, if properly annotated
addIndexes(IndexType.STANDARD, indexAnnotation.standard());
addIndexes(IndexType.UNIQUE, indexAnnotation.unique());
addIndexes(IndexType.HASH, indexAnnotation.hash());
......
......@@ -493,8 +493,7 @@ public class TableInspector {
JQColumn.class.getSimpleName(), fieldDef.isAutoIncrement,
col.isAutoIncrement)));
}
// last check
// default value...
// default value
if (!col.isAutoIncrement && !col.isPrimaryKey) {
// check Model.defaultValue format
if (!ModelUtils.isProperlyFormattedDefaultValue(fieldDef.defaultValue)) {
......@@ -510,20 +509,20 @@ public class TableInspector {
&& !isNullOrEmpty(col.defaultValue)) {
// Model.defaultValue is NULL, Column.defaultValue is NOT NULL
remarks.add(warn(table, col, format("{0}.defaultValue=\"\""
+ " while Column default=\"{1}\"",
+ " 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}\""
+ " while Column default=\"\"",
+ " 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}\""
+ " while Column default=\"{2}\"",
+ " while column default=\"{2}\"",
JQColumn.class.getSimpleName(), fieldDef.defaultValue,
col.defaultValue)));
}
......@@ -533,7 +532,7 @@ public class TableInspector {
if (!ModelUtils.isValidDefaultValue(fieldDef.field.getType(),
fieldDef.defaultValue)) {
remarks.add(error(table, col,
format("{0}.defaultValue=\"{1}\" is invalid!!",
format("{0}.defaultValue=\"{1}\" is invalid!",
JQColumn.class.getSimpleName(),
fieldDef.defaultValue)));
}
......
......@@ -25,7 +25,7 @@ public class UpdateColumnIncrement<T, A> implements UpdateColumn {
}
public Query<T> by(A y) {
query.addDeclarationToken(this);
query.addUpdateColumnDeclaration(this);
this.y = y;
return query;
}
......
......@@ -25,7 +25,7 @@ public class UpdateColumnSet<T, A> implements UpdateColumn {
}
public Query<T> to(A y) {
query.addDeclarationToken(this);
query.addUpdateColumnDeclaration(this);
this.y = y;
return query;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论