From 9e05728dce6908d30a6fd07f21036a45ad651f4c Mon Sep 17 00:00:00 2001 From: Ari Lazier Date: Tue, 24 May 2016 08:23:21 -0700 Subject: [PATCH 1/3] fix for negative timestamps --- CHANGELOG.md | 11 +++++++++++ src/js_object_accessor.hpp | 4 ++-- tests/js/object-tests.js | 17 ++++++++++++++++- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad2ccc9..048726e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +0.13.1 Release notes (yyyy-MM-dd) +============================================================= +### Breaking changes +* None + +### Enhancements +* None + +### Bugfixes +* Fix for crash when inserting dates from before the epoch + 0.13.0 Release notes (2016-5-19) ============================================================= ### Breaking changes diff --git a/src/js_object_accessor.hpp b/src/js_object_accessor.hpp index 4bd985be..326604df 100644 --- a/src/js_object_accessor.hpp +++ b/src/js_object_accessor.hpp @@ -88,8 +88,8 @@ struct NativeAccessor { static Timestamp to_timestamp(ContextType ctx, ValueType &value) { ObjectType date = Value::validated_to_date(ctx, value, "Property"); double milliseconds = Value::to_number(ctx, date); - u_int64_t seconds = milliseconds / 1000; - u_int32_t nanoseconds = ((u_int64_t)milliseconds % 1000) * 1000000; + int64_t seconds = milliseconds / 1000; + int32_t nanoseconds = ((int64_t)milliseconds % 1000) * 1000000; return Timestamp(seconds, nanoseconds); } static ValueType from_timestamp(ContextType ctx, Timestamp ts) { diff --git a/tests/js/object-tests.js b/tests/js/object-tests.js index db231770..ad13da1b 100644 --- a/tests/js/object-tests.js +++ b/tests/js/object-tests.js @@ -474,15 +474,30 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(obj.ignored, true); }, - testCurrentDate: function() { + testDates: function() { Realm.copyBundledRealmFiles(); + // test file format upgrade var realm_v3 = new Realm({path: 'dates-v3.realm', schema: [schemas.DateObject]}); TestCase.assertEqual(realm_v3.objects('Date').length, 1); TestCase.assertEqual(realm_v3.objects('Date')[0].currentDate.getTime(), 1462500087955); + // get new file format is not upgraded var realm_v5 = new Realm({path: 'dates-v5.realm', schema: [schemas.DateObject]}); TestCase.assertEqual(realm_v5.objects('Date').length, 1); TestCase.assertEqual(realm_v5.objects('Date')[0].currentDate.getTime(), 1462500087955); + + // test different dates + var realm = new Realm({schema: [schemas.DateObject]}); + realm.write(function() { + realm.create('Date', { currentDate: new Date(10000) }); + realm.create('Date', { currentDate: new Date(-10000) }); + realm.create('Date', { currentDate: new Date(1000000000000) }); + realm.create('Date', { currentDate: new Date(-1000000000000) }); + }); + TestCase.assertEqual(realm.objects('Date')[0].currentDate.getTime(), 10000); + TestCase.assertEqual(realm.objects('Date')[1].currentDate.getTime(), -10000); + TestCase.assertEqual(realm.objects('Date')[2].currentDate.getTime(), 1000000000000); + TestCase.assertEqual(realm.objects('Date')[3].currentDate.getTime(), -1000000000000); } }); From f8ba388d14aa44d37b39cb1b6b85529b684b7c31 Mon Sep 17 00:00:00 2001 From: Scott Kyle Date: Fri, 20 May 2016 13:42:17 -0700 Subject: [PATCH 2/3] Fix crash and other errors with Results snapshots When deleteAll() is called on a Realm, it calls clear() on all of its Tables, which seems to not update TableViews unless they are synced. The is_row_attached(row_ndx) method still returns true otherwise. A workaround is here until that is fixed. Fixes #434 --- CHANGELOG.md | 1 + src/object-store/src/results.cpp | 19 +++++++++--- tests/js/list-tests.js | 5 ++++ tests/js/results-tests.js | 50 ++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 048726e2..373b7487 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bugfixes * Fix for crash when inserting dates from before the epoch +* Fix for crash when using collection snapshot after realm.deleteAll() 0.13.0 Release notes (2016-5-19) ============================================================= diff --git a/src/object-store/src/results.cpp b/src/object-store/src/results.cpp index 540aac54..fb033bd9 100644 --- a/src/object-store/src/results.cpp +++ b/src/object-store/src/results.cpp @@ -124,9 +124,12 @@ RowExpr Results::get(size_t row_ndx) case Mode::Query: case Mode::TableView: update_tableview(); - if (row_ndx < m_table_view.size()) - return (!m_live && !m_table_view.is_row_attached(row_ndx)) ? RowExpr() : m_table_view.get(row_ndx); - break; + if (row_ndx >= m_table_view.size()) + break; + // FIXME: If clear() was called on the underlying Table, then is_row_attached(row_ndx) will still return true (core issue #1837). + if (!m_live && (m_table_view.get_parent().is_empty() || !m_table_view.is_row_attached(row_ndx))) + return {}; + return m_table_view.get(row_ndx); } throw OutOfBoundsIndexException{row_ndx, size()}; @@ -314,7 +317,15 @@ void Results::clear() case Mode::TableView: validate_write(); update_tableview(); - m_table_view.clear(RemoveMode::unordered); + + if (m_live) { + m_table_view.clear(RemoveMode::unordered); + } + else { + // Copy the TableView because a non-live Results shouldn't have let its size() change. + TableView table_view_copy = m_table_view; + table_view_copy.clear(RemoveMode::unordered); + } break; } } diff --git a/tests/js/list-tests.js b/tests/js/list-tests.js index ab8f8472..8e68e7a5 100644 --- a/tests/js/list-tests.js +++ b/tests/js/list-tests.js @@ -480,6 +480,11 @@ module.exports = BaseTest.extend({ TestCase.assertEqual(objectsCopy.length, 4); TestCase.assertEqual(arrayCopy.length, 2); TestCase.assertEqual(arrayCopy[0], null); + + realm.deleteAll(); + TestCase.assertEqual(objectsCopy.length, 4); + TestCase.assertEqual(arrayCopy.length, 2); + TestCase.assertEqual(arrayCopy[1], null); }); }, diff --git a/tests/js/results-tests.js b/tests/js/results-tests.js index 8a3f3f4e..eb500b53 100644 --- a/tests/js/results-tests.js +++ b/tests/js/results-tests.js @@ -308,5 +308,55 @@ module.exports = BaseTest.extend({ TestCase.assertThrows(function() { objects.sorted('doubleCol', true); }); TestCase.assertThrows(function() { objects.snapshot(); }); }); + }, + + testResultsDeletedObjects: function() { + var realm = new Realm({schema: [schemas.TestObject]}); + + var createTestObjects = function(n) { + for (var i = 0; i < n; i++) { + realm.create('TestObject', {doubleCol: i}); + } + + return realm.objects('TestObject'); + } + + realm.write(function() { + var objects = createTestObjects(10); + var snapshot = objects.snapshot(); + + realm.deleteAll(); + TestCase.assertEqual(objects.length, 0); + TestCase.assertEqual(snapshot.length, 10); + TestCase.assertEqual(snapshot[0], null); + }); + + realm.write(function() { + var objects = createTestObjects(10); + realm.deleteAll(); + + var snapshot = objects.snapshot(); + TestCase.assertEqual(objects.length, 0); + TestCase.assertEqual(snapshot.length, 0); + }); + + realm.write(function() { + var objects = createTestObjects(10); + var snapshot = objects.snapshot(); + + realm.delete(snapshot); + TestCase.assertEqual(objects.length, 0); + TestCase.assertEqual(snapshot.length, 10); + TestCase.assertEqual(snapshot[0], null); + }); + + realm.write(function() { + var objects = createTestObjects(10); + realm.delete(objects); + + var snapshot = objects.snapshot(); + TestCase.assertEqual(objects.length, 0); + TestCase.assertEqual(snapshot.length, 0); + }); } }); From 47776d9b0ad4f3c2fec3fb6756c1162cf1d2194a Mon Sep 17 00:00:00 2001 From: Scott Kyle Date: Tue, 24 May 2016 11:53:10 -0700 Subject: [PATCH 3/3] [0.13.1] Bump version --- CHANGELOG.md | 2 +- package.json | 2 +- src/ios/RealmJS.xcodeproj/project.pbxproj | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 373b7487..894a58dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -0.13.1 Release notes (yyyy-MM-dd) +0.13.1 Release notes (2016-5-24) ============================================================= ### Breaking changes * None diff --git a/package.json b/package.json index 22944d6a..7fc29330 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "realm", "description": "Realm is a mobile database: an alternative to SQLite and key-value stores", - "version": "0.13.0", + "version": "0.13.1", "license": "Apache-2.0", "homepage": "https://realm.io", "keywords": [ diff --git a/src/ios/RealmJS.xcodeproj/project.pbxproj b/src/ios/RealmJS.xcodeproj/project.pbxproj index 5cc3db69..4f9083cc 100644 --- a/src/ios/RealmJS.xcodeproj/project.pbxproj +++ b/src/ios/RealmJS.xcodeproj/project.pbxproj @@ -779,7 +779,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.13.0; + CURRENT_PROJECT_VERSION = 0.13.1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -840,7 +840,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.13.0; + CURRENT_PROJECT_VERSION = 0.13.1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -934,7 +934,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 0.13.0; + CURRENT_PROJECT_VERSION = 0.13.1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -1001,7 +1001,7 @@ buildSettings = { DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0.13.0; + DYLIB_CURRENT_VERSION = 0.13.1; EXECUTABLE_PREFIX = lib; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -1031,7 +1031,7 @@ isa = XCBuildConfiguration; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0.13.0; + DYLIB_CURRENT_VERSION = 0.13.1; EXECUTABLE_PREFIX = lib; GCC_PREPROCESSOR_DEFINITIONS = ( "REALM_PLATFORM_NODE=1", @@ -1060,7 +1060,7 @@ isa = XCBuildConfiguration; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 0.13.0; + DYLIB_CURRENT_VERSION = 0.13.1; EXECUTABLE_PREFIX = lib; GCC_PREPROCESSOR_DEFINITIONS = ( "REALM_PLATFORM_NODE=1",