ormbatchchange.h 5.39 KB
/* ****************************************************************************
 * Copyright 2019 Open Systems Development BV                                 *
 *                                                                            *
 * Permission is hereby granted, free of charge, to any person obtaining a    *
 * copy of this software and associated documentation files (the "Software"), *
 * to deal in the Software without restriction, including without limitation  *
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
 * and/or sell copies of the Software, and to permit persons to whom the      *
 * Software is furnished to do so, subject to the following conditions:       *
 *                                                                            *
 * The above copyright notice and this permission notice shall be included in *
 * all copies or substantial portions of the Software.                        *
 *                                                                            *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING    *
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER        *
 * DEALINGS IN THE SOFTWARE.                                                  *
 * ***************************************************************************/
#ifndef OSDEV_COMPONENTS_ORMBATCHCHANGE_H
#define OSDEV_COMPONENTS_ORMBATCHCHANGE_H

#include <set>

#include <QVariant>

#include "timestamp.h"

namespace osdev {
namespace components {

/**
 * @brief Describes a change that should happen or has happened on a BatchUpdate or MergeUpdate table.
 */
class OrmBatchChange
{
public:
    /**
     * @brief Creates an invalid OrmBatchChange.
     * @note The only way to make an OrmBatchChange valid is by assigning a valid OrmBatchChange to it.
     */
    OrmBatchChange();

    /**
     * @brief Create an OrmBatchChange with a change description.
     * @param ts A valid timestamp (not checked).
     * @param foreignId The value that should be pointed to.
     * @param changeSet The set of record identifiers of records that should point to the given foreignId.
     */
    OrmBatchChange(const Timestamp& ts, const QVariant& foreignId, const std::set<QVariant>& changeSet);

    // Default copyable and movable.
    OrmBatchChange(const OrmBatchChange&) = default;
    OrmBatchChange& operator=(const OrmBatchChange&) = default;
    OrmBatchChange(OrmBatchChange&&) = default;
    OrmBatchChange& operator=(OrmBatchChange&&) = default;

    /**
     * @brief Process an already executed change on this change.
     * The changeset of this object can be reshaped as a result.
     * @param change A known change.
     * @param exclusiveUpdate Flag that indicates if the change should be processed in an exclusive way.
     * @return true to indicate this change is still valid and false otherwise.
     * @note An exclusiveUpdate means that all records that are not mentioned in the change set will not point to the given foreignId.
     */
    bool processChange(const OrmBatchChange& change, bool exclusiveUpdate);

    /**
     * @brief Changes are ordered w.r.t. each other by their timestamp.
     */
    bool operator<(const OrmBatchChange& rhs) const
    {
        return m_changeTimestamp < rhs.m_changeTimestamp;
    }

    /**
     * @brief Change the timestamp of this change.
     * This is necessary when the change is recorded to be permanent. It then becomes the latest change.
     * @param ts The new timestamp (no checks).
     */
    void setTimestamp(const Timestamp& ts)
    {
        m_changeTimestamp = ts;
    }

    /**
     * @return The timestamp of this change.
     */
    const Timestamp& timestamp() const
    {
        return m_changeTimestamp;
    }

    /**
     * @return The foreinId of this change.
     */
    QVariant foreignId() const
    {
        return m_foreignId;
    }

    /**
     * @return The change set of this change.
     */
    std::set<QVariant> changeSet() const
    {
        return m_changeSet;
    }

    /**
     * @return true if this change is valid, false otherwise.
     */
    bool valid() const
    {
        return m_valid;
    }

    /**
     * @brief Static method to convert a QList<QVariant> to an std::set<QVariant>.
     * @param lst The QList<QVariant> to convert.
     * @return the converted set.
     */
    static std::set<QVariant> toSet(const QList<QVariant>& lst);

    /**
     * @brief Static method to convert an std::set<QVariant> to a QList<QVariant>.
     * @param variantSet The set of variants to convert.
     * @return the converted QList.
     */
    static QList<QVariant> toList(const std::set<QVariant>& variantSet);

private:
    Timestamp m_changeTimestamp;        ///< The timestamp of this change.
    QVariant m_foreignId;               ///< The foreignId that should be pointed to.
    std::set<QVariant> m_changeSet;     ///< The set of record identifiers that describe the change.
    bool m_valid;                       ///< Flag that indicates if this change is valid.
};

}   /* End namespace components */
}   /* End namespace osdev */

#endif  /* OSDEV_COMPONENTS_ORMBATCHCHANGE_H */