std::vector<Device *> ControllerDatabaseFactory::fetchDevices( const std::size_t id ) const { std::vector<Device *> devices; DatabaseStatement * statement; DatabaseResult * result; DatabaseResultRow * row; std::string query; std::size_t deviceId; query = "SELECT id " "FROM devices " "WHERE controller_id = "; query = query + std::to_string(id); statement = getDbConnection()->createStatement(query); if( statement != nullptr ) { result = statement->execute(); if( result != nullptr ) { while( result->hasNext() ) { row = result->next(); deviceId = static_cast<std::size_t>( atol(row->getColumn(0).c_str())); devices.push_back(mDeviceContainer->get(deviceId)); delete row; } delete result; } delete statement; } return ( devices ); }
//----------------------------------------------------------------------------- // 描述: 执行SQL (若 resultDataSet 为 NULL,则表示无数据集返回。若失败则抛出异常) //----------------------------------------------------------------------------- void MySqlQuery::doExecute(DbDataSet *resultDataSet) { /* 摘自MYSQL官方手册: Upon connection, mysql_real_connect() sets the reconnect flag (part of the MYSQL structure) to a value of 1 in versions of the API older than 5.0.3, or 0 in newer versions. A value of 1 for this flag indicates that if a statement cannot be performed because of a lost connection, to try reconnecting to the server before giving up. You can use the MYSQL_OPT_RECONNECT option to mysql_options() to control reconnection behavior. 即:只要用 mysql_real_connect() 连接到数据库(而不是 mysql_connect()),那么 在 mysql_real_query() 调用时即使连接丢失(比如TCP连接断开),该调用也会尝试 去重新连接数据库。该特性经测试被证明属实。 注: 1. 对于 <= 5.0.3 的版本,MySQL默认会重连;此后的版本需调用 mysql_options() 明确指定 MYSQL_OPT_RECONNECT 为 true,才会重连。 2. 为了在连接丢失并重连后,能执行“数据库刚建立连接时要执行的命令”,程序明确 指定不让 mysql_real_query() 自动重连,而是由程序显式重连。 */ for (int times = 0; times < 2; times++) { int r = mysql_real_query(&getConnObject(), sql_.c_str(), (int)sql_.length()); // 如果执行SQL失败 if (r != 0) { // 如果是首次,并且错误类型为连接丢失,则重试连接 if (times == 0) { int errNum = mysql_errno(&getConnObject()); if (errNum == CR_SERVER_GONE_ERROR || errNum == CR_SERVER_LOST) { logger().writeStr(SEM_MYSQL_LOST_CONNNECTION); // 强制重新连接 getDbConnection()->activateConnection(true); continue; } } // 否则抛出异常 string sql(sql_); if (sql.length() > 1024*2) { sql.resize(100); sql += "..."; } string errMsg = formatString("%s; Error: %s", sql.c_str(), mysql_error(&getConnObject())); iseThrowDbException(errMsg.c_str()); } else break; } }
std::vector<ValueType *> ValueTypeDatabaseFactory::fetchAll( void ) { DatabaseStatement * statement; DatabaseResult * result; DatabaseResultRow * row; std::vector<ValueType *> types; std::string strId; long bufferId; std::size_t id; std::string identifier; std::string name; std::string description; std::string regex; statement = getDbConnection()->createStatement( "SELECT *" "FROM value_types" ); if( statement != nullptr ) { result = statement->execute(); if( result != nullptr ) { while( result->hasNext() ) { row = result->next(); strId = row->getColumn(0); identifier = row->getColumn(1); regex = row->getColumn(2); name = row->getColumn(3); description = row->getColumn(4); bufferId = atol(strId.c_str()); id = static_cast<std::size_t>(bufferId); types.push_back( new ValueType(id,identifier,name,description,regex) ); delete row; } delete result; } delete statement; } return ( types ); }
std::vector<Controller *> ControllerDatabaseFactory::fetchAll( void ) { std::vector<Controller *> controllers; Controller * controller; DatabaseStatement * statement; DatabaseResult * result; DatabaseResultRow * row; std::string id; std::string identifier; std::string description; std::string name; std::string securityCode; statement = getDbConnection()->createStatement( "SELECT * " "FROM controllers;" ); if( statement != nullptr ) { result = statement->execute(); if( result != nullptr ) { while( result->hasNext() ) { row = result->next(); id = row->getColumn(0); identifier = row->getColumn(1); securityCode = row->getColumn(2); name = row->getColumn(3); description = row->getColumn(4); controller = allocateController(id,identifier,name, description,securityCode); controllers.push_back(controller); delete row; } delete result; } delete statement; } return ( controllers ); }