1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#include "addfieldpathupdate.h"
#include <vespa/document/fieldvalue/iteratorhandler.h>
#include <vespa/document/fieldvalue/arrayfieldvalue.h>
#include <vespa/document/fieldvalue/document.h>
#include <vespa/document/serialization/vespadocumentdeserializer.h>
#include <vespa/vespalib/objects/nbostream.h>
#include <vespa/vespalib/util/exceptions.h>
#include <ostream>
#include <cassert>
using vespalib::nbostream;
namespace document {
using namespace fieldvalue;
using vespalib::make_string;
AddFieldPathUpdate::AddFieldPathUpdate(const DataType& type, stringref fieldPath,
stringref whereClause, std::unique_ptr<ArrayFieldValue> values)
: FieldPathUpdate(Add, fieldPath, whereClause),
_values(std::move(values))
{
checkCompatibility(*_values, type);
}
AddFieldPathUpdate::AddFieldPathUpdate()
: FieldPathUpdate(Add),
_values()
{ }
AddFieldPathUpdate::~AddFieldPathUpdate() = default;
namespace {
class AddIteratorHandler : public fieldvalue::IteratorHandler {
public:
AddIteratorHandler(const ArrayFieldValue &values) : _values(values) {}
fieldvalue::ModificationStatus doModify(FieldValue &fv) override;
bool createMissingPath() const override { return true; }
bool onComplex(const fieldvalue::IteratorHandler::Content &) override { return false; }
private:
const ArrayFieldValue &_values;
};
ModificationStatus
AddIteratorHandler::doModify(FieldValue &fv) {
if (fv.isCollection()) {
auto &cf = static_cast<CollectionFieldValue &>(fv);
for (std::size_t i = 0; i < _values.size(); ++i) {
cf.add(_values[i]);
}
} else {
vespalib::string err = make_string("Unable to add a value to a \"%s\" field value.", fv.className());
throw vespalib::IllegalArgumentException(err, VESPA_STRLOC);
}
return ModificationStatus::MODIFIED;
}
}
bool
AddFieldPathUpdate::operator==(const FieldPathUpdate& other) const
{
if (!FieldPathUpdate::operator==(other)) return false;
const auto & addOther = static_cast<const AddFieldPathUpdate&>(other);
return *addOther._values == *_values;
}
void
AddFieldPathUpdate::print(std::ostream& out, bool verbose, const std::string& indent) const
{
out << "AddFieldPathUpdate(\n";
FieldPathUpdate::print(out, verbose, indent + " ");
out << ",\n" << indent << " " << "values=";
_values->print(out, verbose, indent + " ");
out << "\n" << indent << ")";
}
void
AddFieldPathUpdate::deserialize(const DocumentTypeRepo& repo, const DataType& type, nbostream & stream)
{
FieldPathUpdate::deserialize(repo, type, stream);
FieldPath path;
type.buildFieldPath(path, getOriginalFieldPath());
const DataType& fieldType = getResultingDataType(path);
assert(fieldType.isArray());
FieldValue::UP val = fieldType.createFieldValue();
_values.reset(static_cast<ArrayFieldValue*>(val.release()));
VespaDocumentDeserializer deserializer(repo, stream, Document::getNewestSerializationVersion());
deserializer.read(*_values);
}
std::unique_ptr<IteratorHandler>
AddFieldPathUpdate::getIteratorHandler(Document&, const DocumentTypeRepo &) const {
return std::make_unique<AddIteratorHandler>(*_values);
}
} // ns document
|