C++でPython3を呼び出してSqliteデータベースにアクセスする
1.SqliteEngine.py
import sqlite3 #モジュールをインポート
class SqliteEngine:
def __init__(self,db_name):
self.db_name = db_name
try:
self.conn = sqlite3.connect(db_name)#データベースに接続する
self.cur = self.conn.cursor()
print(“db:" + db_name + “open succeed!")
except Exception as err:
print(str(err))
def close(self):
try:
self.conn.close()
print(“close db")
except Exception as err:
print(str(err))
def query(self,sql):
try:
self.cur = self.conn.cursor()
self.cur.execute(sql)
print('['+sql+’]’ + “success")
return self.get_recodeset(self.cur)
except Exception as err:
print(str(err))
return None
def exec(self,sql):
try:
self.cur = self.conn.cursor()
self.cur.execute(sql)
self.conn.commit()
print('['+sql+’]’ + “success")
return 0
except Exception as err:
self.conn.rollback()
print(str(err))
return -1
def get_recodeset(self,cur):
recodeset = cur.fetchall()#レコードセットを取得
field = [field_name[0] for field_name in cur.description]#レコードセットのフィールドリスト
ret_list=[]#空リスト
for each_item in recodeset:
recode_dic={};#空の辞典
col_index=0
for each_col in each_item:
key = str(field[col_index]).encode(“shift-jis","ignore")
value = str(each_col).encode(“shift-jis","ignore")
recode_dic[key] = value
col_index+=1
ret_list.append(recode_dic)
return tuple(ret_list)
"’
def strPrint(s):
print(s)
return str(s).encode(“shift-jis")
"’
2.SqliteEngine.h
#ifndef SQLITEENGINE_H_
#define SQLITEENGINE_H_
#include <Python.h>
#include <string>
#include <vector>
#include <map>
using namespace std;
typedef vector<map<string,string> > Recodeset;//レコードのクエリの結果セット
typedef map<string,string> Recode;//単一レコード
typedef Recodeset::iterator PRecodeset;
typedef Recode::iterator PRecode;
class SqliteEngine
{
public:
SqliteEngine(string py);
~SqliteEngine(void);
static bool initPython();
static bool unInitPython();
bool open(string db_name);
void close();
int query(string sql,Recodeset& Rec);
int execute(string sql);
private:
PyObject* m_pModule;
PyObject* m_pPySqlite;
string m_Py_module_name;
};
#endif //SQLITEENGINE_H_
3.SqliteEngine.cpp
#include “SqliteEngine.h"
SqliteEngine::SqliteEngine(string py)
:m_pModule(NULL),
m_pPySqlite(NULL),
m_Py_module_name(py)
{
}
SqliteEngine::~SqliteEngine()
{
SqliteEngine::unInitPython();
m_pModule = NULL;
m_pPySqlite = NULL;
}
bool SqliteEngine::initPython()
{
Py_Initialize();
//Py_IsInitializedは0を戻す、Python環境を初期化する
return Py_IsInitialized()?true:false;
}
bool SqliteEngine::unInitPython()
{
Py_Finalize();
return Py_IsInitialized()?false:true;
}
bool SqliteEngine::open(string db_name)
{
//Pythonモジュールのインポート
m_pModule = PyImport_ImportModule(m_Py_module_name.c_str());//*.py,サフィックス無し
if (!m_pModule)
{
printf(“Can not open python file!\n");
return false;
}
//SqliteEngineクラスを取得
PyObject* pClass = PyObject_GetAttrString(m_pModule,"SqliteEngine");
if (!pClass)
{
printf(“Can not find class [SqliteEng]!\n");
return false;
}
//パラメータ
PyObject* pArg = PyTuple_New(1);
PyTuple_SetItem(pArg, 0, Py_BuildValue(“s",db_name.c_str()));
//SqliteEngineの例を構成
m_pPySqlite= PyEval_CallObject(pClass,pArg);
if (!m_pPySqlite)
{
printf(“Can not find instance!\n");
return false;
}
return true;
}
void SqliteEngine::close()
{
if(!m_pPySqlite)
{
return;
}
PyObject_CallMethod(m_pPySqlite,"close",NULL);
}
int SqliteEngine::execute(string sql)
{
if(!m_pPySqlite)
{
return -1;
}
int nRet = 0;
PyObject* py_ret = PyObject_CallMethod(m_pPySqlite,"exec","s",sql);
PyArg_Parse(py_ret,"i",&nRet);
return nRet;
}
int SqliteEngine::query(string sql,Recodeset& Rec)
{
if(!m_pPySqlite)
{
return -1;
}
PyObject* tuple = PyObject_CallMethod(m_pPySqlite, “query", “s",sql.c_str() );
if(!tuple)
{
return -1;
}
Py_ssize_t tuple_size = PyTuple_Size(tuple);
PyObject* dic = NULL;
Py_ssize_t dic_pos = 0;
PyObject *_key = NULL;
PyObject *_value = NULL;
const char* c_sKey =NULL;
const char* c_sVal = NULL;
if( tuple && tuple_size>0 )
{
for(Py_ssize_t i=0;i<tuple_size;i++)
{
dic = PyTuple_GetItem(tuple,i);
dic_pos = 0;
//辞書をトラバーサル
Recode _map;
while ( PyDict_Next(dic,&dic_pos,&_key,&_value) )
{
c_sKey = PyBytes_AsString(_key);
c_sVal = PyBytes_AsString(_value);
if(c_sKey)
{
_map.insert(make_pair(c_sKey,c_sVal));
}
}
Rec.push_back(_map);
}
}
return Rec.size();
}