Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

JugglingDB Support #153

Open
wants to merge 4 commits into from

2 participants

@camshaft

I added support for the ORM framework JugglingDB which creates a multi-database compatibility layer. The api is very similar to mongoose making it easier to transition to. IMO this will add even more flexibility to calipso.

This PR isn't completely ready yet but I did want to create it to get some feedback and possibly help with testing.

I've ran the tests and they all pass on mongodb and the in-place memory adapter. The redis adapter does not work when assigning roles because it won't store an array which I'll hopefully fix in the juggling adapter. I haven't been able to test the rest of the adapters though it shouldn't be to hard to do.

Let me know what you think.

@richtera
Collaborator

Could you rebase this? I am sorry but I merged a large commit of mine. I would like to quickly try this to see if it makes sense to merge or put it on another branch.

@camshaft

Just rebased it. I wasn't able to test it because I'm pretty busy with other projects currently. If I can do anything to help let me know and I should be able to work some time in.

@richtera
Collaborator
@richtera
Collaborator

Sorry, I did not get around to testing this. Are there other projects using jugglingdb yet? I actually have some other projects this might be interesting for as well.

@camshaft

Yeah railway.js uses it as its ORM.

@richtera
Collaborator

This is still pending, sorry. I kind of got caught up in windows specific things and wanted support for google, twitter and facebook auth.

@richtera
Collaborator

I am planning to do this next; getting windows support and everyauth took longer than expected. If you can rebase this it would be greatly appreciated, otherwise I am pretty sure I can figure it out.

@camshaft

No problem. I'll do that later today.

@richtera
Collaborator

I created a branch "CamShaft-jugglingdb" with the merge. I am having some problems with it and some comments.
1. Somehow I can't login using it but it's also not throwing any errors. I'll need to debug but maybe you can check it out.
2. Would it be possible to assume {where:{...}} if you only get {...} so that existing findOne or find doesn't need to change? This is important because other modules would need to be rewritten even through almost 100% of them are just doing a plain where.

@richtera
Collaborator

FYI the active branch in calipso is "master". The "devel" branch is a little behind currently.

@richtera
Collaborator

I am having a problem at https://gist.github.com/4021763 on line 22.
Basically it seems that the Schema can't be used as a constructor but tries to create a new schema.
This tries to decode a value as a type. Any suggestions?

GOOD NEWS! This redis adapter version is deprecated, use redis2 instead. A lot of improvements, and new indexes incompatible with old (sorry about that): now we only store id and not ModelName:id in indexes. Also dates format in indexes changed to unix timestamp for better sorting and filtering performance
5 Nov 19:58:25 - info: Installing module content

welcome, message, default

I added a console.log(self.__data[attr]) at node_modules/jugglingdb/lib/abstract-class.js:82

SyntaxError: Unexpected token w
    at Object.parse (native)
    at AbstractClass._initProperties.def (/Users/andy/calipso/node_modules/jugglingdb/lib/abstract-class.js:82:46)
    at Array.forEach (native)
    at Function.Schema.define.NewClass.forEachProperty (/Users/andy/calipso/node_modules/jugglingdb/lib/schema.js:193:33)
    at ModelConstructor.AbstractClass._initProperties (/Users/andy/calipso/node_modules/jugglingdb/lib/abstract-class.js:74:10)
    at ModelConstructor.AbstractClass (/Users/andy/calipso/node_modules/jugglingdb/lib/abstract-class.js:30:10)
    at new ModelConstructor (/Users/andy/calipso/node_modules/jugglingdb/lib/schema.js:153:23)
    at Object.install (/Users/andy/calipso/modules/core/content/content.js:989:12)
    at /Users/andy/calipso/modules/core/admin/admin.js:540:40
    at Array.forEach (native)
5 Nov 19:58:25 - error: Module 'content' was unable to be installed... Reason: Object welcome, message, default has no method 'forEach'
@richtera
Collaborator

FYI same thing happens with memory database type. Just so you don't specifically check redis:

5 Nov 20:30:23 - info: Installing module content
SyntaxError: Unexpected token w
    at Object.parse (native)
    at AbstractClass._initProperties.def (/Users/andy/calipso/node_modules/jugglingdb/lib/abstract-class.js:81:46)
    at Array.forEach (native)
    at Function.Schema.define.NewClass.forEachProperty (/Users/andy/calipso/node_modules/jugglingdb/lib/schema.js:193:33)
    at ModelConstructor.AbstractClass._initProperties (/Users/andy/calipso/node_modules/jugglingdb/lib/abstract-class.js:74:10)
    at ModelConstructor.AbstractClass (/Users/andy/calipso/node_modules/jugglingdb/lib/abstract-class.js:30:10)
    at new ModelConstructor (/Users/andy/calipso/node_modules/jugglingdb/lib/schema.js:153:23)
    at Object.install (/Users/andy/calipso/modules/core/content/content.js:989:12)
    at /Users/andy/calipso/modules/core/admin/admin.js:540:40
    at Array.forEach (native)
5 Nov 20:30:23 - error: Module 'content' was unable to be installed... Reason: Object welcome, message, default has no method 'forEach'
5 Nov 20:30:23 - info: Installing module contentTypes
@richtera
Collaborator

Figured out this particular problem. The defaults for the initial contents records didn't have an Array as the initial value for the tags property. Your lib was trying to parse it as Json, I suppose mongoose tries to split a string by "," and uses that.

@richtera
Collaborator

Having problems with strings. When I try to serialize the user object into the cookie it looks like this:

{"username":"andy","isAdmin":false,"id":1,"language":"en","roles":[{"0":"A","1":"d","2":"m","3":"i","4":"n","5":"i","6":"s","7":"t","8":"r","9":"a","10":"t","11":"o","12":"r","bold":"\u001b[1mAdministrator\u001b[22m","underline":"\u001b[4mAdministrator\u001b[24m","italic":"\u001b[3mAdministrator\u001b[23m","inverse":"\u001b[7mAdministrator\u001b[27m","grey":"\u001b[90mAdministrator\u001b[39m","black":"\u001b[30mAdministrator\u001b[39m","yellow":"\u001b[33mAdministrator\u001b[39m","red":"\u001b[31mAdministrator\u001b[39m","green":"\u001b[32mAdministrator\u001b[39m","blue":"\u001b[34mAdministrator\u001b[39m","white":"\u001b[37mAdministrator\u001b[39m","cyan":"\u001b[36mAdministrator\u001b[39m","magenta":"\u001b[35mAdministrator\u001b[39m","rainbow":"\u001b[31mA\u001b[39m\u001b[33md\u001b[39m\u001b[32mm\u001b[39m\u001b[34mi\u001b[39m\u001b[35mn\u001b[39m\u001b[31mi\u001b[39m\u001b[33ms\u001b[39m\u001b[32mt\u001b[39m\u001b[34mr\u001b[39m\u001b[35ma\u001b[39m\u001b[31mt\u001b[39m\u001b[33mo\u001b[39m\u001b[32mr\u001b[39m","zebra":"A\u001b[7md\u001b[27mm\u001b[7mi\u001b[27mn\u001b[7mi\u001b[27ms\u001b[7mt\u001b[27mr\u001b[7ma\u001b[27mt\u001b[7mo\u001b[27mr","zalgo":"A̸͕̖̲̲̝̙̱̝̯̯͖̱̰͍̍ͪ̇̅ͥ̑̄̾̈̇̌̌ͤ̽͋̑d̦͓͈̠̤͚̬͚̦̯̮͎̘͇̲̣̱̩̻̬̬͖̯̺̮̼̗̗͍̠͖͇̣͚̱͎͍̤̝̞̻̗͉͚̣̤̮͔͚̯̹̱͚̽ͫ͋ͬͨͧ͜m̷̗̺̲̰̙̩̯̟̹͔̙̼̭̫̰͙̜̻͍̮̮͚͍͚͍̙̬̦̻̖̻̹͕̦̊̉̎̔ͭ͊̈̈͊̍͋́ͦ͋̍ͅi̛̬͙̦̫̲̳̣͈͇̬̮̤̣̲̙͇̪̲̦̜̩͕̯̼̖̟̓ͧͩ̓n͉̲̯̯͇͔̄ͧ̌ͯͤ͊̂̎̇̅ͭ̈̓͗̽ͭ͞ͅi̬͖͎̯͚͓͕͈̬̮̜̠͓̩̻̲̙̲̠̳̻̥̥̞̳̩̜͚͚̪̯̬̪̤͙͙̲͔̪̝͖̓̿͌̓͂̅̃̈̎̀s̶̠͎̣̫̱̮̭̩̪̬͇̙̤̣͕̟̱̻͉̻̣̥̬̞̠̯͕̫ͤ́̉̌͋̾ͅt̸̟̪̱̬͎̟̟̳̹̯̲̝̦̼͎͎͙̑ͩ̏ͦͣͥͤ̄̓̎ͨ̏ͩ̇͆̀̔ͅȓ̡͍͎̼̭͎̠͓̪́̏̿͗͊ͥͮ̋ͫ̂̅͊á̫̯̰̼͕̤̻͎̝͔̖͓̲̠̜̔̾ͮͪ̽͊̈̄́̀̃̈͠ͅt̜̬̭̥̺̦̩̗̞̭̲͇̤͖̳̳̰̬̺̫͈̏́ͣ͋̋̋̽̓ͧ̓ͤ͡o̞̲̙͚̹̦͈̺̬̱̝̳̞͕͈̞̪̮̖̤̭͔̤̭̬̼̫̘̦̲̖̪̬̜͖̠̗̯͇̙͈̾̌̂͗̾̓ͬ̍ͣͨ̎ͩ̍̀̾͠ȓ̟̪͇̻͕̰̪̦̯̤͇ͭͤ̄́ͅ","stripColors":"Administrator","id":1}]}

Which seems to be due to the fact the "new String('something')" in node is not a string but an object of type String. I tried to find out on the node chat to see if this is recent but I doubt it.

@richtera
Collaborator

I think there are problems with the List class. Adding an itemType property to the roles definition makes it work a tiny bit better but it's still broken. The redis2 adapter doesn't work unless indexes are defined and the redis adapter says it's deprecated. Boolean values are converted to strings of "true" and "false" and therefore "false" will show up as true. Do you have any suggestions on how to proceed? Or should we just wait?

@camshaft

ATM I don't have much time to look at it. I'm not using calipso anymore so it isn't a high priority for me.

That being said, if you feel like this is something that it's something you guys want, I can set aside some time to look at it.

@richtera
Collaborator
@camshaft

I have seen that issue with it before and it probably should be fixed upstream. It's an issue with those drivers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 485 additions and 321 deletions.
  1. +3 −2 lib/calipso.js
  2. +5 −1 lib/conf/default.json
  3. +2 −2 lib/core/Form.js
  4. +1 −1  lib/core/Lib.js
  5. +147 −0 lib/core/SessionStorage.js
  6. +66 −59 lib/core/Storage.js
  7. +2 −1  lib/core/Table.js
  8. +1 −1  lib/core/Utils.js
  9. +44 −34 modules/core/admin/admin.js
  10. +13 −13 modules/core/admin/templates/{install_mongo.html → install_db.html}
  11. +2 −2 modules/core/admin/templates/install_user.html
  12. +1 −1  modules/core/admin/templates/install_welcome.html
  13. +42 −46 modules/core/content/content.js
  14. +1 −1  modules/core/content/templates/listAdmin.html
  15. +7 −14 modules/core/contentTypes/contentTypes.js
  16. +1 −1  modules/core/contentTypes/templates/list.html
  17. +14 −19 modules/core/contentVersions/contentVersions.js
  18. +5 −5 modules/core/contentVersions/templates/list.html
  19. +2 −2 modules/core/contentVersions/templates/show.html
  20. +6 −8 modules/core/permissions/permissions.js
  21. +20 −14 modules/core/scheduler/scheduler.js
  22. +12 −14 modules/core/tagcloud/tagcloud.js
  23. +12 −13 modules/core/taxonomy/taxonomy.js
  24. +1 −1  modules/core/user/templates/role.list.html
  25. +24 −28 modules/core/user/user.js
  26. +9 −15 modules/core/user/user.roles.js
  27. +10 −1 package.json
  28. +2 −1  test/helpers/defaultConfig.json
  29. +27 −18 test/{lib.core.storage.js-disabled → lib.core.storage.js}
  30. +3 −3 themes/core/cleanslate/public/css/installation.css
