3 var MongoError = require('mongodb-core').MongoError
4 , f = require('util').format;
7 var Store = function(topology, storeOptions) {
10 storeOptions = storeOptions || {force:false, bufferMaxEntries: -1}
15 , storeOptions: storeOptions
19 Object.defineProperty(this, 'length', {
20 enumerable:true, get: function() { return self.s.storedOps.length; }
24 Store.prototype.add = function(opType, ns, ops, options, callback) {
25 if(this.s.storeOptions.force) {
26 return callback(MongoError.create({message: "db closed by application", driver:true}));
29 if(this.s.storeOptions.bufferMaxEntries == 0) {
30 return callback(MongoError.create({message: f("no connection available for operation and number of stored operation > %s", this.s.storeOptions.bufferMaxEntries), driver:true }));
33 if(this.s.storeOptions.bufferMaxEntries > 0 && this.s.storedOps.length > this.s.storeOptions.bufferMaxEntries) {
34 while(this.s.storedOps.length > 0) {
35 var op = this.s.storedOps.shift();
36 op.c(MongoError.create({message: f("no connection available for operation and number of stored operation > %s", this.s.storeOptions.bufferMaxEntries), driver:true }));
42 this.s.storedOps.push({t: opType, n: ns, o: ops, op: options, c: callback})
45 Store.prototype.addObjectAndMethod = function(opType, object, method, params, callback) {
46 if(this.s.storeOptions.force) {
47 return callback(MongoError.create({message: "db closed by application", driver:true }));
50 if(this.s.storeOptions.bufferMaxEntries == 0) {
51 return callback(MongoError.create({message: f("no connection available for operation and number of stored operation > %s", this.s.storeOptions.bufferMaxEntries), driver:true }));
54 if(this.s.storeOptions.bufferMaxEntries > 0 && this.s.storedOps.length > this.s.storeOptions.bufferMaxEntries) {
55 while(this.s.storedOps.length > 0) {
56 var op = this.s.storedOps.shift();
57 op.c(MongoError.create({message: f("no connection available for operation and number of stored operation > %s", this.s.storeOptions.bufferMaxEntries), driver:true }));
63 this.s.storedOps.push({t: opType, m: method, o: object, p: params, c: callback})
66 Store.prototype.flush = function(err) {
67 while(this.s.storedOps.length > 0) {
68 this.s.storedOps.shift().c(err || MongoError.create({message: f("no connection available for operation"), driver:true }));
72 var primaryOptions = ['primary', 'primaryPreferred', 'nearest', 'secondaryPreferred'];
73 var secondaryOptions = ['secondary', 'secondaryPreferred'];
75 Store.prototype.execute = function(options) {
76 options = options || {};
78 var ops = this.s.storedOps;
80 this.s.storedOps = [];
83 var executePrimary = typeof options.executePrimary === 'boolean'
84 ? options.executePrimary : true;
85 var executeSecondary = typeof options.executeSecondary === 'boolean'
86 ? options.executeSecondary : true;
88 // Execute all the stored ops
89 while(ops.length > 0) {
92 if(op.t == 'cursor') {
93 if(executePrimary && executeSecondary) {
94 op.o[op.m].apply(op.o, op.p);
95 } else if(executePrimary && op.o.options
96 && op.o.options.readPreference
97 && primaryOptions.indexOf(op.o.options.readPreference.mode) != -1) {
98 op.o[op.m].apply(op.o, op.p);
99 } else if(!executePrimary && executeSecondary && op.o.options
100 && op.o.options.readPreference
101 && secondaryOptions.indexOf(op.o.options.readPreference.mode) != -1) {
102 op.o[op.m].apply(op.o, op.p);
104 } else if(op.t == 'auth') {
105 this.s.topology[op.t].apply(this.s.topology, op.o);
107 if(executePrimary && executeSecondary) {
108 this.s.topology[op.t](op.n, op.o, op.op, op.c);
109 } else if(executePrimary && op.op && op.op.readPreference
110 && primaryOptions.indexOf(op.op.readPreference.mode) != -1) {
111 this.s.topology[op.t](op.n, op.o, op.op, op.c);
112 } else if(!executePrimary && executeSecondary && op.op && op.op.readPreference
113 && secondaryOptions.indexOf(op.op.readPreference.mode) != -1) {
114 this.s.topology[op.t](op.n, op.o, op.op, op.c);
120 Store.prototype.all = function() {
121 return this.s.storedOps;
124 // Server capabilities
125 var ServerCapabilities = function(ismaster) {
126 var setup_get_property = function(object, name, value) {
127 Object.defineProperty(object, name, {
129 , get: function () { return value; }
134 var aggregationCursor = false;
135 var writeCommands = false;
136 var textSearch = false;
137 var authCommands = false;
138 var listCollections = false;
139 var listIndexes = false;
140 var maxNumberOfDocsInBatch = ismaster.maxWriteBatchSize || 1000;
141 var commandsTakeWriteConcern = false;
142 var commandsTakeCollation = false;
144 if(ismaster.minWireVersion >= 0) {
148 if(ismaster.maxWireVersion >= 1) {
149 aggregationCursor = true;
153 if(ismaster.maxWireVersion >= 2) {
154 writeCommands = true;
157 if(ismaster.maxWireVersion >= 3) {
158 listCollections = true;
162 if(ismaster.maxWireVersion >= 5) {
163 commandsTakeWriteConcern = true;
164 commandsTakeCollation = true;
167 // If no min or max wire version set to 0
168 if(ismaster.minWireVersion == null) {
169 ismaster.minWireVersion = 0;
172 if(ismaster.maxWireVersion == null) {
173 ismaster.maxWireVersion = 0;
176 // Map up read only parameters
177 setup_get_property(this, "hasAggregationCursor", aggregationCursor);
178 setup_get_property(this, "hasWriteCommands", writeCommands);
179 setup_get_property(this, "hasTextSearch", textSearch);
180 setup_get_property(this, "hasAuthCommands", authCommands);
181 setup_get_property(this, "hasListCollectionsCommand", listCollections);
182 setup_get_property(this, "hasListIndexesCommand", listIndexes);
183 setup_get_property(this, "minWireVersion", ismaster.minWireVersion);
184 setup_get_property(this, "maxWireVersion", ismaster.maxWireVersion);
185 setup_get_property(this, "maxNumberOfDocsInBatch", maxNumberOfDocsInBatch);
186 setup_get_property(this, "commandsTakeWriteConcern", commandsTakeWriteConcern);
187 setup_get_property(this, "commandsTakeCollation", commandsTakeCollation);
190 exports.Store = Store;
191 exports.ServerCapabilities = ServerCapabilities;