summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2009-02-03 19:13:27 -0500
committerAaron <aaron@10gen.com>2009-02-03 19:13:27 -0500
commit48cfea2b1afd3fcc2ec5d0f423c9d952bae1f71c (patch)
treef5f0ec9c876518b686841cd245ba4558bfdf7f07 /db
parentb4976fcb194d2ba5cbea9b5959ea448eea374607 (diff)
downloadmongo-48cfea2b1afd3fcc2ec5d0f423c9d952bae1f71c.tar.gz
Preserve old id on ipdate with no id spec
Diffstat (limited to 'db')
-rw-r--r--db/jsobj.h5
-rw-r--r--db/pdfile.cpp51
-rw-r--r--db/pdfile.h2
3 files changed, 39 insertions, 19 deletions
diff --git a/db/jsobj.h b/db/jsobj.h
index bcd729b6518..c133b8db203 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -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 */
diff --git a/db/pdfile.cpp b/db/pdfile.cpp
index 3515174f50d..226e37375f3 100644
--- a/db/pdfile.cpp
+++ b/db/pdfile.cpp
@@ -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;
diff --git a/db/pdfile.h b/db/pdfile.h
index 5358b91bfbd..7dc870adcfb 100644
--- a/db/pdfile.h
+++ b/db/pdfile.h
@@ -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);