diff options
Diffstat (limited to 'src/mongo/db/namespacestring.h')
-rw-r--r-- | src/mongo/db/namespacestring.h | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/mongo/db/namespacestring.h b/src/mongo/db/namespacestring.h new file mode 100644 index 00000000000..d982c5fff75 --- /dev/null +++ b/src/mongo/db/namespacestring.h @@ -0,0 +1,147 @@ +// @file namespacestring.h + +/** +* Copyright (C) 2008 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <string> + +namespace mongo { + + using std::string; + + /* in the mongo source code, "client" means "database". */ + + const int MaxDatabaseNameLen = 256; // max str len for the db name, including null char + + /* e.g. + NamespaceString ns("acme.orders"); + cout << ns.coll; // "orders" + */ + class NamespaceString { + public: + string db; + string coll; // note collection names can have periods in them for organizing purposes (e.g. "system.indexes") + + NamespaceString( const char * ns ) { init(ns); } + NamespaceString( const string& ns ) { init(ns.c_str()); } + + string ns() const { return db + '.' + coll; } + + bool isSystem() const { return strncmp(coll.c_str(), "system.", 7) == 0; } + bool isCommand() const { return coll == "$cmd"; } + + operator string() const { return ns(); } + + bool operator==( const string& nsIn ) const { return nsIn == ns(); } + bool operator==( const char* nsIn ) const { return (string)nsIn == ns(); } + bool operator==( const NamespaceString& nsIn ) const { return nsIn.db == db && nsIn.coll == coll; } + + bool operator!=( const string& nsIn ) const { return nsIn != ns(); } + bool operator!=( const char* nsIn ) const { return (string)nsIn != ns(); } + bool operator!=( const NamespaceString& nsIn ) const { return nsIn.db != db || nsIn.coll != coll; } + + string toString() const { return ns(); } + + /** + * @return true if ns is 'normal'. $ used for collections holding index data, which do not contain BSON objects in their records. + * special case for the local.oplog.$main ns -- naming it as such was a mistake. + */ + static bool normal(const char* ns) { + const char *p = strchr(ns, '$'); + if( p == 0 ) + return true; + return strcmp( ns, "local.oplog.$main" ) == 0; + } + + static bool special(const char *ns) { + return !normal(ns) || strstr(ns, ".system."); + } + + /** + * samples: + * good: + * foo + * bar + * foo-bar + * bad: + * foo bar + * foo.bar + * foo"bar + * + * @param db - a possible database name + * @return if db is an allowed database name + */ + static bool validDBName( const string& db ) { + if ( db.size() == 0 || db.size() > 64 ) + return false; + size_t good = strcspn( db.c_str() , "/\\. \"" ); + return good == db.size(); + } + + /** + * samples: + * good: + * foo.bar + * bad: + * foo. + * + * @param dbcoll - a possible collection name of the form db.coll + * @return if db.coll is an allowed collection name + */ + static bool validCollectionName(const char* dbcoll){ + const char *c = strchr( dbcoll, '.' ) + 1; + return normal(dbcoll) && c && *c; + } + + private: + void init(const char *ns) { + const char *p = strchr(ns, '.'); + if( p == 0 ) return; + db = string(ns, p - ns); + coll = p + 1; + } + }; + + // "database.a.b.c" -> "database" + inline void nsToDatabase(const char *ns, char *database) { + const char *p = ns; + char *q = database; + while ( *p != '.' ) { + if ( *p == 0 ) + break; + *q++ = *p++; + } + *q = 0; + if (q-database>=MaxDatabaseNameLen) { + log() << "nsToDatabase: ns too long. terminating, buf overrun condition" << endl; + dbexit( EXIT_POSSIBLE_CORRUPTION ); + } + } + inline string nsToDatabase(const char *ns) { + char buf[MaxDatabaseNameLen]; + nsToDatabase(ns, buf); + return buf; + } + inline string nsToDatabase(const string& ns) { + size_t i = ns.find( '.' ); + if ( i == string::npos ) + return ns; + return ns.substr( 0 , i ); + } + +} |