mdbgoose.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright 2015 The MemDB Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  12. // implied. See the License for the specific language governing
  13. // permissions and limitations under the License. See the AUTHORS file
  14. // for names of contributors.
  15. 'use strict';
  16. var path = require('path');
  17. global.MONGOOSE_DRIVER_PATH = '../../../../lib/mongoose-driver'; // path.join(__dirname, 'mongoose-driver');
  18. var P = require('bluebird');
  19. var util = require('util');
  20. var logger = require('memdb-logger').getLogger('memdb-client', __filename);
  21. var memdb = require('./index');
  22. var mongoose = require('mongoose');
  23. // save original connect
  24. var connectMongo = mongoose.connect;
  25. var disconnectMongo = mongoose.disconnect;
  26. mongoose.connect = function(opts){
  27. var promise = P.bind(this)
  28. .then(function(){
  29. if(this._autoconn){
  30. throw new Error('Already connected');
  31. }
  32. return memdb.autoConnect(opts);
  33. })
  34. .then(function(ret){
  35. this._autoconn = ret;
  36. if(opts && opts.backend){
  37. return P.promisify(connectMongo, mongoose)(opts.backend.url);
  38. }
  39. });
  40. var cb = arguments[arguments.length - 1];
  41. if(typeof(cb) === 'function'){
  42. return promise.nodeify(cb);
  43. }
  44. else{
  45. return promise;
  46. }
  47. };
  48. mongoose.disconnect = function(){
  49. var promise = P.bind(this)
  50. .then(function(){
  51. return this.autoconn.close();
  52. })
  53. .then(function(){
  54. this._autoconn = null;
  55. return P.promisify(disconnectMongo, mongoose)();
  56. });
  57. var cb = arguments[arguments.length - 1];
  58. if(typeof(cb) === 'function'){
  59. return promise.nodeify(cb);
  60. }
  61. else{
  62. return promise;
  63. }
  64. };
  65. Object.defineProperty(mongoose, 'autoconn' , {
  66. get : function(){
  67. if(!mongoose._autoconn){
  68. throw new Error('Please connect first');
  69. }
  70. return mongoose._autoconn;
  71. }
  72. });
  73. mongoose.transaction = function(func, shardId, cb){
  74. var promise = this.autoconn.transaction(func, shardId);
  75. if(typeof(cb) === 'function'){
  76. return promise.nodeify(cb);
  77. }
  78. else{
  79. return promise;
  80. }
  81. };
  82. // Parse mongoose model to generate collection config (indexes)
  83. mongoose.genCollectionConfig = function(){
  84. var collections = {};
  85. for(var name in mongoose.models){
  86. var model = mongoose.models[name];
  87. var schema = model.schema;
  88. var collname = model.collection.name;
  89. if(!collections[collname]){
  90. collections[collname] = {};
  91. }
  92. var collection = collections[collname];
  93. if(!collection.indexes){
  94. collection.indexes = [];
  95. }
  96. var paths = schema.paths;
  97. var index = null, mdbIndex = null;
  98. for(var field in paths){
  99. if(field === '_id' || field.indexOf('.') !== -1){
  100. continue; //ignore compound field and _id
  101. }
  102. index = paths[field]._index;
  103. if(!!index){
  104. mdbIndex = {keys : [field]};
  105. if(!!index.unique){
  106. mdbIndex.unique = true;
  107. }
  108. mdbIndex.valueIgnore = {};
  109. mdbIndex.valueIgnore[field] = paths[field].options.indexIgnore || [];
  110. collection.indexes.push(mdbIndex);
  111. }
  112. }
  113. if(!!schema._indexes){
  114. for(var i in schema._indexes){
  115. index = schema._indexes[i];
  116. mdbIndex = {keys : [], valueIgnore : {}};
  117. for(field in index[0]){
  118. if(index[0][field]){
  119. mdbIndex.keys.push(field);
  120. mdbIndex.valueIgnore[field] = paths[field].options.indexIgnore || [];
  121. }
  122. }
  123. if(index[1] && !!index[1].unique){
  124. mdbIndex.unique = true;
  125. }
  126. collection.indexes.push(mdbIndex);
  127. }
  128. }
  129. //Disable versionkey
  130. schema.options.versionKey = false;
  131. }
  132. logger.info('parsed collection config : %j', collections);
  133. return collections;
  134. };
  135. var Model = mongoose.Model;
  136. Model.findMongo = function(){
  137. return this.find.apply(this, [].slice.call(arguments)).comment('$mongo');
  138. };
  139. Model.findOneMongo = function(){
  140. return this.findOne.apply(this, [].slice.call(arguments)).comment('$mongo');
  141. };
  142. Model.findByIdMongo = function(){
  143. return this.findById.apply(this, [].slice.call(arguments)).comment('$mongo');
  144. };
  145. Model.findReadOnly = function(){
  146. return this.find.apply(this, [].slice.call(arguments)).comment('$readonly');
  147. };
  148. Model.findOneReadOnly = function(){
  149. return this.findOne.apply(this, [].slice.call(arguments)).comment('$readonly');
  150. };
  151. Model.findByIdReadOnly = function(){
  152. return this.findById.apply(this, [].slice.call(arguments)).comment('$readonly');
  153. };
  154. Model.countMongo = function(query, cb){
  155. if(!query){
  156. query = {};
  157. }
  158. return this.collection.countMongo(query, {}, cb);
  159. };
  160. var overwrited = ['findByIdAndRemove', 'findByIdAndUpdate', 'findOneAndUpdate', 'findOneAndRemove'];
  161. for (var i = overwrited.length - 1; i >= 0; i--) {
  162. (function(funcName){
  163. mongoose.Model[funcName] = function(){
  164. var cb = arguments[arguments.length-1];
  165. if(typeof(cb) === 'function') {
  166. cb(new Error(util.format('not implemented method: ', funcName)));
  167. } else {
  168. throw new Error(util.format('not implemented method: ', funcName));
  169. }
  170. };
  171. })(overwrited[i]); //jshint ignore:line
  172. }
  173. module.exports = P.promisifyAll(mongoose);