Skip to content

Commit

Permalink
Moved Document.updateReferenceProperties() to utils.updateReferencePr…
Browse files Browse the repository at this point in the history
…operties().
  • Loading branch information
kelp404 committed Jan 29, 2019
1 parent 434b9cb commit b1a38ba
Show file tree
Hide file tree
Showing 9 changed files with 180 additions and 147 deletions.
13 changes: 13 additions & 0 deletions __tests__/__snapshots__/utils.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@

exports[`Bleach regex words. 1`] = `"\\\\^\\\\$\\\\*\\\\+\\\\?\\\\{\\\\}\\\\.\\\\[\\\\]\\\\(\\\\)\\\\\\\\hello\\\\|\\\\/"`;

exports[`Fetch the reference property of the document. 1`] = `
ArticleModel {
"content": null,
"id": null,
"user": UserModel {
"id": "AWiYXbY_SjjuUM2b1CGI",
"name": "enju",
"version": null,
},
"version": null,
}
`;

exports[`Get elasticsearch client. 1`] = `
Object {
"apiVersion": "5.6",
Expand Down
10 changes: 5 additions & 5 deletions __tests__/document.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ generateDataModel = ->

beforeEach ->
DataModel = generateDataModel()
Query.updateReferenceProperties.mockClear?()
utils.updateReferenceProperties.mockClear?()
utils.getIndexPrefix.mockClear?()

test 'Define model.', ->
Expand Down Expand Up @@ -131,11 +131,11 @@ test 'Get the document by id with reference.', ->
_version: 0
_source:
name: 'enju'
Query.updateReferenceProperties = jest.fn (documents) -> new Promise (resolve) ->
utils.updateReferenceProperties = jest.fn (documents) -> new Promise (resolve) ->
expect(documents).toMatchSnapshot()
resolve()
DataModel.get('id').then ->
expect(Query.updateReferenceProperties).toBeCalled()
expect(utils.updateReferenceProperties).toBeCalled()

test 'Get documents by ids without reference.', ->
class DataModel extends enju.Document
Expand Down Expand Up @@ -170,11 +170,11 @@ test 'Get documents by ids with reference.', ->
_source:
name: 'enju'
]
Query.updateReferenceProperties = jest.fn (documents) -> new Promise (resolve) ->
utils.updateReferenceProperties = jest.fn (documents) -> new Promise (resolve) ->
expect(documents).toMatchSnapshot()
resolve()
DataModel.get(['id']).then ->
expect(Query.updateReferenceProperties).toBeCalled()
expect(utils.updateReferenceProperties).toBeCalled()

test 'Is the document exists.', ->
class DataModel extends enju.Document
Expand Down
25 changes: 25 additions & 0 deletions __tests__/utils.coffee
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
config = require 'config'
elasticsearch = require 'elasticsearch'
utils = require '../lib/utils'
enju = require '../'


jest.mock 'elasticsearch'
Expand All @@ -23,3 +24,27 @@ test 'Get index prefix.', ->
test 'Bleach regex words.', ->
result = utils.bleachRegexWords '^$*+?{}.[]()\\hello|/'
expect(result).toMatchSnapshot()

test 'Fetch the reference property of the document.', ->
class UserModel extends enju.Document
@_index = 'users'
@define
name: new enju.StringProperty()
class ArticleModel extends enju.Document
@_index = 'articles'
@define
content: new enju.StringProperty()
user: new enju.ReferenceProperty
referenceClass: UserModel
UserModel.get = jest.fn (ids) -> new Promise (resolve) ->
expect(ids).toEqual ['AWiYXbY_SjjuUM2b1CGI']
resolve [
new UserModel
id: 'AWiYXbY_SjjuUM2b1CGI'
name: 'enju'
]
article = new ArticleModel
user: 'AWiYXbY_SjjuUM2b1CGI'
utils.updateReferenceProperties([article]).then ->
expect(UserModel.get).toBeCalled()
expect(article).toMatchSnapshot()
4 changes: 2 additions & 2 deletions lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@
}
// call resolve()
if (fetchReference) {
return Query.updateReferenceProperties(result).then(function() {
return utils.updateReferenceProperties(result).then(function() {
return resolve(result);
}).catch(function(error) {
return reject(error);
Expand Down Expand Up @@ -217,7 +217,7 @@
// call resolve()
document = new this(args);
if (fetchReference) {
return Query.updateReferenceProperties([document]).then(function() {
return utils.updateReferenceProperties([document]).then(function() {
return resolve(document);
}).catch(function(error) {
return reject(error);
Expand Down
84 changes: 1 addition & 83 deletions lib/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,88 +95,6 @@
this.queryCells = queryCells;
}

// -----------------------------------------------------
// class methods
// -----------------------------------------------------
static updateReferenceProperties(documents) {
return new Promise((resolve, reject) => {
var dataTable, document, documentClassName, documentClasses, documentId, i, items, j, len, len1, property, propertyName, ref, referenceProperties, tasks;
/*
Update reference properties of documents.
@param documents {list<Document>}
@returns {promise}
*/
if (!documents || !documents.length) {
return resolve();
}
dataTable = {}; // {documentClassName: {documentId: {Document}}}
documentClasses = {}; // {documentClassName: documentClass}
referenceProperties = []; // all reference properties in documents
ref = documents[0].constructor._properties;

// scan what kind of documents should be fetched
for (propertyName in ref) {
property = ref[propertyName];
if (property.constructor !== properties.ReferenceProperty) {
continue;
}
if (!(property.referenceClass.name in dataTable)) {
dataTable[property.referenceClass.name] = {};
documentClasses[property.referenceClass.name] = property.referenceClass;
}
referenceProperties.push(property);
}
// scan what id of documents should be fetched
for (i = 0, len = documents.length; i < len; i++) {
document = documents[i];
// loop all reference properties in the document
for (j = 0, len1 = referenceProperties.length; j < len1; j++) {
property = referenceProperties[j];
documentId = document[property.propertyName];
if (documentId) {
dataTable[property.referenceClass.name][documentId] = null;
}
}
}
// fetch documents
tasks = [];
for (documentClassName in dataTable) {
items = dataTable[documentClassName];
tasks.push((function(documentClassName, items) {
return documentClasses[documentClassName].get(Object.keys(items), false).then(function(referenceDocuments) {
var k, len2, referenceDocument, results;
results = [];
for (k = 0, len2 = referenceDocuments.length; k < len2; k++) {
referenceDocument = referenceDocuments[k];
results.push(dataTable[documentClassName][referenceDocument.id] = referenceDocument);
}
return results;
});
})(documentClassName, items));
}
return Promise.all(tasks).then(function() {
var k, l, len2, len3, resolveDocument;
// update reference properties of documents
for (k = 0, len2 = documents.length; k < len2; k++) {
document = documents[k];
// loop all reference properties in the document
for (l = 0, len3 = referenceProperties.length; l < len3; l++) {
property = referenceProperties[l];
resolveDocument = dataTable[property.referenceClass.name][document[property.propertyName]];
if (property.required && !resolveDocument) {
console.log(`There are a reference class can't mapping: ${property.referenceClass.name}::${document[property.propertyName]}`);
continue;
}
document[property.propertyName] = resolveDocument;
}
}
return resolve();
}).catch(function(error) {
return reject(error);
});
});
}

