node的实践(项目二)
Posted 飘然离去
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node的实践(项目二)相关的知识,希望对你有一定的参考价值。
找以前看看简单的demo,看看node是怎么操作Mongo然后又是渲染前台的,与前面的项目一中的对比。
1.操作Mongo数据库的方法和方式。
var mongodb = require(‘./db‘), markdown = require(‘markdown‘).markdown; function Post(name, head, title, tags, post) { this.name = name; this.head = head; this.title = title; this.tags = tags; this.post = post; } module.exports = Post; //存储一篇文章及其相关信息 Post.prototype.save = function(callback) { var date = new Date(); //存储各种时间格式,方便以后扩展 var time = { date: date, year : date.getFullYear(), month : date.getFullYear() + "-" + (date.getMonth() + 1), day : date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(), minute : date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + (date.getMinutes() < 10 ? ‘0‘ + date.getMinutes() : date.getMinutes()) } //要存入数据库的文档 var post = { name: this.name, head: this.head, time: time, title:this.title, tags: this.tags, post: this.post, comments: [], reprint_info: {}, pv: 0 }; //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //将文档插入 posts 集合 collection.insert(post, { safe: true }, function (err) { mongodb.close(); if (err) { return callback(err);//失败!返回 err } callback(null);//返回 err 为 null }); }); }); }; //一次获取十篇文章 Post.getTen = function(name, page, callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } var query = {}; if (name) { query.name = name; } //使用 count 返回特定查询的文档数 total collection.count(query, function (err, total) { //根据 query 对象查询,并跳过前 (page-1)*10 个结果,返回之后的 10 个结果 collection.find(query, { skip: (page - 1)*10, limit: 10 }).sort({ time: -1 }).toArray(function (err, docs) { mongodb.close(); if (err) { return callback(err); } //解析 markdown 为 html docs.forEach(function (doc) { doc.post = markdown.toHTML(doc.post); }); callback(null, docs, total); }); }); }); }); }; //获取一篇文章 Post.getOne = function(name, day, title, callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //根据用户名、发表日期及文章名进行查询 collection.findOne({ "name": name, "time.day": day, "title": title }, function (err, doc) { if (err) { mongodb.close(); return callback(err); } if (doc) { //每访问 1 次,pv 值增加 1 collection.update({ "name": name, "time.day": day, "title": title }, { $inc: {"pv": 1} }, function (err) { mongodb.close(); if (err) { return callback(err); } }); //解析 markdown 为 html doc.post = markdown.toHTML(doc.post); doc.comments.forEach(function (comment) { comment.content = markdown.toHTML(comment.content); }); callback(null, doc);//返回查询的一篇文章 } }); }); }); }; //返回原始发表的内容(markdown 格式) Post.edit = function(name, day, title, callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //根据用户名、发表日期及文章名进行查询 collection.findOne({ "name": name, "time.day": day, "title": title }, function (err, doc) { mongodb.close(); if (err) { return callback(err); } callback(null, doc);//返回查询的一篇文章(markdown 格式) }); }); }); }; //更新一篇文章及其相关信息 Post.update = function(name, day, title, post, callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //更新文章内容 collection.update({ "name": name, "time.day": day, "title": title }, { $set: {post: post} }, function (err) { mongodb.close(); if (err) { return callback(err); } callback(null); }); }); }); }; //删除一篇文章 Post.remove = function(name, day, title, callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //查询要删除的文档 collection.findOne({ "name": name, "time.day": day, "title": title }, function (err, doc) { if (err) { mongodb.close(); return callback(err); } //如果有 reprint_from,即该文章是转载来的,先保存下来 reprint_from var reprint_from = ""; if (doc.reprint_info.reprint_from) { reprint_from = doc.reprint_info.reprint_from; } if (reprint_from != "") { //更新原文章所在文档的 reprint_to collection.update({ "name": reprint_from.name, "time.day": reprint_from.day, "title": reprint_from.title }, { $pull: { "reprint_info.reprint_to": { "name": name, "day": day, "title": title }} }, function (err) { if (err) { mongodb.close(); return callback(err); } }); } //删除转载来的文章所在的文档 collection.remove({ "name": name, "time.day": day, "title": title }, { w: 1 }, function (err) { mongodb.close(); if (err) { return callback(err); } callback(null); }); }); }); }); }; //返回所有文章存档信息 Post.getArchive = function(callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //返回只包含 name、time、title 属性的文档组成的存档数组 collection.find({}, { "name": 1, "time": 1, "title": 1 }).sort({ time: -1 }).toArray(function (err, docs) { mongodb.close(); if (err) { return callback(err); } callback(null, docs); }); }); }); }; //返回所有标签 Post.getTags = function(callback) { //打开数据库 mongodb.open(function (err, db) { if (err) { return callback(err); } //读取 posts 集合 db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //distinct 用来找出给定键的所有不同值 collection.distinct("tags", function (err, docs) { mongodb.close(); if (err) { return callback(err); } callback(null, docs); }); }); }); }; //返回含有特定标签的所有文章 Post.getTag = function(tag, callback) { mongodb.open(function (err, db) { if (err) { return callback(err); } db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //查询所有 tags 数组内包含 tag 的文档 //并返回只含有 name、time、title 组成的数组 collection.find({ "tags": tag }, { "name": 1, "time": 1, "title": 1 }).sort({ time: -1 }).toArray(function (err, docs) { mongodb.close(); if (err) { return callback(err); } callback(null, docs); }); }); }); }; //返回通过标题关键字查询的所有文章信息 Post.search = function(keyword, callback) { mongodb.open(function (err, db) { if (err) { return callback(err); } db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } var pattern = new RegExp(keyword, "i"); collection.find({ "title": pattern }, { "name": 1, "time": 1, "title": 1 }).sort({ time: -1 }).toArray(function (err, docs) { mongodb.close(); if (err) { return callback(err); } callback(null, docs); }); }); }); }; //转载一篇文章 Post.reprint = function(reprint_from, reprint_to, callback) { mongodb.open(function (err, db) { if (err) { return callback(err); } db.collection(‘posts‘, function (err, collection) { if (err) { mongodb.close(); return callback(err); } //找到被转载的文章的原文档 collection.findOne({ "name": reprint_from.name, "time.day": reprint_from.day, "title": reprint_from.title }, function (err, doc) { if (err) { mongodb.close(); return callback(err); } var date = new Date(); var time = { date: date, year : date.getFullYear(), month : date.getFullYear() + "-" + (date.getMonth() + 1), day : date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(), minute : date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + (date.getMinutes() < 10 ? ‘0‘ + date.getMinutes() : date.getMinutes()) } delete doc._id;//注意要删掉原来的 _id doc.name = reprint_to.name; doc.head = reprint_to.head; doc.time = time; doc.title = (doc.title.search(/[转载]/) > -1) ? doc.title : "[转载]" + doc.title; doc.comments = []; doc.reprint_info = {"reprint_from": reprint_from}; doc.pv = 0; //更新被转载的原文档的 reprint_info 内的 reprint_to collection.update({ "name": reprint_from.name, "time.day": reprint_from.day, "title": reprint_from.title }, { $push: { "reprint_info.reprint_to": { "name": doc.name, "day": time.day, "title": doc.title }} }, function (err) { if (err) { mongodb.close(); return callback(err); } }); //将转载生成的副本修改后存入数据库,并返回存储后的文档 collection.insert(doc, { safe: true }, function (err, post) { mongodb.close(); if (err) { return callback(err); } callback(err, post[0]); }); }); }); }); };
2.操作mysql的方式;
‘use strict‘; var pool = require(‘./pool‘); var Util = require(‘../utils/util‘); function User(data) { this.userId = data.userId; //用户id this.userLogin = data.userLogin; //用户名 this.userPass = data.userPass; //密码 this.userSalt = data.userSalt; //加密时使用的盐 this.userNicename = data.userNicename; //名字,通常为中文名 this.userEmail = data.userEmail; //邮箱 this.userRegistered = data.userRegistered || new Date(); //注册日期 this.userStatus = data.userStatus; //用户状态 this.privilege = data.privilege; //权限 } User.ITERATIONS = 8; User.KEY_LEN = 64; User.PWD_LENGTH = 128; /** * 根据id来查找用户 * @static method findById * @for User * @param {Number} id 用户id * @param {Function} callback 回调函数,第一个参数是错误对象或null,第二个参数是User对象 */ User.findById = function(id, callback) { if (!Util.isInt(id)) { return callback(new Error(‘id is not an integer‘)); } pool.getConnection(function(err, conn) { if (err) { return callback(err); } var sql = ‘SELECT * FROM cp_user WHERE user_id = ?‘; conn.query(sql, [id], function(err, rows, fields) { conn.release(); var user; if (!err && rows.length) { var userData = {}; userData.userId = rows[0].user_id; userData.userLogin = rows[0].user_login; userData.userPass = rows[0].user_pass; userData.userSalt = rows[0].user_salt; userData.userNicename = rows[0].user_nicename; userData.userEmail = rows[0].user_email; userData.userRegistered = rows[0].user_registered; userData.userStatus = rows[0].user_status; user = new User(userData); } callback(err, user); }); }); }; /** * 根据email来查找用户 * @static method findByEmail * @for User * @param {String} email 邮箱 * @param {Function} callback 回调函数,第一个参数是错误对象或null,第二个参数是User对象 */ User.findByEmail = function(email, callback) { if (!Util.isString(email)) { return callback(new Error(‘email is not a string type‘)); } pool.getConnection(function(err, conn) { if (err) { callback(err); } else { var sql = ‘SELECT * FROM cp_user WHERE user_email = ?‘; conn.query(sql, [email], function(err, rows, fields) { conn.release(); var user; if (!err && rows.length) { var userData = {}; userData.userId = rows[0].user_id; userData.userLogin = rows[0].user_login; userData.userPass = rows[0].user_pass; userData.userSalt = rows[0].user_salt; userData.userNicename = rows[0].user_nicename; userData.userEmail = rows[0].user_email; userData.userRegistered = rows[0].user_registered; userData.userStatus = rows[0].user_status; user = new User(userData); } callback(err, user); }); } }); }; /** * 查找指定数目的用户,若没有start,count这两个参数,表示要查找所有的用户 * @static method findUsers * @for User * @param {Number} start 索引,索引从0开始 * @param {Number} count 要查找的用户数目 * @param {Function} callback 回调函数,第一个参数是错误对象或null,第二个参数是User对象数组 */ User.findUsers = function(start, count, callback) { if (!Util.isInt(start)) { return callback(new Error(‘start is supposed to be an integer‘)); } if (!Util.isInt(count)) { return callback(new Error(‘count is supposed to be an integer‘)); } if (count <= 0) { return callback(new Error(‘count must be greater than 0‘)); } pool.getConnection(function(err, conn) { if (err) { callback(err); } else { var sql = ‘SELECT * FROM cp_user LIMIT ?, ?‘; var arr = [start, count]; conn.query(sql, arr, function(err, rows, fields) { conn.release(); if (err) { rows = []; } for (var i = 0; i < rows.length; i++) { var userData = {}; userData.userId = rows[i].user_id; userData.userLogin = rows[i].user_login; userData.userPass = rows[i].user_pass; userData.userSalt = rows[i].user_salt; userData.userNicename = rows[i].user_nicename; userData.userEmail = rows[i].user_email; userData.userRegistered = rows[i].user_registered; userData.userStatus = rows[i].user_status; rows[i] = new User(userData); } callback(err, rows); }); } }); }; /** * 查找所有的用户 * @static method findAll * @for User * @param {Function} callback 回调函数,第一个参数是错误对象或null,第二个参数是User对象数组 */ User.findAll = function(callback) { pool.getConnection(function(err, conn) { if (err) { callback(err); } else { var sql = ‘SELECT * FROM cp_user‘; conn.query(sql, function(err, rows, fields) { conn.release(); if (err) { rows = []; } for (var i = 0; i < rows.length; i++) { var userData = {}; userData.userId = rows[i].user_id; userData.userLogin = rows[i].user_login; userData.userPass = rows[i].user_pass; userData.userSalt = rows[i].user_salt; userData.userNicename = rows[i].user_nicename; userData.userEmail = rows[i].user_email; userData.userRegistered = rows[i].user_registered; userData.userStatus = rows[i].user_status; rows[i] = new User(userData); } callback(err, rows); }); } }); }; /** * 根据email来修改用户的密码 * @static method updatePwdByEmail * @for User * @param {String} email 邮箱 * @param {String} passwd 密码 * @param {Function} callback 回调函数,参数是错误对象或null */ User.updatePwdByEmail = function(email, passwd, callback) { if (!Util.isString(email)) { return callback(new Error(‘email is not a string type‘)); } if (!Util.isString(passwd)) { return callback(new Error(‘passwd is not a string type‘)); } if (passwd.length !== User.PWD_LENGTH) { return callback(new Error(‘passwd.length != User.PWD_LENGTH‘)); } pool.getConnection(function(err, conn) { if (err) { callback(err); } else { var sql = ‘UPDATE cp_user SET user_pass = ? WHERE user_email = ?‘; conn.query(sql, [passwd, email], function(err) { conn.release(); callback(err); }); } }); }; /** * 根据id来修改用户的密码 * @static method updatePwdById * @for User * @param {Number} id 用户id * @param {String} passwd 密码 * @param {Function} callback 回调函数,参数是错误对象或null */ User.updatePwdById = function(id, passwd, callback) { if (!Util.isInt(id)) { return callback(new Error(‘id is not an integer‘)); } if (!Util.isString(passwd)) { return callback(new Error(‘passwd is not a string type‘)); } if (passwd.length !== User.PWD_LENGTH) { return callback(new Error(‘passwd.length != User.PWD_LENGTH‘)); } pool.getConnection(function(err, conn) { if(err) { callback(err); }else { var sql = ‘UPDATE cp_user SET user_pass = ? WHERE user_id = ?‘; conn.query(sql, [passwd, id], function(err, result) { conn.release(); callback(err); }); } }); }; /** * 新增一个用户 * @method save * @for User * @param {Function} callback 回调函数,第一个参数是错误对象或null,第二个参数是User对象 */ User.prototype.save = function(callback) { var self = this; pool.getConnection(function(err, conn) { if(err) { return callback(err); } var sql = ‘INSERT INTO cp_user (user_login, user_salt, user_pass, user_nicename, user_email, user_registered, user_status) VALUES (?,?,?,?,?,?,?)‘; var arr = [ self.userLogin, self.userSalt, self.userPass, self.userNicename, self.userEmail, self.userRegistered, self.userStatus]; conn.query(sql, arr, function(err, result) { conn.release(); if(!err) { self.userId = result.insertId; } callback(err, self); }); }); }; /** * 有些属性不能暴露给客户端,返回一个只有部分属性的User对象 * @method toUser * @for User * @return {User} 返回一个User对象 */ User.prototype.toUser = function() { var user = new User(this); delete user.userPass; delete user.userSalt; return user; };
以上是关于node的实践(项目二)的主要内容,如果未能解决你的问题,请参考以下文章