forked from moai/luamongo
-
Notifications
You must be signed in to change notification settings - Fork 3
/
mongo_connection.cpp
133 lines (105 loc) · 3.28 KB
/
mongo_connection.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <client/dbclient.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#if !defined(LUA_VERSION_NUM) || (LUA_VERSION_NUM < 501)
#include <compat-5.1.h>
#endif
};
#include "common.h"
using namespace mongo;
extern const luaL_Reg dbclient_methods[];
namespace {
inline DBClientConnection* userdata_to_connection(lua_State* L, int index) {
void *ud = luaL_checkudata(L, index, LUAMONGO_CONNECTION);
DBClientConnection *connection = *((DBClientConnection **)ud);
return connection;
}
} // anonymous namespace
/*
* db,err = mongo.Connection.New({})
* accepts an optional table of features:
* auto_reconnect (default = false)
* rw_timeout (default = 0) (mongo >= v1.5)
*/
static int connection_new(lua_State *L) {
int resultcount = 1;
try {
bool auto_reconnect;
int rw_timeout;
if (lua_type(L,1) == LUA_TTABLE) {
// extract arguments from table
lua_getfield(L, 1, "auto_reconnect");
auto_reconnect = lua_toboolean(L, -1);
lua_getfield(L, 1, "rw_timeout");
int rw_timeout = lua_tointeger(L, -1);
lua_pop(L, 2);
} else {
auto_reconnect = false;
rw_timeout = 0;
}
DBClientConnection **connection = (DBClientConnection **)lua_newuserdata(L, sizeof(DBClientConnection *));
*connection = new DBClientConnection(auto_reconnect, 0, rw_timeout);
luaL_getmetatable(L, LUAMONGO_CONNECTION);
lua_setmetatable(L, -2);
} catch (std::exception &e) {
lua_pushnil(L);
lua_pushfstring(L, LUAMONGO_ERR_CONNECTION_FAILED, e.what());
resultcount = 2;
}
return resultcount;
}
/*
* ok,err = connection:connect(connection_str)
*/
static int connection_connect(lua_State *L) {
DBClientConnection *connection = userdata_to_connection(L, 1);
const char *connectstr = luaL_checkstring(L, 2);
try {
connection->connect(connectstr);
} catch (std::exception &e) {
lua_pushnil(L);
lua_pushfstring(L, LUAMONGO_ERR_CONNECT_FAILED, connectstr, e.what());
return 2;
}
lua_pushboolean(L, 1);
return 1;
}
/*
* __gc
*/
static int connection_gc(lua_State *L) {
DBClientConnection *connection = userdata_to_connection(L, 1);
delete connection;
return 0;
}
/*
* __tostring
*/
static int connection_tostring(lua_State *L) {
DBClientConnection *connection = userdata_to_connection(L, 1);
lua_pushfstring(L, "%s: %s", LUAMONGO_CONNECTION, connection->toString().c_str());
return 1;
}
int mongo_connection_register(lua_State *L) {
static const luaL_Reg connection_methods[] = {
{"connect", connection_connect},
{NULL, NULL}
};
static const luaL_Reg connection_class_methods[] = {
{"New", connection_new},
{NULL, NULL}
};
luaL_newmetatable(L, LUAMONGO_CONNECTION);
luaL_register(L, NULL, dbclient_methods);
luaL_register(L, NULL, connection_methods);
lua_pushvalue(L,-1);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, connection_gc);
lua_setfield(L, -2, "__gc");
lua_pushcfunction(L, connection_tostring);
lua_setfield(L, -2, "__tostring");
luaL_register(L, LUAMONGO_CONNECTION, connection_class_methods);
return 1;
}