upgrade to latest core and object store
This commit is contained in:
commit
4daa1ff5a1
|
@ -4,6 +4,10 @@ if(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")
|
||||||
set(MAKE_EQUAL_MAKE "MAKE=$(MAKE)")
|
set(MAKE_EQUAL_MAKE "MAKE=$(MAKE)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(SANITIZE_ADDRESS)
|
||||||
|
set(MAKEFLAGS "MAKEFLAGS=EXTRA_CFLAGS=-fsanitize=address EXTRA_LDFLAGS=-fsanitize=address")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (${CMAKE_VERSION} VERSION_GREATER "3.4.0")
|
if (${CMAKE_VERSION} VERSION_GREATER "3.4.0")
|
||||||
set(USES_TERMINAL_BUILD USES_TERMINAL_BUILD 1)
|
set(USES_TERMINAL_BUILD USES_TERMINAL_BUILD 1)
|
||||||
endif()
|
endif()
|
||||||
|
@ -91,7 +95,7 @@ function(clone_and_build_realm_core branch)
|
||||||
PREFIX ${core_prefix_directory}
|
PREFIX ${core_prefix_directory}
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ${MAKE_EQUAL_MAKE} sh build.sh build
|
BUILD_COMMAND export ${MAKEFLAGS} && ${MAKE_EQUAL_MAKE} sh build.sh build
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
${USES_TERMINAL_BUILD}
|
${USES_TERMINAL_BUILD}
|
||||||
)
|
)
|
||||||
|
@ -109,7 +113,7 @@ function(build_existing_realm_core core_directory)
|
||||||
BUILD_IN_SOURCE 1
|
BUILD_IN_SOURCE 1
|
||||||
BUILD_ALWAYS 1
|
BUILD_ALWAYS 1
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ${MAKE_EQUAL_MAKE} sh build.sh build
|
BUILD_COMMAND export ${MAKEFLAGS} && ${MAKE_EQUAL_MAKE} sh build.sh build
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
${USES_TERMINAL_BUILD}
|
${USES_TERMINAL_BUILD}
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
option(SANITIZE_ADDRESS "build with ASan")
|
||||||
|
option(SANITIZE_THREAD "build with TSan")
|
||||||
|
option(SANITIZE_UNDEFINED "build with UBSan")
|
||||||
|
|
||||||
|
if(SANITIZE_ADDRESS)
|
||||||
|
set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=address")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SANITIZE_THREAD)
|
||||||
|
set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=thread")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SANITIZE_UNDEFINED)
|
||||||
|
set(SANITIZER_FLAGS "${SANITIZER_FLAGS} -fsanitize=undefined")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(SANITIZE_ADDRESS OR SANITIZE_THREAD OR SANITIZE_UNDEFINED)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAGS} -fno-omit-frame-pointer")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZER_FLAGS}")
|
||||||
|
endif()
|
|
@ -1,13 +1,15 @@
|
||||||
|
cmake_minimum_required(VERSION 3.2.0)
|
||||||
|
|
||||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "")
|
set(CMAKE_BUILD_TYPE Debug CACHE STRING "")
|
||||||
project(realm-object-store)
|
project(realm-object-store)
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.2.0)
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
|
||||||
|
|
||||||
include(CompilerFlags)
|
include(CompilerFlags)
|
||||||
|
include(Sanitizers)
|
||||||
|
|
||||||
include(RealmCore)
|
include(RealmCore)
|
||||||
set(REALM_CORE_VERSION "0.97.0" CACHE STRING "")
|
set(REALM_CORE_VERSION "0.100.1" CACHE STRING "")
|
||||||
use_realm_core(${REALM_CORE_VERSION})
|
use_realm_core(${REALM_CORE_VERSION})
|
||||||
|
|
||||||
include_directories(${REALM_CORE_INCLUDE_DIR} src external/pegtl)
|
include_directories(${REALM_CORE_INCLUDE_DIR} src external/pegtl)
|
||||||
|
|
|
@ -36,6 +36,14 @@ cmake -DREALM_CORE_VERSION=/path/to/realm-core
|
||||||
|
|
||||||
The given core tree will be built as part of the object store build.
|
The given core tree will be built as part of the object store build.
|
||||||
|
|
||||||
|
### Building with Sanitizers
|
||||||
|
|
||||||
|
The object store can be built using ASan, TSan and/or UBSan by specifying `-DSANITIZE_ADDRESS=1`, `-DSANITIZE_THREAD=1`, or `-DSANITIZE_UNDEFINED=1` when inoking CMake.
|
||||||
|
Building with ASan requires specifying a path to core with `-DREAM_CORE_VERSION` as core needs to also be built with ASan enabled.
|
||||||
|
|
||||||
|
On OS X, the Xcode-provided copy of Clang only comes with ASan, and using TSan or UBSan requires a custom build of Clang.
|
||||||
|
If you have installed Clang as an external Xcode toolchain (using the `install-xcode-toolchain` when building LLVM), note that you'll have to specify `-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++` when running `cmake` to stop cmake from being too clever.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -152,17 +152,9 @@ RealmCoordinator::~RealmCoordinator()
|
||||||
void RealmCoordinator::unregister_realm(Realm* realm)
|
void RealmCoordinator::unregister_realm(Realm* realm)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(m_realm_mutex);
|
std::lock_guard<std::mutex> lock(m_realm_mutex);
|
||||||
for (size_t i = 0; i < m_weak_realm_notifiers.size(); ++i) {
|
auto new_end = remove_if(begin(m_weak_realm_notifiers), end(m_weak_realm_notifiers),
|
||||||
auto& weak_realm_notifier = m_weak_realm_notifiers[i];
|
[=](auto& notifier) { return notifier.expired() || notifier.is_for_realm(realm); });
|
||||||
if (!weak_realm_notifier.expired() && !weak_realm_notifier.is_for_realm(realm)) {
|
m_weak_realm_notifiers.erase(new_end, end(m_weak_realm_notifiers));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i + 1 < m_weak_realm_notifiers.size()) {
|
|
||||||
weak_realm_notifier = std::move(m_weak_realm_notifiers.back());
|
|
||||||
}
|
|
||||||
m_weak_realm_notifiers.pop_back();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealmCoordinator::clear_cache()
|
void RealmCoordinator::clear_cache()
|
||||||
|
|
|
@ -124,7 +124,8 @@ public:
|
||||||
bool set_double(size_t, size_t, double) { return true; }
|
bool set_double(size_t, size_t, double) { return true; }
|
||||||
bool set_string(size_t, size_t, StringData) { return true; }
|
bool set_string(size_t, size_t, StringData) { return true; }
|
||||||
bool set_binary(size_t, size_t, BinaryData) { return true; }
|
bool set_binary(size_t, size_t, BinaryData) { return true; }
|
||||||
bool set_date_time(size_t, size_t, DateTime) { return true; }
|
bool set_olddatetime(size_t, size_t, OldDateTime) { return true; }
|
||||||
|
bool set_timestamp(size_t, size_t, Timestamp) { return true; }
|
||||||
bool set_table(size_t, size_t) { return true; }
|
bool set_table(size_t, size_t) { return true; }
|
||||||
bool set_mixed(size_t, size_t, const Mixed&) { return true; }
|
bool set_mixed(size_t, size_t, const Mixed&) { return true; }
|
||||||
bool set_link(size_t, size_t, size_t, size_t) { return true; }
|
bool set_link(size_t, size_t, size_t, size_t) { return true; }
|
||||||
|
@ -416,7 +417,8 @@ public:
|
||||||
bool set_double(size_t col, size_t row, double) { return mark_dirty(row, col); }
|
bool set_double(size_t col, size_t row, double) { return mark_dirty(row, col); }
|
||||||
bool set_string(size_t col, size_t row, StringData) { return mark_dirty(row, col); }
|
bool set_string(size_t col, size_t row, StringData) { return mark_dirty(row, col); }
|
||||||
bool set_binary(size_t col, size_t row, BinaryData) { return mark_dirty(row, col); }
|
bool set_binary(size_t col, size_t row, BinaryData) { return mark_dirty(row, col); }
|
||||||
bool set_date_time(size_t col, size_t row, DateTime) { return mark_dirty(row, col); }
|
bool set_olddatetime(size_t col, size_t row, OldDateTime) { return mark_dirty(row, col); }
|
||||||
|
bool set_timestamp(size_t col, size_t row, Timestamp) { return mark_dirty(row, col); }
|
||||||
bool set_table(size_t col, size_t row) { return mark_dirty(row, col); }
|
bool set_table(size_t col, size_t row) { return mark_dirty(row, col); }
|
||||||
bool set_mixed(size_t col, size_t row, const Mixed&) { return mark_dirty(row, col); }
|
bool set_mixed(size_t col, size_t row, const Mixed&) { return mark_dirty(row, col); }
|
||||||
bool set_link(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); }
|
bool set_link(size_t col, size_t row, size_t, size_t) { return mark_dirty(row, col); }
|
||||||
|
|
|
@ -87,8 +87,8 @@ namespace realm {
|
||||||
static ValueType from_string(ContextType, StringData);
|
static ValueType from_string(ContextType, StringData);
|
||||||
static std::string to_binary(ContextType, ValueType &);
|
static std::string to_binary(ContextType, ValueType &);
|
||||||
static ValueType from_binary(ContextType, BinaryData);
|
static ValueType from_binary(ContextType, BinaryData);
|
||||||
static DateTime to_datetime(ContextType, ValueType &);
|
static Timestamp to_timestamp(ContextType, ValueType &);
|
||||||
static ValueType from_datetime(ContextType, DateTime);
|
static ValueType from_timestamp(ContextType, Timestamp);
|
||||||
|
|
||||||
static bool is_null(ContextType, ValueType &);
|
static bool is_null(ContextType, ValueType &);
|
||||||
static ValueType null_value(ContextType);
|
static ValueType null_value(ContextType);
|
||||||
|
@ -197,9 +197,11 @@ namespace realm {
|
||||||
case PropertyTypeDouble:
|
case PropertyTypeDouble:
|
||||||
m_row.set_double(column, Accessor::to_double(ctx, value));
|
m_row.set_double(column, Accessor::to_double(ctx, value));
|
||||||
break;
|
break;
|
||||||
case PropertyTypeString:
|
case PropertyTypeString: {
|
||||||
m_row.set_string(column, Accessor::to_string(ctx, value));
|
auto string_value = Accessor::to_string(ctx, value);
|
||||||
|
m_row.set_string(column, string_value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PropertyTypeData:
|
case PropertyTypeData:
|
||||||
m_row.set_binary(column, BinaryData(Accessor::to_binary(ctx, value)));
|
m_row.set_binary(column, BinaryData(Accessor::to_binary(ctx, value)));
|
||||||
break;
|
break;
|
||||||
|
@ -207,7 +209,7 @@ namespace realm {
|
||||||
m_row.set_mixed(column, Accessor::to_mixed(ctx, value));
|
m_row.set_mixed(column, Accessor::to_mixed(ctx, value));
|
||||||
break;
|
break;
|
||||||
case PropertyTypeDate:
|
case PropertyTypeDate:
|
||||||
m_row.set_datetime(column, Accessor::to_datetime(ctx, value));
|
m_row.set_timestamp(column, Accessor::to_timestamp(ctx, value));
|
||||||
break;
|
break;
|
||||||
case PropertyTypeObject: {
|
case PropertyTypeObject: {
|
||||||
if (Accessor::is_null(ctx, value)) {
|
if (Accessor::is_null(ctx, value)) {
|
||||||
|
@ -261,7 +263,7 @@ namespace realm {
|
||||||
case PropertyTypeAny:
|
case PropertyTypeAny:
|
||||||
throw "Any not supported";
|
throw "Any not supported";
|
||||||
case PropertyTypeDate:
|
case PropertyTypeDate:
|
||||||
return Accessor::from_datetime(ctx, m_row.get_datetime(column));
|
return Accessor::from_timestamp(ctx, m_row.get_timestamp(column));
|
||||||
case PropertyTypeObject: {
|
case PropertyTypeObject: {
|
||||||
auto linkObjectSchema = m_realm->config().schema->find(property.object_type);
|
auto linkObjectSchema = m_realm->config().schema->find(property.object_type);
|
||||||
TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), linkObjectSchema->name);
|
TableRef table = ObjectStore::table_for_object_type(m_realm->read_group(), linkObjectSchema->name);
|
||||||
|
@ -297,7 +299,8 @@ namespace realm {
|
||||||
// search for existing object based on primary key type
|
// search for existing object based on primary key type
|
||||||
ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
|
ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
|
||||||
if (primary_prop->type == PropertyTypeString) {
|
if (primary_prop->type == PropertyTypeString) {
|
||||||
row_index = table->find_first_string(primary_prop->table_column, Accessor::to_string(ctx, primary_value));
|
auto primary_string = Accessor::to_string(ctx, primary_value);
|
||||||
|
row_index = table->find_first_string(primary_prop->table_column, primary_string);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
row_index = table->find_first_int(primary_prop->table_column, Accessor::to_long(ctx, primary_value));
|
row_index = table->find_first_int(primary_prop->table_column, Accessor::to_long(ctx, primary_value));
|
||||||
|
|
|
@ -17,14 +17,29 @@
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "object_schema.hpp"
|
#include "object_schema.hpp"
|
||||||
|
|
||||||
#include "object_store.hpp"
|
#include "object_store.hpp"
|
||||||
#include "property.hpp"
|
#include "property.hpp"
|
||||||
|
|
||||||
#include <realm/group_shared.hpp>
|
#include <realm/data_type.hpp>
|
||||||
#include <realm/link_view.hpp>
|
#include <realm/table.hpp>
|
||||||
|
|
||||||
using namespace realm;
|
using namespace realm;
|
||||||
|
|
||||||
|
#define ASSERT_PROPERTY_TYPE_VALUE(property, type) \
|
||||||
|
static_assert(static_cast<int>(PropertyType##property) == type_##type, \
|
||||||
|
"PropertyType and DataType must have the same values")
|
||||||
|
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Int, Int);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Bool, Bool);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Float, Float);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Double, Double);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Data, Binary);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Date, Timestamp);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Any, Mixed);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Object, Link);
|
||||||
|
ASSERT_PROPERTY_TYPE_VALUE(Array, LinkList);
|
||||||
|
|
||||||
ObjectSchema::~ObjectSchema() = default;
|
ObjectSchema::~ObjectSchema() = default;
|
||||||
|
|
||||||
ObjectSchema::ObjectSchema(std::string name, std::string primary_key, std::initializer_list<Property> properties)
|
ObjectSchema::ObjectSchema(std::string name, std::string primary_key, std::initializer_list<Property> properties)
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "schema.hpp"
|
#include "schema.hpp"
|
||||||
|
|
||||||
#include <realm/group.hpp>
|
#include <realm/group.hpp>
|
||||||
#include <realm/link_view.hpp>
|
|
||||||
#include <realm/table.hpp>
|
#include <realm/table.hpp>
|
||||||
#include <realm/table_view.hpp>
|
#include <realm/table_view.hpp>
|
||||||
#include <realm/util/assert.hpp>
|
#include <realm/util/assert.hpp>
|
||||||
|
@ -128,15 +127,18 @@ std::string ObjectStore::table_name_for_object_type(StringData object_type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TableRef ObjectStore::table_for_object_type(Group *group, StringData object_type) {
|
TableRef ObjectStore::table_for_object_type(Group *group, StringData object_type) {
|
||||||
return group->get_table(table_name_for_object_type(object_type));
|
auto name = table_name_for_object_type(object_type);
|
||||||
|
return group->get_table(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstTableRef ObjectStore::table_for_object_type(const Group *group, StringData object_type) {
|
ConstTableRef ObjectStore::table_for_object_type(const Group *group, StringData object_type) {
|
||||||
return group->get_table(table_name_for_object_type(object_type));
|
auto name = table_name_for_object_type(object_type);
|
||||||
|
return group->get_table(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
TableRef ObjectStore::table_for_object_type_create_if_needed(Group *group, StringData object_type, bool &created) {
|
TableRef ObjectStore::table_for_object_type_create_if_needed(Group *group, StringData object_type, bool &created) {
|
||||||
return group->get_or_add_table(table_name_for_object_type(object_type), &created);
|
auto name = table_name_for_object_type(object_type);
|
||||||
|
return group->get_or_add_table(name, &created);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool property_has_changed(Property const& p1, Property const& p2) {
|
static inline bool property_has_changed(Property const& p1, Property const& p2) {
|
||||||
|
@ -241,7 +243,7 @@ static void copy_property_values(const Property& source, const Property& destina
|
||||||
copy_property_values(source, destination, table, &Table::get_binary, &Table::set_binary);
|
copy_property_values(source, destination, table, &Table::get_binary, &Table::set_binary);
|
||||||
break;
|
break;
|
||||||
case PropertyTypeDate:
|
case PropertyTypeDate:
|
||||||
copy_property_values(source, destination, table, &Table::get_datetime, &Table::set_datetime);
|
copy_property_values(source, destination, table, &Table::get_timestamp, &Table::set_timestamp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -288,14 +288,13 @@ template <typename RequestedType, typename TableGetter>
|
||||||
struct ValueGetter;
|
struct ValueGetter;
|
||||||
|
|
||||||
template <typename TableGetter>
|
template <typename TableGetter>
|
||||||
struct ValueGetter<DateTime, TableGetter> {
|
struct ValueGetter<Timestamp, TableGetter> {
|
||||||
static Int convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
static Timestamp convert(TableGetter&&, const parser::Expression & value, Arguments &args)
|
||||||
{
|
{
|
||||||
if (value.type != parser::Expression::Type::Argument) {
|
if (value.type != parser::Expression::Type::Argument) {
|
||||||
throw std::runtime_error("You must pass in a date argument to compare");
|
throw std::runtime_error("You must pass in a date argument to compare");
|
||||||
}
|
}
|
||||||
DateTime dt = args.datetime_for_argument(stot<int>(value.s));
|
return args.timestamp_for_argument(stot<int>(value.s));
|
||||||
return dt.get_datetime();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -390,8 +389,8 @@ void do_add_comparison_to_query(Query &query, const Schema &schema, const Object
|
||||||
value_of_type_for_query<bool>(expr.table_getter, rhs, args));
|
value_of_type_for_query<bool>(expr.table_getter, rhs, args));
|
||||||
break;
|
break;
|
||||||
case PropertyTypeDate:
|
case PropertyTypeDate:
|
||||||
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<DateTime>(expr.table_getter, lhs, args),
|
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<Timestamp>(expr.table_getter, lhs, args),
|
||||||
value_of_type_for_query<DateTime>(expr.table_getter, rhs, args));
|
value_of_type_for_query<Timestamp>(expr.table_getter, rhs, args));
|
||||||
break;
|
break;
|
||||||
case PropertyTypeDouble:
|
case PropertyTypeDouble:
|
||||||
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<Double>(expr.table_getter, lhs, args),
|
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<Double>(expr.table_getter, lhs, args),
|
||||||
|
@ -481,7 +480,7 @@ void do_add_null_comparison_to_query(Query &query, const Schema &schema, const O
|
||||||
do_add_null_comparison_to_query<bool>(query, cmp.op, expr, args);
|
do_add_null_comparison_to_query<bool>(query, cmp.op, expr, args);
|
||||||
break;
|
break;
|
||||||
case PropertyTypeDate:
|
case PropertyTypeDate:
|
||||||
do_add_null_comparison_to_query<DateTime>(query, cmp.op, expr, args);
|
do_add_null_comparison_to_query<Timestamp>(query, cmp.op, expr, args);
|
||||||
break;
|
break;
|
||||||
case PropertyTypeDouble:
|
case PropertyTypeDouble:
|
||||||
do_add_null_comparison_to_query<Double>(query, cmp.op, expr, args);
|
do_add_null_comparison_to_query<Double>(query, cmp.op, expr, args);
|
||||||
|
|
|
@ -19,11 +19,11 @@
|
||||||
#ifndef REALM_QUERY_BUILDER_HPP
|
#ifndef REALM_QUERY_BUILDER_HPP
|
||||||
#define REALM_QUERY_BUILDER_HPP
|
#define REALM_QUERY_BUILDER_HPP
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <realm/util/to_string.hpp>
|
|
||||||
#include "parser.hpp"
|
#include "parser.hpp"
|
||||||
#include "object_accessor.hpp"
|
#include "object_accessor.hpp"
|
||||||
|
|
||||||
|
#include <realm/util/to_string.hpp>
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
class Query;
|
class Query;
|
||||||
class Schema;
|
class Schema;
|
||||||
|
@ -31,10 +31,10 @@ class Schema;
|
||||||
namespace query_builder {
|
namespace query_builder {
|
||||||
class Arguments;
|
class Arguments;
|
||||||
|
|
||||||
void apply_predicate(Query &query, const parser::Predicate &predicate, Arguments &arguments, const Schema &schema, const std::string &objectType);
|
void apply_predicate(Query &query, const parser::Predicate &predicate, Arguments &arguments,
|
||||||
|
const Schema &schema, const std::string &objectType);
|
||||||
|
|
||||||
class Arguments
|
class Arguments {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
virtual bool bool_for_argument(size_t argument_index) = 0;
|
virtual bool bool_for_argument(size_t argument_index) = 0;
|
||||||
virtual long long long_for_argument(size_t argument_index) = 0;
|
virtual long long long_for_argument(size_t argument_index) = 0;
|
||||||
|
@ -42,14 +42,13 @@ class Arguments
|
||||||
virtual double double_for_argument(size_t argument_index) = 0;
|
virtual double double_for_argument(size_t argument_index) = 0;
|
||||||
virtual std::string string_for_argument(size_t argument_index) = 0;
|
virtual std::string string_for_argument(size_t argument_index) = 0;
|
||||||
virtual std::string binary_for_argument(size_t argument_index) = 0;
|
virtual std::string binary_for_argument(size_t argument_index) = 0;
|
||||||
virtual DateTime datetime_for_argument(size_t argument_index) = 0;
|
virtual Timestamp timestamp_for_argument(size_t argument_index) = 0;
|
||||||
virtual size_t object_index_for_argument(size_t argument_index) = 0;
|
virtual size_t object_index_for_argument(size_t argument_index) = 0;
|
||||||
virtual bool is_argument_null(size_t argument_index) = 0;
|
virtual bool is_argument_null(size_t argument_index) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ValueType, typename ContextType>
|
template<typename ValueType, typename ContextType>
|
||||||
class ArgumentConverter : public Arguments
|
class ArgumentConverter : public Arguments {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ArgumentConverter(ContextType context, std::vector<ValueType> arguments) : m_arguments(arguments), m_ctx(context) {};
|
ArgumentConverter(ContextType context, std::vector<ValueType> arguments) : m_arguments(arguments), m_ctx(context) {};
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ class ArgumentConverter : public Arguments
|
||||||
virtual double double_for_argument(size_t argument_index) { return Accessor::to_double(m_ctx, argument_at(argument_index)); }
|
virtual double double_for_argument(size_t argument_index) { return Accessor::to_double(m_ctx, argument_at(argument_index)); }
|
||||||
virtual std::string string_for_argument(size_t argument_index) { return Accessor::to_string(m_ctx, argument_at(argument_index)); }
|
virtual std::string string_for_argument(size_t argument_index) { return Accessor::to_string(m_ctx, argument_at(argument_index)); }
|
||||||
virtual std::string binary_for_argument(size_t argument_index) { return Accessor::to_binary(m_ctx, argument_at(argument_index)); }
|
virtual std::string binary_for_argument(size_t argument_index) { return Accessor::to_binary(m_ctx, argument_at(argument_index)); }
|
||||||
virtual DateTime datetime_for_argument(size_t argument_index) { return Accessor::to_datetime(m_ctx, argument_at(argument_index)); }
|
virtual Timestamp timestamp_for_argument(size_t argument_index) { return Accessor::to_timestamp(m_ctx, argument_at(argument_index)); }
|
||||||
virtual size_t object_index_for_argument(size_t argument_index) { return Accessor::to_existing_object_index(m_ctx, argument_at(argument_index)); }
|
virtual size_t object_index_for_argument(size_t argument_index) { return Accessor::to_existing_object_index(m_ctx, argument_at(argument_index)); }
|
||||||
virtual bool is_argument_null(size_t argument_index) { return Accessor::is_null(m_ctx, argument_at(argument_index)); }
|
virtual bool is_argument_null(size_t argument_index) { return Accessor::is_null(m_ctx, argument_at(argument_index)); }
|
||||||
|
|
||||||
|
|
|
@ -23,25 +23,15 @@
|
||||||
|
|
||||||
namespace realm {
|
namespace realm {
|
||||||
enum PropertyType {
|
enum PropertyType {
|
||||||
/** Integer type: NSInteger, int, long, Int (Swift) */
|
|
||||||
PropertyTypeInt = 0,
|
PropertyTypeInt = 0,
|
||||||
/** Boolean type: BOOL, bool, Bool (Swift) */
|
|
||||||
PropertyTypeBool = 1,
|
PropertyTypeBool = 1,
|
||||||
/** Float type: CGFloat (32bit), float, Float (Swift) */
|
|
||||||
PropertyTypeFloat = 9,
|
PropertyTypeFloat = 9,
|
||||||
/** Double type: CGFloat (64bit), double, Double (Swift) */
|
|
||||||
PropertyTypeDouble = 10,
|
PropertyTypeDouble = 10,
|
||||||
/** String type: NSString, String (Swift) */
|
|
||||||
PropertyTypeString = 2,
|
PropertyTypeString = 2,
|
||||||
/** Data type: NSData */
|
|
||||||
PropertyTypeData = 4,
|
PropertyTypeData = 4,
|
||||||
/** Any type: id, **not supported in Swift** */
|
PropertyTypeAny = 6, // deprecated and will be removed in the future
|
||||||
PropertyTypeAny = 6,
|
PropertyTypeDate = 8,
|
||||||
/** Date type: NSDate */
|
|
||||||
PropertyTypeDate = 7,
|
|
||||||
/** Object type. See [Realm Models](http://realm.io/docs/cocoa/latest/#models) */
|
|
||||||
PropertyTypeObject = 12,
|
PropertyTypeObject = 12,
|
||||||
/** Array type. See [Realm Models](http://realm.io/docs/cocoa/latest/#models) */
|
|
||||||
PropertyTypeArray = 13,
|
PropertyTypeArray = 13,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,7 +45,13 @@ namespace realm {
|
||||||
|
|
||||||
size_t table_column = -1;
|
size_t table_column = -1;
|
||||||
bool requires_index() const { return is_primary || is_indexed; }
|
bool requires_index() const { return is_primary || is_indexed; }
|
||||||
bool is_indexable() const { return type == PropertyTypeInt || type == PropertyTypeBool || type == PropertyTypeString || type == PropertyTypeDate; }
|
bool is_indexable() const
|
||||||
|
{
|
||||||
|
return type == PropertyTypeInt
|
||||||
|
|| type == PropertyTypeBool
|
||||||
|
|| type == PropertyTypeDate
|
||||||
|
|| type == PropertyTypeString;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline const char *string_for_property_type(PropertyType type) {
|
static inline const char *string_for_property_type(PropertyType type) {
|
||||||
|
|
|
@ -223,10 +223,10 @@ size_t Results::index_of(size_t row_ndx)
|
||||||
REALM_UNREACHABLE();
|
REALM_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Int, typename Float, typename Double, typename DateTime>
|
template<typename Int, typename Float, typename Double, typename Timestamp>
|
||||||
util::Optional<Mixed> Results::aggregate(size_t column, bool return_none_for_empty,
|
util::Optional<Mixed> Results::aggregate(size_t column, bool return_none_for_empty,
|
||||||
Int agg_int, Float agg_float,
|
Int agg_int, Float agg_float,
|
||||||
Double agg_double, DateTime agg_datetime)
|
Double agg_double, Timestamp agg_timestamp)
|
||||||
{
|
{
|
||||||
validate_read();
|
validate_read();
|
||||||
if (!m_table)
|
if (!m_table)
|
||||||
|
@ -254,7 +254,7 @@ util::Optional<Mixed> Results::aggregate(size_t column, bool return_none_for_emp
|
||||||
|
|
||||||
switch (m_table->get_column_type(column))
|
switch (m_table->get_column_type(column))
|
||||||
{
|
{
|
||||||
case type_DateTime: return do_agg(agg_datetime);
|
case type_Timestamp: return do_agg(agg_timestamp);
|
||||||
case type_Double: return do_agg(agg_double);
|
case type_Double: return do_agg(agg_double);
|
||||||
case type_Float: return do_agg(agg_float);
|
case type_Float: return do_agg(agg_float);
|
||||||
case type_Int: return do_agg(agg_int);
|
case type_Int: return do_agg(agg_int);
|
||||||
|
@ -269,7 +269,7 @@ util::Optional<Mixed> Results::max(size_t column)
|
||||||
[=](auto const& table) { return table.maximum_int(column); },
|
[=](auto const& table) { return table.maximum_int(column); },
|
||||||
[=](auto const& table) { return table.maximum_float(column); },
|
[=](auto const& table) { return table.maximum_float(column); },
|
||||||
[=](auto const& table) { return table.maximum_double(column); },
|
[=](auto const& table) { return table.maximum_double(column); },
|
||||||
[=](auto const& table) { return table.maximum_datetime(column); });
|
[=](auto const& table) { return table.maximum_timestamp(column); });
|
||||||
}
|
}
|
||||||
|
|
||||||
util::Optional<Mixed> Results::min(size_t column)
|
util::Optional<Mixed> Results::min(size_t column)
|
||||||
|
@ -278,7 +278,7 @@ util::Optional<Mixed> Results::min(size_t column)
|
||||||
[=](auto const& table) { return table.minimum_int(column); },
|
[=](auto const& table) { return table.minimum_int(column); },
|
||||||
[=](auto const& table) { return table.minimum_float(column); },
|
[=](auto const& table) { return table.minimum_float(column); },
|
||||||
[=](auto const& table) { return table.minimum_double(column); },
|
[=](auto const& table) { return table.minimum_double(column); },
|
||||||
[=](auto const& table) { return table.minimum_datetime(column); });
|
[=](auto const& table) { return table.minimum_timestamp(column); });
|
||||||
}
|
}
|
||||||
|
|
||||||
util::Optional<Mixed> Results::sum(size_t column)
|
util::Optional<Mixed> Results::sum(size_t column)
|
||||||
|
|
|
@ -134,7 +134,7 @@ public:
|
||||||
// Get the min/max/average/sum of the given column
|
// Get the min/max/average/sum of the given column
|
||||||
// All but sum() returns none when there are zero matching rows
|
// All but sum() returns none when there are zero matching rows
|
||||||
// sum() returns 0, except for when it returns none
|
// sum() returns 0, except for when it returns none
|
||||||
// Throws UnsupportedColumnTypeException for sum/average on datetime or non-numeric column
|
// Throws UnsupportedColumnTypeException for sum/average on timestamp or non-numeric column
|
||||||
// Throws OutOfBoundsIndexException for an out-of-bounds column
|
// Throws OutOfBoundsIndexException for an out-of-bounds column
|
||||||
util::Optional<Mixed> max(size_t column);
|
util::Optional<Mixed> max(size_t column);
|
||||||
util::Optional<Mixed> min(size_t column);
|
util::Optional<Mixed> min(size_t column);
|
||||||
|
@ -225,10 +225,10 @@ private:
|
||||||
void validate_read() const;
|
void validate_read() const;
|
||||||
void validate_write() const;
|
void validate_write() const;
|
||||||
|
|
||||||
template<typename Int, typename Float, typename Double, typename DateTime>
|
template<typename Int, typename Float, typename Double, typename Timestamp>
|
||||||
util::Optional<Mixed> aggregate(size_t column, bool return_none_for_empty,
|
util::Optional<Mixed> aggregate(size_t column, bool return_none_for_empty,
|
||||||
Int agg_int, Float agg_float,
|
Int agg_int, Float agg_float,
|
||||||
Double agg_double, DateTime agg_datetime);
|
Double agg_double, Timestamp agg_timestamp);
|
||||||
|
|
||||||
void set_table_view(TableView&& tv);
|
void set_table_view(TableView&& tv);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue