Skip to content

Commit 8003348

Browse files
authored
C++ port: add C++ equivalent of FSTDocumentKey. (firebase#762)
Also move kDocumentKeyPath to the only point of usage - make it a static member variable of FieldPath.
1 parent 612d99c commit 8003348

File tree

11 files changed

+326
-11
lines changed

11 files changed

+326
-11
lines changed

Firestore/Example/Firestore.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
ABE6637A201FA81900ED349A /* database_id_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB71064B201FA60300344F18 /* database_id_test.cc */; };
151151
ABF6506C201131F8005F2C74 /* timestamp_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABF6506B201131F8005F2C74 /* timestamp_test.cc */; };
152152
AFE6114F0D4DAECBA7B7C089 /* Pods_Firestore_IntegrationTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */; };
153+
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B6152AD5202A5385000E5744 /* document_key_test.cc */; };
153154
B686F2AF2023DDEE0028D6BE /* field_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2AD2023DDB20028D6BE /* field_path_test.cc */; };
154155
B686F2B22025000D0028D6BE /* resource_path_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = B686F2B02024FFD70028D6BE /* resource_path_test.cc */; };
155156
C4E749275AD0FBDF9F4716A8 /* Pods_SwiftBuildTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32AD40BF6B0E849B07FFD05E /* Pods_SwiftBuildTest.framework */; };
@@ -352,6 +353,7 @@
352353
ABC1D7E22023CDC500BA84F0 /* firebase_credentials_provider_test.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = firebase_credentials_provider_test.mm; sourceTree = "<group>"; };
353354
ABF6506B201131F8005F2C74 /* timestamp_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = timestamp_test.cc; sourceTree = "<group>"; };
354355
B2FA635DF5D116A67A7441CD /* Pods_Firestore_IntegrationTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Firestore_IntegrationTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
356+
B6152AD5202A5385000E5744 /* document_key_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = document_key_test.cc; sourceTree = "<group>"; };
355357
B686F2AD2023DDB20028D6BE /* field_path_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = field_path_test.cc; sourceTree = "<group>"; };
356358
B686F2B02024FFD70028D6BE /* resource_path_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = resource_path_test.cc; sourceTree = "<group>"; };
357359
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>"; };
@@ -582,6 +584,7 @@
582584
AB356EF5200E9D1A0089B766 /* model */ = {
583585
isa = PBXGroup;
584586
children = (
587+
B6152AD5202A5385000E5744 /* document_key_test.cc */,
585588
B686F2B02024FFD70028D6BE /* resource_path_test.cc */,
586589
B686F2AD2023DDB20028D6BE /* field_path_test.cc */,
587590
AB71064B201FA60300344F18 /* database_id_test.cc */,
@@ -1320,6 +1323,7 @@
13201323
5492E0C82021557E00B64F25 /* FSTDatastoreTests.mm in Sources */,
13211324
5492E065202154B900B64F25 /* FSTViewTests.mm in Sources */,
13221325
5492E03C2021401F00B64F25 /* XCTestCase+Await.mm in Sources */,
1326+
B6152AD7202A53CB000E5744 /* document_key_test.cc in Sources */,
13231327
54764FAF1FAA21B90085E60A /* FSTGoogleTestTests.mm in Sources */,
13241328
AB380D04201BC6E400D97691 /* ordered_code_test.cc in Sources */,
13251329
5492E03F2021401F00B64F25 /* FSTHelpers.mm in Sources */,

Firestore/core/src/firebase/firestore/model/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ cc_library(
1818
base_path.h
1919
database_id.cc
2020
database_id.h
21+
document_key.cc
22+
document_key.h
2123
field_path.cc
2224
field_path.h
2325
field_value.cc
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright 2018 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "Firestore/core/src/firebase/firestore/model/document_key.h"
18+
19+
#include <utility>
20+
21+
#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h"
22+
23+
namespace firebase {
24+
namespace firestore {
25+
namespace model {
26+
27+
namespace {
28+
29+
void AssertValidPath(const ResourcePath& path) {
30+
FIREBASE_ASSERT_MESSAGE(DocumentKey::IsDocumentKey(path),
31+
"invalid document key path: %s",
32+
path.CanonicalString().c_str());
33+
}
34+
35+
} // namespace
36+
37+
DocumentKey::DocumentKey(const ResourcePath& path)
38+
: path_{std::make_shared<ResourcePath>(path)} {
39+
AssertValidPath(*path_);
40+
}
41+
42+
DocumentKey::DocumentKey(ResourcePath&& path)
43+
: path_{std::make_shared<ResourcePath>(std::move(path))} {
44+
AssertValidPath(*path_);
45+
}
46+
47+
const DocumentKey& DocumentKey::Empty() {
48+
static const DocumentKey empty;
49+
return empty;
50+
}
51+
52+
} // namespace model
53+
} // namespace firestore
54+
} // namespace firebase
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright 2018 Google
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_
18+
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_
19+
20+
#include <initializer_list>
21+
#include <memory>
22+
#include <string>
23+
24+
#include "Firestore/core/src/firebase/firestore/model/resource_path.h"
25+
#include "absl/strings/string_view.h"
26+
27+
namespace firebase {
28+
namespace firestore {
29+
namespace model {
30+
31+
/**
32+
* DocumentKey represents the location of a document in the Firestore database.
33+
*/
34+
class DocumentKey {
35+
public:
36+
/** Creates a "blank" document key not associated with any document. */
37+
DocumentKey() : path_{std::make_shared<ResourcePath>()} {
38+
}
39+
40+
/** Creates a new document key containing a copy of the given path. */
41+
explicit DocumentKey(const ResourcePath& path);
42+
43+
/** Creates a new document key, taking ownership of the given path. */
44+
explicit DocumentKey(ResourcePath&& path);
45+
46+
/**
47+
* Creates and returns a new document key using '/' to split the string into
48+
* segments.
49+
*/
50+
static DocumentKey FromPathString(const absl::string_view path) {
51+
return DocumentKey{ResourcePath::FromString(path)};
52+
}
53+
54+
/** Creates and returns a new document key with the given segments. */
55+
static DocumentKey FromSegments(std::initializer_list<std::string> list) {
56+
return DocumentKey{ResourcePath{list}};
57+
}
58+
59+
/** Returns a shared instance of an empty document key. */
60+
static const DocumentKey& Empty();
61+
62+
/** Returns true iff the given path is a path to a document. */
63+
static bool IsDocumentKey(const ResourcePath& path) {
64+
return path.size() % 2 == 0;
65+
}
66+
67+
/** The path to the document. */
68+
const ResourcePath& path() const {
69+
return path_ ? *path_ : Empty().path();
70+
}
71+
72+
private:
73+
// This is an optimization to make passing DocumentKey around cheaper (it's
74+
// copied often).
75+
std::shared_ptr<const ResourcePath> path_;
76+
};
77+
78+
inline bool operator==(const DocumentKey& lhs, const DocumentKey& rhs) {
79+
return lhs.path() == rhs.path();
80+
}
81+
inline bool operator!=(const DocumentKey& lhs, const DocumentKey& rhs) {
82+
return lhs.path() != rhs.path();
83+
}
84+
inline bool operator<(const DocumentKey& lhs, const DocumentKey& rhs) {
85+
return lhs.path() < rhs.path();
86+
}
87+
inline bool operator<=(const DocumentKey& lhs, const DocumentKey& rhs) {
88+
return lhs.path() <= rhs.path();
89+
}
90+
inline bool operator>(const DocumentKey& lhs, const DocumentKey& rhs) {
91+
return lhs.path() > rhs.path();
92+
}
93+
inline bool operator>=(const DocumentKey& lhs, const DocumentKey& rhs) {
94+
return lhs.path() >= rhs.path();
95+
}
96+
97+
} // namespace model
98+
} // namespace firestore
99+
} // namespace firebase
100+
101+
#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_

Firestore/core/src/firebase/firestore/model/field_path.cc

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ namespace model {
3030

3131
namespace {
3232

33-
// TODO(varconst): move to C++ equivalent of FSTDocumentKey.{h,cc}
34-
const char* const kDocumentKeyPath = "__name__";
35-
3633
/**
3734
* True if the string could be used as a segment in a field path without
3835
* escaping. Valid identifies follow the regex [a-zA-Z_][a-zA-Z0-9_]*
@@ -146,12 +143,12 @@ const FieldPath& FieldPath::EmptyPath() {
146143
}
147144

148145
const FieldPath& FieldPath::KeyFieldPath() {
149-
static const FieldPath key_field_path{kDocumentKeyPath};
146+
static const FieldPath key_field_path{FieldPath::kDocumentKeyPath};
150147
return key_field_path;
151148
}
152149

153150
bool FieldPath::IsKeyFieldPath() const {
154-
return size() == 1 && first_segment() == kDocumentKeyPath;
151+
return size() == 1 && first_segment() == FieldPath::kDocumentKeyPath;
155152
}
156153

157154
std::string FieldPath::CanonicalString() const {

Firestore/core/src/firebase/firestore/model/field_path.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ namespace model {
3535
*/
3636
class FieldPath : public impl::BasePath<FieldPath> {
3737
public:
38+
/** The field path string that represents the document's key. */
39+
static constexpr const char* kDocumentKeyPath = "__name__";
40+
3841
// Note: Xcode 8.2 requires explicit specification of the constructor.
3942
FieldPath() : impl::BasePath<FieldPath>() {
4043
}

Firestore/core/src/firebase/firestore/model/resource_path.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace firebase {
2828
namespace firestore {
2929
namespace model {
3030

31-
ResourcePath ResourcePath::Parse(const absl::string_view path) {
31+
ResourcePath ResourcePath::FromString(const absl::string_view path) {
3232
// NOTE: The client is ignorant of any path segments containing escape
3333
// sequences (e.g. __id123__) and just passes them through raw (they exist
3434
// for legacy reasons and should not be used frequently).

Firestore/core/src/firebase/firestore/model/resource_path.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ResourcePath : public impl::BasePath<ResourcePath> {
4545
* Creates and returns a new path from the given resource-path string, where
4646
* the path segments are separated by a slash "/".
4747
*/
48-
static ResourcePath Parse(absl::string_view path);
48+
static ResourcePath FromString(absl::string_view path);
4949

5050
/** Returns a standardized string representation of this path. */
5151
std::string CanonicalString() const;

Firestore/core/test/firebase/firestore/model/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ cc_test(
1616
firebase_firestore_model_test
1717
SOURCES
1818
database_id_test.cc
19+
document_key_test.cc
1920
field_path_test.cc
2021
field_value_test.cc
2122
snapshot_version_test.cc

0 commit comments

Comments
 (0)