Ejemplo n.º 1
0
static auto switch_on_type(PropertyType type, Fn&& fn)
{
    using PT = PropertyType;
    bool is_optional = is_nullable(type);
    switch (type & ~PropertyType::Flags) {
        case PT::Int:    return is_optional ? fn((util::Optional<int64_t>*)0) : fn((int64_t*)0);
        case PT::Bool:   return is_optional ? fn((util::Optional<bool>*)0)    : fn((bool*)0);
        case PT::Float:  return is_optional ? fn((util::Optional<float>*)0)   : fn((float*)0);
        case PT::Double: return is_optional ? fn((util::Optional<double>*)0)  : fn((double*)0);
        case PT::String: return fn((StringData*)0);
        case PT::Data:   return fn((BinaryData*)0);
        case PT::Date:   return fn((Timestamp*)0);
        case PT::Object: return fn((RowExpr*)0);
        default: REALM_COMPILER_HINT_UNREACHABLE();
    }
}
Ejemplo n.º 2
0
static const char *string_for_property_type(PropertyType type)
{
    if (is_array(type)) {
        if (type == PropertyType::LinkingObjects)
            return "linking objects";
        return "array";
    }
    switch (type & ~PropertyType::Flags) {
        case PropertyType::String: return "string";
        case PropertyType::Int: return "int";
        case PropertyType::Bool: return "bool";
        case PropertyType::Date: return "date";
        case PropertyType::Data: return "data";
        case PropertyType::Double: return "double";
        case PropertyType::Float: return "float";
        case PropertyType::Object: return "object";
        case PropertyType::Any: return "any";
        case PropertyType::LinkingObjects: return "linking objects";
        default: REALM_COMPILER_HINT_UNREACHABLE();
    }
}
Ejemplo n.º 3
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();
}
Ejemplo n.º 4
0
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();
}