Вот код. Я постарался выбросить все лишнее.
Код: Выделить всё
// db_extphp.cpp
//
#include <Qt/qglobal.h>
#include <QMap>
#include <QString>
#include "lib_db.h"//the CDb object is defined in this library
#ifdef DB_EXT_LIB
# define DB_EXT_EXPORT Q_DECL_EXPORT
#else
# define DB_EXT_EXPORT Q_DECL_IMPORT
#endif
//constants to export
#define DB_EXT_RETURN_VALUE "ReturnValue"
#define DB_EXT_ERROR_DESCRIPTION "ErrorDescription"
class DB_EXT_EXPORT CSelector : public QObject
{
Q_OBJECT
public:
CSelector(){};
~CSelector(){};
QMutex m_mutexDelete;
CDb m_objDB;//logic is in this object
};
class DB_EXT_EXPORT CConnections : public QObject
{
Q_OBJECT
public:
CConnections(){};
~CConnections();
long GetSessionID(char *sUser, char *sPswd, char *sDBHost, long nPort, char *sError);
QMutex m_mutexUseMap;
QMap<long,CSelector *> m_mapSessions;
};
CConnections::~CConnections()
{
QMap<long,CSelector *>::iterator pos;
for(pos=m_mapSessions.begin(); pos != m_mapSessions.end();)
{
try{
pos.value()->m_objDB.logoff();
}
catch(...){
}
try{
delete pos.value();
}
catch(...){
}
pos = m_mapSessions.erase(pos);
}
}
long CConnections::GetSessionID(char *sUser, char *sPswd, char *sDBHost, long nPort, char *sError)
{
long i,nID=0;
CSelector *pSelector=NULL;
pSelector=new CSelector;//new CDb object is created here
if(pSelector)
{
if(pSelector->m_objDB.login(sUser, sPswd, sDBHost, nPort))
{
nID = (long)time(NULL) * 0x9e3779b9;//create session code
for(i=0;i<2048;++i,++nID)
if(m_mapSessions.find(nID) == m_mapSessions.end())
break;
if(i<2048)
{
m_mutexUseMap.lock();
m_mapSessions.insert(nID, pSelector);
m_mutexUseMap.unlock();
}
else
{
nID=0;
delete pSelector;
strcpy(sError,"Too many open connections.");
}
}
else
{
strncpy(sError,pSelector->m_objDB.getLastError().toAscii().data(),255);
delete pSelector;
}
}
else
{
strcpy(sError,"Not enough memory.");
}
return nID;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
CConnections g_Connections;
#define GET_SELECTOR CSelector *pSelector=NULL;\
g_Connections.m_mutexUseMap.lock();\
pSelector = g_Connections.m_mapSessions.value(nSessionID);\
if(!pSelector){\
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong session ID.",1);\
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);\
g_Connections.m_mutexUseMap.unlock();\
return;\
}\
\
QMutexLocker locker(&pSelector->m_mutexDelete);\
g_Connections.m_mutexUseMap.unlock();\
\
#include "php.h"
ZEND_MODULE_STARTUP_D(DB_EXTPHP);
ZEND_MODULE_SHUTDOWN_D(DB_EXTPHP);
ZEND_FUNCTION(dbLogin);
ZEND_FUNCTION(dbLogout);
ZEND_FUNCTION(dbResetDataFields);
/* compiled function list so Zend knows what's in this module */
zend_function_entry DB_EXTPHP_functions[] = {
ZEND_FE(dbLogin, NULL)
ZEND_FE(dbLogout, NULL)
ZEND_FE(dbResetDataFields, NULL)
{NULL, NULL, NULL}
};
/* compiled module information */
zend_module_entry DB_EXTPHP_module_entry = {
STANDARD_MODULE_HEADER,
"DB_EXTPHP",
DB_EXTPHP_functions,
ZEND_MODULE_STARTUP_N(DB_EXTPHP),
ZEND_MODULE_SHUTDOWN_N(DB_EXTPHP),
NULL, NULL, NULL,
NO_VERSION_YET, STANDARD_MODULE_PROPERTIES
};
/* implement standard "stub" routine to introduce ourselves to Zend */
ZEND_GET_MODULE(DB_EXTPHP)
ZEND_MODULE_STARTUP_D(DB_EXTPHP)
{
REGISTER_STRING_CONSTANT("DB_EXT_ERROR_DESCRIPTION", DB_EXT_ERROR_DESCRIPTION, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("DB_EXT_RETURN_VALUE", DB_EXT_RETURN_VALUE, CONST_CS | CONST_PERSISTENT);
return SUCCESS;
}
ZEND_MODULE_SHUTDOWN_D(DB_EXTPHP)
{
return SUCCESS;
}
ZEND_FUNCTION(dbLogin){
char *sUser=NULL;
char *sPswd=NULL;//password
char *sDBHost=NULL;
long nUser;
long nDPswd;
long nDBHost;
long nPort;
long nSessionID;
char sError[256];
zval *pzResource;
CSelector *pSelector=NULL;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssll",
&sUser, &nUser, &sPswd, &nDPswd, &sDBHost, &nDBHost, &nPort) == FAILURE){
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong parameters passed to the function.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
if(!(nSessionID = g_Connections.GetSessionID(sUser,sPswd,sDBHost,nPort,sError))){
sError[255]=0;
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,sError,1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"No error.",1);
add_assoc_long(return_value,DB_EXT_RETURN_VALUE,nSessionID);
}
}
}
ZEND_FUNCTION(dbLogout){
long nSessionID;
CSelector *pSelector=NULL;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &nSessionID) == FAILURE){
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong parameters passed to the function.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
g_Connections.m_mutexUseMap.lock();
pSelector = g_Connections.m_mapSessions.value(nSessionID);
g_Connections.m_mapSessions.remove(nSessionID);
g_Connections.m_mutexUseMap.unlock();
if(pSelector){
pSelector->m_objDB.logoff();
delete pSelector;
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"No error.",1);
add_assoc_long(return_value,DB_EXT_RETURN_VALUE,1);
}
else{
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong session ID.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
}
}
ZEND_FUNCTION(dbResetDataFields){
long nSessionID;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &nSessionID) == FAILURE){
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"Wrong parameters passed to the function.",1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
return;//wrong parameters passed
}
//
GET_SELECTOR
//
pSelector->m_objDB.resetDBExtraction();
if(!pSelector->m_objDB.getLastError().isEmpty()){
char sError[256];
sError[255]=0;
strncpy(sError,pSelector->m_objDB.getLastError().toAscii().data(),255);
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,sError,1);
add_assoc_unset(return_value,DB_EXT_RETURN_VALUE);
}
else{
add_assoc_string(return_value,DB_EXT_ERROR_DESCRIPTION,"No error.",1);
add_assoc_long(return_value,DB_EXT_RETURN_VALUE,1);
}
}
А вот как я собирался использовать.