Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
caosdb-cpplib
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
caosdb
Software
caosdb-cpplib
Commits
5449a831
Commit
5449a831
authored
3 years ago
by
Daniel Hornung
Browse files
Options
Downloads
Patches
Plain Diff
FIX: Workaround: manually parse and convert non-string values.
parent
965205da
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Pipeline
#12496
failed
3 years ago
Stage: info
Stage: setup
Stage: test
Stage: deploy
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/caosdb/entity.h
+20
-1
20 additions, 1 deletion
include/caosdb/entity.h
src/caosdb/entity.cpp
+121
-2
121 additions, 2 deletions
src/caosdb/entity.cpp
with
141 additions
and
3 deletions
include/caosdb/entity.h
+
20
−
1
View file @
5449a831
...
...
@@ -454,7 +454,9 @@ class Property {
public:
explicit
inline
Property
(
ProtoProperty
*
other
)
:
value
(
Value
(
other
->
mutable_value
())),
data_type
(
DataType
(
other
->
mutable_data_type
())),
wrapped
(
other
){};
wrapped
(
other
){
FixValue
();
};
Property
();
/**
...
...
@@ -551,6 +553,13 @@ public:
friend
class
RepeatedPtrFieldWrapper
<
Property
,
ProtoProperty
>
;
private
:
/**
* Workaround until non-string values are supported by the server.
*
* Only has an effect if there is a DataType.
*/
auto
FixValue
()
->
void
;
static
auto
CreateProtoProperty
()
->
ProtoProperty
*
;
Value
value
;
DataType
data_type
;
...
...
@@ -602,6 +611,7 @@ public:
errors
.
wrapped
=
CreateMessagesField
();
warnings
.
wrapped
=
CreateMessagesField
();
infos
.
wrapped
=
CreateMessagesField
();
FixValue
();
};
explicit
Entity
(
IdResponse
*
id_response
);
explicit
Entity
(
ProtoEntity
*
other
)
...
...
@@ -614,11 +624,13 @@ public:
errors
.
wrapped
=
CreateMessagesField
();
warnings
.
wrapped
=
CreateMessagesField
();
infos
.
wrapped
=
CreateMessagesField
();
FixValue
();
};
explicit
inline
Entity
(
EntityResponse
*
response
)
:
Entity
(
response
->
release_entity
())
{
errors
.
wrapped
->
Swap
(
response
->
mutable_errors
());
warnings
.
wrapped
->
Swap
(
response
->
mutable_warnings
());
infos
.
wrapped
->
Swap
(
response
->
mutable_infos
());
FixValue
();
};
[[
nodiscard
]]
inline
auto
GetId
()
const
noexcept
->
const
std
::
string
&
{
return
wrapped
->
id
();
};
...
...
@@ -744,6 +756,13 @@ private:
auto
SetId
(
const
std
::
string
&
id
)
->
void
;
auto
SetVersionId
(
const
std
::
string
&
id
)
->
void
;
/**
* Workaround until non-string values are supported by the server.
*
* Only has an effect if there is a DataType.
*/
auto
FixValue
()
->
void
;
private
:
FileDescriptor
file_descriptor
;
ProtoEntity
*
wrapped
;
...
...
This diff is collapsed.
Click to expand it.
src/caosdb/entity.cpp
+
121
−
2
View file @
5449a831
...
...
@@ -20,10 +20,12 @@
*
*/
#include
"caosdb/entity.h"
#include
"caosdb/exceptions.h"
#include
"caosdb/data_type.h"
// for DataType
#include
"caosdb/entity/v1alpha1/main.pb.h"
// for Messages
#include
"caosdb/protobuf_helper.h"
// for get_arena
#include
"caosdb/value.h"
// for Value
#include
<boost/algorithm/string.hpp>
#include
<google/protobuf/arena.h>
// for Arena
#include
<google/protobuf/generated_message_util.h>
// for Arena::Create...
#include
<new>
// for operator new
...
...
@@ -42,6 +44,13 @@ using google::protobuf::Arena;
Messages
::~
Messages
()
=
default
;
// Forward declarations ///////////////////////////////////////////////////////
template
<
typename
E
>
auto
FixValueImpl
(
E
*
ent
)
->
void
;
// Parent /////////////////////////////////////////////////////////////////////
Parent
::
Parent
()
:
wrapped
(
Parent
::
CreateProtoParent
())
{
// TODO(fspreck) Re-enable once we have decided how to attach
// messages to parents.
...
...
@@ -66,7 +75,9 @@ auto Parent::SetId(const std::string &id) -> void { this->wrapped->set_id(id); }
return
this
->
wrapped
->
description
();
}
Property
::
Property
()
:
Property
(
Property
::
CreateProtoProperty
())
{}
Property
::
Property
()
:
Property
(
Property
::
CreateProtoProperty
())
{
FixValue
();
}
auto
Property
::
CreateProtoProperty
()
->
ProtoProperty
*
{
return
Arena
::
CreateMessage
<
ProtoProperty
>
(
get_arena
());
...
...
@@ -152,6 +163,11 @@ auto Property::SetDataType(const std::string &new_data_type, bool list_type) ->
return
SetDataType
(
DataType
(
new_data_type
,
list_type
));
}
auto
Property
::
FixValue
()
->
void
{
FixValueImpl
(
this
);
}
// Entity /////////////////////////////////////////////////////////////////////
[[
nodiscard
]]
auto
Entity
::
GetParents
()
const
->
const
Parents
&
{
return
parents
;
}
auto
Entity
::
AppendParent
(
const
Parent
&
parent
)
->
void
{
this
->
parents
.
Append
(
parent
);
}
...
...
@@ -174,9 +190,12 @@ Entity::Entity(IdResponse *id_response) : Entity() {
this
->
errors
.
wrapped
->
Swap
(
id_response
->
mutable_errors
());
this
->
warnings
.
wrapped
->
Swap
(
id_response
->
mutable_warnings
());
this
->
infos
.
wrapped
->
Swap
(
id_response
->
mutable_infos
());
FixValue
();
}
Entity
::
Entity
()
:
Entity
(
Entity
::
CreateProtoEntity
())
{}
Entity
::
Entity
()
:
Entity
(
Entity
::
CreateProtoEntity
())
{
FixValue
();
}
auto
Entity
::
CreateMessagesField
()
->
RepeatedPtrField
<
ProtoMessage
>
*
{
return
Arena
::
CreateMessage
<
RepeatedPtrField
<
ProtoMessage
>>
(
get_arena
());
...
...
@@ -256,4 +275,104 @@ auto Entity::SetFilePath(const std::string &path) -> void {
this
->
wrapped
->
mutable_file_descriptor
()
->
set_path
(
path
);
}
auto
Entity
::
FixValue
()
->
void
{
FixValueImpl
(
this
);
}
// Utility functions //////////////////////////////////////////////////////////
template
<
typename
E
>
auto
FixValueImpl
(
E
*
ent
)
->
void
{
const
auto
&
dtype
=
ent
->
GetDataType
();
const
auto
&
value
=
ent
->
GetValue
();
auto
new_value
=
Value
();
if
(
value
.
IsNull
()
||
!
value
.
IsString
()){
// Don't treat NULL and non-string values.
return
;
}
if
(
value
.
IsList
())
{
// Also don't treat empty or non-string lists.
const
auto
&
list
=
value
.
AsList
();
if
(
list
.
empty
()
||
!
list
[
0
].
IsString
())
{
return
;
}
}
auto
atype
=
AtomicDataType
::
UNSPECIFIED
;
if
(
dtype
.
IsList
())
{
// List Datatype
if
(
!
value
.
IsList
())
{
throw
caosdb
::
exceptions
::
Exception
(
StatusCode
::
OTHER_CLIENT_ERROR
,
"DataType is list, but Value is scalar."
);
}
auto
&
list_type
=
dtype
.
AsList
();
atype
=
list_type
.
GetAtomicDataType
();
if
(
!
list_type
.
IsListOfAtomic
()
// References, strings etc. need no treatment.
||
atype
==
AtomicDataType
::
UNSPECIFIED
||
atype
==
AtomicDataType
::
TEXT
||
atype
==
AtomicDataType
::
DATETIME
)
{
return
;
}
if
(
atype
==
AtomicDataType
::
DOUBLE
)
{
std
::
vector
<
double
>
data
;
for
(
auto
&
d
:
value
.
AsList
())
{
data
.
push_back
(
std
::
stod
(
d
.
AsString
()));
}
new_value
=
Value
(
data
)
;
}
else
if
(
atype
==
AtomicDataType
::
INTEGER
)
{
std
::
vector
<
long
>
data
;
for
(
auto
&
d
:
value
.
AsList
())
{
data
.
push_back
(
std
::
stol
(
d
.
AsString
()));
}
new_value
=
Value
(
data
)
;
}
else
if
(
atype
==
AtomicDataType
::
BOOLEAN
)
{
std
::
vector
<
bool
>
data
;
for
(
auto
&
d
:
value
.
AsList
())
{
auto
bool_value
=
d
.
AsString
();
if
(
boost
::
to_upper_copy
(
bool_value
)
==
"TRUE"
)
{
data
.
push_back
(
true
);
}
else
if
(
boost
::
to_upper_copy
(
bool_value
)
==
"FALSE"
)
{
data
.
push_back
(
false
);
}
else
{
throw
caosdb
::
exceptions
::
Exception
(
StatusCode
::
OTHER_CLIENT_ERROR
,
"Boolean value is neither true nor false."
);
}
}
new_value
=
Value
(
data
)
;
}
else
{
std
::
cout
<<
"Unhandled datatype: "
<<
ent
->
ToString
()
<<
std
::
endl
;
throw
std
::
logic_error
(
"Unhandled datatype"
);
}
}
else
{
// Scalar Datatype
if
(
value
.
IsList
())
{
throw
caosdb
::
exceptions
::
Exception
(
StatusCode
::
OTHER_CLIENT_ERROR
,
"Value is list, but DataType is scalar."
);
}
atype
=
dtype
.
AsAtomic
();
if
(
!
dtype
.
IsAtomic
()
// References, strings etc. need no treatment.
||
atype
==
AtomicDataType
::
UNSPECIFIED
||
atype
==
AtomicDataType
::
TEXT
||
atype
==
AtomicDataType
::
DATETIME
)
{
return
;
}
if
(
atype
==
AtomicDataType
::
DOUBLE
)
{
new_value
=
Value
(
std
::
stod
(
value
.
AsString
()));
}
else
if
(
atype
==
AtomicDataType
::
INTEGER
)
{
new_value
=
Value
(
std
::
stol
(
value
.
AsString
()));
}
else
if
(
atype
==
AtomicDataType
::
BOOLEAN
)
{
auto
bool_value
=
value
.
AsString
();
if
(
boost
::
to_upper_copy
(
bool_value
)
==
"TRUE"
)
{
new_value
=
Value
(
true
);
}
else
if
(
boost
::
to_upper_copy
(
bool_value
)
==
"FALSE"
)
{
new_value
=
Value
(
false
);
}
else
{
throw
caosdb
::
exceptions
::
Exception
(
StatusCode
::
OTHER_CLIENT_ERROR
,
"Boolean value is neither true nor false."
);
}
}
else
{
std
::
cout
<<
"Unhandled datatype: "
<<
ent
->
ToString
()
<<
std
::
endl
;
throw
std
::
logic_error
(
"Unhandled datatype"
);
}
}
ent
->
SetValue
(
new_value
);
}
}
// namespace caosdb::entity
This diff is collapsed.
Click to expand it.
Daniel Hornung
@daniel
mentioned in commit
1c14d4dd
·
3 years ago
mentioned in commit
1c14d4dd
mentioned in commit 1c14d4ddd1bad5aaeff8f26e8dcad9de1cb1d7ec
Toggle commit list
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment