upgrade to latest core and object store

This commit is contained in:
Ari Lazier 2016-05-05 13:09:07 -07:00
commit 4daa1ff5a1
14 changed files with 110 additions and 68 deletions

View File

@ -4,6 +4,10 @@ if(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")
set(MAKE_EQUAL_MAKE "MAKE=$(MAKE)")
endif()
if(SANITIZE_ADDRESS)
set(MAKEFLAGS "MAKEFLAGS=EXTRA_CFLAGS=-fsanitize=address EXTRA_LDFLAGS=-fsanitize=address")
endif()
if (${CMAKE_VERSION} VERSION_GREATER "3.4.0")
set(USES_TERMINAL_BUILD USES_TERMINAL_BUILD 1)
endif()
@ -91,7 +95,7 @@ function(clone_and_build_realm_core branch)
PREFIX ${core_prefix_directory}
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_EQUAL_MAKE} sh build.sh build
BUILD_COMMAND export ${MAKEFLAGS} && ${MAKE_EQUAL_MAKE} sh build.sh build
INSTALL_COMMAND ""
${USES_TERMINAL_BUILD}
)
@ -109,7 +113,7 @@ function(build_existing_realm_core core_directory)
BUILD_IN_SOURCE 1
BUILD_ALWAYS 1
CONFIGURE_COMMAND ""
BUILD_COMMAND ${MAKE_EQUAL_MAKE} sh build.sh build
BUILD_COMMAND export ${MAKEFLAGS} && ${MAKE_EQUAL_MAKE} sh build.sh build
INSTALL_COMMAND ""
${USES_TERMINAL_BUILD}
)

20
CMake/Sanitizers.cmake Normal file
View File

@ -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()

View File

@ -1,13 +1,15 @@
cmake_minimum_required(VERSION 3.2.0)
set(CMAKE_BUILD_TYPE Debug CACHE STRING "")
project(realm-object-store)
cmake_minimum_required(VERSION 3.2.0)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
include(CompilerFlags)
include(Sanitizers)
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})
include_directories(${REALM_CORE_INCLUDE_DIR} src external/pegtl)

View File

