
com.iciql.Iciql Maven / Gradle / Ivy
Show all versions of iciql Show documentation
/*
* 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.
*
*
* - @IQIndex("name")
*
- @IQIndex({"street", "city"})
*
- @IQIndex(name="streetidx", value={"street", "city"})
*
- @IQIndex(name="addressidx", type=IndexType.UNIQUE,
* value={"house_number", "street", "city"})
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IQIndex {
/**
* Index name. If null or empty, iciql will generate one.
*/
String name() default "";
/**
* Type of the index.
*
* - com.iciql.iciql.IndexType.STANDARD
*
- com.iciql.iciql.IndexType.UNIQUE
*
- com.iciql.iciql.IndexType.HASH
*
- com.iciql.iciql.IndexType.UNIQUE_HASH
*
*
* HASH indexes may only be valid for single column indexes.
*/
IndexType type() default IndexType.STANDARD;
/**
* Columns to include in index.
*
* - single column index: value = "id"
*
- multiple column index: value = { "id", "name", "date" }
*
*/
String[] value() default {};
}
/**
* Enumeration defining the ON DELETE actions.
*/
public static enum ConstraintDeleteType {
UNSET, CASCADE, RESTRICT, SET_NULL, NO_ACTION, SET_DEFAULT;
}
/**
* Enumeration defining the ON UPDATE actions.
*/
public static enum ConstraintUpdateType {
UNSET, CASCADE, RESTRICT, SET_NULL, NO_ACTION, SET_DEFAULT;
}
/**
* Enumeration defining the deferrability.
*/
public static enum ConstraintDeferrabilityType {
UNSET, DEFERRABLE_INITIALLY_DEFERRED, DEFERRABLE_INITIALLY_IMMEDIATE, NOT_DEFERRABLE;
}
/**
* A foreign key constraint annotation.
*
*
* - @IQContraintForeignKey(
* foreignColumns = { "idaccount"},
* referenceName = "account",
* referenceColumns = { "id" },
* deleteType = ConstrainDeleteType.CASCADE,
* updateType = ConstraintUpdateType.NO_ACTION )
*
* Note : reference columns should have a unique constraint defined in referenceName table,
* some database used to define a unique index instead of a unique constraint
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IQContraintForeignKey {
/**
* Constraint name. If null or empty, iciql will generate one.
*/
String name() default "";
/**
* Type of the action on delete, default to unspecified.
*
* - com.iciql.iciql.ConstrainDeleteType.CASCADE
*
- com.iciql.iciql.ConstrainDeleteType.RESTRICT
*
- com.iciql.iciql.ConstrainDeleteType.SET_NULL
*
- com.iciql.iciql.ConstrainDeleteType.NO_ACTION
*
- com.iciql.iciql.ConstrainDeleteType.SET_DEFAULT
*
*/
ConstraintDeleteType deleteType() default ConstraintDeleteType.UNSET;
/**
* Type of the action on update, default to unspecified.
*
* - com.iciql.iciql.ConstrainUpdateType.CASCADE
*
- com.iciql.iciql.ConstrainUpdateType.RESTRICT
*
- com.iciql.iciql.ConstrainUpdateType.SET_NULL
*
- com.iciql.iciql.ConstrainUpdateType.NO_ACTION
*
- com.iciql.iciql.ConstrainUpdateType.SET_DEFAULT
*
*/
ConstraintUpdateType updateType() default ConstraintUpdateType.UNSET;
/**
* Type of the deferrability mode, default to unspecified
*
* - com.iciql.iciql.ConstrainUpdateType.CASCADE
*
- ConstraintDeferrabilityType.DEFERRABLE_INITIALLY_DEFERRED
*
- ConstraintDeferrabilityType.DEFERRABLE_INITIALLY_IMMEDIATE
*
- ConstraintDeferrabilityType.NOT_DEFERRABLE
*
*/
ConstraintDeferrabilityType deferrabilityType() default ConstraintDeferrabilityType.UNSET;
/**
* The source table for the columns defined as foreign.
*/
String tableName() default "";
/**
* Columns defined as 'foreign'.
*
* - single column : foreignColumns = "id"
*
- multiple column : foreignColumns = { "id", "name", "date" }
*
*/
String[] foreignColumns() default {};
/**
* The reference table for the columns defined as references.
*/
String referenceName() default "";
/**
* Columns defined as 'references'.
*
* - single column : referenceColumns = "id"
*
- multiple column : referenceColumns = { "id", "name", "date" }
*
*/
String[] referenceColumns() default {};
}
/**
* Annotation to specify multiple foreign keys constraints.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IQContraintsForeignKey {
IQContraintForeignKey[] value() default {};
}
/**
* A unique constraint annotation.
*
*
* - @IQContraintUnique(uniqueColumns = { "street", "city" })
*
- @IQContraintUnique(name="streetconstraint", uniqueColumns = { "street", "city" })
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IQContraintUnique {
/**
* Constraint name. If null or empty, iciql will generate one.
*/
String name() default "";
/**
* Columns defined as 'unique'.
*
* - single column : uniqueColumns = "id"
*
- multiple column : uniqueColumns = { "id", "name", "date" }
*
*/
String[] uniqueColumns() default {};
}
/**
* Annotation to specify multiple unique constraints.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IQContraintsUnique {
IQContraintUnique[] value() default {};
}
/**
* Annotation to define a view.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface IQView {
/**
* The view name. If not specified the class name is used as the view
* name.
*
* 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. IQTable and IQView annotations present on the super
* class or above are honored. 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.
*
* - single column primaryKey: value = "id"
*
- compound primary key: value = { "id", "name" }
*
* The primary key may still be overridden in the define() method if the
* model class is not annotated with IQTable. Default: unspecified.
*/
String[] primaryKey() default {};
/**
* The inherit columns allows this model class to inherit columns from
* its super class. IQTable and IQView annotations present on the super
* class or above are honored. Default: false.
*/
boolean inheritColumns() default false;
/**
* Whether or not iciql tries to create the table and indexes. Default:
* true.
*/
boolean create() default true;
/**
* If true, only fields that are explicitly annotated as IQColumn 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
* and HSQL databases. Default: false.
*/
boolean memoryTable() default false;
}
/**
* Annotation to define a column. Annotated fields may have any scope
* (however, the JVM may raise a SecurityException if the SecurityManager
* doesn't allow iciql to access the field.)
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface IQColumn {
/**
* 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;
/**
* Length is used to define the length of a VARCHAR column or to define
* the precision of a DECIMAL(precision, scale) expression.
*
* 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:
*
* - defaultValue="" (null)
*
- defaultValue="CURRENT_TIMESTAMP"
*
- defaultValue="''" (empty string)
*
- defaultValue="'0'"
*
- defaultValue="'1970-01-01 00:00:01'"
*
* 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.
*
* 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 {
X enumId();
Class enumIdClass();
}
/**
* Enumeration representing how to map a java.lang.Enum to a column.
*
*
* - NAME - name() : string
*
- ORDINAL - ordinal() : int
*
- ENUMID - enumId() : X
*
*
* @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.
*
* This annotation can be used on:
*
* - a field instance of an enumeration type
*
- on the enumeration class declaration
*
* 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.
*
* The default mapping is by NAME.
*
*
* 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.
*
NOTE: Data type adapters are not thread-safe!
*
* @param
*/
public interface DataTypeAdapter {
/**
* The SQL data type for this adapter.
*
* @return the SQL data type
*/
String getDataType();
/**
* The Java domain type for this adapter.
*
* @return the Java domain type
*/
Class getJavaType();
/**
* Set the runtime mode.
*
* Allows type adapters to adapt type mappings based on the runtime
* mode.
*
*
* @param mode
*/
void setMode(Mode mode);
/**
* Serializes your Java object into a JDBC object.
*
* @param value
* @return a JDBC object
*/
Object serialize(T value);
/**
* Deserializes a JDBC object into your Java object.
*
* @param value
* @return the Java object
*/
T deserialize(Object value);
}
}