From 80033485be537acaf29924f6b717c777b550a418 Mon Sep 17 00:00:00 2001 From: Konstantin Varlamov Date: Fri, 9 Feb 2018 19:42:28 -0500 Subject: C++ port: add C++ equivalent of FSTDocumentKey. (#762) Also move kDocumentKeyPath to the only point of usage - make it a static member variable of FieldPath. --- .../src/firebase/firestore/model/CMakeLists.txt | 2 + .../src/firebase/firestore/model/document_key.cc | 54 +++++++++++ .../src/firebase/firestore/model/document_key.h | 101 +++++++++++++++++++++ .../src/firebase/firestore/model/field_path.cc | 7 +- .../core/src/firebase/firestore/model/field_path.h | 3 + .../src/firebase/firestore/model/resource_path.cc | 2 +- .../src/firebase/firestore/model/resource_path.h | 2 +- 7 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 Firestore/core/src/firebase/firestore/model/document_key.cc create mode 100644 Firestore/core/src/firebase/firestore/model/document_key.h (limited to 'Firestore/core/src/firebase/firestore/model') diff --git a/Firestore/core/src/firebase/firestore/model/CMakeLists.txt b/Firestore/core/src/firebase/firestore/model/CMakeLists.txt index 169e310..95310ec 100644 --- a/Firestore/core/src/firebase/firestore/model/CMakeLists.txt +++ b/Firestore/core/src/firebase/firestore/model/CMakeLists.txt @@ -18,6 +18,8 @@ cc_library( base_path.h database_id.cc database_id.h + document_key.cc + document_key.h field_path.cc field_path.h field_value.cc diff --git a/Firestore/core/src/firebase/firestore/model/document_key.cc b/Firestore/core/src/firebase/firestore/model/document_key.cc new file mode 100644 index 0000000..ddda4c9 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/model/document_key.cc @@ -0,0 +1,54 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +namespace { + +void AssertValidPath(const ResourcePath& path) { + FIREBASE_ASSERT_MESSAGE(DocumentKey::IsDocumentKey(path), + "invalid document key path: %s", + path.CanonicalString().c_str()); +} + +} // namespace + +DocumentKey::DocumentKey(const ResourcePath& path) + : path_{std::make_shared(path)} { + AssertValidPath(*path_); +} + +DocumentKey::DocumentKey(ResourcePath&& path) + : path_{std::make_shared(std::move(path))} { + AssertValidPath(*path_); +} + +const DocumentKey& DocumentKey::Empty() { + static const DocumentKey empty; + return empty; +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/Firestore/core/src/firebase/firestore/model/document_key.h b/Firestore/core/src/firebase/firestore/model/document_key.h new file mode 100644 index 0000000..6eb1e18 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/model/document_key.h @@ -0,0 +1,101 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * DocumentKey represents the location of a document in the Firestore database. + */ +class DocumentKey { + public: + /** Creates a "blank" document key not associated with any document. */ + DocumentKey() : path_{std::make_shared()} { + } + + /** Creates a new document key containing a copy of the given path. */ + explicit DocumentKey(const ResourcePath& path); + + /** Creates a new document key, taking ownership of the given path. */ + explicit DocumentKey(ResourcePath&& path); + + /** + * Creates and returns a new document key using '/' to split the string into + * segments. + */ + static DocumentKey FromPathString(const absl::string_view path) { + return DocumentKey{ResourcePath::FromString(path)}; + } + + /** Creates and returns a new document key with the given segments. */ + static DocumentKey FromSegments(std::initializer_list list) { + return DocumentKey{ResourcePath{list}}; + } + + /** Returns a shared instance of an empty document key. */ + static const DocumentKey& Empty(); + + /** Returns true iff the given path is a path to a document. */ + static bool IsDocumentKey(const ResourcePath& path) { + return path.size() % 2 == 0; + } + + /** The path to the document. */ + const ResourcePath& path() const { + return path_ ? *path_ : Empty().path(); + } + + private: + // This is an optimization to make passing DocumentKey around cheaper (it's + // copied often). + std::shared_ptr path_; +}; + +inline bool operator==(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() == rhs.path(); +} +inline bool operator!=(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() != rhs.path(); +} +inline bool operator<(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() < rhs.path(); +} +inline bool operator<=(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() <= rhs.path(); +} +inline bool operator>(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() > rhs.path(); +} +inline bool operator>=(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() >= rhs.path(); +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_ diff --git a/Firestore/core/src/firebase/firestore/model/field_path.cc b/Firestore/core/src/firebase/firestore/model/field_path.cc index 0da2319..bc0e97c 100644 --- a/Firestore/core/src/firebase/firestore/model/field_path.cc +++ b/Firestore/core/src/firebase/firestore/model/field_path.cc @@ -30,9 +30,6 @@ namespace model { namespace { -// TODO(varconst): move to C++ equivalent of FSTDocumentKey.{h,cc} -const char* const kDocumentKeyPath = "__name__"; - /** * True if the string could be used as a segment in a field path without * escaping. Valid identifies follow the regex [a-zA-Z_][a-zA-Z0-9_]* @@ -146,12 +143,12 @@ const FieldPath& FieldPath::EmptyPath() { } const FieldPath& FieldPath::KeyFieldPath() { - static const FieldPath key_field_path{kDocumentKeyPath}; + static const FieldPath key_field_path{FieldPath::kDocumentKeyPath}; return key_field_path; } bool FieldPath::IsKeyFieldPath() const { - return size() == 1 && first_segment() == kDocumentKeyPath; + return size() == 1 && first_segment() == FieldPath::kDocumentKeyPath; } std::string FieldPath::CanonicalString() const { diff --git a/Firestore/core/src/firebase/firestore/model/field_path.h b/Firestore/core/src/firebase/firestore/model/field_path.h index ba6e2bd..fdf4918 100644 --- a/Firestore/core/src/firebase/firestore/model/field_path.h +++ b/Firestore/core/src/firebase/firestore/model/field_path.h @@ -35,6 +35,9 @@ namespace model { */ class FieldPath : public impl::BasePath { public: + /** The field path string that represents the document's key. */ + static constexpr const char* kDocumentKeyPath = "__name__"; + // Note: Xcode 8.2 requires explicit specification of the constructor. FieldPath() : impl::BasePath() { } diff --git a/Firestore/core/src/firebase/firestore/model/resource_path.cc b/Firestore/core/src/firebase/firestore/model/resource_path.cc index a4f921f..c95aa63 100644 --- a/Firestore/core/src/firebase/firestore/model/resource_path.cc +++ b/Firestore/core/src/firebase/firestore/model/resource_path.cc @@ -28,7 +28,7 @@ namespace firebase { namespace firestore { namespace model { -ResourcePath ResourcePath::Parse(const absl::string_view path) { +ResourcePath ResourcePath::FromString(const absl::string_view path) { // NOTE: The client is ignorant of any path segments containing escape // sequences (e.g. __id123__) and just passes them through raw (they exist // for legacy reasons and should not be used frequently). diff --git a/Firestore/core/src/firebase/firestore/model/resource_path.h b/Firestore/core/src/firebase/firestore/model/resource_path.h index b0853c6..53c1951 100644 --- a/Firestore/core/src/firebase/firestore/model/resource_path.h +++ b/Firestore/core/src/firebase/firestore/model/resource_path.h @@ -45,7 +45,7 @@ class ResourcePath : public impl::BasePath { * Creates and returns a new path from the given resource-path string, where * the path segments are separated by a slash "/". */ - static ResourcePath Parse(absl::string_view path); + static ResourcePath FromString(absl::string_view path); /** Returns a standardized string representation of this path. */ std::string CanonicalString() const; -- cgit v1.2.3