119b41105359a52aeb80070dec40247241231f05dYigit Boyar/*
219b41105359a52aeb80070dec40247241231f05dYigit Boyar * Copyright (C) 2016 The Android Open Source Project
319b41105359a52aeb80070dec40247241231f05dYigit Boyar *
419b41105359a52aeb80070dec40247241231f05dYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
519b41105359a52aeb80070dec40247241231f05dYigit Boyar * you may not use this file except in compliance with the License.
619b41105359a52aeb80070dec40247241231f05dYigit Boyar * You may obtain a copy of the License at
719b41105359a52aeb80070dec40247241231f05dYigit Boyar *
819b41105359a52aeb80070dec40247241231f05dYigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
919b41105359a52aeb80070dec40247241231f05dYigit Boyar *
1019b41105359a52aeb80070dec40247241231f05dYigit Boyar * Unless required by applicable law or agreed to in writing, software
1119b41105359a52aeb80070dec40247241231f05dYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1219b41105359a52aeb80070dec40247241231f05dYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1319b41105359a52aeb80070dec40247241231f05dYigit Boyar * See the License for the specific language governing permissions and
1419b41105359a52aeb80070dec40247241231f05dYigit Boyar * limitations under the License.
1519b41105359a52aeb80070dec40247241231f05dYigit Boyar */
1619b41105359a52aeb80070dec40247241231f05dYigit Boyar
17bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverettepackage androidx.room;
1819b41105359a52aeb80070dec40247241231f05dYigit Boyar
1919b41105359a52aeb80070dec40247241231f05dYigit Boyarimport java.lang.annotation.ElementType;
2019b41105359a52aeb80070dec40247241231f05dYigit Boyarimport java.lang.annotation.Retention;
2119b41105359a52aeb80070dec40247241231f05dYigit Boyarimport java.lang.annotation.RetentionPolicy;
2219b41105359a52aeb80070dec40247241231f05dYigit Boyarimport java.lang.annotation.Target;
2319b41105359a52aeb80070dec40247241231f05dYigit Boyar
241a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar/**
251a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * Marks a method in a {@link Dao} annotated class as a query method.
261a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
27e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * The value of the annotation includes the query that will be run when this method is called. This
28e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * query is <b>verified at compile time</b> by Room to ensure that it compiles fine against the
29e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * database.
301a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
311a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * The arguments of the method will be bound to the bind arguments in the SQL statement. See
32f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * <href="https://www.sqlite.org/c3ref/bind_blob.html">SQLite's binding documentation</> for
33e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * details of bind arguments in SQLite.
341a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
353542101509120586bbae17b1f748f302e1fb82a3Yigit Boyar * Room only supports named bind parameter {@code :name} to avoid any confusion between the
363542101509120586bbae17b1f748f302e1fb82a3Yigit Boyar * method parameters and the query bind parameters.
371a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
383542101509120586bbae17b1f748f302e1fb82a3Yigit Boyar * Room will automatically bind the parameters of the method into the bind arguments. This is done
393542101509120586bbae17b1f748f302e1fb82a3Yigit Boyar * by matching the name of the parameters to the name of the bind arguments.
401a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <pre>
411a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar *     {@literal @}Query("SELECT * FROM user WHERE user_name LIKE :name AND last_name LIKE :last")
421a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar *     public abstract List&lt;User&gt; findUsersByNameAndLastName(String name, String last);
431a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * </pre>
441a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
451a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * As an extension over SQLite bind arguments, Room supports binding a list of parameters to the
461a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * query. At runtime, Room will build the correct query to have matching number of bind arguments
471a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * depending on the number of items in the method parameter.
481a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <pre>
493542101509120586bbae17b1f748f302e1fb82a3Yigit Boyar *     {@literal @}Query("SELECT * FROM user WHERE uid IN(:userIds)")
50e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets *     public abstract List<User> findByIds(int[] userIds);
511a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * </pre>
52e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * For the example above, if the {@code userIds} is an array of 3 elements, Room will run the
53e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * query as: {@code SELECT * FROM user WHERE uid IN(?, ?, ?)} and bind each item in the
54e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * {@code userIds} array into the statement.
551a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
561a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * There are 3 types of queries supported in {@code Query} methods: SELECT, UPDATE and DELETE.
571a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
581a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * For SELECT queries, Room will infer the result contents from the method's return type and
591a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * generate the code that will automatically convert the query result into the method's return
60f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * type. For single result queries, the return type can be any java object. For queries that return
61f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * multiple values, you can use {@link java.util.List} or {@code Array}. In addition to these, any
62f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * query may return {@link android.database.Cursor Cursor} or any query result can be wrapped in
63bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverette * a {@link androidx.lifecycle.LiveData LiveData}.
641a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * <p>
653c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar * <b>RxJava2</b> If you are using RxJava2, you can also return {@code Flowable<T>} or
663c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar * {@code Publisher<T>} from query methods. Since Reactive Streams does not allow {@code null}, if
673c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar * the query returns a nullable type, it will not dispatch anything if the value is {@code null}
683c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar * (like fetching an {@link Entity} row that does not exist).
693c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar * You can return {@code Flowable<T[]>} or {@code Flowable<List<T>>} to workaround this limitation.
703c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar * <p>
71b6faa288a6994ca345f10a4dedb1dac12c1af0d0Yigit Boyar * Both {@code Flowable<T>} and {@code Publisher<T>} will observe the database for changes and
72b6faa288a6994ca345f10a4dedb1dac12c1af0d0Yigit Boyar * re-dispatch if data changes. If you want to query the database without observing changes, you can
73b6faa288a6994ca345f10a4dedb1dac12c1af0d0Yigit Boyar * use {@code Maybe<T>} or {@code Single<T>}. If a {@code Single<T>} query returns {@code null},
74b6faa288a6994ca345f10a4dedb1dac12c1af0d0Yigit Boyar * Room will throw
75bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverette * {@link androidx.room.EmptyResultSetException EmptyResultSetException}.
76b6faa288a6994ca345f10a4dedb1dac12c1af0d0Yigit Boyar * <p>
771a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * UPDATE or DELETE queries can return {@code void} or {@code int}. If it is an {@code int},
781a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar * the value is the number of rows affected by this query.
79e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * <p>
80e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * You can return arbitrary POJOs from your query methods as long as the fields of the POJO match
81e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * the column names in the query result.
82e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * For example, if you have class:
83e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * <pre>
84e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * class UserName {
85e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets *     public String name;
86e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets *     {@literal @}ColumnInfo(name = "last_name")
87e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets *     public String lastName;
88e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * }
89e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * </pre>
90e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * You can write a query like this:
91e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * <pre>
923542101509120586bbae17b1f748f302e1fb82a3Yigit Boyar *     {@literal @}Query("SELECT last_name, name FROM user WHERE uid = :userId LIMIT 1")
93e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets *     public abstract UserName findOneUserName(int userId);
94e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * </pre>
95e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets * And Room will create the correct implementation to convert the query result into a
96f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * {@code UserName} object. If there is a mismatch between the query result and the fields of the
97f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * POJO, as long as there is at least 1 field match, Room prints a
98f288e96bb97e063b07b17706d5e97837645bb55dYigit Boyar * {@link RoomWarnings#CURSOR_MISMATCH} warning and sets as many fields as it can.
991a87a9b1cbefada2e48d200cc9f6f8af9a9a1c44Yigit Boyar */
10019b41105359a52aeb80070dec40247241231f05dYigit Boyar@Target(ElementType.METHOD)
101e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets@Retention(RetentionPolicy.CLASS)
10219b41105359a52aeb80070dec40247241231f05dYigit Boyarpublic @interface Query {
103e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets    /**
104e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets     * The SQLite query to be run.
105e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets     * @return The query to be run.
106e69e470336d0b6a1b4a16fe1783af17143d0c426Sergey Vasilinets     */
10719b41105359a52aeb80070dec40247241231f05dYigit Boyar    String value();
10819b41105359a52aeb80070dec40247241231f05dYigit Boyar}
109