|
/* |
|
How to (required index.js exported from exporter.js) |
|
* mongo is mongoshell command |
|
|
|
mongo dbname --quiet --eval "let mode='DRYRUN';" mongodbIndexImporter.js |
|
|
|
*/ |
|
|
|
// available modes |
|
let LIVE = 'LIVE'; |
|
let DRYRUN = 'DRYRUN'; // actually all other words except 'LIVE' are DRYRUN mode. |
|
|
|
load('index.js'); |
|
if(typeof mode == 'undefined') { |
|
print(red('mode variable required!')+' '+cyan('--eval "let mode=\'DRYRUN\';" or "let mode=\'LIVE\';')); |
|
} |
|
else { |
|
print('*** Index importer: started with ' + yellow(mode) + ' mode ***'); |
|
|
|
let collections = indexes['collections']; |
|
let collectionNames = db.getCollectionNames(); |
|
|
|
for (let i in collections) { |
|
let collection = collections[i]; |
|
let indexItems = collection["indexes"]; |
|
let collectionName = collection['name']; |
|
print('='.repeat(55)); |
|
if (collectionNames.indexOf(collectionName) >=0) { |
|
print('collection '+ green(collectionName) + ' already '+green('exists')); |
|
} else { |
|
print('will '+yellow('create')+' collection '+ green(collectionName)); |
|
if (mode == LIVE) { |
|
// do create collection |
|
db.createCollection(collectionName) |
|
} |
|
} |
|
|
|
let dbCollection = db.getCollection(collectionName); |
|
let existingIndexes = dbCollection.getIndexes(); |
|
|
|
for(let itemIdx in indexItems) { |
|
let indexItem = indexItems[itemIdx]; |
|
let indexName = indexItem['name']; |
|
let indexKey = indexItem['key']; |
|
let checked = false; |
|
for(let eIdx in existingIndexes) { |
|
let existingIndex = existingIndexes[eIdx]; |
|
if (existingIndex['name'] == indexName) { |
|
if(!isSameKey(existingIndex, indexItem)) { |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' will be '+red('dropped')); |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' will be '+yellow('re-created')); |
|
if(mode == LIVE) { |
|
dbCollection.dropIndex(indexName); |
|
createIndex(dbCollection, indexName, indexItem); |
|
} |
|
} |
|
else { |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' is same, skip.'); |
|
} |
|
checked = true; |
|
break |
|
} |
|
} |
|
|
|
if (!checked) { |
|
print('collection '+green(collectionName)+' index '+green(indexName)+' will be '+yellow('created')); |
|
if(mode == LIVE) { |
|
createIndex(dbCollection, indexName, indexItem); |
|
} |
|
} |
|
} |
|
|
|
for(let eIdx in existingIndexes) { |
|
let checked = false; |
|
let existingIndex = existingIndexes[eIdx]; |
|
for(let itemIdx in indexItems) { |
|
let indexItem = indexItems[itemIdx]; |
|
let indexName = indexItem['name']; |
|
if (existingIndex['name'] == indexName) { |
|
checked = true |
|
break |
|
} |
|
} |
|
|
|
if (!checked) { |
|
print('collection '+green(collectionName)+' index '+green(existingIndex["name"])+' will be '+red('dropped')); |
|
if (mode == LIVE) { |
|
dbCollection.dropIndex(existingIndex["name"]); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (mode == LIVE) { |
|
print('Completed! '+magenta('LIVE MODE. All Operatoins are applied on database!')); |
|
} |
|
else { |
|
print('Completed! '+cyan('TEST MODE. Nothing is applied.')); |
|
} |
|
} |
|
|
|
function createIndex(db, name, indexItem) { |
|
let options = {'name': name}; |
|
let key = indexItem['key']; |
|
if('expireAfterSeconds' in indexItem) { |
|
options['expireAfterSeconds'] = indexItem['expireAfterSeconds']; |
|
} |
|
|
|
if('background' in indexItem) { |
|
options['background'] = indexItem['background']; |
|
} |
|
|
|
if('unique' in indexItem) { |
|
options['unique'] = indexItem['unique']; |
|
} |
|
|
|
if('collation' in indexItem) { |
|
options['collation'] = indexItem['collation']; |
|
} |
|
|
|
db.createIndex(key, options); |
|
} |
|
|
|
function isSameKey(existingIndex, newIndex) { |
|
let key = existingIndex['key']; |
|
let newKey = newIndex['key']; |
|
|
|
// -2: v, ns |
|
let excepted = 0; |
|
for (let keyName in existingIndex) { |
|
if (keyName === "v") { |
|
excepted++ |
|
continue |
|
} |
|
|
|
if (keyName === "ns") { |
|
excepted++ |
|
} |
|
} |
|
|
|
if (Object.keys(existingIndex).length -excepted != Object.keys(newIndex).length) { |
|
return false; |
|
} |
|
|
|
if (Object.keys(key).length != Object.keys(newKey).length) { |
|
return false; |
|
} |
|
|
|
for(let i in key) { |
|
let val = key[i]; |
|
if(i in newKey) { |
|
if(newKey[i] != val) { |
|
return false; |
|
} |
|
} |
|
else { |
|
return false; |
|
} |
|
} |
|
let except = ['v', 'ns', 'key']; |
|
for (let element in existingIndex) { |
|
if (except.indexOf(element) >= 0) { |
|
continue; |
|
} |
|
|
|
if (existingIndex[element] != newIndex[element]) { |
|
let a = existingIndex[element]; |
|
let b = newIndex[element]; |
|
if (isObject(a) && isObject(b)) { |
|
print(element) |
|
for (let el in b) { |
|
if (a[el] != b[el]) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
|
|
} |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
function isObject(val) { |
|
if (val === null) { return false;} |
|
return ( (typeof val === 'function') || (typeof val === 'object') ); |
|
} |
|
|
|
// colors |
|
function red (text) { return colorize(text, 'red') } |
|
function green (text) { return colorize(text, 'green') } |
|
function yellow (text) { return colorize(text, 'yellow') } |
|
function blue (text) { return colorize(text, 'blue') } |
|
function magenta (text) { return colorize(text, 'magenta') } |
|
function cyan (text) { return colorize(text, 'cyan') } |
|
function gray (text) { return colorize(text, 'gray') } |
|
|
|
function colorize(text, color, style) { |
|
// color: 'red', 'green', 'blue'... (see below) |
|
// styles: 'normal' or undefined, 'bright', 'highlight' |
|
|
|
if (!style) { |
|
style = 'normal'; |
|
} |
|
|
|
let _ansi = { |
|
csi: String.fromCharCode(0x1B) + '[', |
|
reset: '0', |
|
text_prop: 'm', |
|
|
|
styles: { |
|
normal: '3', |
|
bright: '9', |
|
highlight: '4' |
|
}, |
|
|
|
colors: { |
|
black: '0', |
|
red: '1', |
|
green: '2', |
|
yellow: '3', |
|
blue: '4', |
|
magenta: '5', |
|
cyan: '6', |
|
gray: '7' |
|
} |
|
}; |
|
|
|
let beginColor = _ansi.csi + _ansi.styles[style] + _ansi.colors[color] + _ansi.text_prop; |
|
let endColor = _ansi.csi + _ansi.reset + _ansi.text_prop; |
|
|
|
return beginColor + text + endColor; |
|
} |
Thank you for feedback. This is applied :)