mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
Preserve old id on ipdate with no id spec
This commit is contained in:
parent
b4976fcb19
commit
48cfea2b1a
@ -337,7 +337,7 @@ namespace mongo {
|
||||
*/
|
||||
int woCompare( const BSONElement &e, bool considerFieldName = true ) const;
|
||||
|
||||
const char * rawdata() {
|
||||
const char * rawdata() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -356,7 +356,7 @@ namespace mongo {
|
||||
type() == CodeWScope;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
// If maxLen is specified, don't scan more than maxLen bytes.
|
||||
BSONElement(const char *d, int maxLen = -1) : data(d) {
|
||||
if ( eoo() )
|
||||
@ -372,6 +372,7 @@ namespace mongo {
|
||||
}
|
||||
totalSize = -1;
|
||||
}
|
||||
private:
|
||||
const char *data;
|
||||
int fieldNameSize;
|
||||
mutable int totalSize; /* caches the computed size */
|
||||
|
@ -677,14 +677,15 @@ namespace mongo {
|
||||
|
||||
NamespaceDetails *d = nsdetails(ns);
|
||||
|
||||
BSONObj objOld(toupdate);
|
||||
BSONElement idOld;
|
||||
int addID = 0;
|
||||
{
|
||||
/* duplicate _id check... */
|
||||
BSONObj objNew(buf);
|
||||
BSONObj objOld(toupdate);
|
||||
BSONElement idNew;
|
||||
objOld.getObjectID(idOld);
|
||||
if( objNew.getObjectID(idNew) ) {
|
||||
BSONElement idOld;
|
||||
objOld.getObjectID(idOld);
|
||||
if( idOld == idNew )
|
||||
;
|
||||
else {
|
||||
@ -699,8 +700,12 @@ namespace mongo {
|
||||
!Helpers::findOne(ns, b.done(), result));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( !idOld.eoo() ) {
|
||||
addID = len;
|
||||
len += idOld.size();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( toupdate->netLength() < len ) {
|
||||
@ -715,7 +720,7 @@ namespace mongo {
|
||||
if ( database->profile )
|
||||
ss << " moved ";
|
||||
deleteRecord(ns, toupdate, dl);
|
||||
insert(ns, buf, len);
|
||||
insert(ns, buf, len, false, idOld);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -770,7 +775,13 @@ namespace mongo {
|
||||
}
|
||||
|
||||
// update in place
|
||||
memcpy(toupdate->data, buf, len);
|
||||
if ( addID ) {
|
||||
((int&)*toupdate->data) = *((int*) buf) + idOld.size();
|
||||
memcpy(toupdate->data+4, idOld.rawdata(), idOld.size());
|
||||
memcpy(toupdate->data+4+idOld.size(), ((char *)buf)+4, addID-4);
|
||||
} else {
|
||||
memcpy(toupdate->data, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
int followupExtentSize(int len, int lastExtentLen) {
|
||||
@ -892,19 +903,22 @@ namespace mongo {
|
||||
}
|
||||
|
||||
#pragma pack(1)
|
||||
struct IDToInsert {
|
||||
struct IDToInsert_ {
|
||||
char type;
|
||||
char _id[4];
|
||||
OID oid;
|
||||
IDToInsert() {
|
||||
IDToInsert_() {
|
||||
type = (char) jstOID;
|
||||
strcpy(_id, "_id");
|
||||
assert( sizeof(IDToInsert) == 17 );
|
||||
assert( sizeof(IDToInsert_) == 17 );
|
||||
}
|
||||
} idToInsert_;
|
||||
struct IDToInsert : public BSONElement {
|
||||
IDToInsert() : BSONElement( ( char * )( &idToInsert_ ) ) {}
|
||||
} idToInsert;
|
||||
#pragma pack()
|
||||
|
||||
DiskLoc DataFileMgr::insert(const char *ns, const void *obuf, int len, bool god) {
|
||||
|
||||
DiskLoc DataFileMgr::insert(const char *ns, const void *obuf, int len, bool god, const BSONElement &writeId) {
|
||||
bool addIndex = false;
|
||||
const char *sys = strstr(ns, "system.");
|
||||
if ( sys ) {
|
||||
@ -988,6 +1002,7 @@ namespace mongo {
|
||||
//indexFullNS += name; // database.table.$index -- note this doesn't contain jsobjs, it contains BtreeBuckets.
|
||||
}
|
||||
|
||||
const BSONElement *newId = &writeId;
|
||||
int addID = 0;
|
||||
if( !god ) {
|
||||
/* Check if we have an _id field. If we don't, we'll add it.
|
||||
@ -996,7 +1011,12 @@ namespace mongo {
|
||||
BSONObj io((const char *) obuf);
|
||||
if( !io.hasField("_id") && !addIndex && strstr(ns, ".local.") == 0 ) {
|
||||
addID = len;
|
||||
len += sizeof(IDToInsert);
|
||||
if ( writeId.eoo() ) {
|
||||
// Very likely we'll add this elt, so little harm in init'ing here.
|
||||
idToInsert_.oid.init();
|
||||
newId = &idToInsert;
|
||||
}
|
||||
len += newId->size();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1028,10 +1048,9 @@ namespace mongo {
|
||||
assert( r->lengthWithHeaders >= lenWHdr );
|
||||
if( addID ) {
|
||||
/* a little effort was made here to avoid a double copy when we add an ID */
|
||||
idToInsert.oid.init();
|
||||
((int&)*r->data) = *((int*) obuf) + sizeof(idToInsert);
|
||||
memcpy(r->data+4, &idToInsert, sizeof(idToInsert));
|
||||
memcpy(r->data+4+sizeof(idToInsert), ((char *)obuf)+4, addID-4);
|
||||
((int&)*r->data) = *((int*) obuf) + newId->size();
|
||||
memcpy(r->data+4, newId->rawdata(), newId->size());
|
||||
memcpy(r->data+4+newId->size(), ((char *)obuf)+4, addID-4);
|
||||
// TEMP:
|
||||
BSONObj foo(r->data);
|
||||
cout << "TEMP:" << foo.toString() << endl;
|
||||
|
@ -87,7 +87,7 @@ namespace mongo {
|
||||
const char *ns,
|
||||
Record *toupdate, const DiskLoc& dl,
|
||||
const char *buf, int len, stringstream& profiling);
|
||||
DiskLoc insert(const char *ns, const void *buf, int len, bool god = false);
|
||||
DiskLoc insert(const char *ns, const void *buf, int len, bool god = false, const BSONElement &writeId = BSONElement());
|
||||
void deleteRecord(const char *ns, Record *todelete, const DiskLoc& dl, bool cappedOK = false);
|
||||
static auto_ptr<Cursor> findAll(const char *ns);
|
||||
|
||||
|
18
jstests/autoid.js
Normal file
18
jstests/autoid.js
Normal file
@ -0,0 +1,18 @@
|
||||
p = function( o ) {
|
||||
print( tojson( o ) );
|
||||
}
|
||||
|
||||
f = db.jstests_autoid;
|
||||
f.drop();
|
||||
|
||||
f.save( {z:1} );
|
||||
a = f.findOne( {z:1} );
|
||||
p( a );
|
||||
f.update( {z:1}, {z:2} );
|
||||
b = f.findOne( {z:2} );
|
||||
p( b );
|
||||
//assert.eq( a._id, b._id );
|
||||
c = f.update( {z:2}, {z:"abcdefgabcdefgabcdefg"} );
|
||||
c = f.findOne( {} );
|
||||
p( c );
|
||||
//assert.eq( a._id, c._id );
|
@ -175,6 +175,7 @@
|
||||
93A8D20F0F37544800C92B85 /* update.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = update.js; sourceTree = "<group>"; };
|
||||
93A8D2100F37544800C92B85 /* update2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = update2.js; sourceTree = "<group>"; };
|
||||
93A8D2110F37544800C92B85 /* where1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = where1.js; sourceTree = "<group>"; };
|
||||
93A8D8200F38FE2400C92B85 /* autoid.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = autoid.js; sourceTree = "<group>"; };
|
||||
93AF75500F216D0300994C66 /* jsontests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = jsontests.cpp; sourceTree = "<group>"; };
|
||||
93B4A81A0F1C01B4000C862C /* security.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = security.cpp; sourceTree = "<group>"; };
|
||||
93B4A81B0F1C01D8000C862C /* lasterror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = lasterror.cpp; sourceTree = "<group>"; };
|
||||
@ -391,6 +392,7 @@
|
||||
93A8D1D10F37544800C92B85 /* jstests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
93A8D8200F38FE2400C92B85 /* autoid.js */,
|
||||
93A8D1D30F37544800C92B85 /* _runner.js */,
|
||||
93A8D1D40F37544800C92B85 /* apitest_db.js */,
|
||||
93A8D1D50F37544800C92B85 /* apitest_dbcollection.js */,
|
||||
|
Loading…
Reference in New Issue
Block a user