Esempio n. 1
0
  /**
   * Limits the number of elements returned. Note: parameter <tt>n</tt> should be positive, although
   * a negative value is supported for legacy reason. Passing a negative value will call {@link
   * DBCursor#batchSize(int)} which is the preferred method.
   *
   * @param n the number of elements to return
   * @return a cursor to iterate the results
   * @dochub limit
   */
  public DBCursor limit(int n) {
    if (_it != null) throw new IllegalStateException("can't set limit after executing query");

    if (n > 0) _limit = n;
    else if (n < 0) batchSize(n);
    return this;
  }
  @Test
  public void testBatchWithActiveCursor() {
    DBCollection c = _db.getCollection("testBatchWithActiveCursor");
    c.drop();

    for (int i = 0; i < 100; i++) c.save(new BasicDBObject("x", i));

    try {
      DBCursor cursor = c.find().batchSize(2); // setting to 1, actually sets to 2 (why, oh why?)
      cursor.next(); // creates real cursor on server.
      cursor.next();
      assertEquals(0, cursor.numGetMores());
      cursor.next();
      assertEquals(1, cursor.numGetMores());
      cursor.next();
      cursor.next();
      assertEquals(2, cursor.numGetMores());
      cursor.next();
      cursor.next();
      assertEquals(3, cursor.numGetMores());
      cursor.batchSize(20);
      cursor.next();
      cursor.next();
      cursor.next();
      assertEquals(4, cursor.numGetMores());
    } catch (IllegalStateException e) {
      assertNotNull(e); // there must be a better way to detect this.
    }
  }
  protected void doFindAll(Exchange exchange) throws Exception {
    DBCollection dbCol = calculateCollection(exchange);
    // do not use getMandatoryBody, because if the body is empty we want to retrieve all objects in
    // the collection
    DBObject query = null;
    // do not run around looking for a type converter unless there is a need for it
    if (exchange.getIn().getBody() != null) {
      query = exchange.getIn().getBody(DBObject.class);
    }
    DBObject fieldFilter =
        exchange.getIn().getHeader(MongoDbConstants.FIELDS_FILTER, DBObject.class);

    // get the batch size and number to skip
    Integer batchSize = exchange.getIn().getHeader(MongoDbConstants.BATCH_SIZE, Integer.class);
    Integer numToSkip = exchange.getIn().getHeader(MongoDbConstants.NUM_TO_SKIP, Integer.class);
    Integer limit = exchange.getIn().getHeader(MongoDbConstants.LIMIT, Integer.class);
    DBObject sortBy = exchange.getIn().getHeader(MongoDbConstants.SORT_BY, DBObject.class);
    DBCursor ret = null;
    try {
      if (query == null && fieldFilter == null) {
        ret = dbCol.find(new BasicDBObject());
      } else if (fieldFilter == null) {
        ret = dbCol.find(query);
      } else {
        ret = dbCol.find(query, fieldFilter);
      }

      if (sortBy != null) {
        ret.sort(sortBy);
      }

      if (batchSize != null) {
        ret.batchSize(batchSize.intValue());
      }

      if (numToSkip != null) {
        ret.skip(numToSkip.intValue());
      }

      if (limit != null) {
        ret.limit(limit.intValue());
      }

      Message resultMessage = prepareResponseMessage(exchange, MongoDbOperation.findAll);
      resultMessage.setBody(ret.toArray());
      resultMessage.setHeader(MongoDbConstants.RESULT_TOTAL_SIZE, ret.count());
      resultMessage.setHeader(MongoDbConstants.RESULT_PAGE_SIZE, ret.size());
    } finally {
      // make sure the cursor is closed
      if (ret != null) {
        ret.close();
      }
    }
  }
  @Test
  public void testHasFinalizer() throws UnknownHostException {
    DBCollection c = _db.getCollection("HasFinalizerTest");
    c.drop();

    for (int i = 0; i < 1000; i++) c.save(new BasicDBObject("_id", i), WriteConcern.SAFE);

    // finalizer is on by default so after calling hasNext should report that it has one
    DBCursor cursor = c.find();
    assertFalse(cursor.hasFinalizer());
    cursor.hasNext();
    assertTrue(cursor.hasFinalizer());
    cursor.close();

    // no finalizer if there is no cursor, as there should not be for a query with only one result
    cursor = c.find(new BasicDBObject("_id", 1));
    cursor.hasNext();
    assertFalse(cursor.hasFinalizer());
    cursor.close();

    // no finalizer if there is no cursor, as there should not be for a query with negative batch
    // size
    cursor = c.find();
    cursor.batchSize(-1);
    cursor.hasNext();
    assertFalse(cursor.hasFinalizer());
    cursor.close();

    // finally, no finalizer if disabled in mongo options
    MongoOptions mongoOptions = new MongoOptions();
    mongoOptions.cursorFinalizerEnabled = false;
    Mongo m = new Mongo("127.0.0.1", mongoOptions);
    try {
      c = m.getDB(cleanupDB).getCollection("HasFinalizerTest");
      cursor = c.find();
      cursor.hasNext();
      assertFalse(cursor.hasFinalizer());
      cursor.close();
    } finally {
      m.close();
    }
  }
  /**
   * Execute the interaction and return output record. The spec is either GET, PUT or DELETE
   * interaction.
   */
  public Record execute(InteractionSpec spec, Record record) throws ResourceException {
    if (!(spec instanceof MongoInteractionSpec)) {
      throw EISException.invalidInteractionSpecType();
    }
    if (!(record instanceof MongoRecord)) {
      throw EISException.invalidRecordType();
    }
    MongoInteractionSpec mongoSpec = (MongoInteractionSpec) spec;
    MongoRecord input = (MongoRecord) record;
    MongoOperation operation = mongoSpec.getOperation();
    String collectionName = mongoSpec.getCollection();
    if (operation == null) {
      ResourceException resourceException = new ResourceException("Mongo operation must be set");
      throw resourceException;
    }
    if (operation == MongoOperation.EVAL) {
      Object result = this.connection.getDB().eval(mongoSpec.getCode());
      return buildRecordFromDBObject((DBObject) result);
    }
    if (collectionName == null) {
      ResourceException resourceException = new ResourceException("DB Collection name must be set");
      throw resourceException;
    }
    try {
      DBCollection collection = this.connection.getDB().getCollection(collectionName);
      if (mongoSpec.getOptions() > 0) {
        collection.setOptions(mongoSpec.getOptions());
      }
      if (mongoSpec.getReadPreference() != null) {
        collection.setReadPreference(mongoSpec.getReadPreference());
      }
      if (mongoSpec.getWriteConcern() != null) {
        collection.setWriteConcern(mongoSpec.getWriteConcern());
      }
      if (operation == MongoOperation.INSERT) {
        DBObject object = buildDBObject(input);
        collection.insert(object);
      } else if (operation == MongoOperation.REMOVE) {
        DBObject object = buildDBObject(input);
        collection.remove(object);
      } else if (operation == MongoOperation.FIND) {
        DBObject sort = null;
        if (input.containsKey(MongoRecord.SORT)) {
          sort = buildDBObject((MongoRecord) input.get(MongoRecord.SORT));
          input.remove(MongoRecord.SORT);
        }
        DBObject select = null;
        if (input.containsKey("$select")) {
          select = buildDBObject((MongoRecord) input.get("$select"));
          input.remove("$select");
        }
        DBObject object = buildDBObject(input);
        DBCursor cursor = collection.find(object, select);
        if (sort != null) {
          cursor.sort(sort);
        }
        try {
          if (mongoSpec.getSkip() > 0) {
            cursor.skip(mongoSpec.getSkip());
          }
          if (mongoSpec.getLimit() != 0) {
            cursor.limit(mongoSpec.getLimit());
          }
          if (mongoSpec.getBatchSize() != 0) {
            cursor.batchSize(mongoSpec.getBatchSize());
          }
          if (!cursor.hasNext()) {
            return null;
          }
          MongoListRecord results = new MongoListRecord();
          while (cursor.hasNext()) {
            DBObject result = cursor.next();
            results.add(buildRecordFromDBObject(result));
          }
          return results;
        } finally {
          cursor.close();
        }

      } else {
        throw new ResourceException("Invalid operation: " + operation);
      }
    } catch (Exception exception) {
      ResourceException resourceException = new ResourceException(exception.toString());
      resourceException.initCause(exception);
      throw resourceException;
    }
    return null;
  }