void DBOperationUpdate::on_criteria_mismatch(DBObjectSnapshot *snapshot) { DatagramPtr resp = Datagram::create(); resp->add_server_header(m_sender, m_dbserver->m_control_channel, m_resp_msgtype); resp->add_uint32(m_context); resp->add_uint8(FAILURE); // Calculate the fields that we are sending in our response: FieldValues mismatched_fields; for(auto it = m_criteria_fields.begin(); it != m_criteria_fields.end(); ++it) { auto it2 = snapshot->m_fields.find(it->first); if(it2 != snapshot->m_fields.end() && !it2->second.empty()) { mismatched_fields[it2->first] = it2->second; } } if(m_resp_msgtype == DBSERVER_OBJECT_SET_FIELDS_IF_EQUALS_RESP) { resp->add_uint16(mismatched_fields.size()); } for(auto it = mismatched_fields.begin(); it != mismatched_fields.end(); ++it) { resp->add_uint16(it->first->get_id()); resp->add_data(it->second); } m_dbserver->route_datagram(resp); delete snapshot; cleanup(); }
void DBOperationGet::on_complete(DBObjectSnapshot *snapshot) { DatagramPtr resp = Datagram::create(); resp->add_server_header(m_sender, m_dbserver->m_control_channel, m_resp_msgtype); resp->add_uint32(m_context); resp->add_uint8(SUCCESS); // Calculate the fields that we are sending in our response: FieldValues response_fields; if(m_resp_msgtype == DBSERVER_OBJECT_GET_ALL_RESP) { // Send everything: response_fields = snapshot->m_fields; } else { // Send only what was requested: for(auto it = m_get_fields.begin(); it != m_get_fields.end(); ++it) { auto it2 = snapshot->m_fields.find(*it); if(it2 != snapshot->m_fields.end()) { response_fields[it2->first] = it2->second; } } } // WHAT we send depends on our m_resp_msgtype, so: if(m_resp_msgtype == DBSERVER_OBJECT_GET_FIELD_RESP) { if(response_fields.empty()) { // We did not find the field we were looking for. // Therefore, this is a failure. on_failure(); return; } resp->add_uint16(response_fields.begin()->first->get_id()); resp->add_data(response_fields.begin()->second); // And that's it. We're done. m_dbserver->route_datagram(resp); delete snapshot; cleanup(); return; } if(m_resp_msgtype == DBSERVER_OBJECT_GET_ALL_RESP) { resp->add_uint16(snapshot->m_dclass->get_id()); } resp->add_uint16(response_fields.size()); for(auto it = response_fields.begin(); it != response_fields.end(); ++it) { resp->add_uint16(it->first->get_id()); resp->add_data(it->second); } m_dbserver->route_datagram(resp); delete snapshot; cleanup(); }
void DBOperationUpdate::on_failure() { DatagramPtr resp = Datagram::create(); resp->add_server_header(m_sender, m_dbserver->m_control_channel, m_resp_msgtype); resp->add_uint32(m_context); resp->add_uint8(FAILURE); m_dbserver->route_datagram(resp); cleanup(); }
void DBOperationUpdate::on_complete() { // Broadcast update to object's channel if(m_dbserver->m_broadcast) { announce_fields(m_set_fields); } // Send update response DatagramPtr resp = Datagram::create(); resp->add_server_header(m_sender, m_dbserver->m_control_channel, m_resp_msgtype); resp->add_uint32(m_context); resp->add_uint8(SUCCESS); m_dbserver->route_datagram(resp); cleanup(); }
void DBStateServer::handle_get_fields(channel_t sender, DatagramIterator &dgi) { uint32_t r_context = dgi.read_uint32(); doid_t r_do_id = dgi.read_doid(); uint16_t field_count = dgi.read_uint16(); if(is_activated_object(r_do_id)) { return; } m_log->trace() << "Received GetFields for inactive object with id " << r_do_id << std::endl; // Read requested fields from datagram std::vector<const Field*> db_fields; // Ram|required db fields in request std::vector<const Field*> ram_fields; // Ram|required but not-db fields in request for(uint16_t i = 0; i < field_count; ++i) { uint16_t field_id = dgi.read_uint16(); const Field* field = g_dcf->get_field_by_id(field_id); if(!field) { DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELDS_RESP); dg->add_uint32(r_context); dg->add_uint8(false); route_datagram(dg); } else if(field->has_keyword("ram") || field->has_keyword("required")) { if(field->has_keyword("db")) { db_fields.push_back(field); } else { ram_fields.push_back(field); } } } if(db_fields.size()) { // Get context for db query uint32_t db_context = m_next_context++; // Prepare reponse datagram if(m_context_datagrams.find(db_context) == m_context_datagrams.end()) { m_context_datagrams[db_context] = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELDS_RESP); } m_context_datagrams[db_context]->add_uint32(r_context); m_context_datagrams[db_context]->add_bool(true); m_context_datagrams[db_context]->add_uint16(ram_fields.size() + db_fields.size()); for(const auto& it : ram_fields) { m_context_datagrams[db_context]->add_uint16(it->get_id()); m_context_datagrams[db_context]->add_data(it->get_default_value()); } // Send query to database DatagramPtr dg = Datagram::create(m_db_channel, r_do_id, DBSERVER_OBJECT_GET_FIELDS); dg->add_uint32(db_context); dg->add_doid(r_do_id); dg->add_uint16(db_fields.size()); for(const auto& it : db_fields) { dg->add_uint16(it->get_id()); } route_datagram(dg); } else { // If no database fields exist DatagramPtr dg = Datagram::create(sender, r_do_id, STATESERVER_OBJECT_GET_FIELDS_RESP); dg->add_uint32(r_context); dg->add_bool(true); dg->add_uint16(ram_fields.size()); for(const auto& it : ram_fields) { dg->add_uint16(it->get_id()); dg->add_data(it->get_default_value()); } route_datagram(dg); } }