00001 // lasterror.h 00002 00003 /* Copyright 2009 10gen Inc. 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #pragma once 00019 00020 #include "../bson/oid.h" 00021 00022 namespace mongo { 00023 class BSONObjBuilder; 00024 class Message; 00025 00026 struct LastError { 00027 int code; 00028 string msg; 00029 enum UpdatedExistingType { NotUpdate, True, False } updatedExisting; 00030 OID upsertedId; 00031 OID writebackId; 00032 long long nObjects; 00033 int nPrev; 00034 bool valid; 00035 bool disabled; 00036 void writeback( OID& oid ) { 00037 reset( true ); 00038 writebackId = oid; 00039 } 00040 void raiseError(int _code , const char *_msg) { 00041 reset( true ); 00042 code = _code; 00043 msg = _msg; 00044 } 00045 void recordUpdate( bool _updateObjects , long long _nObjects , OID _upsertedId ) { 00046 reset( true ); 00047 nObjects = _nObjects; 00048 updatedExisting = _updateObjects ? True : False; 00049 if ( _upsertedId.isSet() ) 00050 upsertedId = _upsertedId; 00051 00052 } 00053 void recordDelete( long long nDeleted ) { 00054 reset( true ); 00055 nObjects = nDeleted; 00056 } 00057 LastError() { 00058 reset(); 00059 } 00060 void reset( bool _valid = false ) { 00061 code = 0; 00062 msg.clear(); 00063 updatedExisting = NotUpdate; 00064 nObjects = 0; 00065 nPrev = 1; 00066 valid = _valid; 00067 disabled = false; 00068 upsertedId.clear(); 00069 writebackId.clear(); 00070 } 00071 00075 bool appendSelf( BSONObjBuilder &b , bool blankErr = true ); 00076 00077 struct Disabled : boost::noncopyable { 00078 Disabled( LastError * le ) { 00079 _le = le; 00080 if ( _le ) { 00081 _prev = _le->disabled; 00082 _le->disabled = true; 00083 } 00084 else { 00085 _prev = false; 00086 } 00087 } 00088 00089 ~Disabled() { 00090 if ( _le ) 00091 _le->disabled = _prev; 00092 } 00093 00094 LastError * _le; 00095 bool _prev; 00096 }; 00097 00098 static LastError noError; 00099 }; 00100 00101 extern class LastErrorHolder { 00102 public: 00103 LastErrorHolder(){} 00104 ~LastErrorHolder(); 00105 00106 LastError * get( bool create = false ); 00107 LastError * getSafe() { 00108 LastError * le = get(false); 00109 if ( ! le ) { 00110 error() << " no LastError!" << endl; 00111 assert( le ); 00112 } 00113 return le; 00114 } 00115 00116 LastError * _get( bool create = false ); // may return a disabled LastError 00117 00118 void reset( LastError * le ); 00119 00121 void initThread(); 00122 00123 int getID(); 00124 00125 void release(); 00126 00128 LastError * startRequest( Message& m , LastError * connectionOwned ); 00129 00130 void disconnect( int clientId ); 00131 00132 // used to disable lastError reporting while processing a killCursors message 00133 // disable causes get() to return 0. 00134 LastError *disableForCommand(); // only call once per command invocation! 00135 private: 00136 boost::thread_specific_ptr<LastError> _tl; 00137 00138 struct Status { 00139 time_t time; 00140 LastError *lerr; 00141 }; 00142 } lastError; 00143 00144 void raiseError(int code , const char *msg); 00145 00146 } // namespace mongo