ebfd616e955f30876be66e0e735f4e8cce6088d7
[aai/esr-gui.git] /
1 "use strict";
2
3 var MongoError = require('mongodb-core').MongoError
4   , f = require('util').format;
5
6 // The store of ops
7 var Store = function(topology, storeOptions) {
8   var self = this;
9   var storedOps = [];
10   storeOptions = storeOptions || {force:false, bufferMaxEntries: -1}
11
12   // Internal state
13   this.s = {
14       storedOps: storedOps
15     , storeOptions: storeOptions
16     , topology: topology
17   }
18
19   Object.defineProperty(this, 'length', {
20     enumerable:true, get: function() { return self.s.storedOps.length; }
21   });
22 }
23
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}));
27   }
28
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 }));
31   }
32
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 }));
37     }
38
39     return;
40   }
41
42   this.s.storedOps.push({t: opType, n: ns, o: ops, op: options, c: callback})
43 }
44
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 }));
48   }
49
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 }));
52   }
53
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 }));
58     }
59
60     return;
61   }
62
63   this.s.storedOps.push({t: opType, m: method, o: object, p: params, c: callback})
64 }
65
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 }));
69   }
70 }
71
72 var primaryOptions = ['primary', 'primaryPreferred', 'nearest', 'secondaryPreferred'];
73 var secondaryOptions = ['secondary', 'secondaryPreferred'];
74
75 Store.prototype.execute = function(options) {
76   options = options || {};
77   // Get current ops
78   var ops = this.s.storedOps;
79   // Reset the ops
80   this.s.storedOps = [];
81
82   // Unpack options
83   var executePrimary = typeof options.executePrimary === 'boolean'
84     ? options.executePrimary : true;
85   var executeSecondary = typeof options.executeSecondary === 'boolean'
86     ? options.executeSecondary : true;
87
88   // Execute all the stored ops
89   while(ops.length > 0) {
90     var op = ops.shift();
91
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);
103       }
104     } else if(op.t == 'auth') {
105       this.s.topology[op.t].apply(this.s.topology, op.o);
106     } else {
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);
115       }
116     }
117   }
118 }
119
120 Store.prototype.all = function() {
121   return this.s.storedOps;
122 }
123
124 // Server capabilities
125 var ServerCapabilities = function(ismaster) {
126   var setup_get_property = function(object, name, value) {
127     Object.defineProperty(object, name, {
128         enumerable: true
129       , get: function () { return value; }
130     });
131   }
132
133   // Capabilities
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;
143
144   if(ismaster.minWireVersion >= 0) {
145     textSearch = true;
146   }
147
148   if(ismaster.maxWireVersion >= 1) {
149     aggregationCursor = true;
150     authCommands = true;
151   }
152
153   if(ismaster.maxWireVersion >= 2) {
154     writeCommands = true;
155   }
156
157   if(ismaster.maxWireVersion >= 3) {
158     listCollections = true;
159     listIndexes = true;
160   }
161
162   if(ismaster.maxWireVersion >= 5) {
163     commandsTakeWriteConcern = true;
164     commandsTakeCollation = true;
165   }
166
167   // If no min or max wire version set to 0
168   if(ismaster.minWireVersion == null) {
169     ismaster.minWireVersion = 0;
170   }
171
172   if(ismaster.maxWireVersion == null) {
173     ismaster.maxWireVersion = 0;
174   }
175
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);
188 }
189
190 exports.Store = Store;
191 exports.ServerCapabilities = ServerCapabilities;