/* * Copyright 2004-2011 H2 Group. * Copyright 2011 James Moger. * Copyright 2012 Frédéric Gaillard. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.iciql; 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. *
* You may implement the Table interface on your model object and optionally use * IQColumn annotations (which imposes a compile-time and runtime-dependency on * iciql), or may choose to use the IQTable and IQColumn annotations only (which * imposes a compile-time and runtime-dependency on this file only). *
* If a class is annotated with IQTable and at the same time implements Table, * the define() method is not called. *
* Fully Supported Data Types: *
All Databases | *|
---|---|
java.lang.String | *VARCHAR (length > 0) or CLOB (length == 0) | *
java.lang.Boolean | *BIT | *
java.lang.Byte | *TINYINT | *
java.lang.Short | *SMALLINT | *
java.lang.Integer | *INT | *
java.lang.Long | *BIGINT | *
java.lang.Float | *REAL | *
java.lang.Double | *DOUBLE | *
java.math.BigDecimal | *DECIMAL (length == 0) * DECIMAL(length, scale) (length > 0) |
*
java.sql.Date | *DATE | *
java.sql.Time | *TIME | *
java.sql.Timestamp | *TIMESTAMP | *
java.util.Date | *TIMESTAMP | *
java.lang.Enum.name() | *VARCHAR (length > 0) or CLOB (length == 0) * EnumType.NAME |
*
java.lang.Enum.ordinal() | *INT * EnumType.ORDINAL |
*
java.lang.Enum implements * com.iciql.Iciql.EnumID.enumId() |
* INT * EnumType.ENUMID |
*
H2 Databases | *|
java.util.UUID | *UUID | *
* Partially Supported Data Types: *
* The following data types can be mapped to columns for all general statements * BUT these field types may not be used to specify compile-time clauses or * constraints. *
byte [] | *BLOB | *
boolean | *BIT | *
byte | *TINYINT | *
short | *SMALLINT | *
int | *INT | *
long | *BIGINT | *
float | *REAL | *
double | *DOUBLE | *
* 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. *
* Table Interface: you may set additional parameters such as table name, * primary key, and indexes in the define() method. *
* Annotations: you may use the annotations with or without implementing the * Table interface. The annotations allow you to decouple your model completely * from iciql other than this file. *
* Automatic model generation: you may automatically generate model classes as * strings with the Db and DbInspector objects: * *
* Db db = Db.open("jdbc:h2:mem:", "sa", "sa"); * DbInspector inspector = new DbInspector(db); * List<String> models = * inspector.generateModel(schema, table, packageName, * annotateSchema, trimStrings) ** * Or you may use the GenerateModels tool to generate and save your classes to * the file system: * *
* java -jar iciql.jar * -url "jdbc:h2:mem:" * -user sa -password sa -schema schemaName -table tableName * -package packageName -folder destination * -annotateSchema false -trimStrings true ** * Model validation: you may validate your model class with DbInspector object. * The DbInspector will report errors, warnings, and suggestions: * *
* 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); * } **/ public interface Iciql { /** * An annotation for an iciql version. *
* * @IQVersion(1) */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface IQVersion { /** * If set to a non-zero value, iciql maintains a "iq_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 value() default 0; } /** * An annotation for a schema. *
* * @IQSchema("PUBLIC") */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface IQSchema { /** * The schema may be optionally specified. Default: unspecified. */ String value() default ""; } /** * Enumeration defining the four index types. */ public static enum IndexType { STANDARD, UNIQUE, HASH, UNIQUE_HASH; } /** * An index annotation. *
*
*
*
* The view name may still be overridden in the define() method if the * model class is not annotated with IQView. Default: unspecified. */ String name() default ""; /** * The source table for the view. *
* The view name may still be overridden in the define() method if the * model class is not annotated with IQView. Default: unspecified. */ String tableName() default ""; /** * The inherit columns allows this model class to inherit columns from * its super class. Any IQTable annotation present on the super class is * ignored. Default: false. */ boolean inheritColumns() default false; /** * Whether or not iciql tries to create the view. Default: * true. */ boolean create() default true; /** * If true, only fields that are explicitly annotated as IQColumn are * mapped. Default: true. */ boolean annotationsOnly() default true; } /** * String snippet defining SQL constraints for a field. Use "this" as * a placeholder for the column name. "this" will be substituted at * runtime. *
* IQConstraint("this > 2 AND this <= 7") *
* This snippet may still be overridden in the define() method if the * model class is not annotated with IQTable or IQView. Default: unspecified. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface IQConstraint { String value() default ""; } /** * Annotation to specify multiple indexes. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface IQIndexes { IQIndex[] value() default {}; } /** * Annotation to define a table. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface IQTable { /** * The table name. If not specified the class name is used as the table * name. *
* The table name may still be overridden in the define() method if the * model class is not annotated with IQTable. 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 IQTable annotation. You may specify * a composite primary key. *
* If larger than zero, it is used during the CREATE TABLE phase. For * string values it may also be used to prevent database exceptions on * INSERT and UPDATE statements (see trim). *
* Any length set in define() may override this annotation setting if * the model class is not annotated with IQTable. Default: 0. */ int length() default 0; /** * Scale is used during the CREATE TABLE phase to define the scale of a * DECIMAL(precision, scale) expression. *
* Any scale set in define() may override this annotation setting if the * model class is not annotated with IQTable. Default: 0. */ int scale() default 0; /** * If true, iciql will automatically trim the string if it exceeds * length (value.substring(0, length)). Default: false. */ boolean trim() default false; /** * If false, iciql will set the column NOT NULL during the CREATE TABLE * phase. Default: true. */ boolean nullable() default true; /** * 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: *
* Alternatively, you may specify a default object value on the field * and this will be converted to a properly formatted DEFAULT expression * during the CREATE TABLE process. *
* Default: unspecified (null). */ String defaultValue() default ""; } /** * Interface for using the EnumType.ENUMID enumeration mapping strategy. *
* Enumerations wishing to use EnumType.ENUMID must implement this
* interface.
*/
public interface EnumId
*
* This annotation can be used on:
*
* The default mapping is by NAME.
*
* NOTE: Data type adapters are not thread-safe!
* Allows type adapters to adapt type mappings based on the runtime
* mode.
*
*
*
* @see com.iciql.Iciql.EnumId interface
*/
public enum EnumType {
NAME, ORDINAL, ENUMID;
public static final EnumType DEFAULT_TYPE = NAME;
}
/**
* Annotation to define how a java.lang.Enum is mapped to a column.
*
*
* If you choose to annotate the class declaration, that will be the default
* mapping strategy for all @IQColumn instances of the enum. This can still
* be overridden for an individual field by specifying the IQEnum
* annotation.
*
* IQEnum(EnumType.NAME)
*
*
* A string mapping will generate either a VARCHAR, if IQColumn.length > 0
* or a TEXT column if IQColumn.length == 0
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.TYPE })
public @interface IQEnum {
EnumType value() default EnumType.NAME;
}
/**
* Annotation to define an ignored field.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IQIgnore{
}
/**
* The runtime mode for Iciql.
*/
public static enum Mode {
DEV, TEST, PROD;
public static Mode fromValue(String value) {
for (Mode mode : values()) {
if (mode.name().equalsIgnoreCase(value)) {
return mode;
}
}
return PROD;
}
}
/**
* This method is called to let the table define the primary key, indexes,
* and the table name.
*/
void defineIQ();
/**
* Specify a custom type adapter for a method return type, a class field, or a method
* parameter. Type adapters allow you to transform content received from or inserted into
* a database field.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface TypeAdapter {
Class extends DataTypeAdapter>> value();
}
/**
* Interface to allow implementations of custom data type adapters for supporting
* database-specific data types, like the Postgres 'json' or 'xml' types,
* or for supporting other object serialization schemes.
*