Giter Site home page Giter Site logo

fongo's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fongo's Issues

Implement orderBy

Hello guys,
We're using a bit of Fongo as well as real Mongo in our tests. We'd love to use Fongo more but it's unable to understand orderBy. Here's an example failing query (in rogue, scala syntax):

(Banana where (_.size eqs "XXL") orderDesc(_.createdAt)).fetch

The same query without the orderDesc returns some values, once we add the ordering it returns Nil.

Implement elemMatch

Working in a project where we need to do some testing with Fongo on querying nested data structure using the elemMatch filter.

Would it be possible to have it implemented in one of the next releases ?

If not, I'm currently working on an implementation of it that I can submit as soon as it's working properly.

Unable to load only specific field for object(not all fields)

I'm using spring MongoTemplate for accessing to the fongo.
I'm using criteria query for loading objects. I'm specifying only one field for loading. When I'm using real mongo database everything works as expected, but when I'm using fongo - all fields of object is loading

Query q = Query.query(Criteria.where("name").is("Demo1"));
q.fields().include("data");
List launches = operations.find(q, MyObj.class);

Thanks in advance

BUG in ExpressionParser when evaluating $or

The ExpressionParser falls down when the query contains $or because the compare evaluation is absolutely wrong ...

  • class :com.foursquare.fongo.impl.ExpressionParser
  • method : private Filter buildExpressionFilter(final List path, final Object expression)
  • BUG : if (path.get(0) == OR) => see Java for dummies
  • FIX : if (OR.equals(path.get(0)))

$type

Fongo seem to ignore $type, which works in Mongo.
Query { field : { $type : 7 } } finds nothing, though the same query in Mongo finds docs with ObjectId as field value.

dropDatabase with 2 collections throw ConcurrentModificationException

Sample (sorry for scala code, but I hope it doesn't matter):

  val fongo = new Fongo("test")
  val db = fongo.getDB("test")
  db.getCollection("test1")
  db.getCollection("test2")
  fongo.dropDatabase("test")

Stacktrace:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:894)
at java.util.HashMap$ValueIterator.next(HashMap.java:922)
at com.mongodb.FongoDB.dropDatabase(FongoDB.java:77)
at com.foursquare.fongo.Fongo.dropDatabase(Fongo.java:92)

Missing license

The project has no OSS license like Apache 2.0. Is it intended?

TTL is not supported?

I have a ttl function in one of my collection. When I unit test it with fongo, seems the data is not delete from db.

Is this because of the fongo does not have a "mongod" running?

Btw, I made my unit test thread to sleep for more than 2 minutes which should have enough time for mongod to check ttl index and perform deletion.

Problem with references

Steps to reproduce:
I Have two classes "Test" and "TestSuite". Class "Test" have filed: private TestSuite testSuite;
I'm trying to find "Test" object by "TestSuite" id using reference: testSuite.$id

log message:
find({ "testSuite.$id" : { "$oid" : "519f379fe44a690dc3258561"}}).limit(0).skip(0)

This doesn't work on fongo but work in real mongodb.

Thanks in advance
Alex

fongo does not ensure an unique index

I've got the following Spring Data Annotation in my bean:

@Indexed(unique = true)
private String email;

which leads to the following index being created when fongo starts:

{ "v" : 1 , "key" : { "email" : 1} , "ns" : "test.user" , "name" : "email" , "dropDups" : false , "sparse" : false , "unique" : true}

However, the unique index is not ensured and this test fails, while it succeeds in mongo:

User user1 = createSampleUserWithEmail("[email protected]");
User user2 = createSampleUserWithEmail("[email protected]");
userRepository.save(user1);
assertEquals(1, userRepository.countAll());
userRepository.save(user2);
assertEquals(1, userRepository.countAll());

Note that a duplicate ID is not inserted, but this is another use case that is - for all I have experienced - not yet supported by fongo.

FongoDBCollection.drop() causes ConcurrentModificationExcpetion

Hi!

Here is background of my case: I'm using NoSqlUnit to write some unit tests with database and FongoDB is used as in-memory version of MongoDB.

