示例#1
0
void Object::set_property_value_impl(ContextType& ctx, const Property &property,
                                     ValueType value, bool try_update, bool is_default)
{
    ctx.will_change(*this, property);

    auto& table = *m_row.get_table();
    size_t col = property.table_column;
    size_t row = m_row.get_index();
    if (is_nullable(property.type) && ctx.is_null(value)) {
        if (property.type == PropertyType::Object) {
            if (!is_default)
                table.nullify_link(col, row);
        }
        else {
            table.set_null(col, row, is_default);
        }

        ctx.did_change();
        return;
    }

    if (is_array(property.type)) {
        if (property.type == PropertyType::LinkingObjects)
            throw ReadOnlyPropertyException(m_object_schema->name, property.name);
        REALM_ASSERT(property.type == PropertyType::Object);

        List list(m_realm, m_row.get_linklist(col));
        list.remove_all();
        if (!ctx.is_null(value)) {
            ContextType child_ctx(ctx, property);
            ctx.enumerate_list(value, [&](auto&& element) {
                list.add(child_ctx, element, try_update);
            });
        }
        ctx.did_change();
        return;
    }

    switch (property.type & ~PropertyType::Flags) {
        case PropertyType::Bool:
            table.set(col, row, ctx.template unbox<bool>(value), is_default);
            break;
        case PropertyType::Int:
            table.set(col, row, ctx.template unbox<int64_t>(value), is_default);
            break;
        case PropertyType::Float:
            table.set(col, row, ctx.template unbox<float>(value), is_default);
            break;
        case PropertyType::Double:
            table.set(col, row, ctx.template unbox<double>(value), is_default);
            break;
        case PropertyType::String:
            table.set(col, row, ctx.template unbox<StringData>(value), is_default);
            break;
        case PropertyType::Data:
            table.set(col, row, ctx.template unbox<BinaryData>(value), is_default);
            break;
        case PropertyType::Any:
            throw std::logic_error("not supported");
        case PropertyType::Date:
            table.set(col, row, ctx.template unbox<Timestamp>(value), is_default);
            break;
        case PropertyType::Object: {
            ContextType child_ctx(ctx, property);
            auto link = child_ctx.template unbox<RowExpr>(value, true, try_update);
            table.set_link(col, row, link.get_index(), is_default);
            break;
        }
        default:
            REALM_COMPILER_HINT_UNREACHABLE();
    }
    ctx.did_change();
}
void Object::set_property_value_impl(ContextType& ctx, const Property &property,
                                     ValueType value, bool try_update, bool update_only_diff, bool is_default)
{
    ctx.will_change(*this, property);

    auto& table = *m_row.get_table();
    size_t col = property.table_column;
    size_t row = m_row.get_index();
    if (is_nullable(property.type) && ctx.is_null(value)) {
        if (!update_only_diff || !table.is_null(col, row)) {
            if (property.type == PropertyType::Object) {
                if (!is_default)
                    table.nullify_link(col, row);
            }
            else {
                table.set_null(col, row, is_default);
            }
        }

        ctx.did_change();
        return;
    }

    if (is_array(property.type)) {
        if (property.type == PropertyType::LinkingObjects)
            throw ReadOnlyPropertyException(m_object_schema->name, property.name);

        ContextType child_ctx(ctx, property);
        List list(m_realm, table, col, m_row.get_index());
        list.assign(child_ctx, value, try_update, update_only_diff);
        ctx.did_change();
        return;
    }

    switch (property.type & ~PropertyType::Nullable) {
        case PropertyType::Object: {
            ContextType child_ctx(ctx, property);
            auto curr_link = table.get_link(col,row);
            auto link = child_ctx.template unbox<RowExpr>(value, true, try_update, update_only_diff, curr_link);
            if (!update_only_diff || curr_link != link.get_index()) {
                table.set_link(col, row, link.get_index(), is_default);
            }
            break;
        }
        case PropertyType::Bool:
            do_update_value<bool>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::Int:
            do_update_value<int64_t>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::Float:
            do_update_value<float>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::Double:
            do_update_value<double>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::String:
            do_update_value<StringData>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::Data:
            do_update_value<BinaryData>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::Date:
            do_update_value<Timestamp>(ctx, table, value, col, row, update_only_diff, is_default);
            break;
        case PropertyType::Any:
            throw std::logic_error("not supported");
        default:
            REALM_COMPILER_HINT_UNREACHABLE();
    }
    ctx.did_change();
}