Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
3eb7e4c5
Unverified
Commit
3eb7e4c5
authored
Apr 21, 2021
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Potential fix
parent
fd08678f
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
468 additions
and
82 deletions
+468
-82
include/cif++/Cif++.hpp
+69
-32
src/Cif++.cpp
+151
-0
test/RXA.cif
+189
-0
test/unit-test.cpp
+59
-50
No files found.
include/cif++/Cif++.hpp
View file @
3eb7e4c5
...
@@ -1115,6 +1115,20 @@ Condition operator==(const Key& key, const T& v)
...
@@ -1115,6 +1115,20 @@ Condition operator==(const Key& key, const T& v)
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
==
0
;
},
s
.
str
()));
{
return
r
[
tag
].
template
compare
<
T
>
(
v
,
icase
)
==
0
;
},
s
.
str
()));
}
}
inline
Condition
operator
==
(
const
Key
&
key
,
const
char
*
value
)
{
if
(
value
!=
nullptr
and
*
value
!=
0
)
{
std
::
ostringstream
s
;
s
<<
" == "
<<
value
;
return
Condition
(
new
detail
::
KeyCompareConditionImpl
(
key
.
mItemTag
,
[
tag
=
key
.
mItemTag
,
value
](
const
Category
&
c
,
const
Row
&
r
,
bool
icase
)
{
return
r
[
tag
].
compare
(
value
,
icase
)
==
0
;
},
s
.
str
()));
}
else
return
Condition
(
new
detail
::
KeyIsEmptyConditionImpl
(
key
.
mItemTag
));
}
// inline Condition operator==(const Key& key, const detail::ItemReference& v)
// inline Condition operator==(const Key& key, const detail::ItemReference& v)
// {
// {
// if (v.empty())
// if (v.empty())
...
@@ -1537,23 +1551,24 @@ class RowSet
...
@@ -1537,23 +1551,24 @@ class RowSet
typedef
std
::
vector
<
Row
>
base_type
;
typedef
std
::
vector
<
Row
>
base_type
;
public
:
public
:
using
size_type
=
std
::
size_t
;
using
size_type
=
std
::
size_t
;
using
difference_type
=
std
::
ptrdiff_t
;
using
difference_type
=
std
::
ptrdiff_t
;
RowSet
(
Category
&
cat
);
RowSet
(
Category
&
cat
);
RowSet
(
Category
&
cat
,
Condition
&&
cond
);
RowSet
(
Category
&
cat
,
Condition
&&
cond
);
RowSet
(
const
RowSet
&
rhs
);
RowSet
(
const
RowSet
&
rhs
);
RowSet
(
RowSet
&&
rhs
);
RowSet
(
RowSet
&&
rhs
);
virtual
~
RowSet
();
virtual
~
RowSet
();
RowSet
&
operator
=
(
const
RowSet
&
rhs
);
RowSet
&
operator
=
(
const
RowSet
&
rhs
);
RowSet
&
operator
=
(
RowSet
&&
rhs
);
RowSet
&
operator
=
(
RowSet
&&
rhs
);
RowSet
&
orderBy
(
const
std
::
string
&
Item
)
RowSet
&
orderBy
(
const
std
::
string
&
Item
)
{
return
orderBy
({
Item
});
}
{
return
orderBy
({
Item
});
}
RowSet
&
orderBy
(
std
::
initializer_list
<
std
::
string
>
Items
);
RowSet
&
orderBy
(
std
::
initializer_list
<
std
::
string
>
Items
);
class
iterator
class
iterator
{
{
...
@@ -1561,22 +1576,26 @@ class RowSet
...
@@ -1561,22 +1576,26 @@ class RowSet
using
iterator_category
=
std
::
forward_iterator_tag
;
using
iterator_category
=
std
::
forward_iterator_tag
;
using
value_type
=
Row
;
using
value_type
=
Row
;
using
difference_type
=
std
::
ptrdiff_t
;
using
difference_type
=
std
::
ptrdiff_t
;
using
pointer
=
value_type
*
;
using
pointer
=
value_type
*
;
using
reference
=
value_type
&
;
using
reference
=
value_type
&
;
iterator
()
{}
iterator
()
{}
iterator
(
const
iterator
&
i
)
iterator
(
const
iterator
&
i
)
:
mPos
(
i
.
mPos
)
:
mPos
(
i
.
mPos
)
,
mEnd
(
i
.
mEnd
)
,
mEnd
(
i
.
mEnd
)
,
mCurrentRow
(
i
.
mCurrentRow
)
{}
,
mCurrentRow
(
i
.
mCurrentRow
)
{
}
iterator
(
const
std
::
vector
<
ItemRow
*>::
iterator
&
p
,
const
std
::
vector
<
ItemRow
*>::
iterator
&
e
)
iterator
(
const
std
::
vector
<
ItemRow
*>::
iterator
&
p
,
const
std
::
vector
<
ItemRow
*>::
iterator
&
e
)
:
mPos
(
p
)
:
mPos
(
p
)
,
mEnd
(
e
)
,
mEnd
(
e
)
,
mCurrentRow
(
p
==
e
?
nullptr
:
*
p
)
{}
,
mCurrentRow
(
p
==
e
?
nullptr
:
*
p
)
{
}
iterator
&
operator
=
(
const
iterator
&
i
)
iterator
&
operator
=
(
const
iterator
&
i
)
{
{
mPos
=
i
.
mPos
;
mPos
=
i
.
mPos
;
mEnd
=
i
.
mEnd
;
mEnd
=
i
.
mEnd
;
...
@@ -1587,7 +1606,7 @@ class RowSet
...
@@ -1587,7 +1606,7 @@ class RowSet
reference
operator
*
()
{
return
mCurrentRow
;
}
reference
operator
*
()
{
return
mCurrentRow
;
}
pointer
operator
->
()
{
return
&
mCurrentRow
;
}
pointer
operator
->
()
{
return
&
mCurrentRow
;
}
iterator
&
operator
++
()
iterator
&
operator
++
()
{
{
++
mPos
;
++
mPos
;
if
(
mPos
!=
mEnd
)
if
(
mPos
!=
mEnd
)
...
@@ -1604,9 +1623,10 @@ class RowSet
...
@@ -1604,9 +1623,10 @@ class RowSet
return
t
;
return
t
;
}
}
iterator
&
operator
+=
(
difference_type
i
)
iterator
&
operator
+=
(
difference_type
i
)
{
{
while
(
i
--
>
0
)
operator
++
();
while
(
i
--
>
0
)
operator
++
();
return
*
this
;
return
*
this
;
}
}
...
@@ -1617,28 +1637,27 @@ class RowSet
...
@@ -1617,28 +1637,27 @@ class RowSet
return
result
;
return
result
;
}
}
friend
iterator
operator
+
(
difference_type
i
,
const
iterator
&
iter
)
friend
iterator
operator
+
(
difference_type
i
,
const
iterator
&
iter
)
{
{
auto
result
=
iter
;
auto
result
=
iter
;
result
+=
i
;
result
+=
i
;
return
result
;
return
result
;
}
}
friend
difference_type
operator
-
(
const
iterator
&
a
,
const
iterator
&
b
)
friend
difference_type
operator
-
(
const
iterator
&
a
,
const
iterator
&
b
)
{
{
return
std
::
distance
(
a
.
mPos
,
b
.
mPos
);
return
std
::
distance
(
a
.
mPos
,
b
.
mPos
);
}
}
bool
operator
==
(
const
iterator
&
i
)
const
{
return
mPos
==
i
.
mPos
;
}
bool
operator
==
(
const
iterator
&
i
)
const
{
return
mPos
==
i
.
mPos
;
}
bool
operator
!=
(
const
iterator
&
i
)
const
{
return
mPos
!=
i
.
mPos
;
}
bool
operator
!=
(
const
iterator
&
i
)
const
{
return
mPos
!=
i
.
mPos
;
}
private
:
private
:
friend
class
RowSet
;
friend
class
RowSet
;
std
::
vector
<
ItemRow
*>::
iterator
current
()
const
{
return
mPos
;
}
std
::
vector
<
ItemRow
*>::
iterator
current
()
const
{
return
mPos
;
}
std
::
vector
<
ItemRow
*>::
iterator
mPos
,
mEnd
;
std
::
vector
<
ItemRow
*>::
iterator
mPos
,
mEnd
;
Row
mCurrentRow
;
Row
mCurrentRow
;
};
};
...
@@ -1649,7 +1668,7 @@ class RowSet
...
@@ -1649,7 +1668,7 @@ class RowSet
size_t
size
()
const
{
return
mItems
.
size
();
}
size_t
size
()
const
{
return
mItems
.
size
();
}
bool
empty
()
const
{
return
mItems
.
empty
();
}
bool
empty
()
const
{
return
mItems
.
empty
();
}
template
<
typename
InputIterator
>
template
<
typename
InputIterator
>
iterator
insert
(
iterator
pos
,
InputIterator
b
,
InputIterator
e
)
iterator
insert
(
iterator
pos
,
InputIterator
b
,
InputIterator
e
)
{
{
difference_type
offset
=
pos
-
begin
();
difference_type
offset
=
pos
-
begin
();
...
@@ -1658,17 +1677,27 @@ class RowSet
...
@@ -1658,17 +1677,27 @@ class RowSet
return
begin
()
+
offset
;
return
begin
()
+
offset
;
}
}
iterator
insert
(
iterator
pos
,
Row
&
row
)
iterator
insert
(
iterator
pos
,
Row
&
row
)
{
{
return
insert
(
pos
,
row
.
mData
);
return
insert
(
pos
,
row
.
mData
);
}
}
iterator
insert
(
iterator
pos
,
ItemRow
*
item
)
iterator
insert
(
iterator
pos
,
ItemRow
*
item
)
{
{
auto
p
=
mItems
.
insert
(
pos
.
current
(),
item
);
auto
p
=
mItems
.
insert
(
pos
.
current
(),
item
);
return
iterator
(
p
,
mItems
.
end
());
return
iterator
(
p
,
mItems
.
end
());
}
}
iterator
push_back
(
ItemRow
*
item
)
{
return
insert
(
end
(),
item
);
}
iterator
push_back
(
Row
&
row
)
{
return
insert
(
end
(),
row
.
mData
);
}
void
make_unique
()
void
make_unique
()
{
{
std
::
sort
(
mItems
.
begin
(),
mItems
.
end
());
std
::
sort
(
mItems
.
begin
(),
mItems
.
end
());
...
@@ -1676,8 +1705,8 @@ class RowSet
...
@@ -1676,8 +1705,8 @@ class RowSet
}
}
private
:
private
:
Category
*
mCat
;
Category
*
mCat
;
std
::
vector
<
ItemRow
*>
mItems
;
std
::
vector
<
ItemRow
*>
mItems
;
// Condition* mCond;
// Condition* mCond;
};
};
...
@@ -1819,6 +1848,10 @@ class Category
...
@@ -1819,6 +1848,10 @@ class Category
void
erase
(
Row
r
);
void
erase
(
Row
r
);
iterator
erase
(
iterator
ri
);
iterator
erase
(
iterator
ri
);
/// \brief Create a copy of Row \a r and return the copy. If this row has
/// a single key field, this will be updated with a new unique value.
Row
copyRow
(
const
Row
&
r
);
// erase without cascade, should only be used when speed is needed
// erase without cascade, should only be used when speed is needed
size_t
erase_nocascade
(
Condition
&&
cond
)
size_t
erase_nocascade
(
Condition
&&
cond
)
...
@@ -1900,6 +1933,10 @@ class Category
...
@@ -1900,6 +1933,10 @@ class Category
// a sequence number. This function will be called until the result is
// a sequence number. This function will be called until the result is
// unique in the context of this category
// unique in the context of this category
std
::
string
getUniqueID
(
std
::
function
<
std
::
string
(
int
)
>
generator
=
cif
::
cifIdForNumber
);
std
::
string
getUniqueID
(
std
::
function
<
std
::
string
(
int
)
>
generator
=
cif
::
cifIdForNumber
);
std
::
string
getUniqueID
(
const
std
::
string
&
prefix
)
{
return
getUniqueID
([
prefix
](
int
nr
)
{
return
prefix
+
std
::
to_string
(
nr
);
});
}
private
:
private
:
...
...
src/Cif++.cpp
View file @
3eb7e4c5
...
@@ -1745,6 +1745,36 @@ auto Category::erase(iterator pos) -> iterator
...
@@ -1745,6 +1745,36 @@ auto Category::erase(iterator pos) -> iterator
return
result
;
return
result
;
}
}
Row
Category
::
copyRow
(
const
Row
&
row
)
{
// copy the values
std
::
vector
<
Item
>
items
;
std
::
copy
(
row
.
begin
(),
row
.
end
(),
std
::
back_inserter
(
items
));
if
(
mCatValidator
and
mCatValidator
->
mKeys
.
size
()
==
1
)
{
auto
key
=
mCatValidator
->
mKeys
.
front
();
auto
kv
=
mCatValidator
->
getValidatorForItem
(
key
);
for
(
auto
&
item
:
items
)
{
if
(
item
.
name
()
!=
key
)
continue
;
if
(
kv
->
mType
->
mPrimitiveType
==
DDL_PrimitiveType
::
Numb
)
item
.
value
(
getUniqueID
(
""
));
else
item
.
value
(
getUniqueID
(
mName
+
"_id_"
));
break
;
}
}
auto
&&
[
result
,
inserted
]
=
emplace
(
items
.
begin
(),
items
.
end
());
// assert(inserted);
return
result
;
}
void
Category
::
getTagOrder
(
std
::
vector
<
std
::
string
>&
tags
)
const
void
Category
::
getTagOrder
(
std
::
vector
<
std
::
string
>&
tags
)
const
{
{
for
(
auto
&
c
:
mColumns
)
for
(
auto
&
c
:
mColumns
)
...
@@ -2400,6 +2430,127 @@ void Category::write(std::ostream& os, const std::vector<std::string>& columns)
...
@@ -2400,6 +2430,127 @@ void Category::write(std::ostream& os, const std::vector<std::string>& columns)
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
Category
::
update_value
(
RowSet
&&
rows
,
const
std
::
string
&
tag
,
const
std
::
string
&
value
)
{
if
(
rows
.
empty
())
return
;
auto
colIx
=
getColumnIndex
(
tag
);
if
(
colIx
>=
mColumns
.
size
())
throw
std
::
runtime_error
(
"Invalid column "
+
value
+
" for "
+
mName
);
auto
&
col
=
mColumns
[
colIx
];
// check the value
if
(
col
.
mValidator
)
(
*
col
.
mValidator
)(
value
);
// first some sanity checks, what was the old value and is it the same for all rows?
std
::
string
oldValue
=
rows
.
front
()[
tag
].
c_str
();
for
(
auto
&
row
:
rows
)
{
if
(
oldValue
!=
row
[
tag
].
c_str
())
throw
std
::
runtime_error
(
"Inconsistent old values in update_value"
);
}
if
(
oldValue
==
value
)
// no need to do anything
return
;
// update rows, but do not cascade
for
(
auto
&
row
:
rows
)
row
.
assign
(
colIx
,
value
,
true
);
// see if we need to update any child categories that depend on this value
auto
&
validator
=
getValidator
();
auto
&
db
=
mDb
;
for
(
auto
parent
:
rows
)
{
for
(
auto
linked
:
validator
.
getLinksForParent
(
mName
))
{
auto
childCat
=
db
.
get
(
linked
->
mChildCategory
);
if
(
childCat
==
nullptr
)
continue
;
if
(
std
::
find
(
linked
->
mParentKeys
.
begin
(),
linked
->
mParentKeys
.
end
(),
tag
)
==
linked
->
mParentKeys
.
end
())
continue
;
Condition
cond
;
std
::
string
childTag
;
for
(
size_t
ix
=
0
;
ix
<
linked
->
mParentKeys
.
size
();
++
ix
)
{
std
::
string
pk
=
linked
->
mParentKeys
[
ix
];
std
::
string
ck
=
linked
->
mChildKeys
[
ix
];
// TODO add code to *NOT* test mandatory fields for Empty
if
(
pk
==
tag
)
{
childTag
=
ck
;
cond
=
std
::
move
(
cond
)
&&
Key
(
ck
)
==
oldValue
;
}
else
cond
=
std
::
move
(
cond
)
&&
Key
(
ck
)
==
parent
[
pk
].
c_str
();
}
auto
children
=
RowSet
{
*
childCat
,
std
::
move
(
cond
)
};
if
(
children
.
empty
())
continue
;
// now be careful. If we search back from child to parent and still find a valid parent row
// we cannot simply rename the child but will have to create a new child. Unless that new
// child already exists of course.
for
(
auto
child
:
children
)
{
Condition
cond
;
for
(
size_t
ix
=
0
;
ix
<
linked
->
mParentKeys
.
size
();
++
ix
)
{
std
::
string
pk
=
linked
->
mParentKeys
[
ix
];
std
::
string
ck
=
linked
->
mChildKeys
[
ix
];
// TODO add code to *NOT* test mandatory fields for Empty
cond
=
std
::
move
(
cond
)
&&
Key
(
pk
)
==
child
[
ck
].
c_str
();
}
auto
parents
=
find
(
std
::
move
(
cond
));
if
(
parents
.
empty
())
continue
;
// oops, we need to split this child, unless a row already exists for the new value
Condition
check
;
for
(
size_t
ix
=
0
;
ix
<
linked
->
mParentKeys
.
size
();
++
ix
)
{
std
::
string
pk
=
linked
->
mParentKeys
[
ix
];
std
::
string
ck
=
linked
->
mChildKeys
[
ix
];
// TODO add code to *NOT* test mandatory fields for Empty
if
(
pk
==
tag
)
check
=
std
::
move
(
check
)
&&
Key
(
ck
)
==
value
;
else
check
=
std
::
move
(
check
)
&&
Key
(
ck
)
==
parent
[
pk
].
c_str
();
}
if
(
childCat
->
exists
(
std
::
move
(
check
)))
// phew..., narrow escape
continue
;
// create the actual copy
childCat
->
copyRow
(
child
);
}
// finally, update the children
childCat
->
update_value
(
std
::
move
(
children
),
childTag
,
value
);
}
}
}
// --------------------------------------------------------------------
Row
::
Row
(
const
Row
&
rhs
)
Row
::
Row
(
const
Row
&
rhs
)
:
mData
(
rhs
.
mData
)
:
mData
(
rhs
.
mData
)
,
mCascade
(
rhs
.
mCascade
)
,
mCascade
(
rhs
.
mCascade
)
...
...
test/RXA.cif
0 → 100644
View file @
3eb7e4c5
data_RXA
#
_chem_comp.id RXA
_chem_comp.name "RENAMED RETINOIC ACID"
_chem_comp.type NON-POLYMER
_chem_comp.pdbx_type HETAIN
_chem_comp.formula "C20 H28 O2"
_chem_comp.mon_nstd_parent_comp_id ?
_chem_comp.pdbx_synonyms ?
_chem_comp.pdbx_formal_charge 0
_chem_comp.pdbx_initial_date 1999-07-08
_chem_comp.pdbx_modified_date 2016-10-18
_chem_comp.pdbx_ambiguous_flag N
_chem_comp.pdbx_release_status REL
_chem_comp.pdbx_replaced_by ?
_chem_comp.pdbx_replaces 3KV
_chem_comp.formula_weight 300.435
_chem_comp.one_letter_code ?
_chem_comp.three_letter_code RXA
_chem_comp.pdbx_model_coordinates_details ?
_chem_comp.pdbx_model_coordinates_missing_flag N
_chem_comp.pdbx_ideal_coordinates_details Corina
_chem_comp.pdbx_ideal_coordinates_missing_flag N
_chem_comp.pdbx_model_coordinates_db_code 1CBS
_chem_comp.pdbx_subcomponent_list ?
_chem_comp.pdbx_processing_site RCSB
#
loop_
_chem_comp_atom.comp_id
_chem_comp_atom.atom_id
_chem_comp_atom.alt_atom_id
_chem_comp_atom.type_symbol
_chem_comp_atom.charge
_chem_comp_atom.pdbx_align
_chem_comp_atom.pdbx_aromatic_flag
_chem_comp_atom.pdbx_leaving_atom_flag
_chem_comp_atom.pdbx_stereo_config
_chem_comp_atom.model_Cartn_x
_chem_comp_atom.model_Cartn_y
_chem_comp_atom.model_Cartn_z
_chem_comp_atom.pdbx_model_Cartn_x_ideal
_chem_comp_atom.pdbx_model_Cartn_y_ideal
_chem_comp_atom.pdbx_model_Cartn_z_ideal
_chem_comp_atom.pdbx_component_atom_id
_chem_comp_atom.pdbx_component_comp_id
_chem_comp_atom.pdbx_ordinal
RXA C1 C1 C 0 1 N N N 21.972 29.831 16.739 -4.684 0.932 -0.497 C1 RXA 1
RXA C2 C2 C 0 1 N N N 20.921 30.524 15.841 -5.837 0.190 -1.176 C2 RXA 2
RXA C3 C3 C 0 1 N N N 20.245 29.635 14.848 -6.441 -0.798 -0.171 C3 RXA 3
RXA C4 C4 C 0 1 N N N 19.555 28.479 15.488 -5.418 -1.903 0.100 C4 RXA 4
RXA C5 C5 C 0 1 N N N 20.389 27.812 16.587 -4.082 -1.301 0.429 C5 RXA 5
RXA C6 C6 C 0 1 N N N 21.425 28.446 17.218 -3.756 -0.048 0.161 C6 RXA 6
RXA C7 C7 C 0 1 N N N 22.242 27.851 18.297 -2.457 0.396 0.516 C7 RXA 7
RXA C8 C8 C 0 1 N N N 21.868 26.977 19.240 -1.363 -0.229 0.007 C8 RXA 8
RXA C9 C9 C 0 1 N N N 22.705 26.434 20.286 -0.076 0.257 0.298 C9 RXA 9
RXA C10 C10 C 0 1 N N N 22.159 25.536 21.131 1.022 -0.370 -0.213 C10 RXA 10
RXA C11 C11 C 0 1 N N N 22.875 24.924 22.234 2.306 0.115 0.077 C11 RXA 11
RXA C12 C12 C 0 1 N N N 22.237 24.026 22.990 3.405 -0.513 -0.435 C12 RXA 12
RXA C13 C13 C 0 1 N N N 22.856 23.377 24.125 4.689 -0.028 -0.144 C13 RXA 13
RXA C14 C14 C 0 1 N N N 22.135 22.473 24.834 5.787 -0.655 -0.656 C14 RXA 14
RXA C15 C15 C 0 1 N N N 22.563 21.710 26.016 7.077 -0.265 -0.244 C15 RXA 15
RXA C16 C16 C 0 1 N N N 22.238 30.737 17.948 -5.246 1.886 0.559 C16 RXA 16
RXA C17 C17 C 0 1 N N N 23.292 29.620 15.948 -3.911 1.737 -1.544 C17 RXA 17
RXA C18 C18 C 0 1 N N N 19.791 26.449 16.947 -3.056 -2.175 1.103 C18 RXA 18
RXA C19 C19 C 0 1 N N N 24.181 26.841 20.385 0.090 1.471 1.175 C19 RXA 19
RXA C20 C20 C 0 1 N N N 24.303 23.747 24.489 4.855 1.186 0.733 C20 RXA 20
RXA O1 O1 O 0 1 N N N 23.640 21.075 25.978 7.210 0.553 0.648 O1 RXA 21
RXA O2 O2 O 0 1 N N N 21.840 21.712 27.037 8.166 -0.798 -0.840 O2 RXA 22
RXA H21 H21 H 0 1 N N N 20.147 30.955 16.494 -6.598 0.905 -1.490 H21 RXA 23
RXA H22 H22 H 0 1 N N N 21.425 31.330 15.288 -5.462 -0.353 -2.044 H22 RXA 24
RXA H31 H31 H 0 1 N N N 19.501 30.227 14.295 -6.673 -0.278 0.759 H31 RXA 25
RXA H32 H32 H 0 1 N N N 21.001 29.250 14.148 -7.349 -1.234 -0.586 H32 RXA 26
RXA H41 H41 H 0 1 N N N 18.613 28.835 15.931 -5.756 -2.511 0.938 H41 RXA 27
RXA H42 H42 H 0 1 N N N 19.335 27.730 14.713 -5.322 -2.531 -0.786 H42 RXA 28
RXA H7 H7 H 0 1 N N N 23.276 28.162 18.329 -2.337 1.230 1.191 H7 RXA 29
RXA H8 H8 H 0 1 N N N 20.840 26.645 19.217 -1.482 -1.100 -0.622 H8 RXA 30
RXA H10 H10 H 0 1 N N N 21.127 25.256 20.977 0.903 -1.241 -0.842 H10 RXA 31
RXA H11 H11 H 0 1 N N N 23.902 25.189 22.440 2.425 0.985 0.706 H11 RXA 32
RXA H12 H12 H 0 1 N N N 21.216 23.774 22.743 3.286 -1.383 -1.063 H12 RXA 33
RXA H14 H14 H 0 1 N N N 21.127 22.292 24.490 5.667 -1.451 -1.376 H14 RXA 34
RXA H161 H161 H 0 0 N N N 22.984 30.265 18.604 -5.802 1.316 1.303 H161 RXA 35
RXA H162 H162 H 0 0 N N N 22.618 31.709 17.601 -4.426 2.415 1.044 H162 RXA 36
RXA H163 H163 H 0 0 N N N 21.302 30.887 18.506 -5.911 2.605 0.081 H163 RXA 37
RXA H171 H171 H 0 0 N N N 24.033 29.127 16.595 -4.598 2.394 -2.077 H171 RXA 38
RXA H172 H172 H 0 0 N N N 23.095 28.989 15.069 -3.146 2.335 -1.050 H172 RXA 39
RXA H173 H173 H 0 0 N N N 23.683 30.595 15.620 -3.439 1.054 -2.251 H173 RXA 40
RXA H181 H181 H 0 0 N N N 20.397 25.979 17.736 -3.448 -3.187 1.201 H181 RXA 41
RXA H182 H182 H 0 0 N N N 18.761 26.584 17.308 -2.145 -2.194 0.503 H182 RXA 42
RXA H183 H183 H 0 0 N N N 19.786 25.804 16.056 -2.831 -1.775 2.092 H183 RXA 43
RXA H191 H191 H 0 0 N N N 24.647 26.327 21.238 0.171 1.159 2.216 H191 RXA 44
RXA H192 H192 H 0 0 N N N 24.702 26.559 19.458 0.993 2.008 0.885 H192 RXA 45
RXA H193 H193 H 0 0 N N N 24.252 27.929 20.529 -0.774 2.125 1.058 H193 RXA 46
RXA H201 H201 H 0 0 N N N 24.620 23.168 25.369 5.026 0.871 1.762 H201 RXA 47
RXA H202 H202 H 0 0 N N N 24.965 23.516 23.641 5.707 1.771 0.386 H202 RXA 48
RXA H203 H203 H 0 0 N N N 24.360 24.822 24.717 3.952 1.795 0.685 H203 RXA 49
RXA HO2 HO2 H 0 1 N N N 22.244 21.180 27.713 9.006 -0.469 -0.490 HO2 RXA 50
#
loop_
_chem_comp_bond.comp_id
_chem_comp_bond.atom_id_1
_chem_comp_bond.atom_id_2
_chem_comp_bond.value_order
_chem_comp_bond.pdbx_aromatic_flag
_chem_comp_bond.pdbx_stereo_config
_chem_comp_bond.pdbx_ordinal
RXA C1 C2 SING N N 1
RXA C1 C6 SING N N 2
RXA C1 C16 SING N N 3
RXA C1 C17 SING N N 4
RXA C2 C3 SING N N 5
RXA C2 H21 SING N N 6
RXA C2 H22 SING N N 7
RXA C3 C4 SING N N 8
RXA C3 H31 SING N N 9
RXA C3 H32 SING N N 10
RXA C4 C5 SING N N 11
RXA C4 H41 SING N N 12
RXA C4 H42 SING N N 13
RXA C5 C6 DOUB N N 14
RXA C5 C18 SING N N 15
RXA C6 C7 SING N N 16
RXA C7 C8 DOUB N E 17
RXA C7 H7 SING N N 18
RXA C8 C9 SING N N 19
RXA C8 H8 SING N N 20
RXA C9 C10 DOUB N E 21
RXA C9 C19 SING N N 22
RXA C10 C11 SING N N 23
RXA C10 H10 SING N N 24
RXA C11 C12 DOUB N E 25
RXA C11 H11 SING N N 26
RXA C12 C13 SING N N 27
RXA C12 H12 SING N N 28
RXA C13 C14 DOUB N E 29
RXA C13 C20 SING N N 30
RXA C14 C15 SING N N 31
RXA C14 H14 SING N N 32
RXA C15 O1 DOUB N N 33
RXA C15 O2 SING N N 34
RXA C16 H161 SING N N 35
RXA C16 H162 SING N N 36
RXA C16 H163 SING N N 37
RXA C17 H171 SING N N 38
RXA C17 H172 SING N N 39
RXA C17 H173 SING N N 40
RXA C18 H181 SING N N 41
RXA C18 H182 SING N N 42
RXA C18 H183 SING N N 43
RXA C19 H191 SING N N 44
RXA C19 H192 SING N N 45
RXA C19 H193 SING N N 46
RXA C20 H201 SING N N 47
RXA C20 H202 SING N N 48
RXA C20 H203 SING N N 49
RXA O2 HO2 SING N N 50
#
loop_
_pdbx_chem_comp_descriptor.comp_id
_pdbx_chem_comp_descriptor.type
_pdbx_chem_comp_descriptor.program
_pdbx_chem_comp_descriptor.program_version
_pdbx_chem_comp_descriptor.descriptor
RXA SMILES ACDLabs 12.01 "C1(CCCC(=C1\C=C\C(=C\C=C\C(=C\C(=O)O)C)C)C)(C)C"
RXA InChI InChI 1.03 "InChI=1S/C20H28O2/c1-15(8-6-9-16(2)14-19(21)22)11-12-18-17(3)10-7-13-20(18,4)5/h6,8-9,11-12,14H,7,10,13H2,1-5H3,(H,21,22)/b9-6+,12-11+,15-8+,16-14+"
RXA InChIKey InChI 1.03 SHGAZHPCJJPHSC-YCNIQYBTSA-N
RXA SMILES_CANONICAL CACTVS 3.385 "CC1=C(\C=C\C(C)=C\C=C\C(C)=C\C(O)=O)C(C)(C)CCC1"
RXA SMILES CACTVS 3.385 "CC1=C(C=CC(C)=CC=CC(C)=CC(O)=O)C(C)(C)CCC1"
RXA SMILES_CANONICAL "OpenEye OEToolkits" 1.7.6 "CC1=C(C(CCC1)(C)C)/C=C/C(=C/C=C/C(=C/C(=O)O)/C)/C"
RXA SMILES "OpenEye OEToolkits" 1.7.6 "CC1=C(C(CCC1)(C)C)C=CC(=CC=CC(=CC(=O)O)C)C"
#
loop_
_pdbx_chem_comp_identifier.comp_id
_pdbx_chem_comp_identifier.type
_pdbx_chem_comp_identifier.program
_pdbx_chem_comp_identifier.program_version
_pdbx_chem_comp_identifier.identifier
RXA "SYSTEMATIC NAME" ACDLabs 12.01 "retinoic acid"
RXA "SYSTEMATIC NAME" "OpenEye OEToolkits" 1.7.6 "(2E,4E,6E,8E)-3,7-dimethyl-9-(2,6,6-trimethylcyclohexen-1-yl)nona-2,4,6,8-tetraenoic acid"
#
loop_
_pdbx_chem_comp_audit.comp_id
_pdbx_chem_comp_audit.action_type
_pdbx_chem_comp_audit.date
_pdbx_chem_comp_audit.processing_site
RXA "Create component" 1999-07-08 RCSB
RXA "Modify descriptor" 2011-06-04 RCSB
RXA "Other modification" 2016-10-18 RCSB
#
test/unit-test.cpp
View file @
3eb7e4c5
...
@@ -1271,7 +1271,7 @@ save__cat_1.id
...
@@ -1271,7 +1271,7 @@ save__cat_1.id
_item.mandatory_code yes
_item.mandatory_code yes
_item_linked.child_name '_cat_2.parent_id'
_item_linked.child_name '_cat_2.parent_id'
_item_linked.parent_name '_cat_1.id'
_item_linked.parent_name '_cat_1.id'
_item_type.code
code
_item_type.code
int
save_
save_
save__cat_1.name
save__cat_1.name
...
@@ -1396,7 +1396,6 @@ _cat_2.desc
...
@@ -1396,7 +1396,6 @@ _cat_2.desc
1 aap 1 'Een dier'
1 aap 1 'Een dier'
2 aap 2 'Een andere aap'
2 aap 2 'Een andere aap'
3 noot 1 'walnoot bijvoorbeeld'
3 noot 1 'walnoot bijvoorbeeld'
4 n2 1 hazelnoot
loop_
loop_
_cat_3.id
_cat_3.id
...
@@ -1439,63 +1438,73 @@ _cat_3.num
...
@@ -1439,63 +1438,73 @@ _cat_3.num
BOOST_CHECK
(
num
==
2
);
BOOST_CHECK
(
num
==
2
);
BOOST_CHECK
(
name
==
"aap"
);
BOOST_CHECK
(
name
==
"aap"
);
int
i
=
0
;
for
(
const
auto
&
[
id
,
name
,
num
,
desc
]
:
cat2
.
rows
<
int
,
std
::
string
,
int
,
std
::
string
>
({
"id"
,
"name"
,
"num"
,
"desc"
}))
{
switch
(
++
i
)
{
case
1
:
BOOST_CHECK
(
id
==
1
);
BOOST_CHECK
(
num
==
1
);
BOOST_CHECK
(
name
==
"aapje"
);
BOOST_CHECK
(
desc
==
"Een dier"
);
break
;
case
2
:
BOOST_CHECK
(
id
==
2
);
BOOST_CHECK
(
num
==
2
);
BOOST_CHECK
(
name
==
"aap"
);
BOOST_CHECK
(
desc
==
"Een andere aap"
);
break
;
// // check a rename in parent and child
case
3
:
BOOST_CHECK
(
id
==
3
);
// for (auto r: cat1.find(cif::Key("id") == 1))
BOOST_CHECK
(
num
==
1
);
// {
BOOST_CHECK
(
name
==
"noot"
);
// r["id"] = 10;
BOOST_CHECK
(
desc
==
"walnoot bijvoorbeeld"
);
// break;
break
;
// }
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat1.find(cif::Key("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::Key("id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 10).size() == 2);
// // check a rename in parent and child, this time only one child should be renamed
// for (auto r: cat1.find(cif::Key("id") == 2))
// {
// r["id"] = 20;
// break;
// }
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat1.find(cif::Key("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::Key("id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 2).size() == 1);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 2 and cif::Key("name2") == "noot").size() == 0);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 2 and cif::Key("name2") == "n2").size() == 1);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 20 and cif::Key("name2") == "noot").size() == 1);
// BOOST_CHECK(cat2.find(cif::Key("parent_id") == 20 and cif::Key("name2") == "n2").size() == 0);
// // // --------------------------------------------------------------------
// // cat1.erase(cif::Key("id") == 10);
default
:
BOOST_FAIL
(
"Unexpected record"
);
}
}
// // BOOST_CHECK(cat1.size() == 2);
BOOST_CHECK
(
cat1
.
size
()
==
4
);
// // BOOST_CHECK(cat2.size() == 2);
i
=
0
;
for
(
const
auto
&
[
id
,
name
,
desc
]
:
cat1
.
rows
<
int
,
std
::
string
,
std
::
string
>
({
"id"
,
"name"
,
"desc"
}))
{
switch
(
++
i
)
{
case
1
:
BOOST_CHECK
(
id
==
1
);
BOOST_CHECK
(
name
==
"aapje"
);
BOOST_CHECK
(
desc
==
"Aap"
);
break
;
// // cat1.erase(cif::Key("id") == 20);
case
2
:
BOOST_CHECK
(
id
==
2
);
BOOST_CHECK
(
name
==
"noot"
);
BOOST_CHECK
(
desc
==
"Noot"
);
break
;
// // BOOST_CHECK(cat1.size() == 1);
case
3
:
// // BOOST_CHECK(cat2.size() == 1);
BOOST_CHECK
(
id
==
3
);
BOOST_CHECK
(
name
==
"mies"
);
BOOST_CHECK
(
desc
==
"Mies"
);
break
;
case
4
:
BOOST_CHECK
(
id
==
4
);
BOOST_CHECK
(
name
==
"aap"
);
BOOST_CHECK
(
desc
==
"Aap"
);
break
;
default
:
BOOST_FAIL
(
"Unexpected record"
);
}
}
f
.
save
(
std
::
cout
);
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment