001 |
//函数返回0:成功 >0 出错 |
|
002 |
class cmongo{ |
003 |
public: |
|
004 |
//默认构造函数,默认连接数为1 |
005 |
cmongo(); |
|
006 |
//传入连接数到构造函数,默认连接数为size |
007 |
cmongo(int size); |
|
008 |
//析构函数 |
009 |
~cmongo(); |
|
010 |
public: |
011 |
//设置tcp读写超时时间 |
|
012 |
int set_wr_timeout(double t); |
013 |
//连接 |
|
014 |
int conn(string mhost="127.0.0.1",int mport=27017); |
015 |
//设置db collection |
|
016 |
int setdb(string mdb,string mcollection); |
017 |
|
|
018 |
int setindex(string key); |
019 |
//查询 |
|
020 |
int get(map<string,string>& out,vector<string> in,string key,string key_val); |
021 |
//投递一批要查询的字段,fields为要查询哪些字段 |
|
022 |
int gets(map< string,map<string,string> >& rout,vector<string> fields,vector<string> in,string key); |
023 |
//dump key-value dumpkey对应一个value |
|
024 |
int dumpkey(map< string,string >& rout,string key,string val); |
025 |
//dump key->map<key,value> dumpkey对应一组value |
|
026 |
int dumpvals(map< string,map<string,string> >& rout,vector<string> in,string key); |
027 |
//写入 |
|
028 |
int set(map<string,string> in,string key,string key_val); |
029 |
//批量写入 |
|
030 |
//更新接口,批量更新key="id" |
031 |
// "123456":<key,value>,<key,value> |
032 |
// "123457":<key,value>,<key,value> |
033 |
int sets(map< string,map<string,string> > in,string key); |
|
034 |
//删除 |
035 |
int remove(string key,string key_val); |
|
036 |
private: |
037 |
string doc; |
|
038 |
//tcp读写超时时间 |
039 |
double wr_timeout; |
|
040 |
pthread_mutex_t _jobmux; |
041 |
sem_t _jobsem; |
|
042 |
map<DBClientConnection*,bool> _joblst; |
043 |
pthread_mutex_t _dbmux; |
|
044 |
|
045 |
}; |
046 |
|
047 |
|
048 |
|
049 |
cmongo::cmongo(int size){ |
|
050 |
//doc |
051 |
doc=string(DB_DB)+"."+string(DB_COLLECTION); |
|
052 |
wr_timeout=3; |
053 |
//最大连接0-200 |
|
054 |
if(size<0){ |
055 |
size=1; |
|
056 |
} |
057 |
if(size>200){ |
|
058 |
size=200; |
059 |
} |
|
060 |
if(_joblst.size()>0){ |
061 |
return; |
|
062 |
} |
063 |
bool auto_conn=true; |
|
064 |
pthread_mutex_init(&_jobmux,NULL); |
065 |
if((sem_init(&_jobsem,0,0))<0){ |
|
066 |
return; |
067 |
} |
|
068 |
pthread_mutex_lock(&_jobmux); |
069 |
for(int i=0;i<size;++i){ |
|
070 |
DBClientConnection* pconn = newDBClientConnection(auto_conn,0,wr_timeout); |
071 |
if(pconn != NULL){ |
|
072 |
_joblst[pconn]=false; |
073 |
} |
|
074 |
} |
075 |
pthread_mutex_unlock(&_jobmux); |
|
076 |
|
077 |
|
|
078 |
} |
079 |
cmongo::~cmongo(){ |
|
080 |
doc=""; |
081 |
pthread_mutex_lock(&_jobmux); |
|
082 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
083 |
while(it != _joblst.end()){ |
|
084 |
delete it->first; |
085 |
it++; |
|
086 |
} |
087 |
pthread_mutex_unlock(&_jobmux); |
|
088 |
} |
089 |
int cmongo::set_wr_timeout(double t){ |
|
090 |
wr_timeout=t; |
091 |
return RET_OK; |
|
092 |
} |
093 |
int cmongo::conn(string mhost,int mport){ |
|
094 |
pthread_mutex_lock(&_jobmux); |
095 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
|
096 |
while(it!=_joblst.end()){ |
097 |
string errmsg=""; |
|
098 |
HostAndPort hp(mhost,mport); |
099 |
if(!(it->first->connect(hp,errmsg))){ |
|
100 |
cerr<<"connect mhost:"<<mhost<<" mport:"<<mport<<" msg:"<<errmsg<<endl; |
101 |
it->second=true; |
|
102 |
} |
103 |
sem_post(&_jobsem); |
|
104 |
it++; |
105 |
} |
|
106 |
pthread_mutex_unlock(&_jobmux); |
107 |
return RET_OK; |
|
108 |
} |
109 |
int cmongo::setdb(string mdb,string mcollection){ |
|
110 |
if(mdb.empty() || mcollection.empty()){ |
111 |
return RET_PARERR; |
|
112 |
} |
113 |
doc=mdb+"."+mcollection; |
|
114 |
return RET_OK; |
115 |
} |
|
116 |
int cmongo::setindex(string key){ |
117 |
if(key.empty()){ |
|
118 |
return RET_PARERR; |
119 |
} |
|
120 |
sem_wait(&_jobsem); |
121 |
pthread_mutex_lock(&_jobmux); |
|
122 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
123 |
while(it!=_joblst.end()){ |
|
124 |
if(it->second == false){ |
125 |
it->second=true; |
|
126 |
break; |
127 |
} |
|
128 |
it++; |
129 |
} |
|
130 |
pthread_mutex_unlock(&_jobmux); |
131 |
string bindex="{"+key+":1}"; |
|
132 |
it->first->ensureIndex(doc,fromjson(bindex)); |
133 |
|
|
134 |
pthread_mutex_lock(&_jobmux); |
135 |
it->second=false; |
|
136 |
pthread_mutex_unlock(&_jobmux); |
137 |
sem_post(&_jobsem); |
|
138 |
|
139 |
return RET_OK; |
|
140 |
} |
141 |
//out为检索出来的key-value数据对应,in 为要检索的字段,key,key_value为要检索的条件,暂不支持多条件检索 |
|
142 |
//单列查询 |
143 |
int cmongo::get(map<string,string>& out,vector<string> in,string key,string key_val){ |
|
144 |
//key key_val 要检索字段 |
145 |
if(key.empty() || key_val.empty() || in.size()<=0){ |
|
146 |
return RET_PARERR; |
147 |
} |
|
148 |
BSONObjBuilder b; |
149 |
for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){ |
|
150 |
b.append(*iter,1); |
151 |
} |
|
152 |
|
153 |
sem_wait(&_jobsem); |
|
154 |
pthread_mutex_lock(&_jobmux); |
155 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
|
156 |
while(it!=_joblst.end()){ |
157 |
if(it->second == false){ |
|
158 |
it->second=true; |
159 |
break; |
|
160 |
} |
161 |
it++; |
|
162 |
} |
163 |
pthread_mutex_unlock(&_jobmux); |
|
164 |
BSONObj ob=b.obj(); |
165 |
|
|
166 |
BSONObj p=it->first->findOne(doc,QUERY(key<<key_val),&ob); |
167 |
|
|
168 |
map<string,string> temp; |
169 |
for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){ |
|
170 |
string mkey=*iter; |
171 |
temp[*iter]=p.getStringField(mkey.c_str()); |
|
172 |
} |
173 |
out=temp; |
|
174 |
|
175 |
pthread_mutex_lock(&_jobmux); |
|
176 |
it->second=false; |
177 |
pthread_mutex_unlock(&_jobmux); |
|
178 |
sem_post(&_jobsem); |
179 |
|
|
180 |
return RET_OK; |
181 |
} |
|
182 |
//查询key为key的一批数据的 某些字段 |
183 |
//fields为要查询的字段集 |
|
184 |
//key="id" 值为in 一批key |
185 |
//返回key->map<key,value> |
|
186 |
int cmongo::gets(map< string,map<string,string> >& rout,vector<string> fields,vector<string> in,string key){ |
187 |
if(key.empty()){ |
|
188 |
return RET_PARERR; |
189 |
} |
|
190 |
sem_wait(&_jobsem); |
191 |
pthread_mutex_lock(&_jobmux); |
|
192 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
193 |
while(it!=_joblst.end()){ |
|
194 |
if(it->second == false){ |
195 |
it->second=true; |
|
196 |
break; |
197 |
} |
|
198 |
it++; |
199 |
} |
|
200 |
pthread_mutex_unlock(&_jobmux); |
201 |
|
|
202 |
BSONObjBuilder b; |
203 |
b.append(key,1); |
|
204 |
for(vector<string>::iterator iter=fields.begin();iter!=fields.end();++iter){ |
205 |
b.append(*iter,1); |
|
206 |
} |
207 |
|
|
208 |
BSONObj p=b.obj(); |
209 |
for(vector<string>::iterator iter2=in.begin();iter2!=in.end();++iter2){ |
210 |
BSONObj ob=it->first->findOne(doc,QUERY(key<<*iter2),&p); |
211 |
map<string,string> temp; |
|
212 |
for(vector<string>::iterator iter=fields.begin();iter!=fields.end();++iter){ |
213 |
string mkey=*iter; |
||
214 |
temp[*iter]=ob.getStringField(mkey.c_str()); |
215 |
} |
|
216 |
rout[ob.getStringField(key.c_str())]=temp; |
217 |
} |
|
218 |
|
219 |
pthread_mutex_lock(&_jobmux); |
|
220 |
it->second=false; |
221 |
pthread_mutex_unlock(&_jobmux); |
|
222 |
sem_post(&_jobsem); |
223 |
|
|
224 |
return RET_OK; |
225 |
} |
|
226 |
//dumpkey key-value 返回 key对应的val值 |
227 |
//key val |
|
228 |
int cmongo::dumpkey(map< string,string >& rout,string key,string val){ |
229 |
if(key.empty()){ |
|
230 |
return RET_PARERR; |
231 |
} |
|
232 |
sem_wait(&_jobsem); |
233 |
pthread_mutex_lock(&_jobmux); |
|
234 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
235 |
while(it!=_joblst.end()){ |
|
236 |
if(it->second == false){ |
237 |
it->second=true; |
|
238 |
break; |
239 |
} |
|
240 |
it++; |
241 |
} |
|
242 |
pthread_mutex_unlock(&_jobmux); |
243 |
|
|
244 |
BSONObjBuilder b; |
245 |
b.append(key,1); |
|
246 |
if(!val.empty()){ |
247 |
b.append(val,1); |
|
248 |
} |
249 |
|
|
250 |
BSONObj p=b.obj(); |
251 |
|
|
252 |
pthread_mutex_lock(&_dbmux); |
253 |
auto_ptr<DBClientCursor> cursor = it->first->query(doc,Query(),0,0,&p); |
|
254 |
while(cursor->more()){ |
255 |
BSONObj ob=cursor->next(); |
||
256 |
rout[ob.getStringField(key.c_str())]=ob.getStringField(val.c_str()); |
257 |
} |
|
258 |
pthread_mutex_unlock(&_dbmux); |
259 |
|
|
260 |
pthread_mutex_lock(&_jobmux); |
261 |
it->second=false; |
|
262 |
pthread_mutex_unlock(&_jobmux); |
263 |
sem_post(&_jobsem); |
|
264 |
|
265 |
return RET_OK; |
|
266 |
} |
267 |
//dumpkey key对应多个value |
|
268 |
//key->map<key,value>. |
269 |
//其实dumpvals接口完全可以包含dumpkey,为了方便运用独立出来 |
|
270 |
//out 返回的key 对应的map<key,value> |
271 |
//in 每个key需要对应的返回哪些字段 |
|
272 |
//key="id" |
273 |
int cmongo::dumpvals(map< string,map<string,string> >& rout,vector<string> in,string key){ |
|
274 |
if(key.empty()){ |
275 |
return RET_PARERR; |
|
276 |
} |
277 |
sem_wait(&_jobsem); |
|
278 |
pthread_mutex_lock(&_jobmux); |
279 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
|
280 |
while(it!=_joblst.end()){ |
281 |
if(it->second == false){ |
|
282 |
it->second=true; |
283 |
break; |
|
284 |
} |
285 |
it++; |
|
286 |
} |
287 |
pthread_mutex_unlock(&_jobmux); |
|
288 |
|
289 |
BSONObjBuilder b; |
|
290 |
b.append(key,1); |
291 |
for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){ |
|
292 |
b.append(*iter,1); |
293 |
} |
|
294 |
|
295 |
BSONObj p=b.obj(); |
|
296 |
|
297 |
pthread_mutex_lock(&_dbmux); |
|
298 |
auto_ptr<DBClientCursor> cursor = it->first->query(doc,Query(),0,0,&p); |
299 |
while(cursor->more()){ |
|
300 |
BSONObj ob=cursor->next(); |
301 |
map<string,string> temp; |
|
302 |
for(vector<string>::iterator iter=in.begin();iter!=in.end();++iter){ |
303 |
string val=*iter; |
|
304 |
temp[val]=ob.getStringField(val.c_str()); |
305 |
} |
|
306 |
rout[ob.getStringField(key.c_str())]=temp; |
307 |
temp.clear(); |
|
308 |
} |
309 |
pthread_mutex_unlock(&_dbmux); |
|
310 |
|
311 |
pthread_mutex_lock(&_jobmux); |
|
312 |
it->second=false; |
313 |
pthread_mutex_unlock(&_jobmux); |
|
314 |
sem_post(&_jobsem); |
315 |
|
|
316 |
return RET_OK; |
317 |
} |
|
318 |
//更新接口,暂不支持key对应多条记录的更新 |
319 |
int cmongo::set(map<string,string> in,string key,string key_val){ |
|
320 |
//如果map没有数据,返回参数错误 |
321 |
if(in.size()<=0 || key.empty() || key_val.empty()){ |
|
322 |
return RET_PARERR; |
323 |
} |
|
324 |
BSONObjBuilder b; |
325 |
map<string,string>::iterator iter; |
|
326 |
for(iter=in.begin();iter!=in.end();++iter){ |
327 |
b.append(iter->first,iter->second); |
|
328 |
} |
329 |
|
|
330 |
sem_wait(&_jobsem); |
331 |
pthread_mutex_lock(&_jobmux); |
|
332 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
333 |
while(it!=_joblst.end()){ |
|
334 |
if(it->second == false){ |
335 |
it->second=true; |
|
336 |
break; |
337 |
} |
|
338 |
it++; |
339 |
} |
|
340 |
pthread_mutex_unlock(&_jobmux); |
341 |
BSONObj ob=b.obj(); |
||
342 |
it->first->update(doc,QUERY(key<<key_val),BSON("$set"<<ob),true); |
343 |
|
|
344 |
int ret=RET_OK; |
345 |
string errmsg=it->first->getLastError(); |
|
346 |
if(!errmsg.empty()){ |
347 |
ret=RET_ERR; |
|
348 |
} |
349 |
|
|
350 |
pthread_mutex_lock(&_jobmux); |
351 |
it->second=false; |
|
352 |
pthread_mutex_unlock(&_jobmux); |
353 |
sem_post(&_jobsem); |
|
354 |
|
355 |
return ret; |
|
356 |
} |
357 |
//更新接口,批量更新key="id" |
|
358 |
// "123456":<key,value>,<key,value> |
359 |
// "123457":<key,value>,<key,value> |
|
360 |
int cmongo::sets(map< string,map<string,string> > in,string key){ |
361 |
//如果map没有数据,返回参数错误 |
|
362 |
if(in.size()<=0 || key.empty() ){ |
363 |
return RET_PARERR; |
|
364 |
} |
365 |
|
|
366 |
sem_wait(&_jobsem); |
367 |
pthread_mutex_lock(&_jobmux); |
|
368 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
369 |
while(it!=_joblst.end()){ |
|
370 |
if(it->second == false){ |
371 |
it->second=true; |
|
372 |
break; |
373 |
} |
|
374 |
it++; |
375 |
} |
|
376 |
pthread_mutex_unlock(&_jobmux); |
377 |
|
|
378 |
int ret=RET_OK; |
379 |
map< string,map<string,string> >::iterator iter; |
|
380 |
for(iter=in.begin();iter!=in.end();++iter){ |
381 |
BSONObjBuilder b; |
|
382 |
for(map<string,string>::iterator iter2=iter->second.begin();iter2!=iter->second.end();++iter2){ |
383 |
b.append(iter2->first,iter2->second); |
|
384 |
} |
385 |
BSONObj ob=b.obj(); |
||
386 |
it->first->update(doc,QUERY(key<<iter->first),BSON("$set"<<ob),true); |
387 |
string errmsg=it->first->getLastError(); |
|
388 |
if(!errmsg.empty()){ |
389 |
ret=RET_ERR; |
|
390 |
} |
391 |
} |
|
392 |
|
393 |
|
|
394 |
pthread_mutex_lock(&_jobmux); |
395 |
it->second=false; |
|
396 |
pthread_mutex_unlock(&_jobmux); |
397 |
sem_post(&_jobsem); |
|
398 |
|
399 |
return ret; |
|
400 |
} |
401 |
//删除接口,删除记录 key=id key_val=587.即删除id="587"的记录 |
|
402 |
int cmongo::remove(string key,string key_val){ |
403 |
|
|
404 |
if(key.empty() || key_val.empty()){ |
405 |
return RET_PARERR; |
|
406 |
} |
407 |
sem_wait(&_jobsem); |
|
408 |
pthread_mutex_lock(&_jobmux); |
409 |
map<DBClientConnection*,bool>::iterator it=_joblst.begin(); |
|
410 |
while(it!=_joblst.end()){ |
411 |
if(it->second == false){ |
|
412 |
it->second=true; |
413 |
break; |
|
414 |
} |
415 |
it++; |
|
416 |
} |
417 |
pthread_mutex_unlock(&_jobmux); |
|
418 |
|
419 |
it->first->remove(doc,BSON(key << key_val)); |
|
420 |
|
421 |
pthread_mutex_lock(&_jobmux); |
|
422 |
it->second=false; |
423 |
pthread_mutex_unlock(&_jobmux); |
|
424 |
sem_post(&_jobsem); |
425 |
|
|
426 |
return RET_OK; |
427 |
} |