From d75150aa939129e87f63ec3ffea5e8a40ef86055 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Mon, 18 Jun 2018 22:55:01 +0200 Subject: [PATCH 1/3] Add support for creating template objects --- CHANGELOG.md | 12 ++++++++++++ docs/realm.js | 8 ++++++++ lib/extensions.js | 41 +++++++++++++++++++++++++++++++++++++++++ lib/index.d.ts | 6 ++++++ tests/js/realm-tests.js | 23 +++++++++++++++++++++++ 5 files changed, 90 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d685875..1097b2a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +2.9.0 Release notes (YYYY-MM-DD) +============================================================= +### Compatibility +* Sync protocol: 24 +* Server-side history format: 4 +* File format: 7 +* Realm Object Server: 3.0.0 or later + +### Enhancements +* Added `Realm.createTemplateObject(objectSchema)' (#1870). + + 2.8.4 Release notes (2018-6-15) ============================================================= ### Compatibility diff --git a/docs/realm.js b/docs/realm.js index e6eb215d..ded2998d 100644 --- a/docs/realm.js +++ b/docs/realm.js @@ -132,6 +132,14 @@ class Realm { */ static automaticSyncConfiguration(user) {} + /** + * Creates a template object where all optional fields are `undefined` and all required fields have the default + * value for the given data type, i.e. `0`, false and `""`. + * + * @param {Realm~ObjectSchema} schema object describing the class + */ + static createTemplateObject(objectSchema) {} + /** * Closes this Realm so it may be re-opened with a newer schema version. * All objects and collections from this Realm are no longer valid after calling this method. diff --git a/lib/extensions.js b/lib/extensions.js index bbd5ce4b..8181d108 100644 --- a/lib/extensions.js +++ b/lib/extensions.js @@ -126,6 +126,47 @@ module.exports = function(realmConstructor) { callback(error); }); }, + + createTemplateObject(objectSchema) { + let obj = {}; + for (let key in objectSchema.properties) { + + let type; + if (typeof objectSchema.properties[key] === 'string' || objectSchema.properties[key] instanceof String) { + // Simple declaration of the type + type = objectSchema.properties[key]; + } else { + // Advanced property setup + const property = objectSchema.properties[key]; + + // if optional is set, it wil take precedence over any `?` set on the type parameter + if (property.optional === true) { + continue; + } + + // If a default value is explicitly set, always set the property + if (property.default !== undefined) { + obj[property.name] = property.default; + continue; + } + + type = property.type; + } + + // Set the default value for all required primitive types. + // Lists are always treated as empty if not specified and references to objects are always optional + switch (type) { + case 'bool': obj[key] = false; break; + case 'int': obj[key] = 0; break; + case 'float': obj[key] = 0.0; break; + case 'double': obj[key] = 0.0; break; + case 'string': obj[key] = ""; break; + case 'data': obj[key] = new Uint8Array(0); break; + case 'date': obj[key] = new Date(0); break; + } + } + return obj; + } })); // Add sync methods diff --git a/lib/index.d.ts b/lib/index.d.ts index 11ba8602..2bb42836 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -620,6 +620,12 @@ declare class Realm { */ static automaticSyncConfiguration(user?: Realm.Sync.User): string; + /** + * FIXME + * @returns {T} + */ + static createTemplateObject(objectSchema: Realm.ObjectSchema): T; + /** * Delete the Realm file for the given configuration. * @param {Configuration} config diff --git a/tests/js/realm-tests.js b/tests/js/realm-tests.js index d85f699c..60e046a5 100644 --- a/tests/js/realm-tests.js +++ b/tests/js/realm-tests.js @@ -1256,6 +1256,29 @@ module.exports = { }); }, + testCreateTemplateObject: function() { + var realm = new Realm({schema: [ + schemas.AllTypes, + schemas.DefaultValues, + schemas.TestObject, + schemas.LinkToAllTypes + ]}); + realm.beginTransaction(); + + // Test all simple data types + let template = Realm.createTemplateObject(schemas.AllTypes); + TestCase.assertEqual(Object.keys(template).length, 7); + let unmanagedObj = Object.assign(template, { boolCol: true }); + let managedObj = realm.create(schemas.AllTypes.name, unmanagedObj) ; + TestCase.assertEqual(unmanagedObj, managedObj); + + // Default values + unmanagedObj = Realm.createTemplateObject(schemas.DefaultValues); + TestCase.assertEqual(Object.keys(template).length, 10); + managedObj = realm.create(schemas.DefaultValues.name, template); + TestCase.assertEqual(unmanagedObj, managedObj); + } + // FIXME: reanble test /* From fa96eeec9ee1a1db2f7d6794e788b44a9d026540 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Tue, 19 Jun 2018 00:19:49 +0200 Subject: [PATCH 2/3] Fix tests --- lib/extensions.js | 4 ++-- tests/js/realm-tests.js | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/extensions.js b/lib/extensions.js index 8181d108..cabd02f1 100644 --- a/lib/extensions.js +++ b/lib/extensions.js @@ -146,7 +146,7 @@ module.exports = function(realmConstructor) { // If a default value is explicitly set, always set the property if (property.default !== undefined) { - obj[property.name] = property.default; + obj[key] = property.default; continue; } @@ -161,7 +161,7 @@ module.exports = function(realmConstructor) { case 'float': obj[key] = 0.0; break; case 'double': obj[key] = 0.0; break; case 'string': obj[key] = ""; break; - case 'data': obj[key] = new Uint8Array(0); break; + case 'data': obj[key] = new ArrayBuffer(0); break; case 'date': obj[key] = new Date(0); break; } } diff --git a/tests/js/realm-tests.js b/tests/js/realm-tests.js index 60e046a5..53cee85b 100644 --- a/tests/js/realm-tests.js +++ b/tests/js/realm-tests.js @@ -1270,13 +1270,22 @@ module.exports = { TestCase.assertEqual(Object.keys(template).length, 7); let unmanagedObj = Object.assign(template, { boolCol: true }); let managedObj = realm.create(schemas.AllTypes.name, unmanagedObj) ; - TestCase.assertEqual(unmanagedObj, managedObj); + TestCase.assertEqual(managedObj.boolCol, true); // Default values unmanagedObj = Realm.createTemplateObject(schemas.DefaultValues); - TestCase.assertEqual(Object.keys(template).length, 10); - managedObj = realm.create(schemas.DefaultValues.name, template); - TestCase.assertEqual(unmanagedObj, managedObj); + TestCase.assertEqual(Object.keys(unmanagedObj).length, 10); + managedObj = realm.create(schemas.DefaultValues.name, unmanagedObj); + TestCase.assertEqual(managedObj.boolCol, true); + TestCase.assertEqual(managedObj.intCol, -1); + TestCase.assertEqualWithTolerance(managedObj.floatCol, -1.1, 0.000001); + TestCase.assertEqualWithTolerance(managedObj.doubleCol, -1.11, 0.000001); + TestCase.assertEqual(managedObj.stringCol, 'defaultString'); + TestCase.assertEqual(managedObj.dateCol.getTime(), 1); + TestCase.assertEqual(managedObj.dataCol.byteLength, 1); + TestCase.assertEqual(managedObj.objectCol.doubleCol, 1); + TestCase.assertEqual(managedObj.nullObjectCol, null); + TestCase.assertEqual(managedObj.arrayCol[0].doubleCol, 2); } From fdcedf86f75401b161675ee57486743f4cb90751 Mon Sep 17 00:00:00 2001 From: Christian Melchior Date: Tue, 19 Jun 2018 09:08:14 +0200 Subject: [PATCH 3/3] Docs --- docs/realm.js | 5 +++-- lib/index.d.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/realm.js b/docs/realm.js index 41003e4d..4530d551 100644 --- a/docs/realm.js +++ b/docs/realm.js @@ -133,8 +133,9 @@ class Realm { static automaticSyncConfiguration(user) {} /** - * Creates a template object where all optional fields are `undefined` and all required fields have the default - * value for the given data type, i.e. `0`, false and `""`. + * Creates a template object for a Realm model class where all optional fields are `undefined` and all required + * fields have the default value for the given data type, either the value set by the `default` property in the + * schema or the default value for the datatype if the schema doesn't specify one, i.e. `0`, false and `""`. * * @param {Realm~ObjectSchema} schema object describing the class */ diff --git a/lib/index.d.ts b/lib/index.d.ts index 2bb42836..dcdb1106 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -621,7 +621,7 @@ declare class Realm { static automaticSyncConfiguration(user?: Realm.Sync.User): string; /** - * FIXME + * @param {Realm.ObjectSchema} object schema describing the object that should be created. * @returns {T} */ static createTemplateObject(objectSchema: Realm.ObjectSchema): T;