I receive ConcurrentModificationException during removing of all collections from FongoDB. Steps of removal are pretty straightforward (db is instance of FongoDB class):

  • take all collection names using db.getCollectionNames() method,
  • in for each name loop:
    • get collection by name using db.getCollection(collectionName)
    • and call collection.drop() where collection is an instance of FongoDBCollection class

This causes that ConcurrentModificationException arises on attempt to remove an entry from FongoDB's private collMap.

There are two possible solutions for this case:

  1. Since FongoDB.getCollectionNames() returns only an immutable VIEW on key set of collMap private field every client using FongoDB should copy names collection to a new set.
  2. FongoDB.getCollectionNames() should provide on every call a new set filled with keys of collMap field.

I think the latter option is the most interesting for users of the library. Am I right?

This is extremely important issue for my project and its unit tests. Is it possible (since it seems to be a small change) to provide the fix ASAP, please?

GeoNear

I have written tests that uses MongoDB´s GeoNear feature. When using MongoDB via Spring Data the tests run green but when testing using Fongo the tests fail beacuse Fongo does not return the expected result like MongoDB when using GeoNear.

Are there any issues with Fongo´s GeoNear?

Fongo and Morphia

I'm trying to use Fongo together with Morphia (https://github.com/jmkgreen/morphia), however I've run into two issues:

When calling Datastore#merge() it fails with the following exception.
com.github.jmkgreen.morphia.query.UpdateException: Not updated: { "serverUsed" : "0.0.0.0/0.0.0.0:27017" , "ok" : true , "n" : 1}
It seems to expect getLastError for the update to contain the text "updatedExisting".

