用newlisp通过C++动态库访问MongoDB

我想让我的newlisp程序访问MongoDB. 现在已经有MongoDB C driver,但是我没有时间去学习,只想尽快的完成工作。下面是我的方法,用C++创建一个动态库,这个动态库引用了MongoDB C++ driver. 但是会用extern "C" 导出C函数。

一件事情必须知道,MongoDB C++ driver必须用-fPIC选项编译。

首先,创建db.h文件

extern "C" void CheckOnline();
extern "C" void Init(char * mongo_uri);

然后编辑db.cc文件

#include "db.h"
#include <stdlib.h>
#include <ctype.h>
#include <iostream>
#include "mongo_session_factory.h"
#include "mongo_session.h"
#include <mongo/bson/bsonobj.h>
#include <mongo/bson/bsonobjbuilder.h>
using namespace std;
class Config {
public:
  string mongo_uri;
};
Config config;
void SetOffline(mongo::DBClientBase& con, mongo::OID const& id) {
  mongo::BSONObjBuilder condition;
  condition.append("_id", id);
  mongo::BSONObjBuilder update_field;
  update_field.append("status", "offline");
  mongo::BSONObjBuilder set_field;
  set_field.append("$set", update_field.obj());
  con.update("kaimei.display", mongo::Query(condition.obj()), set_field.obj());
}
/**
 * Check every sign status
 */
void CheckOnline() {
  cout << config.mongo_uri << endl;
  std::shared_ptr<MongoSession> session = MongoSessionFactory::GetSession(config.mongo_uri);
  mongo::DBClientBase & con = session->get_db_client_base();
  mongo::BSONObjBuilder condition;
  std::unique_ptr<mongo::DBClientCursor> cursor = con.query("kaimei.display", mongo::Query(condition.obj()));
  while (cursor->more()) {
    mongo::BSONObj record = cursor->next();
    uint64_t t1 = record.getField("last_active_time").numberLong();
    timeval tv;
    gettimeofday(&tv,NULL);
    if (tv.tv_sec - t1 > 300) {
      SetOffline(con, record.getField("_id").OID());
    }
  }
}

void Init(char * mongo_uri) {
  config.mongo_uri = mongo_uri;
}

在include 和 src目录下,有一些辅助类被称为MongoSessionFactory和MongoSession。他们帮助建立和MongoDB server的连接(ReplicaSet 和 Single server)

好了,现在编译吧,参考build.lsp文件

#!/usr/bin/newlisp
(if (file? "db.so")
    (delete-file "db.so"))
(if (directory? "objects")
    (exec "rm -rf objects"))
(make-dir "objects")
(exec "c++ -g -fPIC -std=c++11 -I./include  -Wall -o ./objects/mongo_session_factory.cc.o -c ./src/mongo_session_factory.cc")
(exec "c++ -g -fPIC -std=c++11 -I./include  -Wall -o ./objects/mongo_session.cc.o -c ./src/mongo_session.cc")
(exec "c++ -g -fPIC -std=c++11 -I./include  -Wall -o ./objects/db.cc.o -c ./src/db.cc")
(exec "c++ -g -fPIC -std=c++11 ./objects/mongo_session_factory.cc.o ./objects/mongo_session.cc.o ./objects/db.cc.o -shared -o db.so -rdynamic -lpthread -lmongoclient -lboost_system -lboost_thread -lboost_filesystem")
(exit)

编译成功后,写一个check.lsp文件用来使用db.so库。

#!/usr/bin/newlisp 

(set 'db-path "/path/to/your/db.so")
(import db-path "Init")
(import db-path "CheckOnline")
(Init "localhost:27017")
(CheckOnline)
(exit)

这就完了。可以运行了。



你可能感兴趣的:(用newlisp通过C++动态库访问MongoDB)