diff --git a/src/RJSResults.cpp b/src/RJSResults.cpp index b7483de9..b0d1d709 100644 --- a/src/RJSResults.cpp +++ b/src/RJSResults.cpp @@ -22,7 +22,9 @@ JSValueRef ResultsGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef return JSValueMakeNumber(ctx, size); } - return RJSObjectCreate(ctx, Object(results->realm, results->object_schema, results->get(RJSValidatedPositiveIndex(indexStr)))); + return RJSObjectCreate(ctx, Object(results->get_realm(), + results->object_schema, + results->get(RJSValidatedPositiveIndex(indexStr)))); } catch (std::out_of_range &exp) { // getters for nonexistent properties in JS should always return undefined @@ -61,7 +63,7 @@ bool ResultsSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef proper void ResultsPropertyNames(JSContextRef ctx, JSObjectRef object, JSPropertyNameAccumulatorRef propertyNames) { Results *results = RJSGetInternal(object); char str[32]; - for (int i = 0; i < results->table_view.size(); i++) { + for (int i = 0; i < results->size(); i++) { sprintf(str, "%i", i); JSStringRef name = JSStringCreateWithUTF8CString(str); JSPropertyNameAccumulatorAddName(propertyNames, name); @@ -74,7 +76,7 @@ JSValueRef SortByProperty(JSContextRef ctx, JSObjectRef function, JSObjectRef th Results *results = RJSGetInternal(thisObject); RJSValidateArgumentRange(argumentCount, 1, 2); std::string propName = RJSValidatedStringForValue(ctx, arguments[0]); - Property *prop = results->object_schema.property_for_name(propName); + const Property *prop = results->object_schema.property_for_name(propName); if (!prop) { throw std::runtime_error("Property '" + propName + "' does not exist on object type '" + results->object_schema.name + "'"); } @@ -84,8 +86,7 @@ JSValueRef SortByProperty(JSContextRef ctx, JSObjectRef function, JSObjectRef th ascending = JSValueToBoolean(ctx, arguments[1]); } - SortOrder sort = {{prop->table_column}, {ascending}}; - results->setSort(sort); + *results = results->sort({{prop->table_column}, {ascending}}); } catch (std::exception &exp) { if (jsException) { diff --git a/src/object-store/object_accessor.hpp b/src/object-store/object_accessor.hpp index dfae7c16..ffa3edb6 100644 --- a/src/object-store/object_accessor.hpp +++ b/src/object-store/object_accessor.hpp @@ -7,6 +7,7 @@ #include #include "shared_realm.hpp" +#include "schema.hpp" #include "list.hpp" namespace realm { diff --git a/src/object-store/results.cpp b/src/object-store/results.cpp index f361e6f5..2f466476 100644 --- a/src/object-store/results.cpp +++ b/src/object-store/results.cpp @@ -20,19 +20,21 @@ using namespace realm; #define REALM_FALLTHROUGH #endif -Results::Results(SharedRealm r, Query q, SortOrder s) +Results::Results(SharedRealm r, const ObjectSchema &o, Query q, SortOrder s) : m_realm(std::move(r)) , m_query(std::move(q)) , m_table(m_query.get_table().get()) , m_sort(std::move(s)) , m_mode(Mode::Query) +, object_schema(o) { } -Results::Results(SharedRealm r, Table& table) +Results::Results(SharedRealm r, const ObjectSchema &o, Table& table) : m_realm(std::move(r)) , m_table(&table) , m_mode(Mode::Table) +, object_schema(o) { } @@ -146,9 +148,9 @@ size_t Results::index_of(Row const& row) throw DetatchedAccessorException{}; } if (m_table && row.get_table() != m_table) { - throw IncorrectTableException{ - ObjectStore::object_type_for_table_name(m_table->get_name()), - ObjectStore::object_type_for_table_name(row.get_table()->get_name())}; + throw IncorrectTableException(object_schema.name, + ObjectStore::object_type_for_table_name(row.get_table()->get_name()), + "Attempting to get the index of a Row of the wrong type"); } return index_of(row.get_index()); } @@ -298,23 +300,18 @@ TableView Results::get_tableview() REALM_UNREACHABLE(); } -StringData Results::get_object_type() const noexcept -{ - return ObjectStore::object_type_for_table_name(m_table->get_name()); -} - Results Results::sort(realm::SortOrder&& sort) const { - return Results(m_realm, get_query(), std::move(sort)); + return Results(m_realm, object_schema, get_query(), std::move(sort)); } Results Results::filter(Query&& q) const { - return Results(m_realm, get_query().and_query(std::move(q)), get_sort()); + return Results(m_realm, object_schema, get_query().and_query(std::move(q)), get_sort()); } -Results::UnsupportedColumnTypeException::UnsupportedColumnTypeException(size_t column, const Table* table) { - column_index = column; - column_name = table->get_column_name(column); - column_type = table->get_column_type(column); +Results::UnsupportedColumnTypeException::UnsupportedColumnTypeException(size_t column, const Table* table) : + column_index(column), column_name(table->get_column_name(column)), column_type(table->get_column_type(column)), + std::runtime_error((std::string)"Operation not supported on '" + table->get_column_name(column).data() + "' columns") +{ } diff --git a/src/object-store/results.hpp b/src/object-store/results.hpp index bf9761a3..53ee6815 100644 --- a/src/object-store/results.hpp +++ b/src/object-store/results.hpp @@ -32,8 +32,8 @@ public: // or a wrapper around a query and a sort order which creates and updates // the tableview as needed Results() = default; - Results(SharedRealm r, Table& table); - Results(SharedRealm r, Query q, SortOrder s = {}); + Results(SharedRealm r, const ObjectSchema &o, Table& table); + Results(SharedRealm r, const ObjectSchema &o, Query q, SortOrder s = {}); // Results is copyable and moveable Results(Results const&) = default; @@ -41,6 +41,12 @@ public: Results& operator=(Results const&) = default; Results& operator=(Results&&) = default; + // Get the Realm + SharedRealm get_realm() const { return m_realm; } + + // Object schema describing the vendored object type + ObjectSchema object_schema; + // Get a query which will match the same rows as is contained in this Results // Returned query will not be valid if the current mode is Empty Query get_query() const; @@ -52,7 +58,7 @@ public: TableView get_tableview(); // Get the object type which will be returned by get() - StringData get_object_type() const noexcept; + StringData get_object_type() const noexcept { return object_schema.name; } // Get the size of this results // Can be either O(1) or O(N) depending on the state of things @@ -104,25 +110,36 @@ public: // The Results object has been invalidated (due to the Realm being invalidated) // All non-noexcept functions can throw this - struct InvalidatedException {}; + struct InvalidatedException : public std::runtime_error + { + InvalidatedException() : std::runtime_error("Access to invalidated Results objects") {} + }; // The input index parameter was out of bounds - struct OutOfBoundsIndexException { - size_t requested; - size_t valid_count; + struct OutOfBoundsIndexException : public std::out_of_range + { + OutOfBoundsIndexException(size_t r, size_t c) : requested(r), valid_count(c), + std::out_of_range((std::string)"Requested index " + std::to_string(r) + + " greater than max " + std::to_string(c)) {} + const size_t requested; + const size_t valid_count; }; // The input Row object is not attached - struct DetatchedAccessorException { }; + struct DetatchedAccessorException : public std::runtime_error { + DetatchedAccessorException() : std::runtime_error("Atempting to access an invalid object") {} + }; // The input Row object belongs to a different table - struct IncorrectTableException { - StringData expected; - StringData actual; + struct IncorrectTableException : public std::runtime_error { + IncorrectTableException(StringData e, StringData a, const std::string &error) : + expected(e), actual(a), std::runtime_error(error) {} + const StringData expected; + const StringData actual; }; // The requested aggregate operation is not supported for the column type - struct UnsupportedColumnTypeException { + struct UnsupportedColumnTypeException : public std::runtime_error { size_t column_index; StringData column_name; DataType column_type; diff --git a/src/object-store/shared_realm.hpp b/src/object-store/shared_realm.hpp index 3a31d878..0503282a 100644 --- a/src/object-store/shared_realm.hpp +++ b/src/object-store/shared_realm.hpp @@ -105,10 +105,6 @@ namespace realm { // Realm after closing it will produce undefined behavior. void close(); - // Close this Realm and remove it from the cache. Continuing to use a - // Realm after closing it will produce undefined behavior. - void close(); - ~Realm(); private: