Constraints and indexes declarations

KittyORM supports indexes and constraints declaration by using annotations. Right now KittyORM offers you functionality to define seven supported by SQLite constraints without any need to define them in raw SQL code. Also in such way you can define table indexes. KittyORM is capable to define database schema with nearly all features that are supported by SQLite (SQL As Understood By SQLite) with usage only of annotations. In demo you can play with form for creating and inserting entity that declares all constraints and index.
Table of contents
NOT NULLconstraint declarationDEFAULTconstraint declarationUNIQUEconstraint declarationCHECKconstraint declarationCOLLATEconstraint declarationPRIMARY KEYconstraint declarationFOREIGN KEYconstraint declaration- Indexes declaration
NOT NULL constraint declaration
To declare NOT NULL constraint just annotate corresponding model field with @NOT_NULL annotation. Example:
1@KITTY_COLUMN(columnOrder = 0)
2@PRIMARY_KEY
3@NOT_NULL // NOT NULL constraint declaration
4public Long id;DEFAULT constraint declaration
To declare DEFAULT constraint just annotate corresponding model field with @DEFAULT annotation. Example:
1@KITTY_COLUMN(columnOrder = 3)
2@DEFAULT(signedInteger = 28) // You can choose for options for default declaration, if nothing set than 0 value would be used
3@NOT_NULL
4public Integer defaultNumber;@DEFAULT annotation then default value for annotated field would be 0 (int, zero). KittyORM provide you some options on declaring default constraints, for example, you can set as a default value for field predefined LiteralValues enum element, signed integer, literal value or expression. Example of declaring DEFAULT constraint from predefined literals:
1@KITTY_COLUMN(columnOrder = 4)
2@DEFAULT(
3 predefinedLiteralValue = LiteralValues.CURRENT_DATE
4)
5@NOT_NULL
6public String creationDate;DEFAULT constraint before inserting model you have to invoke on this model KittyModel.setFieldExclusion("modelFieldName") method. Example:
1IndexesAndConstraintsModel model = new IndexesAndConstraintsModel();
2model.animal = someAnimal;
3...
4model.setFieldExclusion("creationDate"); // Forces KittyORM to exclude this field at insertion so DEFAULT constraint would be triggered
5...
6KittyMapper mapper = getDatabase().getMapper(IndexesAndConstraintsModel.class);
7mapper.save(model);
8mapper.close();UNIQUE constraint declaration
You can declare UNIQUE constraint in two ways:
To declare
UNIQUEconstraint only on one column than just annotate model corresponding field with@UNIQUEannotation. Example:In order to set conflict clause just set1@KITTY_COLUMN(columnOrder = 1) 2@NOT_NULL 3@UNIQUE 4public Long rndId;@UNIQUE.onConflictfield with any suitable value fromConflictClausesenum.To declare
UNIQUEconstraint on more than one column annotate model with@UNIQUE_Tannotation. Example:In order to set conflict clause just set1@KITTY_TABLE(tableName = "cai") 2@FOREIGN_KEY_T( 3 name = "CAI_FK", 4 columns = {IndexesAndConstraintsModel.RANDOM_ID_CNAME}, 5 reference = @FOREIGN_KEY_REFERENCE( 6 foreignTableName = "random", 7 foreignTableColumns = {"id"}, 8 onUpdate = OnUpdateDeleteActions.CASCADE, 9 onDelete = OnUpdateDeleteActions.CASCADE 10 ) 11) 12@INDEX(indexColumns = {"creation_date"}) 13@UNIQUE_T(columns = {"rnd_id, animal"}) // Declaring unique constraint on more than two columns 14public class IndexesAndConstraintsModel extends KittyModel { 15 ... 16}@UNIQUE_T.onConflictfield with any suitable value fromConflictClausesenum.
In order to setUNIQUEconstraint name set@UNIQUE_T.nameotherwise it would be generated automatically.
If you need more than oneUNIQUEconstraint declaration defined with usage of@UNIQUE_Tannotation, annotate model withUNIQUE_T_ARRAY.
CHECK constraint declaration
To declare CHECK constraint just annotate corresponding model field with @CHECK annotation and specify check expression. Example:
1@KITTY_COLUMN(columnOrder = 2)
2@CHECK(checkExpression = "animal IN (\"CAT\", \"TIGER\", \"LION\")") // only cats allowed to this party
3public Animals animal;COLLATE constraint declaration
To declare COLLATE constraint just annotate corresponding model field with @COLLATE annotation and specify built-in collation. Example:
1@KITTY_COLUMN(columnOrder = 2)
2@COLLATE(collation = BuiltInCollations.NOCASE) // Collation example
3@CHECK(checkExpression = "animal IN (\"CAT\", \"TIGER\", \"LION\")")
4public Animals animal;PRIMARY KEY constraint declaration
You can declare PRIMARY KEY constraint in three ways:
To define
INTEGER PRIMARY KEYjust set@KITTY_COLUMN.isIPKfield value totrueof corresponding model field. Example:1@KITTY_COLUMN( 2 columnOrder = 0, 3 isIPK = true 4) 5public Long id;Second way to define
PRIMARY KEYis to annotate corresponding model field with@PRIMARY_KEYannotation. Example:In order to set order just set1@KITTY_COLUMN(columnOrder = 0) 2@PRIMARY_KEY 3@NOT_NULL 4public Long id;PRIMARY_KEY.orderAscDescfield with any suitable value fromAscDescenum.
In order to setAUTOIMCREMENTflag set@PRIMARY_KEY.autoincrementfield to true (default false).
In order to set conflict clause just set@PRIMARY_KEY.onConflictfield with any suitable value fromConflictClausesenum.Third way to define
PRIMARY KEYis to annotate model implementation with@PRIMARY_KEY_Tannotation and specify@PRIMARY_KEY_T.columnsarray. Example:In order to set1@KITTY_TABLE(tableName = "cpk_test") 2@PRIMARY_KEY_T( 3 columns = {"user_name", "email"} 4) 5public class CPKModel extends KittyModel { 6 7 @KITTY_COLUMN(columnOrder = 0) 8 public String userName; 9 10 @KITTY_COLUMN(columnOrder = 1) 11 @UNIQUE 12 public String email; 13 14 ... 15}PRIMARY KEYconstraint name set@PRIMARY_KEY_T.nameotherwise it would be generated automatically.
In order to set conflict clause just set@PRIMARY_KEY_T.onConflictfield with any suitable value fromConflictClausesenum.
FOREIGN KEY constraint declaration
You can declare FOREIGN KEY constraint in two ways:
If you have only one column at table that refer to another table column you can just annotate corresponding model field with
@FOREIGN_KEYannotation and specify@FOREIGN_KEY.referencewith@FOREIGN_KEY_REFERENCE. Example:1@KITTY_COLUMN(columnOrder = 1) 2@NOT_NULL 3@UNIQUE 4@FOREIGN_KEY( 5 reference = @FOREIGN_KEY_REFERENCE( 6 foreignTableName = "random", 7 foreignTableColumns = {"id"}, 8 onUpdate = OnUpdateDeleteActions.CASCADE, 9 onDelete = OnUpdateDeleteActions.CASCADE 10 ) 11) 12public Long rndId;If you have more than one reference column at
FOREIGN KEYdeclaration, annotate model with@FOREIGN_KEY_Tannotation and specify@FOREIGN_KEY_T.referencewith@FOREIGN_KEY_REFERENCEand@FOREIGN_KEY_T.columnswith string array of reference columns. Example:In order to set1@KITTY_TABLE(tableName = "cai") 2@FOREIGN_KEY_T( 3 name = "CAI_FK", 4 columns = {IndexesAndConstraintsModel.RANDOM_ID_CNAME}, 5 reference = @FOREIGN_KEY_REFERENCE( 6 foreignTableName = "random", 7 foreignTableColumns = {"id"}, 8 onUpdate = OnUpdateDeleteActions.CASCADE, 9 onDelete = OnUpdateDeleteActions.CASCADE 10 ) 11) 12@INDEX(indexColumns = {"creation_date"}) 13public class IndexesAndConstraintsModel extends KittyModel { 14 ... 15 16 @KITTY_COLUMN(columnOrder = 1) 17 @NOT_NULL 18 @UNIQUE 19 public Long rndId; 20 21 ... 22}FOREIGN KEYconstraint name set@FOREIGN_KEY_T.nameotherwise it would be generated automatically.
If you need more than one FK that can be declared only with @FOREIGN_KEY_T you can annotate model implementation @FOREIGN_KEY_T_ARRAY and specify at @FOREIGN_KEY_T_ARRAY.foreignKeys all foreign keys you need.
At @FOREIGN_KEY_REFERENCE annotation you have to specify reference table and columns by setting @FOREIGN_KEY_REFERENCE.foreignTableName and @FOREIGN_KEY_REFERENCE.foreignTableColumns. Optionally you can specify ON UPDATE and ON DELETE actions by setting @FOREIGN_KEY_REFERENCE.onUpdate and @FOREIGN_KEY_REFERENCE.onDelete with enum element from OnUpdateDeleteActions. Also, you can specify defferable option by setting @FOREIGN_KEY_REFERENCE.deferrableOption with some value DeferrableOptions enumeration.
Do not forget to turn on foreign keys supports by setting @KITTY_DATABASE.isPragmaOn to true at your KittyORM database implementation if you want to use them!
Indexes declaration
In KittyORM indexes declarations stored at same POJO classes that are used for schema generation. To declare an index just annotate model implementation with columns that would be indexed with @INDEX annotation and set @INDEX.indexColumns with array of those indexed columns or in case when there is only one indexed column for one index declaration just annotate corresponding nodel implementation field with @ONE_COLUMN_INDEX. Example:
Index declaration with
@INDEXannotation:1@KITTY_TABLE(tableName = "cai") 2@FOREIGN_KEY_T( 3 name = "CAI_FK", 4 columns = {IndexesAndConstraintsModel.RANDOM_ID_CNAME}, 5 reference = @FOREIGN_KEY_REFERENCE( 6 foreignTableName = "random", 7 foreignTableColumns = {"id"}, 8 onUpdate = OnUpdateDeleteActions.CASCADE, 9 onDelete = OnUpdateDeleteActions.CASCADE 10 ) 11) 12@INDEX(indexColumns = {"creation_date"}) // index declaration 13public class IndexesAndConstraintsModel extends KittyModel { 14 ... 15 16 @KITTY_COLUMN(columnOrder = 4) 17 @DEFAULT( 18 predefinedLiteralValue = LiteralValues.CURRENT_DATE 19 ) 20 @NOT_NULL 21 public String creationDate; // indexed column 22 23 ... 24}Index declaration with
@ONE_COLUMN_INDEXannotation:1@KITTY_TABLE(tableName = "cai") 2... 3public class IndexesAndConstraintsModel extends KittyModel { 4 ... 5 6 @KITTY_COLUMN(columnOrder = 5) 7 @DEFAULT( 8 predefinedLiteralValue = LiteralValues.CURRENT_TIMESTAMP 9 ) 10 // One column indexe declaration example 11 @ONE_COLUMN_INDEX(unique = true, indexName = "IAC_unique_index_creation_timestamp") 12 @NOT_NULL 13 public Timestamp creationTmstmp; 14 15 ... 16}
For both @INDEX and @ONE_COLUMN_INDEX index declaration you can specify index uniqueness (@INDEX.unique and @ONE_COLUMN_INDEX.unique fields), IF NOT EXISTS flag (@INDEX.ifNotExists and @ONE_COLUMN_INDEX.ifNotExists fields), where expression (@INDEX.whereExpression and @ONE_COLUMN_INDEX.whereExpression fields) and index name (@INDEX.indexName and @ONE_COLUMN_INDEX.indexName fields).
If you need more than one index declaration with more than one indexed columns than annotate model implementation with @INDEX_ARRAY annotation and define your indexes there.