1/*
2 * Copyright (C) 2016 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
17package androidx.room;
18
19import java.lang.annotation.ElementType;
20import java.lang.annotation.Retention;
21import java.lang.annotation.RetentionPolicy;
22import java.lang.annotation.Target;
23
24/**
25 * Marks a method in a {@link Dao} annotated class as a query method.
26 * <p>
27 * The value of the annotation includes the query that will be run when this method is called. This
28 * query is <b>verified at compile time</b> by Room to ensure that it compiles fine against the
29 * database.
30 * <p>
31 * The arguments of the method will be bound to the bind arguments in the SQL statement. See
32 * <href="https://www.sqlite.org/c3ref/bind_blob.html">SQLite's binding documentation</> for
33 * details of bind arguments in SQLite.
34 * <p>
35 * Room only supports named bind parameter {@code :name} to avoid any confusion between the
36 * method parameters and the query bind parameters.
37 * <p>
38 * Room will automatically bind the parameters of the method into the bind arguments. This is done
39 * by matching the name of the parameters to the name of the bind arguments.
40 * <pre>
41 *     {@literal @}Query("SELECT * FROM user WHERE user_name LIKE :name AND last_name LIKE :last")
42 *     public abstract List&lt;User&gt; findUsersByNameAndLastName(String name, String last);
43 * </pre>
44 * <p>
45 * As an extension over SQLite bind arguments, Room supports binding a list of parameters to the
46 * query. At runtime, Room will build the correct query to have matching number of bind arguments
47 * depending on the number of items in the method parameter.
48 * <pre>
49 *     {@literal @}Query("SELECT * FROM user WHERE uid IN(:userIds)")
50 *     public abstract List<User> findByIds(int[] userIds);
51 * </pre>
52 * For the example above, if the {@code userIds} is an array of 3 elements, Room will run the
53 * query as: {@code SELECT * FROM user WHERE uid IN(?, ?, ?)} and bind each item in the
54 * {@code userIds} array into the statement.
55 * <p>
56 * There are 3 types of queries supported in {@code Query} methods: SELECT, UPDATE and DELETE.
57 * <p>
58 * For SELECT queries, Room will infer the result contents from the method's return type and
59 * generate the code that will automatically convert the query result into the method's return
60 * type. For single result queries, the return type can be any java object. For queries that return
61 * multiple values, you can use {@link java.util.List} or {@code Array}. In addition to these, any
62 * query may return {@link android.database.Cursor Cursor} or any query result can be wrapped in
63 * a {@link androidx.lifecycle.LiveData LiveData}.
64 * <p>
65 * <b>RxJava2</b> If you are using RxJava2, you can also return {@code Flowable<T>} or
66 * {@code Publisher<T>} from query methods. Since Reactive Streams does not allow {@code null}, if
67 * the query returns a nullable type, it will not dispatch anything if the value is {@code null}
68 * (like fetching an {@link Entity} row that does not exist).
69 * You can return {@code Flowable<T[]>} or {@code Flowable<List<T>>} to workaround this limitation.
70 * <p>
71 * Both {@code Flowable<T>} and {@code Publisher<T>} will observe the database for changes and
72 * re-dispatch if data changes. If you want to query the database without observing changes, you can
73 * use {@code Maybe<T>} or {@code Single<T>}. If a {@code Single<T>} query returns {@code null},
74 * Room will throw
75 * {@link androidx.room.EmptyResultSetException EmptyResultSetException}.
76 * <p>
77 * UPDATE or DELETE queries can return {@code void} or {@code int}. If it is an {@code int},
78 * the value is the number of rows affected by this query.
79 * <p>
80 * You can return arbitrary POJOs from your query methods as long as the fields of the POJO match
81 * the column names in the query result.
82 * For example, if you have class:
83 * <pre>
84 * class UserName {
85 *     public String name;
86 *     {@literal @}ColumnInfo(name = "last_name")
87 *     public String lastName;
88 * }
89 * </pre>
90 * You can write a query like this:
91 * <pre>
92 *     {@literal @}Query("SELECT last_name, name FROM user WHERE uid = :userId LIMIT 1")
93 *     public abstract UserName findOneUserName(int userId);
94 * </pre>
95 * And Room will create the correct implementation to convert the query result into a
96 * {@code UserName} object. If there is a mismatch between the query result and the fields of the
97 * POJO, as long as there is at least 1 field match, Room prints a
98 * {@link RoomWarnings#CURSOR_MISMATCH} warning and sets as many fields as it can.
99 */
100@Target(ElementType.METHOD)
101@Retention(RetentionPolicy.CLASS)
102public @interface Query {
103    /**
104     * The SQLite query to be run.
105     * @return The query to be run.
106     */
107    String value();
108}
109