Skip to content

Commit

Permalink
Port Firestore Document to C++ (firebase#777)
Browse files Browse the repository at this point in the history
* implement SnapshotVersion and test

* update project

* implement MaybeDocument and test

* move snapshot-version from core to model

* fix a bug

* implement Document and test

* implement NoDocument

* adding type tag and fix style

* fix a few bugs, discovered after merging and test run.

* add assert to check FieldValue type and more test for comparision.

* address changes

* allow moving FieldValue to construct Document.

* address changes

* add document tests to project

* use std::less convention

* make Type::Unknown static initializer
  • Loading branch information
zxu123 committed Feb 13, 2018
1 parent adf9fb3 commit 9504582
Show file tree
Hide file tree
Showing 12 changed files with 545 additions and 3 deletions.
12 changes: 12 additions & 0 deletions Firestore/Example/Firestore.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@
AB380D02201BC69F00D97691 /* bits_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D01201BC69F00D97691 /* bits_test.cc */; };
AB380D04201BC6E400D97691 /* ordered_code_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB380D03201BC6E400D97691 /* ordered_code_test.cc */; };
AB38D93020236E21000A432D /* database_info_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D92E20235D22000A432D /* database_info_test.cc */; };
AB6B908420322E4D00CC290A /* document_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB6B908320322E4D00CC290A /* document_test.cc */; };
AB6B908620322E6D00CC290A /* maybe_document_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB6B908520322E6D00CC290A /* maybe_document_test.cc */; };
AB6B908820322E8800CC290A /* no_document_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB6B908720322E8800CC290A /* no_document_test.cc */; };
AB7BAB342012B519001E0872 /* geo_point_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB7BAB332012B519001E0872 /* geo_point_test.cc */; };
ABA495BB202B7E80008A7851 /* snapshot_version_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */; };
ABC1D7DC2023A04B00BA84F0 /* credentials_provider_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB38D9342023966E000A432D /* credentials_provider_test.cc */; };
Expand Down Expand Up @@ -346,6 +349,9 @@
AB38D93220239654000A432D /* user_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = user_test.cc; sourceTree = "<group>"; };
AB38D9342023966E000A432D /* credentials_provider_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = credentials_provider_test.cc; sourceTree = "<group>"; };
AB38D93620239689000A432D /* empty_credentials_provider_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = empty_credentials_provider_test.cc; sourceTree = "<group>"; };
AB6B908320322E4D00CC290A /* document_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = document_test.cc; sourceTree = "<group>"; };
AB6B908520322E6D00CC290A /* maybe_document_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = maybe_document_test.cc; sourceTree = "<group>"; };
AB6B908720322E8800CC290A /* no_document_test.cc */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = no_document_test.cc; sourceTree = "<group>"; };
AB71064B201FA60300344F18 /* database_id_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = database_id_test.cc; sourceTree = "<group>"; };
AB7BAB332012B519001E0872 /* geo_point_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = geo_point_test.cc; path = ../../core/test/firebase/firestore/geo_point_test.cc; sourceTree = "<group>"; };
ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = snapshot_version_test.cc; sourceTree = "<group>"; };
Expand Down Expand Up @@ -585,10 +591,13 @@
isa = PBXGroup;
children = (
B6152AD5202A5385000E5744 /* document_key_test.cc */,
AB6B908320322E4D00CC290A /* document_test.cc */,
B686F2B02024FFD70028D6BE /* resource_path_test.cc */,
B686F2AD2023DDB20028D6BE /* field_path_test.cc */,
AB71064B201FA60300344F18 /* database_id_test.cc */,
AB356EF6200EA5EB0089B766 /* field_value_test.cc */,
AB6B908520322E6D00CC290A /* maybe_document_test.cc */,
AB6B908720322E8800CC290A /* no_document_test.cc */,
ABA495B9202B7E79008A7851 /* snapshot_version_test.cc */,
ABF6506B201131F8005F2C74 /* timestamp_test.cc */,
);
Expand Down Expand Up @@ -1310,13 +1319,15 @@
5492E0AD2021552D00B64F25 /* FSTMemoryMutationQueueTests.mm in Sources */,
5492E051202154AA00B64F25 /* FIRQueryTests.mm in Sources */,
5492E054202154AB00B64F25 /* FIRFieldValueTests.mm in Sources */,
AB6B908620322E6D00CC290A /* maybe_document_test.cc in Sources */,
5492E09F2021552D00B64F25 /* FSTLevelDBMigrationsTests.mm in Sources */,
5492E053202154AB00B64F25 /* FIRDocumentReferenceTests.mm in Sources */,
5492E09D2021552D00B64F25 /* FSTLocalStoreTests.mm in Sources */,
5492E0A32021552D00B64F25 /* FSTLocalSerializerTests.mm in Sources */,
5492E0A72021552D00B64F25 /* FSTLevelDBKeyTests.mm in Sources */,
5492E0A22021552D00B64F25 /* FSTQueryCacheTests.mm in Sources */,
5492E0A52021552D00B64F25 /* FSTMemoryRemoteDocumentCacheTests.mm in Sources */,
AB6B908820322E8800CC290A /* no_document_test.cc in Sources */,
5492E0BD2021555100B64F25 /* FSTDocumentTests.mm in Sources */,
5492E0B92021555100B64F25 /* FSTDocumentKeyTests.mm in Sources */,
DE2EF0871F3D0B6E003D0CDC /* FSTImmutableSortedSet+Testing.m in Sources */,
Expand All @@ -1331,6 +1342,7 @@
5492E0AB2021552D00B64F25 /* StringViewTests.mm in Sources */,
5492E0C92021557E00B64F25 /* FSTRemoteEventTests.mm in Sources */,
ABC1D7E42024AFDE00BA84F0 /* firebase_credentials_provider_test.mm in Sources */,
AB6B908420322E4D00CC290A /* document_test.cc in Sources */,
ABF6506C201131F8005F2C74 /* timestamp_test.cc in Sources */,
5492E0AE2021552D00B64F25 /* FSTLevelDBQueryCacheTests.mm in Sources */,
ABC1D7DC2023A04B00BA84F0 /* credentials_provider_test.cc in Sources */,
Expand Down
10 changes: 8 additions & 2 deletions Firestore/core/src/firebase/firestore/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,22 @@ cc_library(
base_path.h
database_id.cc
database_id.h
document.cc
document.h
document_key.cc
document_key.h
field_path.cc
field_path.h
field_value.cc
field_value.h
snapshot_version.cc
snapshot_version.h
maybe_document.cc
maybe_document.h
no_document.cc
no_document.h
resource_path.cc
resource_path.h
snapshot_version.cc
snapshot_version.h
timestamp.cc
timestamp.h
DEPENDS
Expand Down
50 changes: 50 additions & 0 deletions Firestore/core/src/firebase/firestore/model/document.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 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.h"

#include <utility>

#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h"

namespace firebase {
namespace firestore {
namespace model {

Document::Document(FieldValue&& data,
DocumentKey key,
SnapshotVersion version,
bool has_local_mutations)
: MaybeDocument(std::move(key), std::move(version)),
data_(std::move(data)),
has_local_mutations_(has_local_mutations) {
set_type(Type::Document);
FIREBASE_ASSERT(FieldValue::Type::Object == data.type());
}

bool Document::Equals(const MaybeDocument& other) const {
if (other.type() != Type::Document) {
return false;
}
const Document& other_doc = static_cast<const Document&>(other);
return MaybeDocument::Equals(other) &&
has_local_mutations_ == other_doc.has_local_mutations_ &&
data_ == other_doc.data_;
}

} // namespace model
} // namespace firestore
} // namespace firebase
72 changes: 72 additions & 0 deletions Firestore/core/src/firebase/firestore/model/document.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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_H_
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_H_

#include "Firestore/core/src/firebase/firestore/model/field_value.h"
#include "Firestore/core/src/firebase/firestore/model/maybe_document.h"

namespace firebase {
namespace firestore {
namespace model {

/**
* Represents a document in Firestore with a key, version, data and whether the
* data has local mutations applied to it.
*/
class Document : public MaybeDocument {
public:
/**
* Construct a document. FieldValue must be passed by rvalue.
*/
Document(FieldValue&& data,
DocumentKey key,
SnapshotVersion version,
bool has_local_mutations);

const FieldValue& data() const {
return data_;
}

bool has_local_mutations() const {
return has_local_mutations_;
}

protected:
bool Equals(const MaybeDocument& other) const override;

private:
FieldValue data_; // This is of type Object.
bool has_local_mutations_;
};

/** Compares against another Document. */
inline bool operator==(const Document& lhs, const Document& rhs) {
return lhs.version() == rhs.version() && lhs.key() == rhs.key() &&
lhs.has_local_mutations() == rhs.has_local_mutations() &&
lhs.data() == rhs.data();
}

inline bool operator!=(const Document& lhs, const Document& rhs) {
return !(lhs == rhs);
}

} // namespace model
} // namespace firestore
} // namespace firebase

#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_H_
38 changes: 38 additions & 0 deletions Firestore/core/src/firebase/firestore/model/maybe_document.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* 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/maybe_document.h"

#include <utility>

#include "Firestore/core/src/firebase/firestore/util/firebase_assert.h"

namespace firebase {
namespace firestore {
namespace model {

MaybeDocument::MaybeDocument(DocumentKey key, SnapshotVersion version)
: key_(std::move(key)), version_(std::move(version)) {
}

bool MaybeDocument::Equals(const MaybeDocument& other) const {
return type_ == other.type_ && version_ == other.version_ &&
key_ == other.key_;
}

} // namespace model
} // namespace firestore
} // namespace firebase
100 changes: 100 additions & 0 deletions Firestore/core/src/firebase/firestore/model/maybe_document.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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_MAYBE_DOCUMENT_H_
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MAYBE_DOCUMENT_H_

#include <functional>

#include "Firestore/core/src/firebase/firestore/model/document_key.h"
#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h"

namespace firebase {
namespace firestore {
namespace model {

/**
* The result of a lookup for a given path may be an existing document or a
* tombstone that marks the path deleted.
*/
class MaybeDocument {
public:
/**
* All the different kinds of documents, including MaybeDocument and its
* subclasses. This is used to provide RTTI for documents.
*/
enum class Type {
Unknown,
Document,
NoDocument,
};

MaybeDocument(DocumentKey key, SnapshotVersion version);

/** The runtime type of this document. */
Type type() const {
return type_;
}

/** The key for this document. */
const DocumentKey& key() const {
return key_;
}

/**
* Returns the version of this document if it exists or a version at which
* this document was guaranteed to not exist.
*/
const SnapshotVersion& version() const {
return version_;
}

protected:
// Only allow subclass to set their types.
void set_type(Type type) {
type_ = type;
}

virtual bool Equals(const MaybeDocument& other) const;

friend bool operator==(const MaybeDocument& lhs, const MaybeDocument& rhs);

private:
Type type_ = Type::Unknown;
DocumentKey key_;
SnapshotVersion version_;
};

inline bool operator==(const MaybeDocument& lhs, const MaybeDocument& rhs) {
return lhs.Equals(rhs);
}

inline bool operator!=(const MaybeDocument& lhs, const MaybeDocument& rhs) {
return !(lhs == rhs);
}

/** Compares against another MaybeDocument by keys only. */
struct DocumentKeyComparator : public std::less<MaybeDocument> {
bool operator()(const MaybeDocument& lhs, const MaybeDocument& rhs) const {
return lhs.key() < rhs.key();
}
};

} // namespace model
} // namespace firestore
} // namespace firebase

#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MAYBE_DOCUMENT_H_
32 changes: 32 additions & 0 deletions Firestore/core/src/firebase/firestore/model/no_document.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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/no_document.h"

#include <utility>

namespace firebase {
namespace firestore {
namespace model {

NoDocument::NoDocument(DocumentKey key, SnapshotVersion version)
: MaybeDocument(std::move(key), std::move(version)) {
set_type(Type::NoDocument);
}

} // namespace model
} // namespace firestore
} // namespace firebase
Loading

0 comments on commit 9504582

Please sign in to comment.