-
Notifications
You must be signed in to change notification settings - Fork 58
/
waMysqlClient.cpp
308 lines (267 loc) · 7.24 KB
/
waMysqlClient.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
/// \file waMysqlClient.cpp
/// webapp::MysqlClient,webapp::MysqlData类实现文件
// 编译参数:
// (CC) -I /usr/local/include/mysql/ -L /usr/local/lib/mysql -lmysqlclient -lm
#include <cstring>
#include "waMysqlClient.h"
using namespace std;
/// Web Application Library namaspace
namespace webapp {
/// \ingroup waMysqlClient
/// \fn string escape_sql( const string &str )
/// SQL语句字符转义
/// \param 要转换的SQL字符串
/// \return 转义过的字符串
string escape_sql( const string &str ) {
char *p = new char[str.length()*2+1];
mysql_escape_string( p, str.c_str(), str.length() );
string s = p;
delete[] p;
return s;
}
////////////////////////////////////////////////////////////////////////////
// MysqlData
/// MysqlData析构函数
MysqlData::~MysqlData() {
if ( _mysqlres != NULL )
mysql_free_result( _mysqlres );
_mysqlres = 0;
_mysqlfields = 0;
}
/// 返回指定位置的MysqlData数据
/// \param row 数据行位置,默认为0
/// \param col 数据列位置,默认为0
/// \return 返回数据,不存在则返回空字符串
string MysqlData::get_data( const size_t row, const size_t col ) {
if( _mysqlres!=NULL && row<_rows && col<_cols ) {
if ( row != _fetched ) {
if ( row != _curpos+1 ) {
mysql_data_seek( _mysqlres, row );
}
_mysqlrow = mysql_fetch_row( _mysqlres );
_fetched = row;
}
if ( _mysqlrow!=NULL && _mysqlrow[col]!=NULL ) {
_curpos = row; // log current cursor
return string( _mysqlrow[col] );
}
}
return string( "" );
}
/// 返回指定字段的MysqlData数据
/// \param row 行位置
/// \param field 字段名
/// \return 数据字符串,不存在返回空字符串
string MysqlData::get_data( const size_t row, const string &field ) {
int col = this->field_pos( field );
if ( col != -1 )
return this->get_data( row, col );
else
return string( "" );
}
/// 返回指定位置的MysqlData数据行
/// \param row 数据行位置,默认为0即第一行
/// \return 返回值类型为MysqlDataRow,即map<string,string>
MysqlDataRow MysqlData::get_row( const size_t row ) {
MysqlDataRow datarow;
string field;
if( _mysqlres!=NULL && row<_rows ) {
if ( row != _curpos ) {
if ( row != _curpos+1 ) {
mysql_data_seek( _mysqlres, row );
}
_mysqlrow = mysql_fetch_row( _mysqlres );
}
if ( _mysqlrow != NULL ) {
_curpos = row; // log current cursor
for ( size_t i=0; i<_cols; ++i ) {
field = this->field_name( i );
if ( field!="" && _mysqlrow[i]!=NULL ) {
datarow.insert( MysqlDataRow::value_type(field,_mysqlrow[i]) );
}
}
}
}
return datarow;
}
/// 填充MysqlData数据
/// \param mysql MYSQL*参数
/// \retval true 成功
/// \retval false 失败
bool MysqlData::fill_data( MYSQL *mysql ) {
if ( mysql == NULL )
return false;
// clean
if ( _mysqlres != NULL )
mysql_free_result( _mysqlres );
_mysqlres = 0;
_curpos = 0; // return to first position
_field_pos.clear(); // clean field pos cache
// fill data
_mysqlres = mysql_store_result( mysql );
if ( _mysqlres != NULL ) {
_rows = mysql_num_rows( _mysqlres );
_cols = mysql_num_fields( _mysqlres );
_mysqlfields = mysql_fetch_fields( _mysqlres );
// init first data
mysql_data_seek( _mysqlres, 0 );
_mysqlrow = mysql_fetch_row( _mysqlres );
_fetched = 0;
return true;
}
return false;
}
/// 返回字段位置
/// \param field 字段名
/// \return 若数据结果中存在该字段则返回字段位置,否则返回-1
int MysqlData::field_pos( const string &field ) {
if ( _mysqlfields==0 || field=="" )
return -1;
// check cache
if ( _field_pos.find(field) != _field_pos.end() )
return _field_pos[field];
for( size_t i=0; i<_cols; ++i ) {
if ( strcmp(field.c_str(),_mysqlfields[i].name) == 0 ) {
_field_pos[field] = i;
return i;
}
}
_field_pos[field] = -1;
return -1;
}
/// 返回字段名称
/// \param col 字段位置
/// \return 若数据结果中存在该字段则返回字段名称,否则返回空字符串
string MysqlData::field_name( size_t col ) const {
if ( _mysqlfields!=0 && col<=_cols )
return string( _mysqlfields[col].name );
else
return string( "" );
}
////////////////////////////////////////////////////////////////////////////
// MysqlClient
/// 连接数据库
/// \param host MySQL主机IP
/// \param user MySQL用户名
/// \param pwd 用户口令
/// \param database 要打开的数据库
/// \param port 数据库端口,默认为0
/// \param socket UNIX_SOCKET,默认为NULL
/// \retval true 成功
/// \retval false 失败
bool MysqlClient::connect( const string &host, const string &user, const string &pwd,
const string &database, const int port, const char* socket )
{
this->disconnect();
if ( mysql_init(&_mysql) ) {
if ( mysql_real_connect( &_mysql, host.c_str(), user.c_str(),
pwd.c_str(), database.c_str(), port, socket, CLIENT_COMPRESS ) )
_connected = true;
}
return _connected;
}
/// 断开数据库连接
void MysqlClient::disconnect() {
if( _connected ) {
mysql_close( &_mysql );
_connected = false;
}
}
/// 判断是否连接数据库
/// \retval true 连接
/// \retval false 断开
bool MysqlClient::is_connected() {
if ( _connected ) {
if ( mysql_ping(&_mysql) == 0 )
_connected = true;
else
_connected = false;
}
return _connected;
}
/// 选择数据库
/// \param database 数据库名
/// \retval true 成功
/// \retval false 失败
bool MysqlClient::select_db( const string &database ) {
if ( _connected && mysql_select_db(&_mysql,database.c_str())==0 )
return true;
else
return false;
}
/// 执行SQL语句,取得查询结果
/// \param sqlstr 要执行的SQL语句
/// \param records 保存数据结果的MysqlData对象
/// \retval true 成功
/// \retval false 失败
bool MysqlClient::query( const string &sqlstr, MysqlData &records ) {
if ( _connected && mysql_real_query(&_mysql,sqlstr.c_str(),sqlstr.length())==0 ) {
if( records.fill_data(&_mysql) )
return true;
}
return false;
}
/// 执行SQL语句
/// \param sqlstr 要执行的SQL语句
/// \retval true 成功
/// \retval false 失败
bool MysqlClient::query( const string &sqlstr ) {
if ( _connected && mysql_real_query(&_mysql,sqlstr.c_str(),sqlstr.length())==0 )
return true;
else
return false;
}
/// 返回查询结果中指定位置的字符串值
/// \param sqlstr SQL查询字符串
/// \param row 数据行位置,默认为0
/// \param col 数据列位置,默认为0
/// \return 查询成功返回字符串,否则返回空字符串
string MysqlClient::query_val( const string &sqlstr, const size_t row,
const size_t col )
{
MysqlData data;
if ( this->query(sqlstr,data) ) {
if ( data.rows()>row && data.cols()>col )
return data(row,col);
}
return string( "" );
}
/// 返回查询结果中指定行
/// \param sqlstr SQL查询字符串
/// \param row 数据行位置,默认为0
/// \return 返回值类型为MysqlDataRow,即map<string,string>
MysqlDataRow MysqlClient::query_row( const string &sqlstr, const size_t row ) {
MysqlData data;
MysqlDataRow datarow;
if ( this->query(sqlstr,data) ) {
if ( row < data.rows() )
datarow = data.get_row( row );
}
return datarow;
}
/// 上次查询动作所影响的记录条数
/// \return 返回记录条数,类型size_t
size_t MysqlClient::affected() {
if ( _connected )
return mysql_affected_rows( &_mysql );
else
return 0;
}
/// 取得上次查询的一个AUTO_INCREMENT列生成的ID
/// 一个Mysql表只能有一个AUTO_INCREMENT列,且必须为索引
/// \return 返回生成的ID
size_t MysqlClient::last_id() {
if ( _connected )
return mysql_insert_id( &_mysql );
else
return 0;
}
/// 取得更新信息
/// \return 返回更新信息
string MysqlClient::info() {
if ( _connected )
return string( mysql_info(&_mysql) );
else
return string( "" );
}
} // namespace