database and ajax test added

This commit is contained in:
2019-02-01 14:06:44 +01:00
parent b5eb4c2b79
commit f3c33a35cd
562 changed files with 154325 additions and 16 deletions
@@ -0,0 +1,85 @@
'use strict';
module.exports = assignRawDocsToIdStructure;
/*!
* Assign `vals` returned by mongo query to the `rawIds`
* structure returned from utils.getVals() honoring
* query sort order if specified by user.
*
* This can be optimized.
*
* Rules:
*
* if the value of the path is not an array, use findOne rules, else find.
* for findOne the results are assigned directly to doc path (including null results).
* for find, if user specified sort order, results are assigned directly
* else documents are put back in original order of array if found in results
*
* @param {Array} rawIds
* @param {Array} vals
* @param {Boolean} sort
* @api private
*/
function assignRawDocsToIdStructure(rawIds, resultDocs, resultOrder, options, recursed) {
// honor user specified sort order
const newOrder = [];
const sorting = options.sort && rawIds.length > 1;
let doc;
let sid;
let id;
for (let i = 0; i < rawIds.length; ++i) {
id = rawIds[i];
if (Array.isArray(id)) {
// handle [ [id0, id2], [id3] ]
assignRawDocsToIdStructure(id, resultDocs, resultOrder, options, true);
newOrder.push(id);
continue;
}
if (id === null && !sorting) {
// keep nulls for findOne unless sorting, which always
// removes them (backward compat)
newOrder.push(id);
continue;
}
sid = String(id);
doc = resultDocs[sid];
// If user wants separate copies of same doc, use this option
if (options.clone) {
doc = doc.constructor.hydrate(doc._doc);
}
if (recursed) {
if (doc) {
if (sorting) {
newOrder[resultOrder[sid]] = doc;
} else {
newOrder.push(doc);
}
} else {
newOrder.push(id);
}
} else {
// apply findOne behavior - if document in results, assign, else assign null
newOrder[i] = doc || null;
}
}
rawIds.length = 0;
if (newOrder.length) {
// reassign the documents based on corrected order
// forEach skips over sparse entries in arrays so we
// can safely use this to our advantage dealing with sorted
// result sets too.
newOrder.forEach(function(doc, i) {
rawIds[i] = doc;
});
}
}
+181
View File
@@ -0,0 +1,181 @@
'use strict';
/*!
* ignore
*/
const Mixed = require('../../schema/mixed');
const get = require('../get');
const leanPopulateMap = require('./leanPopulateMap');
const mpath = require('mpath');
/*!
* @param {Schema} schema
* @param {Object} doc POJO
* @param {string} path
*/
module.exports = function getSchemaTypes(schema, doc, path) {
const pathschema = schema.path(path);
const topLevelDoc = doc;
if (pathschema) {
return pathschema;
}
function search(parts, schema, subdoc, nestedPath) {
let p = parts.length + 1;
let foundschema;
let trypath;
while (p--) {
trypath = parts.slice(0, p).join('.');
foundschema = schema.path(trypath);
if (foundschema == null) {
continue;
}
if (foundschema.caster) {
// array of Mixed?
if (foundschema.caster instanceof Mixed) {
return foundschema.caster;
}
let schemas = null;
if (doc != null && foundschema.schema != null && foundschema.schema.discriminators != null) {
const discriminators = foundschema.schema.discriminators;
const discriminatorKeyPath = trypath + '.' +
foundschema.schema.options.discriminatorKey;
const keys = subdoc ? mpath.get(discriminatorKeyPath, subdoc) || [] : [];
schemas = Object.keys(discriminators).
reduce(function(cur, discriminator) {
if (keys.indexOf(discriminator) !== -1) {
cur.push(discriminators[discriminator]);
}
return cur;
}, []);
}
// Now that we found the array, we need to check if there
// are remaining document paths to look up for casting.
// Also we need to handle array.$.path since schema.path
// doesn't work for that.
// If there is no foundschema.schema we are dealing with
// a path like array.$
if (p !== parts.length && foundschema.schema) {
let ret;
if (parts[p] === '$') {
if (p + 1 === parts.length) {
// comments.$
return foundschema;
}
// comments.$.comments.$.title
ret = search(
parts.slice(p + 1),
schema,
subdoc ? mpath.get(trypath, subdoc) : null,
nestedPath.concat(parts.slice(0, p))
);
if (ret) {
ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
!foundschema.schema.$isSingleNested;
}
return ret;
}
if (schemas != null && schemas.length > 0) {
ret = [];
for (let i = 0; i < schemas.length; ++i) {
const _ret = search(
parts.slice(p),
schemas[i],
subdoc ? mpath.get(trypath, subdoc) : null,
nestedPath.concat(parts.slice(0, p))
);
if (_ret != null) {
_ret.$isUnderneathDocArray = _ret.$isUnderneathDocArray ||
!foundschema.schema.$isSingleNested;
if (_ret.$isUnderneathDocArray) {
ret.$isUnderneathDocArray = true;
}
ret.push(_ret);
}
}
return ret;
} else {
ret = search(
parts.slice(p),
foundschema.schema,
subdoc ? mpath.get(trypath, subdoc) : null,
nestedPath.concat(parts.slice(0, p))
);
if (ret) {
ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
!foundschema.schema.$isSingleNested;
}
return ret;
}
}
}
const fullPath = nestedPath.concat([trypath]).join('.');
if (topLevelDoc.$__ && topLevelDoc.populated(fullPath) && p < parts.length) {
const schema = get(doc.$__.populated[fullPath], 'options.model.schema');
if (schema != null) {
const ret = search(
parts.slice(p),
schema,
subdoc ? mpath.get(trypath, subdoc) : null,
nestedPath.concat(parts.slice(0, p))
);
if (ret) {
ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
!schema.$isSingleNested;
}
return ret;
}
}
const _val = get(topLevelDoc, trypath);
if (_val != null) {
const model = Array.isArray(_val) && _val.length > 0 ?
leanPopulateMap.get(_val[0]) :
leanPopulateMap.get(_val);
// Populated using lean, `leanPopulateMap` value is the foreign model
const schema = model != null ? model.schema : null;
if (schema != null) {
const ret = search(
parts.slice(p),
schema,
subdoc ? mpath.get(trypath, subdoc) : null,
nestedPath.concat(parts.slice(0, p))
);
if (ret) {
ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
!schema.$isSingleNested;
}
return ret;
}
}
return foundschema;
}
}
// look for arrays
const parts = path.split('.');
for (let i = 0; i < parts.length; ++i) {
if (parts[i] === '$') {
// Re: gh-5628, because `schema.path()` doesn't take $ into account.
parts[i] = '0';
}
}
return search(parts, schema, doc, []);
};
+61
View File
@@ -0,0 +1,61 @@
'use strict';
module.exports = getVirtual;
/*!
* ignore
*/
function getVirtual(schema, name) {
if (schema.virtuals[name]) {
return schema.virtuals[name];
}
const parts = name.split('.');
let cur = '';
let nestedSchemaPath = '';
for (let i = 0; i < parts.length; ++i) {
cur += (cur.length > 0 ? '.' : '') + parts[i];
if (schema.virtuals[cur]) {
if (i === parts.length - 1) {
schema.virtuals[cur].$nestedSchemaPath = nestedSchemaPath;
return schema.virtuals[cur];
}
continue;
}
if (schema.nested[cur]) {
continue;
}
if (schema.paths[cur] && schema.paths[cur].schema) {
schema = schema.paths[cur].schema;
const rest = parts.slice(i + 1).join('.');
if (schema.virtuals[rest]) {
if (i === parts.length - 2) {
schema.virtuals[rest].$nestedSchemaPath =
[nestedSchemaPath, cur].filter(v => !!v).join('.');
return schema.virtuals[rest];
}
continue;
}
if (i + 1 < parts.length && schema.discriminators) {
for (const key of Object.keys(schema.discriminators)) {
const _virtual = getVirtual(schema.discriminators[key], rest);
if (_virtual != null) {
_virtual.$nestedSchemaPath = [nestedSchemaPath, cur].
filter(v => !!v).join('.');
return _virtual;
}
}
}
nestedSchemaPath += (nestedSchemaPath.length > 0 ? '.' : '') + cur;
cur = '';
continue;
}
return null;
}
}
+7
View File
@@ -0,0 +1,7 @@
'use strict';
/*!
* ignore
*/
module.exports = new WeakMap();
+45
View File
@@ -0,0 +1,45 @@
'use strict';
module.exports = function normalizeRefPath(refPath, doc, populatedPath) {
if (refPath == null) {
return refPath;
}
if (typeof refPath === 'function') {
refPath = refPath.call(doc, doc, populatedPath);
}
// If populated path has numerics, the end `refPath` should too. For example,
// if populating `a.0.b` instead of `a.b` and `b` has `refPath = a.c`, we
// should return `a.0.c` for the refPath.
const hasNumericProp = /(\.\d+$|\.\d+\.)/g;
if (hasNumericProp.test(populatedPath)) {
const chunks = populatedPath.split(hasNumericProp);
if (chunks[chunks.length - 1] === '') {
throw new Error('Can\'t populate individual element in an array');
}
let _refPath = '';
let _remaining = refPath;
// 2nd, 4th, etc. will be numeric props. For example: `[ 'a', '.0.', 'b' ]`
for (let i = 0; i < chunks.length; i += 2) {
const chunk = chunks[i];
if (_remaining.startsWith(chunk + '.')) {
_refPath += _remaining.substr(0, chunk.length) + chunks[i + 1];
_remaining = _remaining.substr(chunk.length + 1);
} else if (i === chunks.length - 1) {
_refPath += _remaining;
_remaining = '';
break;
} else {
throw new Error('Could not normalize ref path, chunk ' + chunk + ' not in populated path');
}
}
return _refPath;
}
return refPath;
};
+19
View File
@@ -0,0 +1,19 @@
'use strict';
const MongooseError = require('../../error/mongooseError');
const util = require('util');
module.exports = validateRef;
function validateRef(ref, path) {
if (typeof ref === 'string') {
return;
}
if (typeof ref === 'function') {
return;
}
throw new MongooseError('Invalid ref at path "' + path + '". Got ' +
util.inspect(ref, { depth: 0 }));
}