Skip to content

Commit

Permalink
More db schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
billstclair committed May 9, 2012
1 parent 14faabb commit a7c3463
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 24 deletions.
4 changes: 2 additions & 2 deletions README
@@ -1,5 +1,5 @@
A simple maze game written in JavaScript.
Uses node.js, socket.io, express, and redis for the server side.
Uses node.js, socket.io, express, and mongoose/MongoDB for the server side.

There's a live server under active development (hence likely to be
flaky) at:
Expand All @@ -9,7 +9,7 @@ flaky) at:
The Git archive does NOT include required modules. To get them:

cd /path/to/jsmaze # or a parent directory. I use $HOME
npm install socket.io express redis optimist
npm install socket.io express mongoose optimist

To run the server:

Expand Down
176 changes: 155 additions & 21 deletions server/lib/db.js
Expand Up @@ -17,26 +17,91 @@ function DB() {
var self = this;

// Models
var Account = null;
var Account;
var Player;
var Maze;
var Image;

init();

function addJSONVirtual(model, vfield, field) {
model.virtual(vfield)
.get(function() {
var val = this[field];
return (val===undefined) ? undefined : JSON.parse(val);
})
.set(function(val) {
this.set(field, JSON.stringify(val));
});
}

function init() {
self.mongoose = mongoose;
mongoose.connect('mongodb://localhost/jsmaze');

var Schema = mongoose.Schema;
var noId = {noId: true};

Account = new Schema({
userid: {type: String, index: true},
userid: {type: String, unique: true},
pwhash: {type: String},
email: {type: String}
});
}, noId);
Account = mongoose.model('Account', Account);

// An account can have multiple players
Player = new Schema({
name: {type: String, unique: true},
userid: {type: String, index: true},
_appearance: String, // {left:l, right:r, front:f, back:b}
maze: String, // name of last maze
_pos: String, // {i:<i>,j:<j>}
_dir: String, // {i:<i>,j:<j>}
size: Number
}, noId);
addJSONVirtual(Player, 'appearance', '_appearance');
addJSONVirtual(Player, 'pos', '_pos');
addJSONVirtual(Player, 'dir', '_dir');
Player = mongoose.model('Player', Player);

Maze = new Schema({
name: {type: String, unique: true}, // unique name (good idea?)
userid: {type: String, index: true}, // user who owns this maze
_map: String, // arg to new jsmaze.Maze()
_walls: String, // {'i,j':<idx>, ...}
size: Number
}, noId);
addJSONVirtual(Maze, 'map', '_map');
addJSONVirtual(Maze, 'walls', '_walls');
Maze = mongoose.model('Maze', Maze);

Image = new Schema({
idx: {type: Number, unique: true},
userid: {type: String, index: true},
url: String,
size: Number
}, noId);
Image = mongoose.model('Image', Image);

Stats = new Schema({
userid: {type: String, unique: true},
totalSize: Number,
playerCount: Number,
playerSize: Number,
mazeCount: Number,
mazeSize: Number,
imageCount: Number,
ImageSize: Number
});
Stats = mongoose.model('Stats', Stats);
}

self.print = function(error, result) {
console.log(error ? error : result);
console.log(error ? 'error: ' + error : result);
}

function ensureCallback(cb) {
return (typeof(cb) == 'function') ? cb : self.print;
}

self.sha256 = sha256;
Expand All @@ -46,32 +111,101 @@ function DB() {
return hash.digest('hex');
}

self.createAccount = function(login, password, email, callback) {
Account.findOne({login: login}, function(err, res) {
if (res) callback('An account already exists for: ' + login);
else {
var pwhash = sha256(password);
acct = new Account({login: login, pwhash: pwhash, email: email});
acct.save(callback);
}
function pwhash(login, password) {
return sha256(login + password);
}

//
// Account functions
//

self.makeAccount = function(login, password, email, _return) {
_return = ensureCallback(_return);
var hash = pwhash(login, password);
var acct = new Account({login: login, pwhash: hash, email: email});
acct.save(function(err, res) {
if (err) _return('An account already exists for: ' + login);
else _return(null, res);
});
}

function eachModel(model, each) {
if (!(typeof(each) == 'function')) each = console.log;
var stream = model.find().stream();
stream.on('data', function(doc) {
each(doc);
});
stream.on('close', function() {
each(null);
});
}

self.users = function(callback) {
Account.find({}, callback);
self.eachAccount = function(each) {
eachModel(Account, each);
}

self.deleteAccount = function(login, _return) {
_return = ensureCallback(_return);
Account.remove({login: login}, _return);
}

self.deleteAccount = function(login, callback) {
Account.remove({login: login}, callback);
self.findAccount = function(login, _return) {
_return = ensureCallback(_return);
Account.findOne({login: login}, _return);
}

self.login = function(login, password, callback) {
self.login = function(login, password, _return) {
_return = ensureCallback(_return);
var badmsg = 'Unknown login or wrong password';
Account.findOne({login: login}, function(err, res) {
if (err || res==null) return callback(err || badmsg);
var pwhash = sha256(password);
if (res.pwhash != pwhash) return callback(badmsg);
callback(null, res);
if (err || res==null) return _return(err || badmsg);
var hash = pwhash(login, password);
if (res.pwhash != hash) _return(badmsg);
else _return(null, res);
});
}

function cb(user, local) {
return function(err, res) {
if (err) user && user(err);
else local(res);
};
}

//
// Player functions
//
self.makePlayer = function(name, userid, _return) {
_return = ensureCallback(_return);
self.findAccount(userid, cb(_return, function(user) {
if (!user) _return('No user with userid: ' + userid);
else {
var player = new Player({name: name, userid: userid});
player.save(function(err, res) {
if (err) _return('Player already exists with name: ' + name);
else _return(null, res);
});
}
}));
}

self.findPlayer = function(name, _return) {
_return = ensureCallback(_return);
Player.findOne({name: name}, _return);
}

self.findUserPlayers = function(userid, _return) {
_return = ensureCallback(_return);
Player.find({userid: userid}, _return);
}

self.eachPlayer = function(each) {
eachModel(Player, each);
}

self.deletePlayer = function(name, _return) {
_return = ensureCallback(_return);
Player.remove({name: name}, _return);
}

}
1 change: 0 additions & 1 deletion server/lib/network.js
Expand Up @@ -11,7 +11,6 @@
var express = require('express');
var app = express.createServer();
var io = require('socket.io').listen(app);
var fs = require('fs');
var evaluator = require('../shared/evalFactory').makeEvaluator();
var mazeServer = require('./mazeServer');
var url = require('url');
Expand Down

0 comments on commit a7c3463

Please sign in to comment.