/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* * Copyright 2024. Couchbase, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include namespace couchbase { /** * A scan term used to specify the bounds of a range scan operation. * * @since 1.0.0 * @committed */ struct scan_term { public: /** * Constructs an instance representing the scan term for the given term. * * @param term the string representation of the term. * * @since 1.0.0 * @committed */ explicit scan_term(std::string term) : term_{ std::move(term) } { } /** * Specifies whether this term is excluded from the scan results. The bounds are included by * default. * * @param exclusive whether the term should be excluded. * @return the scan term object for chaining purposes. */ auto exclusive(bool exclusive) -> scan_term& { exclusive_ = exclusive; return *this; } /** * Immutable value representing the scan term. * * @since 1.0.0 * @internal */ struct built { std::string term; bool exclusive; }; /** * Returns the scan term as an immutable value. * * @return scan term as an immutable value. * * @since 1.0.0 * @internal */ [[nodiscard]] auto build() const -> built { return { term_, exclusive_ }; } private: std::string term_{}; bool exclusive_{ false }; }; /** * The base class for the different scan types. * * @since 1.0.0 * @committed */ struct scan_type { virtual ~scan_type() = default; /** * Immutable value representing the scan type. * * @since 1.0.0 * @internal */ struct built { enum type { prefix_scan, range_scan, sampling_scan }; type type; std::string prefix{}; std::optional from{}; std::optional to{}; std::size_t limit{}; std::optional seed{}; }; /** * Returns the scan type as an immutable value. * * @return scan type as an immutable value. * * @since 1.0.0 * @internal */ [[nodiscard]] virtual auto build() const -> built = 0; }; /** * A prefix scan performs a scan that includes all documents whose keys start with the given prefix. * * @since 1.0.0 * @committed */ struct prefix_scan : scan_type { public: /** * Creates an instance of a prefix scan type. * * @param prefix The prefix all document keys should start with. * * @since 1.0.0 * @committed */ explicit prefix_scan(std::string prefix) : prefix_{ std::move(prefix) } { } /** * Returns the prefix scan type as an immutable value. * * @return scan type as an immutable value. * * @since 1.0.0 * @internal */ [[nodiscard]] auto build() const -> built override { return { scan_type::built::prefix_scan, prefix_, }; } private: std::string prefix_{}; }; /** * A range scan performs a scan on a range of keys. * * @since 1.0.0 * @committed */ struct range_scan : scan_type { public: /** * Creates an instance of a range scan type with no bounds. * * @since 1.0.0 * @committed */ range_scan() = default; /** * Creates an instance of a range scan type * * @param from the scan term representing the lower bound of the range, optional. * @param to the scan term representing the upper bound of the range, optional. * * @since 1.0.0 * @committed */ range_scan(std::optional from, std::optional to) : from_{ std::move(from) } , to_{ std::move(to) } { } /** * Specifies the lower bound of the range * * @param from scan term representing the lower bound. * @return the range scan object for chaining purposes. * * @since 1.0.0 * @committed */ auto from(scan_term from) -> range_scan& { from_ = std::move(from); return *this; } /** * Specifies the upper bound of the range. * * @param to scan term representing the upper bound. * @return the range scan object for chaining purposes. * * @since 1.0.0 * @committed */ auto to(scan_term to) -> range_scan& { to_ = std::move(to); return *this; } /** * Returns the range scan type as an immutable value. * * @return scan type as an immutable value. * * @since 1.0.0 * @internal */ [[nodiscard]] auto build() const -> built override { return { scan_type::built::type::range_scan, {}, (from_) ? std::make_optional(from_->build()) : std::nullopt, (to_) ? std::make_optional(to_->build()) : std::nullopt, }; } private: std::optional from_{}; std::optional to_{}; }; /** * A sampling scan performs a scan that randomly selects documents up to a configured limit. * * @since 1.0.0 * @committed */ struct sampling_scan : scan_type { public: /** * Creates an instance of a sampling scan type. * * @param limit the maximum number of documents the sampling scan can return. * * @since 1.0.0 * @committed */ explicit sampling_scan(std::size_t limit) : limit_{ limit } { } /** * Creates an instance of a sampling scan type with a seed. * * @param limit the maximum number of documents the sampling scan can return. * @param seed the seed used for the random number generator that selects the documents. * * @since 1.0.0 * @committed */ sampling_scan(std::size_t limit, std::uint64_t seed) : limit_{ limit } , seed_{ seed } { } /** * Sets the seed for the sampling scan. * * @param seed the seed used for the random number generator that selects the documents. * @return the sampling scan object for chaining purposes. * * @since 1.0.0 * @committed */ auto seed(std::uint64_t seed) -> sampling_scan& { seed_ = seed; return *this; } /** * Returns the sampling scan type as an immutable value. * * @return scan type as an immutable value. * * @since 1.0.0 * @internal */ [[nodiscard]] auto build() const -> built override { return { scan_type::built::type::sampling_scan, {}, {}, {}, limit_, seed_, }; } private: std::size_t limit_{}; std::optional seed_{}; }; } // namespace couchbase