summaryrefslogtreecommitdiff
path: root/src/mongo/db/namespace_string.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/namespace_string.h')
-rw-r--r--src/mongo/db/namespace_string.h513
1 files changed, 278 insertions, 235 deletions
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 655dbf68a73..cd1067b7b45 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -38,271 +38,314 @@
namespace mongo {
- /* in the mongo source code, "client" means "database". */
-
- const size_t MaxDatabaseNameLen = 128; // max str len for the db name, including null char
-
- /** @return true if a client can modify this namespace even though it is under ".system."
- For example <dbname>.system.users is ok for regular clients to update.
- @param write used when .system.js
- */
- bool legalClientSystemNS( StringData ns , bool write );
-
- /* e.g.
- NamespaceString ns("acme.orders");
- cout << ns.coll; // "orders"
- */
- class NamespaceString {
- public:
- /**
- * Constructs an empty NamespaceString.
- */
- NamespaceString();
-
- /**
- * Constructs a NamespaceString from the fully qualified namespace named in "ns".
- */
- explicit NamespaceString( StringData ns );
-
- /**
- * Constructs a NamespaceString for the given database and collection names.
- * "dbName" must not contain a ".", and "collectionName" must not start with one.
- */
- NamespaceString( StringData dbName, StringData collectionName );
-
- /**
- * Note that these values are derived from the mmap_v1 implementation and that
- * is the only reason they are constrained as such.
- */
- enum MaxNsLenValue {
- // Maximum possible length of name any namespace, including special ones like $extra.
- // This includes rum for the NUL byte so it can be used when sizing buffers.
- MaxNsLenWithNUL = 128,
-
- // MaxNsLenWithNUL excluding the NUL byte. Use this when comparing std::string lengths.
- MaxNsLen = MaxNsLenWithNUL - 1,
-
- // Maximum allowed length of fully qualified namespace name of any real collection.
- // Does not include NUL so it can be directly compared to std::string lengths.
- MaxNsCollectionLen = MaxNsLen - 7/*strlen(".$extra")*/,
- };
-
- StringData db() const;
- StringData coll() const;
-
- const std::string& ns() const { return _ns; }
-
- operator const std::string&() const { return ns(); }
- const std::string& toString() const { return ns(); }
-
- size_t size() const { return _ns.size(); }
-
- //
- // The following methods assume isValid() is true for this NamespaceString.
- //
-
- bool isSystem() const { return coll().startsWith( "system." ); }
- bool isSystemDotIndexes() const { return coll() == "system.indexes"; }
- bool isSystemDotProfile() const { return coll() == "system.profile"; }
- bool isConfigDB() const { return db() == "config"; }
- bool isCommand() const { return coll() == "$cmd"; }
- bool isOplog() const { return oplog( _ns ); }
- bool isSpecialCommand() const { return coll().startsWith("$cmd.sys"); }
- bool isSpecial() const { return special( _ns ); }
- bool isOnInternalDb() const { return internalDb(db()); }
- bool isNormal() const { return normal( _ns ); }
- bool isListCollectionsGetMore() const;
- bool isListIndexesGetMore() const;
-
- /**
- * Given a NamespaceString for which isListIndexesGetMore() returns true, returns the
- * NamespaceString for the collection that the "listIndexesGetMore" targets.
- */
- NamespaceString getTargetNSForListIndexesGetMore() const;
-
- /**
- * @return true if the namespace is valid. Special namespaces for internal use are considered as valid.
- */
- bool isValid() const { return validDBName( db() ) && !coll().empty(); }
-
- bool operator==( const std::string& nsIn ) const { return nsIn == _ns; }
- bool operator==( StringData nsIn ) const { return nsIn == _ns; }
- bool operator==( const NamespaceString& nsIn ) const { return nsIn._ns == _ns; }
-
- bool operator!=( const std::string& nsIn ) const { return nsIn != _ns; }
- bool operator!=( const NamespaceString& nsIn ) const { return nsIn._ns != _ns; }
-
- bool operator<( const NamespaceString& rhs ) const { return _ns < rhs._ns; }
-
- /** ( foo.bar ).getSisterNS( "blah" ) == foo.blah
- */
- std::string getSisterNS( StringData local ) const;
-
- // @return db() + ".system.indexes"
- std::string getSystemIndexesCollection() const;
-
- // @return db() + ".$cmd"
- std::string getCommandNS() const;
-
- /**
- * Function to escape most non-alpha characters from file names
- */
- static std::string escapeDbName( const StringData dbname );
-
- /**
- * @return true if ns is 'normal'. A "$" is used for namespaces holding index data,
- * which do not contain BSON objects in their records. ("oplog.$main" is the exception)
- */
- static bool normal(StringData ns);
-
- /**
- * @return true if the ns is an oplog one, otherwise false.
- */
- static bool oplog(StringData ns);
-
- static bool special(StringData ns);
-
- /**
- * Returns true for DBs with special meaning to mongodb.
- */
- static bool internalDb(StringData ns) {
- if (ns == "admin") return true;
- if (ns == "local") return true;
- if (ns == "config") return true;
- return false;
- }
-
- /**
- * 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( StringData dbin );
-
- /**
- * Takes a fully qualified namespace (ie dbname.collectionName), and returns true if
- * the collection name component of the namespace is valid.
- * samples:
- * good:
- * foo.bar
- * bad:
- * foo.
- *
- * @param ns - a full namespace (a.b)
- * @return if db.coll is an allowed collection name
- */
- static bool validCollectionComponent(StringData ns);
-
- /**
- * Takes a collection name and returns true if it is a valid collection name.
- * samples:
- * good:
- * foo
- * system.indexes
- * bad:
- * $foo
- * @param coll - a collection name component of a namespace
- * @return if the input is a valid collection name
- */
- static bool validCollectionName(StringData coll);
-
- private:
-
- std::string _ns;
- size_t _dotIndex;
+/* in the mongo source code, "client" means "database". */
+
+const size_t MaxDatabaseNameLen = 128; // max str len for the db name, including null char
+
+/** @return true if a client can modify this namespace even though it is under ".system."
+ For example <dbname>.system.users is ok for regular clients to update.
+ @param write used when .system.js
+*/
+bool legalClientSystemNS(StringData ns, bool write);
+
+/* e.g.
+ NamespaceString ns("acme.orders");
+ cout << ns.coll; // "orders"
+*/
+class NamespaceString {
+public:
+ /**
+ * Constructs an empty NamespaceString.
+ */
+ NamespaceString();
+
+ /**
+ * Constructs a NamespaceString from the fully qualified namespace named in "ns".
+ */
+ explicit NamespaceString(StringData ns);
+
+ /**
+ * Constructs a NamespaceString for the given database and collection names.
+ * "dbName" must not contain a ".", and "collectionName" must not start with one.
+ */
+ NamespaceString(StringData dbName, StringData collectionName);
+
+ /**
+ * Note that these values are derived from the mmap_v1 implementation and that
+ * is the only reason they are constrained as such.
+ */
+ enum MaxNsLenValue {
+ // Maximum possible length of name any namespace, including special ones like $extra.
+ // This includes rum for the NUL byte so it can be used when sizing buffers.
+ MaxNsLenWithNUL = 128,
+
+ // MaxNsLenWithNUL excluding the NUL byte. Use this when comparing std::string lengths.
+ MaxNsLen = MaxNsLenWithNUL - 1,
+
+ // Maximum allowed length of fully qualified namespace name of any real collection.
+ // Does not include NUL so it can be directly compared to std::string lengths.
+ MaxNsCollectionLen = MaxNsLen - 7 /*strlen(".$extra")*/,
};
+ StringData db() const;
+ StringData coll() const;
- // "database.a.b.c" -> "database"
- inline StringData nsToDatabaseSubstring( StringData ns ) {
- size_t i = ns.find( '.' );
- if ( i == std::string::npos ) {
- massert(10078, "nsToDatabase: db too long", ns.size() < MaxDatabaseNameLen );
- return ns;
- }
- massert(10088, "nsToDatabase: db too long", i < static_cast<size_t>(MaxDatabaseNameLen));
- return ns.substr( 0, i );
+ const std::string& ns() const {
+ return _ns;
}
- // "database.a.b.c" -> "database"
- inline void nsToDatabase(StringData ns, char *database) {
- StringData db = nsToDatabaseSubstring( ns );
- db.copyTo( database, true );
+ operator const std::string&() const {
+ return ns();
+ }
+ const std::string& toString() const {
+ return ns();
}
- // TODO: make this return a StringData
- inline std::string nsToDatabase(StringData ns) {
- return nsToDatabaseSubstring( ns ).toString();
+ size_t size() const {
+ return _ns.size();
}
- // "database.a.b.c" -> "a.b.c"
- inline StringData nsToCollectionSubstring( StringData ns ) {
- size_t i = ns.find( '.' );
- massert(16886, "nsToCollectionSubstring: no .", i != std::string::npos );
- return ns.substr( i + 1 );
+ //
+ // The following methods assume isValid() is true for this NamespaceString.
+ //
+
+ bool isSystem() const {
+ return coll().startsWith("system.");
+ }
+ bool isSystemDotIndexes() const {
+ return coll() == "system.indexes";
+ }
+ bool isSystemDotProfile() const {
+ return coll() == "system.profile";
}
+ bool isConfigDB() const {
+ return db() == "config";
+ }
+ bool isCommand() const {
+ return coll() == "$cmd";
+ }
+ bool isOplog() const {
+ return oplog(_ns);
+ }
+ bool isSpecialCommand() const {
+ return coll().startsWith("$cmd.sys");
+ }
+ bool isSpecial() const {
+ return special(_ns);
+ }
+ bool isOnInternalDb() const {
+ return internalDb(db());
+ }
+ bool isNormal() const {
+ return normal(_ns);
+ }
+ bool isListCollectionsGetMore() const;
+ bool isListIndexesGetMore() const;
/**
- * foo = false
- * foo. = false
- * foo.a = true
+ * Given a NamespaceString for which isListIndexesGetMore() returns true, returns the
+ * NamespaceString for the collection that the "listIndexesGetMore" targets.
*/
- inline bool nsIsFull( StringData ns ) {
- size_t i = ns.find( '.' );
- if ( i == std::string::npos )
- return false;
- if ( i == ns.size() - 1 )
- return false;
- return true;
+ NamespaceString getTargetNSForListIndexesGetMore() const;
+
+ /**
+ * @return true if the namespace is valid. Special namespaces for internal use are considered as valid.
+ */
+ bool isValid() const {
+ return validDBName(db()) && !coll().empty();
}
+ bool operator==(const std::string& nsIn) const {
+ return nsIn == _ns;
+ }
+ bool operator==(StringData nsIn) const {
+ return nsIn == _ns;
+ }
+ bool operator==(const NamespaceString& nsIn) const {
+ return nsIn._ns == _ns;
+ }
+
+ bool operator!=(const std::string& nsIn) const {
+ return nsIn != _ns;
+ }
+ bool operator!=(const NamespaceString& nsIn) const {
+ return nsIn._ns != _ns;
+ }
+
+ bool operator<(const NamespaceString& rhs) const {
+ return _ns < rhs._ns;
+ }
+
+ /** ( foo.bar ).getSisterNS( "blah" ) == foo.blah
+ */
+ std::string getSisterNS(StringData local) const;
+
+ // @return db() + ".system.indexes"
+ std::string getSystemIndexesCollection() const;
+
+ // @return db() + ".$cmd"
+ std::string getCommandNS() const;
+
+ /**
+ * Function to escape most non-alpha characters from file names
+ */
+ static std::string escapeDbName(const StringData dbname);
+
+ /**
+ * @return true if ns is 'normal'. A "$" is used for namespaces holding index data,
+ * which do not contain BSON objects in their records. ("oplog.$main" is the exception)
+ */
+ static bool normal(StringData ns);
+
+ /**
+ * @return true if the ns is an oplog one, otherwise false.
+ */
+ static bool oplog(StringData ns);
+
+ static bool special(StringData ns);
+
/**
- * foo = true
- * foo. = false
- * foo.a = false
+ * Returns true for DBs with special meaning to mongodb.
*/
- inline bool nsIsDbOnly(StringData ns) {
- size_t i = ns.find('.');
- if (i == std::string::npos)
+ static bool internalDb(StringData ns) {
+ if (ns == "admin")
+ return true;
+ if (ns == "local")
+ return true;
+ if (ns == "config")
return true;
return false;
}
/**
- * NamespaceDBHash and NamespaceDBEquals allow you to do something like
- * unordered_map<std::string,int,NamespaceDBHash,NamespaceDBEquals>
- * and use the full namespace for the string
- * but comparisons are done only on the db piece
+ * 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(StringData dbin);
/**
- * this can change, do not store on disk
+ * Takes a fully qualified namespace (ie dbname.collectionName), and returns true if
+ * the collection name component of the namespace is valid.
+ * samples:
+ * good:
+ * foo.bar
+ * bad:
+ * foo.
+ *
+ * @param ns - a full namespace (a.b)
+ * @return if db.coll is an allowed collection name
*/
- int nsDBHash( const std::string& ns );
+ static bool validCollectionComponent(StringData ns);
- bool nsDBEquals( const std::string& a, const std::string& b );
+ /**
+ * Takes a collection name and returns true if it is a valid collection name.
+ * samples:
+ * good:
+ * foo
+ * system.indexes
+ * bad:
+ * $foo
+ * @param coll - a collection name component of a namespace
+ * @return if the input is a valid collection name
+ */
+ static bool validCollectionName(StringData coll);
- struct NamespaceDBHash {
- int operator()( const std::string& ns ) const {
- return nsDBHash( ns );
- }
- };
+private:
+ std::string _ns;
+ size_t _dotIndex;
+};
- struct NamespaceDBEquals {
- bool operator()( const std::string& a, const std::string& b ) const {
- return nsDBEquals( a, b );
- }
- };
+// "database.a.b.c" -> "database"
+inline StringData nsToDatabaseSubstring(StringData ns) {
+ size_t i = ns.find('.');
+ if (i == std::string::npos) {
+ massert(10078, "nsToDatabase: db too long", ns.size() < MaxDatabaseNameLen);
+ return ns;
+ }
+ massert(10088, "nsToDatabase: db too long", i < static_cast<size_t>(MaxDatabaseNameLen));
+ return ns.substr(0, i);
+}
+
+// "database.a.b.c" -> "database"
+inline void nsToDatabase(StringData ns, char* database) {
+ StringData db = nsToDatabaseSubstring(ns);
+ db.copyTo(database, true);
+}
+
+// TODO: make this return a StringData
+inline std::string nsToDatabase(StringData ns) {
+ return nsToDatabaseSubstring(ns).toString();
+}
+
+// "database.a.b.c" -> "a.b.c"
+inline StringData nsToCollectionSubstring(StringData ns) {
+ size_t i = ns.find('.');
+ massert(16886, "nsToCollectionSubstring: no .", i != std::string::npos);
+ return ns.substr(i + 1);
+}
+
+/**
+ * foo = false
+ * foo. = false
+ * foo.a = true
+ */
+inline bool nsIsFull(StringData ns) {
+ size_t i = ns.find('.');
+ if (i == std::string::npos)
+ return false;
+ if (i == ns.size() - 1)
+ return false;
+ return true;
+}
+
+/**
+ * foo = true
+ * foo. = false
+ * foo.a = false
+ */
+inline bool nsIsDbOnly(StringData ns) {
+ size_t i = ns.find('.');
+ if (i == std::string::npos)
+ return true;
+ return false;
+}
+
+/**
+ * NamespaceDBHash and NamespaceDBEquals allow you to do something like
+ * unordered_map<std::string,int,NamespaceDBHash,NamespaceDBEquals>
+ * and use the full namespace for the string
+ * but comparisons are done only on the db piece
+ */
+
+/**
+ * this can change, do not store on disk
+ */
+int nsDBHash(const std::string& ns);
+
+bool nsDBEquals(const std::string& a, const std::string& b);
+
+struct NamespaceDBHash {
+ int operator()(const std::string& ns) const {
+ return nsDBHash(ns);
+ }
+};
+
+struct NamespaceDBEquals {
+ bool operator()(const std::string& a, const std::string& b) const {
+ return nsDBEquals(a, b);
+ }
+};
}