From f4dc155ba557d127f59ff87ae1bc986d3857ac66 Mon Sep 17 00:00:00 2001 From: Alexis Kofman Date: Fri, 6 May 2016 18:49:55 +0200 Subject: [PATCH] Fixes async options when not specified from the schema --- lib/index.js | 180 ++++++++++++++++++++++++++------------------------- test/test.js | 2 +- 2 files changed, 92 insertions(+), 90 deletions(-) diff --git a/lib/index.js b/lib/index.js index 2f7419a..9000265 100644 --- a/lib/index.js +++ b/lib/index.js @@ -104,8 +104,8 @@ exports.setSchema = function (schema) { }); /** - * Transform a relational object into a PouchDB doc. - */ + * Transform a relational object into a PouchDB doc. + */ function toRawDoc(typeInfo, obj) { obj = extend(true, {}, obj); var doc = {}; @@ -155,8 +155,8 @@ exports.setSchema = function (schema) { } /** - * Transform a PouchDB doc into a relational object. - */ + * Transform a PouchDB doc into a relational object. + */ function fromRawDoc(pouchDoc) { var obj = pouchDoc.data; obj.id = deserialize(pouchDoc._id); @@ -241,7 +241,7 @@ exports.setSchema = function (schema) { opts.skip = idOrIds.skip; } } else { - // find by single id + // find by single id opts.key = serialize(typeInfo.documentType, idOrIds); } @@ -257,68 +257,70 @@ exports.setSchema = function (schema) { foundObjects.get(type).set(JSON.stringify(obj.id), obj); - // fetch all relations var subTasks = []; - Object.keys(typeInfo.relations || {}).forEach(function (field) { - var relationDef = typeInfo.relations[field]; - var relationType = Object.keys(relationDef)[0]; - var relatedType = relationDef[relationType]; - if (typeof relatedType !== 'string') { - var relationOptions = relatedType.options; - var async = idOrIds && idOrIds.async; - if (async || (relationOptions && relationOptions.async && (async === undefined))) { - return; - } - relatedType = relatedType.type; - } - if (relationType === 'belongsTo') { - var relatedId = obj[field]; - if (typeof relatedId !== 'undefined') { - subTasks.push(Promise.resolve().then(function () { - - // short-circuit if it's already in the foundObjects - // else we could get caught in an infinite loop - if (foundObjects.has(relatedType) && - foundObjects.get(relatedType).has(JSON.stringify(relatedId))) { - return; - } - - // signal that we need to fetch it - return { - relatedType: relatedType, - relatedIds: [relatedId] - }; - })); + + if (!idOrIds || !idOrIds.async) { + // fetch all relations + Object.keys(typeInfo.relations || {}).forEach(function (field) { + var relationDef = typeInfo.relations[field]; + var relationType = Object.keys(relationDef)[0]; + var relatedType = relationDef[relationType]; + if (typeof relatedType !== 'string') { + var relationOptions = relatedType.options; + if (relationOptions && relationOptions.async && typeof idOrIds === 'undefined') { + return; + } + relatedType = relatedType.type; } - } else { // hasMany - var relatedIds = extend(true, [], obj[field]); - if (typeof relatedIds !== 'undefined' && relatedIds.length) { - subTasks.push(Promise.resolve().then(function () { - - // filter out all ids that are already in the foundObjects - for (var i = relatedIds.length - 1; i >= 0; i--) { - var relatedId = relatedIds[i]; + if (relationType === 'belongsTo') { + var relatedId = obj[field]; + if (typeof relatedId !== 'undefined') { + subTasks.push(Promise.resolve().then(function () { + + // short-circuit if it's already in the foundObjects + // else we could get caught in an infinite loop if (foundObjects.has(relatedType) && - foundObjects.get(relatedType).has(JSON.stringify(relatedId))) { - delete relatedIds[i]; + foundObjects.get(relatedType).has(JSON.stringify(relatedId))) { + return; } - } - relatedIds = relatedIds.filter(function (relatedId) { - return typeof relatedId !== 'undefined'; - }); - - // just return the ids and the types. We'll find them all - // in a single bulk operation in order to minimize HTTP requests - if (relatedIds.length) { + + // signal that we need to fetch it return { relatedType: relatedType, - relatedIds: relatedIds + relatedIds: [relatedId] }; - } - })); + })); + } + } else { // hasMany + var relatedIds = extend(true, [], obj[field]); + if (typeof relatedIds !== 'undefined' && relatedIds.length) { + subTasks.push(Promise.resolve().then(function () { + + // filter out all ids that are already in the foundObjects + for (var i = relatedIds.length - 1; i >= 0; i--) { + var relatedId = relatedIds[i]; + if (foundObjects.has(relatedType) && + foundObjects.get(relatedType).has(JSON.stringify(relatedId))) { + delete relatedIds[i]; + } + } + relatedIds = relatedIds.filter(function (relatedId) { + return typeof relatedId !== 'undefined'; + }); + + // just return the ids and the types. We'll find them all + // in a single bulk operation in order to minimize HTTP requests + if (relatedIds.length) { + return { + relatedType: relatedType, + relatedIds: relatedIds + }; + } + })); + } } - } - }); + }); + } return Promise.all(subTasks); }); return Promise.all(tasks); @@ -331,7 +333,7 @@ exports.setSchema = function (schema) { return; } typesToIds[fetchTask.relatedType] = - (typesToIds[fetchTask.relatedType] || []).concat(fetchTask.relatedIds); + (typesToIds[fetchTask.relatedType] || []).concat(fetchTask.relatedIds); }); }); @@ -417,41 +419,41 @@ exports.setSchema = function (schema) { if (!defaultType) { var matchingSchemaTypes = schema.filter( function (schemaType) { return schemaType.documentType === type; }); - if (matchingSchemaTypes.length > 0) { - type = matchingSchemaTypes[0].singular; + if (matchingSchemaTypes.length > 0) { + type = matchingSchemaTypes[0].singular; + } } + + return { + type: type, + id: relId + }; } - return { - type: type, - id: relId - }; - } + function makeDocID(obj) { + var type = obj.type; - function makeDocID(obj) { - var type = obj.type; + var typeInfo = keysToSchemas.get(type); + if (typeInfo) { + type = typeInfo.documentType; + } - var typeInfo = keysToSchemas.get(type); - if (typeInfo) { - type = typeInfo.documentType; + return serialize(type, obj.id); } - return serialize(type, obj.id); - } - - db.rel = { - save: save, - find: find, - del: del, - getAttachment: getAttachment, - putAttachment: putAttachment, - removeAttachment: removeAttachment, - parseDocID: parseDocID, - makeDocID: makeDocID + db.rel = { + save: save, + find: find, + del: del, + getAttachment: getAttachment, + putAttachment: putAttachment, + removeAttachment: removeAttachment, + parseDocID: parseDocID, + makeDocID: makeDocID + }; }; -}; -/* istanbul ignore next */ -if (typeof window !== 'undefined' && window.PouchDB) { - window.PouchDB.plugin(exports); -} + /* istanbul ignore next */ + if (typeof window !== 'undefined' && window.PouchDB) { + window.PouchDB.plugin(exports); + } diff --git a/test/test.js b/test/test.js index e60bfcf..079120b 100644 --- a/test/test.js +++ b/test/test.js @@ -1990,7 +1990,7 @@ function tests(dbName, dbType) { singular: 'author', plural: 'authors', relations: { - books: {hasMany: {type: 'books', options: {async: false}}} + books: {hasMany: 'books'} } }, {