-
之前有好多人在为这件事情头疼不已:
想有一个不需要安装mysql客户端就可以导入数据库脚本,但找不到对应的api调用。所以得需要自己去实现导入数据库的实现方法:
common.h
01.
#ifndef _COMMON_H
02.
#define _COMMON_H
03.
#ifdef WIN32
04.
05.
#include <winsock2.h>
06.
07.
typedef __int8 int8_t;
08.
typedef __int16 int16_t;
09.
typedef __int32 int32_t;
10.
typedef __int64 int64_t;
11.
12.
typedef unsigned __int8 uint8_t;
13.
typedef unsigned __int16 uint16_t;
14.
typedef unsigned __int32 uint32_t;
15.
typedef unsigned __int64 uint64_t;
16.
17.
#define atoll(_String) \
18.
_atoi64(_String)
19.
#
else
20.
#include <sys/types.h>
21.
#include <sys/socket.h>
22.
#include <stdint.h>
23.
#include<linux/string.h>
24.
#endif
25.
#include <stdlib.h>
26.
#include <stdio.h>
27.
#include <string>
28.
#include <vector>
29.
#include <map>
30.
#include <set>
31.
#include <list>
32.
using namespace std;
33.
enum
SERVER_ACTION{
34.
SERVER_STARTNEW =
0
,
//开新服
35.
};
36.
#ifdef WIN32
37.
#define PATH_DELIMTER
"\\"
38.
#
else
39.
#define PATH_DELIMTER
"/"
40.
#endif
41.
#endif
dbmanager.h01.
#ifndef _DBMANAGER_H
02.
#define _DBMANAGER_H
03.
#include <string>
04.
using namespace std;
05.
#include
"common.h"
06.
#include <mysql.h>
07.
//数据库配置信息
08.
struct DBInfo
09.
{
10.
string host;
11.
string user;
12.
string passwd;
13.
string db;
14.
uint16_t port;
15.
};
16.
class
DBManager
17.
{
18.
public
:
19.
DBManager();
20.
~DBManager();
21.
22.
bool SelectDB(string dbName);
23.
bool ConnectDB(DBInfo &dbInfo);
24.
MYSQL_RES* ExeSql(
const
char
* sql,
int
len);
25.
bool readFromSql(string fileName,vector<string>& sql);
26.
bool sourceSql(string fileName);
27.
private
:
28.
MYSQL *mysqlInit(DBInfo &info);
29.
void
mysqlClose();
30.
private
:
31.
MYSQL *m_mysqlConn;
32.
DBInfo m_dbConfig;
33.
};
34.
35.
36.
extern DBManager g_DBManager;
37.
38.
39.
40.
41.
42.
43.
44.
45.
#endif
dbmanager.cpp001.
#include
"dbmanager.h"
002.
#include <fstream>
003.
DBManager g_DBManager;
004.
DBManager::DBManager()
005.
{
006.
}
007.
DBManager::~DBManager()
008.
{
009.
}
010.
bool DBManager::ConnectDB(DBInfo &dbInfo)
011.
{
012.
m_dbConfig = dbInfo;
013.
m_mysqlConn = mysqlInit(dbInfo);
014.
if
(!m_mysqlConn)
015.
{
016.
return
false
;
017.
}
018.
return
true
;
019.
}
020.
021.
MYSQL *DBManager::mysqlInit(DBInfo &info)
022.
{
023.
MYSQL *mysql = mysql_init(NULL);
024.
if
(!mysql)
025.
return
NULL;
026.
027.
if
(!mysql_real_connect(mysql,
028.
info.host.c_str(),
029.
info.user.c_str(),
030.
info.passwd.c_str(),
031.
info.db.c_str(),
032.
info.port, NULL,
0
))
033.
{
034.
int
ret = mysql_errno(mysql);
035.
036.
mysql_close(mysql);
037.
return
NULL;
038.
}
039.
040.
#
if
MYSQL_VERSION_ID >=
50013
041.
my_bool reconnect =
1
;
042.
if
(mysql_options(mysql, MYSQL_OPT_RECONNECT, &reconnect))
043.
{
044.
int
ret = mysql_errno(mysql);
045.
046.
mysql_close(mysql);
047.
return
NULL;
048.
}
049.
#
else
050.
mysql->reconnect =
1
;
051.
#endif
052.
053.
054.
return
mysql;
055.
}
056.
057.
void
DBManager::mysqlClose()
058.
{
059.
if
(m_mysqlConn)
060.
{
061.
mysql_close(m_mysqlConn);
062.
m_mysqlConn = NULL;
063.
}
064.
}
065.
/************************************************************************/
066.
/* 执行SQL语句 */
067.
/************************************************************************/
068.
MYSQL_RES* DBManager::ExeSql(
const
char
* sql,
int
len)
069.
{
070.
MYSQL_RES* res = NULL;
071.
int
ret = mysql_real_query(m_mysqlConn, sql, len);
072.
if
(ret ==
0
)
073.
{
074.
res = mysql_store_result(m_mysqlConn);
075.
}
else
{
076.
printf(
"mysql query %s return errorcode:%d\n"
,sql, mysql_errno(m_mysqlConn));
077.
}
078.
return
res;
079.
}
080.
/************************************************************************/
081.
/* 选择数据库 */
082.
/************************************************************************/
083.
bool DBManager::SelectDB(string dbName)
084.
{
085.
if
(mysql_select_db(m_mysqlConn,dbName.c_str()))
086.
return
false
;
087.
else
088.
return
true
;
089.
}
090.
/************************************************************************/
091.
/*fileName是sql文件的路径, 解析出fileName中的每一条sql语句,放入到sql容器中 */
092.
/************************************************************************/
093.
bool DBManager::readFromSql(string fileName,vector<string>& sql){
094.
ifstream in(fileName.c_str(), ios::in);
//linux
095.
string signalSql,s;
096.
if
(!in){
097.
return
false
;
098.
}
099.
while
(getline(in,s)){
100.
int
pos = s.find(
";"
);
101.
signalSql += s;
102.
if
(pos != s.npos){
//找到了一条语句的结束位
103.
sql.push_back(signalSql);
104.
signalSql.clear();
105.
}
106.
s.clear();
107.
}
108.
in.close();
109.
return
true
;
110.
}
111.
/************************************************************************/
112.
/* 导入数据库sql */
113.
/************************************************************************/
114.
bool DBManager::sourceSql(string fileName){
115.
vector<string> vecSql;
116.
bool ret = readFromSql(fileName,vecSql);
117.
if
(ret ==
false
){
118.
printf(
"导入gamedb.sql失败"
);
119.
return
false
;
120.
}
121.
for
(vector<string>::iterator it = vecSql.begin(); it != vecSql.end(); it++)
122.
{
123.
ExeSql((*it).c_str(), (*it).length());
124.
}
125.
return
true
;
126.
}
我这里的source实现其实就是把sql脚本里的记录按行读取,如果遇到了一个分号,表示已经是一个语句了,把它放到一个sql语句的容器中,不知道还有没有别人有更好的方法,希望可以在这里交流,并留下你们的代码
FROM: http://www.it165.net/database/html/201502/10729.html