Last active
December 16, 2017 17:18
-
-
Save jonathanxie/87b2b280f5ecadcd96ec to your computer and use it in GitHub Desktop.
Use command line nodeJS to drop, create, and seed a mongoDB database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Utility library for handlng asynchronous calls | |
| var async = require('async'); | |
| // URL to connect to a local MongoDB with database test | |
| var databaseURL = 'mongodb://localhost:27017/test'; | |
| // We use mongoose to define our schema and interact with MongoDB | |
| var mongoose = require('mongoose'); | |
| var bcrypt = require('bcrypt-nodejs'); | |
| // Define User schema model with 3 fields: user, email, password | |
| var userSchema = new mongoose.Schema({ | |
| name: { type: String, required: "Name is required", }, | |
| email: { type: String, required: "Email is required", unique: true }, | |
| password: { type: String, required: "Your password is required"}, | |
| }); | |
| // Mongoose middleware that is called before save to hash the password | |
| userSchema.pre('save', function(next, err) { | |
| var user = this; | |
| var SALT_FACTOR = 10; | |
| // If user is not new or the password is not modified | |
| if (!user.isNew && !user.isModified('password')) { | |
| return next(); | |
| } | |
| // Encrypt password before saving to database | |
| bcrypt.genSalt(SALT_FACTOR, function(err, salt) { | |
| if (err) return next(err); | |
| bcrypt.hash(user.password, salt, null, function(err, hash) { | |
| if (err) | |
| return next(err); | |
| user.password = hash; | |
| next(); | |
| }); | |
| }); | |
| }); | |
| var User = mongoose.model('User', userSchema); | |
| // User series method to make sure asynchronous calls below run serially | |
| async.series([ | |
| // First function - connect to MongoDB, then drop the database | |
| function(callback) { | |
| /** | |
| * Originally, I wanted to use mongoose to drop the database | |
| * but the code below doesn't drop the database, only clears | |
| * all documents. Refer to: | |
| * | |
| * https://github.com/LearnBoost/mongoose/issues/1654 | |
| */ | |
| /* | |
| mongoose.connection.on('open', function() { | |
| mongoose.connection.db.dropDatabase(function(err) { | |
| if (err) console.log(err); | |
| mongoose.connection.close(function(err) { | |
| callback(null, 'Dropped database'); | |
| }); | |
| }); | |
| }); | |
| */ | |
| // Conncect to MongoDB using the native MongoDB client for NodeJS | |
| var MongoClient = require('mongodb').MongoClient; | |
| MongoClient.connect(databaseURL, function(err, db) { | |
| if(err) throw err; | |
| // Drop database | |
| db.dropDatabase(); | |
| // Close database connection because we need to open a connection | |
| // with mongoose later to populate the database | |
| db.close(); | |
| // Execute callback so next method in async.serial gets called | |
| callback(null, 'SUCCESS - dropped database'); | |
| }); | |
| }, | |
| // Second function - connect to MongoDB using mongoose, which is an asynchronous call | |
| function(callback) { | |
| // Open connection to DB | |
| mongoose.connect(databaseURL); | |
| // Need to listen to 'connected' event then execute callback method | |
| // to call the next set of code in the async.serial array | |
| mongoose.connection.on('connected', function(){ | |
| console.log('db connected via mongoose'); | |
| callback(null, 'SUCCESS - Connected to mongodb'); | |
| }); | |
| }, | |
| // Third function - use Mongoose to create a User model and save it to database | |
| function(callback) { | |
| // BEGIN SEED DATABASE | |
| // Use an array to store a list of User model objects to save to the database | |
| var users = []; | |
| var testUserCount = 20; | |
| for (i = 0; i < testUserCount; i++) { | |
| var user = new User({ | |
| name: i, | |
| email: i + '@' + i + '.com', | |
| // Password will be hashed in the userSchema.pre middleware | |
| password: 'asdfasdf' | |
| }); | |
| // Add newly create User model to 'users' array | |
| users.push(user); | |
| } | |
| console.log("Populating database with %s users", users.length); | |
| // Use 'async.eachSeries' to loop through the users array | |
| // to make sure each asnychronous call to save the user completes | |
| // before moving to the next User model item | |
| async.eachSeries( | |
| // First parameter is the array to be iterated over | |
| users, | |
| // 2nd param is the function that each item is passed to | |
| // Note there is another 'callback' method called asyncEachCallback | |
| function(user, asyncEachCallback){ | |
| // There is no need to make a call to create the 'test' database | |
| // Saving a model will automatically create the database | |
| user.save(function(err) { | |
| if(err) { | |
| // Send JSON response to console for errors | |
| console.dir(err); | |
| } | |
| // Print out which user we are saving | |
| console.log("Saving user #%s out of %s", user.name, testUserCount); | |
| // Call 'ayncEachCallback' and NOT 'callback' to ensure that the next | |
| // 'user' item in the 'users' array gets called to be saved to the database | |
| asyncEachCallback(); | |
| }); | |
| }, | |
| // 3rd param is the function to call when everything's done | |
| function(err){ | |
| if (err) console.dir(err); | |
| // All tasks are done now | |
| console.log("Finished aysnc.each in seeding db") | |
| //Callback for async series call | |
| callback(null, 'SUCCESS - Seed database'); | |
| } | |
| ); | |
| // END SEED DATABASE | |
| } | |
| ], | |
| // optional callback | |
| function(err, results){ | |
| console.log("\n\nExiting database seed"); | |
| if(err) { | |
| console.log("Errors = "); | |
| console.dir(errors) | |
| } else { | |
| console.log("Results = "); | |
| console.log(results); | |
| } | |
| // Exit the process to get back to terrminal console | |
| process.exit(0); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment