1
0
mirror of /repos/Prototyper.git synced 2025-12-30 06:31:32 +01:00
Prototyper/lib/mongoData.js
2015-07-03 17:35:37 +02:00

203 lines
6.4 KiB
JavaScript

'use strict';
var ObjectID = require('mongodb').ObjectID;
var _ = require('underscore');
module.exports = function (config, db) {
// config.database.pk = '_id'
/*
* options:
* collection (mandatory)
* query (mandatory)
*/
function getMongoContent(options, callback) {
config.debug && config.debug('getMongoContent options', options);
if (!options.collection) {
return callback && callback(new Error('Data not found / missing collection'));
}
return db.collection(options.collection, function collection(err, col) {
if (err) {
config.error && config.error('ERR2 getMongoContent', err);
return callback && callback(err);
}
if (!options.query) {
return callback && callback(new Error('Data not found ' + options.collection + ' / missing query'), null, col);
}
if (options.query._id && !(options.query._id instanceof Object)) {
try {
options.query._id = new ObjectID.createFromHexString(options.query._id);
} catch (error) {
config.error && config.error('ERR3 getMongoContent', error);
return callback && callback(error);
}
}
return col.findOne(options.query, function foundOne(err, result) {
if (err) {
config.error && config.error('ERR4 getMongoContent', err);
return callback && callback(err);
}
if (!result) {
return callback && callback(new Error('Data not found ' + options.collection + '/' + JSON.stringify(options.query)), null, col);
}
return callback && callback(null, result, col);
});
});
}
/*
* options:
* collection (mandatory)
* query (mandatory)
* attribute (mandatory)
*/
function getMongoAttribute(options, callback) {
config.debug && config.debug('getMongoAttribute options', options);
return getMongoContent(options, function document(err, result, col) {
if (err) {
config.error && config.error('ERR1 getMongoAttribute', err);
return callback && callback(err);
}
if (!options.attribute) {
return callback && callback(new Error('Data not found / ' + options.collection + '/' + JSON.stringify(options.query) + ' missing attribute', null, col));
}
var attribute_options = null;
config.debug && config.debug('getMongoAttribute result', result);
if (result &&
result.hasOwnProperty(options.attribute) &&
result[options.attribute].guid) {
attribute_options = {
collection: options.collection,
query: {_id: result[options.attribute].guid}
};
config.debug && config.debug('getMongoAttribute attribute_options', attribute_options);
getMongoContent(attribute_options, function attribute(err, attribute_result, coll) {
if (err) {
config.error && config.error('ERR2 getMongoAttribute', err);
return callback && callback(err);
}
config.debug && config.debug('getMongoAttribute attribute_result', attribute_result);
return callback && callback(err, attribute_result, coll);
});
} else {
config.debug && config.debug('getMongoAttribute try direct lookup');
attribute_options = {
collection: options.collection,
query: {
parent: result._id,
name: result.name + '.' + options.attribute
}
};
config.debug && config.debug('getMongoAttribute attribute_options', attribute_options);
return getMongoContent(attribute_options, function attribute(err, attribute_result, coll) {
if (err) {
config.error && config.error('ERR getMongoAttribute', err);
return callback && callback(err);
}
config.debug && config.debug('getMongoAttribute direct attribute_result', attribute_result);
return callback && callback(err, attribute_result, coll);
});
}
});
}
function saveData(collection, data, callback) {
if (data._id && !(data._id instanceof Object)) {
data._id = new ObjectID.createFromHexString(data._id);
}
config.debug && config.debug('saveData saving', data._id);
collection.save(data, {safe: true}, function (err, result2, result3) {
if (err) {
config.error && config.error('ERR saveData', err);
return callback && callback(err);
}
config.debug && config.debug('saveData saved', data._id, result2, result3);
return callback && callback(null, data, collection);
});
}
var updating = false;
function updateData(collection, data, callback) {
if (updating) {
//noinspection JSUnresolvedFunction
setImmediate(function rescheduling() {
config.debug && config.debug('Updating, rescheduling');
return updateData(collection, data, callback);
});
} else {
updating = true;
var stopUpdating = function (err, result, col) {
config.debug && config.debug('Stop updating');
updating = false;
if (err) {
return callback && callback(err);
}
return callback && callback(null, result, col);
};
return collection.findOne({_id: data._id}, function foundOne(err, result) {
if (err) {
config.error && config.error('ERR updateData', err);
return callback && callback(err);
}
_.extend(result, data);
return saveData(collection, result, stopUpdating);
});
}
}
/*
* options:
* collection (mandatory)
* query (mandatory)
* operation (optional) : version info
* update (optional) : extends existing content
*/
function setMongoContent(data, options, callback) {
config.debug && config.debug('setMongoContent options', options);
return db.collection(options.collection, function handleCollection(err, collection) {
if (err) {
config.error && config.error('ERR2 setMongoContent', err);
return callback && callback(err);
}
if (options.operation && options.operation.v) {
data.version = options.operation.v;
}
var dumpData = saveData;
if (options.update) {
dumpData = updateData;
}
if (!data._id) {
config.debug && config.debug('setMongoContent lookup by query', options.query, 'updating:', options.update);
collection.findOne(options.query, function foundOne(err, result) {
if (err) {
config.error && config.error('ERR3 setMongoContent', err);
return callback && callback(err);
}
if (result && result._id) {
data._id = result._id;
}
return dumpData(collection, data, callback);
});
} else {
return dumpData(collection, data, callback);
}
});
}
return {
saveData: saveData,
updateData: updateData,
getAttribute: getMongoAttribute,
getContent: getMongoContent,
setContent: setMongoContent
};
};