MySQL C API Wrapper



  • Hallo allerseits,

    ich weiß, dass es einen MySQL-Connector für C++ gibt, aber ich bin bisher damit noch nicht richtig warm geworden und habe statt dessen einen Wrapper für den MySQL-Connector für C geschrieben.

    mysql.h:

    #ifndef MYSQL_HEADER_INCLUDED
    #define MYSQL_HEADER_INCLUDED
    
    #include "mysql/mysql.h"
    
    #include <string>
    #include <map>
    
    typedef int MySQLQuery;
    typedef MYSQL_RES MySQLRes;
    typedef std::map<MySQLQuery,MySQLRes*> MySQLResMap;
    typedef MYSQL_ROW MySQLRow;
    
    class MySQL
    {
    	private:
    	MYSQL* m_instance;
    	MySQLResMap m_resmap;
    
    	public:
    	MySQL();
    	~MySQL();
    
    	bool Connect(const std::string& host,unsigned int port,const std::string& user,const std::string& pw,const std::string& db);
    	MySQLQuery Query(const std::string& query);
    	int NumRows(MySQLQuery query) const;
    	int NumCols(MySQLQuery query) const;
    	MySQLRow FetchRow(MySQLQuery query) const;
    	void FreeResult(MySQLQuery query);
    	void Free(MySQLQuery query);
    	void Close();
    	void Destroy();
    };
    
    #endif
    

    mysql.cpp:

    #include "mysql.h"
    
    #ifdef WIN
    #pragma comment(lib,"libmysql.lib")
    #endif
    
    MySQL::MySQL()
    {
    	m_instance = 0;
    }
    
    MySQL::~MySQL()
    {
    	Close();
    }
    
    bool MySQL::Connect(const std::string& host,unsigned int port,const std::string& user,const std::string& pw,const std::string& db)
    {
    	if (!m_instance) m_instance = mysql_init(0);
    	return mysql_real_connect(m_instance,host.c_str(),user.c_str(),pw.c_str(),db.c_str(),port,0,CLIENT_COMPRESS);
    }
    
    MySQLQuery MySQL::Query(const std::string& query)
    {
    	MySQLQuery result = mysql_query(m_instance,query.c_str());
    	m_resmap[result] = mysql_store_result(m_instance);
    	return result;
    }
    
    int MySQL::NumRows(MySQLQuery query) const
    {
    	MySQLResMap::const_iterator it = m_resmap.find(query);
    	if (it == m_resmap.end()) return -1;
    	return mysql_num_rows(it->second);
    }
    
    int MySQL::NumCols(MySQLQuery query) const
    {
    	MySQLResMap::const_iterator it = m_resmap.find(query);
    	if (it == m_resmap.end()) return -1;
    	return mysql_num_fields(it->second);
    }
    
    MySQLRow MySQL::FetchRow(MySQLQuery query) const
    {
    	MySQLResMap::const_iterator it = m_resmap.find(query);
    	if (it == m_resmap.end()) return 0;
    	return (MySQLRow)mysql_fetch_row(it->second);
    }
    
    void MySQL::FreeResult(MySQLQuery query)
    {
    	MySQLResMap::iterator it = m_resmap.find(query);
    	if (it == m_resmap.end()) return;
    	mysql_free_result(it->second);
    	m_resmap.erase(it);
    }
    
    void MySQL::Free(MySQLQuery query)
    {
    	FreeResult(query);
    }
    
    void MySQL::Close()
    {
    	if (m_resmap.size())
    	{
    		MySQLResMap::iterator it;
    		for (it = m_resmap.begin(); it != m_resmap.end(); it++) mysql_free_result(it->second);
    		m_resmap.clear();
    	}
    	if (m_instance) mysql_close(m_instance);
    	m_instance = 0;
    }
    
    void MySQL::Destroy()
    {
    	delete this;
    }
    

    Das Problem:

    Momentan knallt es leider in allen drei const-Methoden, also zb. bei MySQL::NumRows.

    Der Fehler ist ein Speicherzugriffsfehler und tritt bei NumRows beim Aufruf der Funktion mysql_num_rows auf.

    Ich habe das Gefühl, dass ich mit der std::map irgendwas falsch mache, aber ich komme nicht drauf ...

    LG Max



  • Ok, kein Wunder - habs gelöst.

    Ich ging fest davon aus, dass mein MySQL::Connect erfolgreich war - leider nein und, weil ich nie abgefragt hatte, ob die Verbindung überhaupt steht, ein unerwartetes Verhalten.

    Also werde ich jetzt noch eine bool m_connected; einbauen und fleißig abfragen 🙂

    LG Max


Anmelden zum Antworten