1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package androidx.room;
17 
18 import static java.lang.annotation.RetentionPolicy.SOURCE;
19 
20 import androidx.annotation.IntDef;
21 
22 import java.lang.annotation.Retention;
23 
24 /**
25  * Declares a foreign key on another {@link Entity}.
26  * <p>
27  * Foreign keys allows you to specify constraints across Entities such that SQLite will ensure that
28  * the relationship is valid when you modify the database.
29  * <p>
30  * When a foreign key constraint is specified, SQLite requires the referenced columns to be part of
31  * a unique index in the parent table or the primary key of that table. You must create a unique
32  * index in the parent entity that covers the referenced columns (Room will verify this at compile
33  * time and print an error if it is missing).
34  * <p>
35  * It is also recommended to create an index on the child table to avoid full table scans when the
36  * parent table is modified. If a suitable index on the child table is missing, Room will print
37  * {@link RoomWarnings#MISSING_INDEX_ON_FOREIGN_KEY_CHILD} warning.
38  * <p>
39  * A foreign key constraint can be deferred until the transaction is complete. This is useful if
40  * you are doing bulk inserts into the database in a single transaction. By default, foreign key
41  * constraints are immediate but you can change this value by setting {@link #deferred()} to
42  * {@code true}. You can also use
43  * <a href="https://sqlite.org/pragma.html#pragma_defer_foreign_keys">defer_foreign_keys</a> PRAGMA
44  * to defer them depending on your transaction.
45  * <p>
46  * Please refer to the SQLite <a href="https://sqlite.org/foreignkeys.html">foreign keys</a>
47  * documentation for details.
48  */
49 public @interface ForeignKey {
50     /**
51      * The parent Entity to reference. It must be a class annotated with {@link Entity} and
52      * referenced in the same database.
53      *
54      * @return The parent Entity.
55      */
entity()56     Class entity();
57 
58     /**
59      * The list of column names in the parent {@link Entity}.
60      * <p>
61      * Number of columns must match the number of columns specified in {@link #childColumns()}.
62      *
63      * @return The list of column names in the parent Entity.
64      * @see #childColumns()
65      */
parentColumns()66     String[] parentColumns();
67 
68     /**
69      * The list of column names in the current {@link Entity}.
70      * <p>
71      * Number of columns must match the number of columns specified in {@link #parentColumns()}.
72      *
73      * @return The list of column names in the current Entity.
74      */
childColumns()75     String[] childColumns();
76 
77     /**
78      * Action to take when the parent {@link Entity} is deleted from the database.
79      * <p>
80      * By default, {@link #NO_ACTION} is used.
81      *
82      * @return The action to take when the referenced entity is deleted from the database.
83      */
onDelete()84     @Action int onDelete() default NO_ACTION;
85 
86     /**
87      * Action to take when the parent {@link Entity} is updated in the database.
88      * <p>
89      * By default, {@link #NO_ACTION} is used.
90      *
91      * @return The action to take when the referenced entity is updated in the database.
92      */
onUpdate()93     @Action int onUpdate() default NO_ACTION;
94 
95     /**
96      * * A foreign key constraint can be deferred until the transaction is complete. This is useful
97      * if you are doing bulk inserts into the database in a single transaction. By default, foreign
98      * key constraints are immediate but you can change it by setting this field to {@code true}.
99      * You can also use
100      * <a href="https://sqlite.org/pragma.html#pragma_defer_foreign_keys">defer_foreign_keys</a>
101      * PRAGMA to defer them depending on your transaction.
102      *
103      * @return Whether the foreign key constraint should be deferred until the transaction is
104      * complete. Defaults to {@code false}.
105      */
deferred()106     boolean deferred() default false;
107 
108     /**
109      * Possible value for {@link #onDelete()} or {@link #onUpdate()}.
110      * <p>
111      * When a parent key is modified or deleted from the database, no special action is taken.
112      * This means that SQLite will not make any effort to fix the constraint failure, instead,
113      * reject the change.
114      */
115     int NO_ACTION = 1;
116 
117     /**
118      * Possible value for {@link #onDelete()} or {@link #onUpdate()}.
119      * <p>
120      * The RESTRICT action means that the application is prohibited from deleting
121      * (for {@link #onDelete()}) or modifying (for {@link #onUpdate()}) a parent key when there
122      * exists one or more child keys mapped to it. The difference between the effect of a RESTRICT
123      * action and normal foreign key constraint enforcement is that the RESTRICT action processing
124      * happens as soon as the field is updated - not at the end of the current statement as it would
125      * with an immediate constraint, or at the end of the current transaction as it would with a
126      * {@link #deferred()} constraint.
127      * <p>
128      * Even if the foreign key constraint it is attached to is {@link #deferred()}, configuring a
129      * RESTRICT action causes SQLite to return an error immediately if a parent key with dependent
130      * child keys is deleted or modified.
131      */
132     int RESTRICT = 2;
133 
134     /**
135      * Possible value for {@link #onDelete()} or {@link #onUpdate()}.
136      * <p>
137      * If the configured action is "SET NULL", then when a parent key is deleted
138      * (for {@link #onDelete()}) or modified (for {@link #onUpdate()}), the child key columns of all
139      * rows in the child table that mapped to the parent key are set to contain {@code NULL} values.
140      */
141     int SET_NULL = 3;
142 
143     /**
144      * Possible value for {@link #onDelete()} or {@link #onUpdate()}.
145      * <p>
146      * The "SET DEFAULT" actions are similar to {@link #SET_NULL}, except that each of the child key
147      * columns is set to contain the columns default value instead of {@code NULL}.
148      */
149     int SET_DEFAULT = 4;
150 
151     /**
152      * Possible value for {@link #onDelete()} or {@link #onUpdate()}.
153      * <p>
154      * A "CASCADE" action propagates the delete or update operation on the parent key to each
155      * dependent child key. For {@link #onDelete()} action, this means that each row in the child
156      * entity that was associated with the deleted parent row is also deleted. For an
157      * {@link #onUpdate()} action, it means that the values stored in each dependent child key are
158      * modified to match the new parent key values.
159      */
160     int CASCADE = 5;
161 
162     /**
163      * Constants definition for values that can be used in {@link #onDelete()} and
164      * {@link #onUpdate()}.
165      */
166     @IntDef({NO_ACTION, RESTRICT, SET_NULL, SET_DEFAULT, CASCADE})
167     @Retention(SOURCE)
168     @interface Action {
169     }
170 }
171