@ -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.
### 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
```

View File

@ -152,17 +152,9 @@ RealmCoordinator::~RealmCoordinator()
void RealmCoordinator::unregister_realm(Realm* realm)
{
std::lock_guard<std::mutex> lock(m_realm_mutex);
for (size_t i = 0; i < m_weak_realm_notifiers.size(); ++i) {
auto& weak_realm_notifier = m_weak_realm_notifiers[i];
if (!weak_realm_notifier.expired() && !weak_realm_notifier.is_for_realm(realm)) {
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();
}
auto new_end = remove_if(begin(m_weak_realm_notifiers), end(m_weak_realm_notifiers),
[=](auto& notifier) { return notifier.expired() || notifier.is_for_realm(realm); });
m_weak_realm_notifiers.erase(new_end, end(m_weak_realm_notifiers));
}
void RealmCoordinator::clear_cache()

View File

@ -124,7 +124,8 @@ public:
bool set_double(size_t, size_t, double) { return true; }
bool set_string(size_t, size_t, StringData) { 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_mixed(size_t, size_t, const Mixed&) { 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_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_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_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); }

View File

@ -87,8 +87,8 @@ namespace realm {
static ValueType from_string(ContextType, StringData);
static std::string to_binary(ContextType, ValueType &);
static ValueType from_binary(ContextType, BinaryData);
static DateTime to_datetime(ContextType, ValueType &);
static ValueType from_datetime(ContextType, DateTime);
static Timestamp to_timestamp(ContextType, ValueType &);
static ValueType from_timestamp(ContextType, Timestamp);
static bool is_null(ContextType, ValueType &);
static ValueType null_value(ContextType);
@ -197,9 +197,11 @@ namespace realm {
case PropertyTypeDouble:
m_row.set_double(column, Accessor::to_double(ctx, value));
break;
case PropertyTypeString:
m_row.set_string(column, Accessor::to_string(ctx, value));
case PropertyTypeString: {
auto string_value = Accessor::to_string(ctx, value);
m_row.set_string(column, string_value);
break;
}
case PropertyTypeData:
m_row.set_binary(column, BinaryData(Accessor::to_binary(ctx, value)));
break;
@ -207,7 +209,7 @@ namespace realm {
m_row.set_mixed(column, Accessor::to_mixed(ctx, value));
break;
case PropertyTypeDate:
m_row.set_datetime(column, Accessor::to_datetime(ctx, value));
m_row.set_timestamp(column, Accessor::to_timestamp(ctx, value));
break;
case PropertyTypeObject: {
if (Accessor::is_null(ctx, value)) {
@ -261,7 +263,7 @@ namespace realm {
case PropertyTypeAny:
throw "Any not supported";
case PropertyTypeDate:
return Accessor::from_datetime(ctx, m_row.get_datetime(column));
return Accessor::from_timestamp(ctx, m_row.get_timestamp(column));
case PropertyTypeObject: {
auto linkObjectSchema = m_realm->config().schema->find(property.object_type);
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
ValueType primary_value = Accessor::dict_value_for_key(ctx, value, object_schema.primary_key);
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 {
row_index = table->find_first_int(primary_prop->table_column, Accessor::to_long(ctx, primary_value));

View File

@ -17,14 +17,29 @@
////////////////////////////////////////////////////////////////////////////
#include "object_schema.hpp"
#include "object_store.hpp"
#include "property.hpp"
#include <realm/group_shared.hpp>
#include <realm/link_view.hpp>
#include <realm/data_type.hpp>
#include <realm/table.hpp>
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(std::string name, std::string primary_key, std::initializer_list<Property> properties)

View File

@ -21,7 +21,6 @@
#include "schema.hpp"
#include <realm/group.hpp>
#include <realm/link_view.hpp>
#include <realm/table.hpp>
#include <realm/table_view.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) {
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) {
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) {
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) {
@ -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);
break;
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;
default:
break;

View File

@ -288,14 +288,13 @@ template <typename RequestedType, typename TableGetter>
struct ValueGetter;
template <typename TableGetter>
struct ValueGetter<DateTime, TableGetter> {
static Int convert(TableGetter&&, const parser::Expression & value, Arguments &args)
struct ValueGetter<Timestamp, TableGetter> {
static Timestamp convert(TableGetter&&, const parser::Expression & value, Arguments &args)
{
if (value.type != parser::Expression::Type::Argument) {
throw std::runtime_error("You must pass in a date argument to compare");
}
DateTime dt = args.datetime_for_argument(stot<int>(value.s));
return dt.get_datetime();
return args.timestamp_for_argument(stot<int>(value.s));
}
};
@ -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));
break;
case PropertyTypeDate:
add_numeric_constraint_to_query(query, cmp.op, value_of_type_for_query<DateTime>(expr.table_getter, lhs, args),
value_of_type_for_query<DateTime>(expr.table_getter, rhs, 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<Timestamp>(expr.table_getter, rhs, args));
break;
case PropertyTypeDouble:
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);
break;
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;
case PropertyTypeDouble:
do_add_null_comparison_to_query<Double>(query, cmp.op, expr, args);

View File

@ -19,11 +19,11 @@
#ifndef REALM_QUERY_BUILDER_HPP
#define REALM_QUERY_BUILDER_HPP
#include <string>
#include <realm/util/to_string.hpp>
#include "parser.hpp"
#include "object_accessor.hpp"
#include <realm/util/to_string.hpp>
namespace realm {
class Query;
class Schema;
@ -31,10 +31,10 @@ class Schema;
namespace query_builder {
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:
virtual bool bool_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 std::string string_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 bool is_argument_null(size_t argument_index) = 0;
};
template<typename ValueType, typename ContextType>
class ArgumentConverter : public Arguments
{
class ArgumentConverter : public Arguments {
public:
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 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 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 bool is_argument_null(size_t argument_index) { return Accessor::is_null(m_ctx, argument_at(argument_index)); }

View File

@ -23,25 +23,15 @@
namespace realm {
enum PropertyType {
/** Integer type: NSInteger, int, long, Int (Swift) */
PropertyTypeInt = 0,
/** Boolean type: BOOL, bool, Bool (Swift) */
PropertyTypeBool = 1,
/** Float type: CGFloat (32bit), float, Float (Swift) */
PropertyTypeFloat = 9,
/** Double type: CGFloat (64bit), double, Double (Swift) */
PropertyTypeDouble = 10,
/** String type: NSString, String (Swift) */
PropertyTypeString = 2,
/** Data type: NSData */
PropertyTypeData = 4,
/** Any type: id, **not supported in Swift** */
PropertyTypeAny = 6,
/** Date type: NSDate */
PropertyTypeDate = 7,
/** Object type. See [Realm Models](http://realm.io/docs/cocoa/latest/#models) */
PropertyTypeAny = 6, // deprecated and will be removed in the future
PropertyTypeDate = 8,
PropertyTypeObject = 12,
/** Array type. See [Realm Models](http://realm.io/docs/cocoa/latest/#models) */
PropertyTypeArray = 13,
};
@ -55,7 +45,13 @@ namespace realm {
size_t table_column = -1;
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) {

View File

@ -223,10 +223,10 @@ size_t Results::index_of(size_t row_ndx)
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,
Int agg_int, Float agg_float,
Double agg_double, DateTime agg_datetime)
Double agg_double, Timestamp agg_timestamp)
{
validate_read();
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))
{
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_Float: return do_agg(agg_float);
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_float(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)
@ -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_float(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)

View File

@ -134,7 +134,7 @@ public:
// Get the min/max/average/sum of the given column
// All but sum() returns none when there are zero matching rows
// 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
util::Optional<Mixed> max(size_t column);
util::Optional<Mixed> min(size_t column);
@ -225,10 +225,10 @@ private:
void validate_read() 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,
Int agg_int, Float agg_float,
Double agg_double, DateTime agg_datetime);
Double agg_double, Timestamp agg_timestamp);
void set_table_view(TableView&& tv);
};