// -----------------------------------------------------
// public methods
// -----------------------------------------------------
Expand Down Expand Up @@ -413,7 +331,7 @@
})();
total = response.hits.total;
if (args.fetchReference) {
return Query.updateReferenceProperties(items).then(function() {
return utils.updateReferenceProperties(items).then(function() {
return resolve({
items: items,
total: total
Expand Down
82 changes: 81 additions & 1 deletion lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(function() {
var config, elasticsearch, util,
var config, elasticsearch, properties, util,
indexOf = [].indexOf;

util = require('util');
Expand All @@ -8,6 +8,8 @@

elasticsearch = require('elasticsearch');

properties = require('./properties');

module.exports = {
getElasticsearch: function() {
/*
Expand Down Expand Up @@ -38,6 +40,84 @@
}
}
return result.join('');
},
updateReferenceProperties: function(documents) {
return new Promise(function(resolve, reject) {
var dataTable, document, documentClassName, documentClasses, documentId, i, items, j, len, len1, property, propertyName, ref, referenceProperties, tasks;
/*
Fetch reference properties of documents.
@param documents {list<Document>}
@returns {promise} The data will direct apply on the arguments.
*/
if (!documents || !documents.length) {
return resolve();
}
dataTable = {}; // {documentClassName: {documentId: {Document}}}
documentClasses = {}; // {documentClassName: documentClass}
referenceProperties = []; // all reference properties in documents
ref = documents[0].constructor._properties;

// scan what kind of documents should be fetched
for (propertyName in ref) {
property = ref[propertyName];
if (property.constructor !== properties.ReferenceProperty) {
continue;
}
if (!(property.referenceClass.name in dataTable)) {
dataTable[property.referenceClass.name] = {};
documentClasses[property.referenceClass.name] = property.referenceClass;
}
referenceProperties.push(property);
}
// scan what id of documents should be fetched
for (i = 0, len = documents.length; i < len; i++) {
document = documents[i];
// loop all reference properties in the document
for (j = 0, len1 = referenceProperties.length; j < len1; j++) {
property = referenceProperties[j];
documentId = document[property.propertyName];
if (documentId) {
dataTable[property.referenceClass.name][documentId] = null;
}
}
}
// fetch documents
tasks = [];
for (documentClassName in dataTable) {
items = dataTable[documentClassName];
tasks.push((function(documentClassName, items) {
return documentClasses[documentClassName].get(Object.keys(items), false).then(function(referenceDocuments) {
var k, len2, referenceDocument, results;
results = [];
for (k = 0, len2 = referenceDocuments.length; k < len2; k++) {
referenceDocument = referenceDocuments[k];
results.push(dataTable[documentClassName][referenceDocument.id] = referenceDocument);
}
return results;
});
})(documentClassName, items));
}
return Promise.all(tasks).then(function() {
var k, l, len2, len3, resolveDocument;
// update reference properties of documents
for (k = 0, len2 = documents.length; k < len2; k++) {
document = documents[k];
// loop all reference properties in the document
for (l = 0, len3 = referenceProperties.length; l < len3; l++) {
property = referenceProperties[l];
resolveDocument = dataTable[property.referenceClass.name][document[property.propertyName]];
if (property.required && !resolveDocument) {
console.log(`There are a reference class can't mapping: ${property.referenceClass.name}::${document[property.propertyName]}`);
continue;
}
document[property.propertyName] = resolveDocument;
}
}
return resolve();
}).catch(function(error) {
return reject(error);
});
});
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/lib/document.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ module.exports = class Document

# call resolve()
if fetchReference
Query.updateReferenceProperties(result).then ->
utils.updateReferenceProperties(result).then ->
resolve result
.catch (error) ->
reject error
Expand Down Expand Up @@ -148,7 +148,7 @@ module.exports = class Document
# call resolve()
document = new @(args)
if fetchReference
Query.updateReferenceProperties([document]).then ->
utils.updateReferenceProperties([document]).then ->
resolve document
.catch (error) ->
reject error
Expand Down
55 changes: 1 addition & 54 deletions src/lib/query.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -64,59 +64,6 @@ module.exports = class Query
@queryCells = queryCells


# -----------------------------------------------------
# class methods
# -----------------------------------------------------
@updateReferenceProperties = (documents) -> new Promise (resolve, reject) =>
###
Update reference properties of documents.
@param documents {list<Document>}
@returns {promise}
###
if not documents or not documents.length
return resolve()

dataTable = {} # {documentClassName: {documentId: {Document}}}
documentClasses = {} # {documentClassName: documentClass}
referenceProperties = [] # all reference properties in documents

# scan what kind of documents should be fetched
for propertyName, property of documents[0].constructor._properties
if property.constructor isnt properties.ReferenceProperty
continue
if property.referenceClass.name not of dataTable
dataTable[property.referenceClass.name] = {}
documentClasses[property.referenceClass.name] = property.referenceClass
referenceProperties.push property

# scan what id of documents should be fetched
for document in documents
for property in referenceProperties # loop all reference properties in the document
documentId = document[property.propertyName]
if documentId
dataTable[property.referenceClass.name][documentId] = null

# fetch documents
tasks = []
for documentClassName, items of dataTable
tasks.push do (documentClassName, items) ->
documentClasses[documentClassName].get(Object.keys(items), no).then (referenceDocuments) ->
for referenceDocument in referenceDocuments
dataTable[documentClassName][referenceDocument.id] = referenceDocument
Promise.all(tasks).then ->
# update reference properties of documents
for document in documents
for property in referenceProperties # loop all reference properties in the document
resolveDocument = dataTable[property.referenceClass.name][document[property.propertyName]]
if property.required and not resolveDocument
console.log "There are a reference class can't mapping: #{property.referenceClass.name}::#{document[property.propertyName]}"
continue
document[property.propertyName] = resolveDocument
resolve()
.catch (error) ->
reject error


# -----------------------------------------------------
# public methods
# -----------------------------------------------------
Expand Down Expand Up @@ -294,7 +241,7 @@ module.exports = class Query
result
total = response.hits.total
if args.fetchReference
Query.updateReferenceProperties(items).then ->
utils.updateReferenceProperties(items).then ->
resolve
items: items
total: total
Expand Down
Loading

0 comments on commit b1a38ba

Please sign in to comment.