HTMLify
getIndexes.js
Views: 6 | Author: cody
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | 'use strict'; const get = require('../get'); const helperIsObject = require('../isObject'); /*! * Gather all indexes defined in the schema, including single nested, * document arrays, and embedded discriminators. */ module.exports = function getIndexes(schema) { let indexes = []; const schemaStack = new WeakMap(); const indexTypes = schema.constructor.indexTypes; const indexByName = new Map(); collectIndexes(schema); return indexes; function collectIndexes(schema, prefix, baseSchema) { // Ignore infinitely nested schemas, if we've already seen this schema // along this path there must be a cycle if (schemaStack.has(schema)) { return; } schemaStack.set(schema, true); prefix = prefix || ''; const keys = Object.keys(schema.paths); for (const key of keys) { const path = schema.paths[key]; if (baseSchema != null && baseSchema.paths[key]) { // If looking at an embedded discriminator schema, don't look at paths // that the continue; } if (path.$isMongooseDocumentArray || path.$isSingleNested) { if (get(path, 'options.excludeIndexes') !== true && get(path, 'schemaOptions.excludeIndexes') !== true && get(path, 'schema.options.excludeIndexes') !== true) { collectIndexes(path.schema, prefix + key + '.'); } if (path.schema.discriminators != null) { const discriminators = path.schema.discriminators; const discriminatorKeys = Object.keys(discriminators); for (const discriminatorKey of discriminatorKeys) { collectIndexes(discriminators[discriminatorKey], prefix + key + '.', path.schema); } } // Retained to minimize risk of backwards breaking changes due to // gh-6113 if (path.$isMongooseDocumentArray) { continue; } } const index = path._index || (path.caster && path.caster._index); if (index !== false && index !== null && index !== undefined) { const field = {}; const isObject = helperIsObject(index); const options = isObject ? index : {}; const type = typeof index === 'string' ? index : isObject ? index.type : false; if (type && indexTypes.indexOf(type) !== -1) { field[prefix + key] = type; } else if (options.text) { field[prefix + key] = 'text'; delete options.text; } else { const isDescendingIndex = Number(index) === -1; field[prefix + key] = isDescendingIndex ? -1 : 1; } delete options.type; if (!('background' in options)) { options.background = true; } if (schema.options.autoIndex != null) { options._autoIndex = schema.options.autoIndex; } const indexName = options && options.name; if (typeof indexName === 'string') { if (indexByName.has(indexName)) { Object.assign(indexByName.get(indexName), field); } else { indexes.push([field, options]); indexByName.set(indexName, field); } } else { indexes.push([field, options]); indexByName.set(indexName, field); } } } schemaStack.delete(schema); if (prefix) { fixSubIndexPaths(schema, prefix); } else { schema._indexes.forEach(function(index) { if (!('background' in index[1])) { index[1].background = true; } }); indexes = indexes.concat(schema._indexes); } } /*! * Checks for indexes added to subdocs using Schema.index(). * These indexes need their paths prefixed properly. * * schema._indexes = [ [indexObj, options], [indexObj, options] ..] */ function fixSubIndexPaths(schema, prefix) { const subindexes = schema._indexes; const len = subindexes.length; for (let i = 0; i < len; ++i) { const indexObj = subindexes[i][0]; const indexOptions = subindexes[i][1]; const keys = Object.keys(indexObj); const klen = keys.length; const newindex = {}; // use forward iteration, order matters for (let j = 0; j < klen; ++j) { const key = keys[j]; newindex[prefix + key] = indexObj[key]; } const newIndexOptions = Object.assign({}, indexOptions); if (indexOptions != null && indexOptions.partialFilterExpression != null) { newIndexOptions.partialFilterExpression = {}; const partialFilterExpression = indexOptions.partialFilterExpression; for (const key of Object.keys(partialFilterExpression)) { newIndexOptions.partialFilterExpression[prefix + key] = partialFilterExpression[key]; } } indexes.push([newindex, newIndexOptions]); } } }; |