0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 00:56:44 +01:00

$addToSet : { $each : ... } SERVER-628

This commit is contained in:
Eliot Horowitz 2010-02-27 22:05:59 -05:00
parent 6ac50f8e9e
commit b32a47826e
3 changed files with 100 additions and 27 deletions

View File

@ -102,25 +102,48 @@ namespace mongo {
bb.done();
break;
}
case ADDTOSET: {
uassert( 12592 , "$addToSet can only be applied to an array" , in.type() == Array );
BSONObjBuilder bb( b.subarrayStart( shortFieldName ) );
BSONObjIterator i( in.embeddedObject() );
bool found = false;
int n=0;
while ( i.more() ){
BSONElement cur = i.next();
bb.append( cur );
n++;
if ( elt.woCompare( cur , false ) == 0 )
found = true;
int n=0;
if ( isEach() ){
BSONElementSet toadd;
parseEach( toadd );
while ( i.more() ){
BSONElement cur = i.next();
bb.append( cur );
n++;
toadd.erase( cur );
}
for ( BSONElementSet::iterator j=toadd.begin(); j!=toadd.end(); j++ ){
bb.appendAs( *j , BSONObjBuilder::numStr( n++ ) );
}
}
else {
bool found = false;
while ( i.more() ){
BSONElement cur = i.next();
bb.append( cur );
n++;
if ( elt.woCompare( cur , false ) == 0 )
found = true;
}
if ( ! found )
bb.appendAs( elt , bb.numStr( n ) );
}
if ( ! found )
bb.appendAs( elt , bb.numStr( n ) );
bb.done();
break;
}
@ -340,17 +363,28 @@ namespace mongo {
case Mod::ADDTOSET: {
uassert( 12591 , "Cannot apply $addToSet modifier to non-array", e.type() == Array || e.eoo() );
BSONObjIterator i( e.embeddedObject() );
bool found = false;
while( i.more() ) {
BSONElement arrI = i.next();
if ( arrI.woCompare( m.elt , false ) == 0 ){
found = true;
break;
if ( m.isEach() ){
BSONElementSet toadd;
m.parseEach( toadd );
while( i.more() ) {
BSONElement arrI = i.next();
toadd.erase( arrI );
}
mss->amIInPlacePossible( toadd.size() == 0 );
}
else {
bool found = false;
while( i.more() ) {
BSONElement arrI = i.next();
if ( arrI.woCompare( m.elt , false ) == 0 ){
found = true;
break;
}
}
mss->amIInPlacePossible( found );
}
mss->amIInPlacePossible( found );
break;
}

View File

@ -132,6 +132,25 @@ namespace mongo {
}
}
bool isEach() const {
if ( elt.type() != Object )
return false;
BSONElement e = elt.embeddedObject().firstElement();
if ( e.type() != Array )
return false;
return strcmp( e.fieldName() , "$each" ) == 0;
}
BSONObj getEach() const {
return elt.embeddedObjectUserCheck().firstElement().embeddedObjectUserCheck();
}
void parseEach( BSONElementSet& s ) const {
BSONObjIterator i(getEach());
while ( i.more() ){
s.insert( i.next() );
}
}
};
/**
@ -408,9 +427,14 @@ namespace mongo {
case Mod::PUSH:
case Mod::ADDTOSET: {
BSONObjBuilder arr( b.subarrayStart( m.shortFieldName ) );
arr.appendAs( m.elt, "0" );
arr.done();
if ( m.isEach() ){
b.appendArray( m.shortFieldName , m.getEach() );
}
else {
BSONObjBuilder arr( b.subarrayStart( m.shortFieldName ) );
arr.appendAs( m.elt, "0" );
arr.done();
}
break;
}

View File

@ -15,12 +15,27 @@ t.update( {} , { $addToSet : { a : 3 } } );
assert.eq( o , t.findOne() , "A3" );
// SERVER-628
// t.update( {} , { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } } );
t.update( {} , { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } } );
o.a.push( 5 )
o.a.push( 6 )
assert.eq( o , t.findOne() , "B1" )
t.drop()
o = { _id : 1 , a : [ 3 , 5 , 6 ] }
t.insert( o );
t.update( {} , { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } } );
assert.eq( o , t.findOne() , "B2" );
t.drop();
t.update( { _id : 1 } , { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } } , true );
assert.eq( o , t.findOne() , "B3" );
t.update( { _id : 1 } , { $addToSet : { a : { $each : [ 3 , 5 , 6 ] } } } , true );
assert.eq( o , t.findOne() , "B4" );
// SERVER-630
t.drop();
t.update( { _id : 2 } , { $addToSet : { a : 3 } } , true );
assert.eq( 1 , t.count() , "B1" );
assert.eq( { _id : 2 , a : [ 3 ] } , t.findOne() , "B2" );
assert.eq( 1 , t.count() , "C1" );
assert.eq( { _id : 2 , a : [ 3 ] } , t.findOne() , "C2" );