Skip to content
Newer
Older
100644 884 lines (750 sloc) 24.3 KB
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
1 #include <client/dbclient.h>
2
3 extern "C" {
4 #include <lua.h>
5 #include <lauxlib.h>
6
7 #if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
8 #include <compat-5.1.h>
9 #endif
10 };
11
12 #include "utils.h"
13 #include "common.h"
14
15 using namespace mongo;
16
17 extern int cursor_create(lua_State *L, DBClientBase *connection, const char *ns,
18 const Query &query, int nToReturn, int nToSkip,
19 const BSONObj *fieldsToReturn, int queryOptions, int batchSize);
20
21 extern void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj);
22 extern void bson_to_lua(lua_State *L, const BSONObj &obj);
23 extern void lua_push_value(lua_State *L, const BSONElement &elem);
24
25
26 DBClientBase* userdata_to_dbclient(lua_State *L, int stackpos)
27 {
28 // adapted from http://www.lua.org/source/5.1/lauxlib.c.html#luaL_checkudata
29 void *ud = lua_touserdata(L, stackpos);
30 if (ud == NULL)
31 luaL_typerror(L, stackpos, "userdata");
32
33 // try Connection
34 lua_getfield(L, LUA_REGISTRYINDEX, LUAMONGO_CONNECTION);
35 if (lua_getmetatable(L, stackpos))
36 {
37 if (lua_rawequal(L, -1, -2))
38 {
39 DBClientConnection *connection = *((DBClientConnection **)ud);
40 lua_pop(L, 2);
41 return connection;
42 }
1d1cfe2 @neoxic + Fix segfault on MongoDB restart (add check for lost connection)
neoxic authored Jan 31, 2012
43 lua_pop(L, 2);
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
44 }
45 else
46 lua_pop(L, 1);
47
48 // try ReplicaSet
49 lua_getfield(L, LUA_REGISTRYINDEX, LUAMONGO_REPLICASET); // get correct metatable
50 if (lua_getmetatable(L, stackpos))
51 {
52 if (lua_rawequal(L, -1, -2))
53 {
54 DBClientReplicaSet *replicaset = *((DBClientReplicaSet **)ud);
55 lua_pop(L, 2); // remove both metatables
56 return replicaset;
57 }
1d1cfe2 @neoxic + Fix segfault on MongoDB restart (add check for lost connection)
neoxic authored Jan 31, 2012
58 lua_pop(L, 2);
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
59 }
60 else
61 lua_pop(L, 1);
62
63 luaL_typerror(L, stackpos, LUAMONGO_DBCLIENT);
64 return NULL; // should never get here
65 }
66
67
68 /***********************************************************************/
69 // The following methods are common to all DBClients
70 // (DBClientConnection and DBClientReplicaSet)
71 /***********************************************************************/
72
73
74 /*
75 * created = db:ensure_index(ns, json_str or lua_table[, unique[, name]])
76 */
77 static int dbclient_ensure_index(lua_State *L) {
78 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
79 const char *ns = luaL_checkstring(L, 2);
80 BSONObj fields;
81
82 try {
83 int type = lua_type(L, 3);
84 if (type == LUA_TSTRING) {
85 const char *jsonstr = luaL_checkstring(L, 3);
86 fields = fromjson(jsonstr);
87 } else if (type == LUA_TTABLE) {
88 lua_to_bson(L, 3, fields);
89 } else {
90 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
91 }
92 } catch (std::exception &e) {
93 lua_pushboolean(L, 0);
94 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "ensure_index", e.what());
95 return 2;
96 } catch (const char *err) {
97 lua_pushboolean(L, 0);
98 lua_pushstring(L, err);
99 return 2;
100 }
101
102 bool unique = lua_toboolean(L, 4);
103 const char *name = luaL_optstring(L, 5, "");
104
105 bool res = dbclient->ensureIndex(ns, fields, unique, name);
106
107 lua_pushboolean(L, res);
108 return 1;
109 }
110
111 /*
112 * ok,err = db:auth({})
113 * accepts a table of parameters:
114 * dbname database to authenticate (required)
115 * username username to authenticate against (required)
116 * password password to authenticate against (required)
117 * digestPassword set to true if password is pre-digested (default = true)
118 *
119 */
120 static int dbclient_auth(lua_State *L) {
121 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
122
123 luaL_checktype(L, 2, LUA_TTABLE);
124 lua_getfield(L, 2, "dbname");
125 const char *dbname = luaL_checkstring(L, -1);
126 lua_getfield(L, 2, "username");
127 const char *username = luaL_checkstring(L, -1);
128 lua_getfield(L, 2, "password");
129 const char *password = luaL_checkstring(L, -1);
130 lua_getfield(L, 2, "digestPassword");
131 bool digestPassword = lua_isnil(L, -1) ? true : lua_toboolean(L, -1);
132 lua_pop(L, 4);
133
134 std::string errmsg;
135 bool success = dbclient->auth(dbname, username, password, errmsg, digestPassword);
136 if (!success) {
137 lua_pushnil(L);
138 lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, errmsg.c_str());
139 return 2;
140 }
141 lua_pushboolean(L, 1);
142 return 1;
143 }
144
145 /*
146 * is_failed = db:is_failed()
147 */
148 static int dbclient_is_failed(lua_State *L) {
149 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
150
151 bool is_failed = dbclient->isFailed();
152 lua_pushboolean(L, is_failed);
153 return 1;
154 }
155
156 /*
157 * addr = db:get_server_address()
158 */
159 static int dbclient_get_server_address(lua_State *L) {
160 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
161
162 std::string address = dbclient->getServerAddress();
163 lua_pushstring(L, address.c_str());
164 return 1;
165 }
166
167 /*
73200f3 @neoxic + Add 'query' to db:count()
neoxic authored Feb 2, 2012
168 * count,err = db:count(ns, lua_table or json_str)
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
169 */
170 static int dbclient_count(lua_State *L) {
171 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
172 const char *ns = luaL_checkstring(L, 2);
173
174 int count = 0;
175 try {
73200f3 @neoxic + Add 'query' to db:count()
neoxic authored Feb 2, 2012
176 BSONObj query;
177 int type = lua_type(L, 3);
178 if (type == LUA_TSTRING) {
179 const char *jsonstr = luaL_checkstring(L, 3);
180 query = fromjson(jsonstr);
181 } else if (type == LUA_TTABLE) {
182 lua_to_bson(L, 3, query);
183 }
184 count = dbclient->count(ns, query);
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
185 } catch (std::exception &e) {
186 lua_pushnil(L);
187 lua_pushfstring(L, LUAMONGO_ERR_COUNT_FAILED, e.what());
188 return 2;
189 }
190
191 lua_pushinteger(L, count);
192 return 1;
193 }
194
195 /*
196 * ok,err = db:insert(ns, lua_table or json_str)
197 */
198 static int dbclient_insert(lua_State *L) {
199 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
200 const char *ns = luaL_checkstring(L, 2);
201
202 try {
203 int type = lua_type(L, 3);
204 if (type == LUA_TSTRING) {
205 const char *jsonstr = luaL_checkstring(L, 3);
206 dbclient->insert(ns, fromjson(jsonstr));
207 } else if (type == LUA_TTABLE) {
208 BSONObj data;
209 lua_to_bson(L, 3, data);
210
211 dbclient->insert(ns, data);
212 } else {
213 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
214 }
215 } catch (std::exception &e) {
216 lua_pushboolean(L, 0);
217 lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
218 return 2;
219 } catch (const char *err) {
220 lua_pushboolean(L, 0);
221 lua_pushstring(L, err);
222 return 2;
223 }
224
225 lua_pushboolean(L, 1);
226 return 1;
227 }
228
229 /*
230 * ok,err = db:insert_batch(ns, lua_array_of_tables)
231 */
232 static int dbclient_insert_batch(lua_State *L) {
233 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
234 const char *ns = luaL_checkstring(L, 2);
235 luaL_checktype(L, 3, LUA_TTABLE);
236
237 try {
238 std::vector<BSONObj> vdata;
239 size_t tlen = lua_objlen(L, 3) + 1;
240 for (size_t i = 1; i < tlen; ++i) {
241 vdata.push_back(BSONObj());
242 lua_rawgeti(L, 3, i);
243 lua_to_bson(L, 4, vdata.back());
244 lua_pop(L, 1);
245 }
246 dbclient->insert(ns, vdata);
247 } catch (std::exception &e) {
248 lua_pushboolean(L, 0);
249 lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
250 return 2;
251 } catch (const char *err) {
252 lua_pushboolean(L, 0);
253 lua_pushstring(L, err);
254 return 2;
255 }
256
257 lua_pushboolean(L, 1);
258 return 1;
259 }
260
261 /*
262 * cursor,err = db:query(ns, lua_table or json_str or query_obj, limit, skip, lua_table or json_str, options, batchsize)
263 */
264 static int dbclient_query(lua_State *L) {
265 int n = lua_gettop(L);
266 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
267 const char *ns = luaL_checkstring(L, 2);
268
269 Query query;
270 if (!lua_isnoneornil(L, 3)) {
271 try {
272 int type = lua_type(L, 3);
273 if (type == LUA_TSTRING) {
274 query = fromjson(luaL_checkstring(L, 3));
275 } else if (type == LUA_TTABLE) {
276 BSONObj obj;
277 lua_to_bson(L, 3, obj);
278 query = obj;
279 } else if (type == LUA_TUSERDATA) {
280 void *uq = 0;
281
282 uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
283 query = *(*((Query **)uq));
284 } else {
285 throw(LUAMONGO_REQUIRES_QUERY);
286 }
287 } catch (std::exception &e) {
288 lua_pushnil(L);
289 lua_pushfstring(L, LUAMONGO_ERR_QUERY_FAILED, e.what());
290 return 2;
291 } catch (const char *err) {
292 lua_pushnil(L);
293 lua_pushstring(L, err);
294 return 2;
295 }
296 }
297
298 int nToReturn = luaL_optint(L, 4, 0);
299 int nToSkip = luaL_optint(L, 5, 0);
300
301 const BSONObj *fieldsToReturn = NULL;
302 if (!lua_isnoneornil(L, 6)) {
303 int type = lua_type(L, 6);
304
305 if (type == LUA_TSTRING) {
306 fieldsToReturn = new BSONObj(luaL_checkstring(L, 6));
307 } else if (type == LUA_TTABLE) {
308 BSONObj obj;
309 lua_to_bson(L, 6, obj);
310 fieldsToReturn = new BSONObj(obj);
311 } else {
312 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
313 }
314 }
315
316 int queryOptions = luaL_optint(L, 7, 0);
317 int batchSize = luaL_optint(L, 8, 0);
318
319 int res = cursor_create(L, dbclient, ns, query, nToReturn, nToSkip,
320 fieldsToReturn, queryOptions, batchSize);
321
322 if (fieldsToReturn) {
323 delete fieldsToReturn;
324 }
325
326 return res;
327 }
328
9025545 @mabako Added db:find_one
mabako authored Feb 5, 2012
329 /**
330 * lua_table,err = db:find_one(ns, lua_table or json_str or query_obj, lua_table or json_str, options)
331 */
332 static int dbclient_find_one(lua_State *L) {
333 int n = lua_gettop(L);
334 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
335 const char *ns = luaL_checkstring(L, 2);
336
337 Query query;
338 if (!lua_isnoneornil(L, 3)) {
339 try {
340 int type = lua_type(L, 3);
341 if(type == LUA_TSTRING) {
342 query = fromjson(luaL_checkstring(L, 3));
343 } else if (type == LUA_TTABLE) {
344 BSONObj obj;
345 lua_to_bson(L, 3, obj);
346 query = obj;
347 } else if (type == LUA_TUSERDATA) {
348 void *uq = 0;
349
350 uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
351 query = *(*((Query **)uq));
352 } else {
353 throw(LUAMONGO_REQUIRES_QUERY);
354 }
355 } catch(std::exception &e) {
356 lua_pushnil(L);
bf36d85 @mabako Stopped a db:find_one assertion from being propagated, instead handle…
mabako authored Feb 5, 2012
357 lua_pushfstring(L, LUAMONGO_ERR_FIND_ONE_FAILED, e.what());
9025545 @mabako Added db:find_one
mabako authored Feb 5, 2012
358 return 2;
359 } catch (const char *err) {
360 lua_pushnil(L);
361 lua_pushstring(L, err);
362 return 2;
363 }
364 }
365
366 const BSONObj *fieldsToReturn = NULL;
367 if (!lua_isnoneornil(L, 4)) {
368 int type = lua_type(L, 4);
369
370 if (type == LUA_TSTRING) {
371 fieldsToReturn = new BSONObj(luaL_checkstring(L, 4));
372 } else if (type == LUA_TTABLE) {
373 BSONObj obj;
374 lua_to_bson(L, 4, obj);
375 fieldsToReturn = new BSONObj(obj);
376 } else {
377 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
378 }
379 }
380
381 int queryOptions = luaL_optint(L, 5, 0);
382
bf36d85 @mabako Stopped a db:find_one assertion from being propagated, instead handle…
mabako authored Feb 5, 2012
383 int retval = 1;
384 try {
385 BSONObj ret = dbclient->findOne(ns, query, fieldsToReturn, queryOptions);
386 bson_to_lua(L, ret);
387 } catch (AssertionException &e) {
388 lua_pushnil(L);
389 lua_pushfstring(L, LUAMONGO_ERR_FIND_ONE_FAILED, e.what());
390 retval = 2;
391 }
9025545 @mabako Added db:find_one
mabako authored Feb 5, 2012
392
393 if (fieldsToReturn) {
394 delete fieldsToReturn;
395 }
bf36d85 @mabako Stopped a db:find_one assertion from being propagated, instead handle…
mabako authored Feb 5, 2012
396 return retval;
9025545 @mabako Added db:find_one
mabako authored Feb 5, 2012
397 }
398
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
399 /*
400 * ok,err = db:remove(ns, lua_table or json_str or query_obj)
401 */
402 static int dbclient_remove(lua_State *L) {
403 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
404 const char *ns = luaL_checkstring(L, 2);
405
406 try {
407 int type = lua_type(L, 3);
408 bool justOne = lua_toboolean(L, 4);
409
410 if (type == LUA_TSTRING) {
411 const char *jsonstr = luaL_checkstring(L, 3);
412 dbclient->remove(ns, fromjson(jsonstr), justOne);
413 } else if (type == LUA_TTABLE) {
414 BSONObj data;
415 lua_to_bson(L, 3, data);
416
417 dbclient->remove(ns, data, justOne);
418 } else if (type == LUA_TUSERDATA) {
419 Query query;
420 void *uq = 0;
421
422 uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
423 query = *(*((Query **)uq));
424
425 dbclient->remove(ns, query, justOne);
426 } else {
427 throw(LUAMONGO_REQUIRES_QUERY);
428 }
429 } catch (std::exception &e) {
430 lua_pushboolean(L, 0);
431 lua_pushfstring(L, LUAMONGO_ERR_REMOVE_FAILED, e.what());
432 return 2;
433 } catch (const char *err) {
434 lua_pushboolean(L, 0);
435 lua_pushstring(L, err);
436 return 2;
437 }
438
439 lua_pushboolean(L, 1);
440 return 1;
441 }
442
443 /*
444 * ok,err = db:update(ns, lua_table or json_str or query_obj, lua_table or json_str, upsert, multi)
445 */
446 static int dbclient_update(lua_State *L) {
447 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
448 const char *ns = luaL_checkstring(L, 2);
449
450 try {
451 int type_query = lua_type(L, 3);
452 int type_obj = lua_type(L, 4);
453
454 bool upsert = lua_toboolean(L, 5);
455 bool multi = lua_toboolean(L, 6);
456
457 Query query;
458 BSONObj obj;
459
460 if (type_query == LUA_TSTRING) {
461 const char *jsonstr = luaL_checkstring(L, 3);
462 query = fromjson(jsonstr);
463 } else if (type_query == LUA_TTABLE) {
464 BSONObj q;
465
466 lua_to_bson(L, 3, q);
467 query = q;
468 } else if (type_query == LUA_TUSERDATA) {
469 void *uq = 0;
470
471 uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
472 query = *(*((Query **)uq));
473 } else {
474 throw(LUAMONGO_REQUIRES_QUERY);
475 }
476
477 if (type_obj == LUA_TSTRING) {
478 const char *jsonstr = luaL_checkstring(L, 4);
479 obj = fromjson(jsonstr);
480 } else if (type_obj == LUA_TTABLE) {
481 lua_to_bson(L, 4, obj);
482 } else {
483 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
484 }
485
486 dbclient->update(ns, query, obj, upsert, multi);
487 } catch (std::exception &e) {
488 lua_pushboolean(L, 0);
489 lua_pushfstring(L, LUAMONGO_ERR_UPDATE_FAILED, e.what());
490 return 2;
491 } catch (const char *err) {
492 lua_pushboolean(L, 0);
493 lua_pushstring(L, err);
494 return 2;
495 }
496
497 lua_pushboolean(L, 1);
498 return 1;
499 }
500
501 /*
502 * ok,err = db:drop_collection(ns)
503 */
504 static int dbclient_drop_collection(lua_State *L) {
505 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
506 const char *ns = luaL_checkstring(L, 2);
507
508 try {
509 dbclient->dropCollection(ns);
510 } catch (std::exception &e) {
511 lua_pushboolean(L, 0);
512 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_collection", e.what());
513 return 2;
514 }
515
516 lua_pushboolean(L, 1);
517 return 1;
518 }
519
520 /*
521 * ok,err = db:drop_index_by_fields(ns, json_str or lua_table)
522 */
523 static int dbclient_drop_index_by_fields(lua_State *L) {
524 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
525 const char *ns = luaL_checkstring(L, 2);
526
527 BSONObj keys;
528
529 try {
530 int type = lua_type(L, 3);
531 if (type == LUA_TSTRING) {
532 const char *jsonstr = luaL_checkstring(L, 3);
533 keys = fromjson(jsonstr);
534 } else if (type == LUA_TTABLE) {
535 lua_to_bson(L, 3, keys);
536 } else {
537 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
538 }
539
540 dbclient->dropIndex(ns, keys);
541 } catch (std::exception &e) {
542 lua_pushboolean(L, 0);
543 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_fields", e.what());
544 return 2;
545 } catch (const char *err) {
546 lua_pushboolean(L, 0);
547 lua_pushstring(L, err);
548 return 2;
549 }
550
551 lua_pushboolean(L, 1);
552 return 1;
553 }
554
555 /*
556 * ok,err = db:drop_index_by_name(ns, index_name)
557 */
558 static int dbclient_drop_index_by_name(lua_State *L) {
559 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
560 const char *ns = luaL_checkstring(L, 2);
561
562 try {
563 dbclient->dropIndex(ns, luaL_checkstring(L, 3));
564 } catch (std::exception &e) {
565 lua_pushboolean(L, 0);
566 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_name", e.what());
567 return 2;
568 }
569
570 lua_pushboolean(L, 1);
571 return 1;
572 }
573
574 /*
575 * ok,err = db:drop_indexes(ns)
576 */
577 static int dbclient_drop_indexes(lua_State *L) {
578 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
579 const char *ns = luaL_checkstring(L, 2);
580
581 try {
582 dbclient->dropIndexes(ns);
583 } catch (std::exception &e) {
584 lua_pushboolean(L, 0);
585 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_indexes", e.what());
586 return 2;
587 }
588
589 lua_pushboolean(L, 1);
590 return 1;
591 }
592
593 /*
594 * res,err = (dbname, jscode[, args_table])
595 */
596 static int dbclient_eval(lua_State *L) {
597 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
598 const char *dbname = luaL_checkstring(L, 2);
599 const char *jscode = luaL_checkstring(L, 3);
600
601 BSONObj info;
602 BSONElement retval;
603 BSONObj *args = NULL;
604 if (!lua_isnoneornil(L, 4)) {
605 try {
606 int type = lua_type(L, 4);
607
608 if (type == LUA_TSTRING) {
609 args = new BSONObj(luaL_checkstring(L, 4));
610 } else if (type == LUA_TTABLE) {
611 BSONObj obj;
612 lua_to_bson(L, 4, obj);
613
614 args = new BSONObj(obj);
615 } else {
616 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
617 }
618 } catch (std::exception &e) {
619 lua_pushnil(L);
620 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", e.what());
621 return 2;
622 } catch (const char *err) {
623 lua_pushnil(L);
624 lua_pushstring(L, err);
625 return 2;
626 }
627 }
628
629 bool res = dbclient->eval(dbname, jscode, info, retval, args);
630
631 if (!res) {
632 lua_pushboolean(L, 0);
633 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", info["errmsg"].str().c_str());
634
635 return 2;
636 }
637
638 if (args) {
639 delete args;
640 }
641
642 lua_push_value(L, retval);
643 return 1;
644 }
645
646 /*
647 * bool = db:exists(ns)
648 */
649 static int dbclient_exists(lua_State *L) {
650 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
651 const char *ns = luaL_checkstring(L, 2);
652
653 bool res = dbclient->exists(ns);
654
655 lua_pushboolean(L, res);
656
657 return 1;
658 }
659
660 /*
661 * name = db:gen_index_name(json_str or lua_table)
662 */
663 static int dbclient_gen_index_name(lua_State *L) {
664 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
665
666 string name = "";
667
668 try {
669 int type = lua_type(L, 2);
670 if (type == LUA_TSTRING) {
671 const char *jsonstr = luaL_checkstring(L, 2);
672 name = dbclient->genIndexName(fromjson(jsonstr));
673 } else if (type == LUA_TTABLE) {
674 BSONObj data;
675 lua_to_bson(L, 2, data);
676
677 name = dbclient->genIndexName(data);
678 } else {
679 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
680 }
681 } catch (std::exception &e) {
682 lua_pushnil(L);
683 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "gen_index_name", e.what());
684 return 2;
685 } catch (const char *err) {
686 lua_pushnil(L);
687 lua_pushstring(L, err);
688 return 2;
689 }
690
691 lua_pushstring(L, name.c_str());
692 return 1;
693 }
694
695 /*
1d1cfe2 @neoxic + Fix segfault on MongoDB restart (add check for lost connection)
neoxic authored Jan 31, 2012
696 * cursor,err = db:get_indexes(ns)
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
697 */
698 static int dbclient_get_indexes(lua_State *L) {
699 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
700 const char *ns = luaL_checkstring(L, 2);
701
702 auto_ptr<DBClientCursor> autocursor = dbclient->getIndexes(ns);
703
1d1cfe2 @neoxic + Fix segfault on MongoDB restart (add check for lost connection)
neoxic authored Jan 31, 2012
704 if (!autocursor.get()) {
705 lua_pushnil(L);
706 lua_pushstring(L, LUAMONGO_ERR_CONNECTION_LOST);
707 return 2;
708 }
709
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
710 DBClientCursor **cursor = (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *));
711 *cursor = autocursor.get();
712 autocursor.release();
713
714 luaL_getmetatable(L, LUAMONGO_CURSOR);
715 lua_setmetatable(L, -2);
716
717 return 1;
718 }
719
720 /*
721 * res,err = db:mapreduce(jsmapfunc, jsreducefunc[, query[, output]])
722 */
723 static int dbclient_mapreduce(lua_State *L) {
724 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
725 const char *ns = luaL_checkstring(L, 2);
726 const char *jsmapfunc = luaL_checkstring(L, 3);
727 const char *jsreducefunc = luaL_checkstring(L, 4);
728
729 BSONObj query;
730 if (!lua_isnoneornil(L, 5)) {
731 try {
732 int type = lua_type(L, 5);
733 if (type == LUA_TSTRING) {
734 const char *jsonstr = luaL_checkstring(L, 5);
735 query = fromjson(jsonstr);
736 } else if (type == LUA_TTABLE) {
737 lua_to_bson(L, 5, query);
738 } else {
739 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
740 }
741 } catch (std::exception &e) {
742 lua_pushnil(L);
743 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "mapreduce", e.what());
744 return 2;
745 } catch (const char *err) {
746 lua_pushnil(L);
747 lua_pushstring(L, err);
748 return 2;
749 }
750 }
751
752 const char *output = luaL_optstring(L, 6, "");
753
754 BSONObj res = dbclient->mapreduce(ns, jsmapfunc, jsreducefunc, query, output);
755
756 bson_to_lua(L, res);
757
758 return 1;
759 }
760
761 /*
762 * ok,err = db:reindex(ns);
763 */
764 static int dbclient_reindex(lua_State *L) {
765 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
766 const char *ns = luaL_checkstring(L, 2);
767
768 try {
769 dbclient->reIndex(ns);
770 } catch (std::exception &e) {
771 lua_pushboolean(L, 0);
772 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "reindex", e.what());
773 return 2;
774 }
775
776 lua_pushboolean(L, 1);
777 return 1;
778 }
779
780 /*
781 * db:reset_index_cache()
782 */
783 static int dbclient_reset_index_cache(lua_State *L) {
784 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
785
786 dbclient->resetIndexCache();
787
788 return 0;
789 }
790
3aec1d0 Add getLastError and getLastErrorDetailed
Ezra Nuite authored Jan 18, 2012
791 /*
792 * db:get_last_error()
793 */
794 static int dbclient_get_last_error(lua_State *L) {
795 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
796
797 string result = dbclient->getLastError();
798 lua_pushlstring(L, result.c_str(), result.size());
799 return 1;
800 }
801
802 /*
803 * db:get_last_error_detailed()
804 */
805 static int dbclient_get_last_error_detailed(lua_State *L) {
806 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
807
808 BSONObj res = dbclient->getLastErrorDetailed();
809 bson_to_lua(L, res);
810 return 1;
811 }
812
993e514 Add run command. Patch submitted by neomantra
Rob LaRubbio authored Jan 19, 2012
813 /*
814 * res,err = db:run_command(dbname, lua_table or json_str, options)
815 */
816 static int dbclient_run_command(lua_State *L) {
817 DBClientBase *dbclient = userdata_to_dbclient(L, 1);
818 const char *ns = luaL_checkstring(L, 2);
819 int options = lua_tointeger(L, 4); // if it is invalid it returns 0
820
821 BSONObj command; // arg 3
822 try {
823 int type = lua_type(L, 3);
824 if (type == LUA_TSTRING) {
825 const char *jsonstr = luaL_checkstring(L, 3);
826 command = fromjson(jsonstr);
827 } else if (type == LUA_TTABLE) {
828 lua_to_bson(L, 3, command);
829 } else {
830 throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
831 }
832
833 BSONObj retval;
834 bool success = dbclient->runCommand(ns, command, retval, options);
835 if ( !success )
836 throw "run_command failed";
837
838 bson_to_lua(L, retval );
839 return 1;
840 } catch (std::exception &e) {
841 lua_pushboolean(L, 0);
842 lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION,
1d1cfe2 @neoxic + Fix segfault on MongoDB restart (add check for lost connection)
neoxic authored Jan 31, 2012
843 "run_command", e.what());
993e514 Add run command. Patch submitted by neomantra
Rob LaRubbio authored Jan 19, 2012
844 return 2;
845 } catch (const char *err) {
846 lua_pushboolean(L, 0);
847 lua_pushstring(L, err);
848 return 2;
849 }
850 }
851
852
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
853 // Method registration table for DBClients
854 extern const luaL_Reg dbclient_methods[] = {
855 {"auth", dbclient_auth},
856 {"count", dbclient_count},
857 {"drop_collection", dbclient_drop_collection},
858 {"drop_index_by_fields", dbclient_drop_index_by_fields},
859 {"drop_index_by_name", dbclient_drop_index_by_name},
860 {"drop_indexes", dbclient_drop_indexes},
861 {"ensure_index", dbclient_ensure_index},
862 {"eval", dbclient_eval},
863 {"exists", dbclient_exists},
9025545 @mabako Added db:find_one
mabako authored Feb 5, 2012
864 {"find_one", dbclient_find_one},
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
865 {"gen_index_name", dbclient_gen_index_name},
866 {"get_indexes", dbclient_get_indexes},
3aec1d0 Add getLastError and getLastErrorDetailed
Ezra Nuite authored Jan 18, 2012
867 {"get_last_error", dbclient_get_last_error},
868 {"get_last_error_detailed", dbclient_get_last_error_detailed},
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
869 {"get_server_address", dbclient_get_server_address},
870 {"insert", dbclient_insert},
871 {"insert_batch", dbclient_insert_batch},
872 {"is_failed", dbclient_is_failed},
873 {"mapreduce", dbclient_mapreduce},
874 {"query", dbclient_query},
875 {"reindex", dbclient_reindex},
876 {"remove", dbclient_remove},
877 {"reset_index_cache", dbclient_reset_index_cache},
993e514 Add run command. Patch submitted by neomantra
Rob LaRubbio authored Jan 19, 2012
878 {"run_command", dbclient_run_command},
90e2fdf @neomantra Added ReplicaSet support
neomantra authored Jul 30, 2011
879 {"update", dbclient_update},
880 {NULL, NULL}
881 };
882
883
Something went wrong with that request. Please try again.