ormbatchchange.h 3.75 KB
#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 */