PageRenderTime 36ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/mongo_connection.cpp

http://luamongo.googlecode.com/
C++ | 798 lines | 588 code | 125 blank | 85 comment | 88 complexity | 519677028b3e5d3ca54938823e585ad9 MD5 | raw file
Possible License(s): MIT
  1. #include <iostream>
  2. #include <client/dbclient.h>
  3. extern "C" {
  4. #include <lua.h>
  5. #include <lauxlib.h>
  6. #include <lualib.h>
  7. #if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
  8. #include <compat-5.1.h>
  9. #endif
  10. };
  11. #include "utils.h"
  12. #include "common.h"
  13. using namespace mongo;
  14. extern int cursor_create(lua_State *L, DBClientConnection *connection, const char *ns,
  15. const Query &query, int nToReturn, int nToSkip,
  16. const BSONObj *fieldsToReturn, int queryOptions, int batchSize);
  17. extern void lua_to_bson(lua_State *L, int stackpos, BSONObj &obj);
  18. extern void bson_to_lua(lua_State *L, const BSONObj &obj);
  19. extern void lua_push_value(lua_State *L, const BSONElement &elem);
  20. namespace {
  21. inline DBClientConnection* userdata_to_connection(lua_State* L, int index) {
  22. void *ud = 0;
  23. ud = luaL_checkudata(L, index, LUAMONGO_CONNECTION);
  24. DBClientConnection *connection = *((DBClientConnection **)ud);
  25. return connection;
  26. }
  27. } // anonymous namespace
  28. /*
  29. * db,err = mongo.Connection.New({})
  30. * accepts an optional table of features:
  31. * auto_reconnect (default = false)
  32. * rw_timeout (default = 0) (mongo >= v1.5)
  33. */
  34. static int connection_new(lua_State *L) {
  35. int resultcount = 1;
  36. try {
  37. bool auto_reconnect;
  38. int rw_timeout;
  39. if (lua_type(L,1) == LUA_TTABLE) {
  40. // extract arguments from table
  41. lua_getfield(L, 1, "auto_reconnect");
  42. auto_reconnect = lua_toboolean(L, -1);
  43. lua_getfield(L, 1, "rw_timeout");
  44. int rw_timeout = lua_tointeger(L, -1);
  45. lua_pop(L, 2);
  46. } else {
  47. auto_reconnect = false;
  48. rw_timeout = 0;
  49. }
  50. DBClientConnection **connection = (DBClientConnection **)lua_newuserdata(L, sizeof(DBClientConnection *));
  51. #if defined(MONGO_PRE_1_5)
  52. *connection = new DBClientConnection(auto_reconnect, 0);
  53. #else
  54. *connection = new DBClientConnection(auto_reconnect, 0, rw_timeout);
  55. #endif
  56. luaL_getmetatable(L, LUAMONGO_CONNECTION);
  57. lua_setmetatable(L, -2);
  58. } catch (std::exception &e) {
  59. lua_pushnil(L);
  60. lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, e.what());
  61. resultcount = 2;
  62. }
  63. return resultcount;
  64. }
  65. /*
  66. * ok,err = db:connect(connection_str)
  67. */
  68. static int connection_connect(lua_State *L) {
  69. DBClientConnection *connection = userdata_to_connection(L, 1);
  70. const char *connectstr = luaL_checkstring(L, 2);
  71. try {
  72. connection->connect(connectstr);
  73. } catch (std::exception &e) {
  74. lua_pushnil(L);
  75. lua_pushfstring(L, LUAMONGO_ERR_CONNECT_FAILED, connectstr, e.what());
  76. return 2;
  77. }
  78. lua_pushboolean(L, 1);
  79. return 1;
  80. }
  81. /*
  82. * created = db:ensure_index(ns, json_str or lua_table[, unique[, name]])
  83. */
  84. static int connection_ensure_index(lua_State *L) {
  85. DBClientConnection *connection = userdata_to_connection(L, 1);
  86. const char *ns = luaL_checkstring(L, 2);
  87. BSONObj fields;
  88. try {
  89. int type = lua_type(L, 3);
  90. if (type == LUA_TSTRING) {
  91. const char *jsonstr = luaL_checkstring(L, 3);
  92. fields = fromjson(jsonstr);
  93. } else if (type == LUA_TTABLE) {
  94. lua_to_bson(L, 3, fields);
  95. } else {
  96. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  97. }
  98. } catch (std::exception &e) {
  99. lua_pushboolean(L, 0);
  100. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "ensure_index", e.what());
  101. return 2;
  102. } catch (const char *err) {
  103. lua_pushboolean(L, 0);
  104. lua_pushstring(L, err);
  105. return 2;
  106. }
  107. bool unique = lua_toboolean(L, 4);
  108. const char *name = luaL_optstring(L, 5, "");
  109. bool res = connection->ensureIndex(ns, fields, unique, name);
  110. lua_pushboolean(L, res);
  111. return 1;
  112. }
  113. /*
  114. * ok,err = db:auth({})
  115. * accepts a table of parameters:
  116. * dbname database to authenticate (required)
  117. * username username to authenticate against (required)
  118. * password password to authenticate against (required)
  119. * digestPassword set to true if password is pre-digested (default = true)
  120. *
  121. */
  122. static int connection_auth(lua_State *L) {
  123. DBClientConnection *connection = userdata_to_connection(L, 1);
  124. luaL_checktype(L, 2, LUA_TTABLE);
  125. lua_getfield(L, 2, "dbname");
  126. const char *dbname = luaL_checkstring(L, -1);
  127. lua_getfield(L, 2, "username");
  128. const char *username = luaL_checkstring(L, -1);
  129. lua_getfield(L, 2, "password");
  130. const char *password = luaL_checkstring(L, -1);
  131. lua_getfield(L, 2, "digestPassword");
  132. bool digestPassword = lua_isnil(L, -1) ? true : lua_toboolean(L, -1);
  133. lua_pop(L, 4);
  134. std::string errmsg;
  135. bool success = connection->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. * is_failed = db:is_failed()
  146. */
  147. static int connection_is_failed(lua_State *L) {
  148. DBClientConnection *connection = userdata_to_connection(L, 1);
  149. bool is_failed = connection->isFailed();
  150. lua_pushboolean(L, is_failed);
  151. return 1;
  152. }
  153. /*
  154. * addr = db:get_server_address()
  155. */
  156. static int connection_get_server_address(lua_State *L) {
  157. DBClientConnection *connection = userdata_to_connection(L, 1);
  158. std::string address = connection->getServerAddress();
  159. lua_pushstring(L, address.c_str());
  160. return 1;
  161. }
  162. /*
  163. * count,err = db:count(ns)
  164. */
  165. static int connection_count(lua_State *L) {
  166. DBClientConnection *connection = userdata_to_connection(L, 1);
  167. const char *ns = luaL_checkstring(L, 2);
  168. int count = 0;
  169. try {
  170. count = connection->count(ns);
  171. } catch (std::exception &e) {
  172. lua_pushnil(L);
  173. lua_pushfstring(L, LUAMONGO_ERR_COUNT_FAILED, e.what());
  174. return 2;
  175. }
  176. lua_pushinteger(L, count);
  177. return 1;
  178. }
  179. /*
  180. * ok,err = db:insert(ns, lua_table or json_str)
  181. */
  182. static int connection_insert(lua_State *L) {
  183. DBClientConnection *connection = userdata_to_connection(L, 1);
  184. const char *ns = luaL_checkstring(L, 2);
  185. try {
  186. int type = lua_type(L, 3);
  187. if (type == LUA_TSTRING) {
  188. const char *jsonstr = luaL_checkstring(L, 3);
  189. connection->insert(ns, fromjson(jsonstr));
  190. } else if (type == LUA_TTABLE) {
  191. BSONObj data;
  192. lua_to_bson(L, 3, data);
  193. connection->insert(ns, data);
  194. } else {
  195. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  196. }
  197. } catch (std::exception &e) {
  198. lua_pushboolean(L, 0);
  199. lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
  200. return 2;
  201. } catch (const char *err) {
  202. lua_pushboolean(L, 0);
  203. lua_pushstring(L, err);
  204. return 2;
  205. }
  206. lua_pushboolean(L, 1);
  207. return 1;
  208. }
  209. /*
  210. * ok,err = db:insert_batch(ns, lua_array_of_tables)
  211. */
  212. static int connection_insert_batch(lua_State *L) {
  213. DBClientConnection *connection = userdata_to_connection(L, 1);
  214. const char *ns = luaL_checkstring(L, 2);
  215. luaL_checktype(L, 3, LUA_TTABLE);
  216. try {
  217. std::vector<BSONObj> vdata;
  218. size_t tlen = lua_objlen(L, 3) + 1;
  219. for (size_t i = 1; i < tlen; ++i) {
  220. vdata.push_back(BSONObj());
  221. lua_rawgeti(L, 3, i);
  222. lua_to_bson(L, 4, vdata.back());
  223. lua_pop(L, 1);
  224. }
  225. connection->insert(ns, vdata);
  226. } catch (std::exception &e) {
  227. lua_pushboolean(L, 0);
  228. lua_pushfstring(L, LUAMONGO_ERR_INSERT_FAILED, e.what());
  229. return 2;
  230. } catch (const char *err) {
  231. lua_pushboolean(L, 0);
  232. lua_pushstring(L, err);
  233. return 2;
  234. }
  235. lua_pushboolean(L, 1);
  236. return 1;
  237. }
  238. /*
  239. * cursor,err = db:query(ns, lua_table or json_str or query_obj, limit, skip, lua_table or json_str, options, batchsize)
  240. */
  241. static int connection_query(lua_State *L) {
  242. int n = lua_gettop(L);
  243. DBClientConnection *connection = userdata_to_connection(L, 1);
  244. const char *ns = luaL_checkstring(L, 2);
  245. Query query;
  246. if (!lua_isnoneornil(L, 3)) {
  247. try {
  248. int type = lua_type(L, 3);
  249. if (type == LUA_TSTRING) {
  250. query = fromjson(luaL_checkstring(L, 3));
  251. } else if (type == LUA_TTABLE) {
  252. BSONObj obj;
  253. lua_to_bson(L, 3, obj);
  254. query = obj;
  255. } else if (type == LUA_TUSERDATA) {
  256. void *uq = 0;
  257. uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
  258. query = *(*((Query **)uq));
  259. } else {
  260. throw(LUAMONGO_REQUIRES_QUERY);
  261. }
  262. } catch (std::exception &e) {
  263. lua_pushnil(L);
  264. lua_pushfstring(L, LUAMONGO_ERR_QUERY_FAILED, e.what());
  265. return 2;
  266. } catch (const char *err) {
  267. lua_pushnil(L);
  268. lua_pushstring(L, err);
  269. return 2;
  270. }
  271. }
  272. int nToReturn = luaL_optint(L, 4, 0);
  273. int nToSkip = luaL_optint(L, 5, 0);
  274. const BSONObj *fieldsToReturn = NULL;
  275. if (!lua_isnoneornil(L, 6)) {
  276. fieldsToReturn = new BSONObj();
  277. int type = lua_type(L, 6);
  278. if (type == LUA_TSTRING) {
  279. fieldsToReturn = new BSONObj(luaL_checkstring(L, 6));
  280. } else if (type == LUA_TTABLE) {
  281. BSONObj obj;
  282. lua_to_bson(L, 6, obj);
  283. fieldsToReturn = new BSONObj(obj);
  284. } else {
  285. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  286. }
  287. }
  288. int queryOptions = luaL_optint(L, 7, 0);
  289. int batchSize = luaL_optint(L, 8, 0);
  290. int res = cursor_create(L, connection, ns, query, nToReturn, nToSkip,
  291. fieldsToReturn, queryOptions, batchSize);
  292. if (fieldsToReturn) {
  293. delete fieldsToReturn;
  294. }
  295. return res;
  296. }
  297. /*
  298. * ok,err = db:remove(ns, lua_table or json_str or query_obj)
  299. */
  300. static int connection_remove(lua_State *L) {
  301. DBClientConnection *connection = userdata_to_connection(L, 1);
  302. const char *ns = luaL_checkstring(L, 2);
  303. try {
  304. int type = lua_type(L, 3);
  305. bool justOne = lua_toboolean(L, 4);
  306. if (type == LUA_TSTRING) {
  307. const char *jsonstr = luaL_checkstring(L, 3);
  308. connection->remove(ns, fromjson(jsonstr), justOne);
  309. } else if (type == LUA_TTABLE) {
  310. BSONObj data;
  311. lua_to_bson(L, 3, data);
  312. connection->remove(ns, data, justOne);
  313. } else if (type == LUA_TUSERDATA) {
  314. Query query;
  315. void *uq = 0;
  316. uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
  317. query = *(*((Query **)uq));
  318. connection->remove(ns, query, justOne);
  319. } else {
  320. throw(LUAMONGO_REQUIRES_QUERY);
  321. }
  322. } catch (std::exception &e) {
  323. lua_pushboolean(L, 0);
  324. lua_pushfstring(L, LUAMONGO_ERR_REMOVE_FAILED, e.what());
  325. return 2;
  326. } catch (const char *err) {
  327. lua_pushboolean(L, 0);
  328. lua_pushstring(L, err);
  329. return 2;
  330. }
  331. lua_pushboolean(L, 1);
  332. return 1;
  333. }
  334. /*
  335. * ok,err = db:update(ns, lua_table or json_str or query_obj, lua_table or json_str, upsert, multi)
  336. */
  337. static int connection_update(lua_State *L) {
  338. DBClientConnection *connection = userdata_to_connection(L, 1);
  339. const char *ns = luaL_checkstring(L, 2);
  340. try {
  341. int type_query = lua_type(L, 3);
  342. int type_obj = lua_type(L, 4);
  343. bool upsert = lua_toboolean(L, 5);
  344. bool multi = lua_toboolean(L, 6);
  345. Query query;
  346. BSONObj obj;
  347. if (type_query == LUA_TSTRING) {
  348. const char *jsonstr = luaL_checkstring(L, 3);
  349. query = fromjson(jsonstr);
  350. } else if (type_query == LUA_TTABLE) {
  351. BSONObj q;
  352. lua_to_bson(L, 3, q);
  353. query = q;
  354. } else if (type_query == LUA_TUSERDATA) {
  355. void *uq = 0;
  356. uq = luaL_checkudata(L, 3, LUAMONGO_QUERY);
  357. query = *(*((Query **)uq));
  358. } else {
  359. throw(LUAMONGO_REQUIRES_QUERY);
  360. }
  361. if (type_obj == LUA_TSTRING) {
  362. const char *jsonstr = luaL_checkstring(L, 4);
  363. obj = fromjson(jsonstr);
  364. } else if (type_obj == LUA_TTABLE) {
  365. lua_to_bson(L, 4, obj);
  366. } else {
  367. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  368. }
  369. connection->update(ns, query, obj, upsert, multi);
  370. } catch (std::exception &e) {
  371. lua_pushboolean(L, 0);
  372. lua_pushfstring(L, LUAMONGO_ERR_UPDATE_FAILED, e.what());
  373. return 2;
  374. } catch (const char *err) {
  375. lua_pushboolean(L, 0);
  376. lua_pushstring(L, err);
  377. return 2;
  378. }
  379. lua_pushboolean(L, 1);
  380. return 1;
  381. }
  382. /*
  383. * ok,err = db:drop_collection(ns)
  384. */
  385. static int connection_drop_collection(lua_State *L) {
  386. DBClientConnection *connection = userdata_to_connection(L, 1);
  387. const char *ns = luaL_checkstring(L, 2);
  388. try {
  389. connection->dropCollection(ns);
  390. } catch (std::exception &e) {
  391. lua_pushboolean(L, 0);
  392. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_collection", e.what());
  393. return 2;
  394. }
  395. lua_pushboolean(L, 1);
  396. return 1;
  397. }
  398. /*
  399. * ok,err = db:drop_index_by_fields(ns, json_str or lua_table)
  400. */
  401. static int connection_drop_index_by_fields(lua_State *L) {
  402. DBClientConnection *connection = userdata_to_connection(L, 1);
  403. const char *ns = luaL_checkstring(L, 2);
  404. BSONObj keys;
  405. try {
  406. int type = lua_type(L, 3);
  407. if (type == LUA_TSTRING) {
  408. const char *jsonstr = luaL_checkstring(L, 3);
  409. keys = fromjson(jsonstr);
  410. } else if (type == LUA_TTABLE) {
  411. lua_to_bson(L, 3, keys);
  412. } else {
  413. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  414. }
  415. connection->dropIndex(ns, keys);
  416. } catch (std::exception &e) {
  417. lua_pushboolean(L, 0);
  418. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_fields", e.what());
  419. return 2;
  420. } catch (const char *err) {
  421. lua_pushboolean(L, 0);
  422. lua_pushstring(L, err);
  423. return 2;
  424. }
  425. lua_pushboolean(L, 1);
  426. return 1;
  427. }
  428. /*
  429. * ok,err = db:drop_index_by_name(ns, index_name)
  430. */
  431. static int connection_drop_index_by_name(lua_State *L) {
  432. DBClientConnection *connection = userdata_to_connection(L, 1);
  433. const char *ns = luaL_checkstring(L, 2);
  434. try {
  435. connection->dropIndex(ns, luaL_checkstring(L, 3));
  436. } catch (std::exception &e) {
  437. lua_pushboolean(L, 0);
  438. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_index_by_name", e.what());
  439. return 2;
  440. }
  441. lua_pushboolean(L, 1);
  442. return 1;
  443. }
  444. /*
  445. * ok,err = db:drop_indexes(ns)
  446. */
  447. static int connection_drop_indexes(lua_State *L) {
  448. DBClientConnection *connection = userdata_to_connection(L, 1);
  449. const char *ns = luaL_checkstring(L, 2);
  450. try {
  451. connection->dropIndexes(ns);
  452. } catch (std::exception &e) {
  453. lua_pushboolean(L, 0);
  454. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "drop_indexes", e.what());
  455. return 2;
  456. }
  457. lua_pushboolean(L, 1);
  458. return 1;
  459. }
  460. /*
  461. * res,err = (dbname, jscode[, args_table])
  462. */
  463. static int connection_eval(lua_State *L) {
  464. DBClientConnection *connection = userdata_to_connection(L, 1);
  465. const char *dbname = luaL_checkstring(L, 2);
  466. const char *jscode = luaL_checkstring(L, 3);
  467. BSONObj info;
  468. BSONElement retval;
  469. BSONObj *args = NULL;
  470. if (!lua_isnoneornil(L, 4)) {
  471. try {
  472. int type = lua_type(L, 4);
  473. if (type == LUA_TSTRING) {
  474. args = new BSONObj(luaL_checkstring(L, 4));
  475. } else if (type == LUA_TTABLE) {
  476. BSONObj obj;
  477. lua_to_bson(L, 4, obj);
  478. args = new BSONObj(obj);
  479. } else {
  480. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  481. }
  482. } catch (std::exception &e) {
  483. lua_pushnil(L);
  484. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", e.what());
  485. return 2;
  486. } catch (const char *err) {
  487. lua_pushnil(L);
  488. lua_pushstring(L, err);
  489. return 2;
  490. }
  491. }
  492. bool res = connection->eval(dbname, jscode, info, retval, args);
  493. if (!res) {
  494. lua_pushboolean(L, 0);
  495. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "eval", info["errmsg"].str().c_str());
  496. return 2;
  497. }
  498. if (args) {
  499. delete args;
  500. }
  501. lua_push_value(L, retval);
  502. return 1;
  503. }
  504. /*
  505. * bool = db:exists(ns)
  506. */
  507. static int connection_exists(lua_State *L) {
  508. DBClientConnection *connection = userdata_to_connection(L, 1);
  509. const char *ns = luaL_checkstring(L, 2);
  510. bool res = connection->exists(ns);
  511. lua_pushboolean(L, res);
  512. return 1;
  513. }
  514. /*
  515. * name = db:gen_index_name(json_str or lua_table)
  516. */
  517. static int connection_gen_index_name(lua_State *L) {
  518. DBClientConnection *connection = userdata_to_connection(L, 1);
  519. string name = "";
  520. try {
  521. int type = lua_type(L, 2);
  522. if (type == LUA_TSTRING) {
  523. const char *jsonstr = luaL_checkstring(L, 2);
  524. name = connection->genIndexName(fromjson(jsonstr));
  525. } else if (type == LUA_TTABLE) {
  526. BSONObj data;
  527. lua_to_bson(L, 2, data);
  528. name = connection->genIndexName(data);
  529. } else {
  530. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  531. }
  532. } catch (std::exception &e) {
  533. lua_pushnil(L);
  534. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "gen_index_name", e.what());
  535. return 2;
  536. } catch (const char *err) {
  537. lua_pushnil(L);
  538. lua_pushstring(L, err);
  539. return 2;
  540. }
  541. lua_pushstring(L, name.c_str());
  542. return 1;
  543. }
  544. /*
  545. * cursor = db:get_indexes(ns)
  546. */
  547. static int connection_get_indexes(lua_State *L) {
  548. DBClientConnection *connection = userdata_to_connection(L, 1);
  549. const char *ns = luaL_checkstring(L, 2);
  550. auto_ptr<DBClientCursor> autocursor = connection->getIndexes(ns);
  551. DBClientCursor **cursor = (DBClientCursor **)lua_newuserdata(L, sizeof(DBClientCursor *));
  552. *cursor = autocursor.get();
  553. autocursor.release();
  554. luaL_getmetatable(L, LUAMONGO_CURSOR);
  555. lua_setmetatable(L, -2);
  556. return 1;
  557. }
  558. /*
  559. * res,err = db:mapreduce(jsmapfunc, jsreducefunc[, query[, output]])
  560. */
  561. static int connection_mapreduce(lua_State *L) {
  562. DBClientConnection *connection = userdata_to_connection(L, 1);
  563. const char *ns = luaL_checkstring(L, 2);
  564. const char *jsmapfunc = luaL_checkstring(L, 3);
  565. const char *jsreducefunc = luaL_checkstring(L, 4);
  566. BSONObj query;
  567. if (!lua_isnoneornil(L, 5)) {
  568. try {
  569. int type = lua_type(L, 5);
  570. if (type == LUA_TSTRING) {
  571. const char *jsonstr = luaL_checkstring(L, 5);
  572. query = fromjson(jsonstr);
  573. } else if (type == LUA_TTABLE) {
  574. lua_to_bson(L, 5, query);
  575. } else {
  576. throw(LUAMONGO_REQUIRES_JSON_OR_TABLE);
  577. }
  578. } catch (std::exception &e) {
  579. lua_pushnil(L);
  580. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "mapreduce", e.what());
  581. return 2;
  582. } catch (const char *err) {
  583. lua_pushnil(L);
  584. lua_pushstring(L, err);
  585. return 2;
  586. }
  587. }
  588. const char *output = luaL_optstring(L, 6, "");
  589. BSONObj res = connection->mapreduce(ns, jsmapfunc, jsreducefunc, query, output);
  590. bson_to_lua(L, res);
  591. return 1;
  592. }
  593. /*
  594. * ok,err = db:reindex(ns);
  595. */
  596. static int connection_reindex(lua_State *L) {
  597. DBClientConnection *connection = userdata_to_connection(L, 1);
  598. const char *ns = luaL_checkstring(L, 2);
  599. try {
  600. connection->reIndex(ns);
  601. } catch (std::exception &e) {
  602. lua_pushboolean(L, 0);
  603. lua_pushfstring(L, LUAMONGO_ERR_CALLING, LUAMONGO_CONNECTION, "reindex", e.what());
  604. return 2;
  605. }
  606. lua_pushboolean(L, 1);
  607. return 1;
  608. }
  609. /*
  610. * db:reset_index_cache()
  611. */
  612. static int connection_reset_index_cache(lua_State *L) {
  613. DBClientConnection *connection = userdata_to_connection(L, 1);
  614. connection->resetIndexCache();
  615. return 0;
  616. }
  617. /*
  618. * __gc
  619. */
  620. static int connection_gc(lua_State *L) {
  621. DBClientConnection *connection = userdata_to_connection(L, 1);
  622. delete connection;
  623. return 0;
  624. }
  625. /*
  626. * __tostring
  627. */
  628. static int connection_tostring(lua_State *L) {
  629. DBClientConnection *connection = userdata_to_connection(L, 1);
  630. lua_pushfstring(L, "%s: %s", LUAMONGO_CONNECTION, connection->toString().c_str());
  631. return 1;
  632. }
  633. int mongo_connection_register(lua_State *L) {
  634. static const luaL_Reg connection_methods[] = {
  635. {"auth", connection_auth},
  636. {"connect", connection_connect},
  637. {"count", connection_count},
  638. {"drop_collection", connection_drop_collection},
  639. {"drop_index_by_fields", connection_drop_index_by_fields},
  640. {"drop_index_by_name", connection_drop_index_by_name},
  641. {"drop_indexes", connection_drop_indexes},
  642. {"ensure_index", connection_ensure_index},
  643. {"eval", connection_eval},
  644. {"exists", connection_exists},
  645. {"gen_index_name", connection_gen_index_name},
  646. {"get_indexes", connection_get_indexes},
  647. {"get_server_address", connection_get_server_address},
  648. {"insert", connection_insert},
  649. {"insert_batch", connection_insert_batch},
  650. {"is_failed", connection_is_failed},
  651. {"mapreduce", connection_mapreduce},
  652. {"query", connection_query},
  653. {"reindex", connection_reindex},
  654. {"remove", connection_remove},
  655. {"reset_index_cache", connection_reset_index_cache},
  656. {"update", connection_update},
  657. {NULL, NULL}
  658. };
  659. static const luaL_Reg connection_class_methods[] = {
  660. {"New", connection_new},
  661. {NULL, NULL}
  662. };
  663. luaL_newmetatable(L, LUAMONGO_CONNECTION);
  664. luaL_register(L, 0, connection_methods);
  665. lua_pushvalue(L,-1);
  666. lua_setfield(L, -2, "__index");
  667. lua_pushcfunction(L, connection_gc);
  668. lua_setfield(L, -2, "__gc");
  669. lua_pushcfunction(L, connection_tostring);
  670. lua_setfield(L, -2, "__tostring");
  671. luaL_register(L, LUAMONGO_CONNECTION, connection_class_methods);
  672. return 1;
  673. }