bool validate_check()

in src/server/pegasus_write_service_impl.h [945:1071]


    bool validate_check(TDecree decree,
                        ::dsn::apps::cas_check_type::type check_type,
                        const ::dsn::blob &check_operand,
                        bool value_exist,
                        const ::dsn::blob &check_value,
                        bool &invalid_argument)
    {
        invalid_argument = false;
        switch (check_type) {
        case ::dsn::apps::cas_check_type::CT_NO_CHECK:
            return true;

        case ::dsn::apps::cas_check_type::CT_VALUE_NOT_EXIST:
            return !value_exist;

        case ::dsn::apps::cas_check_type::CT_VALUE_NOT_EXIST_OR_EMPTY:
            return !value_exist || check_value.empty();

        case ::dsn::apps::cas_check_type::CT_VALUE_EXIST:
            return value_exist;

        case ::dsn::apps::cas_check_type::CT_VALUE_NOT_EMPTY:
            return value_exist && !check_value.empty();

        case ::dsn::apps::cas_check_type::CT_VALUE_MATCH_ANYWHERE:
        case ::dsn::apps::cas_check_type::CT_VALUE_MATCH_PREFIX:
        case ::dsn::apps::cas_check_type::CT_VALUE_MATCH_POSTFIX: {
            if (!value_exist) {
                return false;
            }

            if (check_operand.empty()) {
                return true;
            }

            if (check_value.length() < check_operand.length()) {
                return false;
            }

            if (check_type == ::dsn::apps::cas_check_type::CT_VALUE_MATCH_ANYWHERE) {
                return check_value.contains(check_operand);
            }

            if (check_type == ::dsn::apps::cas_check_type::CT_VALUE_MATCH_PREFIX) {
                return check_value.starts_with(check_operand);
            }

            CHECK(check_type == ::dsn::apps::cas_check_type::CT_VALUE_MATCH_POSTFIX,
                  "check_type({}) should be CT_VALUE_MATCH_POSTFIX",
                  cas_check_type_to_string(check_type));

            return check_value.ends_with(check_operand);
        }

        case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS:
        case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS_OR_EQUAL:
        case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_EQUAL:
        case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER_OR_EQUAL:
        case ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER: {
            if (!value_exist) {
                return false;
            }

            const int c = check_value.compare(check_operand);
            if (c < 0) {
                return check_type <= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS_OR_EQUAL;
            }

            if (c > 0) {
                return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER_OR_EQUAL;
            }

            // Must be c == 0.
            return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_LESS_OR_EQUAL &&
                   check_type <= ::dsn::apps::cas_check_type::CT_VALUE_BYTES_GREATER_OR_EQUAL;
        }

        case ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS:
        case ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS_OR_EQUAL:
        case ::dsn::apps::cas_check_type::CT_VALUE_INT_EQUAL:
        case ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER_OR_EQUAL:
        case ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER: {
            if (!value_exist) {
                return false;
            }

            int64_t check_value_int = 0;
            if (!dsn::buf2int64(check_value.to_string_view(), check_value_int)) {
                // `check_value` is not a valid int64.
                LOG_ERROR_PREFIX("check failed: decree = {}, error = check value \"{}\" is "
                                 "not a valid integer or out of range",
                                 decree,
                                 utils::c_escape_sensitive_string(check_value));
                invalid_argument = true;
                return false;
            }

            int64_t check_operand_int = 0;
            if (!dsn::buf2int64(check_operand.to_string_view(), check_operand_int)) {
                // `check_operand` is not a valid int64.
                LOG_ERROR_PREFIX("check failed: decree = {}, error = check operand \"{}\" is "
                                 "not a valid integer or out of range",
                                 decree,
                                 utils::c_escape_sensitive_string(check_operand));
                invalid_argument = true;
                return false;
            }

            if (check_value_int < check_operand_int) {
                return check_type <= ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS_OR_EQUAL;
            }

            if (check_value_int > check_operand_int) {
                return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER_OR_EQUAL;
            }

            // Must be check_value_int == check_operand_int.
            return check_type >= ::dsn::apps::cas_check_type::CT_VALUE_INT_LESS_OR_EQUAL &&
                   check_type <= ::dsn::apps::cas_check_type::CT_VALUE_INT_GREATER_OR_EQUAL;
        }

        default:
            CHECK(false, "unsupported check type: {}", check_type);
        }

        return false;
    }