Exemple #1
0
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();
}
Exemple #2
0
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();
}
Exemple #3
0
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();
}
Exemple #4
0
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();
}
Exemple #5
0
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);
    }
}