function handleDollarUpdates(that, options, query, originalSet, queryKey, queryValue, modifiedSet, document, queryPart, toSet, recordId, isSingleDollar, parentExp) { if (queryKey !== undefined) { var key = queryKey.substr(0, queryKey.indexOf(".")); var restPart = queryKey.substr(queryKey.indexOf(".") + 1); if (queryPart === parentExp) { if (Utils.isJSONObject(document)) { handleNested(that, options, query, originalSet, queryKey, queryValue, modifiedSet, document, queryPart, toSet, recordId, isSingleDollar); } else { var message = "Value should be Jsonobject at break point but found [" + typeof document + "]"; insertLogs(that, options, message, originalSet); // throw new Error("Value should be Jsonobject at break point but found [" + typeof document + "]") } } else { var value = document[key]; if (Array.isArray(value)) { for (var j = 0; j < value.length; j++) { handleDollarUpdates(that, options, query, originalSet, restPart, queryValue, modifiedSet, value[j], queryPart, toSet, recordId, isSingleDollar, parentExp ? parentExp + "." + key : key); } } else if (Utils.isJSONObject(value)) { handleDollarUpdates(that, options, query, originalSet, restPart, queryValue, modifiedSet, value, queryPart, toSet, recordId, isSingleDollar, parentExp ? parentExp + "." + key : key); } else { var message = "value should be array of object for field [" + key + "]"; insertLogs(that, options, message, originalSet); } } } else { return; } }
function handleNested(that, options, query, originalSet, queryKey, queryValue, modifiedSet, document, queryPart, toSet, recordId, isSingleDollar) { if (!Utils.isJSONObject(document)) { // throw Error("document should be object"); var message = "document should be object at break point but found [" + JSON.stringify(document) + "]"; insertLogs(that, options, message, originalSet); } if (isSingleDollar) { handleSingleDollar(that, options, query, queryKey, queryValue, originalSet, document, document._id, queryPart, recordId); } else { var targetValue = document[toSet]; if (targetValue !== undefined) { if (Array.isArray(targetValue) || Utils.isJSONObject(targetValue)) { var restQueryPart = queryKey.substr(queryKey.indexOf(".") + 1); var isChanged = prepareNestedUpdates(restQueryPart, queryValue, originalSet, modifiedSet, targetValue); if (isChanged) { finalUpdateOnMongo(that, options, document, recordId, queryPart, toSet, targetValue, originalSet); } else { return; } } } else { return } } }
function needToAddEventFields(eventFields, fields, parentFields) { // console.log("eventFields>>>>" + JSON.stringify(eventFields)) // console.log("fields>>>>" + JSON.stringify(fields)) // console.log("parentFields>>>>" + JSON.stringify(parentFields)) if ((!fields || fields.length == 0) && (!eventFields || eventFields.length == 0) && (!parentFields || parentFields.length == 0)) { //it will return onInsert/onSave return true; } if (eventFields) { for (var i = 0; i < eventFields.length; i++) { var eventField = eventFields[i]; if (Utils.isJSONObject(eventField) && parentFields && parentFields.length > 0 && eventField[parentFields[0]]) { var newParentFields = []; for (var j = 1; j < parentFields.length; j++) { newParentFields.push(parentFields[j]); } return needToAddEventFields(eventField[parentFields[0]], fields, newParentFields); } else if (typeof eventField == "string" && (!parentFields || parentFields.length == 0)) { // check for onValue if (fields) { for (var j = 0; j < fields.length; j++) { var field = fields[j]; if (Utils.isExists(eventFields, field) !== undefined) { return true; } } } } } } }
Document.prototype.getDocuments = function (property, operation) { if (!this.updates) { return; } validateProperty(property); var value = checkValue.call(this, property); if (Array.isArray(value)) { var docs = handleArray(value, operation, this.oldRecord ? this.oldRecord[property] : null, null, this.requiredValues ? this.requiredValues[property] : null); setDocAsParent(docs, this); return docs; } else if (Utility.isJSONObject(value)) { if (value.$insert || value.$update || value.$delete) { var docs = handleArray(value, operation, this.oldRecord ? this.oldRecord[property] : null, null, this.requiredValues ? this.requiredValues[property] : null); setDocAsParent(docs, this); return docs; } else { return handleObject(value, this.oldRecord ? this.oldRecord[property] : null, this.type, this.requiredValues ? this.requiredValues[property] : null, operation); } } else if (value !== null && value !== undefined) { return undefined; } else if (value === null) { /* * unset case or value set==null in $set * */ var oldValue = this.oldRecord ? this.oldRecord[property] : null; if (Array.isArray(oldValue)) { var docs = handleArray(null, operation, oldValue, null, this.requiredValues ? this.requiredValues[property] : null) setDocAsParent(docs, this); return docs; } else if (Utility.isJSONObject(oldValue)) { return handleObject(null, oldValue, "update", this.requiredValues ? this.requiredValues[property] : null, operation); } else { return undefined; } } else { var oldValue = this.oldRecord ? this.oldRecord[property] : null; if (Array.isArray(oldValue)) { var docs = handleArray({}, operation, oldValue, "nochange", this.requiredValues ? this.requiredValues[property] : null) setDocAsParent(docs, this); return docs; } else if (Utility.isJSONObject(oldValue)) { return handleObject({}, oldValue, "nochange", this.requiredValues ? this.requiredValues[property] : null, operation); } else { var requiredValues = this.requiredValues ? this.requiredValues[property] : null; if (Array.isArray(requiredValues)) { throw new Error("Array Document not supported for only requiredValues>>>>>>>>" + JSON.stringify(this)); // return handleArray({}, operation, oldValue, "nochange", this.requiredValues ? this.requiredValues[property] : null) } else if (Utility.isJSONObject(requiredValues)) { return handleObject({}, {}, "nochange", requiredValues, operation); } else { return undefined; } } } }
Utils.iterateArray(filterKeys, callback, function (filterKey, callback) { var filterValue = filter[filterKey]; if (filterKey == Constants.Query.Filter.OR || filterKey == Constants.Query.Filter.AND) { Utils.iterateArray(filterValue, callback, function (row, callback) { populateFilter(row, parameters, db, callback); }) } else { if (Utils.isJSONObject(filterValue)) { if (filterValue.$function) { resolveFunction(filterValue.$function, parameters, db, function (err, result) { if (err) { callback(err); return; } filter[filterKey] = result; callback(); }); } else { var filterValueKeys = Object.keys(filterValue); Utils.iterateArray(filterValueKeys, callback, function (filterValueKey, callback) { var innerFilterValue = filterValue[filterValueKey]; if (!Utils.isJSONObject(innerFilterValue)) { if (innerFilterValue && typeof innerFilterValue == "string" && innerFilterValue.indexOf("$") == 0) { filterValue[filterValueKey] = Utils.resolveValue(parameters, innerFilterValue.substring(1)); } callback(); return; } if (!innerFilterValue.$function) { callback(); return; } resolveFunction(innerFilterValue.$function, parameters, db, function (err, result) { if (err) { callback(err); return; } console.log("result >>>>>>>>>>>>>>" + JSON.stringify(result)); filterValue[filterValueKey] = result; callback(); }); }) } } else { if (filterValue && typeof filterValue == "string" && filterValue.indexOf("$") == 0) { filter[filterKey] = Utils.resolveValue(parameters, filterValue.substring(1)); } callback(); } } })
Document.prototype.getRevisedUpdatedFields = function () { var value = this.convertToJSON(); var oldValue = this.oldRecord; if (!value || !Utility.isJSONObject(value)) { return undefined; } if (oldValue && Utility.deepEqual(value, oldValue)) { return undefined; } oldValue = oldValue || {}; var keys = []; populateUpdatedFields(value, oldValue, keys); return keys; }
function prepareNestedUpdates(query, queryValue, originalSet, modifiedSet, targetValue) { if (Array.isArray(targetValue)) { var updated = false; for (var i = 0; i < targetValue.length; i++) { var nestedpdated = prepareNestedUpdates(query, queryValue, originalSet, modifiedSet, targetValue[i]); updated = updated || nestedpdated; } return updated; } else if (Utils.isJSONObject(targetValue)) { if (query.indexOf(".") >= 0) { var queryFirstPart = query.substr(0, query.indexOf(".")); var queryRestPart = query.substr(query.indexOf(".") + 1); var value = targetValue[queryFirstPart]; return prepareNestedUpdates(queryRestPart, queryValue, originalSet, modifiedSet, value); } else { if (targetValue[query] === queryValue) { updateValue(targetValue, modifiedSet); return true; } else { return false; } } } else { return false; } }
exports.doQuery = function (query, collection, db, callback) { try { var queryChilds = query[Constants.Query.CHILDS]; if (!queryChilds || Object.keys(queryChilds).length == 0) { callback(); return; } delete query[Constants.Query.CHILDS]; var queryChildAliases = Object.keys(queryChilds); Utils.iterateArray(queryChildAliases, callback, function (queryChildAlias, callback) { var queryChildValue = queryChilds[queryChildAlias]; getChildDef(queryChildValue, queryChildAlias, collection, function (err, childDef) { if (err) { callback(err); return; } if (!childDef) { throw new Error("Child Defination not found for child alias [" + queryChildAlias + "]"); } var innerQuery = childDef.query || {$collection:childDef.collection}; var childCollectionName = typeof childDef.collection == "string" ? childDef.collection : childDef.collection.collection; addRecursionInQuery(innerQuery, childCollectionName, db, function (err) { if (err) { callback(err); return; } addSubQuery(query, queryChildAlias, innerQuery, childDef.fk); callback(); }) }) }) } catch (e) { callback(e); } }
that.db.query(query, function (err, data) { if (err) { callback(err); return; } else { var oldData = data.result[0]; var docId = Utils.getUnique(); var document = new Document({"_id":id}, oldData, "delete"); ModuleManager.preDelete(docId, document, modules, that, that.db, function (err) { if (err) { callback(err); return; } if (document.cancelUpdates) { callback(null, 0); return; } that.mongoCollection.remove({_id:id}, options, function (err, result) { if (err) { callback(err); return; } ModuleManager.postDelete(docId, document, modules, that, that.db, function (err) { if (err) { callback(err); return; } callback(null, result); }) }); }); } });
function (docIndex, nestedDoc) { console.log("nested doc>>>" + JSON.stringify(nestedDoc)); var d11 = Q.defer(); var nestedOptions = Utils.deepClone(options); nestedOptions.parentFields = nestedOptions.parentFields || []; nestedOptions.parentFields.push(updatedField); if (nestedDoc.type == "insert") { console.log("firing nested field insert") delete nestedOptions.fields; return Self.triggerEvents("onInsert", nestedDoc, events, db, nestedOptions); } else if (nestedDoc.type == "update") { console.log("firing nested field udpate") nestedOptions.fields = nestedDoc.getRevisedUpdatedFields(); console.log("nested options>>>" + JSON.stringify(nestedOptions)); return Self.triggerEvents("onValue", nestedDoc, events, db, nestedOptions); } else if (nestedDoc.type == "delete") { console.log("firing nested field delete") nestedDoc.updates.$unset = nestedDoc.updates.$unset || {}; if (nestedDoc.oldRecord) { for (var k in nestedDoc.oldRecord) { nestedDoc.updates.$unset[k] = ""; } delete nestedDoc.updates.$unset._id; } console.log(">>>nestedDoc>>>" + JSON.stringify(nestedDoc)); nestedOptions.fields = nestedDoc.getRevisedUpdatedFields(); console.log("nested options>>>" + JSON.stringify(nestedOptions)); return Self.triggerEvents("onValue", nestedDoc, events, db, nestedOptions); } else { d11.resolve(); } return d11.promise; }).then(
function populateFilter(filter, fkcolumns) { var newQueryFilter = {}; for (var exp in filter) { var filterValue = filter[exp]; if (exp == Constants.Query.Filter.OR || exp == Constants.Query.Filter.AND) { if (!Array.isArray(filterValue)) { throw new Error("Filter value must be an Array in $or/$and Filter."); } var newOrFilterArray = []; for (var i = 0; i < filterValue.length; i++) { var newOrFilter = populateFilter(filterValue[i], fkcolumns); newOrFilterArray.push(newOrFilter); } newQueryFilter[exp] = newOrFilterArray; } else { if (fkcolumns[exp]) { if (Utils.isJSONObject(filterValue) && filterValue._id) { filterValue = filterValue._id; } exp = exp + "._id"; } populateSubQueryInFilter(newQueryFilter, fkcolumns, filterValue, exp, exp); } } return newQueryFilter; }
Utils.iterateArray(referredFks, callback, function (referredFk, callback) { var referredFkSet = referredFk[Constants.Admin.ReferredFks.SET]; if (!referredFkSet || referredFkSet.length == 0) { callback(); return; } var referredField = referredFk[Constants.Admin.ReferredFks.FIELD]; var valueToSet = {}; for (var i = 0; i < referredFkSet.length; i++) { if (updatedFields.indexOf(referredFkSet[i]) != -1) { valueToSet[referredField + "." + referredFkSet[i]] = Utils.resolveValue(updatedFieldValues, referredFkSet[i]); } } if (!valueToSet || Object.keys(valueToSet) == 0) { callback(); return; } var query = {}; query[referredField.replace(/\.\$/g, "") + "._id"] = updatedId; var update = {}; update[Constants.Update.Update.QUERY] = query; update[Constants.Update.Update.SET] = valueToSet; var updateQuery = {}; updateQuery[Constants.Query.COLLECTION] = referredFk[Constants.Admin.ReferredFks.COLLECTION_ID][Constants.Admin.Collections.COLLECTION]; updateQuery[Constants.Update.UPDATE] = [update]; console.log("updates >>>>>>>>>>>>>>>>>>>>>>>++++++++++++++++++++++++++++++" + JSON.stringify(updateQuery)); db.batchUpdate([updateQuery], {w:1, multi:true}, callback); });
function handleDeleteDocuments(documents, newUpdate, expression) { var pull = newUpdate.$pull ? newUpdate.$pull : {}; var filters = []; var filterKey = null; for (var i = 0; i < documents.length; i++) { var operation = documents[i].updates ? documents[i].updates : documents[i].oldRecord; operation = operation.$query ? operation.$query : operation; if (Utils.isJSONObject(operation)) { filterKey = Object.keys(operation)[0]; filters.push(operation[filterKey]); } else { filters.push(operation); } } if (filterKey) { var newFilter = {}; newFilter[filterKey] = {"$in":filters}; pull[expression] = newFilter; } else { if (filters.length > 0) { pull[expression] = {"$in":filters}; } } newUpdate.$pull = pull; }
function handleArrayUpdate(document, field, update, pExp) { var updatedFields = document.getUpdatedFields() || []; for (var i = 0; i < updatedFields.length; i++) { var field = updatedFields[i]; var documents = document.getDocuments(field); var newParentExp = pExp ? pExp + "." + field : field; if (Array.isArray(documents)) { handleSet(update, newParentExp, document, field); } else if (Utils.isJSONObject(documents)) { handleArrayUpdate(documents, field, update, newParentExp); } else { if (document.updates && document.updates.$inc && document.updates.$inc[field] !== undefined) { handleInc(update, newParentExp, document, field); } else if ((document.updates && document.updates.$unset && document.updates.$unset[field] !== undefined) || (document.updates && document.updates.$set && document.updates.$set[field] !== undefined)) { handleSet(update, newParentExp, document, field); } else if (document.updates && document.updates[field] && document.updates[field].$query) { throw new Error("updates for field[" + field + "] cannot contain $query >>> updates found are " + JSON.stringify(document.updates)); } else if (document.updates && document.updates[field] !== undefined) { handleSet(update, newParentExp, document, field); } else { throw new Error("updates for field[" + field + "] must be in one of $set,$unset,$inc>>> updates found are " + JSON.stringify(document.updates)); } } } }
function addRecursionInQuery(innerQuery, collectionName, db, callback) { var innerQueryChilds = innerQuery[Constants.Query.CHILDS]; if (!innerQueryChilds || Object.keys(innerQueryChilds).length == 0) { callback(); return; } var innerQueryChildAliases = Object.keys(innerQueryChilds); var recursiveAlias = undefined; Utils.iterateArray(innerQueryChildAliases, function (err) { if (err) { callback(err); return; } if (!recursiveAlias) { callback(); return; } if (Object.keys(recursiveAlias).length > 1) { throw new Error("More than one recursive columns found in child [" + JSON.stringify(recursiveAlias) + "]"); } var recursiveChildAlias = Object.keys(recursiveAlias)[0]; var fkColumn = recursiveAlias[recursiveChildAlias].fk; innerQuery[Constants.Query.FILTER] = innerQuery[Constants.Query.FILTER] || {}; if (!innerQuery[Constants.Query.FILTER][fkColumn]) { innerQuery[Constants.Query.FILTER][fkColumn] = null; } if (!innerQuery[Constants.Query.RECURSION]) { var recursion = {}; recursion[fkColumn] = "_id"; recursion[Constants.Query.Recursion.ALIAS] = recursiveChildAlias; innerQuery[Constants.Query.RECURSION] = recursion; } callback(null, {return:true}); }, function (innerQueryChildAlias, callback) { var innerQueryChildValue = innerQueryChilds[innerQueryChildAlias]; db.collection(innerQuery[Constants.Query.COLLECTION], function (err, innerQueryCollection) { if (err) { callback(err); return; } getChildDef(innerQueryChildValue, innerQueryChildAlias, innerQueryCollection, function (err, childDef) { if (err) { callback(err); return; } if (!childDef) { throw new Error("Child Defination not found for child alias [" + innerQueryChildAlias + "]"); } var innerCollectionName = typeof childDef.collection == "string" ? childDef.collection : childDef.collection.collection; if (collectionName == innerCollectionName) { delete innerQueryChilds[innerQueryChildAlias]; recursiveAlias = recursiveAlias || {}; recursiveAlias[innerQueryChildAlias] = childDef; } callback(); }) }) }) }
function ensureFields(query, db, callback) { if (!query[Constants.Query.FIELDS]) { callback(); return; } try { var fields = query[Constants.Query.FIELDS]; var fieldKeys = Object.keys(fields); Utils.iterateArray(fieldKeys, callback, function (fieldkey, callback) { var fieldValue = fields[fieldkey]; var indexOf = fieldkey.indexOf("."); if (indexOf > 0) { var firstPart = fieldkey.substring(0, indexOf); var secondPart = fieldkey.substring(indexOf + 1); if (fields[firstPart]) { if (secondPart != "_id") { throw new Error("Dotted Fields can not be defined if you want to get whole data."); } else { delete fields[fieldkey]; } } } if (Utils.isJSONObject(fieldValue) && fieldValue[Constants.Query.Fields.QUERY] && fieldValue[Constants.Query.Fields.FK]) { db.collection(fieldValue[Constants.Query.Fields.QUERY][Constants.Query.COLLECTION], function (err, collection) { if (err) { callback(err); return; } try { collection.get(Constants.Admin.Collections.FIELDS, function (err, collectionFields) { if (err) { callback(err); return; } try { var fkColumns = {}; populateFKColumns(fkColumns, collectionFields); if (fkColumns[fieldValue[Constants.Query.Fields.FK]]) { fieldValue[Constants.Query.Fields.FK] = fieldValue[Constants.Query.Fields.FK] + "._id"; } callback(); } catch (e) { callback(e); } }) } catch (e) { callback(e); } }) } else { callback(); } }) } catch (e) { callback(e); } }
Collection.prototype.insertAsPromise = function (inserts, modules, options) { var d = Q.defer(); options = options || {w:1}; var that = this; var docId = Utils.getUnique(); var document = new Document(inserts, null, "insert"); var events = undefined; Utils.populate_IdInArray(inserts); that.getAsPromise(Constants.Admin.Collections.EVENTS).then( function (collectionEvents) { events = collectionEvents; return EventManager.triggerEvents("onInsert", document, events, that.db); }).then( function () { return EventManager.triggerEvents("onSave", document, events, that.db, {pre:true}); }).then( function () { var d1 = Q.defer(); Q.delay(0).then( function () { prepareInserts(inserts); that.mongoCollection.insert(inserts, options, function (err, result) { if (err) { d1.reject(err) return; } d1.resolve(result[0]); }); }).fail(function (err) { d1.reject(err); }) return d1.promise; }).then( function (insertedValue) { document.updates._id = insertedValue._id; return EventManager.triggerEvents("onSave", document, events, that.db, {post:true}); }).then( function () { d.resolve(); }).fail(function (err) { d.reject(err); }) return d.promise; };
function populateUpdatedFields(value, oldValue, updatedFields) { for (var k in value) { if (oldValue[k] === undefined || !Utility.deepEqual(value[k], oldValue[k])) { if (updatedFields.indexOf(k) < 0) { updatedFields.push(k); } } } }
Collection.prototype.insert = function (inserts, modules, options, callback) { if (typeof modules == "function") { callback = modules; options = {w:1}; modules = undefined; } else if (typeof options == "function") { callback = options; options = modules; modules = undefined; } var that = this; var docId = Utils.getUnique(); // if (!inserts._id) { // inserts._id = Utils.getUnique(); // } Utils.populate_IdInArray(inserts); var document = new Document(inserts, null, "insert"); ModuleManager.preInsert(docId, document, modules, that, that.db, function (err) { if (err) { callback(err); return; } if (document.cancelUpdates) { callback(); return; } prepareInserts(inserts); that.mongoCollection.insert(inserts, options, function (err, result) { if (err) { callback(err); return; } document.updates = result[0]; ModuleManager.postInsert(docId, document, modules, that, that.db, function (err) { if (err) { callback(err); return; } callback(null, result); }); }); }); };
function (index, updatedField) { var d1 = Q.defer(); var updatedFieldDoc = document.getDocuments(updatedField, ["insert", "update", "delete"]); if (!updatedFieldDoc || !Array.isArray(updatedFieldDoc)) { d1.resolve(); return d1.promise; } console.log(">>NestedupdatedField >>>>>>>>>>>>>>>>>" + JSON.stringify(updatedField)); Utils.iterateArrayWithPromise(updatedFieldDoc, function (docIndex, nestedDoc) { console.log("nested doc>>>" + JSON.stringify(nestedDoc)); var d11 = Q.defer(); var nestedOptions = Utils.deepClone(options); nestedOptions.parentFields = nestedOptions.parentFields || []; nestedOptions.parentFields.push(updatedField); if (nestedDoc.type == "insert") { console.log("firing nested field insert") delete nestedOptions.fields; return Self.triggerEvents("onInsert", nestedDoc, events, db, nestedOptions); } else if (nestedDoc.type == "update") { console.log("firing nested field udpate") nestedOptions.fields = nestedDoc.getRevisedUpdatedFields(); console.log("nested options>>>" + JSON.stringify(nestedOptions)); return Self.triggerEvents("onValue", nestedDoc, events, db, nestedOptions); } else if (nestedDoc.type == "delete") { console.log("firing nested field delete") nestedDoc.updates.$unset = nestedDoc.updates.$unset || {}; if (nestedDoc.oldRecord) { for (var k in nestedDoc.oldRecord) { nestedDoc.updates.$unset[k] = ""; } delete nestedDoc.updates.$unset._id; } console.log(">>>nestedDoc>>>" + JSON.stringify(nestedDoc)); nestedOptions.fields = nestedDoc.getRevisedUpdatedFields(); console.log("nested options>>>" + JSON.stringify(nestedOptions)); return Self.triggerEvents("onValue", nestedDoc, events, db, nestedOptions); } else { d11.resolve(); } return d11.promise; }).then( function () { //nested doc has done its all work, now it should var documentJSON = document.convertToJSON(); mergedDocument[updatedField] = documentJSON[updatedField]; d1.resolve(); }).fail(function (err) { d1.reject(err); }); return d1.promise; }).then(
that.get("fields", function (err, fields) { if (err) { callback(err); return; } console.log("document>>>>>>>>>>>>>>>>>>>>>>>>>>>" + JSON.stringify(document)); var newUpdates = {}; newUpdates.query = {_id:id}; var arrayUpdates = []; modifyUpdates(document, newUpdates, arrayUpdates, id, fields); var pushUpdates = newUpdates.$push; var pullUpdates = newUpdates.$pull; delete newUpdates.$push; delete newUpdates.$pull; if (newUpdates.$set || newUpdates.$unset || newUpdates.$inc) { arrayUpdates.push(newUpdates); } if (pushUpdates && Object.keys(pushUpdates).length > 0) { arrayUpdates.push({query:{_id:id}, $push:pushUpdates}); } if (pullUpdates && Object.keys(pullUpdates).length > 0) { arrayUpdates.push({query:{_id:id}, $pull:pullUpdates}); } console.log("arrayUPdate>>>>>>>>>." + JSON.stringify(arrayUpdates)); var finalResult = {}; Utils.iterateArray(arrayUpdates, function (err) { if (err) { callback(err); return; } ModuleManager.postUpdate(docId, document, modules, that, that.db, function (err) { if (err) { callback(err); return; } callback(null, finalResult); }); }, function (newUpdate, callback) { var query = newUpdate.query; delete newUpdate.query; if (!newUpdate || Object.keys(newUpdate).length == 0) { callback(); return; } that.mongoCollection.update(query, newUpdate, options, function (err, result) { if (err) { callback(err); return; } finalResult = result; callback(null, result); }) }); });
function dottedFieldCheck(db, setField, collection, indexOfDot, fields, callback) { var firstPart = setField.substring(0, indexOfDot); var fieldResult = []; Utils.iterateArray(fields, function (err) { if (err) { callback(err); return; } if (fieldResult.length == 0) { throw new Error("field [" + setField + "] not found in collection [" + collection + "]"); } callback(); }, function (field, callback) { if (field.field == firstPart) { fieldResult.push(1); var fieldType = field.type; var secondPart = setField.substring(indexOfDot + 1); indexOfDot = secondPart.indexOf("."); if (fieldType == "object") { if (indexOfDot !== -1) { dottedFieldCheck(db, secondPart, collection, indexOfDot, field.fields, callback); } else { withoutDottedFieldCheck(db, secondPart, collection, field.fields); callback(); } } else if (fieldType === "fk") { var collection_fk = field.collection; validateCollection(db, collection_fk, function (err, data) { if (err) { callback(err); return; } var collectionId = data.result[0]._id; getFields(db, collectionId, function (err, collectionFields) { if (err) { callback(err); return } if (indexOfDot !== -1) { dottedFieldCheck(db, secondPart, collection_fk, indexOfDot, collectionFields.result, callback); } else { withoutDottedFieldCheck(db, secondPart, collection_fk, collectionFields.result); callback(); } }); }); } else { throw new Error("field [" + setField + "] not found in collection [" + collection + "]"); } } else { callback(); } }) }
function prepareInserts(inserts) { var keys = Object.keys(inserts); for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (Utils.isJSONObject(inserts[key])) { if (inserts[key].$insert) { inserts[key] = inserts[key].$insert; } for (var j = 0; j < inserts[key].length; j++) { prepareInserts(inserts[key][j]); } } else if (Array.isArray(inserts[key])) { for (var j = 0; j < inserts[key].length; j++) { if (Utils.isJSONObject(inserts[key][j])) { prepareInserts(inserts[key][j]); } } } } }
function fetchIndex(query, oldData) { var indexes = []; var length = oldData ? oldData.length : 0; for (var i = 0; i < length; i++) { if (Utils.evaluateFilter(query, oldData[i])) { indexes.push({index:i, data:oldData[i]}); } } return indexes; }
exports.preInsert = function (document, collection, db, callback) { if (document.cancelUpdates || db.txid === undefined) { callback(); return; } var txid = db.txid; var documentId = Utils.getUnique(); document.set("txid", documentId); var collectionName = collection.mongoCollection.collectionName; var tx = {collection: collectionName, delete: {txid: documentId}}; var update = [ {$collection: Constants.TRANSACTIONS, $update: [ {$query: {_id: txid}, $push: {updates: {$each: [ {_id: Utils.getUnique(), tx: tx} ]}}} ]} ]; /*update the pl.txs collection with the reverse effect of insert(delete with the record id )*/ db.batchUpdate(update, callback); }
function fetchIndex(query, oldData) { var Utils = require("ApplaneCore/apputil/util.js"); var indexes = []; var length = oldData ? oldData.length : 0; for (var i = 0; i < length; i++) { if (Utils.evaluateFilter(query, oldData[i])) { indexes.push({index: i, data: oldData[i]}); } } return indexes; }
function getTriggers(event, events, options) { console.log("......getTriggers" + JSON.stringify(options) + ">>event>>>" + event) var d = Q.defer(); var eventsToTrigger = []; for (var i = 0; i < events.length; i++) { var e = events[i]; if (e.eventName == event) { options = options || {}; var needToAdd = false; if (event == "onInsert") { console.log("options >>>>>>>>>>>>>>>" + JSON.stringify(options)); if (!options.parentFields && !e.fields) { needToAdd = true; } else if (options.parentFields && e.fields) { if (needToAddEventFields(e.fields, options.fields, options.parentFields, 0)) { needToAdd = true; } } else { //do not add } } else if (options.fields && e.fields) { if (needToAddEventFields(e.fields, options.fields, options.parentFields, 0)) { needToAdd = true; } } else if ((options.pre && e.pre == options.pre)) { needToAdd = true; } else if (options.post && e.post == options.post) { needToAdd = true; } if (needToAdd) { console.log(">>>>>>adding triger>>>>>>>>>>" + JSON.stringify(e)); var trigerAlreadyAdded = false; for (var j = 0; j < eventsToTrigger.length; j++) { var evetntToTrigger = eventsToTrigger[j]; if (Utils.deepEqual(evetntToTrigger.function, e.function)) { trigerAlreadyAdded = true; break; } } if (!trigerAlreadyAdded) { eventsToTrigger.push(e); } } } } // console.log(">>>eventsToTrigger>>>>" + JSON.stringify(eventsToTrigger)) d.resolve(eventsToTrigger); return d.promise; }
function generateRecursiveQuery(query) { // console.log("query >>>>>>>>>>>>>>>" + JSON.stringify(query)); // if (!query[Constants.Query.FIELDS]) { // throw new Error("Fields is mandatory if recursion is defined in query."); // } var recursiveColumn = undefined; var recursiveColumnValue = undefined; var queryRecursion = query[Constants.Query.RECURSION]; delete query[Constants.Query.RECURSION]; for (var column in queryRecursion) { if (column.indexOf("$") != 0) { recursiveColumn = column; recursiveColumnValue = queryRecursion[recursiveColumn]; break; } } var queryFilter = query[Constants.Query.FILTER]; // TODO doubt in case of recursion query. if (!queryFilter || (queryFilter[recursiveColumn] === undefined && queryFilter[recursiveColumn + "._id"] === undefined)) { throw new Error("Filter on recursive column is mandatory."); } var childQuery = {}; childQuery[Constants.Query.COLLECTION] = query[Constants.Query.COLLECTION]; childQuery[Constants.Query.FIELDS] = Utils.deepClone(query[Constants.Query.FIELDS]); var childDataFilter = {}; for (var exp in queryFilter) { if (exp != recursiveColumn) { childDataFilter[exp] = queryFilter[exp]; } } childQuery[Constants.Query.FILTER] = childDataFilter; if (queryRecursion[Constants.Query.Recursion.LEVEL]) { queryRecursion[Constants.Query.Recursion.LEVEL] = queryRecursion[Constants.Query.Recursion.LEVEL] - 1; } queryRecursion[Constants.Query.Recursion.COUNTER] = queryRecursion[Constants.Query.Recursion.COUNTER] + 1; childQuery[Constants.Query.RECURSION] = queryRecursion; childQuery[Constants.Query.UNWIND] = query[Constants.Query.UNWIND]; childQuery[Constants.Query.SORT] = query[Constants.Query.SORT]; childQuery[Constants.Query.CHILDS] = query[Constants.Query.CHILDS]; childQuery[Constants.Query.MODULES] = query[Constants.Query.MODULES]; var childData = {}; //always show recursionDataAlias data in array format.. childData[Constants.Query.Fields.TYPE] = "n-rows"; childData[Constants.Query.Fields.ENSURE] = queryRecursion[Constants.Query.Recursion.ENSURE]; childData[Constants.Query.Fields.QUERY] = childQuery; childData[Constants.Query.Fields.FK] = recursiveColumn; childData[Constants.Query.Fields.PARENT] = recursiveColumnValue; query[Constants.Query.FIELDS] = query[Constants.Query.FIELDS] || {}; query[Constants.Query.FIELDS][queryRecursion[Constants.Query.Recursion.ALIAS] || "children"] = childData; // console.log("query After Recursion ++++++++++++++++++++++++++++++++++++++" + JSON.stringify(query)); }
function resolveFunction(functionValue, parameters, db, callback) { var functionName = undefined; var functionParams = undefined; if (Utils.isJSONObject(functionValue)) { functionName = Object.keys(functionValue)[0]; functionParams = functionValue[functionName]; } else { functionName = functionValue; } if (functionParams && !Utils.isJSONObject(functionParams)) { throw new Error("Parameters defined for function should be Object."); } for (var functionParamsKey in functionParams) { var funcParamsValue = functionParams[functionParamsKey]; if (funcParamsValue && typeof funcParamsValue == "string" && funcParamsValue.indexOf("$") == 0) { functionParams[functionParamsKey] = Utils.resolveValue(parameters, funcParamsValue.substring(1)); } } db.invokeFunction(functionName, functionParams ? [functionParams] : undefined, callback); }
function handleArray(value, operation, oldRecord, isNoChange, requiredValue) { oldRecord = oldRecord || {}; value = value || {}; requiredValue = requiredValue || []; if (value.$insert || value.$update || value.$delete) { var documentArray = []; populateArrayRevised(value, oldRecord, requiredValue, documentArray); if (operation) { return handleOperationInArray(documentArray, operation); } else { return documentArray; } } else { if ((value && value.length > 0 && Utility.isJSONObject(value[0])) || (oldRecord && oldRecord.length > 0 && Utility.isJSONObject(oldRecord[0]))) { var newDocumentArray = []; for (var i = 0; i < value.length; i++) { newDocumentArray.push(new Document(value[i], null, "insert", requiredValue[i])); } for (var i = 0; i < oldRecord.length; i++) { var type = isNoChange ? "nochange" : "delete"; var updates = isNoChange ? {} : undefined; if (type === "nochange") { var requiredIndex = Utility.isExists(requiredValue, value, "_id"); var rValue = requiredIndex !== undefined ? requiredValue[requiredIndex] : null; newDocumentArray.push(new Document(updates, oldRecord[i], type, rValue)); } else { newDocumentArray.push(new Document(updates, oldRecord[i], type, null)); } } if (operation) { return handleOperationInArray(newDocumentArray, operation); } else { return newDocumentArray; } } else { return undefined; } } }