0
0
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:
Aaron 2009-02-03 19:13:27 -05:00
parent b4976fcb19
commit 48cfea2b1a
5 changed files with 59 additions and 19 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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
View 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 );

View File

@ -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 */,