/* * 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.jaqu; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * A class that implements this interface can be used as a database table. * <p> * You may implement the Table interface on your model object and optionally use * 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> * If a class is annotated with JQTable and at the same time implements Table, * the define() method is not called. * <p> * 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> * </tr> * <tr> * <td>java.lang.Byte</td><td>TINYINT</td> * </tr> * <tr> * <td>java.lang.Short</td><td>SMALLINT</td> * </tr> * <tr> * <td>java.lang.Integer</td><td>INT</td> * </tr> * <tr> * <td>java.lang.Long</td><td>BIGINT</td> * </tr> * <tr> * <td>java.lang.Float</td><td>REAL</td> * </tr> * <tr> * <td>java.lang.Double</td><td>DOUBLE</td> * </tr> * <tr> * <td>java.math.BigDecimal</td><td>DECIMAL</td> * </tr> * <tr> * <td>java.util.Date</td><td>TIMESTAMP</td> * </tr> * <tr> * <td>java.sql.Date</td><td>DATE</td> * </tr> * <tr> * <td>java.sql.Time</td><td>TIME</td> * </tr> * <tr> * <td>java.sql.Timestamp</td><td>TIMESTAMP</td> * </tr> * </table> * <p> * Unsupported data types: binary types (BLOB, etc), and custom types. * <p> * 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> * Table Interface: you may set additional parameters such as table name, * primary key, and indexes in the define() method. * <p> * 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> * Automatic model generation: you may automatically generate model classes as * strings with the Db and DbInspector objects: * <pre> * Db db = Db.open("jdbc:h2:mem:", "sa", "sa"); * DbInspector inspector = new DbInspector(db); * List<String> models = * inspector.generateModel(schema, table, packageName, * annotateSchema, trimStrings) * </pre> * 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 "jdbc:h2:mem:" * -user sa -password sa -schema schemaName -table tableName * -package packageName -folder destination * -annotateSchema false -trimStrings true * </pre> * * Model validation: you may validate your model class with DbInspector object. * The DbInspector will report errors, warnings, and suggestions: * <pre> * Db db = Db.open("jdbc:h2:mem:", "sa", "sa"); * DbInspector inspector = new DbInspector(db); * List<Validation> remarks = * inspector.validateModel(new MyModel(), throwOnError); * for (Validation remark : remarks) { * System.out.println(remark); * } * </pre> */ public interface Table { /** * An annotation for a database. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface JQDatabase { /** * 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. * Default: unspecified. */ String name() default ""; } /** * Enumeration defining the 4 index types. */ public static enum IndexType { STANDARD, UNIQUE, HASH, UNIQUE_HASH; } /** * An index annotation. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface JQIndex { /** * Standard indexes may be optionally specified. * <ul> * <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. */ String[] standard() default {}; /** * Unique indexes may be optionally specified. * <ul> * <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 define() method if * the model class is not annotated with JQTable. * Default: unspecified. */ String[] unique() default {}; /** * Hash indexes may be optionally specified. * <ul> * <li>hash = "name" * <li>hash = { "name", "date" } * </ul> * Hash indexes may still be added in the define() method if * the model class is not annotated with JQTable. * Default: unspecified. */ String[] hash() default {}; /** * Unique hash indexes may be optionally specified. * <ul> * <li>uniqueHash = "id" * <li>uniqueHash = "name" * <li>uniqueHash = { "id", "name" } * </ul> * Unique hash indexes may still be added in the define() method if * the model class is not annotated with JQTable. * Default: unspecified. */ String[] uniqueHash() default {}; } /** * Annotation to define a table. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface JQTable { /** * 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 define() method * if the model class is not annotated with JQTable. * Default: unspecified. */ String name() default ""; /** * 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 primary key may still be overridden in the define() method * if the model class is not annotated with JQTable. * Default: unspecified. */ String primaryKey() default ""; /** * The inherit columns allows this model class to inherit columns from * its super class. Any JQTable annotation present on the super class is * ignored. * Default: false. */ boolean inheritColumns() default false; /** * Whether or not JaQu tries to create the table and indexes. Default: * true. */ boolean createIfRequired() default true; /** * 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; /** * If true, only fields that are explicitly * annotated as JQColumn are mapped. * Default: true. */ boolean annotationsOnly() default true; /** * 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 non-zero, JaQu will * maintain 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; } /** * 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 not specified, the field name is used as the column name. * Default: the field name. */ String name() default ""; /** * This column is the primary key. * Default: false. */ boolean primaryKey() default false; /** * The column is created with a * sequence as the default value. * Default: false. */ boolean autoIncrement() default false; /** * 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 define() may override this annotation * setting if the model class is not annotated with JQTable. * Default: 0. */ int maxLength() default 0; /** * If true, JaQu will automatically trim the * string if it exceeds maxLength * (value.substring(0, maxLength)). * Default: false. */ boolean trimString() default false; /** * If false, JaQu will set * the column NOT NULL during the CREATE TABLE phase. * Default: false. */ boolean allowNull() default false; /** * 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" * <li>defaultValue="''" (empty string) * <li>defaultValue="'0'" * <li>defaultValue="'1970-01-01 00:00:01'" * </ul> * 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 ""; } /** * This method is called to let the table define the primary key, indexes, * and the table name. */ void define(); }