Skip to content

Commit

Permalink
C++ port: add C++ equivalent of FSTDocumentKey. (firebase#762)
Browse files Browse the repository at this point in the history
Also move kDocumentKeyPath to the only point of usage - make it a static
member variable of FieldPath.
  • Loading branch information
var-const committed Feb 10, 2018
1 parent 612d99c commit 8003348
Show file tree
Hide file tree
Showing 11 changed files with 326 additions and 11 deletions.
4 changes: 4 additions & 0 deletions Firestore/Example/Firestore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
ABE6637A201FA81900ED349A /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; };
ABF6506C201131F8005F2C74 /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; };
AFE6114F0D4DAECBA7B7C089 /* Pods_Firestore_IntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */; };
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; };
B686F2AF2023DDEE0028D6BE /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; };
B686F2B22025000D0028D6BE /* resource_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2B02024FFD70028D6BE /* resource_path_test.cc */; };
C4E749275AD0FBDF9F4716A8 /* Pods_SwiftBuildTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32AD40BF6B0E849B07FFD05E /* Pods_SwiftBuildTest.framework */; };
Expand Down Expand Up @@ -352,6 +353,7 @@
ABC1D7E22023CDC500BA84F0 /* firebase_credentials_provider_test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = firebase_credentials_provider_test.mm; sourceTree = "<group>"; };
ABF6506B201131F8005F2C74 /* timestamp_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = timestamp_test.cc; sourceTree = "<group>"; };
B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B6152AD5202A5385000E5744 /* document_key_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = document_key_test.cc; sourceTree = "<group>"; };
B686F2AD2023DDB20028D6BE /* field_path_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field_path_test.cc; sourceTree = "<group>"; };
B686F2B02024FFD70028D6BE /* resource_path_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_path_test.cc; sourceTree = "<group>"; };
CE00BABB5A3AAB44A4C209E2 /* Pods-Firestore_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Firestore_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Firestore_Tests/Pods-Firestore_Tests.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -582,6 +584,7 @@
AB356EF5200E9D1A0089B766 /* model */ = {
isa = PBXGroup;
children = (
B6152AD5202A5385000E5744 /* document_key_test.cc */,
B686F2B02024FFD70028D6BE /* resource_path_test.cc */,
B686F2AD2023DDB20028D6BE /* field_path_test.cc */,
AB71064B201FA60300344F18 /* database_id_test.cc */,
Expand Down Expand Up @@ -1320,6 +1323,7 @@
5492E0C82021557E00B64F25 /* FSTDatastoreTests.mm in Sources */,
5492E065202154B900B64F25 /* FSTViewTests.mm in Sources */,
5492E03C2021401F00B64F25 /* XCTestCase+Await.mm in Sources */,
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */,
54764FAF1FAA21B90085E60A /* FSTGoogleTestTests.mm in Sources */,
AB380D04201BC6E400D97691 /* ordered_code_test.cc in Sources */,
5492E03F2021401F00B64F25 /* FSTHelpers.mm in Sources */,
Expand Down
2 changes: 2 additions & 0 deletions Firestore/core/src/firebase/firestore/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
54 changes: 54 additions & 0 deletions Firestore/core/src/firebase/firestore/model/document_key.cc
Original file line number Diff line number Diff line change
@@ -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 <utility>

#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<ResourcePath>(path)} {
AssertValidPath(*path_);
}

DocumentKey::DocumentKey(ResourcePath&& path)
: path_{std::make_shared<ResourcePath>(std::move(path))} {
AssertValidPath(*path_);
}

const DocumentKey& DocumentKey::Empty() {
static const DocumentKey empty;
return empty;
}

} // namespace model
} // namespace firestore
} // namespace firebase
101 changes: 101 additions & 0 deletions Firestore/core/src/firebase/firestore/model/document_key.h
Original file line number Diff line number Diff line change
@@ -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 <initializer_list>
#include <memory>
#include <string>

#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<ResourcePath>()} {
}

/** 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<std::string> 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<const ResourcePath> 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_
7 changes: 2 additions & 5 deletions Firestore/core/src/firebase/firestore/model/field_path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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_]*
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions Firestore/core/src/firebase/firestore/model/field_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ namespace model {
*/
class FieldPath : public impl::BasePath<FieldPath> {
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<FieldPath>() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ResourcePath : public impl::BasePath<ResourcePath> {
* 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ cc_test(
firebase_firestore_model_test
SOURCES
database_id_test.cc
document_key_test.cc
field_path_test.cc
field_value_test.cc
snapshot_version_test.cc
Expand Down
Loading

0 comments on commit 8003348

Please sign in to comment.