parser: ComputeProdLocationVisitor also compute *_looses tokens
[nit.git] / lib / mongodb / native_mongodb.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2015 Alexandre Terrasa <alexandre@moz-code.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # 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,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Native wrapper for the MongoDB C Driver
18 #
19 # See [mongoc](http://api.mongodb.org/c/1.1.4/index.html).
20 module native_mongodb is pkgconfig "libmongoc-1.0"
21
22 import c
23
24 in "C header" `{
25 #include <mongoc.h>
26 `}
27
28 # Wrapper for `bson_t`.
29 #
30 # All data manipulated by `mongoc` are BSON formated.
31 #
32 # The `bson_t` structure represents a BSON document.
33 # This structure manages the underlying BSON encoded buffer.
34 # For mutable documents, it can append new data to the document.
35 #
36 # See [`bson_t`](http://api.mongodb.org/libbson/current/bson_t.html).
37 extern class NativeBSON `{ bson_t * `}
38
39 # Wrapper for `bson_new()`.
40 #
41 # The `bson_new()` function shall create a new `bson_t` structure on the heap.
42 # It should be freed with `bson_destroy()` when it is no longer in use.
43 new `{ return bson_new(); `}
44
45 # Wrapper for `bson_new_from_json()`.
46 #
47 # The `bson_new_from_json()` function allocates and initialize a new `bson_t`
48 # by parsing the JSON found in `data`.
49 # Only a single JSON object may exist in data or an error will be set and
50 # `NULL` returned.
51 new from_json_string(data: NativeString) import set_mongoc_error `{
52 bson_error_t error;
53 bson_t *bson;
54 bson = bson_new_from_json(data, -1, &error);
55 if(!bson) {
56 NativeBSON_set_mongoc_error(recv, &error);
57 return NULL;
58 }
59 return bson;
60 `}
61
62 # Wrapper for `bson_as_json()`.
63 #
64 # The `bson_as_json()` function shall encode bson as a JSON encoded UTF-8 string.
65 # The caller is responsible for freeing the resulting UTF-8 encoded string
66 # by calling `bson_free()` with the result.
67 fun to_native_string: NativeString `{ return bson_as_json(recv, NULL); `}
68
69 # Wrapper for `bson_destroy()`.
70 #
71 # The `bson_destroy()` function shall free an allocated `bson_t` structure.
72 # This function should always be called when you are done with a `bson_t`
73 # unless otherwise specified.
74 #
75 # This instance should not be used beyond this point!
76 fun destroy `{ bson_destroy(recv); `}
77
78 # Utility method to set `Sys.last_mongoc_error`.
79 fun set_mongoc_error(err: BSONError) do sys.last_mongoc_error = err
80 end
81
82 # Wrapper for `bson_error_t`.
83 #
84 # The `bson_error_t` structure is used to encapsulate information about an error.
85 #
86 # See [`bson_error_t`](http://api.mongodb.org/libbson/current/bson_error_t.html).
87 extern class BSONError `{ bson_error_t * `}
88
89 # Wrapper for `error.domain`.
90 #
91 # The `error.domain` field contains the logical domain within a library that
92 # created the error.
93 fun domain: Int `{ return recv->domain; `}
94
95 # Wrapper for `error.code`.
96 #
97 # The `error.code` field contains the domain specific error code.
98 fun code: Int `{ return recv->code; `}
99
100 # Wrapper for `error.message`.
101 #
102 # The `error.message` field contains a human printable error message.
103 fun message: NativeString `{ return recv->message; `}
104 end
105
106 redef class Sys
107 # Last error raised by `monogdb::MongoClient`.
108 #
109 # See `MongoClient::last_error`.
110 var last_mongoc_error: nullable BSONError = null
111 end
112
113 # Wrapper for `char**`.
114 #
115 # Used to handle array of NativeString returned by MongoDB.
116 redef class NativeCStringArray
117 # Frees `self`.
118 #
119 # This instance should not be used beyond this point!
120 fun destroy `{ free(recv); `}
121 end
122
123 # Wrapper for `mongoc_client_t`.
124 #
125 # `mongoc_client_t` is an opaque type that provides access to a MongoDB node,
126 # replica-set, or sharded-cluster.
127 # It maintains management of underlying sockets and routing to individual nodes.
128 #
129 # See [`mongoc_client_t`](http://api.mongodb.org/c/current/mongoc_client_t.html).
130 extern class NativeMongoClient `{ mongoc_client_t * `}
131
132 # Wrapper for `mongoc_client_new()`.
133 #
134 # Creates a new `mongoc_client_t` using the `uri` string provided.
135 new(uri: NativeString) `{
136 mongoc_init();
137 return mongoc_client_new(uri);
138 `}
139
140 # Wrapper for `mongoc_client_get_server_status()`.
141 #
142 # Queries the server for the current server status.
143 # Returns `null` if an error occured.
144 fun server_status: nullable NativeBSON import set_mongoc_error, NativeBSON.as nullable `{
145 bson_error_t error;
146 bson_t *reply = bson_new();
147 if(!mongoc_client_get_server_status(recv, NULL, reply, &error)){
148 NativeMongoClient_set_mongoc_error(recv, &error);
149 return null_NativeBSON();
150 }
151 return NativeBSON_as_nullable(reply);
152 `}
153
154 # Wrapper for `mongoc_client_get_database_names()`.
155 #
156 # This function queries the MongoDB server for a list of known databases.
157 # Returns `null` if an error occured.
158 fun database_names: nullable NativeCStringArray
159 import set_mongoc_error, NativeCStringArray, NativeCStringArray.as nullable `{
160 bson_error_t error;
161 char **strv;
162 if(strv = mongoc_client_get_database_names(recv, &error)) {
163 return NativeCStringArray_as_nullable(strv);
164 }
165 NativeMongoClient_set_mongoc_error(recv, &error);
166 return null_NativeCStringArray();
167 `}
168
169 # Wrapper for `mongoc_client_destroy()`.
170 #
171 # This instance should not be used beyond this point!
172 fun destroy `{
173 mongoc_client_destroy(recv);
174 mongoc_cleanup();
175 `}
176
177 # Utility method to set `Sys.last_mongoc_error`.
178 fun set_mongoc_error(err: BSONError) do sys.last_mongoc_error = err
179 end
180
181 # Wrapper for `mongoc_database_t`.
182 #
183 # `mongoc_database_t` provides access to a MongoDB database.
184 # This handle is useful for actions a particular database object.
185 # It is not a container for `mongoc_collection_t` structures.
186 #
187 # See [`mongoc_database_t`](http://api.mongodb.org/c/current/mongoc_database_t.html).
188 extern class NativeMongoDb `{ mongoc_database_t * `}
189
190 # Wrapper for `mongoc_client_get_database()`.
191 #
192 # Get a newly allocated `mongoc_database_t` for the database named name.
193 #
194 # Database are automatically created on the MongoDB server upon insertion of
195 # the first document into a collection.
196 # There is no need to create a database manually.
197 new(client: NativeMongoClient, db_name: NativeString) `{
198 return mongoc_client_get_database(client, db_name);
199 `}
200
201 # Wrapper for `mongoc_database_get_collection_names()`.
202 #
203 # Fetches a `NULL` terminated array of `NULL-byte` terminated `char*` strings
204 # containing the names of all of the collections in database.
205 fun collection_names: nullable NativeCStringArray
206 import set_mongoc_error, NativeCStringArray, NativeCStringArray.as nullable `{
207 bson_error_t error;
208 char **strv;
209 if(strv = mongoc_database_get_collection_names(recv, &error)) {
210 return NativeCStringArray_as_nullable(strv);
211 }
212 NativeMongoDb_set_mongoc_error(recv, &error);
213 return null_NativeCStringArray();
214 `}
215
216 # Wrapper for `mongoc_database_get_collection()`.
217 #
218 # Allocates a new `mongoc_collection_t` structure for the collection named
219 # `name` in database.
220 fun collection(name: NativeString): NativeMongoCollection `{
221 return mongoc_database_get_collection(recv, name);
222 `}
223
224 # Wrapper for `mongoc_database_has_collection()`.
225 #
226 # This function checks to see if a collection exists on the MongoDB server
227 # within database.
228 fun has_collection(name: NativeString): Bool import set_mongoc_error `{
229 bson_error_t error;
230 if(!mongoc_database_has_collection(recv, name, &error)) {
231 NativeMongoDb_set_mongoc_error(recv, &error);
232 return false;
233 }
234 return true;
235 `}
236
237 # Wrapper for `mongoc_database_drop()`.
238 #
239 # This function attempts to drop a database on the MongoDB server.
240 fun drop: Bool import set_mongoc_error `{
241 bson_error_t error;
242 if(!mongoc_database_drop(recv, &error)) {
243 NativeMongoDb_set_mongoc_error(recv, &error);
244 return false;
245 }
246 return true;
247 `}
248
249 # Wrapper for `mongoc_database_destroy()`.
250 #
251 # This instance should not be used beyond this point!
252 fun destroy `{ mongoc_database_destroy(recv); `}
253
254 # Utility method to set `Sys.last_mongoc_error`.
255 fun set_mongoc_error(err: BSONError) do sys.last_mongoc_error = err
256 end
257
258 # Wrapper for `mongoc_collection_t`.
259 #
260 # `mongoc_collection_t` provides access to a MongoDB collection.
261 # This handle is useful for actions for most CRUD operations,
262 # I.e. insert, update, delete, find, etc.
263 #
264 # It is an error to call `mongoc_collection_destroy()` on a collection that has
265 # operations pending.
266 # It is required that you release `mongoc_cursor_t` structures before calling
267 # `mongoc_collection_destroy()`.
268 #
269 # See [`mongoc_collection_t`](http://api.mongodb.org/c/current/mongoc_collection_t.html).
270 extern class NativeMongoCollection `{ mongoc_collection_t * `}
271
272 # Wrapper for `mongoc_client_get_collection()`.
273 #
274 # Get a newly allocated `mongoc_collection_t` for the collection named
275 # `collection` in the database named `db`.
276 #
277 # Collections are automatically created on the MongoDB server upon insertion
278 # of the first document.
279 # There is no need to create a collection manually.
280 new(client: NativeMongoClient, db, collection: NativeString) `{
281 return mongoc_client_get_collection(client, db, collection);
282 `}
283
284 # Wrapper for `mongoc_collection_insert()`.
285 #
286 # This function shall insert `document` into the collection.
287 # If no `_id` element is found in document, then a `bson_oid_t` will be
288 # generated locally and added to the document.
289 #
290 # You can retrieve a generated `_id` from `mongoc_collection_get_last_error()`.
291 fun insert(doc: NativeBSON): Bool import set_mongoc_error `{
292 bson_error_t error;
293 if(!mongoc_collection_insert(recv, MONGOC_INSERT_NONE, doc, NULL, &error)) {
294 NativeMongoCollection_set_mongoc_error(recv, &error);
295 return false;
296 }
297 return true;
298 `}
299
300 # Wrapper for `mongoc_collection_save()`.
301 #
302 # This function shall save a document into the collection.
303 # If the document has an `_id` field it will be updated.
304 # Otherwise it will be inserted.
305 fun save(document: NativeBSON): Bool import set_mongoc_error `{
306 bson_error_t error;
307 if(!mongoc_collection_save(recv, document, NULL, &error)) {
308 NativeMongoCollection_set_mongoc_error(recv, &error);
309 return false;
310 }
311 return true;
312 `}
313
314 # Wrapper for `mongoc_collection_remove(MONGOC_REMOVE_SINGLE_REMOVE)`.
315 #
316 # This function shall remove the first document in the collection that matches
317 # `selector`.
318 # The bson selector is not validated, simply passed along as appropriate to the server.
319 fun remove(selector: NativeBSON): Bool import set_mongoc_error `{
320 bson_error_t error;
321 if(!mongoc_collection_remove(recv, MONGOC_REMOVE_SINGLE_REMOVE, selector, NULL, &error)) {
322 NativeMongoCollection_set_mongoc_error(recv, &error);
323 return false;
324 }
325 return true;
326 `}
327
328 # Wrapper for `mongoc_collection_remove(MONGOC_REMOVE_NONE)`.
329 #
330 # This function shall remove documents in the collection that match `selector`.
331 fun remove_all(selector: NativeBSON): Bool import set_mongoc_error `{
332 bson_error_t error;
333 if(!mongoc_collection_remove(recv, MONGOC_REMOVE_NONE, selector, NULL, &error)) {
334 NativeMongoCollection_set_mongoc_error(recv, &error);
335 return false;
336 }
337 return true;
338 `}
339
340 # Wrapper for `mongoc_collection_update(MONGOC_UPDATE_NONE)`.
341 #
342 # This function shall update the first document in the collection that
343 # matches `selector`.
344 fun update(selector, update: NativeBSON): Bool import set_mongoc_error `{
345 bson_error_t error;
346 if(!mongoc_collection_update(recv, MONGOC_UPDATE_NONE, selector, update, NULL, &error)) {
347 NativeMongoCollection_set_mongoc_error(recv, &error);
348 return false;
349 }
350 return true;
351 `}
352
353 # Wrapper for `mongoc_collection_update(MONGOC_UPDATE_MULTI_UPDATE)`.
354 #
355 # This function shall update documents in the collection that match `selector`.
356 fun update_all(selector, update: NativeBSON): Bool import set_mongoc_error `{
357 bson_error_t error;
358 if(!mongoc_collection_update(recv, MONGOC_UPDATE_MULTI_UPDATE, selector, update, NULL, &error)) {
359 NativeMongoCollection_set_mongoc_error(recv, &error);
360 return false;
361 }
362 return true;
363 `}
364
365 # Wrapper for `mongoc_collection_count()`.
366 #
367 # This function shall execute a count `query` on the underlying collection.
368 fun count(query: NativeBSON): Int import set_mongoc_error `{
369 bson_error_t error;
370 int64_t count = mongoc_collection_count(recv, MONGOC_QUERY_NONE, query, 0, 0, NULL, &error);
371 if(count < 0) {
372 NativeMongoCollection_set_mongoc_error(recv, &error);
373 return -1;
374 }
375 return count;
376 `}
377
378 # Wrapper for `mongoc_collection_find()`.
379 #
380 # This function shall execute a `query` on the underlying collection.
381 #
382 # If no options are necessary, `query` can simply contain a query such as `{a:1}`.
383 #
384 # If you would like to specify options such as a sort order,
385 # the query must be placed inside of `{"$query": {}}`.
386 fun find(query: NativeBSON): nullable NativeMongoCursor import
387 NativeMongoCursor.as nullable, set_mongoc_error `{
388 bson_error_t error;
389 mongoc_cursor_t *cursor;
390 cursor = mongoc_collection_find(recv, MONGOC_QUERY_NONE, 0, 0, 0, query, NULL, NULL);
391
392 if (mongoc_cursor_error(cursor, &error)) {
393 NativeMongoCollection_set_mongoc_error(recv, &error);
394 return null_NativeMongoCursor();
395 }
396
397 return NativeMongoCursor_as_nullable(cursor);
398 `}
399
400 # Wrapper for `mongoc_collection_stats()`.
401 #
402 # This function is a helper to retrieve statistics about the collection.
403 fun stats: nullable NativeBSON import set_mongoc_error, NativeBSON.as nullable `{
404 bson_error_t error;
405 bson_t *reply = bson_new();
406 if(!mongoc_collection_stats(recv, NULL, reply, &error)){
407 NativeMongoCollection_set_mongoc_error(recv, &error);
408 return null_NativeBSON();
409 }
410 return NativeBSON_as_nullable(reply);
411 `}
412
413 # Wrapper for `mongoc_collection_drop()`.
414 #
415 # This function requests that the `collection` be dropped,
416 # including all indexes associated with the collection.
417 fun drop: Bool import set_mongoc_error `{
418 bson_error_t error;
419 if(!mongoc_collection_drop(recv, &error)) {
420 NativeMongoCollection_set_mongoc_error(recv, &error);
421 return false;
422 }
423 return true;
424 `}
425
426 # Wrapper for `mongoc_collection_rename()`.
427 #
428 # This function is a helper to rename an existing collection on a MongoDB server.
429 # The name of the collection will also be updated internally so it is safe
430 # to continue using this collection after the rename.
431 # Additional operations will occur on renamed collection.
432 fun rename(new_database, new_name: NativeString): Bool `{
433 bson_error_t error;
434 if(!mongoc_collection_rename(recv, new_database, new_name, false, &error)){
435 NativeMongoCollection_set_mongoc_error(recv, &error);
436 return false;
437 }
438 return true;
439 `}
440
441 # Wrapper for `mongoc_collection_destroy()`.
442 #
443 # This instance should not be used beyond this point!
444 fun destroy `{ mongoc_collection_destroy(recv); `}
445
446 # Utility method to set `Sys.last_mongoc_error`.
447 fun set_mongoc_error(err: BSONError) do sys.last_mongoc_error = err
448 end
449
450 # Wrapper for `mongoc_cursor_t`.
451 #
452 # `mongoc_cursor_t` provides access to a MongoDB query cursor.
453 # It wraps up the wire protocol negotation required to initiate a query and
454 # retreive an unknown number of documents.
455 #
456 # Cursors are lazy, meaning that no network traffic occurs until the first call
457 # to mongoc_cursor_next().
458 #
459 # At that point we can:
460 # * Retreive more records with repeated calls to `mongoc_cursor_next()`.
461 # * Test for more records with `mongoc_cursor_more()`.
462 # * Retrieve the document under the cursor with `mongoc_cursor_current()`.
463 #
464 # See [`mongoc_cursor_t`](http://api.mongodb.org/c/current/mongoc_cursor_t.html).
465 extern class NativeMongoCursor `{ mongoc_cursor_t* `}
466
467 # Wrapper for `mongoc_cursor_current()`.
468 #
469 # Fetches the cursors current document or NULL if there has been an error.
470 fun current: NativeBSON `{ return (bson_t*) mongoc_cursor_current(recv); `}
471
472 # Wrapper for `mongoc_cursor_next()`.
473 #
474 # This function shall iterate the underlying cursor, setting `current` to the next
475 # document.
476 #
477 # This function is a blocking function.
478 fun next: Bool `{
479 const bson_t *doc;
480 return mongoc_cursor_next(recv, &doc);
481 `}
482
483 # Wrapper for `mongoc_cursor_more()`.
484 #
485 # This function shall indicate if there is more data to be read from the cursor.
486 fun more: Bool `{ return mongoc_cursor_more(recv); `}
487
488 # Wrapper for `mongoc_cursor_destroy()`.
489 #
490 # This instance should not be used beyond this point!
491 fun destroy `{ mongoc_cursor_destroy(recv); `}
492 end