Example #1
0
    virtual bool get_field(doid_t do_id, const Field* field, vector<uint8_t> &value)
    {
        // Get class from the objects table
        const Class* dcc = get_class(do_id);
        if(!dcc) {
            return false; // Object does not exist
        }

        bool stored = is_storable(dcc->get_id());
        if(!stored) {
            return false; // Class has no database fields
        }

        FieldList fields;
        fields.push_back(field);
        FieldValues values;

        get_fields_from_table(do_id, dcc, fields, values);

        auto val_it = values.find(field);
        if(val_it == values.end()) {
            return false;
        }

        value = val_it->second;

        return true;
    }
Example #2
0
    virtual bool set_fields_if_empty(doid_t do_id, FieldValues &values)
    {
        // Get class from the objects table
        const Class* dcc = get_class(do_id);
        if(!dcc) {
            values.clear();
            return false; // Object does not exist
        }

        bool stored = is_storable(dcc->get_id());
        if(!stored) {
            values.clear();
            return false; // Class has no database fields
        }

        bool failed = false;
        string value;
        indicator ind;
        try {
            m_sql.begin(); // Start transaction
            for(auto it = values.begin(); it != values.end(); ++it) {
                const Field* field = it->first;
                if(field->has_keyword("db")) {
                    m_sql << "SELECT " << field->get_name() << " FROM fields_" << dcc->get_name()
                          << " WHERE object_id=" << do_id << ";", into(value, ind);
                    if(ind != i_null) {
                        bool parse_err;
                        failed = true;
                        string packed_data = parse_value(field->get_type(), value, parse_err);
                        if(parse_err) {
                            m_log->error() << "Failed parsing value for field '" << field->get_name()
                                           << "' of object " << do_id << "' from database.\n";
                            continue;
                        }
                        values[field] = vector<uint8_t>(packed_data.begin(), packed_data.end());
                        continue;
                    }

                    value = format_value(it->first->get_type(), it->second);
                    m_sql << "UPDATE fields_" << dcc->get_name() << " SET " << field->get_name()
                          << "='" << value << "' WHERE object_id=" << do_id << ";";
                }
            }

            if(failed) {
                m_sql.rollback(); // Revert transaction
            } else {
                m_sql.commit(); // End transaction
            }
        } catch(const soci_error &e) {
            m_sql.rollback(); // Revert transaction
            values.clear();
            return false;
        }
        return true;
    }
Example #3
0
bool DBOperation::verify_fields(const dclass::Class *dclass, const FieldValues& fields)
{
    bool valid = true;
    for(auto it = fields.begin(); it != fields.end(); ++it) {
        if(!dclass->get_field_by_id(it->first->get_id())) {
            m_dbserver->m_log->warning() << "Field " << it->first->get_name()
                                         << " does not belong to object " << m_doid
                                         << "(" << dclass->get_name() << ")\n";
            valid = false;
        }
    }
    return valid;
}
Example #4
0
 void set_fields_in_table(doid_t id, const Class* dcc,
                          const FieldValues &fields)
 {
     string name, value;
     for(auto it = fields.begin(); it != fields.end(); ++it) {
         if(it->first->has_keyword("db")) {
             name = it->first->get_name();
             value = format_value(it->first->get_type(), it->second);
             m_sql << "UPDATE fields_" << dcc->get_name() << " SET " << name << "='" << value
                   << "' WHERE object_id=" << id << ";";
         }
     }
 }
Example #5
0
void DBOperation::announce_fields(const FieldValues& fields)
{
    // Calculate the fields that we are sending in our response:
    FieldValues changed_fields;
    FieldSet deleted_fields;
    for(auto it = fields.begin(); it != fields.end(); ++it) {
        if(it->second.empty())
            deleted_fields.insert(it->first);
        else
            changed_fields[it->first] = it->second;
    }

    // Send delete fields broadcast
    if(!deleted_fields.empty()) {
        bool multi = (deleted_fields.size() > 1);
        DatagramPtr update = Datagram::create();
        update->add_server_header(database_to_object(m_doid), m_sender,
                                  multi ? DBSERVER_OBJECT_DELETE_FIELDS :
                                  DBSERVER_OBJECT_DELETE_FIELD);
        update->add_doid(m_doid);
        if(multi) {
            update->add_uint16(deleted_fields.size());
        }
        for(auto it = deleted_fields.begin(); it != deleted_fields.end(); ++it) {
            update->add_uint16((*it)->get_id());
        }
        m_dbserver->route_datagram(update);
    }

    // Send update fields broadcast
    if(!changed_fields.empty()) {
        bool multi = (changed_fields.size() > 1);
        DatagramPtr update = Datagram::create();
        update->add_server_header(database_to_object(m_doid), m_sender,
                                  multi ? DBSERVER_OBJECT_SET_FIELDS :
                                  DBSERVER_OBJECT_SET_FIELD);
        update->add_doid(m_doid);
        if(multi) {
            update->add_uint16(changed_fields.size());
        }
        for(auto it = changed_fields.begin(); it != changed_fields.end(); ++it) {
            update->add_uint16(it->first->get_id());
            update->add_data(it->second);
        }
        m_dbserver->route_datagram(update);
    }
}