MongoDB  2.7.0
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 "mongo/pch.h"
21 
22 #include <stack>
23 
25 #include "mongo/client/export_macros.h"
26 #include "mongo/db/jsobj.h"
27 #include "mongo/db/json.h"
28 #include "mongo/util/net/message.h"
29 
30 namespace mongo {
31 
32  class AScopedConnection;
33 
37  class MONGO_CLIENT_API DBClientCursorInterface : boost::noncopyable {
38  public:
39  virtual ~DBClientCursorInterface() {}
40  virtual bool more() = 0;
41  virtual BSONObj next() = 0;
42  // TODO bring more of the DBClientCursor interface to here
43  protected:
45  };
46 
48  class MONGO_CLIENT_API DBClientCursor : public DBClientCursorInterface {
49  public:
51  bool more();
52 
58  int objsLeftInBatch() const { _assertIfNull(); return _putBack.size() + batch.nReturned - batch.pos; }
59  bool moreInCurrentBatch() { return objsLeftInBatch() > 0; }
60 
70  BSONObj next();
71 
75  void putBack( const BSONObj &o ) { _putBack.push( o.getOwned() ); }
76 
79  BSONObj o = next();
80  if( strcmp(o.firstElementFieldName(), "$err") == 0 ) {
81  string s = "nextSafe(): " + o.toString();
82  LOG(5) << s;
83  uasserted(13106, s);
84  }
85  return o;
86  }
87 
93  void peek(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 { return !this || cursorId == 0; }
121 
122  bool tailable() const { return (opts & QueryOption_CursorTailable) != 0; }
123 
128  bool hasResultFlag( int flag ) {
129  _assertIfNull();
130  return (resultFlags & flag) != 0;
131  }
132 
134  void setBatchSize(int newBatchSize) { batchSize = newBatchSize; }
135 
136  DBClientCursor( DBClientBase* client, const string &_ns, BSONObj _query, int _nToReturn,
137  int _nToSkip, const BSONObj *_fieldsToReturn, int queryOptions , int bs ) :
138  _client(client),
139  ns(_ns),
140  query(_query),
141  nToReturn(_nToReturn),
142  haveLimit( _nToReturn > 0 && !(queryOptions & QueryOption_CursorTailable)),
143  nToSkip(_nToSkip),
144  fieldsToReturn(_fieldsToReturn),
145  opts(queryOptions),
146  batchSize(bs==1?2:bs),
147  resultFlags(0),
148  cursorId(),
149  _ownCursor( true ),
150  wasError( false ) {
151  _finishConsInit();
152  }
153 
154  DBClientCursor( DBClientBase* client, const string &_ns, long long _cursorId, int _nToReturn, int options ) :
155  _client(client),
156  ns(_ns),
157  nToReturn( _nToReturn ),
158  haveLimit( _nToReturn > 0 && !(options & QueryOption_CursorTailable)),
159  nToSkip(0),
160  fieldsToReturn(0),
161  opts( options ),
162  batchSize(0),
163  resultFlags(0),
164  cursorId(_cursorId),
165  _ownCursor(true),
166  wasError(false) {
167  _finishConsInit();
168  }
169 
170  virtual ~DBClientCursor();
171 
172  long long getCursorId() const { return cursorId; }
173 
177  void decouple() { _ownCursor = false; }
178 
179  void attach( AScopedConnection * conn );
180 
181  string originalHost() const { return _originalHost; }
182 
183  string getns() const { return ns; }
184 
185  Message* getMessage(){ return batch.m.get(); }
186 
195  bool initCommand();
196 
200  bool init();
201 
202  void initLazy( bool isRetry = false );
203  bool initLazyFinish( bool& retry );
204 
205  class Batch : boost::noncopyable {
206  friend class DBClientCursor;
207  auto_ptr<Message> m;
208  int nReturned;
209  int pos;
210  const char *data;
211  public:
212  Batch() : m( new Message() ), nReturned(), pos(), data() { }
213  };
214 
215  private:
216  friend class DBClientBase;
217  friend class DBClientConnection;
218 
219  int nextBatchSize();
220  void _finishConsInit();
221 
222  Batch batch;
223  DBClientBase* _client;
224  string _originalHost;
225  string ns;
226  BSONObj query;
227  int nToReturn;
228  bool haveLimit;
229  int nToSkip;
230  const BSONObj *fieldsToReturn;
231  int opts;
232  int batchSize;
233  stack< BSONObj > _putBack;
234  int resultFlags;
235  long long cursorId;
236  bool _ownCursor; // see decouple()
237  string _scopedHost;
238  string _lazyHost;
239  bool wasError;
240 
241  void dataReceived() { bool retry; string lazyHost; dataReceived( retry, lazyHost ); }
242  void dataReceived( bool& retry, string& lazyHost );
243  void requestMore();
244  void exhaustReceiveMore(); // for exhaust
245 
246  // Don't call from a virtual function
247  void _assertIfNull() const { uassert(13348, "connection died", this); }
248 
249  // non-copyable , non-assignable
250  DBClientCursor( const DBClientCursor& );
251  DBClientCursor& operator=( const DBClientCursor& );
252 
253  // init pieces
254  void _assembleInit( Message& toSend );
255  };
256 
259  class MONGO_CLIENT_API DBClientCursorBatchIterator {
260  public:
261  DBClientCursorBatchIterator( DBClientCursor &c ) : _c( c ), _n() {}
262  bool moreInCurrentBatch() { return _c.moreInCurrentBatch(); }
263  BSONObj nextSafe() {
264  massert( 13383, "BatchIterator empty", moreInCurrentBatch() );
265  ++_n;
266  return _c.nextSafe();
267  }
268  int n() const { return _n; }
269  private:
270  DBClientCursor &_c;
271  int _n;
272  };
273 
274 } // namespace mongo
275 
BSONObj nextSafe()
throws AssertionException if get back { $err : ...
Definition: dbclientcursor.h:78
LogstreamBuilder error()
Returns a LogstreamBuilder for logging a message with LogSeverity::Error().
Definition: log.h:51
bool isDead() const
cursor no longer valid – use with tailable cursors.
Definition: dbclientcursor.h:120
iterate over objects in current batch only - will not cause a network call
Definition: dbclientcursor.h:259
BSON classes.
for mock purposes only – do not create variants of DBClientCursor, nor hang code here ...
Definition: dbclientcursor.h:37
BSONObj getOwned() const
assure the data buffer is under the control of this BSONObj and not a remote buffer ...
Definition: bson-inl.h:232
abstract class that implements the core db operations
Definition: dbclientinterface.h:1058
const char * firstElementFieldName() const
faster than firstElement().fieldName() - for the first element we can easily find the fieldname witho...
Definition: bsonobj.h:388
void setBatchSize(int newBatchSize)
Change batchSize after construction. Can change after requesting first batch.
Definition: dbclientcursor.h:134
void putBack(const BSONObj &o)
restore an object previously returned by next() to the cursor
Definition: dbclientcursor.h:75
int itcount()
iterate the rest of the cursor and return the number if items
Definition: dbclientcursor.h:106
A basic connection to the database.
Definition: dbclientinterface.h:1194
void decouple()
by default we "own" the cursor and will send the server a KillCursor message when ~DBClientCursor() i...
Definition: dbclientcursor.h:177
Core MongoDB C++ driver interfaces are defined here.
Definition: dbclientcursor.h:205
Queries return a cursor object.
Definition: dbclientcursor.h:48
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77
bool hasResultFlag(int flag)
see ResultFlagType (constants.h) for flag values mostly these flags are for internal purposes - Resul...
Definition: dbclientcursor.h:128
int objsLeftInBatch() const
If true, there is more in our local buffers to be fetched via next().
Definition: dbclientcursor.h:58
Definition: connpool.h:257
Definition: message.h:153
QueryOption_CursorTailable
Tailable means cursor is not closed when the last data is retrieved.
Definition: dbclientinterface.h:47