Merge pull request #40 from realm/tg/list

Wrap more of LinkView in List
This commit is contained in:
Thomas Goyne 2016-02-16 17:35:58 -08:00
commit 87655793b7
2 changed files with 173 additions and 59 deletions

View File

@ -18,69 +18,152 @@
#include "list.hpp"
#include "results.hpp"
#include "shared_realm.hpp"
#include <stdexcept>
using namespace realm;
size_t List::size() {
List::List() noexcept = default;
List::~List() = default;
List::List(std::shared_ptr<Realm> r, const ObjectSchema& s, LinkViewRef l) noexcept
: m_realm(std::move(r))
, m_object_schema(&s)
, m_link_view(std::move(l))
{
}
Query List::get_query() const
{
verify_attached();
return m_link_view->get_target_table().where(m_link_view);
}
void List::verify_valid_row(size_t row_ndx, bool insertion) const
{
size_t size = m_link_view->size();
if (row_ndx > size || (!insertion && row_ndx == size)) {
throw std::out_of_range("Index " + std::to_string(row_ndx) + " is outside of range 0..." +
std::to_string(size) + ".");
}
}
bool List::is_valid() const
{
m_realm->verify_thread();
return m_link_view && m_link_view->is_attached();
}
void List::verify_attached() const
{
if (!is_valid()) {
throw std::runtime_error("LinkView is not attached");
}
}
void List::verify_in_transaction() const
{
verify_attached();
if (!m_realm->is_in_transaction()) {
throw InvalidTransactionException("Must be in a write transaction");
}
}
size_t List::size() const
{
verify_attached();
return m_link_view->size();
}
Row List::get(std::size_t row_ndx) {
RowExpr List::get(size_t row_ndx) const
{
verify_attached();
verify_valid_row(row_ndx);
return m_link_view->get(row_ndx);
}
void List::set(std::size_t row_ndx, std::size_t target_row_ndx) {
size_t List::find(ConstRow const& row) const
{
verify_attached();
verify_in_tranaction();
verify_valid_row(row_ndx);
m_link_view->set(row_ndx, target_row_ndx);
if (!row.is_attached() || row.get_table() != &m_link_view->get_target_table()) {
return not_found;
}
return m_link_view->find(row.get_index());
}
void List::add(std::size_t target_row_ndx) {
verify_attached();
verify_in_tranaction();
void List::add(size_t target_row_ndx)
{
verify_in_transaction();
m_link_view->add(target_row_ndx);
}
void List::insert(std::size_t row_ndx, std::size_t target_row_ndx) {
verify_attached();
verify_in_tranaction();
void List::insert(size_t row_ndx, size_t target_row_ndx)
{
verify_in_transaction();
verify_valid_row(row_ndx, true);
m_link_view->insert(row_ndx, target_row_ndx);
}
void List::remove(std::size_t row_ndx) {
verify_attached();
verify_in_tranaction();
void List::move(size_t source_ndx, size_t dest_ndx)
{
verify_in_transaction();
verify_valid_row(source_ndx);
verify_valid_row(dest_ndx); // Can't be one past end due to removing one earlier
m_link_view->move(source_ndx, dest_ndx);
}
void List::remove(size_t row_ndx)
{
verify_in_transaction();
verify_valid_row(row_ndx);
m_link_view->remove(row_ndx);
}
Query List::get_query() {
verify_attached();
return m_link_view->get_target_table().where(m_link_view);
void List::remove_all()
{
verify_in_transaction();
m_link_view->clear();
}
void List::verify_valid_row(std::size_t row_ndx, bool insertion) {
size_t size = m_link_view->size();
if (row_ndx > size || (!insertion && row_ndx == size)) {
throw std::out_of_range(std::string("Index ") + std::to_string(row_ndx) + " is outside of range 0..." + std::to_string(size) + ".");
}
void List::set(size_t row_ndx, size_t target_row_ndx)
{
verify_in_transaction();
verify_valid_row(row_ndx);
m_link_view->set(row_ndx, target_row_ndx);
}
void List::verify_attached() {
if (!m_link_view->is_attached()) {
throw std::runtime_error("Tableview is not attached");
}
m_link_view->sync_if_needed();
void List::swap(size_t ndx1, size_t ndx2)
{
verify_in_transaction();
verify_valid_row(ndx1);
verify_valid_row(ndx2);
m_link_view->swap(ndx1, ndx2);
}
void List::verify_in_tranaction() {
if (!m_realm->is_in_transaction()) {
throw std::runtime_error("Can only mutate a list within a transaction.");
}
void List::delete_all()
{
verify_in_transaction();
m_link_view->remove_all_target_rows();
}
Results List::sort(SortOrder order)
{
return Results(m_realm, *m_object_schema, get_query(), std::move(order));
}
// These definitions rely on that LinkViews are interned by core
bool List::operator==(List const& rgt) const noexcept
{
return m_link_view.get() == rgt.m_link_view.get();
}
namespace std {
size_t hash<realm::List>::operator()(realm::List const& list) const
{
return std::hash<void*>()(list.m_link_view.get());
}
}

View File

@ -19,45 +19,76 @@
#ifndef REALM_LIST_HPP
#define REALM_LIST_HPP
#include "shared_realm.hpp"
#include <realm/link_view.hpp>
#include <memory>
namespace realm {
class List {
public:
List(SharedRealm &r, const ObjectSchema &s, LinkViewRef l) : m_realm(r), m_object_schema(&s), m_link_view(l) {}
template<typename T> class BasicRowExpr;
using RowExpr = BasicRowExpr<Table>;
const ObjectSchema &get_object_schema() const { return *m_object_schema; }
SharedRealm realm() { return m_realm; }
class ObjectSchema;
class Realm;
class Results;
struct SortOrder;
size_t size();
Row get(std::size_t row_ndx);
void set(std::size_t row_ndx, std::size_t target_row_ndx);
class List {
public:
List() noexcept;
List(std::shared_ptr<Realm> r, const ObjectSchema& s, LinkViewRef l) noexcept;
~List();
void add(size_t target_row_ndx);
void remove(size_t list_ndx);
void insert(size_t list_ndx, size_t target_row_ndx);
const std::shared_ptr<Realm>& get_realm() const { return m_realm; }
Query get_query() const;
const ObjectSchema& get_object_schema() const { return *m_object_schema; }
template<typename ValueType, typename ContextType>
void add(ContextType ctx, ValueType value);
bool is_valid() const;
void verify_attached() const;
void verify_in_transaction() const;
template<typename ValueType, typename ContextType>
void insert(ContextType ctx, ValueType value, size_t list_ndx);
size_t size() const;
RowExpr get(size_t row_ndx) const;
size_t find(ConstRow const& row) const;
template<typename ValueType, typename ContextType>
void set(ContextType ctx, ValueType value, size_t list_ndx);
void add(size_t target_row_ndx);
void insert(size_t list_ndx, size_t target_row_ndx);
void move(size_t source_ndx, size_t dest_ndx);
void remove(size_t list_ndx);
void remove_all();
void set(size_t row_ndx, size_t target_row_ndx);
void swap(size_t ndx1, size_t ndx2);
Query get_query();
void delete_all();
void verify_valid_row(std::size_t row_ndx, bool insertion = false);
void verify_attached();
void verify_in_tranaction();
Results sort(SortOrder order);
private:
SharedRealm m_realm;
const ObjectSchema *m_object_schema;
LinkViewRef m_link_view;
};
bool operator==(List const& rgt) const noexcept;
// These are implemented in object_accessor.hpp
template <typename ValueType, typename ContextType>
void add(ContextType ctx, ValueType value);
template <typename ValueType, typename ContextType>
void insert(ContextType ctx, ValueType value, size_t list_ndx);
template <typename ValueType, typename ContextType>
void set(ContextType ctx, ValueType value, size_t list_ndx);
private:
std::shared_ptr<Realm> m_realm;
const ObjectSchema* m_object_schema;
LinkViewRef m_link_view;
void verify_valid_row(size_t row_ndx, bool insertion = false) const;
friend struct std::hash<List>;
};
} // namespace realm
namespace std {
template<> struct hash<realm::List> {
size_t operator()(realm::List const&) const;
};
}
#endif /* REALM_LIST_HPP */