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:
parent
6ac50f8e9e
commit
b32a47826e
@ -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;
|
||||
}
|
||||
|
||||
|
30
db/update.h
30
db/update.h
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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" );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user