View
5 lib/calipso.js
@@ -155,8 +155,8 @@ function initialiseCalipso(reloadConfig) {
// Configure the logging
calipso.logging.configureLogging();
- // Check / Connect Mongo
- calipso.storage.mongoConnect(calipso.config.get('database:uri'), false, function(err, connected) {
+ // Check / Connect Database
+ calipso.storage.connect(calipso.config.get('database:type'), calipso.config.get('database:configuration'), false, function(err, connected) {
if (err) {
console.log("There was an error connecting to the database: " + err.message);
@@ -175,6 +175,7 @@ function initialiseCalipso(reloadConfig) {
// Initialise, callback via calipso.initCallback
calipso.module.initModules();
+ calipso.db.autoupdate();
});
});
View
6 lib/conf/default.json
@@ -2,7 +2,11 @@
"version":"0.3.0",
"installed":false,
"database": {
- "uri":"mongodb://localhost/calipso"
+ "type": "memory",
+ "configuration": {
+ "database": "calipso"
+ },
+ "logQueries": false
},
"server": {
"name":"Calipso",
View
4 lib/core/Form.js
@@ -1096,9 +1096,9 @@ me.mapFields = function(fields, record) {
var props = Object.getOwnPropertyNames(fields);
props.forEach( function(name) {
- // If not private (e.g. _id), then copy
+ // If not private (e.g. id), then copy
if(!name.match(/^_.*/)) {
- record.set(name, fields[name]);
+ record[name] = fields[name];
}
});
View
2  lib/core/Lib.js
@@ -16,7 +16,7 @@ module.exports = {
express: require('express'),
step: require('step'),
util: require('util'),
- mongoose: require('mongoose'),
+ jugglingdb: require('jugglingdb'),
url: require('url'),
ejs: require('ejs'),
pager: require(rootpath + 'utils/pager'),
View
147 lib/core/SessionStorage.js
@@ -0,0 +1,147 @@
+/**
+ * Module dependencies.
+ */
+
+var Store = require('connect').session.Store,
+ _ = require('underscore'),
+ jugglingdb = require('jugglingdb');
+
+/**
+ * Initialize a new `JugglingStore`.
+ *
+ * @api public
+ */
+
+var JugglingStore = module.exports = function JugglingStore(dbType, dbConfig) {
+ this.db = new jugglingdb.Schema(dbType, dbConfig);
+ this.db.define('Session', {
+ sid: String,
+ data: String
+ });
+};
+
+/**
+ * Inherit from `Store.prototype`.
+ */
+
+JugglingStore.prototype.__proto__ = Store.prototype;
+
+/**
+ * Attempt to fetch session by the given `sid`.
+ *
+ * @param {String} sid
+ * @param {Function} fn
+ * @api public
+ */
+
+JugglingStore.prototype.get = function(sid, fn){
+ var self = this;
+ process.nextTick(function(){
+
+ var Session = self.db.models.Session;
+
+ Session.findOne({where:{sid:sid}}, function (err, sess) {
+ var expires;
+ if (!err && sess && sess.data) {
+ var sessData = JSON.parse(sess.data);
+ expires = 'string' == typeof sessData.cookie.expires
+ ? new Date(sessData.cookie.expires)
+ : sessData.cookie.expires;
+ if (!expires || new Date < expires) {
+ fn(null, sessData);
+ } else {
+ sess.destroy(fn);
+ }
+ } else {
+ fn();
+ }
+ })
+ });
+};
+
+/**
+ * Commit the given `sess` object associated with the given `sid`.
+ *
+ * @param {String} sid
+ * @param {Session} sess
+ * @param {Function} fn
+ * @api public
+ */
+
+JugglingStore.prototype.set = function(sid, sess, fn){
+ var self = this;
+ process.nextTick(function(){
+ var Session = self.db.models.Session;
+ Session.findOne({where:{sid:sid}}, function(err, session) {
+ if(err) {
+ fn(err);
+ return;
+ }
+ if(!session) session = new Session({sid:sid, data:'{}'});
+
+ var sessData = JSON.parse(session.data) || {};
+ _.extend(sessData, sess);
+ session.data = JSON.stringify(sessData);
+
+ session.save(fn);
+ })
+ });
+};
+
+/**
+ * Destroy the session associated with the given `sid`.
+ *
+ * @param {String} sid
+ * @api public
+ */
+
+JugglingStore.prototype.destroy = function(sid, fn){
+ var self = this;
+ process.nextTick(function(){
+ self.db.models.Session.findOne({where:{sid:sid}}, function(err, sess) {
+ if(err) fn(err);
+ if(sess) sess.destroy(fn);
+ else fn();
+ })
+ });
+};
+
+/**
+ * Invoke the given callback `fn` with all active sessions.
+ *
+ * @param {Function} fn
+ * @api public
+ */
+
+JugglingStore.prototype.all = function(fn){
+ var arr = []
+ this.db.models.Session.all({},function(err, sessions) {
+ if (err) fn(err);
+ for(sess in sessions) {
+ arr.push(sess.sid);
+ }
+ fn(null, arr);
+ });
+};
+
+/**
+ * Clear all sessions.
+ *
+ * @param {Function} fn
+ * @api public
+ */
+
+JugglingStore.prototype.clear = function(fn){
+ this.db.models.Session.destroyAll(fn||function() {});
+};
+
+/**
+ * Fetch number of sessions.
+ *
+ * @param {Function} fn
+ * @api public
+ */
+
+JugglingStore.prototype.length = function(fn){
+ this.db.models.Session.count({}, fn||function() {});
+};
View
125 lib/core/Storage.js
@@ -1,16 +1,16 @@
/*!
- * Calipso MongoDB Storage Library
+ * Calipso DB Storage Library
* Copyright(c) 2011 Clifton Cunningham
* MIT Licensed
*
- * This library provides a few simple functions that can be used to help manage MongoDB and Mongoose.
+ * This library provides a few simple functions that can be used to help manage JugglingDB.
*/
var rootpath = process.cwd(),
path = require('path'),
events = require('events'),
- mongoStore = require('connect-mongodb'),
- mongoose = require('mongoose'),
+ jugglingdb = require('jugglingdb'),
+ SessionStorage = require('./SessionStorage'),
calipso = require(path.join('..', 'calipso'));
function Storage() {
@@ -19,91 +19,98 @@ function Storage() {
}
/**
- * Check that the mongodb instance specified in the configuration is valid.
+ * Check that the database instance specified in the configuration is valid.
*/
-Storage.prototype.mongoConnect = function(dbUri, checkInstalling, next) {
+Storage.prototype.connect = function(dbType, config, checkInstalling, next) {
- // Test the mongodb configuration
+ // Test the db configuration
var isInstalled = calipso.config.get('installed');
- // If first option is callback, ste dbUri to config value
- if (typeof dbUri === "function") {
- next = dbUri;
- dbUri = calipso.config.get('database:uri');
+ // If first option is callback, set dbType to config value
+ if (typeof dbType === "function") {
+ next = dbType;
+ dbType = 'memory';
checkInstalling = false;
}
// Check we are installing ...
if (checkInstalling) {
- var db = mongoose.createConnection(dbUri, function(err) {
+ try {
+ var db = new jugglingdb.Schema(dbType, config);
+ db.on('connected', function () {
+ next(null, true);
+ })
+ }
+ catch(err) {
next(err, false);
- });
+ }
return;
}
if (isInstalled) {
- // Always disconnect first just in case any left overs from installation
- mongoose.disconnect(function() {
-
- // TODO - what the hell is going on with mongoose?
- calipso.db = mongoose.createConnection(dbUri, function(err) {
-
- if (err) {
-
- calipso.error("Unable to connect to the specified database ".red + dbUri + ", the problem was: ".red + err.message);
- mongoose.disconnect(function() {
- return next(err, false);
- });
-
- } else {
-
- calipso.silly("Database connection to " + dbUri + " was successful.");
-
- // Replace the inmemory session with mongodb backed one
- var foundMiddleware = false, mw;
-
- calipso.app.stack.forEach(function(middleware, key) {
- if (middleware.handle.tag === 'session') {
- foundMiddleware = true;
- var maxAge = calipso.config.get('session:maxAge');
- if (maxAge) {
- try {
- maxAge = Number(maxAge) * 1000;
- }
- catch (e) {
- calipso.error('MaxAge value ' + maxAge + ' is not a numeric string');
- maxAge = undefined;
- }
+ try {
+ calipso.db = new jugglingdb.Schema(dbType, config);
+ // To maintain compatibility
+ calipso.db.model = function (model) {
+ return calipso.db.models[model];
+ }
+ }
+ catch(err) {
+ calipso.error("Unable to connect to the specified database ".red + dbType + ", the problem was: ".red + err.message);
+ next(err, false);
+ return;
+ }
+ calipso.db.on('connected',function () {
+
+ calipso.silly("Database connection to " + dbType + " was successful.");
+
+ // Replace the inmemory session with database backed one
+ var foundMiddleware = false, mw;
+
+ calipso.app.stack.forEach(function(middleware, key) {
+ if (middleware.handle.tag === 'session') {
+ foundMiddleware = true;
+
+ var maxAge = calipso.config.get('session:maxAge');
+ if (maxAge) {
+ try {
+ maxAge = Number(maxAge) * 1000;
+ }
+ catch (e) {
+ calipso.error('MaxAge value ' + maxAge + ' is not a numeric string');
+ maxAge = undefined;
}
+ }
+
+ var store = new SessionStorage(dbType, config);
+ store.db.on('connected', function() {
mw = calipso.lib.express.session({
secret: calipso.config.get('session:secret'),
- store: calipso.app.sessionStore = new mongoStore({
- db: calipso.db.db
- }),
- cookie: { maxAge: maxAge }
+ store: store,
+ cookie: {maxAge: maxAge}
});
mw.tag = 'session';
calipso.app.stack[key].handle = mw;
- }
- });
-
- if (!foundMiddleware) {
- return next(new Error("Unable to load the MongoDB backed session, please check your session and db configuration"), false);
+ });
}
+ });
- return next(null, true);
-
+ if (!foundMiddleware) {
+ return next(new Error("Unable to load the Database backed session, please check your session and db configuration"), false);
}
+
+ return next(null, true);
+
});
- });
+
} else {
- calipso.silly("Database connection not attempted to " + dbUri + " as in installation mode.");
+ calipso.silly("Database connection not attempted to " + dbType + " as in installation mode.");
// Create a dummy connection to enable models to be defined
- calipso.db = mongoose.createConnection('');
+ calipso.db = new jugglingdb.Schema('memory');
next(null, false);
View
3  lib/core/Table.js
@@ -147,7 +147,8 @@ function getHeaderClass(table, column) {
}
/**
- * Convert a sortBy parameter into mongo sort queries
+ * Convert a sortBy parameter into db sort queries
+ * TODO: convert to JugglingDB
*/
CalipsoTable.prototype.sortQuery = function(qry, sortBy) {
View
2  lib/core/Utils.js
@@ -64,7 +64,7 @@ module.exports = {
var fields = _.keys(schema.paths);
_.each(fields, function(key) {
- if (key !== '_id') copy.set(key, object.get(key));
+ if (key !== 'id') copy.set(key, object.get(key));
});
},
View
78 modules/core/admin/admin.js
@@ -117,7 +117,7 @@ function init(module, app, next) {
// Default installation routers - only accessible in install mode
module.router.addRoute('GET /admin/install', install, null, this.parallel());
module.router.addRoute('POST /admin/install', install, null, this.parallel());
- module.router.addRoute('POST /admin/installTest/mongo', installMongoTest, null, this.parallel());
+ module.router.addRoute('POST /admin/installTest/db', installDbTest, null, this.parallel());
module.router.addRoute('POST /admin/installTest/user', installUserTest, null, this.parallel());
}, function done() {
@@ -232,8 +232,8 @@ function install(req, res, template, block, next) {
case "welcome":
installWelcome(req,res,localNext);
break;
- case "mongodb":
- installMongo(req,res,localNext);
+ case "db":
+ installDb(req,res,localNext);
break;
case "user":
installUser(req,res,localNext);
@@ -288,38 +288,47 @@ function installWelcome(req,res,next) {
}
/**
- * Installation mongodb - called by install router, not a routing function.
+ * Installation db - called by install router, not a routing function.
*/
-function installMongo(req,res,next) {
+function installDb(req,res,next) {
// Manually grab the template
- var template = calipso.modules.admin.templates.install_mongo;
+ var template = calipso.modules.admin.templates.install_db;
// Create the form
- var mongoForm = {id:'install-mongo-form',title:'',type:'form',method:'POST',action:'/admin/install',
+ var dbForm = {id:'install-db-form',title:'',type:'form',method:'POST',action:'/admin/install',
fields:[
- {label:'MongoDB URI',name:'database:uri',cls:'database-uri', type:'text',description:'Enter the database URI, in the form: mongodb://servername:port/database'},
+ {label:'Type', name:'database:type',cls:'database-type', type:'select', options:['mongodb','mongoose','postgres','mysql','riak','redis','couchdb','memory']}, // TODO : Select based on available
+ {label:'Host',name:'database:configuration:host',cls:'database-host', type:'text',description:'Enter the database hostname'},
+ {label:'Port',name:'database:configuration:port',cls:'database-port', type:'text',description:'Enter the database port'},
+ {label:'Username',name:'database:configuration:user',cls:'database-user', type:'text',description:'Enter the database username'},
+ {label:'Password',name:'database:configuration:password',cls:'database-password', type:'password',description:'Enter the database password'},
+ {label:'Database',name:'database:configuration:database',cls:'database-database', type:'text',description:'Enter the database name'},
{label:'',name:'installStep',type:'hidden'}
],
buttons:[]}; // Submitted via template
var formValues = {
database: {
- uri: calipso.config.get('database:uri')
+ type: calipso.config.get('database:type'),
+ host: calipso.config.get('database:configuration:host'),
+ port: calipso.config.get('database:configuration:port'),
+ user: calipso.config.get('database:configuration:user'),
+ password: calipso.config.get('database:configuration:password'),
+ database: calipso.config.get('database:configuration:database')
},
'installStep':'user'
}
- calipso.form.render(mongoForm, formValues, req, function(form) {
- calipso.theme.renderItem(req, res, template, 'admin.install.mongo', {form:form}, next);
+ calipso.form.render(dbForm, formValues, req, function(form) {
+ calipso.theme.renderItem(req, res, template, 'admin.install.db', {form:form}, next);
});
-
}
/**
- * Function to enable ajax testing of the mongo configuration
+ * Function to enable ajax testing of the db configuration
*/
-function installMongoTest(req, res, template, block, next) {
+function installDbTest(req, res, template, block, next) {
if (calipso.config.get('installed')) {
res.format = "json";
@@ -327,27 +336,22 @@ function installMongoTest(req, res, template, block, next) {
}
calipso.form.process(req,function(form) {
-
- var dbUri = form.dbUri;
+
+ var dbType = form.type;
+ var config = form;
+ delete config.type;
var output = {};
- if(dbUri) {
- calipso.storage.mongoConnect(dbUri,true,function(err,connected) {
- if(!err) {
- output.status = "OK";
- } else {
- output.status = "FAILED";
- output.message= "Failed to connect to MongoDB because: " + err.message;
- }
- res.format = "json";
- res.end(JSON.stringify(output),"UTF-8");
- });
- } else {
- output.status = "FAILED";
- output.message= "You need to provide a valid database uri, in the format described.";
+ calipso.storage.connect(dbType,config,true,function(err,connected) {
+ if(!err) {
+ output.status = "OK";
+ } else {
+ output.status = "FAILED";
+ output.message= "Failed to connect to database because: " + err.message;
+ }
res.format = "json";
res.end(JSON.stringify(output),"UTF-8");
- }
+ });
});
}
@@ -392,7 +396,7 @@ function installUser(req,res,next) {
}
/**
- * Function to enable ajax testing of the mongo configuration
+ * Function to enable ajax testing of the db configuration
*/
function installUserTest(req, res, template, block, next) {
@@ -497,7 +501,7 @@ function doInstallation(req, res, next) {
// Set the install flag to true, enable db connection
calipso.config.set('installed',true);
- calipso.storage.mongoConnect(function(err) {
+ calipso.storage.connect(function(err) {
if(err) {
return next(err);
@@ -532,7 +536,13 @@ function doInstallation(req, res, next) {
modulesToInstall.forEach(function(module){
calipso.info("Installing module " + module);
- calipso.modules[module].fn.install(group());
+ try {
+ calipso.modules[module].fn.install(group());
+ }
+ catch (err) {
+ calipso.error("Module '"+module+ "' was unable to be installed... Reason: "+err.message);
+ }
+
});
},
View
26 ...s/core/admin/templates/install_mongo.html → modules/core/admin/templates/install_db.html
@@ -23,13 +23,13 @@
</div>
<div class="admin-body">
- <h2><%= t("Step 1: Configure MongoDB") %></h2>
+ <h2><%= t("Step 1: Configure Database") %></h2>
- <div id="mongo-status" style="display: none;">
+ <div id="db-status" style="display: none;">
</div>
- <p>To store content, we need to connect to MongoDB. Please provide the location of your database here:
+ <p>To store content, we need to connect to a database:
<%- form %>
<footer class="admin-install-links">
@@ -45,27 +45,27 @@
if(window.jQuery){
- // Ajax request to /admin/install/mongo/test
- function checkMongo() {
+ // Ajax request to /admin/install/db/test
+ function checkDb() {
- $('#mongo-status').show();
- $('.submit').html("Connecting to MongoDB ...").addClass("loading");
+ $('#db-status').show();
+ $('.submit').html("Connecting to Database ...").addClass("loading");
- var dbUri = $(".database-uri").val();
- var postData = {"dbUri":dbUri};
+ var type = $(".database-type").val();
+ var postData = {"type":type};
$.ajax({
type: "POST",
- url: "/admin/installTest/mongo",
+ url: "/admin/installTest/db",
dataType:"json",
data:postData,
success: function(res){
if(res.status === "OK") {
setTimeout(function() {
- $('#install-mongo-form').submit();
+ $('#install-db-form').submit();
}, 1500);
} else {
- $('#mongo-status').html("<div class='error'>MongoDB connection failed, please check the details and try again.</div>");
+ $('#db-status').html("<div class='error'>Database connection failed, please check the details and try again.</div>");
$('.submit').html("Create Database").addClass("loading");
}
}
@@ -74,7 +74,7 @@
$('#form-submit').click(function(event) {
event.preventDefault();
- checkMongo();
+ checkDb();
});
} else {
View
4 modules/core/admin/templates/install_user.html
@@ -33,7 +33,7 @@
<%- form %>
<footer class="admin-install-links">
- <a class="button back" href="?installStep=mongodb"><%= t("Change Database") %></a>
+ <a class="button back" href="?installStep=db"><%= t("Change Database") %></a>
<a id="form-submit" class="button next" href="#"><%= t("Create Admin") %></a>
</footer>
@@ -45,7 +45,7 @@
if(window.jQuery){
- // Ajax request to /admin/install/mongo/test
+ // Ajax request to /admin/install/user/test
function checkUser() {
$('#user-status').show();
View
2  modules/core/admin/templates/install_welcome.html
@@ -15,7 +15,7 @@
</ol>
<footer class="admin-install-links">
- <a class="step_1 button next" href="?installStep=mongodb"><%= t("Let's Begin") %></a>
+ <a class="step_1 button next" href="?installStep=db"><%= t("Let's Begin") %></a>
</footer>
</div>
View
88 modules/core/content/content.js
@@ -6,7 +6,6 @@
var rootpath = process.cwd() + '/',
path = require('path'),
calipso = require(path.join(rootpath, 'lib/calipso')),
- Query = require("mongoose").Query,
utils = require('connect').utils,
merge = utils.merge;
@@ -91,32 +90,30 @@ function init(module,app,next) {
calipso.helpers.addHelper('getContentList', function() { return getContentList; });
// Default Content Schema
- var Content = new calipso.lib.mongoose.Schema({
- title:{type: String, required: true, "default": ''},
- teaser:{type: String, required: false, "default": ''},
- taxonomy:{type: String, "default":''},
- content:{type: String, required: false, "default":''},
- status:{type: String, required: false, "default":'draft', index: true},
- alias:{type: String, required: true, index: true},
- author:{type: String, required: true},
- etag:{type: String, "default":''},
- tags:[String],
- published: { type: Date },
- scheduled: { type: Date },
- created: { type: Date, "default": Date.now },
- updated: { type: Date, "default": Date.now },
- contentType:{type: String}, // Copy from content type
- layout:{type: String}, // Copy from content type
- ispublic:{type: Boolean, index: true} // Copy from content type
+ var Content = calipso.db.define('Content', {
+ title: {type: String, required: true, "default": ''},
+ teaser: {type: String, required: false, "default": ''},
+ taxonomy: {type: String, "default":''},
+ content: {type: String, required: false, "default":''},
+ status: {type: String, required: false, "default":'draft', index: true},
+ alias: {type: String, required: true, index: true},
+ author: {type: String, required: true},
+ etag: {type: String, "default":''},
+ tags: {type: Array},
+ published: { type: Date },
+ scheduled: { type: Date },
+ created: { type: Date, "default": Date.now },
+ updated: { type: Date, "default": Date.now },
+ contentType: {type: String}, // Copy from content type
+ layout: {type: String}, // Copy from content type
+ ispublic: {type: Boolean, index: true} // Copy from content type
});
// Set post hook to enable simple etag generation
- Content.pre('save', function (next) {
+ Content.beforeSave = function (next) {
this.etag = calipso.lib.crypto.etag(this.title + this.teaser + this.content);
next();
- });
-
- calipso.db.model('Content', Content);
+ };
next();
@@ -154,7 +151,7 @@ function getContent(req, options, next) {
var Content = calipso.db.model('Content');
- Content.findOne({alias:options.alias},function (err, c) {
+ Content.findOne({where:{alias:options.alias}},function (err, c) {
if(err || !c) {
@@ -178,9 +175,9 @@ function getContent(req, options, next) {
if(options.property) {
- var text = c.get(options.property) || req.t("Invalid content property: {property}",{property:options.property});
+ var text = c[options.property] || req.t("Invalid content property: {property}",{property:options.property});
if(options.clickEdit && req.session && req.session.user && req.session.user.isAdmin) {
- text = "<span title='" + req.t("Double click to edit content block ...") + "' class='content-block' id='" + c._id + "'>" +
+ text = "<span title='" + req.t("Double click to edit content block ...") + "' class='content-block' id='" + c.id + "'>" +
text + "</span>";
}
@@ -270,7 +267,7 @@ function createContent(req,res,template,block,next) {
var returnTo = form.returnTo ? form.returnTo : "";
// Get content type
- ContentType.findOne({contentType:form.content.contentType}, function(err, contentType) {
+ ContentType.findOne({where:{contentType:form.content.contentType}}, function(err, contentType) {
if(err || !contentType) {
@@ -311,7 +308,7 @@ function createContent(req,res,template,block,next) {
if(returnTo) {
res.redirect(returnTo);
} else {
- res.redirect('/content/show/' + c._id);
+ res.redirect('/content/show/' + c.id);
}
next();
});
@@ -361,10 +358,10 @@ function getForm(req,action,title,contentType,next) {
// Get content type
var ContentType = calipso.db.model('ContentType');
- ContentType.findOne({contentType:contentType}, function(err, ct) {
+ ContentType.findOne({where:{contentType:contentType}}, function(err, ct) {
// Add any fields
- if(!err && ct && ct.get("fields")) { // FIX as this added later, get is 'safer' if not existing in document
+ if(!err && ct && ct["fields"]) { // FIX as this added later, get is 'safer' if not existing in document
var fields = [];
@@ -507,7 +504,7 @@ function editContentForm(req,res,template,block,next) {
res.menu.adminToolbar.addMenuItem(req, {name:'Delete',weight:4,path:'delete',url:'/content/delete/' + id,description:'Delete content ...',permit:dPerm});
- Content.findById(id, function(err, c) {
+ Content.find(id, function(err, c) {
if(err || c === null) {
@@ -560,7 +557,7 @@ function updateContent(req,res,template,block,next) {
var returnTo = form.returnTo ? form.returnTo : "";
var id = req.moduleParams.id;
- Content.findById(id, function(err, c) {
+ Content.find(id, function(err, c) {
if (c) {
// Default mapper
@@ -572,7 +569,7 @@ function updateContent(req,res,template,block,next) {
c.tags = form.content.tags ? form.content.tags.replace(/[\s]+/g, "").split(",") : [];
// Get content type
- ContentType.findOne({contentType:form.content.contentType}, function(err, contentType) {
+ ContentType.findOne({where:{contentType:form.content.contentType}}, function(err, contentType) {
if(err || !contentType) {
req.flash('error',req.t('Could not save content as I was unable to locate content type {type}.',{type:form.content.contentType}));
@@ -658,7 +655,7 @@ function showAliasedContent(req, res, template, block, next) {
var Content = calipso.db.model('Content');
- Content.findOne({alias:alias},function (err, content) {
+ Content.findOne({where:{alias:alias}},function (err, content) {
if(err || !content) {
// Create content if it doesn't exist
@@ -676,7 +673,7 @@ function showAliasedContent(req, res, template, block, next) {
next(err);
} else {
// Add the user display details to content
- content.set('displayAuthor',userDetails);
+ content.displayAuthor = userDetails;
showContent(req,res,template,block,next,err,content,format);
}
});
@@ -703,7 +700,8 @@ function showContentByID(req,res,template,block,next) {
var id = req.moduleParams.id;
var format = req.moduleParams.format ? req.moduleParams.format : 'html';
- Content.findById(id, function(err, content) {
+ Content.find(id, function(err, content) {
+
// Error locating content
if(err) {
res.statusCode = 500;
@@ -719,7 +717,7 @@ function showContentByID(req,res,template,block,next) {
next(err);
} else {
// Add the user display details to content
- content.set('displayAuthor',userDetails);
+ content.displayAuthor = userDetails;
showContent(req,res,template,block,next,err,content,format);
}
@@ -807,18 +805,18 @@ function listContent(req,res,template,block,next) {
var t3 = req.moduleParams.t3 ? req.moduleParams.t3 : '';
var t4 = req.moduleParams.t4 ? req.moduleParams.t4 : '';
- var query = new Query();
+ var query = {where:{}};
if(req.session && req.session.user && vPerm(req.session.user)) {
// Show all
} else {
// Published only if not admin
- query.where('status','published');
+ query.where.status = 'published';
}
if(tag) {
res.layout = "tagLanding" // Enable landing page layout to be created for a tag view
- query.where('tags',tag);
+ query.where.tags = tag;
}
// Taxonomy tags
@@ -838,7 +836,7 @@ function listContent(req,res,template,block,next) {
}
if(taxonomy) {
- query.where('taxonomy',new RegExp(taxonomy));
+ query.where.taxonomy = new RegExp(taxonomy);
}
// Get the content list
@@ -851,7 +849,7 @@ function listContent(req,res,template,block,next) {
* Helper function for link to user
*/
function contentLink(req, content) {
- return calipso.link.render({id:content._id,title:req.t('View {content}',{content:content.title}),label:content.title,url:'/content/show/' + content._id});
+ return calipso.link.render({id:content.id,title:req.t('View {content}',{content:content.title}),label:content.title,url:'/content/show/' + content.id});
}
/**
@@ -884,12 +882,10 @@ function getContentList(query,out,next) {
pagerHtml = calipso.lib.pager.render(from,limit,total,out.req.url);
}
- var qry = Content.find(query).skip(from).limit(limit);
-
// Add sort
// qry = calipso.table.sortQuery(qry, out.sortBy);
- qry.find(function (err, contents) {
+ var qry = Content.all({skip:from,limit:limit}, function (err, contents) {
if(out && out.res) {
@@ -947,12 +943,12 @@ function deleteContent(req,res,template,block,next) {
var Content = calipso.db.model('Content');
var id = req.moduleParams.id;
- Content.findById(id, function(err, c) {
+ Content.find(id, function(err, c) {
// Raise CONTENT_CREATE event
calipso.e.pre_emit('CONTENT_DELETE',c);
- Content.remove({_id:id}, function(err) {
+ c.destroy(function(err) {
if(err) {
req.flash('info',req.t('Unable to delete the content because {msg}',{msg:err.message}));
res.redirect("/");
View
2  modules/core/content/templates/listAdmin.html
@@ -8,7 +8,7 @@
</tr>
<% contents.forEach(function(item) { %>
<tr class='content-list-item content-list-item-<%- item.status %> content-type-<%- item.contentType %>'>
- <td><a href='/content/show/<%= item._id %>'><%- item.title %></a></td>
+ <td><a href='/content/show/<%= item.id %>'><%- item.title %></a></td>
<td><%- item.contentType %></td>
<td><%- item.author %></td>
<td><%- prettyDate(item.published) %></td>
View
21 modules/core/contentTypes/contentTypes.js
@@ -6,8 +6,7 @@
var rootpath = process.cwd() + '/',
path = require('path'),
- calipso = require(path.join(rootpath, 'lib/calipso')),
- Query = require("mongoose").Query;
+ calipso = require(path.join(rootpath, 'lib/calipso'));
/**
* Define the routes that this module will repsond to.
@@ -76,7 +75,7 @@ function init(module,app,next) {
calipso.permission.Helper.addPermission("admin:content:type","Content Types",true);
// Schemea
- var ContentType = new calipso.lib.mongoose.Schema({
+ var ContentType = calipso.db.define('ContentType', {
contentType:{type: String, required: true, unique: true, "default": 'default', index: true},
description:{type: String, required: true, "default": 'Default Content Type'},
layout:{type: String, required: true, "default": 'default'},
@@ -89,8 +88,6 @@ function init(module,app,next) {
listTemplate:{type: String, "default": ''},
});
- calipso.db.model('ContentType', ContentType);
-
// Cache the content types in the calipso.data object
if(app.config.get('installed')) {
storeContentTypes(null,null,function(){});
@@ -340,7 +337,7 @@ function showContentType(req,res,template,block,next) {
res.menu.adminToolbar.addMenuItem(req, {name:'Edit',path:'edit',url:'/content/type/edit/' + id,description:'Edit content type ...',permit:calipso.permission.Helper.hasPermission("admin:content:type:edit")});
res.menu.adminToolbar.addMenuItem(req, {name:'Delete',path:'delete',url:'/content/type/delete/' + id,description:'Delete content type ...',permit:calipso.permission.Helper.hasPermission("admin:content:type:delete")});
- item = {id:content._id,type:'content',meta:content.toObject()};
+ item = {id:content.id,type:'content',meta:content.toObject()};
}
@@ -384,16 +381,12 @@ function listContentType(req,res,template,block,next) {
var format = req.moduleParams.format || 'html';
- var query = new Query();
-
// Initialise the block based on our content
- ContentType.count(query, function (err, count) {
+ ContentType.count({}, function (err, count) {
var total = count;
- ContentType.find(query)
- .sort('contentType', 1)
- .find(function (err, contents) {
+ ContentType.all({sort:'contentType'}, function (err, contents) {
// Render the item into the response
if(format === 'html') {
@@ -428,7 +421,7 @@ function deleteContentType(req,res,template,block,next) {
calipso.e.pre_emit('CONTENT_TYPE_DELETE',c);
- ContentType.remove({_id:id}, function(err) {
+ c.destroy(function(err) {
if(err) {
req.flash('info',req.t('Unable to delete the content type because {msg}.',{msg:err.message}));
res.redirect("/content/type");
@@ -491,7 +484,7 @@ function storeContentTypes(event,contentType,next) {
delete calipso.data.contentTypes;
calipso.data.contentTypes = [];
- ContentType.find({}).sort('contentType',1).find(function (err, types) {
+ ContentType.all({order: 'contentType'}, function (err, types) {
if(err || !types) {
// Don't throw error, just pass back failure.
View
2  modules/core/contentTypes/templates/list.html
@@ -9,7 +9,7 @@
items.forEach(function(item) {
%>
<tr>
- <td><a href='/content/type/show/<%- item._id %>'><%- item.contentType %></a></td>
+ <td><a href='/content/type/show/<%- item.id %>'><%- item.contentType %></a></td>
<td> <%- item.description %></td>
<td> <%- item.layout %></td>
<td> <%- item.ispublic ? "Yes" : "No" %></td>
View
33 modules/core/contentVersions/contentVersions.js
@@ -7,7 +7,6 @@
var rootpath = process.cwd() + '/',
path = require('path'),
calipso = require(path.join(rootpath, 'lib/calipso')),
- Query = require('mongoose').Query,
diff = require('./support/jsdiff');
exports = module.exports = {
@@ -69,13 +68,11 @@ function init(module,app,next) {
function done() {
// Schema
- var ContentVersion = new calipso.lib.mongoose.Schema({
+ var ContentVersion = new calipso.db.define('ContentVersion', {
contentId:{type: String}
// All other properties are dynamically mapped, hence use of .set / .get
});
- calipso.db.model('ContentVersion', ContentVersion);
-
// Version event listeners
calipso.e.post('CONTENT_CREATE', module.name, saveVersion);
calipso.e.post('CONTENT_UPDATE', module.name, saveVersion);
@@ -131,10 +128,10 @@ function saveVersion(event, content, next) {
// Create version and map fields
var version = new ContentVersion();
- calipso.utils.copyMongoObject(content, version, content.schema);
- version.contentId = content._id;
+ calipso.utils.copyDbObject(content, version, content.schema);
+ version.contentId = content.id;
- if(version.get("version")) {
+ if(version.version) {
calipso.e.pre_emit('CONTENT_VERSION', version);
}
@@ -172,7 +169,7 @@ function showVersion(req,res,template,block,next) {
res.menu.adminToolbar.addMenuItem(req, {name:'Return',path:'return',permit:vPerm,url:'/content/show/' + contentId + '/versions',description:'Show content ...',security:[]});
res.menu.adminToolbar.addMenuItem(req, {name:'Revert',path:'revert',permit:rPerm,url:'/content/show/' + contentId + '/version/' + id + '/revert',description:'Revert to this version of content ...',security:[]});
- ContentVersion.findById(id,function(err,version) {
+ ContentVersion.find(id,function(err,version) {
if(err && !version) {
calipso.err(err);
@@ -207,10 +204,10 @@ function diffVersion(req,res,template,block,next) {
var ContentVersion = calipso.db.model('ContentVersion');
- ContentVersion.findById(a,function(err,versionA) {
+ ContentVersion.find(a,function(err,versionA) {
if(!err && versionA) {
- ContentVersion.findById(b,function(err,versionB) {
+ ContentVersion.find(b,function(err,versionB) {
if(!err && versionB) {
// TODO : Use a proper HTML diff parser ... this only works for non-HTML
@@ -273,12 +270,10 @@ function listVersions(req,res,template,block,next) {
var format = req.moduleParams.format ? req.moduleParams.format : 'html';
- var query = new Query({contentId:id});
+ var query = new Query();
// Initialise the block based on our content
- ContentVersion.find(query)
- .sort('updated', -1)
- .find(function (err, versions) {
+ ContentVersion.find({where:{contentId:id}, sort:'updated'}, function (err, versions) {
// Render the item into the response
if(format === 'html') {
@@ -310,7 +305,7 @@ function revertVersion(req,res,template,block,next) {
var Content = calipso.db.model('Content');
var ContentVersion = calipso.db.model('ContentVersion');
- ContentVersion.findById(id,function(err,version) {
+ ContentVersion.find(id,function(err,version) {
if(err && !version) {
@@ -320,7 +315,7 @@ function revertVersion(req,res,template,block,next) {
}
// Copy over
- Content.findById(contentId,function(err, content) {
+ Content.find(contentId,function(err, content) {
if(err && !content) {
calipso.err(err)
@@ -328,12 +323,12 @@ function revertVersion(req,res,template,block,next) {
return;
}
- calipso.utils.copyMongoObject(version, content, content.schema);
+ calipso.utils.copyDbObject(version, content, content.schema);
content.author = req.session.user.username;
- content.set("comment",'Reverted to version: ' + content.updated);
+ content.comment = 'Reverted to version: ' + content.updated;
content.updated = new Date();
- content.set("version", 'Yes');
+ content.version = 'Yes';
content.save(function(err) {
res.redirect('/content/show/' + contentId);
View
10 modules/core/contentVersions/templates/list.html
@@ -35,7 +35,7 @@
versions.forEach(function(item) {
%>
<tr class='content-list-item'>
- <td><a href='/content/show/<%= item.contentId %>/version/<%= item._id %>'><%- item.get('updated') %></a></td>
+ <td><a href='/content/show/<%= item.contentId %>/version/<%= item.id %>'><%- item.get('updated') %></a></td>
<td><%- item.get('title') %></a></td>
<td><%- item.get('status') %></a></td>
<td><%- item.get('author') %></td>
@@ -43,16 +43,16 @@
<td><%- item.get('comment') %></td>
<td>
<% if(counter === 0) { %>
- <input class="diff-select" type="radio" value="<%- item._id %>" name="a" checked></input></td>
+ <input class="diff-select" type="radio" value="<%- item.id %>" name="a" checked></input></td>
<% } else { %>
- <input class="diff-select" type="radio" value="<%- item._id %>" name="a"></input></td>
+ <input class="diff-select" type="radio" value="<%- item.id %>" name="a"></input></td>
<% } %>
<td>
<% if(counter === 1) { %>
- <input class="diff-select" type="radio" value="<%- item._id %>" name="b" checked></input>
+ <input class="diff-select" type="radio" value="<%- item.id %>" name="b" checked></input>
<% }
if(counter > 1) { %>
- <input class="diff-select" type="radio" value="<%- item._id %>" name="b"></input>
+ <input class="diff-select" type="radio" value="<%- item.id %>" name="b"></input>
<% }
%></td>
</tr>
View
4 modules/core/contentVersions/templates/show.html
@@ -1,6 +1,6 @@
<div class='content-version'>
- <h2>Version: <%- version._id %></h2>
- <p><a href='/content/show/<%= version.get("contentId") %>/version/<%= version._id %>'><%- version.get("title") %></a></p>
+ <h2>Version: <%- version.id %></h2>
+ <p><a href='/content/show/<%= version.get("contentId") %>/version/<%= version.id %>'><%- version.get("title") %></a></p>
<p class='by'>By <a href='/user/profile/<%- version.get("author") %>'><%- version.get("author") %></a></small>
<p class='status'><%- version.get("status") %></p>
<p class='created'><%- version.get("created") %>
View
14 modules/core/permissions/permissions.js
@@ -3,8 +3,7 @@
*/
var rootpath = process.cwd() + '/',
path = require('path'),
- calipso = require(path.join(rootpath, 'lib/calipso')),
- Query = require("mongoose").Query;
+ calipso = require(path.join(rootpath, 'lib/calipso'));
/**
* Routes this module will respond to
@@ -53,11 +52,10 @@ function init(module, app, next) {
calipso.permission.Helper.addPermission("admin:permission:configuration","Manage role based permissions.");
- var PermissionRole = new calipso.lib.mongoose.Schema({
+ var PermissionRole = calipso.db.define('PermissionRole', {
permission:{type: String, required: true},
role:{type: String, required: true}
});
- calipso.db.model('PermissionRole', PermissionRole);
loadPermissionRoles(function(err) {
next(err);
@@ -78,7 +76,7 @@ function loadPermissionRoles(next) {
perm.clearPermissionRoles();
// Load the permissions
- PermissionRole.find({}).sort('permission',1).sort('role',1).find(function (err, prs) {
+ PermissionRole.all({order: 'permission'}, function (err, prs) {
prs.forEach(function(pr) {
perm.addPermissionRole(pr.permission, pr.role);
@@ -101,7 +99,7 @@ function showPermissions(req, res, options, next) {
Role = calipso.db.model('Role'),
PermissionRole = calipso.db.model('PermissionRole');
- Role.find({}).sort('name',1).find(function (err, roles) {
+ Role.all({sort:'name'}, function (err, roles) {
var output = renderPermissionTable(structuredPermissions, roles);
calipso.theme.renderItem(req, res, options.templateFn, options.block, {output: output}, next);
});
@@ -192,11 +190,11 @@ function updatePermissions(req, res, options, next) {
// Delete all the existing permissions
- PermissionRole.find({}).find(function (err, prs) {
+ PermissionRole.all({}, function (err, prs) {
// Delete all
calipso.lib.async.map(prs, function(permission, next) {
- PermissionRole.remove({_id: permission._id}, function(err) {
+ permission.destroy(function(err) {
next(err);
})
}, function(err) {
View
34 modules/core/scheduler/scheduler.js
@@ -52,7 +52,7 @@ function init(module,app,next) {
function done() {
// Ensure we have the job schema defined
- var ScheduledJob = new calipso.lib.mongoose.Schema({
+ var ScheduledJob = calipso.db.define('ScheduledJob', {
name:{type: String, required: true, unique: true},
cronTime:{type: String, "default":'* * * * * *',required: true},
enabled:{type: Boolean, "default":false, required: true},
@@ -60,7 +60,6 @@ function init(module,app,next) {
method:{type: String, "default":'', required: true},
args:{type: String, "default":'', required: false}
});
- calipso.db.model('ScheduledJob', ScheduledJob);
// Load the exposed job functions into a job function array
// This scans all the other modules
@@ -93,7 +92,7 @@ function loadJobs(next) {
// Create a holder for our jobs - DOES THIS STOP EVERYTHING ELSE??!
calipso.jobs = {};
- ScheduledJob.find({}, function(err, jobs) {
+ ScheduledJob.all({}, function(err, jobs) {
jobs.forEach(function(job) {
@@ -186,7 +185,7 @@ function enableScheduler(req,res,template,block,next) {
/**
* Admin interface to job list
- * This uses the currently loaded job list from the calipso cache, not the MongoDB list
+ * This uses the currently loaded job list from the calipso cache, not the Database list
* If any external processes are creating jobs they will not appear without the module
* being reloaded
*/
@@ -297,7 +296,7 @@ function createJob(req,res,template,block,next) {
}
/**
- * Process form variables and convert to form suitable for storing against mongoose object
+ * Process form variables and convert to form suitable for storing against database object
* Extracted out due to the common conversion of crontime form elements to cron time field
*/
function processForm(formObject) {
@@ -355,7 +354,7 @@ function editJobForm(req,res,template,block,next) {
res.menu.adminToolbar.addMenuItem(req, {name:'Delete',path:'delete',url:'/scheduler/delete/' + jobName,description:'Delete schedule ...',security:[]});
- ScheduledJob.findOne({name:jobName}, function(err, job) {
+ ScheduledJob.findOne({where:{name:jobName}}, function(err, job) {
if(err || job === null) {
@@ -400,7 +399,7 @@ function updateJob(req,res,template,block,next) {
var ScheduledJob = calipso.db.model('ScheduledJob');
var jobName = req.moduleParams.jobName;
- ScheduledJob.findOne({name:jobName}, function(err, job) {
+ ScheduledJob.findOne({where:{name:jobName}}, function(err, job) {
if(err) {
calipso.error(err);
@@ -484,14 +483,14 @@ function showJob(req,res,template,block,next,err) {
res.menu.adminToolbar.addMenuItem(req, {name:'Delete',path:'delete',url:'/scheduler/delete/' + jobName,description:'Delete schedule ...',security:[]});
- ScheduledJob.findOne({name:jobName}, function(err, job) {
+ ScheduledJob.findOne({where:{name:jobName}}, function(err, job) {
if(err || job === null) {
res.redirect("/scheduler");
next();
return;
} else {
- item = {id:job._id,type:'job',meta:job.toObject()};
+ item = {id:job.id,type:'job',meta:job.toObject()};
}
calipso.theme.renderItem(req,res,template,block,{item:item},next);
@@ -509,15 +508,22 @@ function deleteJob(req,res,template,block,next,err) {
var ScheduledJob = calipso.db.model('ScheduledJob');
var jobName = req.moduleParams.jobName;
- ScheduledJob.remove({name:jobName}, function(err) {
+ ScheduledJob.findOne({where:{name:jobName}}, function(err, job) {
if(err) {
req.flash('info',req.t('Unable to delete the job {job} because {msg}.', {job:jobName,msg:err.message}));
res.redirect("/scheduler");
} else {
- calipso.jobs[jobName].disable() // Disable it
- delete calipso.jobs[jobName]; // 'Delete' it - GC will get it later ???
- req.flash('info',req.t('Job {job} has now been deleted.',{job:jobName}));
- res.redirect("/scheduler");
+ job.destroy(function(err) {
+ if(err) {
+ req.flash('info',req.t('Unable to delete the job {job} because {msg}.', {job:jobName,msg:err.message}));
+ res.redirect("/scheduler");
+ } else {
+ calipso.jobs[jobName].disable() // Disable it
+ delete calipso.jobs[jobName]; // 'Delete' it - GC will get it later ???
+ req.flash('info',req.t('Job {job} has now been deleted.',{job:jobName}));
+ res.redirect("/scheduler");
+ }
+ })
}
next();
});
View
26 modules/core/tagcloud/tagcloud.js
@@ -33,14 +33,12 @@ function init(module,app,next) {
function done() {
// Define our tag clouds
- var Tag = new calipso.lib.mongoose.Schema({
+ var Tag = calipso.db.define('Tag', {
// Tag name is in _ID from MR
"_id":{type:String},
"value":{type: Number}
});
- calipso.db.model('Tag', Tag);
-
// Register for events
calipso.e.post('CONTENT_CREATE',module.name,mapReduceTagCloud);
calipso.e.post('CONTENT_UPDATE',module.name,mapReduceTagCloud);
@@ -92,18 +90,19 @@ function mapReduceTagCloud(event,options,next) {
out: 'tags' // what collection are we outputting to? mongo 1.7.4 + is different see http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions
};
- calipso.db.db.executeDbCommand(command, function(err, dbres)
- {
+ // Figure out with juggling
+ // calipso.db.db.executeDbCommand(command, function(err, dbres)
+ // {
- // Reset
- calipso.storage.mr.tagcloud = false;
- if (err) {
- // Do Something!!
- calipso.error(err);
- }
+ // // Reset
+ // calipso.storage.mr.tagcloud = false;
+ // if (err) {
+ // // Do Something!!
+ // calipso.error(err);
+ // }
return next();
- });
+ //});
};
@@ -114,8 +113,7 @@ function tagCloud(req,res,template,block,next) {
var Tag = calipso.db.model('Tag');
- Tag.find({})
- .find(function (err, tags) {
+ Tag.all({}, function (err, tags) {
// Render the item into the response
calipso.theme.renderItem(req,res,template,block,{tags:tags},next);
View
25 modules/core/taxonomy/taxonomy.js
@@ -41,14 +41,12 @@ function init(module,app,next) {
function done() {
// Define our taxonomy
- var TaxonomyMenu = new calipso.lib.mongoose.Schema({
+ var TaxonomyMenu = calipso.db.define('TaxonomyMenu', {
// Tag name is in _ID from MR
"_id":{type:String},
"value":{type: Number}
});
- calipso.db.model('TaxonomyMenu', TaxonomyMenu);
-
// Register for events
calipso.e.post('CONTENT_CREATE',module.name,mapReduceTaxonomy);
calipso.e.post('CONTENT_UPDATE',module.name,mapReduceTaxonomy);
@@ -111,16 +109,17 @@ function mapReduceTaxonomy(event, options, next) {
out: 'taxonomymenus' // what collection are we outputting to? mongo 1.7.4 + is different see http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions
};
- calipso.db.db.executeDbCommand(command, function(err, dbres)
- {
- // Reset
- calipso.storage.mr.taxonomy = false;
- if (err) {
- // Do Something!!
- calipso.error(err);
- }
+ // Figure out with juggling
+ // calipso.db.db.executeDbCommand(command, function(err, dbres)
+ // {
+ // // Reset
+ // calipso.storage.mr.taxonomy = false;
+ // if (err) {
+ // // Do Something!!
+ // calipso.error(err);
+ // }
return next();
- });
+ //});
};
@@ -132,7 +131,7 @@ function taxonomy(req, res, template, block, next) {
// Generate the menu from the taxonomy
var TaxonomyMenu = calipso.db.model('TaxonomyMenu');
- TaxonomyMenu.find({},function (err, tax) {
+ TaxonomyMenu.all({},function (err, tax) {
// Render the item into the response
tax.forEach(function(item) {
//TODO: This needs to be improved!
View
2  modules/core/user/templates/role.list.html
@@ -9,7 +9,7 @@
items.forEach(function(item) {
%>
<tr>
- <td><a href='/user/role/show/<%- item._id %>'><%- item.name %></a></td>
+ <td><a href='/user/role/show/<%- item.id %>'><%- item.name %></a></td>
<td> <%- item.description %></td>
<td> <%- item.isAdmin ? "Yes" : "No" %></td>
<td> <%- item.isDefault ? "Yes" : "No" %></td>
View
52 modules/core/user/user.js
@@ -4,8 +4,7 @@
var rootpath = process.cwd() + '/',
path = require('path'),
calipso = require(path.join(rootpath, 'lib/calipso')),
- roles = require('./user.roles'),
- Query = require("mongoose").Query;
+ roles = require('./user.roles');
exports = module.exports = {
init: init,
@@ -76,7 +75,7 @@ function init(module, app, next) {
},
function done() {
- var User = new calipso.lib.mongoose.Schema({
+ var User = calipso.db.define('User', {
// Single default property
username:{type: String, required: true, unique:true},
fullname:{type: String, required: false},
@@ -87,12 +86,10 @@ function init(module, app, next) {
showEmail:{type: String, "default":'registered'},
about:{type: String},
language:{type: String, "default":'en'},
- roles:[String],
+ roles:{type: Array},
locked:{type: Boolean, "default":false}
});
- calipso.db.model('User', User);
-
// Initialise roles
roles.init(module, app, next);
@@ -141,7 +138,7 @@ function userDisplay(req, username, next) {
var User = calipso.db.model('User');
var responseData = {name:'',email:''};
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
if(err || !u) {
@@ -393,7 +390,7 @@ function updateUserForm(req, res, template, block, next) {
return;
}
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
// Allow admins to register other admins
if(req.session.user && req.session.user.isAdmin) {
@@ -436,7 +433,7 @@ function lockUser(req, res, template, block, next) {
var User = calipso.db.model('User');
var username = req.moduleParams.username;
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
if(err || !u) {
req.flash('error',req.t('There was an error unlocking that user account.'));
@@ -470,7 +467,7 @@ function unlockUser(req, res, template, block, next) {
var User = calipso.db.model('User');
var username = req.moduleParams.username;
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
if(err || !u) {
req.flash('error',req.t('There was an error unlocking that user account.'));
@@ -572,7 +569,7 @@ function updateUserProfile(req, res, template, block, next) {
var old_password = form.user.old_password;
delete form.user.old_password;
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
u.fullname = form.user.fullname;
u.username = uname || form.user.username;
@@ -687,12 +684,13 @@ function loginUser(req, res, template, block, next) {
var username = form.user.username;
var found = false;
- User.findOne({username:username},function (err, user) {
+ User.findOne({where:{username:username}},function (err, user) {
// Check if the user hash is ok, or if there is no hash (supports transition from password to hash)
// TO BE REMOVED In later version
if(user && calipso.lib.crypto.check(form.user.password,user.hash) || (user && user.hash === '')) {
- if(!user.locked) {
+ // JugglingDB type error. Need to get this fixed
+ if(!user.locked || user.locked == "false") {
found = true;
calipso.e.post_emit('USER_LOGIN',user);
createUserSession(req, res, user, function(err) {
@@ -710,6 +708,7 @@ function loginUser(req, res, template, block, next) {
return;
}
next();
+
return;
});
@@ -724,6 +723,7 @@ function loginUser(req, res, template, block, next) {
function isUserAdmin(user) {
// Set admin
var isAdmin = false;
+ if (!user.roles) return isAdmin;
user.roles.forEach(function(role) {
if(calipso.data.roles[role] && calipso.data.roles[role].isAdmin){
isAdmin = true;
@@ -740,7 +740,7 @@ function createUserSession(req, res, user, next) {
var isAdmin = isUserAdmin(user);
// Create session
- req.session.user = {username:user.username, isAdmin:isAdmin, id:user._id,language:user.language,roles:user.roles};
+ req.session.user = {username:user.username, isAdmin:isAdmin, id:user.id,language:user.language,roles:user.roles};
req.session.save(function(err) {
next(err);
});
@@ -757,7 +757,7 @@ function logoutUser(req, res, template, block, next) {
var User = calipso.db.model('User');
- User.findOne({username:req.session.user.username}, function(err, u) {
+ User.findOne({where:{username:req.session.user.username}}, function(err, u) {
req.session.user = null;
req.session.save(function(err) {
@@ -895,7 +895,7 @@ function userProfile(req, res, template, block, next) {
var User = calipso.db.model('User');
var username = req.moduleParams.username;
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
if(err || !u) {
req.flash('error',req.t('Could not locate user: {user}',{user:username}));
@@ -948,12 +948,12 @@ function deleteUser(req, res, template, block, next) {
var User = calipso.db.model('User');
var username = req.moduleParams.username;
- User.findOne({username:username}, function(err, u) {
+ User.findOne({where:{username:username}}, function(err, u) {
// Raise USER_DELETE event
calipso.e.pre_emit('USER_DELETE',u);
- User.remove({_id:u._id}, function(err) {
+ u.destroy(function(err) {
if(err) {
req.flash('info',req.t('Unable to delete the user because {msg}',{msg:err.message}));
res.redirect("/user/list");
@@ -974,7 +974,7 @@ function deleteUser(req, res, template, block, next) {
* Helper function for link to user
*/
function userLink(req,user) {
- return calipso.link.render({id:user._id,title:req.t('View {user}',{user:user.username}),label:user.username,url:'/user/profile/' + user.username});
+ return calipso.link.render({id:user.id,title:req.t('View {user}',{user:user.username}),label:user.username,url:'/user/profile/' + user.username});
}
function roleLink(req,role) {
@@ -998,19 +998,15 @@ function listUsers(req,res,template,block,next) {
var limit = req.moduleParams.limit ? parseInt(req.moduleParams.limit) : 5;
var sortBy = req.moduleParams.sortBy;
- var query = new Query();
-
// Initialise the block based on our content
- User.count(query, function (err, count) {
+ User.count({}, function (err, count) {
var total = count;
- var qry = User.find(query).skip(from).limit(limit);
-
// Add sort
- qry = calipso.table.sortQuery(qry,sortBy);
+ //qry = calipso.table.sortQuery(qry,sortBy);
- qry.find(function (err, users) {
+ var qry = User.all({limit:limit,skip:from}, function (err, users) {
// Render the item into the response
if(format === 'html') {
@@ -1018,7 +1014,7 @@ function listUsers(req,res,template,block,next) {
var table = {
id:'user-list',sort:true,cls:'table-admin',
columns:[
- {name:'_id',sort:'username',label:'User',fn:userLink},
+ {name:'id',sort:'username',label:'User',fn:userLink},
{name:'fullname',label:'Full Name'},
{name:'roles',label:'Roles',sortable:false},
{name:'email',label:'Email',fn:function(req,row) {
@@ -1130,7 +1126,7 @@ function listRoles(req,res,template,block,next) {
*/
function install(next) {
- // Create the default content types
+ // Create the default content users
var User = calipso.db.model('User');
calipso.lib.step(
View
24 modules/core/user/user.roles.js
@@ -4,7 +4,6 @@
*/
var rootpath = process.cwd() + '/',
path = require('path'),
- Query = require("mongoose").Query,
calipso = require(path.join(rootpath, 'lib/calipso'));
module.exports = {
@@ -52,13 +51,12 @@ function init(module, app, next) {
calipso.lib.async.map(routes, function(options, next) { module.router.addRoute(options, next) }, function(err, data) {
// Done adding routes
- var Role = new calipso.lib.mongoose.Schema({
+ var Role = calipso.db.define('Role', {
name:{type: String, required: true, unique:true},
description:{type: String,"default":''},
isAdmin:{type: Boolean, required: true, "default": false},
isDefault:{type: Boolean, required: true, "default": false}
});
- calipso.db.model('Role', Role);
// Load roles into calipso data
if(app.config.get('installed')) {
@@ -87,7 +85,7 @@ function storeRoles(event, data, next) {
calipso.data.roleArray = [];
calipso.data.roles = {};
- Role.find({}).sort('name',1).find(function (err, roles) {
+ Role.all({order: 'name'}, function (err, roles) {
if(err || !roles) {
// Don't throw error, just pass back failure.
@@ -197,7 +195,7 @@ function editRoleForm(req,res,template,block,next) {
res.menu.adminToolbar.addMenuItem(req, {name:'Edit',path:'edit',url:'/user/role/edit/' + id,description:'Edit role ...',permit:calipso.permission.Helper.hasPermission("admin:user:role:edit")});
res.menu.adminToolbar.addMenuItem(req, {name:'Delete',path:'delete',url:'/user/role/delete/' + id,description:'Delete role ...',permit:calipso.permission.Helper.hasPermission("admin:user:role:delete")});
- Role.findById(id, function(err, c) {
+ Role.find(id, function(err, c) {
if(err || c === null) {
@@ -235,7 +233,7 @@ function updateRole(req,res,template,block,next) {
var Role = calipso.db.model('Role');
var id = req.moduleParams.id;
- Role.findById(id, function(err, c) {
+ Role.find(id, function(err, c) {
if (!err && c) {
calipso.form.mapFields(form.role,c);
@@ -282,7 +280,7 @@ function showRole(req,res,template,block,next) {
var id = req.moduleParams.id;
format = req.moduleParams.format || 'html';
- Role.findById(id, function(err, role) {
+ Role.find(id, function(err, role) {
if(err || role === null) {
@@ -329,16 +327,12 @@ function listRole(req,res,template,block,next) {
var format = req.moduleParams.format || 'html';
- var query = new Query();
-
// Initialise the block based on our content
- Role.count(query, function (err, count) {
+ Role.count({}, function (err, count) {
var total = count;
- Role.find(query)
- .sort('role', 1)
- .find(function (err, roles) {
+ Role.all({sort:'role'}, function (err, roles) {
// Render the item into the response
if(format === 'html') {
@@ -369,11 +363,11 @@ function deleteRole(req,res,template,block,next) {
var Role = calipso.db.model('Role');
var id = req.moduleParams.id;
- Role.findById(id, function(err, c) {
+ Role.find(id, function(err, c) {
calipso.e.pre_emit('USER_ROLE_DELETE',c);
- Role.remove({_id:id}, function(err) {
+ c.destroy(function(err) {
if(err) {
req.flash('info',req.t('Unable to delete the role because {msg}.',{msg:err.message}));