1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.enhanced.dynamodb;
17 
18 import java.util.function.Consumer;
19 import software.amazon.awssdk.annotations.SdkPublicApi;
20 import software.amazon.awssdk.annotations.ThreadSafe;
21 import software.amazon.awssdk.core.pagination.sync.SdkIterable;
22 import software.amazon.awssdk.enhanced.dynamodb.model.Page;
23 import software.amazon.awssdk.enhanced.dynamodb.model.QueryConditional;
24 import software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest;
25 import software.amazon.awssdk.enhanced.dynamodb.model.ScanEnhancedRequest;
26 
27 /**
28  * Synchronous interface for running commands against an object that is linked to a specific DynamoDb secondary index
29  * and knows how to map records from the table that index is linked to into a modelled object.
30  * <p>
31  * By default, all command methods throw an {@link UnsupportedOperationException} to prevent interface extensions from breaking
32  * implementing classes.
33  *
34  * @param <T> The type of the modelled object.
35  */
36 @SdkPublicApi
37 @ThreadSafe
38 public interface DynamoDbIndex<T> {
39 
40     /**
41      * Executes a query against a secondary index using a {@link QueryConditional} expression to retrieve a list of
42      * items matching the given conditions.
43      * <p>
44      * The result is accessed through iterable pages (see {@link Page}) in an interactive way; each time a
45      * result page is retrieved, a query call is made to DynamoDb to get those entries. If no matches are found,
46      * the resulting iterator will contain an empty page. Results are sorted by sort key value in
47      * ascending order by default; this behavior can be overridden in the {@link QueryEnhancedRequest}.
48      * <p>
49      * The additional configuration parameters that the enhanced client supports are defined
50      * in the {@link QueryEnhancedRequest}.
51      * <p>
52      * This operation calls the low-level DynamoDB API Query operation. Consult the Query documentation for
53      * further details and constraints.
54      * <p>
55      * Example:
56      * <pre>
57      * {@code
58      *
59      * QueryConditional queryConditional = QueryConditional.keyEqualTo(Key.builder().partitionValue("id-value").build());
60      * Iterator<Page<MyItem>> results = mappedIndex.query(QueryEnhancedRequest.builder()
61      *                                                                        .queryConditional(queryConditional)
62      *                                                                        .build());
63      * }
64      * </pre>
65      *
66      * @param request A {@link QueryEnhancedRequest} defining the query conditions and how
67      * to handle the results.
68      * @return an iterator of type {@link SdkIterable} with paginated results (see {@link Page}).
69      */
query(QueryEnhancedRequest request)70     default SdkIterable<Page<T>> query(QueryEnhancedRequest request) {
71         throw new UnsupportedOperationException();
72     }
73 
74     /**
75      * Executes a query against a secondary index using a {@link QueryConditional} expression to retrieve a list of
76      * items matching the given conditions.
77      * <p>
78      * The result is accessed through iterable pages (see {@link Page}) in an interactive way; each time a
79      * result page is retrieved, a query call is made to DynamoDb to get those entries. If no matches are found,
80      * the resulting iterator will contain an empty page. Results are sorted by sort key value in
81      * ascending order by default; this behavior can be overridden in the {@link QueryEnhancedRequest}.
82      * <p>
83      * The additional configuration parameters that the enhanced client supports are defined
84      * in the {@link QueryEnhancedRequest}.
85      * <p>
86      * This operation calls the low-level DynamoDB API Query operation. Consult the Query documentation for
87      * further details and constraints.
88      * <p>
89      * <b>Note:</b> This is a convenience method that creates an instance of the request builder avoiding the need to create one
90      * manually via {@link QueryEnhancedRequest#builder()}.
91      * <p>
92      * Example:
93      * <pre>
94      * {@code
95      *
96      * Iterator<Page<MyItem>> results =
97      *     mappedIndex.query(r -> r.queryConditional(QueryConditional.keyEqualTo(k -> k.partitionValue("id-value"))));
98      * }
99      * </pre>
100      *
101      * @param requestConsumer A {@link Consumer} of {@link QueryEnhancedRequest} defining the query conditions and how to
102      * handle the results.
103      * @return an iterator of type {@link SdkIterable} with paginated results (see {@link Page}).
104      */
query(Consumer<QueryEnhancedRequest.Builder> requestConsumer)105     default SdkIterable<Page<T>> query(Consumer<QueryEnhancedRequest.Builder> requestConsumer) {
106         throw new UnsupportedOperationException();
107     }
108 
109     /**
110      * Executes a query against the secondary index of the table using a {@link QueryConditional} expression to retrieve
111      * a list of items matching the given conditions.
112      * <p>
113      * The result is accessed through iterable pages (see {@link Page}) in an interactive way; each time a
114      * result page is retrieved, a query call is made to DynamoDb to get those entries. If no matches are found,
115      * the resulting iterator will contain an empty page. Results are sorted by sort key value in
116      * ascending order.
117      * <p>
118      * This operation calls the low-level DynamoDB API Query operation. Consult the Query documentation for
119      * further details and constraints.
120      * <p>
121      * Example:
122      * <pre>
123      * {@code
124      *
125      * Iterator<Page<MyItem>> results =
126      *     mappedIndex.query(QueryConditional.keyEqualTo(Key.builder().partitionValue("id-value").build()));
127      * }
128      * </pre>
129      *
130      * @param queryConditional A {@link QueryConditional} defining the matching criteria for records to be queried.
131      * @return an iterator of type {@link SdkIterable} with paginated results (see {@link Page}).
132      */
query(QueryConditional queryConditional)133     default SdkIterable<Page<T>> query(QueryConditional queryConditional) {
134         throw new UnsupportedOperationException();
135     }
136 
137     /**
138      * Scans the table against a secondary index and retrieves all items.
139      * <p>
140      * The result is accessed through iterable pages (see {@link Page}) in an interactive way; each time a
141      * result page is retrieved, a scan call is made to DynamoDb to get those entries. If no matches are found,
142      * the resulting iterator will contain an empty page.
143      * <p>
144      * The additional configuration parameters that the enhanced client supports are defined
145      * in the {@link ScanEnhancedRequest}.
146      * <p>
147      * Example:
148      * <pre>
149      * {@code
150      *
151      * Iterator<Page<MyItem>> results = mappedTable.scan(ScanEnhancedRequest.builder().consistentRead(true).build());
152      * }
153      * </pre>
154      *
155      * @param request A {@link ScanEnhancedRequest} defining how to handle the results.
156      * @return an iterator of type {@link SdkIterable} with paginated results (see {@link Page}).
157      */
scan(ScanEnhancedRequest request)158     default SdkIterable<Page<T>> scan(ScanEnhancedRequest request) {
159         throw new UnsupportedOperationException();
160     }
161 
162     /**
163      * Scans the table against a secondary index and retrieves all items.
164      * <p>
165      * The result is accessed through iterable pages (see {@link Page}) in an interactive way; each time a
166      * result page is retrieved, a scan call is made to DynamoDb to get those entries. If no matches are found,
167      * the resulting iterator will contain an empty page.
168      * <p>
169      * The additional configuration parameters that the enhanced client supports are defined
170      * in the {@link ScanEnhancedRequest}.
171      * <p>
172      * <b>Note:</b> This is a convenience method that creates an instance of the request builder avoiding the need to create one
173      * manually via {@link ScanEnhancedRequest#builder()}.
174      * <p>
175      * Example:
176      * <pre>
177      * {@code
178      *
179      * Iterator<Page<MyItem>> results = mappedTable.scan(r -> r.limit(5));
180      * }
181      * </pre>
182      *
183      * @param requestConsumer A {@link Consumer} of {@link ScanEnhancedRequest} defining the query conditions and how to
184      * handle the results.
185      * @return an iterator of type {@link SdkIterable} with paginated results (see {@link Page}).
186      */
scan(Consumer<ScanEnhancedRequest.Builder> requestConsumer)187     default SdkIterable<Page<T>> scan(Consumer<ScanEnhancedRequest.Builder> requestConsumer) {
188         throw new UnsupportedOperationException();
189     }
190 
191     /**
192      * Scans the table against a secondary index and retrieves all items using default settings.
193      * <p>
194      * The result is accessed through iterable pages (see {@link Page}) in an interactive way; each time a
195      * result page is retrieved, a scan call is made to DynamoDb to get those entries. If no matches are found,
196      * the resulting iterator will contain an empty page.
197      * <p>
198      * Example:
199      * <pre>
200      * {@code
201      *
202      * Iterator<Page<MyItem>> results = mappedTable.scan();
203      * }
204      * </pre>
205      *
206      * @return an iterator of type {@link SdkIterable} with paginated results (see {@link Page}).
207      */
scan()208     default SdkIterable<Page<T>> scan() {
209         throw new UnsupportedOperationException();
210     }
211 
212     /**
213      * Gets the {@link DynamoDbEnhancedClientExtension} associated with this mapped resource.
214      * @return The {@link DynamoDbEnhancedClientExtension} associated with this mapped resource.
215      */
mapperExtension()216     DynamoDbEnhancedClientExtension mapperExtension();
217 
218     /**
219      * Gets the {@link TableSchema} object that this mapped table was built with.
220      * @return The {@link TableSchema} object for this mapped table.
221      */
tableSchema()222     TableSchema<T> tableSchema();
223 
224     /**
225      * Gets the physical table name that operations performed by this object will be executed against.
226      * @return The physical table name.
227      */
tableName()228     String tableName();
229 
230     /**
231      * Gets the physical secondary index name that operations performed by this object will be executed against.
232      * @return The physical secondary index name.
233      */
indexName()234     String indexName();
235 
236     /**
237      * Creates a {@link Key} object from a modelled item. This key can be used in query conditionals and get
238      * operations to locate a specific record.
239      * @param item The item to extract the key fields from.
240      * @return A key that has been initialized with the index values extracted from the modelled object.
241      */
keyFrom(T item)242     Key keyFrom(T item);
243 }
244