When saving and then getting an object that has a DBRef to another object (via Morphia's @reference), the DBRefBase will have a null _db field, which makes it throw an exception.

Both of these cases work if I connect to a real Mongo server rather than Fongo.

Fongo should return new objects or immutable (unmodifiable) objects/collections when find methods called

If I modify an object (or an object in a collection) returned by Fongo and then retrieve the same object from Fongo I see the 'new', changed object, not the one that was stored originally.

Here's some example code:

    Fongo fongo = new Fongo("mongo server 1");

    DB db = fongo.getDB("mydb");
    DBCollection coll = db.getCollection("mycollection");

    // Insert 2 objects
    DBObject bdo1 = new BasicDBObject("_id", 1).append("name", "tom");
    DBObject bdo2 = new BasicDBObject("_id", 2).append("name", "jon");

    coll.insert(bdo1);
    coll.insert(bdo2);

    // Get the 2nd one (name = jon) back
    DBObject bdo3 = coll.findOne(new BasicDBObject("_id",2));

    // Modify it locally
    bdo3.put("name", "jon2");

    // Retrieve the jon object again
    DBObject bdo4 = coll.findOne(new BasicDBObject("_id",2));

    LOG.info("bdo3 = {}", bdo3);  // Shows name='jon2'
    LOG.info("bdo4 = {}", bdo4);  // Also shows name='jon2'

I checked against MongoDB and it behaves as expected, ie with the code above, the name field of bdo3 is logged as 'jon2' but the name field of bdo4 is still 'jon'.

I guess this can be fixed by making the objects and collections returned by the various find methods immutable or by returning results in completely new objects (not referencing to the 'base' Fongo objects).

That's probably a pain for 99% of tests but the above behaviour can be very time consuming to debug in an elaborate test case.

I'm using Fongo 1.1.0 and the 2.11.1 mongo-java-driver.

ObjectId._new is not set to false when loading an object

When I store an object in MongoDB, the newly generated ObjectId has _new set to true, but the ObjectId Serialization String is computed from _time, _machine, _inc (see ObjectId.toByteArray). When being deserialized (i.e. when the Object is loaded), _new is set to false (see ObjectId(String s)).

In fongo, however, there is no (de)serialization and the _new is never set to false in a simple save&retrieve object scenario. This causes problems when I try to update an object - the mongo driver is trying to handle it as an insert if _new==true. Currently updates only work as expected if I manually replace the ObjectId of a retrieved object before saving it:

xyz.setId(new ObjectId(xyz.getId().toString()))

I think it would make sense to ensure that ObjectId.notNew() is called whenever an object is stored in a FongoDBCollection.

$gte throws Exception on non-Comparable

When Fongo applies $gte to a field value which doesn't implement Comparable, it throws exception: com.foursquare.fongo.FongoException: stored value expected to be of type java.lang.Comparable but is { "origin" : "ABC" , "key" : "KEY-2"}.

The same situation doesn't produce an error in Mongo. Mongo calculates the comparison result to false.

Example:

db.x.insert({a:{b:1, c:1}})
db.x.insert({a:2})
db.x.find()
{ "_id" : ObjectId("520cd390e829454261c64219"), "a" : { "b" : 1, "c" : 1 } }
{ "_id" : ObjectId("520cd39ce829454261c6421a"), "a" : 2 }
db.x.find({a:{$gte:2}})
{ "_id" : ObjectId("520cd39ce829454261c6421a"), "a" : 2 }

java.lang.ClassNotFoundException: com.mongodb.Cursor

I am getting a java.lang.ClassNotFoundException: com.mongodb.Cursor exception while trying to run a junit with fongo(1.5.5) and spring(3.2.4), I looked at the fongo code in github and could not find any reference to com.mongodb.Cursor class.

I even checked out the latest code and added 1.5.7-SNAPSHOT dependency in my code but still getting the same error.

$pull with $in operator does not work

Following test fails:

  @Test
  public void testEmbeddedPullWithInOperation() {
    UpdateEngine updateEngine = new UpdateEngine();
    DBObject update = new BasicDBObjectBuilder()
            .push("$pull").push("a").append("$in", Arrays.asList(Pattern.compile("a\\w+"))).pop().pop()
            .get();

    assertEquals(new BasicDBObject("a", Util.list("bb")),
        updateEngine.doUpdate(new BasicDBObject("a", Util.list("aa", "bb"
        )), update));
  }

fongo doesn't return nested fields in projections

I've tried code below in test. The nested field in projections are not returned:

considering inserted object is

{ "name" : "jon" , "seq" : [ { "a" : "b"}]}

and query

find({ "name" : "jon"}, { "seq.a" : 1}).

it returns

[{ "_id" : { "$oid" : "51f77b9b3004fb2bbe43a7c2"}}]

instead of expected result

DBCollection collection = newCollection();

BasicDBObject obj = new BasicDBObject("name", "jon").append("seq", Arrays.asList(new BasicDBObject("a", "b")));
collection.insert(obj);

DBCursor cursor = collection.find(new BasicDBObject("name", "jon"));

assertEquals("should have one record", 1, cursor.toArray().size());

DBCursor cursor2 = collection.find(new BasicDBObject("name", "jon"), new BasicDBObject("seq.a", 1));

System.out.println(cursor2.toArray());
assertEquals("should have one record", 1, cursor2.toArray().size());

Applying orderBy to a cursor yields no results at all

When you apply a sort order to a cursor, there are no results at all, even if the query without the sort applied would yield results.

The following test fails:

@Test
public void testFindWithQueryAndSort() {
    DBCollection collection = newCollection();
    collection.insert(new BasicDBObject("name", "neil").append("age", 10));
    collection.insert(new BasicDBObject("name", "jon").append("age", 9));
    collection.insert(new BasicDBObject("name", "neil").append("age", 8));
    collection.insert(new BasicDBObject("name", "leo").append("age", 7));

    DBCursor cursor = collection.find(new BasicDBObject("name", "neil"));
    cursor.sort(new BasicDBObject("age", 1));

    List<DBObject> results = cursor.toArray();
    assertEquals("should have two neils", 2, results.size());
    assertEquals("age of first result", 8, results.get(0).get("age"));
    assertEquals("age of second result", 10, results.get(1).get("age"));
}

findAndRemove fails on documents containing embedded lists

I think this is ultimately a bug with the Fongo filter generator, but going to go ahead and file this as it presented to me. Examples using JRuby for convenience.

Doing a findAndRemove which matches a record which contains an embedded list throws. As best as I can understand, findAndRemove passes the object directly to remove. remove then tries to generate a filter, and because a DBList is an subclass of DBObject, it tries to parse it as a special form query (specifically, ExpressionParser.java around line 321). Since DBList can only have integer keys, this throws:

[3] pry(main)> f = com.foursquare.fongo.Fongo.new('test')
=> #<Java::ComFoursquareFongo::Fongo:0x6481aa7a>
[4] pry(main)> coll = f.getDB('test').getCollection('test')
=> #<Java::ComMongodb::FongoDBCollection:0x2e86ae77>
[5] pry(main)> obj = com.mongodb.BasicDBObject.new
=> {}
[6] pry(main)> obj.put('_id', 'foo')
=> nil
[7] pry(main)> obj.put('alist', [])
=> nil
[8] pry(main)> coll.save(obj)
=> #<Java::ComMongodb::WriteResult:0x7942e612>
[9] pry(main)> coll.findAndRemove(com.mongodb.BasicDBObject.new('_id', 'foo'))
NativeException: java.lang.IllegalArgumentException: BasicBSONList can only work with numeric keys, not: [$not]
from org/bson/types/BasicBSONList.java:161:in `_getInt'

Just to make sure this wasn't expected, I tried this with the actual Mongo driver:

[10] pry(main)> m = com.mongodb.Mongo.new
=> #<Java::ComMongodb::Mongo:0xaefd4fb>
[11] pry(main)> coll = m.getDB('test').getCollection('test')
=> #<#<Class:0x68546d88>:0x22a0c2ca>
[12] pry(main)> coll.save(obj)
=> #<Java::ComMongodb::WriteResult:0x6eb6b89f>
[13] pry(main)> coll.findAndRemove(com.mongodb.BasicDBObject.new('_id', 'foo'))
=> {"_id"=>"foo", "alist"=>#<Java::ComMongodb::BasicDBList:0x2438de02>}

I suspect the right solution here is to check if the value is a DBList before trying to parse it as a DBObject. If that seems reasonable, I can try to sketch up a patch.

fongoDBCollection.rename("newname") results in CommandFailureException

Attempting to rename a collection using fongo throws an exception:

com.mongodb.CommandFailureException: { "serverUsed" : "localhost:27017" , "ok" : 0 , "errmsg" : "no such cmd: renameCollection"}
    at com.mongodb.CommandResult.getException(CommandResult.java:76)
    at com.mongodb.CommandResult.throwOnError(CommandResult.java:140)
    at com.mongodb.DBCollection.rename(DBCollection.java:1314)
    ...

This method appears to be unimplemented (the generated command is unhandled anyway). It'd be handy if it worked, and without knowing anything about the internals of fongo, it seems like it might be an easy one to add :-)

findAndModify() returns nested properties of the updated object instead of the original object

If you call findAndModify() with the parameter new set to false the driver should return the original object as before the update.

The code basically tries to implement this, but fails with nested properties.

Example

Before

{
    _id: 1,
    foo: 'bar',
    property: {
          value: "a"
    }
}

Update

db.collection.findAndModify({
    query: { _id: 1 },
    update: { 'foo': 'xxx', 'property.value': 'b' }
})

Expected

same as before

Actual

{
    _id: 1,
    foo: 'bar',
    property: {
          value: 'b'
    }
}

The property foo is returned correctly with the old value, however the property property.value has the new value.

fongo - order by not work

Hello. Fongo not work order by.

Example used spring-data

@document
public class Test {

public Test(String id) {
    this.id = id;
}

@Id
private String id;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

}

@Test
public void test(){
    mongoRepository.save(new Test("a"));
    mongoRepository.save(new Test("z"));
    mongoRepository.save(new Test("x"));
    mongoRepository.save(new Test("c"));
    mongoRepository.save(new Test("v"));

    mongoRepository.findAll(new PageRequest(0,10, Sort.Direction.DESC,"id"));
    mongoRepository.findOrderById()
}

-Found content 0.

MongoClient doesn't return correct MongoOptions and MongoClientOptions

Hi,

MockMongoClient retun null for both methods.

Why using Objenesis, I don't understand ?

I try with a very simple :

 public static MockMongoClient create(Fongo fongo) {
    try {
      MockMongoClient client = new MockMongoClient();
      client.setFongo(fongo);
      return client;
    } catch (UnknownHostException uhe) {
      throw new RuntimeException(uhe);
    }
  }

and all tests are green ?

FongoDBCollection.idsIn(DBObject) throws ClassCastException

Firstly, thank you so much for this framework, it's made my life so much easier!

When executing MongoTemplate.find(Query.query(Criteria.where("id").in(ids)), class) using Fongo I get the below exception as an Object[] is being cast to a List.

Offending Lines

     else if (idValue instanceof DBObject ){
          DBObject idDbObject = (DBObject)idValue;
          List inList = (List)idDbObject.get(ExpressionParser.IN);

Exception:

    java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.util.List
        at com.mongodb.FongoDBCollection.idsIn(FongoDBCollection.java:228)
        at com.mongodb.FongoDBCollection.__find(FongoDBCollection.java:349)
        at com.mongodb.DBCursor._check(DBCursor.java:368)
        at com.mongodb.DBCursor._hasNext(DBCursor.java:459)
        at com.mongodb.DBCursor.hasNext(DBCursor.java:484)
        at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1541)
        at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1347)
        at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1333)
        at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:505)
        at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:500)
        at com.im.sonic.data.spi.service.AbstractServiceImpl.findAll(AbstractServiceImpl.java:88)
        at com.im.sonic.data.spi.service.AuthorServiceImpleTest.testFindAll(AuthorServiceImpleTest.java:118)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
        at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
        at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

fongo should throw an exception when inserting duplicate keys

When performing an "insert", mongo does not allow duplicate keys. If an object with the same key already exists in the database, mongo will throw an exception (com.mongodb.MongoException.DuplicateKey). Fongo does not duplicate this behavior.

Can you create a new release of Fongo?

I submitted a ticket a while ago for a bug fix (#75). It looks like the work has already been done, but I have not seen a new release in while. Would you be able to release a new version of Fongo with this fix in it? Thanks!

Fongo should be able to handle $in clause for Sets (and anything else that Mongo supports)

Fongo throws an exception when using an $in clause with a Set. For example:

Set<String> mySet = new HashSet<>();
mySet.add("ABC");

BasicDBOjbect query = new BasicDBobject("i", 
                               new BasicDBObject("$in", mySet) );

cursor = coll.find(query);
....

This works with a real Mongo database, but not with Fongo. Fongo throws an exception "$in clause expected to be of type java.util.List but was ...."

I don't know all the types that the Mongo java driver supports for the $in clause (I couldn't find any documentation on it), but perhaps java.util.Collection would be the best choice for Fongo to support. That should pretty much catch everything, and Collection specifies a contains() method that could be used for $in.

Also, as an aside, the exception message (which comes from ExpressionParser.java:142) is very confusing because it lists the expected type, but not the actual type. It just uses the toString to print out the contents of the object. It would be nice if it said something like this:

fieldName + " expected to be of type " + clazz.getName() + " but is " + (obj!=null ? obj.getName() : null) + " toString is: " + obj

That would protect against nulls as well as providing a better error message. It is nice to have both the type, which is what caused the error, as well as the value (if it implemented toString) to help pinpoint what went wrong.

DBCollection.findAndRemove() throws an Exception instead of returning null

If DBCollection.findAndRemove() does not find matching objects, it fails with a "java.lang.IllegalArgumentException: Don't know how to clone: null" in com.foursquare.fongo.impl.Util.clone().

The MongoDB driver instead returns null in this case.

Example:

DBObject query = new BasicDBObject("does", "notexist"); // matching objects do not exist in coll
coll.findAndRemove(query); // Fongo driver throws an exception, MongoDB driver returns null

Exception:
java.lang.IllegalArgumentException: Don't know how to clone: null
at com.foursquare.fongo.impl.Util.clone(Util.java:51)
at com.mongodb.FongoDBCollection.findAndModify(FongoDBCollection.java:585)

findAndRemove() calls findAndModify(), which tries to return a clone of either the beforeObject or the afterObject:

if (returnNew){
  return Util.clone(afterObject);
} else {
  return Util.clone(beforeObject);
}

In the case of findAndRemove() with no matching objects, it tries to clone beforeObject, which is null.

Solution 1: handle nulls gracefully in com.foursquare.fongo.impl.Util.clone()
Solution 2: check for null in com.mongodb.FongoDBCollection.findAndModify()

regex operator matches nothing when pattern matching on multiple lines

Tried both with Fongo 1.0.9 and 1.1.0.

I'm trying to use $regex (http://docs.mongodb.org/manual/reference/operator/regex/) in a way like this (MongoDB shell):

// multiline text that I will match:

db.testdata.insert({ text: "one\ntwo\nthree"})

// single line text for comparison:

db.testdata.insert({ text: "one 2two 3three"})

// no 's' option so dot does not match new line characters:

db.testdata.find({ text: {$regex: 'one.two.'}})
{ "_id" : ObjectId("51b53a609b7dcea0d4150460"), "text" : "one 2two 3three" }

// this and the rest use 's' and other options and match properly:
db.testdata.find({ text: {$regex: 'one.two.', $options: 's'}})
{ "_id" : ObjectId("51b53a209b7dcea0d415045f"), "text" : "one\ntwo\nthree" }
{ "_id" : ObjectId("51b53a609b7dcea0d4150460"), "text" : "one 2two 3three" }

db.testdata.find({ text: {$regex: 'one.two.', $options: 'sm'}})
{ "_id" : ObjectId("51b53a209b7dcea0d415045f"), "text" : "one\ntwo\nthree" }
{ "_id" : ObjectId("51b53a609b7dcea0d4150460"), "text" : "one 2two 3three" }

db.testdata.find({ text: {$regex: 'one.two.', $options: 'disum'}})
{ "_id" : ObjectId("51b53a209b7dcea0d415045f"), "text" : "one\ntwo\nthree" }
{ "_id" : ObjectId("51b53a609b7dcea0d4150460"), "text" : "one 2two 3three" }

The problem with Fongo is that document matches only when regex is on a single line, i.e. from the examples 'two' will match, but 'one.two.' will match nothing.

Just FYI I'm using:
CASE_INSENSITIVE | DOTALL | UNIX_LINES | UNICODE_CHARACTER_CLASS | UNICODE_CASE | MULTILINE
from java.util.regex.Pattern when compiling pattern. I use it after with 'matches' in Rogue DSL which works fine on real MongoDB.

Thanks!

Compatibility with Jongo

I tested the latest Fongo version 1.2.0 and I noticed that there is an incompatibility with the Jongo library (http://jongo.org/) that I also use. I think it is due to the cloning of DB objects which doesn't work in this case.

Here is a unit test to reproduce the problem:

static class FongoJongoBean {
    private String str;
    private int num;
}

@Test
public void testFongoJongo() {
    Fongo fongo = new Fongo("Mocked Mongo server");
    Jongo jongo = new Jongo(fongo.getDB("test"));

    MongoCollection coll = jongo.getCollection("coll");

    coll.save(new FongoJongoBean());

    Iterator<FongoJongoBean> it = coll.find().as(FongoJongoBean.class).iterator();
    while (it.hasNext()) {
        System.out.println("obj=" + it.next());
    }
}

The code throws this exception:

java.lang.IllegalArgumentException: Don't know how to clone: { "num" : 0 , "_id" : null }
at com.foursquare.fongo.impl.Util.clone(Util.java:51)
at com.mongodb.FongoDBCollection.copyResults(FongoDBCollection.java:413)
at com.mongodb.FongoDBCollection.__find(FongoDBCollection.java:401)
at com.mongodb.DBCursor._check(DBCursor.java:368)
at com.mongodb.DBCursor._hasNext(DBCursor.java:459)
at com.mongodb.DBCursor.hasNext(DBCursor.java:484)
at org.jongo.MongoIterator.hasNext(MongoIterator.java:36)

The object given to Util has a type org.jongo.Insert$AlreadyCheckedDBObject which extends com.mongodb.LazyWriteableDBObject.

Could Util be enhanced to support this kind of objects?

Note: I'm also using a pre-release of Jongo 0.5. Here are my pom.xml:

    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>2.11.2</version>
    </dependency>

    <dependency>
        <groupId>com.foursquare</groupId>
        <artifactId>fongo</artifactId>
        <version>1.2.0</version>
    </dependency>

    <dependency>
        <groupId>org.jongo</groupId>
        <artifactId>jongo</artifactId>
        <version>0.5-early-20130912-1506</version>
    </dependency>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.