All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
aerospike_query.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2015 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 /**
20  * @defgroup query_operations Query Operations (3.0 only)
21  * @ingroup client_operations
22  *
23  * The Aerospike Query Operations provide the ability to query data in the
24  * Aerospike database. The queries can only be performed on secondary indexes,
25  * which have been created in the database. To scan all the records in the
26  * database, then you must use the @ref scan_operations.
27  *
28  * ## Usage
29  *
30  * Before you can execute a query, you first need to build a query using
31  * as_query. See as_query for details on building queries.
32  *
33  * Once you have a query defined, then you can execute the query :
34  *
35  * - aerospike_query_foreach() - Executes a query and invokes a callback
36  * function for each result returned.
37  *
38  * When aerospike_query_foreach() is executed, it will process the results
39  * and create records on the stack. Because the records are on the stack,
40  * they will only be available within the context of the callback function.
41  *
42  *
43  * ## Walk-through
44  *
45  * First, we define a query using as_query. The query will be for the "test"
46  * namespace and "demo" set. We will add a where predicate on "bin2", on which
47  * we have already created a secondary index.
48  *
49  * ~~~~~~~~~~{.c}
50  * as_query query;
51  * as_query_init(&query, "test", "demo");
52  *
53  * as_query_where_init(&query, 1);
54  * as_query_where(&query, "bin2", as_integer_equals(100));
55  * ~~~~~~~~~~
56  *
57  * Now that we have a query defined, we want to execute it using
58  * aerospike_query_foreach().
59  *
60  * ~~~~~~~~~~{.c}
61  * if ( aerospike_query_foreach(&as, &err, NULL, &query, callback, NULL) != AEROSPIKE_OK ) {
62  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
63  * }
64  * ~~~~~~~~~~
65  *
66  * The callback provided to the function above is implemented as:
67  *
68  * ~~~~~~~~~~{.c}
69  * bool callback(const as_val * val, void * udata) {
70  * as_record * rec = as_record_fromval(val);
71  * if ( !rec ) return false;
72  * fprintf("record contains %d bins", as_record_numbins(rec));
73  * return true;
74  * }
75  * ~~~~~~~~~~
76  *
77  * An as_query is simply a query definition, so it does not contain any state,
78  * allowing it to be reused for multiple query operations.
79  *
80  * When you are finished with the query, you should destroy the resources
81  * allocated to it:
82  *
83  * ~~~~~~~~~~{.c}
84  * as_query_destroy(&query);
85  * ~~~~~~~~~~
86  *
87  */
88 
89 #include <aerospike/aerospike.h>
90 #include <aerospike/as_error.h>
91 #include <aerospike/as_job.h>
92 #include <aerospike/as_policy.h>
93 #include <aerospike/as_query.h>
94 #include <aerospike/as_status.h>
95 #include <aerospike/as_stream.h>
96 
97 #ifdef __cplusplus
98 extern "C" {
99 #endif
100 
101 /******************************************************************************
102  * TYPES
103  *****************************************************************************/
104 
105 /**
106  * This callback will be called for each value or record returned from a query.
107  * Multiple threads will likely be calling this callback in parallel. Therefore,
108  * your callback implementation should be thread safe.
109  *
110  * The aerospike_query_foreach() function accepts this callback.
111  *
112  * ~~~~~~~~~~{.c}
113  * bool my_callback(as_val * val, void * udata) {
114  * return true;
115  * }
116  * ~~~~~~~~~~
117  *
118  * @param val The value received from the query.
119  * @param udata User-data provided to the calling function.
120  *
121  * @return `true` to continue to the next value. Otherwise, iteration will end.
122  *
123  * @ingroup query_operations
124  */
125 typedef bool (* aerospike_query_foreach_callback)(const as_val * val, void * udata);
126 
127 /******************************************************************************
128  * FUNCTIONS
129  *****************************************************************************/
130 
131 /**
132  * Execute a query and call the callback function for each result item.
133  * Multiple threads will likely be calling the callback in parallel. Therefore,
134  * your callback implementation should be thread safe.
135  *
136  * ~~~~~~~~~~{.c}
137  * as_query query;
138  * as_query_init(&query, "test", "demo");
139  * as_query_select(&query, "bin1");
140  * as_query_where(&query, "bin2", as_integer_equals(100));
141  *
142  * if ( aerospike_query_foreach(&as, &err, NULL, &query, callback, NULL) != AEROSPIKE_OK ) {
143  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
144  * }
145  *
146  * as_query_destroy(&query);
147  * ~~~~~~~~~~
148  *
149  * @param as The aerospike instance to use for this operation.
150  * @param err The as_error to be populated if an error occurs.
151  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
152  * @param query The query to execute against the cluster.
153  * @param callback The callback function to call for each result value.
154  * @param udata User-data to be passed to the callback.
155  *
156  * @return AEROSPIKE_OK on success, otherwise an error.
157  *
158  * @ingroup query_operations
159  */
160 as_status
162  aerospike * as, as_error * err, const as_policy_query * policy,
163  const as_query * query,
164  aerospike_query_foreach_callback callback, void * udata
165  );
166 
167 /**
168  * Apply user defined function on records that match the query filter.
169  * Records are not returned to the client.
170  * This asynchronous server call will return before command is complete.
171  * The user can optionally wait for command completion.
172  *
173  * ~~~~~~~~~~{.c}
174  * as_query query;
175  * as_query_init(&query, "test", "demo");
176  * as_query_select(&query, "bin1");
177  * as_query_where(&query, "bin2", as_integer_equals(100));
178  * as_query_apply(&query, "my_lua.lua", "my_lua_function", NULL);
179  * uint64_t query_id = 0;
180  *
181  * if (aerospike_query_background(&as, &err, NULL, &query, &query_id) == AEROSPIKE_OK) {
182  * aerospike_query_wait(as, &err, NULL, &query, query_id, 0);
183  * }
184  * else {
185  * fprintf(stderr, "error(%d) %s at [%s:%d]", err.code, err.message, err.file, err.line);
186  * }
187  *
188  * as_query_destroy(&query);
189  * ~~~~~~~~~~
190  *
191  * @param as The aerospike instance to use for this operation.
192  * @param err The as_error to be populated if an error occurs.
193  * @param policy The policy to use for this operation. If NULL, then the default policy will be used.
194  * @param query The query to execute against the cluster.
195  * @param query_id The id for the query job, which can be used for querying the status of the query.
196  *
197  * @return AEROSPIKE_OK on success, otherwise an error.
198  *
199  * @ingroup query_operations
200  */
201 as_status
203  aerospike* as, as_error* err, const as_policy_write* policy,
204  const as_query* query, uint64_t* query_id
205  );
206 
207 /**
208  * Wait for a background query to be completed by servers.
209  *
210  * @param as The aerospike instance to use for this operation.
211  * @param err The as_error to be populated if an error occurs.
212  * @param policy The info policy to use for this operation. If NULL, then the default policy will be used.
213  * @param query The query that was executed against the cluster.
214  * @param query_id The id for the query job, which can be used for querying the status of the query.
215  * @param interval_ms Polling interval in milliseconds. If zero, 1000 ms is used.
216  *
217  * @return AEROSPIKE_OK on success, otherwise an error.
218  *
219  * @ingroup query_operations
220  */
221 static inline as_status
223  aerospike* as, as_error* err, const as_policy_info* policy,
224  const as_query* query, uint64_t query_id, uint32_t interval_ms
225  )
226 {
227  const char* module = (query->where.size > 0)? "query" : "scan";
228  return aerospike_job_wait(as, err, policy, module, query_id, interval_ms);
229 }
230 
231 /**
232  * Check the progress of a background query running on the database.
233  *
234  * @param as The aerospike instance to use for this operation.
235  * @param err The as_error to be populated if an error occurs.
236  * @param policy The info policy to use for this operation. If NULL, then the default policy will be used.
237  * @param query The query that was executed against the cluster.
238  * @param query_id The id for the query job, which can be used for querying the status of the query.
239  * @param info Information about this background query, to be populated by this operation.
240  *
241  * @return AEROSPIKE_OK on success, otherwise an error.
242  *
243  * @ingroup query_operations
244  */
245 static inline as_status
247  aerospike* as, as_error* err, const as_policy_info* policy,
248  const as_query* query, uint64_t query_id, as_job_info* info
249  )
250 {
251  const char* module = (query->where.size > 0)? "query" : "scan";
252  return aerospike_job_info(as, err, policy, module, query_id, false, info);
253 }
254 
255 #ifdef __cplusplus
256 } // end extern "C"
257 #endif