Skip to content

Instantly share code, notes, and snippets.

@yanatan16
Last active June 27, 2022 09:03
Show Gist options
  • Save yanatan16/6148978 to your computer and use it in GitHub Desktop.
Save yanatan16/6148978 to your computer and use it in GitHub Desktop.
My .mongorc.js file
(function () {
rcversion = '1.0';
load('underscore.min.js')
// NOTES
// Basics, wrap the whole thing in a function
// Set a version for sanity's sake
// Load underscore, a must in any javascript environment
(function () {
var cmdCount = 0;
var isMaster = db.isMaster();
if (isMaster.setName) {
prompt = function () {
return isMaster.setName + '(' + (isMaster.ismaster() ? 'pri' : 'sec' ) + '):' + db + '-' + (cmdCount++) + ' > ';
};
} else {
prompt = function () {
return db + '-' + (cmdCount++) + ' > ';
};
}
})()
// NOTES
// Setup the prompt
// This prompt tells us if we are on a replica set, and if we are on the primary
// It also shows the current database and the current command count
var login = function (dbname, username) {
// Or load('auth_tokens.js')
var tokens = {
'admin-username': 'admin-password',
'readonly-username': 'foo-readonly-password',
'readwrite-username': 'foo-readwrite-password'
};
// Only login on the correct database.
if (dbname !== db) {
db.auth(username, tokens[username]);
}
};
auth = {
admin: _.bind(login, 'admin', 'admin-username'),
ro: _.bind(login, 'foo', 'readonly-username'),
rw: _.bind(login, 'foo', 'readwrite-username')
};
// NOTES
// Setup authentication helpers.
// Add in your own authentication schemes and tokens. (you can also load these from another file)
// This provides some nice functions like `auth.rw()` to authenticate read-write
_.mixin({
// A deep getter
get: function (obj, key) {
return _.reduce(key.split('.'), function (o, k) {
return o && o[k];
}, obj);
},
// Get a random integer
randint: function (n) {
return Math.floor(Math.random() * (n || 2));
},
// Get a random choice
randchoice: function (seq) {
return seq[_.randint(seq.length)];
},
// Get the current timestamp
now: function () {
return (new Date()).getTime() / 1000;
},
// Create an object id based on a timestamp
oid: function(timestamp) {
if (!timestamp) {
return new ObjectId();
}
// Convert string date to Date object (otherwise assume timestamp is a date)
if ( ! timestamp instanceof Date ) {
timestamp = new Date( timestamp );
}
// Convert date object to hex seconds since Unix epoch
var hexSeconds = Math.floor( timestamp / 1000 ).toString( 16 );
// Create an ObjectId with that hex timestamp
return ObjectId( hexSeconds + "0000000000000000" );
},
// Aggregate sequence into prefix sequences
aggregate: function (seq) {
return _.reduce(seq, function (memo, nxt) {
var agg = memo[0], cur = memo[1].concat(nxt);
return [agg.concat([cur]), cur];
}, [[], []])[0];
},
// Aggregate and join a sequence of strings
aggjoin: function (seq, sep) {
return _.map(_.aggregate(seq), function (agg) {
return agg.join(sep);
});
},
// Sum a sequence of numbers
sum: function (seq) {
return _.reduce(seq, function (a, b) { return a + b; }, 0);
}
});
// NOTES
// Various useful helper functions. I just stick them on the underscore object to make using them
// easer. I don't have to remember multiple helper objects. Especially helpful is _.oid, which
// is oddly missing from the shell functions.
// Walks a recursive object (`node`), testing them with tester and making callbacks when tester returns true.
// The only option is `depth`: defaults to 20 but can be set arbitrarily (up to shell limit) to control recursion.
var walker = function (node, tester, callback, opts) {
depth = (opts || {}).depth || 20;
var walk;
walk = function (branch, n) {
n = n || 0;
if (n > depth) return null;
if (tester(branch)) {
callback(branch);
}
if (_.isObject(branch) || _.isArray(branch)) {
_.each(branch, function (subbranch) {
walk(subbranch, n + 1);
});
}
}
return walk(node);
};
// NOTES
// This is a base function for walking a tree structure to find things.
// Mongo is based off of javascript objects, which are so easy to nest.
// We have some arbitrarily nested structures in our database, and parsing
// them in the shell is tedious at best. We'll start with this and build up
// some useful functions for dealing with arbitrarily nested data.
// Take a selector and create a testor for the walker function
// The goal is to create a tester that will find objects with certain
// key/value pairs.
// Selectors can be strings, objects, or arrays.
// Objects and arrays just create AND filters trying to match part of objects
// String filters can be 'FIELD:' (to search for having the field 'FIELD')
// or 'FIELD:VALUE' to search for string equality.
var kv_typetest = function (selector) {
var expect = {}, match = {}, tests = [];
if (_.isString(selector)) {
_.each(selector.split(' '), function (sel) {
var kvsplit = sel.split(':');
if (kvsplit.length === 1) {
expect[kvsplit[1]] = true;
} else if (kvsplit.length === 2) {
match[kvsplit[0]] = kvsplit[1];
}
});
} else if (_.isObject(selector)) {
expect = selector;
} else if (_.isArray(selector)) {
tests = _.map(selector, kv_typetest);
} else {
throw new Error("Expected string or object for selector");
}
return function (branch) {
return _.every(expect, function (value, key) {
if (value instanceof RegExp) {
return value.test(_.get(branch, key));
} else {
return _.isEqual(_.clone(_.get(branch, key)), value);
}
}) && _.every(match, function (_value, key) {
return branch.hasOwnProperty(key);
}) && _.every(tests, function (t) {
return t();
});
};
};
// NOTES
// Here, I start to build a tester function for the walker base function
// We start to introduce something of the ease of jquery selector syntax for finding
// objects nested deeply in data.
// It's not fully featured, and can't find children, but it works well for what it does.
// Select the children of element based on tester
// If tester is not a function, use kv_typetest to create one
// Options are pass-throughed to walker.
var selector = $ = function (element, tester, opts) {
var buf = [];
if (!_.isFunction(tester)) {
tester = kv_typetest(tester);
}
var callback = function (branch) {
buf.push(branch);
};
walker(element, tester, callback, opts);
if (buf.length === 1)
return buf[0];
return buf;
};
$ = selector;
// NOTES
// Selector is the third and final piece in this selection feature
// It allows one to do something like `$(nested_obj, 'hello:world')`
// to find all nodes with {hello: 'world'} in it.
// Or load('app_specific_mongorc.js');
_.mixin({
session: function (key) {
return db.sessions.findOne({_id: key});
},
invalidate_session: function (key) {
return db.sessions.remove({_id: key});
},
// add your own
});
// NOTES
// This is a great place to put application-specific helper functions
// for helping you deal with the day-to-day tasks in your database.
// Autologin
auth.ro();
})();
// Finally, auto-login into read-only mode and execute the closure.
@kols
Copy link

kols commented Mar 28, 2016

testing the script and find that isMaster.ismaster is not a function but a boolean value:
https://gist.github.com/yanatan16/6148978#file-mongorc-js-L17

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment