00001
00002
00019 #pragma once
00020
00021 #include "../pch.h"
00022 #include "diskloc.h"
00023 #include "jsobj.h"
00024 #include "indexkey.h"
00025
00026 namespace mongo {
00027
00028
00029
00030
00031
00032
00033
00034 class IndexDetails {
00035 public:
00043 DiskLoc head;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 DiskLoc info;
00055
00056
00057
00058
00059
00060 BSONObj getKeyFromQuery(const BSONObj& query) const {
00061 BSONObj k = keyPattern();
00062 BSONObj res = query.extractFieldsUnDotted(k);
00063 return res;
00064 }
00065
00066
00067
00068
00069
00070
00071 void getKeysFromObject( const BSONObj& obj, BSONObjSetDefaultOrder& keys) const;
00072
00073
00074
00075
00076 BSONObj keyPattern() const {
00077 return info.obj().getObjectField("key");
00078 }
00079
00084 int keyPatternOffset( const string& key ) const;
00085 bool inKeyPattern( const string& key ) const { return keyPatternOffset( key ) >= 0; }
00086
00087
00088 bool hasKey(const BSONObj& key);
00089 bool wouldCreateDup(const BSONObj& key, DiskLoc self);
00090
00091
00092
00093 string indexNamespace() const {
00094 BSONObj io = info.obj();
00095 string s;
00096 s.reserve(Namespace::MaxNsLen);
00097 s = io.getStringField("ns");
00098 assert( !s.empty() );
00099 s += ".$";
00100 s += io.getStringField("name");
00101 return s;
00102 }
00103
00104 string indexName() const {
00105 BSONObj io = info.obj();
00106 return io.getStringField("name");
00107 }
00108
00109 static bool isIdIndexPattern( const BSONObj &pattern ) {
00110 BSONObjIterator i(pattern);
00111 BSONElement e = i.next();
00112 if( strcmp(e.fieldName(), "_id") != 0 ) return false;
00113 return i.next().eoo();
00114 }
00115
00116
00117 bool isIdIndex() const {
00118 return isIdIndexPattern( keyPattern() );
00119 }
00120
00121
00122
00123
00124 string parentNS() const {
00125 BSONObj io = info.obj();
00126 return io.getStringField("ns");
00127 }
00128
00129 bool unique() const {
00130 BSONObj io = info.obj();
00131 return io["unique"].trueValue() ||
00132
00133 isIdIndex();
00134 }
00135
00136
00137 bool dropDups() const {
00138 return info.obj().getBoolField( "dropDups" );
00139 }
00140
00141
00142
00143
00144 void kill_idx();
00145
00146 const IndexSpec& getSpec() const;
00147
00148 string toString() const {
00149 return info.obj().toString();
00150 }
00151 };
00152
00153 struct IndexChanges {
00154 BSONObjSetDefaultOrder oldkeys;
00155 BSONObjSetDefaultOrder newkeys;
00156 vector<BSONObj*> removed;
00157 vector<BSONObj*> added;
00158
00162 void dupCheck(IndexDetails& idx, DiskLoc curObjLoc) {
00163 if( added.empty() || !idx.unique() )
00164 return;
00165 for( vector<BSONObj*>::iterator i = added.begin(); i != added.end(); i++ ) {
00166 bool dup = idx.wouldCreateDup(**i, curObjLoc);
00167 uassert( 11001 , "E11001 duplicate key on update", !dup);
00168 }
00169 }
00170 };
00171
00172 class NamespaceDetails;
00173
00174 void getIndexChanges(vector<IndexChanges>& v, NamespaceDetails& d, BSONObj newObj, BSONObj oldObj, bool &cangedId);
00175 void dupCheck(vector<IndexChanges>& v, NamespaceDetails& d, DiskLoc curObjLoc);
00176 }