MongoDB C++ Driver  legacy-1.1.2
dbclientcursor.h
1 // file dbclientcursor.h
2 
3 /* Copyright 2009 10gen Inc.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #pragma once
19 
20 #include <stack>
21 
23 #include "mongo/client/export_macros.h"
24 #include "mongo/db/jsobj.h"
25 #include "mongo/db/json.h"
26 #include "mongo/util/net/message.h"
27 
28 namespace mongo {
29 
30 class DBClientCursorShim;
31 class DBClientCursorShimCursorID;
32 class DBClientCursorShimArray;
33 class DBClientCursorShimTransform;
34 
38 class MONGO_CLIENT_API DBClientCursorInterface : boost::noncopyable {
39 public:
40  virtual ~DBClientCursorInterface() {}
41  virtual bool more() = 0;
42  virtual BSONObj next() = 0;
43  // TODO bring more of the DBClientCursor interface to here
44 protected:
46 };
47 
49 class MONGO_CLIENT_API DBClientCursor : public DBClientCursorInterface {
50 public:
52  bool more();
53 
59  int objsLeftInBatch() const {
60  _assertIfNull();
61  return _putBack.size() + batch.nReturned - batch.pos;
62  }
63  bool moreInCurrentBatch() {
64  return objsLeftInBatch() > 0;
65  }
66 
76  BSONObj next();
77 
81  void putBack(const BSONObj& o) {
82  _putBack.push(o.getOwned());
83  }
84 
86  BSONObj nextSafe();
87 
93  void peek(std::vector<BSONObj>&, int atMost);
94 
95  // Peeks at first element, if exists
96  BSONObj peekFirst();
97 
101  bool peekError(BSONObj* error = NULL);
102 
106  int itcount() {
107  int c = 0;
108  while (more()) {
109  next();
110  c++;
111  }
112  return c;
113  }
114 
120  bool isDead() const {
121  return cursorId == 0;
122  }
123 
124  bool tailable() const {
125  return (opts & QueryOption_CursorTailable) != 0;
126  }
127 
132  bool hasResultFlag(int flag) {
133  _assertIfNull();
134  return (resultFlags & flag) != 0;
135  }
136 
138  void setBatchSize(int newBatchSize) {
139  batchSize = newBatchSize;
140  }
141 
143  const std::string& _ns,
144  BSONObj _query,
145  int _nToReturn,
146  int _nToSkip,
147  const BSONObj* _fieldsToReturn,
148  int queryOptions,
149  int bs);
151  const std::string& _ns,
152  long long _cursorId,
153  int _nToReturn,
154  int options,
155  int _batchSize);
156 
157  virtual ~DBClientCursor();
158 
159  long long getCursorId() const {
160  return cursorId;
161  }
162 
166  void decouple() {
167  _ownCursor = false;
168  }
169 
170  std::string originalHost() const {
171  return _originalHost;
172  }
173 
174  std::string getns() const {
175  return ns;
176  }
177 
178  Message* getMessage() {
179  return batch.m.get();
180  }
181 
190  bool initCommand();
191 
195  bool init();
196 
197  void initLazy(bool isRetry = false);
198  bool initLazyFinish(bool& retry);
199 
200  class Batch : boost::noncopyable {
201  friend class DBClientCursor;
202  std::auto_ptr<Message> m;
203  int nReturned;
204  int pos;
205  const char* data;
206 
207  public:
208  Batch() : m(new Message()), nReturned(), pos(), data() {}
209  };
210 
221  void kill();
222 
223 private:
224  friend class DBClientBase;
225  friend class DBClientConnection;
226  friend class DBClientCursorShimCursorID;
227  friend class DBClientCursorShimArray;
228  friend class DBClientCursorShimTransform;
229  friend class DBClientWithCommands;
230 
231  int nextBatchSize();
232  void _finishConsInit();
233 
234  BSONObj rawNext();
235  bool rawMore();
236 
237  std::auto_ptr<DBClientCursorShim> shim;
238 
239  Batch batch;
240  DBClientBase* _client;
241  std::string _originalHost;
242  std::string ns;
243  BSONObj query;
244  int nToReturn;
245  int nToSkip;
246  long long nReturned;
247  const BSONObj* fieldsToReturn;
248  int opts;
249  int batchSize;
250  std::stack<BSONObj> _putBack;
251  int resultFlags;
252  long long cursorId;
253  bool _ownCursor; // see decouple()
254  std::string _scopedHost;
255  std::string _lazyHost;
256  bool wasError;
257 
258  void dataReceived() {
259  bool retry;
260  std::string lazyHost;
261  dataReceived(retry, lazyHost);
262  }
263  void dataReceived(bool& retry, std::string& lazyHost);
264  void requestMore();
265  void exhaustReceiveMore(); // for exhaust
266 
267  // Don't call from a virtual function
268  void _assertIfNull() const {
269  uassert(13348, "connection died", this);
270  }
271 
272  // non-copyable , non-assignable
273  DBClientCursor(const DBClientCursor&);
274  DBClientCursor& operator=(const DBClientCursor&);
275 
276  // init pieces
277  void _assembleInit(Message& toSend);
278 };
279 
282 class MONGO_CLIENT_API DBClientCursorBatchIterator {
283 public:
284  DBClientCursorBatchIterator(DBClientCursor& c) : _c(c), _n() {}
285  bool moreInCurrentBatch() {
286  return _c.moreInCurrentBatch();
287  }
288  BSONObj nextSafe() {
289  massert(13383, "BatchIterator empty", moreInCurrentBatch());
290  ++_n;
291  return _c.nextSafe();
292  }
293  int n() const {
294  return _n;
295  }
296 
297 private:
298  DBClientCursor& _c;
299  int _n;
300 };
301 
302 } // namespace mongo
DBClientCursorShimCursorID implements the shim interface over a cursor reply document, rather than the traditional OP_REPLY.
Definition: dbclientcursorshimcursorid.h:29
void setBatchSize(int newBatchSize)
Change batchSize after construction. Can change after requesting first batch.
Definition: dbclientcursor.h:138
DB "commands" Basically just invocations of connection.
Definition: dbclientinterface.h:771
Definition: message.h:305
Utility functions for parsing numbers from strings.
Definition: compare_numbers.h:20
void putBack(const BSONObj &o)
restore an object previously returned by next() to the cursor
Definition: dbclientcursor.h:81
BSON classes.
Definition: dbclientcursor.h:200
Queries return a cursor object.
Definition: dbclientcursor.h:49
bool isDead() const
cursor no longer valid – use with tailable cursors.
Definition: dbclientcursor.h:120
BSONObj getOwned() const
assure the data buffer is under the control of this BSONObj and not a remote buffer ...
int objsLeftInBatch() const
If true, there is more in our local buffers to be fetched via next().
Definition: dbclientcursor.h:59
for mock purposes only – do not create variants of DBClientCursor, nor hang code here ...
Definition: dbclientcursor.h:38
A basic connection to the database.
Definition: dbclientinterface.h:1716
int itcount()
iterate the rest of the cursor and return the number if items
Definition: dbclientcursor.h:106
void decouple()
by default we "own" the cursor and will send the server a KillCursor message when ~DBClientCursor() i...
Definition: dbclientcursor.h:166
Core MongoDB C++ driver interfaces are defined here.
DBClientCursorShimTransform implements the shim interface over a cursor reply document by allowing a ...
Definition: dbclientcursorshimtransform.h:29
iterate over objects in current batch only - will not cause a network call
Definition: dbclientcursor.h:282
bool hasResultFlag(int flag)
see ResultFlagType (constants.h) for flag values mostly these flags are for internal purposes - Resul...
Definition: dbclientcursor.h:132
abstract class that implements the core db operations
Definition: dbclientinterface.h:1422
DBClientCursorShimArray implements the shim interface over an array of bson obj's.
Definition: dbclientcursorshimarray.h:28
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary represent...
Definition: bsonobj.h:78
QueryOption_CursorTailable
Tailable means cursor is not closed when the last data is retrieved.
Definition: dbclientinterface.h:55