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
04b7828a
Unverified
Commit
04b7828a
authored
Aug 04, 2022
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
validator work
parent
9c621eca
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1088 additions
and
571 deletions
+1088
-571
include/cif++/v2/category.hpp
+69
-42
include/cif++/v2/datablock.hpp
+39
-0
include/cif++/v2/dictionary_parser.hpp
+1
-1
include/cif++/v2/file.hpp
+69
-8
include/cif++/v2/item.hpp
+17
-1
include/cif++/v2/row.hpp
+6
-0
include/cif++/v2/validate.hpp
+78
-83
src/v2/category.cpp
+436
-73
src/v2/condition.cpp
+4
-4
src/v2/dictionary_parser.cpp
+51
-51
src/v2/item.cpp
+8
-0
src/v2/validate.cpp
+79
-79
test/unit-v2-test.cpp
+231
-229
No files found.
include/cif++/v2/category.hpp
View file @
04b7828a
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include <cif++/v2/iterator.hpp>
#include <cif++/v2/iterator.hpp>
#include <cif++/v2/row.hpp>
#include <cif++/v2/row.hpp>
#include <cif++/v2/validate.hpp>
#include <cif++/v2/validate.hpp>
namespace
cif
::
v2
namespace
cif
::
v2
{
{
...
@@ -127,17 +128,22 @@ class category
...
@@ -127,17 +128,22 @@ class category
throw
std
::
runtime_error
(
"No Validator specified"
);
throw
std
::
runtime_error
(
"No Validator specified"
);
if
(
m_cat_validator
==
nullptr
)
if
(
m_cat_validator
==
nullptr
)
m_validator
->
report
E
rror
(
"undefined Category"
,
true
);
m_validator
->
report
_e
rror
(
"undefined Category"
,
true
);
iset
result
;
iset
result
;
for
(
auto
&
iv
:
m_cat_validator
->
m
ItemV
alidators
)
for
(
auto
&
iv
:
m_cat_validator
->
m
_item_v
alidators
)
result
.
insert
(
iv
.
m
T
ag
);
result
.
insert
(
iv
.
m
_t
ag
);
return
result
;
return
result
;
}
}
const
Validator
*
get_validator
()
const
{
return
m_validator
;
}
void
set_validator
(
const
validator
*
v
,
datablock
&
db
);
const
ValidateCategory
*
get_cat_validator
()
const
{
return
m_cat_validator
;
}
void
update_links
(
datablock
&
db
);
const
validator
*
get_validator
()
const
{
return
m_validator
;
}
const
category_validator
*
get_cat_validator
()
const
{
return
m_cat_validator
;
}
bool
is_valid
()
const
;
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
@@ -379,6 +385,10 @@ class category
...
@@ -379,6 +385,10 @@ class category
// insert_impl(pos, std::move(row));
// insert_impl(pos, std::move(row));
// }
// }
iterator
erase
(
iterator
pos
);
size_t
erase
(
condition
&&
cond
);
size_t
erase
(
condition
&&
cond
,
std
::
function
<
void
(
row_handle
)
>
&&
visit
);
iterator
emplace
(
std
::
initializer_list
<
item
>
items
)
iterator
emplace
(
std
::
initializer_list
<
item
>
items
)
{
{
return
this
->
emplace
(
items
.
begin
(),
items
.
end
());
return
this
->
emplace
(
items
.
begin
(),
items
.
end
());
...
@@ -388,29 +398,29 @@ class category
...
@@ -388,29 +398,29 @@ class category
iterator
emplace
(
ItemIter
b
,
ItemIter
e
)
iterator
emplace
(
ItemIter
b
,
ItemIter
e
)
{
{
// First, make sure all mandatory fields are supplied
// First, make sure all mandatory fields are supplied
// if (mCatValidator != nullptr and b != e)
if
(
m_cat_validator
!=
nullptr
and
b
!=
e
)
// {
{
// for (auto &col : m_columns)
for
(
const
auto
&
[
column
,
iv
]
:
m_columns
)
// {
{
// auto iv = mCatValidator->getValidatorForItem(col.mName);
if
(
iv
==
nullptr
)
continue
;
// if (iv == nullptr)
bool
seen
=
false
;
// continue;
// bool seen = false;
for
(
auto
v
=
b
;
v
!=
e
;
++
v
)
{
if
(
iequals
(
v
->
name
(),
column
))
{
iv
->
operator
()(
v
->
value
());
// for (auto v = b; v != e; ++v)
seen
=
true
;
// {
break
;
// if (iequals(v->name(), col.mName))
}
// {
}
// seen = true;
// break;
// }
// }
// if (not seen and iv->mM
andatory)
if
(
not
seen
and
iv
->
m_m
andatory
)
// throw std::runtime_error("missing mandatory field " + col.mName + " for category " + mN
ame);
throw
std
::
runtime_error
(
"missing mandatory field "
+
column
+
" for category "
+
m_n
ame
);
//
}
}
// if (mIndex != nullptr)
// if (mIndex != nullptr)
// {
// {
...
@@ -433,7 +443,7 @@ class category
...
@@ -433,7 +443,7 @@ class category
// isNew = false;
// isNew = false;
// }
// }
// }
// }
//
}
}
row
*
r
=
this
->
create_row
();
row
*
r
=
this
->
create_row
();
...
@@ -486,12 +496,12 @@ class category
...
@@ -486,12 +496,12 @@ class category
break
;
break
;
}
}
// if (VERBOSE > 0 and result == m_columns.size() and mCatV
alidator != nullptr) // validate the name, if it is known at all (since it was not found)
if
(
VERBOSE
>
0
and
result
==
m_columns
.
size
()
and
m_cat_v
alidator
!=
nullptr
)
// validate the name, if it is known at all (since it was not found)
//
{
{
// auto iv = mCatValidator->getValidatorForItem(
name);
auto
iv
=
m_cat_validator
->
get_validator_for_item
(
column_
name
);
//
if (iv == nullptr)
if
(
iv
==
nullptr
)
// std::cerr << "Invalid name used '" << name << "' is not a known column in " + mN
ame << std::endl;
std
::
cerr
<<
"Invalid name used '"
<<
name
<<
"' is not a known column in "
+
m_n
ame
<<
std
::
endl
;
//
}
}
return
result
;
return
result
;
}
}
...
@@ -504,14 +514,14 @@ class category
...
@@ -504,14 +514,14 @@ class category
if
(
result
==
m_columns
.
size
())
if
(
result
==
m_columns
.
size
())
{
{
const
ValidateItem
*
item_validator
=
nullptr
;
const
item_validator
*
item_validator
=
nullptr
;
// if (mCatV
alidator != nullptr)
if
(
m_cat_v
alidator
!=
nullptr
)
//
{
{
// item_validator = mCatValidator->getValidatorForI
tem(column_name);
item_validator
=
m_cat_validator
->
get_validator_for_i
tem
(
column_name
);
//
if (item_validator == nullptr)
if
(
item_validator
==
nullptr
)
// m_validator->reportError("tag " + std::string(column_name) + " not allowed in category " + mN
ame, false);
m_validator
->
report_error
(
"tag "
+
std
::
string
(
column_name
)
+
" not allowed in category "
+
m_n
ame
,
false
);
//
}
}
m_columns
.
emplace_back
(
column_name
,
item_validator
);
m_columns
.
emplace_back
(
column_name
,
item_validator
);
}
}
...
@@ -523,6 +533,9 @@ class category
...
@@ -523,6 +533,9 @@ class category
void
update_value
(
row
*
row
,
size_t
column
,
std
::
string_view
value
,
bool
updateLinked
,
bool
validate
=
true
);
void
update_value
(
row
*
row
,
size_t
column
,
std
::
string_view
value
,
bool
updateLinked
,
bool
validate
=
true
);
private
:
private
:
bool
is_orphan
(
row_handle
r
)
const
;
void
erase_orphans
(
condition
&&
cond
);
using
allocator_type
=
std
::
allocator
<
void
>
;
using
allocator_type
=
std
::
allocator
<
void
>
;
constexpr
allocator_type
get_allocator
()
const
constexpr
allocator_type
get_allocator
()
const
...
@@ -645,15 +658,27 @@ class category
...
@@ -645,15 +658,27 @@ class category
struct
item_column
struct
item_column
{
{
std
::
string
m_name
;
std
::
string
m_name
;
const
ValidateItem
*
m_validator
;
const
item_validator
*
m_validator
;
item_column
(
std
::
string_view
name
,
const
ValidateItem
*
validator
)
item_column
(
std
::
string_view
name
,
const
item_validator
*
validator
)
:
m_name
(
name
)
:
m_name
(
name
)
,
m_validator
(
validator
)
,
m_validator
(
validator
)
{
{
}
}
};
};
struct
link
{
link
(
category
*
linked
,
const
link_validator
*
v
)
:
linked
(
linked
)
,
v
(
v
)
{
}
category
*
linked
;
const
link_validator
*
v
;
};
// proxy methods for every insertion
// proxy methods for every insertion
iterator
insert_impl
(
const_iterator
pos
,
row
*
n
);
iterator
insert_impl
(
const_iterator
pos
,
row
*
n
);
...
@@ -661,8 +686,10 @@ class category
...
@@ -661,8 +686,10 @@ class category
std
::
string
m_name
;
std
::
string
m_name
;
std
::
vector
<
item_column
>
m_columns
;
std
::
vector
<
item_column
>
m_columns
;
const
Validator
*
m_validator
=
nullptr
;
const
validator
*
m_validator
=
nullptr
;
const
ValidateCategory
*
m_cat_validator
=
nullptr
;
const
category_validator
*
m_cat_validator
=
nullptr
;
std
::
vector
<
link
>
m_parent_links
,
m_child_links
;
bool
m_cascade
=
true
;
row
*
m_head
=
nullptr
,
*
m_tail
=
nullptr
;
row
*
m_head
=
nullptr
,
*
m_tail
=
nullptr
;
};
};
...
...
include/cif++/v2/datablock.hpp
View file @
04b7828a
...
@@ -63,6 +63,31 @@ class datablock
...
@@ -63,6 +63,31 @@ class datablock
const
std
::
string
&
name
()
const
{
return
m_name
;
}
const
std
::
string
&
name
()
const
{
return
m_name
;
}
void
set_validator
(
const
validator
*
v
)
{
m_validator
=
v
;
for
(
auto
&
cat
:
*
this
)
cat
.
set_validator
(
v
,
*
this
);
}
const
validator
*
get_validator
()
const
{
return
m_validator
;
}
bool
is_valid
()
const
{
if
(
m_validator
==
nullptr
)
throw
std
::
runtime_error
(
"Validator not specified"
);
bool
result
=
true
;
for
(
auto
&
cat
:
*
this
)
result
=
cat
.
is_valid
()
and
result
;
return
result
;
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
bool
empty
()
const
{
return
m_categories
.
empty
();
}
bool
empty
()
const
{
return
m_categories
.
empty
();
}
...
@@ -102,6 +127,18 @@ class datablock
...
@@ -102,6 +127,18 @@ class datablock
return
i
==
m_categories
.
end
()
?
s_empty
:
*
i
;
return
i
==
m_categories
.
end
()
?
s_empty
:
*
i
;
}
}
category
*
get
(
std
::
string_view
name
)
{
auto
i
=
std
::
find_if
(
m_categories
.
begin
(),
m_categories
.
end
(),
[
name
](
const
category
&
c
)
{
return
iequals
(
c
.
name
(),
name
);
});
return
i
==
m_categories
.
end
()
?
nullptr
:
&*
i
;
}
const
category
*
get
(
std
::
string_view
name
)
const
{
return
const_cast
<
datablock
*>
(
this
)
->
get
(
name
);
}
std
::
tuple
<
iterator
,
bool
>
emplace
(
std
::
string_view
name
)
std
::
tuple
<
iterator
,
bool
>
emplace
(
std
::
string_view
name
)
{
{
bool
is_new
=
true
;
bool
is_new
=
true
;
...
@@ -182,6 +219,7 @@ class datablock
...
@@ -182,6 +219,7 @@ class datablock
private
:
private
:
category_list
m_categories
;
category_list
m_categories
;
std
::
string
m_name
;
std
::
string
m_name
;
const
validator
*
m_validator
=
nullptr
;
};
};
}
//
namespace
cif
::
v2
}
//
namespace
cif
::
v2
\ No newline at end of file
include/cif++/v2/dictionary_parser.hpp
View file @
04b7828a
...
@@ -31,6 +31,6 @@
...
@@ -31,6 +31,6 @@
namespace
cif
::
v2
namespace
cif
::
v2
{
{
V
alidator
parse_dictionary
(
std
::
string_view
name
,
std
::
istream
&
is
);
v
alidator
parse_dictionary
(
std
::
string_view
name
,
std
::
istream
&
is
);
}
// namespace cif::v2
}
// namespace cif::v2
include/cif++/v2/file.hpp
View file @
04b7828a
...
@@ -60,6 +60,57 @@ class file
...
@@ -60,6 +60,57 @@ class file
file
&
operator
=
(
const
file
&
)
=
default
;
file
&
operator
=
(
const
file
&
)
=
default
;
file
&
operator
=
(
file
&&
)
=
default
;
file
&
operator
=
(
file
&&
)
=
default
;
void
set_validator
(
const
validator
*
v
)
{
m_validator
=
v
;
for
(
auto
&
db
:
*
this
)
db
.
set_validator
(
v
);
}
const
validator
*
get_validator
()
const
{
return
m_validator
;
}
bool
is_valid
()
const
{
if
(
m_validator
==
nullptr
)
std
::
runtime_error
(
"No validator loaded explicitly, cannot continue"
);
bool
result
=
true
;
for
(
auto
&
d
:
*
this
)
result
=
d
.
is_valid
()
and
result
;
return
result
;
}
bool
is_valid
()
{
if
(
m_validator
==
nullptr
)
{
if
(
VERBOSE
>
0
)
std
::
cerr
<<
"No dictionary loaded explicitly, loading default"
<<
std
::
endl
;
load_dictionary
();
}
bool
result
=
true
;
for
(
auto
&
d
:
*
this
)
result
=
d
.
is_valid
()
and
result
;
return
result
;
}
void
load_dictionary
()
{
load_dictionary
(
"mmcif_ddl"
);
}
void
load_dictionary
(
std
::
string_view
name
)
{
set_validator
(
&
validator_factory
::
instance
()[
name
]);
}
datablock
&
operator
[](
std
::
string_view
name
)
datablock
&
operator
[](
std
::
string_view
name
)
{
{
auto
i
=
std
::
find_if
(
m_datablocks
.
begin
(),
m_datablocks
.
end
(),
[
name
](
const
datablock
&
c
)
auto
i
=
std
::
find_if
(
m_datablocks
.
begin
(),
m_datablocks
.
end
(),
[
name
](
const
datablock
&
c
)
...
@@ -112,27 +163,36 @@ class file
...
@@ -112,27 +163,36 @@ class file
bool
empty
()
const
{
return
m_datablocks
.
empty
();
}
bool
empty
()
const
{
return
m_datablocks
.
empty
();
}
size_t
size
()
const
{
return
m_datablocks
.
size
();
}
size_t
size
()
const
{
return
m_datablocks
.
size
();
}
iterator
begin
()
{
return
m_datablocks
.
begin
();
}
iterator
end
()
{
return
m_datablocks
.
end
();
}
const_iterator
cbegin
()
{
return
m_datablocks
.
begin
();
}
const_iterator
cend
()
{
return
m_datablocks
.
end
();
}
const_iterator
begin
()
const
{
return
m_datablocks
.
begin
();
}
const_iterator
end
()
const
{
return
m_datablocks
.
end
();
}
reference
front
()
{
return
m_datablocks
.
front
();
}
reference
front
()
{
return
m_datablocks
.
front
();
}
reference
back
()
{
return
m_datablocks
.
back
();
}
reference
back
()
{
return
m_datablocks
.
back
();
}
void
load
(
std
::
istream
&
is
)
void
load
(
std
::
istream
&
is
)
{
{
// auto saved = mV
alidator;
auto
saved
=
m_v
alidator
;
// setV
alidator(nullptr);
set_v
alidator
(
nullptr
);
parser
p
(
is
,
*
this
);
parser
p
(
is
,
*
this
);
p
.
parse_file
();
p
.
parse_file
();
//
if (saved != nullptr)
if
(
saved
!=
nullptr
)
//
{
{
// setV
alidator(saved);
set_v
alidator
(
saved
);
// (void)isV
alid();
(
void
)
is_v
alid
();
//
}
}
}
}
private
:
private
:
datablock_list
m_datablocks
;
datablock_list
m_datablocks
;
std
::
unique_ptr
<
Validator
>
m_validato
r
;
const
validator
*
m_validator
=
nullpt
r
;
};
};
}
}
\ No newline at end of file
include/cif++/v2/item.hpp
View file @
04b7828a
...
@@ -199,7 +199,7 @@ struct item_handle
...
@@ -199,7 +199,7 @@ struct item_handle
item_handle
&
operator
=
(
const
T
&
value
)
item_handle
&
operator
=
(
const
T
&
value
)
{
{
item
v
{
""
,
value
};
item
v
{
""
,
value
};
m_row_handle
.
assign
(
m_column
,
v
.
value
(),
false
);
assign_value
(
v
);
return
*
this
;
return
*
this
;
}
}
...
@@ -281,6 +281,8 @@ struct item_handle
...
@@ -281,6 +281,8 @@ struct item_handle
uint16_t
m_column
;
uint16_t
m_column
;
row_handle
&
m_row_handle
;
row_handle
&
m_row_handle
;
void
assign_value
(
const
item
&
value
);
static
constexpr
const
char
*
s_empty_result
=
""
;
static
constexpr
const
char
*
s_empty_result
=
""
;
};
};
...
@@ -432,6 +434,20 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_same_v<T, const ch
...
@@ -432,6 +434,20 @@ struct item_handle::item_value_as<T, std::enable_if_t<std::is_same_v<T, const ch
};
};
template
<
typename
T
>
template
<
typename
T
>
struct
item_handle
::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_same_v
<
T
,
std
::
string_view
>>>
{
// static std::string_view convert(const item_handle &ref)
// {
// return ref.text();
// }
static
int
compare
(
const
item_handle
&
ref
,
const
std
::
string_view
&
value
,
bool
icase
)
{
return
icase
?
cif
::
icompare
(
ref
.
text
(),
value
)
:
ref
.
text
().
compare
(
value
);
}
};
template
<
typename
T
>
struct
item_handle
::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_same_v
<
T
,
std
::
string
>>>
struct
item_handle
::
item_value_as
<
T
,
std
::
enable_if_t
<
std
::
is_same_v
<
T
,
std
::
string
>>>
{
{
static
std
::
string
convert
(
const
item_handle
&
ref
)
static
std
::
string
convert
(
const
item_handle
&
ref
)
...
...
include/cif++/v2/row.hpp
View file @
04b7828a
...
@@ -135,6 +135,7 @@ class row_handle
...
@@ -135,6 +135,7 @@ class row_handle
{
{
public
:
public
:
friend
class
item_handle
;
friend
class
item_handle
;
friend
class
category
;
row_handle
()
=
default
;
row_handle
()
=
default
;
...
@@ -262,6 +263,11 @@ class row_handle
...
@@ -262,6 +263,11 @@ class row_handle
uint16_t
add_column
(
std
::
string_view
name
);
uint16_t
add_column
(
std
::
string_view
name
);
operator
row
*
()
{
return
m_row
;
}
void
assign
(
const
item
&
i
,
bool
updateLinked
)
void
assign
(
const
item
&
i
,
bool
updateLinked
)
{
{
assign
(
i
.
name
(),
i
.
value
(),
updateLinked
);
assign
(
i
.
name
(),
i
.
value
(),
updateLinked
);
...
...
include/cif++/v2/validate.hpp
View file @
04b7828a
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#pragma once
#pragma once
#include <filesystem>
#include <filesystem>
#include <mutex>
// duh.. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
// duh.. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
// #include <regex>
// #include <regex>
...
@@ -43,19 +44,19 @@ namespace io = boost::iostreams;
...
@@ -43,19 +44,19 @@ namespace io = boost::iostreams;
namespace
cif
::
v2
namespace
cif
::
v2
{
{
struct
ValidateCategory
;
struct
category_validator
;
class
ValidatorF
actory
;
class
validator_f
actory
;
// --------------------------------------------------------------------
// --------------------------------------------------------------------
class
ValidationE
rror
:
public
std
::
exception
class
validation_e
rror
:
public
std
::
exception
{
{
public
:
public
:
ValidationE
rror
(
const
std
::
string
&
msg
);
validation_e
rror
(
const
std
::
string
&
msg
);
ValidationE
rror
(
const
std
::
string
&
cat
,
const
std
::
string
&
item
,
validation_e
rror
(
const
std
::
string
&
cat
,
const
std
::
string
&
item
,
const
std
::
string
&
msg
);
const
std
::
string
&
msg
);
const
char
*
what
()
const
noexcept
{
return
m
M
sg
.
c_str
();
}
const
char
*
what
()
const
noexcept
{
return
m
_m
sg
.
c_str
();
}
std
::
string
m
M
sg
;
std
::
string
m
_m
sg
;
};
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
...
@@ -67,126 +68,120 @@ enum class DDL_PrimitiveType
...
@@ -67,126 +68,120 @@ enum class DDL_PrimitiveType
Numb
Numb
};
};
DDL_PrimitiveType
map
ToPrimitiveT
ype
(
std
::
string_view
s
);
DDL_PrimitiveType
map
_to_primitive_t
ype
(
std
::
string_view
s
);
struct
ValidateType
struct
type_validator
{
{
std
::
string
m
N
ame
;
std
::
string
m
_n
ame
;
DDL_PrimitiveType
m
PrimitiveT
ype
;
DDL_PrimitiveType
m
_primitive_t
ype
;
// std::regex mRx;
// std::regex mRx;
boost
::
regex
m
R
x
;
boost
::
regex
m
_r
x
;
bool
operator
<
(
const
ValidateType
&
rhs
)
const
bool
operator
<
(
const
type_validator
&
rhs
)
const
{
{
return
icompare
(
m
Name
,
rhs
.
mN
ame
)
<
0
;
return
icompare
(
m
_name
,
rhs
.
m_n
ame
)
<
0
;
}
}
// compare values based on type
// int compare(const std::string& a, const std::string& b) const
// {
// return compare(a.c_str(), b.c_str());
// }
int
compare
(
const
char
*
a
,
const
char
*
b
)
const
;
int
compare
(
const
char
*
a
,
const
char
*
b
)
const
;
};
};
struct
ValidateItem
struct
item_validator
{
{
std
::
string
m
T
ag
;
std
::
string
m
_t
ag
;
bool
m
M
andatory
;
bool
m
_m
andatory
;
const
ValidateType
*
mT
ype
;
const
type_validator
*
m_t
ype
;
cif
::
iset
m
E
nums
;
cif
::
iset
m
_e
nums
;
std
::
string
m
D
efault
;
std
::
string
m
_d
efault
;
bool
m
DefaultIsN
ull
;
bool
m
_default_is_n
ull
;
ValidateCategory
*
mC
ategory
=
nullptr
;
category_validator
*
m_c
ategory
=
nullptr
;
// ItemLinked is used for non-key links
// ItemLinked is used for non-key links
struct
ItemLinked
struct
item_link
{
{
ValidateItem
*
mP
arent
;
item_validator
*
m_p
arent
;
std
::
string
m
ParentI
tem
;
std
::
string
m
_parent_i
tem
;
std
::
string
m
ChildI
tem
;
std
::
string
m
_child_i
tem
;
};
};
std
::
vector
<
ItemLinked
>
mLinked
;
std
::
vector
<
item_link
>
mLinked
;
bool
operator
<
(
const
ValidateItem
&
rhs
)
const
bool
operator
<
(
const
item_validator
&
rhs
)
const
{
{
return
icompare
(
m
Tag
,
rhs
.
mT
ag
)
<
0
;
return
icompare
(
m
_tag
,
rhs
.
m_t
ag
)
<
0
;
}
}
bool
operator
==
(
const
ValidateItem
&
rhs
)
const
bool
operator
==
(
const
item_validator
&
rhs
)
const
{
{
return
iequals
(
m
Tag
,
rhs
.
mT
ag
);
return
iequals
(
m
_tag
,
rhs
.
m_t
ag
);
}
}
void
operator
()(
std
::
string
value
)
const
;
void
operator
()(
std
::
string
_view
value
)
const
;
};
};
struct
ValidateCategory
struct
category_validator
{
{
std
::
string
m
N
ame
;
std
::
string
m
_n
ame
;
std
::
vector
<
std
::
string
>
m
K
eys
;
std
::
vector
<
std
::
string
>
m
_k
eys
;
cif
::
iset
m
G
roups
;
cif
::
iset
m
_g
roups
;
cif
::
iset
m
MandatoryF
ields
;
cif
::
iset
m
_mandatory_f
ields
;
std
::
set
<
ValidateItem
>
mItemV
alidators
;
std
::
set
<
item_validator
>
m_item_v
alidators
;
bool
operator
<
(
const
ValidateCategory
&
rhs
)
const
bool
operator
<
(
const
category_validator
&
rhs
)
const
{
{
return
icompare
(
m
Name
,
rhs
.
mN
ame
)
<
0
;
return
icompare
(
m
_name
,
rhs
.
m_n
ame
)
<
0
;
}
}
void
addItemValidator
(
ValidateItem
&&
v
);
void
addItemValidator
(
item_validator
&&
v
);
const
ValidateItem
*
getValidatorForI
tem
(
std
::
string_view
tag
)
const
;
const
item_validator
*
get_validator_for_i
tem
(
std
::
string_view
tag
)
const
;
const
std
::
set
<
ValidateItem
>
&
itemV
alidators
()
const
const
std
::
set
<
item_validator
>
&
item_v
alidators
()
const
{
{
return
m
ItemV
alidators
;
return
m
_item_v
alidators
;
}
}
};
};
struct
ValidateLink
struct
link_validator
{
{
int
m
LinkGroupID
;
int
m
_link_group_id
;
std
::
string
m
ParentC
ategory
;
std
::
string
m
_parent_c
ategory
;
std
::
vector
<
std
::
string
>
m
ParentK
eys
;
std
::
vector
<
std
::
string
>
m
_parent_k
eys
;
std
::
string
m
ChildC
ategory
;
std
::
string
m
_child_c
ategory
;
std
::
vector
<
std
::
string
>
m
ChildK
eys
;
std
::
vector
<
std
::
string
>
m
_child_k
eys
;
std
::
string
m
LinkGroupL
abel
;
std
::
string
m
_link_group_l
abel
;
};
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
class
V
alidator
class
v
alidator
{
{
public
:
public
:
V
alidator
(
std
::
string_view
name
)
v
alidator
(
std
::
string_view
name
)
:
m_name
(
name
)
:
m_name
(
name
)
{
{
}
}
~
V
alidator
()
=
default
;
~
v
alidator
()
=
default
;
Validator
(
const
V
alidator
&
rhs
)
=
delete
;
validator
(
const
v
alidator
&
rhs
)
=
delete
;
Validator
&
operator
=
(
const
V
alidator
&
rhs
)
=
delete
;
validator
&
operator
=
(
const
v
alidator
&
rhs
)
=
delete
;
Validator
(
V
alidator
&&
rhs
)
=
default
;
validator
(
v
alidator
&&
rhs
)
=
default
;
Validator
&
operator
=
(
V
alidator
&&
rhs
)
=
default
;
validator
&
operator
=
(
v
alidator
&&
rhs
)
=
default
;
friend
class
dictionary_parser
;
friend
class
dictionary_parser
;
void
add
TypeValidator
(
ValidateType
&&
v
);
void
add
_type_validator
(
type_validator
&&
v
);
const
ValidateType
*
getValidatorForType
(
std
::
string_view
typeC
ode
)
const
;
const
type_validator
*
get_validator_for_type
(
std
::
string_view
type_c
ode
)
const
;
void
add
CategoryValidator
(
ValidateCategory
&&
v
);
void
add
_category_validator
(
category_validator
&&
v
);
const
ValidateCategory
*
getValidatorForC
ategory
(
std
::
string_view
category
)
const
;
const
category_validator
*
get_validator_for_c
ategory
(
std
::
string_view
category
)
const
;
void
add
LinkValidator
(
ValidateLink
&&
v
);
void
add
_link_validator
(
link_validator
&&
v
);
std
::
vector
<
const
ValidateLink
*>
getLinksForP
arent
(
std
::
string_view
category
)
const
;
std
::
vector
<
const
link_validator
*>
get_links_for_p
arent
(
std
::
string_view
category
)
const
;
std
::
vector
<
const
ValidateLink
*>
getLinksForC
hild
(
std
::
string_view
category
)
const
;
std
::
vector
<
const
link_validator
*>
get_links_for_c
hild
(
std
::
string_view
category
)
const
;
void
report
E
rror
(
const
std
::
string
&
msg
,
bool
fatal
)
const
;
void
report
_e
rror
(
const
std
::
string
&
msg
,
bool
fatal
)
const
;
const
std
::
string
&
name
()
const
{
return
m_name
;
}
const
std
::
string
&
name
()
const
{
return
m_name
;
}
void
set_name
(
const
std
::
string
&
name
)
{
m_name
=
name
;
}
void
set_name
(
const
std
::
string
&
name
)
{
m_name
=
name
;
}
...
@@ -196,37 +191,37 @@ class Validator
...
@@ -196,37 +191,37 @@ class Validator
private
:
private
:
// name is fully qualified here:
// name is fully qualified here:
ValidateItem
*
getValidatorForI
tem
(
std
::
string_view
name
)
const
;
item_validator
*
get_validator_for_i
tem
(
std
::
string_view
name
)
const
;
std
::
string
m_name
;
std
::
string
m_name
;
std
::
string
m_version
;
std
::
string
m_version
;
bool
m_strict
=
false
;
bool
m_strict
=
false
;
std
::
set
<
ValidateType
>
mTypeV
alidators
;
std
::
set
<
type_validator
>
m_type_v
alidators
;
std
::
set
<
ValidateCategory
>
mCategoryV
alidators
;
std
::
set
<
category_validator
>
m_category_v
alidators
;
std
::
vector
<
ValidateLink
>
mLinkV
alidators
;
std
::
vector
<
link_validator
>
m_link_v
alidators
;
};
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
class
ValidatorF
actory
class
validator_f
actory
{
{
public
:
public
:
static
ValidatorF
actory
&
instance
()
static
validator_f
actory
&
instance
()
{
{
static
ValidatorF
actory
s_instance
;
static
validator_f
actory
s_instance
;
return
s_instance
;
return
s_instance
;
}
}
const
V
alidator
&
operator
[](
std
::
string_view
dictionary_name
);
const
v
alidator
&
operator
[](
std
::
string_view
dictionary_name
);
private
:
private
:
void
construct_validator
(
std
::
string_view
name
,
std
::
istream
&
is
);
void
construct_validator
(
std
::
string_view
name
,
std
::
istream
&
is
);
// --------------------------------------------------------------------
// --------------------------------------------------------------------
ValidatorF
actory
()
=
default
;
validator_f
actory
()
=
default
;
std
::
mutex
m
M
utex
;
std
::
mutex
m
_m
utex
;
std
::
list
<
Validator
>
mV
alidators
;
std
::
list
<
validator
>
m_v
alidators
;
};
};
}
// namespace cif::v2
}
// namespace cif::v2
src/v2/category.cpp
View file @
04b7828a
...
@@ -25,10 +25,371 @@
...
@@ -25,10 +25,371 @@
*/
*/
#include <cif++/v2/category.hpp>
#include <cif++/v2/category.hpp>
#include <cif++/v2/datablock.hpp>
namespace
cif
::
v2
namespace
cif
::
v2
{
{
template
<
typename
V
>
std
::
string
join
(
const
V
&
arr
,
std
::
string_view
sep
)
{
std
::
ostringstream
s
;
if
(
not
arr
.
empty
())
{
auto
ai
=
arr
.
begin
();
auto
ni
=
std
::
next
(
ai
);
for
(;;)
{
s
<<
*
ai
;
ai
=
ni
;
ni
=
std
::
next
(
ai
);
if
(
ni
==
arr
.
end
())
break
;
s
<<
sep
;
}
}
return
s
.
str
();
}
void
category
::
set_validator
(
const
validator
*
v
,
datablock
&
db
)
{
m_validator
=
v
;
// if (m_index != nullptr)
// {
// delete m_index;
// m_index = nullptr;
// }
if
(
m_validator
!=
nullptr
)
{
m_cat_validator
=
m_validator
->
get_validator_for_category
(
m_name
);
// if (m_cat_validator != nullptr)
// {
// m_index = new CatIndex(this);
// m_index->reconstruct();
// //#if DEBUG
// // assert(m_index->size() == size());
// // m_index->validate();
// //#endif
// }
}
else
m_cat_validator
=
nullptr
;
for
(
auto
&&
[
column
,
cv
]
:
m_columns
)
cv
=
m_cat_validator
?
m_cat_validator
->
get_validator_for_item
(
column
)
:
nullptr
;
update_links
(
db
);
}
void
category
::
update_links
(
datablock
&
db
)
{
m_child_links
.
clear
();
m_parent_links
.
clear
();
if
(
m_validator
!=
nullptr
)
{
for
(
auto
link
:
m_validator
->
get_links_for_parent
(
m_name
))
{
auto
childCat
=
db
.
get
(
link
->
m_child_category
);
if
(
childCat
==
nullptr
)
continue
;
m_child_links
.
emplace_back
(
childCat
,
link
);
}
for
(
auto
link
:
m_validator
->
get_links_for_child
(
m_name
))
{
auto
parentCat
=
db
.
get
(
link
->
m_parent_category
);
if
(
parentCat
==
nullptr
)
continue
;
m_parent_links
.
emplace_back
(
parentCat
,
link
);
}
}
}
bool
category
::
is_valid
()
const
{
bool
result
=
true
;
if
(
m_validator
==
nullptr
)
throw
std
::
runtime_error
(
"no Validator specified"
);
if
(
empty
())
{
if
(
VERBOSE
>
2
)
std
::
cerr
<<
"Skipping validation of empty Category "
<<
m_name
<<
std
::
endl
;
return
true
;
}
if
(
m_cat_validator
==
nullptr
)
{
m_validator
->
report_error
(
"undefined Category "
+
m_name
,
false
);
return
false
;
}
auto
mandatory
=
m_cat_validator
->
m_mandatory_fields
;
for
(
auto
&
col
:
m_columns
)
{
auto
iv
=
m_cat_validator
->
get_validator_for_item
(
col
.
m_name
);
if
(
iv
==
nullptr
)
{
m_validator
->
report_error
(
"Field "
+
col
.
m_name
+
" is not valid in Category "
+
m_name
,
false
);
result
=
false
;
}
// col.m_validator = iv;
if
(
col
.
m_validator
!=
iv
)
m_validator
->
report_error
(
"Column validator is not specified correctly"
,
true
);
mandatory
.
erase
(
col
.
m_name
);
}
if
(
not
mandatory
.
empty
())
{
m_validator
->
report_error
(
"In Category "
+
m_name
+
" the following mandatory fields are missing: "
+
join
(
mandatory
,
", "
),
false
);
result
=
false
;
}
//#if not defined(NDEBUG)
// // check index?
// if (m_index)
// {
// m_index->validate();
// for (auto r: *this)
// {
// if (m_index->find(r.mData) != r.mData)
// m_validator->report_error("Key not found in index for Category " + m_name);
// }
// }
//#endif
// validate all values
mandatory
=
m_cat_validator
->
m_mandatory_fields
;
for
(
auto
ri
=
m_head
;
ri
!=
nullptr
;
ri
=
ri
->
m_next
)
{
for
(
size_t
cix
=
0
;
cix
<
m_columns
.
size
();
++
cix
)
{
bool
seen
=
false
;
auto
iv
=
m_columns
[
cix
].
m_validator
;
if
(
iv
==
nullptr
)
{
m_validator
->
report_error
(
"invalid field "
+
m_columns
[
cix
].
m_name
+
" for Category "
+
m_name
,
false
);
result
=
false
;
continue
;
}
for
(
auto
vi
=
ri
->
m_head
;
vi
!=
nullptr
;
vi
=
vi
->
m_next
)
{
if
(
vi
->
m_column_ix
==
cix
)
{
seen
=
true
;
try
{
(
*
iv
)(
vi
->
text
());
}
catch
(
const
std
::
exception
&
e
)
{
m_validator
->
report_error
(
"Error validating "
+
m_columns
[
cix
].
m_name
+
": "
+
e
.
what
(),
false
);
continue
;
}
}
}
if
(
seen
or
ri
!=
m_head
)
continue
;
if
(
iv
!=
nullptr
and
iv
->
m_mandatory
)
{
m_validator
->
report_error
(
"missing mandatory field "
+
m_columns
[
cix
].
m_name
+
" for Category "
+
m_name
,
false
);
result
=
false
;
}
}
}
return
result
;
}
category
::
iterator
category
::
erase
(
iterator
pos
)
{
row_handle
rh
=
*
pos
;
row
*
r
=
rh
;
iterator
result
=
++
pos
;
iset
keys
;
if
(
m_cat_validator
)
keys
=
iset
(
m_cat_validator
->
m_keys
.
begin
(),
m_cat_validator
->
m_keys
.
end
());
if
(
m_head
==
nullptr
)
throw
std
::
runtime_error
(
"erase"
);
// if (mIndex != nullptr)
// mIndex->erase(r.mData);
if
(
r
==
m_head
)
{
m_head
=
m_head
->
m_next
;
r
->
m_next
=
nullptr
;
}
else
{
for
(
auto
pi
=
m_head
;
pi
!=
nullptr
;
pi
=
pi
->
m_next
)
{
if
(
pi
->
m_next
==
r
)
{
pi
->
m_next
=
r
->
m_next
;
r
->
m_next
=
nullptr
;
break
;
}
}
}
// links are created based on the _pdbx_item_linked_group_list entries
// in mmcif_pdbx_v50.dic dictionary.
//
// For each link group in _pdbx_item_linked_group_list
// a std::set of keys from one category is mapped to another.
// If all values in a child are the same as the specified parent ones
// the child is removed as well, recursively of course.
if
(
m_validator
!=
nullptr
)
{
for
(
auto
&&
[
childCat
,
link
]
:
m_child_links
)
{
condition
cond
;
for
(
size_t
ix
=
0
;
ix
<
link
->
m_parent_keys
.
size
();
++
ix
)
{
std
::
string_view
value
=
rh
[
link
->
m_parent_keys
[
ix
]].
text
();
cond
=
std
::
move
(
cond
)
and
(
key
(
link
->
m_child_keys
[
ix
])
==
value
);
}
childCat
->
erase_orphans
(
std
::
move
(
cond
));
}
}
delete_row
(
r
);
// reset mTail, if needed
if
(
r
==
m_tail
)
{
m_tail
=
m_head
;
if
(
m_tail
!=
nullptr
)
while
(
m_tail
->
m_next
!=
nullptr
)
m_tail
=
m_tail
->
m_next
;
}
return
result
;
}
size_t
category
::
erase
(
condition
&&
cond
)
{
size_t
result
=
0
;
cond
.
prepare
(
*
this
);
auto
ri
=
begin
();
while
(
ri
!=
end
())
{
if
(
cond
(
*
ri
))
{
ri
=
erase
(
ri
);
++
result
;
}
else
++
ri
;
}
return
result
;
}
size_t
category
::
erase
(
condition
&&
cond
,
std
::
function
<
void
(
row_handle
)
>
&&
visit
)
{
size_t
result
=
0
;
cond
.
prepare
(
*
this
);
auto
ri
=
begin
();
while
(
ri
!=
end
())
{
if
(
cond
(
*
ri
))
{
visit
(
*
ri
);
ri
=
erase
(
ri
);
++
result
;
}
else
++
ri
;
}
return
result
;
}
bool
category
::
is_orphan
(
row_handle
r
)
const
{
// be safe
if
(
m_cat_validator
==
nullptr
)
return
false
;
bool
isOrphan
=
true
;
for
(
auto
&&
[
parentCat
,
link
]
:
m_parent_links
)
{
condition
cond
;
for
(
size_t
ix
=
0
;
ix
<
link
->
m_child_keys
.
size
();
++
ix
)
{
std
::
string_view
value
=
r
[
link
->
m_child_keys
[
ix
]].
text
();
cond
=
std
::
move
(
cond
)
and
(
key
(
link
->
m_parent_keys
[
ix
])
==
value
);
}
// if (VERBOSE > 2)
// std::cerr << "Check condition '" << cond << "' in parent category " << link->mParentCategory << " for child cat " << mName << std::endl;
if
(
parentCat
->
exists
(
std
::
move
(
cond
)))
{
if
(
VERBOSE
>
2
)
std
::
cerr
<<
"Not removing because row has a parent in category "
<<
link
->
m_parent_category
<<
std
::
endl
;
isOrphan
=
false
;
break
;
}
}
return
isOrphan
;
}
void
category
::
erase_orphans
(
condition
&&
cond
)
{
std
::
vector
<
row
*>
remove
;
cond
.
prepare
(
*
this
);
for
(
auto
r
:
*
this
)
{
if
(
cond
(
r
)
and
is_orphan
(
r
))
{
if
(
VERBOSE
>
1
)
std
::
cerr
<<
"Removing orphaned record: "
<<
std
::
endl
<<
r
<<
std
::
endl
<<
std
::
endl
;
remove
.
push_back
(
r
);
}
}
for
(
auto
r
:
remove
)
erase
(
iterator
(
*
this
,
r
));
}
void
category
::
update_value
(
row
*
row
,
size_t
column
,
std
::
string_view
value
,
bool
updateLinked
,
bool
validate
)
void
category
::
update_value
(
row
*
row
,
size_t
column
,
std
::
string_view
value
,
bool
updateLinked
,
bool
validate
)
{
{
auto
&
col
=
m_columns
[
column
];
auto
&
col
=
m_columns
[
column
];
...
@@ -50,9 +411,9 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
...
@@ -50,9 +411,9 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
std
::
string
oldStrValue
=
oldValue
?
oldValue
:
""
;
std
::
string
oldStrValue
=
oldValue
?
oldValue
:
""
;
//
//
check the value
// check the value
//
if (col.m_validator and validate)
if
(
col
.
m_validator
and
validate
)
// (*col.m_validator
)(value);
col
.
m_validator
->
operator
(
)(
value
);
// If the field is part of the Key for this Category, remove it from the index
// If the field is part of the Key for this Category, remove it from the index
// before updating
// before updating
...
@@ -60,11 +421,11 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
...
@@ -60,11 +421,11 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
bool
reinsert
=
false
;
bool
reinsert
=
false
;
// if (updateLinked and // an update of an Item's value
// if (updateLinked and // an update of an Item's value
// cat->m
I
ndex != nullptr and cat->keyFieldsByIndex().count(column))
// cat->m
_i
ndex != nullptr and cat->keyFieldsByIndex().count(column))
// {
// {
// reinsert = cat->m
I
ndex->find(mData);
// reinsert = cat->m
_i
ndex->find(mData);
// if (reinsert)
// if (reinsert)
// cat->m
I
ndex->erase(mData);
// cat->m
_i
ndex->erase(mData);
// }
// }
// first remove old value with cix
// first remove old value with cix
...
@@ -112,87 +473,89 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
...
@@ -112,87 +473,89 @@ void category::update_value(row *row, size_t column, std::string_view value, boo
// if (reinsert)
// if (reinsert)
// cat->mIndex->insert(mData);
// cat->mIndex->insert(mData);
// // see if we need to update any child categories that depend on this value
// see if we need to update any child categories that depend on this value
// auto iv = col.m_validator;
auto
iv
=
col
.
m_validator
;
// if (not skipUpdateLinked and iv != nullptr and mCascade)
if
(
updateLinked
and
iv
!=
nullptr
/*and m_cascade*/
)
// {
{
// for (auto &&[childCat, linked] : cat->mChildLinks)
row_handle
rh
(
*
this
,
*
row
);
// {
// if (find(linked->mParentKeys.begin(), linked->mParentKeys.end(), iv->mTag) == linked->mParentKeys.end())
// continue;
// Condition cond;
for
(
auto
&&
[
childCat
,
linked
]
:
m_child_links
)
// std::string childTag;
{
if
(
std
::
find
(
linked
->
m_parent_keys
.
begin
(),
linked
->
m_parent_keys
.
end
(),
iv
->
m_tag
)
==
linked
->
m_parent_keys
.
end
())
continue
;
// for (size_t ix = 0; ix < linked->mParentKeys.size(); ++ix)
condition
cond
;
// {
std
::
string
childTag
;
// std::string pk = linked->mParentKeys[ix];
// std::string ck = linked->mChildKeys[ix];
// // TODO add code to *NOT* test mandatory fields for Empty
for
(
size_t
ix
=
0
;
ix
<
linked
->
m_parent_keys
.
size
();
++
ix
)
{
std
::
string
pk
=
linked
->
m_parent_keys
[
ix
];
std
::
string
ck
=
linked
->
m_child_keys
[
ix
];
// if (pk == iv->mTag)
// TODO add code to *NOT* test mandatory fields for Empty
// {
// childTag = ck;
// cond = std::move(cond) && Key(ck) == oldStrValue;
// }
// else
// {
// const char *pk_value = (*this)[pk].c_str();
// if (*pk_value == 0)
// cond = std::move(cond) && Key(ck) == Empty();
// else
// cond = std::move(cond) && ((Key(ck) == pk_value) or Key(ck) == Empty());
// }
// }
// auto rows = childCat->find(std::move(cond));
if
(
pk
==
iv
->
m_tag
)
// if (rows.empty())
{
// continue;
childTag
=
ck
;
cond
=
std
::
move
(
cond
)
and
key
(
ck
)
==
oldStrValue
;
}
else
{
std
::
string_view
pk_value
=
rh
[
pk
].
text
();
if
(
pk_value
.
empty
())
cond
=
std
::
move
(
cond
)
and
key
(
ck
)
==
null
;
else
cond
=
std
::
move
(
cond
)
and
((
key
(
ck
)
==
pk_value
)
or
key
(
ck
)
==
null
);
}
}
// // if (cif::VERBOSE > 2)
auto
rows
=
childCat
->
find
(
std
::
move
(
cond
));
// // {
if
(
rows
.
empty
())
// // std::cerr << "Parent: " << linked->mParentCategory << " Child: " << linked->mChildCategory << std::endl
continue
;
// // << cond << std::endl;
// // }
// // Now, suppose there are already rows in child that conform to the new value,
// if (cif::VERBOSE > 2)
// // we then skip this renam
// {
// std::cerr << "Parent: " << linked->mParentCategory << " Child: " << linked->mChildCategory << std::endl
// << cond << std::endl;
// }
// Condition cond_n;
// Now, suppose there are already rows in child that conform to the new value,
// we then skip this renam
// for (size_t ix = 0; ix < linked->mParentKeys.size(); ++ix)
condition
cond_n
;
// {
// std::string pk = linked->mParentKeys[ix];
// std::string ck = linked->mChildKeys[ix];
// // TODO add code to *NOT* test mandatory fields for Empty
for
(
size_t
ix
=
0
;
ix
<
linked
->
m_parent_keys
.
size
();
++
ix
)
{
std
::
string
pk
=
linked
->
m_parent_keys
[
ix
];
std
::
string
ck
=
linked
->
m_child_keys
[
ix
];
// if (pk == iv->mTag)
// TODO add code to *NOT* test mandatory fields for Empty
// cond_n = std::move(cond_n) && Key(ck) == value;
// else
// {
// const char *pk_value = (*this)[pk].c_str();
// if (*pk_value == 0)
// cond_n = std::move(cond_n) && Key(ck) == Empty();
// else
// cond_n = std::move(cond_n) && ((Key(ck) == pk_value) or Key(ck) == Empty());
// }
// }
// auto rows_n = childCat->find(std::move(cond_n));
if
(
pk
==
iv
->
m_tag
)
// if (not rows_n.empty())
cond_n
=
std
::
move
(
cond_n
)
and
key
(
ck
)
==
value
;
// {
else
// if (cif::VERBOSE > 0)
{
// std::cerr << "Will not rename in child category since there are already rows that link to the parent" << std::endl;
std
::
string_view
pk_value
=
rh
[
pk
].
text
();
if
(
pk_value
.
empty
())
cond_n
=
std
::
move
(
cond_n
)
and
key
(
ck
)
==
null
;
else
cond_n
=
std
::
move
(
cond_n
)
and
((
key
(
ck
)
==
pk_value
)
or
key
(
ck
)
==
null
);
}
}
// continue;
auto
rows_n
=
childCat
->
find
(
std
::
move
(
cond_n
));
// }
if
(
not
rows_n
.
empty
())
{
if
(
cif
::
VERBOSE
>
0
)
std
::
cerr
<<
"Will not rename in child category since there are already rows that link to the parent"
<<
std
::
endl
;
// for (auto &cr : rows)
continue
;
// cr.assign(childTag, value, false);
}
// }
// }
for
(
auto
cr
:
rows
)
cr
.
assign
(
childTag
,
value
,
false
);
}
}
}
}
// proxy methods for every insertion
// proxy methods for every insertion
...
...
src/v2/condition.cpp
View file @
04b7828a
...
@@ -47,11 +47,11 @@ bool is_column_type_uchar(const category &cat, std::string_view col)
...
@@ -47,11 +47,11 @@ bool is_column_type_uchar(const category &cat, std::string_view col)
auto
cv
=
cat
.
get_cat_validator
();
auto
cv
=
cat
.
get_cat_validator
();
if
(
cv
)
if
(
cv
)
{
{
auto
iv
=
cv
->
get
ValidatorForI
tem
(
col
);
auto
iv
=
cv
->
get
_validator_for_i
tem
(
col
);
if
(
iv
!=
nullptr
and
iv
->
m
T
ype
!=
nullptr
)
if
(
iv
!=
nullptr
and
iv
->
m
_t
ype
!=
nullptr
)
{
{
auto
type
=
iv
->
m
T
ype
;
auto
type
=
iv
->
m
_t
ype
;
result
=
type
->
m
PrimitiveT
ype
==
DDL_PrimitiveType
::
UChar
;
result
=
type
->
m
_primitive_t
ype
==
DDL_PrimitiveType
::
UChar
;
}
}
}
}
...
...
src/v2/dictionary_parser.cpp
View file @
04b7828a
...
@@ -43,7 +43,7 @@ inline void replace_all(std::string &s, std::string_view pat, std::string_view r
...
@@ -43,7 +43,7 @@ inline void replace_all(std::string &s, std::string_view pat, std::string_view r
class
dictionary_parser
:
public
parser
class
dictionary_parser
:
public
parser
{
{
public
:
public
:
dictionary_parser
(
V
alidator
&
validator
,
std
::
istream
&
is
,
file
&
f
)
dictionary_parser
(
v
alidator
&
validator
,
std
::
istream
&
is
,
file
&
f
)
:
parser
(
is
,
f
)
:
parser
(
is
,
f
)
,
m_validator
(
validator
)
,
m_validator
(
validator
)
{
{
...
@@ -83,17 +83,17 @@ class dictionary_parser : public parser
...
@@ -83,17 +83,17 @@ class dictionary_parser : public parser
// store all validators
// store all validators
for
(
auto
&
ic
:
mCategoryValidators
)
for
(
auto
&
ic
:
mCategoryValidators
)
m_validator
.
add
CategoryV
alidator
(
std
::
move
(
ic
));
m_validator
.
add
_category_v
alidator
(
std
::
move
(
ic
));
mCategoryValidators
.
clear
();
mCategoryValidators
.
clear
();
for
(
auto
&
iv
:
mItemValidators
)
for
(
auto
&
iv
:
mItemValidators
)
{
{
auto
cv
=
m_validator
.
get
ValidatorForC
ategory
(
iv
.
first
);
auto
cv
=
m_validator
.
get
_validator_for_c
ategory
(
iv
.
first
);
if
(
cv
==
nullptr
)
if
(
cv
==
nullptr
)
error
(
"Undefined category '"
+
iv
.
first
);
error
(
"Undefined category '"
+
iv
.
first
);
for
(
auto
&
v
:
iv
.
second
)
for
(
auto
&
v
:
iv
.
second
)
const_cast
<
ValidateCategory
*>
(
cv
)
->
addItemValidator
(
std
::
move
(
v
));
const_cast
<
category_validator
*>
(
cv
)
->
addItemValidator
(
std
::
move
(
v
));
}
}
// check all item validators for having a typeValidator
// check all item validators for having a typeValidator
...
@@ -145,15 +145,15 @@ class dictionary_parser : public parser
...
@@ -145,15 +145,15 @@ class dictionary_parser : public parser
std
::
vector
<
std
::
string
>
tags
;
std
::
vector
<
std
::
string
>
tags
;
while
(
m_lookahead
==
CIFToken
::
Tag
)
while
(
m_lookahead
==
CIFToken
::
Tag
)
{
{
std
::
string
catName
,
item
N
ame
;
std
::
string
catName
,
item
_n
ame
;
std
::
tie
(
catName
,
item
N
ame
)
=
splitTagName
(
m_token_value
);
std
::
tie
(
catName
,
item
_n
ame
)
=
splitTagName
(
m_token_value
);
if
(
cat
==
dict
.
end
())
if
(
cat
==
dict
.
end
())
std
::
tie
(
cat
,
std
::
ignore
)
=
dict
.
emplace
(
catName
);
std
::
tie
(
cat
,
std
::
ignore
)
=
dict
.
emplace
(
catName
);
else
if
(
not
iequals
(
cat
->
name
(),
catName
))
else
if
(
not
iequals
(
cat
->
name
(),
catName
))
error
(
"inconsistent categories in loop_"
);
error
(
"inconsistent categories in loop_"
);
tags
.
push_back
(
item
N
ame
);
tags
.
push_back
(
item
_n
ame
);
match
(
CIFToken
::
Tag
);
match
(
CIFToken
::
Tag
);
}
}
...
@@ -173,8 +173,8 @@ class dictionary_parser : public parser
...
@@ -173,8 +173,8 @@ class dictionary_parser : public parser
}
}
else
else
{
{
std
::
string
catName
,
item
N
ame
;
std
::
string
catName
,
item
_n
ame
;
std
::
tie
(
catName
,
item
N
ame
)
=
splitTagName
(
m_token_value
);
std
::
tie
(
catName
,
item
_n
ame
)
=
splitTagName
(
m_token_value
);
if
(
cat
==
dict
.
end
()
or
not
iequals
(
cat
->
name
(),
catName
))
if
(
cat
==
dict
.
end
()
or
not
iequals
(
cat
->
name
(),
catName
))
std
::
tie
(
cat
,
std
::
ignore
)
=
dict
.
emplace
(
catName
);
std
::
tie
(
cat
,
std
::
ignore
)
=
dict
.
emplace
(
catName
);
...
@@ -183,7 +183,7 @@ class dictionary_parser : public parser
...
@@ -183,7 +183,7 @@ class dictionary_parser : public parser
if
(
cat
->
empty
())
if
(
cat
->
empty
())
cat
->
emplace
({});
cat
->
emplace
({});
cat
->
back
()[
item
N
ame
]
=
m_token_value
;
cat
->
back
()[
item
_n
ame
]
=
m_token_value
;
match
(
CIFToken
::
Value
);
match
(
CIFToken
::
Value
);
}
}
...
@@ -204,7 +204,7 @@ class dictionary_parser : public parser
...
@@ -204,7 +204,7 @@ class dictionary_parser : public parser
for
(
auto
g
:
dict
[
"category_group"
])
for
(
auto
g
:
dict
[
"category_group"
])
groups
.
insert
(
g
[
"id"
].
as
<
std
::
string
>
());
groups
.
insert
(
g
[
"id"
].
as
<
std
::
string
>
());
mCategoryValidators
.
push_back
(
ValidateCategory
{
category
,
keys
,
groups
});
mCategoryValidators
.
push_back
(
category_validator
{
category
,
keys
,
groups
});
}
}
else
else
{
{
...
@@ -212,9 +212,9 @@ class dictionary_parser : public parser
...
@@ -212,9 +212,9 @@ class dictionary_parser : public parser
std
::
string
typeCode
;
std
::
string
typeCode
;
cif
::
v2
::
tie
(
typeCode
)
=
dict
[
"item_type"
].
front
().
get
(
"code"
);
cif
::
v2
::
tie
(
typeCode
)
=
dict
[
"item_type"
].
front
().
get
(
"code"
);
const
ValidateType
*
tv
=
nullptr
;
const
type_validator
*
tv
=
nullptr
;
if
(
not
(
typeCode
.
empty
()
or
typeCode
==
"?"
))
if
(
not
(
typeCode
.
empty
()
or
typeCode
==
"?"
))
tv
=
m_validator
.
get
ValidatorForT
ype
(
typeCode
);
tv
=
m_validator
.
get
_validator_for_t
ype
(
typeCode
);
iset
ess
;
iset
ess
;
for
(
auto
e
:
dict
[
"item_enumeration"
])
for
(
auto
e
:
dict
[
"item_enumeration"
])
...
@@ -240,10 +240,10 @@ class dictionary_parser : public parser
...
@@ -240,10 +240,10 @@ class dictionary_parser : public parser
cif
::
v2
::
tie
(
tagName
,
category
,
mandatory
)
=
i
.
get
(
"name"
,
"category_id"
,
"mandatory_code"
);
cif
::
v2
::
tie
(
tagName
,
category
,
mandatory
)
=
i
.
get
(
"name"
,
"category_id"
,
"mandatory_code"
);
std
::
string
catName
,
item
N
ame
;
std
::
string
catName
,
item
_n
ame
;
std
::
tie
(
catName
,
item
N
ame
)
=
splitTagName
(
tagName
);
std
::
tie
(
catName
,
item
_n
ame
)
=
splitTagName
(
tagName
);
if
(
catName
.
empty
()
or
item
N
ame
.
empty
())
if
(
catName
.
empty
()
or
item
_n
ame
.
empty
())
error
(
"Invalid tag name in _item.name "
+
tagName
);
error
(
"Invalid tag name in _item.name "
+
tagName
);
if
(
not
iequals
(
category
,
catName
)
and
not
(
category
.
empty
()
or
category
==
"?"
))
if
(
not
iequals
(
category
,
catName
)
and
not
(
category
.
empty
()
or
category
==
"?"
))
...
@@ -253,13 +253,13 @@ class dictionary_parser : public parser
...
@@ -253,13 +253,13 @@ class dictionary_parser : public parser
auto
&
ivs
=
mItemValidators
[
category
];
auto
&
ivs
=
mItemValidators
[
category
];
auto
vi
=
find
(
ivs
.
begin
(),
ivs
.
end
(),
ValidateItem
{
itemN
ame
});
auto
vi
=
find
(
ivs
.
begin
(),
ivs
.
end
(),
item_validator
{
item_n
ame
});
if
(
vi
==
ivs
.
end
())
if
(
vi
==
ivs
.
end
())
ivs
.
push_back
(
ValidateItem
{
itemN
ame
,
iequals
(
mandatory
,
"yes"
),
tv
,
ess
,
defaultValue
,
defaultIsNull
});
ivs
.
push_back
(
item_validator
{
item_n
ame
,
iequals
(
mandatory
,
"yes"
),
tv
,
ess
,
defaultValue
,
defaultIsNull
});
else
else
{
{
// need to update the itemValidator?
// need to update the itemValidator?
if
(
vi
->
m
M
andatory
!=
(
iequals
(
mandatory
,
"yes"
)))
if
(
vi
->
m
_m
andatory
!=
(
iequals
(
mandatory
,
"yes"
)))
{
{
if
(
VERBOSE
>
2
)
if
(
VERBOSE
>
2
)
{
{
...
@@ -268,24 +268,24 @@ class dictionary_parser : public parser
...
@@ -268,24 +268,24 @@ class dictionary_parser : public parser
if
(
iequals
(
tagName
,
saveFrameName
))
if
(
iequals
(
tagName
,
saveFrameName
))
std
::
cerr
<<
"choosing "
<<
mandatory
<<
std
::
endl
;
std
::
cerr
<<
"choosing "
<<
mandatory
<<
std
::
endl
;
else
else
std
::
cerr
<<
"choosing "
<<
(
vi
->
m
M
andatory
?
"Y"
:
"N"
)
<<
std
::
endl
;
std
::
cerr
<<
"choosing "
<<
(
vi
->
m
_m
andatory
?
"Y"
:
"N"
)
<<
std
::
endl
;
}
}
if
(
iequals
(
tagName
,
saveFrameName
))
if
(
iequals
(
tagName
,
saveFrameName
))
vi
->
m
M
andatory
=
(
iequals
(
mandatory
,
"yes"
));
vi
->
m
_m
andatory
=
(
iequals
(
mandatory
,
"yes"
));
}
}
if
(
vi
->
m
Type
!=
nullptr
and
tv
!=
nullptr
and
vi
->
mT
ype
!=
tv
)
if
(
vi
->
m
_type
!=
nullptr
and
tv
!=
nullptr
and
vi
->
m_t
ype
!=
tv
)
{
{
if
(
VERBOSE
>
1
)
if
(
VERBOSE
>
1
)
std
::
cerr
<<
"inconsistent type for "
<<
tagName
<<
" in dictionary"
<<
std
::
endl
;
std
::
cerr
<<
"inconsistent type for "
<<
tagName
<<
" in dictionary"
<<
std
::
endl
;
}
}
// vi->mMandatory = (iequals(mandatory, "yes"));
// vi->mMandatory = (iequals(mandatory, "yes"));
if
(
vi
->
m
T
ype
==
nullptr
)
if
(
vi
->
m
_t
ype
==
nullptr
)
vi
->
m
T
ype
=
tv
;
vi
->
m
_t
ype
=
tv
;
vi
->
m
E
nums
.
insert
(
ess
.
begin
(),
ess
.
end
());
vi
->
m
_e
nums
.
insert
(
ess
.
begin
(),
ess
.
end
());
// anything else yet?
// anything else yet?
// ...
// ...
...
@@ -349,15 +349,15 @@ class dictionary_parser : public parser
...
@@ -349,15 +349,15 @@ class dictionary_parser : public parser
int
link_group_id
;
int
link_group_id
;
cif
::
v2
::
tie
(
child
,
parent
,
link_group_id
)
=
gl
.
get
(
"child_name"
,
"parent_name"
,
"link_group_id"
);
cif
::
v2
::
tie
(
child
,
parent
,
link_group_id
)
=
gl
.
get
(
"child_name"
,
"parent_name"
,
"link_group_id"
);
auto
civ
=
m_validator
.
get
ValidatorForI
tem
(
child
);
auto
civ
=
m_validator
.
get
_validator_for_i
tem
(
child
);
if
(
civ
==
nullptr
)
if
(
civ
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
auto
piv
=
m_validator
.
get
ValidatorForI
tem
(
parent
);
auto
piv
=
m_validator
.
get
_validator_for_i
tem
(
parent
);
if
(
piv
==
nullptr
)
if
(
piv
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
key_type
key
{
piv
->
m
Category
->
mName
,
civ
->
mCategory
->
mN
ame
,
link_group_id
};
key_type
key
{
piv
->
m
_category
->
m_name
,
civ
->
m_category
->
m_n
ame
,
link_group_id
};
if
(
not
linkIndex
.
count
(
key
))
if
(
not
linkIndex
.
count
(
key
))
{
{
linkIndex
[
key
]
=
linkKeys
.
size
();
linkIndex
[
key
]
=
linkKeys
.
size
();
...
@@ -365,7 +365,7 @@ class dictionary_parser : public parser
...
@@ -365,7 +365,7 @@ class dictionary_parser : public parser
}
}
size_t
ix
=
linkIndex
.
at
(
key
);
size_t
ix
=
linkIndex
.
at
(
key
);
addLink
(
ix
,
piv
->
m
Tag
,
civ
->
mT
ag
);
addLink
(
ix
,
piv
->
m
_tag
,
civ
->
m_t
ag
);
}
}
// Only process inline linked items if the linked group list is absent
// Only process inline linked items if the linked group list is absent
...
@@ -377,15 +377,15 @@ class dictionary_parser : public parser
...
@@ -377,15 +377,15 @@ class dictionary_parser : public parser
std
::
string
child
,
parent
;
std
::
string
child
,
parent
;
std
::
tie
(
child
,
parent
)
=
li
;
std
::
tie
(
child
,
parent
)
=
li
;
auto
civ
=
m_validator
.
get
ValidatorForI
tem
(
child
);
auto
civ
=
m_validator
.
get
_validator_for_i
tem
(
child
);
if
(
civ
==
nullptr
)
if
(
civ
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
error
(
"in pdbx_item_linked_group_list, item '"
+
child
+
"' is not specified"
);
auto
piv
=
m_validator
.
get
ValidatorForI
tem
(
parent
);
auto
piv
=
m_validator
.
get
_validator_for_i
tem
(
parent
);
if
(
piv
==
nullptr
)
if
(
piv
==
nullptr
)
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
error
(
"in pdbx_item_linked_group_list, item '"
+
parent
+
"' is not specified"
);
key_type
key
{
piv
->
m
Category
->
mName
,
civ
->
mCategory
->
mN
ame
,
0
};
key_type
key
{
piv
->
m
_category
->
m_name
,
civ
->
m_category
->
m_n
ame
,
0
};
if
(
not
linkIndex
.
count
(
key
))
if
(
not
linkIndex
.
count
(
key
))
{
{
linkIndex
[
key
]
=
linkKeys
.
size
();
linkIndex
[
key
]
=
linkKeys
.
size
();
...
@@ -393,7 +393,7 @@ class dictionary_parser : public parser
...
@@ -393,7 +393,7 @@ class dictionary_parser : public parser
}
}
size_t
ix
=
linkIndex
.
at
(
key
);
size_t
ix
=
linkIndex
.
at
(
key
);
addLink
(
ix
,
piv
->
m
Tag
,
civ
->
mT
ag
);
addLink
(
ix
,
piv
->
m
_tag
,
civ
->
m_t
ag
);
}
}
}
}
...
@@ -402,29 +402,29 @@ class dictionary_parser : public parser
...
@@ -402,29 +402,29 @@ class dictionary_parser : public parser
// now store the links in the validator
// now store the links in the validator
for
(
auto
&
kv
:
linkIndex
)
for
(
auto
&
kv
:
linkIndex
)
{
{
ValidateLink
link
=
{};
link_validator
link
=
{};
std
::
tie
(
link
.
m
ParentCategory
,
link
.
mChildCategory
,
link
.
mLinkGroupID
)
=
kv
.
first
;
std
::
tie
(
link
.
m
_parent_category
,
link
.
m_child_category
,
link
.
m_link_group_id
)
=
kv
.
first
;
std
::
tie
(
link
.
m
ParentKeys
,
link
.
mChildK
eys
)
=
linkKeys
[
kv
.
second
];
std
::
tie
(
link
.
m
_parent_keys
,
link
.
m_child_k
eys
)
=
linkKeys
[
kv
.
second
];
// look up the label
// look up the label
for
(
auto
r
:
linkedGroup
.
find
(
"category_id"
_key
==
link
.
m
ChildCategory
and
"link_group_id"
_key
==
link
.
mLinkGroupID
))
for
(
auto
r
:
linkedGroup
.
find
(
"category_id"
_key
==
link
.
m
_child_category
and
"link_group_id"
_key
==
link
.
m_link_group_id
))
{
{
link
.
m
LinkGroupL
abel
=
r
[
"label"
].
as
<
std
::
string
>
();
link
.
m
_link_group_l
abel
=
r
[
"label"
].
as
<
std
::
string
>
();
break
;
break
;
}
}
m_validator
.
add
LinkV
alidator
(
std
::
move
(
link
));
m_validator
.
add
_link_v
alidator
(
std
::
move
(
link
));
}
}
// now make sure the itemType is specified for all itemValidators
// now make sure the itemType is specified for all itemValidators
for
(
auto
&
cv
:
m_validator
.
m
CategoryV
alidators
)
for
(
auto
&
cv
:
m_validator
.
m
_category_v
alidators
)
{
{
for
(
auto
&
iv
:
cv
.
m
ItemV
alidators
)
for
(
auto
&
iv
:
cv
.
m
_item_v
alidators
)
{
{
if
(
iv
.
m
T
ype
==
nullptr
and
cif
::
VERBOSE
>=
0
)
if
(
iv
.
m
_t
ype
==
nullptr
and
cif
::
VERBOSE
>=
0
)
std
::
cerr
<<
"Missing item_type for "
<<
iv
.
m
T
ag
<<
std
::
endl
;
std
::
cerr
<<
"Missing item_type for "
<<
iv
.
m
_t
ag
<<
std
::
endl
;
}
}
}
}
}
}
...
@@ -449,10 +449,10 @@ class dictionary_parser : public parser
...
@@ -449,10 +449,10 @@ class dictionary_parser : public parser
try
try
{
{
ValidateType
v
=
{
type_validator
v
=
{
code
,
map
ToPrimitiveT
ype
(
primitiveCode
),
boost
::
regex
(
construct
,
boost
::
regex
::
extended
|
boost
::
regex
::
optimize
)};
code
,
map
_to_primitive_t
ype
(
primitiveCode
),
boost
::
regex
(
construct
,
boost
::
regex
::
extended
|
boost
::
regex
::
optimize
)};
m_validator
.
add
TypeV
alidator
(
std
::
move
(
v
));
m_validator
.
add
_type_v
alidator
(
std
::
move
(
v
));
}
}
catch
(
const
std
::
exception
&
)
catch
(
const
std
::
exception
&
)
{
{
...
@@ -473,19 +473,19 @@ class dictionary_parser : public parser
...
@@ -473,19 +473,19 @@ class dictionary_parser : public parser
return
result
;
return
result
;
}
}
V
alidator
&
m_validator
;
v
alidator
&
m_validator
;
bool
m_collected_item_types
=
false
;
bool
m_collected_item_types
=
false
;
std
::
vector
<
ValidateCategory
>
mCategoryValidators
;
std
::
vector
<
category_validator
>
mCategoryValidators
;
std
::
map
<
std
::
string
,
std
::
vector
<
ValidateItem
>>
mItemValidators
;
std
::
map
<
std
::
string
,
std
::
vector
<
item_validator
>>
mItemValidators
;
std
::
set
<
std
::
tuple
<
std
::
string
,
std
::
string
>>
mLinkedItems
;
std
::
set
<
std
::
tuple
<
std
::
string
,
std
::
string
>>
mLinkedItems
;
};
};
// --------------------------------------------------------------------
// --------------------------------------------------------------------
V
alidator
parse_dictionary
(
std
::
string_view
name
,
std
::
istream
&
is
)
v
alidator
parse_dictionary
(
std
::
string_view
name
,
std
::
istream
&
is
)
{
{
V
alidator
result
(
name
);
v
alidator
result
(
name
);
file
f
;
file
f
;
dictionary_parser
p
(
result
,
is
,
f
);
dictionary_parser
p
(
result
,
is
,
f
);
...
...
src/v2/item.cpp
View file @
04b7828a
...
@@ -31,13 +31,21 @@ namespace cif::v2
...
@@ -31,13 +31,21 @@ namespace cif::v2
std
::
string_view
item_handle
::
text
()
const
std
::
string_view
item_handle
::
text
()
const
{
{
if
(
m_row_handle
.
m_row
!=
nullptr
)
{
for
(
auto
iv
=
m_row_handle
.
m_row
->
m_head
;
iv
!=
nullptr
;
iv
=
iv
->
m_next
)
for
(
auto
iv
=
m_row_handle
.
m_row
->
m_head
;
iv
!=
nullptr
;
iv
=
iv
->
m_next
)
{
{
if
(
iv
->
m_column_ix
==
m_column
)
if
(
iv
->
m_column_ix
==
m_column
)
return
iv
->
text
();
return
iv
->
text
();
}
}
}
return
{};
return
{};
}
}
void
item_handle
::
assign_value
(
const
item
&
v
)
{
m_row_handle
.
assign
(
m_column
,
v
.
value
(),
false
);
}
}
}
src/v2/validate.cpp
View file @
04b7828a
...
@@ -28,8 +28,8 @@
...
@@ -28,8 +28,8 @@
#include <fstream>
#include <fstream>
#include <iostream>
#include <iostream>
#include <cif++/v2/validate.hpp>
#include <cif++/v2/dictionary_parser.hpp>
#include <cif++/v2/dictionary_parser.hpp>
#include <cif++/v2/validate.hpp>
namespace
cif
namespace
cif
{
{
...
@@ -41,19 +41,19 @@ namespace cif::v2
...
@@ -41,19 +41,19 @@ namespace cif::v2
using
cif
::
VERBOSE
;
using
cif
::
VERBOSE
;
ValidationError
::
ValidationE
rror
(
const
std
::
string
&
msg
)
validation_error
::
validation_e
rror
(
const
std
::
string
&
msg
)
:
m
M
sg
(
msg
)
:
m
_m
sg
(
msg
)
{
{
}
}
ValidationError
::
ValidationE
rror
(
const
std
::
string
&
cat
,
const
std
::
string
&
item
,
const
std
::
string
&
msg
)
validation_error
::
validation_e
rror
(
const
std
::
string
&
cat
,
const
std
::
string
&
item
,
const
std
::
string
&
msg
)
:
m
M
sg
(
"When validating _"
+
cat
+
'.'
+
item
+
": "
+
msg
)
:
m
_m
sg
(
"When validating _"
+
cat
+
'.'
+
item
+
": "
+
msg
)
{
{
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
DDL_PrimitiveType
map
ToPrimitiveT
ype
(
std
::
string_view
s
)
DDL_PrimitiveType
map
_to_primitive_t
ype
(
std
::
string_view
s
)
{
{
DDL_PrimitiveType
result
;
DDL_PrimitiveType
result
;
if
(
iequals
(
s
,
"char"
))
if
(
iequals
(
s
,
"char"
))
...
@@ -63,13 +63,13 @@ DDL_PrimitiveType mapToPrimitiveType(std::string_view s)
...
@@ -63,13 +63,13 @@ DDL_PrimitiveType mapToPrimitiveType(std::string_view s)
else
if
(
iequals
(
s
,
"numb"
))
else
if
(
iequals
(
s
,
"numb"
))
result
=
DDL_PrimitiveType
::
Numb
;
result
=
DDL_PrimitiveType
::
Numb
;
else
else
throw
ValidationE
rror
(
"Not a known primitive type"
);
throw
validation_e
rror
(
"Not a known primitive type"
);
return
result
;
return
result
;
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
int
ValidateType
::
compare
(
const
char
*
a
,
const
char
*
b
)
const
int
type_validator
::
compare
(
const
char
*
a
,
const
char
*
b
)
const
{
{
int
result
=
0
;
int
result
=
0
;
...
@@ -81,7 +81,7 @@ int ValidateType::compare(const char *a, const char *b) const
...
@@ -81,7 +81,7 @@ int ValidateType::compare(const char *a, const char *b) const
{
{
try
try
{
{
switch
(
m
PrimitiveT
ype
)
switch
(
m
_primitive_t
ype
)
{
{
case
DDL_PrimitiveType
:
:
Numb
:
case
DDL_PrimitiveType
:
:
Numb
:
{
{
...
@@ -123,7 +123,7 @@ int ValidateType::compare(const char *a, const char *b) const
...
@@ -123,7 +123,7 @@ int ValidateType::compare(const char *a, const char *b) const
char
ca
=
*
ai
;
char
ca
=
*
ai
;
char
cb
=
*
bi
;
char
cb
=
*
bi
;
if
(
m
PrimitiveT
ype
==
DDL_PrimitiveType
::
UChar
)
if
(
m
_primitive_t
ype
==
DDL_PrimitiveType
::
UChar
)
{
{
ca
=
tolower
(
ca
);
ca
=
tolower
(
ca
);
cb
=
tolower
(
cb
);
cb
=
tolower
(
cb
);
...
@@ -161,10 +161,10 @@ int ValidateType::compare(const char *a, const char *b) const
...
@@ -161,10 +161,10 @@ int ValidateType::compare(const char *a, const char *b) const
// --------------------------------------------------------------------
// --------------------------------------------------------------------
//void ValidateItem::addLinked(ValidateItem* parent, const std::string& parentItem, const std::string& childItem)
//
void ValidateItem::addLinked(ValidateItem* parent, const std::string& parentItem, const std::string& childItem)
//{
//{
//// if (mParent != nullptr and VERBOSE)
//// if (mParent != nullptr and VERBOSE)
//// cerr << "replacing parent in " << mCategory->m
Name << " from " << mParent->mCategory->mName << " to " << parent->mCategory->mN
ame << endl;
//// cerr << "replacing parent in " << mCategory->m
_name << " from " << mParent->mCategory->m_name << " to " << parent->mCategory->m_n
ame << endl;
//// mParent = parent;
//// mParent = parent;
//
//
// if (mType == nullptr and parent != nullptr)
// if (mType == nullptr and parent != nullptr)
...
@@ -181,40 +181,40 @@ int ValidateType::compare(const char *a, const char *b) const
...
@@ -181,40 +181,40 @@ int ValidateType::compare(const char *a, const char *b) const
// }
// }
//}
//}
void
ValidateItem
::
operator
()(
std
::
string
value
)
const
void
item_validator
::
operator
()(
std
::
string_view
value
)
const
{
{
if
(
not
value
.
empty
()
and
value
!=
"?"
and
value
!=
"."
)
if
(
not
value
.
empty
()
and
value
!=
"?"
and
value
!=
"."
)
{
{
if
(
m
Type
!=
nullptr
and
not
regex_match
(
value
,
mType
->
mR
x
))
if
(
m
_type
!=
nullptr
and
not
regex_match
(
value
.
begin
(),
value
.
end
(),
m_type
->
m_r
x
))
throw
ValidationError
(
mCategory
->
mName
,
mTag
,
"Value '"
+
value
+
"' does not match type expression for type "
+
mType
->
mN
ame
);
throw
validation_error
(
m_category
->
m_name
,
m_tag
,
"Value '"
+
std
::
string
{
value
}
+
"' does not match type expression for type "
+
m_type
->
m_n
ame
);
if
(
not
m
E
nums
.
empty
())
if
(
not
m
_e
nums
.
empty
())
{
{
if
(
m
Enums
.
count
(
value
)
==
0
)
if
(
m
_enums
.
count
(
std
::
string
{
value
}
)
==
0
)
throw
ValidationError
(
mCategory
->
mName
,
mTag
,
"Value '"
+
value
+
"' is not in the list of allowed values"
);
throw
validation_error
(
m_category
->
m_name
,
m_tag
,
"Value '"
+
std
::
string
{
value
}
+
"' is not in the list of allowed values"
);
}
}
}
}
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
ValidateCategory
::
addItemValidator
(
ValidateItem
&&
v
)
void
category_validator
::
addItemValidator
(
item_validator
&&
v
)
{
{
if
(
v
.
m
M
andatory
)
if
(
v
.
m
_m
andatory
)
m
MandatoryFields
.
insert
(
v
.
mT
ag
);
m
_mandatory_fields
.
insert
(
v
.
m_t
ag
);
v
.
m
C
ategory
=
this
;
v
.
m
_c
ategory
=
this
;
auto
r
=
m
ItemV
alidators
.
insert
(
std
::
move
(
v
));
auto
r
=
m
_item_v
alidators
.
insert
(
std
::
move
(
v
));
if
(
not
r
.
second
and
VERBOSE
>=
4
)
if
(
not
r
.
second
and
VERBOSE
>=
4
)
std
::
cout
<<
"Could not add validator for item "
<<
v
.
m
Tag
<<
" to category "
<<
mN
ame
<<
std
::
endl
;
std
::
cout
<<
"Could not add validator for item "
<<
v
.
m
_tag
<<
" to category "
<<
m_n
ame
<<
std
::
endl
;
}
}
const
ValidateItem
*
ValidateCategory
::
getValidatorForI
tem
(
std
::
string_view
tag
)
const
const
item_validator
*
category_validator
::
get_validator_for_i
tem
(
std
::
string_view
tag
)
const
{
{
const
ValidateItem
*
result
=
nullptr
;
const
item_validator
*
result
=
nullptr
;
auto
i
=
m
ItemValidators
.
find
(
ValidateItem
{
std
::
string
(
tag
)});
auto
i
=
m
_item_validators
.
find
(
item_validator
{
std
::
string
(
tag
)});
if
(
i
!=
m
ItemV
alidators
.
end
())
if
(
i
!=
m
_item_v
alidators
.
end
())
result
=
&*
i
;
result
=
&*
i
;
else
if
(
VERBOSE
>
4
)
else
if
(
VERBOSE
>
4
)
std
::
cout
<<
"No validator for tag "
<<
tag
<<
std
::
endl
;
std
::
cout
<<
"No validator for tag "
<<
tag
<<
std
::
endl
;
...
@@ -223,53 +223,53 @@ const ValidateItem *ValidateCategory::getValidatorForItem(std::string_view tag)
...
@@ -223,53 +223,53 @@ const ValidateItem *ValidateCategory::getValidatorForItem(std::string_view tag)
// --------------------------------------------------------------------
// --------------------------------------------------------------------
void
Validator
::
addTypeValidator
(
ValidateType
&&
v
)
void
validator
::
add_type_validator
(
type_validator
&&
v
)
{
{
auto
r
=
m
TypeV
alidators
.
insert
(
std
::
move
(
v
));
auto
r
=
m
_type_v
alidators
.
insert
(
std
::
move
(
v
));
if
(
not
r
.
second
and
VERBOSE
>
4
)
if
(
not
r
.
second
and
VERBOSE
>
4
)
std
::
cout
<<
"Could not add validator for type "
<<
v
.
m
N
ame
<<
std
::
endl
;
std
::
cout
<<
"Could not add validator for type "
<<
v
.
m
_n
ame
<<
std
::
endl
;
}
}
const
ValidateType
*
Validator
::
getValidatorForT
ype
(
std
::
string_view
typeCode
)
const
const
type_validator
*
validator
::
get_validator_for_t
ype
(
std
::
string_view
typeCode
)
const
{
{
const
ValidateType
*
result
=
nullptr
;
const
type_validator
*
result
=
nullptr
;
auto
i
=
m
TypeValidators
.
find
(
ValidateType
{
std
::
string
(
typeCode
),
DDL_PrimitiveType
::
Char
,
boost
::
regex
()});
auto
i
=
m
_type_validators
.
find
(
type_validator
{
std
::
string
(
typeCode
),
DDL_PrimitiveType
::
Char
,
boost
::
regex
()});
if
(
i
!=
m
TypeV
alidators
.
end
())
if
(
i
!=
m
_type_v
alidators
.
end
())
result
=
&*
i
;
result
=
&*
i
;
else
if
(
VERBOSE
>
4
)
else
if
(
VERBOSE
>
4
)
std
::
cout
<<
"No validator for type "
<<
typeCode
<<
std
::
endl
;
std
::
cout
<<
"No validator for type "
<<
typeCode
<<
std
::
endl
;
return
result
;
return
result
;
}
}
void
Validator
::
addCategoryValidator
(
ValidateCategory
&&
v
)
void
validator
::
add_category_validator
(
category_validator
&&
v
)
{
{
auto
r
=
m
CategoryV
alidators
.
insert
(
std
::
move
(
v
));
auto
r
=
m
_category_v
alidators
.
insert
(
std
::
move
(
v
));
if
(
not
r
.
second
and
VERBOSE
>
4
)
if
(
not
r
.
second
and
VERBOSE
>
4
)
std
::
cout
<<
"Could not add validator for category "
<<
v
.
m
N
ame
<<
std
::
endl
;
std
::
cout
<<
"Could not add validator for category "
<<
v
.
m
_n
ame
<<
std
::
endl
;
}
}
const
ValidateCategory
*
Validator
::
getValidatorForC
ategory
(
std
::
string_view
category
)
const
const
category_validator
*
validator
::
get_validator_for_c
ategory
(
std
::
string_view
category
)
const
{
{
const
ValidateCategory
*
result
=
nullptr
;
const
category_validator
*
result
=
nullptr
;
auto
i
=
m
CategoryValidators
.
find
(
ValidateCategory
{
std
::
string
(
category
)});
auto
i
=
m
_category_validators
.
find
(
category_validator
{
std
::
string
(
category
)});
if
(
i
!=
m
CategoryV
alidators
.
end
())
if
(
i
!=
m
_category_v
alidators
.
end
())
result
=
&*
i
;
result
=
&*
i
;
else
if
(
VERBOSE
>
4
)
else
if
(
VERBOSE
>
4
)
std
::
cout
<<
"No validator for category "
<<
category
<<
std
::
endl
;
std
::
cout
<<
"No validator for category "
<<
category
<<
std
::
endl
;
return
result
;
return
result
;
}
}
ValidateItem
*
Validator
::
getValidatorForI
tem
(
std
::
string_view
tag
)
const
item_validator
*
validator
::
get_validator_for_i
tem
(
std
::
string_view
tag
)
const
{
{
ValidateItem
*
result
=
nullptr
;
item_validator
*
result
=
nullptr
;
std
::
string
cat
,
item
;
std
::
string
cat
,
item
;
std
::
tie
(
cat
,
item
)
=
splitTagName
(
tag
);
std
::
tie
(
cat
,
item
)
=
splitTagName
(
tag
);
auto
*
cv
=
get
ValidatorForC
ategory
(
cat
);
auto
*
cv
=
get
_validator_for_c
ategory
(
cat
);
if
(
cv
!=
nullptr
)
if
(
cv
!=
nullptr
)
result
=
const_cast
<
ValidateItem
*>
(
cv
->
getValidatorForI
tem
(
item
));
result
=
const_cast
<
item_validator
*>
(
cv
->
get_validator_for_i
tem
(
item
));
if
(
result
==
nullptr
and
VERBOSE
>
4
)
if
(
result
==
nullptr
and
VERBOSE
>
4
)
std
::
cout
<<
"No validator for item "
<<
tag
<<
std
::
endl
;
std
::
cout
<<
"No validator for item "
<<
tag
<<
std
::
endl
;
...
@@ -277,80 +277,80 @@ ValidateItem *Validator::getValidatorForItem(std::string_view tag) const
...
@@ -277,80 +277,80 @@ ValidateItem *Validator::getValidatorForItem(std::string_view tag) const
return
result
;
return
result
;
}
}
void
Validator
::
addLinkValidator
(
ValidateLink
&&
v
)
void
validator
::
add_link_validator
(
link_validator
&&
v
)
{
{
assert
(
v
.
m
ParentKeys
.
size
()
==
v
.
mChildK
eys
.
size
());
assert
(
v
.
m
_parent_keys
.
size
()
==
v
.
m_child_k
eys
.
size
());
if
(
v
.
m
ParentKeys
.
size
()
!=
v
.
mChildK
eys
.
size
())
if
(
v
.
m
_parent_keys
.
size
()
!=
v
.
m_child_k
eys
.
size
())
throw
std
::
runtime_error
(
"unequal number of keys for parent and child in link"
);
throw
std
::
runtime_error
(
"unequal number of keys for parent and child in link"
);
auto
pcv
=
get
ValidatorForCategory
(
v
.
mParentC
ategory
);
auto
pcv
=
get
_validator_for_category
(
v
.
m_parent_c
ategory
);
auto
ccv
=
get
ValidatorForCategory
(
v
.
mChildC
ategory
);
auto
ccv
=
get
_validator_for_category
(
v
.
m_child_c
ategory
);
if
(
pcv
==
nullptr
)
if
(
pcv
==
nullptr
)
throw
std
::
runtime_error
(
"unknown parent category "
+
v
.
m
ParentC
ategory
);
throw
std
::
runtime_error
(
"unknown parent category "
+
v
.
m
_parent_c
ategory
);
if
(
ccv
==
nullptr
)
if
(
ccv
==
nullptr
)
throw
std
::
runtime_error
(
"unknown child category "
+
v
.
m
ChildC
ategory
);
throw
std
::
runtime_error
(
"unknown child category "
+
v
.
m
_child_c
ategory
);
for
(
size_t
i
=
0
;
i
<
v
.
m
ParentK
eys
.
size
();
++
i
)
for
(
size_t
i
=
0
;
i
<
v
.
m
_parent_k
eys
.
size
();
++
i
)
{
{
auto
piv
=
pcv
->
get
ValidatorForItem
(
v
.
mParentK
eys
[
i
]);
auto
piv
=
pcv
->
get
_validator_for_item
(
v
.
m_parent_k
eys
[
i
]);
if
(
piv
==
nullptr
)
if
(
piv
==
nullptr
)
throw
std
::
runtime_error
(
"unknown parent tag _"
+
v
.
m
ParentCategory
+
'.'
+
v
.
mParentK
eys
[
i
]);
throw
std
::
runtime_error
(
"unknown parent tag _"
+
v
.
m
_parent_category
+
'.'
+
v
.
m_parent_k
eys
[
i
]);
auto
civ
=
ccv
->
get
ValidatorForItem
(
v
.
mChildK
eys
[
i
]);
auto
civ
=
ccv
->
get
_validator_for_item
(
v
.
m_child_k
eys
[
i
]);
if
(
civ
==
nullptr
)
if
(
civ
==
nullptr
)
throw
std
::
runtime_error
(
"unknown child tag _"
+
v
.
m
ChildCategory
+
'.'
+
v
.
mChildK
eys
[
i
]);
throw
std
::
runtime_error
(
"unknown child tag _"
+
v
.
m
_child_category
+
'.'
+
v
.
m_child_k
eys
[
i
]);
if
(
civ
->
m
Type
==
nullptr
and
piv
->
mT
ype
!=
nullptr
)
if
(
civ
->
m
_type
==
nullptr
and
piv
->
m_t
ype
!=
nullptr
)
const_cast
<
ValidateItem
*>
(
civ
)
->
mType
=
piv
->
mT
ype
;
const_cast
<
item_validator
*>
(
civ
)
->
m_type
=
piv
->
m_t
ype
;
}
}
m
LinkV
alidators
.
emplace_back
(
std
::
move
(
v
));
m
_link_v
alidators
.
emplace_back
(
std
::
move
(
v
));
}
}
std
::
vector
<
const
ValidateLink
*>
Validator
::
getLinksForP
arent
(
std
::
string_view
category
)
const
std
::
vector
<
const
link_validator
*>
validator
::
get_links_for_p
arent
(
std
::
string_view
category
)
const
{
{
std
::
vector
<
const
ValidateLink
*>
result
;
std
::
vector
<
const
link_validator
*>
result
;
for
(
auto
&
l
:
m
LinkV
alidators
)
for
(
auto
&
l
:
m
_link_v
alidators
)
{
{
if
(
l
.
m
ParentC
ategory
==
category
)
if
(
l
.
m
_parent_c
ategory
==
category
)
result
.
push_back
(
&
l
);
result
.
push_back
(
&
l
);
}
}
return
result
;
return
result
;
}
}
std
::
vector
<
const
ValidateLink
*>
Validator
::
getLinksForC
hild
(
std
::
string_view
category
)
const
std
::
vector
<
const
link_validator
*>
validator
::
get_links_for_c
hild
(
std
::
string_view
category
)
const
{
{
std
::
vector
<
const
ValidateLink
*>
result
;
std
::
vector
<
const
link_validator
*>
result
;
for
(
auto
&
l
:
m
LinkV
alidators
)
for
(
auto
&
l
:
m
_link_v
alidators
)
{
{
if
(
l
.
m
ChildC
ategory
==
category
)
if
(
l
.
m
_child_c
ategory
==
category
)
result
.
push_back
(
&
l
);
result
.
push_back
(
&
l
);
}
}
return
result
;
return
result
;
}
}
void
Validator
::
reportE
rror
(
const
std
::
string
&
msg
,
bool
fatal
)
const
void
validator
::
report_e
rror
(
const
std
::
string
&
msg
,
bool
fatal
)
const
{
{
if
(
m_strict
or
fatal
)
if
(
m_strict
or
fatal
)
throw
ValidationE
rror
(
msg
);
throw
validation_e
rror
(
msg
);
else
if
(
VERBOSE
>
0
)
else
if
(
VERBOSE
>
0
)
std
::
cerr
<<
msg
<<
std
::
endl
;
std
::
cerr
<<
msg
<<
std
::
endl
;
}
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
const
Validator
&
ValidatorF
actory
::
operator
[](
std
::
string_view
dictionary_name
)
const
validator
&
validator_f
actory
::
operator
[](
std
::
string_view
dictionary_name
)
{
{
std
::
lock_guard
lock
(
m
M
utex
);
std
::
lock_guard
lock
(
m
_m
utex
);
for
(
auto
&
validator
:
m
V
alidators
)
for
(
auto
&
validator
:
m
_v
alidators
)
{
{
if
(
iequals
(
validator
.
name
(),
dictionary_name
))
if
(
iequals
(
validator
.
name
(),
dictionary_name
))
return
validator
;
return
validator
;
...
@@ -417,14 +417,14 @@ const Validator &ValidatorFactory::operator[](std::string_view dictionary_name)
...
@@ -417,14 +417,14 @@ const Validator &ValidatorFactory::operator[](std::string_view dictionary_name)
throw
std
::
runtime_error
(
"Dictionary not found or defined ("
+
dictionary
.
string
()
+
")"
);
throw
std
::
runtime_error
(
"Dictionary not found or defined ("
+
dictionary
.
string
()
+
")"
);
}
}
assert
(
iequals
(
m
V
alidators
.
back
().
name
(),
dictionary_name
));
assert
(
iequals
(
m
_v
alidators
.
back
().
name
(),
dictionary_name
));
return
m
V
alidators
.
back
();
return
m
_v
alidators
.
back
();
}
}
void
ValidatorF
actory
::
construct_validator
(
std
::
string_view
name
,
std
::
istream
&
is
)
void
validator_f
actory
::
construct_validator
(
std
::
string_view
name
,
std
::
istream
&
is
)
{
{
mValidators
.
emplace_back
(
parse_dictionary
(
name
,
is
)
);
parse_dictionary
(
name
,
is
);
}
}
}
// namespace cif
}
// namespace cif
::v2
test/unit-v2-test.cpp
View file @
04b7828a
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
// #include <cif++/CifParser.hpp>
// #include <cif++/CifParser.hpp>
#include <cif++/v2/parser.hpp>
#include <cif++/v2/parser.hpp>
#include <cif++/v2/dictionary_parser.hpp>
namespace
tt
=
boost
::
test_tools
;
namespace
tt
=
boost
::
test_tools
;
...
@@ -307,7 +308,7 @@ _test.name
...
@@ -307,7 +308,7 @@ _test.name
// test.clear();
// test.clear();
// auto n = test.erase(cif::
K
ey("id") == 1, [](const cif::Row &r)
// auto n = test.erase(cif::
v2::k
ey("id") == 1, [](const cif::Row &r)
// {
// {
// BOOST_CHECK_EQUAL(r["id"].as<int>(), 1);
// BOOST_CHECK_EQUAL(r["id"].as<int>(), 1);
// BOOST_CHECK_EQUAL(r["name"].as<std::string>(), "aap"); });
// BOOST_CHECK_EQUAL(r["name"].as<std::string>(), "aap"); });
...
@@ -385,171 +386,172 @@ _test.value
...
@@ -385,171 +386,172 @@ _test.value
BOOST_CHECK
(
test
.
find
(
"value"
_key
==
cif
::
v2
::
null
).
size
()
==
2
);
BOOST_CHECK
(
test
.
find
(
"value"
_key
==
cif
::
v2
::
null
).
size
()
==
2
);
}
}
// // --------------------------------------------------------------------
// --------------------------------------------------------------------
// BOOST_AUTO_TEST_CASE(d1)
// {
// const char dict[] = R"(
// data_test_dict.dic
// _datablock.id test_dict.dic
// _datablock.description
// ;
// A test dictionary
// ;
// _dictionary.title test_dict.dic
// _dictionary.datablock_id test_dict.dic
// _dictionary.version 1.0
// loop_
// _item_type_list.code
// _item_type_list.primitive_code
// _item_type_list.construct
// _item_type_list.detail
// code char
// '[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
// ; code item types/single words ...
// ;
// text char
// '[][ \n\t()_,.;:"&<>/\{}'`~!@#$%?+=*A-Za-z0-9|^-]*'
// ; text item types / multi-line text ...
// ;
// int numb
// '[+-]?[0-9]+'
// ; int item types are the subset of numbers that are the negative
// or positive integers.
// ;
// save_cat_1
// _category.description 'A simple test category'
// _category.id cat_1
// _category.mandatory_code no
// _category_key.name '_cat_1.id'
// save_
// save__cat_1.id
// _item.name '_cat_1.id'
// _item.category_id cat_1
// _item.mandatory_code yes
// _item_aliases.dictionary cif_core.dic
// _item_aliases.version 2.0.1
// _item_linked.child_name '_cat_2.parent_id'
// _item_linked.parent_name '_cat_1.id'
// _item_type.code code
// save_
// save__cat_1.name
// _item.name '_cat_1.name'
// _item.category_id cat_1
// _item.mandatory_code yes
// _item_aliases.dictionary cif_core.dic
// _item_aliases.version 2.0.1
// _item_type.code text
// save_
// save_cat_2
// _category.description 'A second simple test category'
// _category.id cat_2
// _category.mandatory_code no
// _category_key.name '_cat_2.id'
// save_
// save__cat_2.id
// _item.name '_cat_2.id'
// _item.category_id cat_2
// _item.mandatory_code yes
// _item_aliases.dictionary cif_core.dic
// _item_aliases.version 2.0.1
// _item_type.code int
// save_
// save__cat_2.parent_id
// _item.name '_cat_2.parent_id'
// _item.category_id cat_2
// _item.mandatory_code yes
// _item_aliases.dictionary cif_core.dic
// _item_aliases.version 2.0.1
// _item_type.code code
// save_
// save__cat_2.desc
// _item.name '_cat_2.desc'
// _item.category_id cat_2
// _item.mandatory_code yes
// _item_aliases.dictionary cif_core.dic
// _item_aliases.version 2.0.1
// _item_type.code text
// save_
// )";
// struct membuf : public std::streambuf
BOOST_AUTO_TEST_CASE
(
d1
)
// {
{
// membuf(char *text, size_t length)
const
char
dict
[]
=
R"(
// {
data_test_dict.dic
// this->setg(text, text, text + length);
_datablock.id test_dict.dic
// }
_datablock.description
// } buffer(const_cast<char *>(dict), sizeof(dict) - 1);
;
A test dictionary
;
_dictionary.title test_dict.dic
_dictionary.datablock_id test_dict.dic
_dictionary.version 1.0
loop_
_item_type_list.code
_item_type_list.primitive_code
_item_type_list.construct
_item_type_list.detail
code char
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
; code item types/single words ...
;
text char
'[][ \n\t()_,.;:"&<>/\{}'`~!@#$%?+=*A-Za-z0-9|^-]*'
; text item types / multi-line text ...
;
int numb
'[+-]?[0-9]+'
; int item types are the subset of numbers that are the negative
or positive integers.
;
save_cat_1
_category.description 'A simple test category'
_category.id cat_1
_category.mandatory_code no
_category_key.name '_cat_1.id'
save_
save__cat_1.id
_item.name '_cat_1.id'
_item.category_id cat_1
_item.mandatory_code yes
_item_aliases.dictionary cif_core.dic
_item_aliases.version 2.0.1
_item_linked.child_name '_cat_2.parent_id'
_item_linked.parent_name '_cat_1.id'
_item_type.code code
save_
save__cat_1.name
_item.name '_cat_1.name'
_item.category_id cat_1
_item.mandatory_code yes
_item_aliases.dictionary cif_core.dic
_item_aliases.version 2.0.1
_item_type.code text
save_
save_cat_2
_category.description 'A second simple test category'
_category.id cat_2
_category.mandatory_code no
_category_key.name '_cat_2.id'
save_
save__cat_2.id
_item.name '_cat_2.id'
_item.category_id cat_2
_item.mandatory_code yes
_item_aliases.dictionary cif_core.dic
_item_aliases.version 2.0.1
_item_type.code int
save_
save__cat_2.parent_id
_item.name '_cat_2.parent_id'
_item.category_id cat_2
_item.mandatory_code yes
_item_aliases.dictionary cif_core.dic
_item_aliases.version 2.0.1
_item_type.code code
save_
save__cat_2.desc
_item.name '_cat_2.desc'
_item.category_id cat_2
_item.mandatory_code yes
_item_aliases.dictionary cif_core.dic
_item_aliases.version 2.0.1
_item_type.code text
save_
)"
;
// std::istream is_dict(&buffer);
struct
membuf
:
public
std
::
streambuf
{
membuf
(
char
*
text
,
size_t
length
)
{
this
->
setg
(
text
,
text
,
text
+
length
);
}
}
buffer
(
const_cast
<
char
*>
(
dict
),
sizeof
(
dict
)
-
1
);
// cif::Validator validator("test", is_dict
);
std
::
istream
is_dict
(
&
buffer
);
// cif::File f;
auto
validator
=
cif
::
v2
::
parse_dictionary
(
"test"
,
is_dict
);
// f.setValidator(&validator);
// // --------------------------------------------------------------------
cif
::
v2
::
file
f
;
f
.
set_validator
(
&
validator
);
// const char data[] = R"(
// --------------------------------------------------------------------
// data_test
// loop_
// _cat_1.id
// _cat_1.name
// 1 Aap
// 2 Noot
// 3 Mies
// loop_
const
char
data
[]
=
R"(
// _cat_2.id
data_test
// _cat_2.parent_id
loop_
// _cat_2.desc
_cat_1.id
// 1 1 'Een dier'
_cat_1.name
// 2 1 'Een andere aap'
1 Aap
// 3 2 'walnoot bijvoorbeeld'
2 Noot
// )";
3 Mies
// struct data_membuf : public std::streambuf
loop_
// {
_cat_2.id
// data_membuf(char *text, size_t length)
_cat_2.parent_id
// {
_cat_2.desc
// this->setg(text, text, text + length);
1 1 'Een dier'
// }
2 1 'Een andere aap'
// } data_buffer(const_cast<char *>(data), sizeof(data) - 1);
3 2 'walnoot bijvoorbeeld'
)"
;
struct
data_membuf
:
public
std
::
streambuf
{
data_membuf
(
char
*
text
,
size_t
length
)
{
this
->
setg
(
text
,
text
,
text
+
length
);
}
}
data_buffer
(
const_cast
<
char
*>
(
data
),
sizeof
(
data
)
-
1
);
//
std::istream is_data(&data_buffer);
std
::
istream
is_data
(
&
data_buffer
);
//
f.load(is_data);
f
.
load
(
is_data
);
//
auto &cat1 = f.front()["cat_1"];
auto
&
cat1
=
f
.
front
()[
"cat_1"
];
//
auto &cat2 = f.front()["cat_2"];
auto
&
cat2
=
f
.
front
()[
"cat_2"
];
//
BOOST_CHECK(cat1.size() == 3);
BOOST_CHECK
(
cat1
.
size
()
==
3
);
//
BOOST_CHECK(cat2.size() == 3);
BOOST_CHECK
(
cat2
.
size
()
==
3
);
// cat1.erase(cif::K
ey("id") == 1);
cat1
.
erase
(
cif
::
v2
::
k
ey
(
"id"
)
==
1
);
//
BOOST_CHECK(cat1.size() == 2);
BOOST_CHECK
(
cat1
.
size
()
==
2
);
//
BOOST_CHECK(cat2.size() == 1);
BOOST_CHECK
(
cat2
.
size
()
==
1
);
//
// BOOST_CHECK_THROW(cat2.emplace({
// BOOST_CHECK_THROW(cat2.emplace({
//
// { "id", 4 },
// { "id", 4 },
//
// { "parent_id", 4 },
// { "parent_id", 4 },
//
// { "desc", "moet fout gaan" }
// { "desc", "moet fout gaan" }
//
// }), std::exception);
// }), std::exception);
// BOOST_CHECK_THROW(cat2.emplace({{"id", "vijf"}, // <- invalid value
BOOST_CHECK_THROW
(
cat2
.
emplace
({
// {"parent_id", 2},
{
"id"
,
"vijf"
},
// <- invalid value
// {"desc", "moet fout gaan"}}),
{
"parent_id"
,
2
},
// std::exception);
{
"desc"
,
"moet fout gaan"
}}),
// }
std
::
exception
);
}
// // --------------------------------------------------------------------
// // --------------------------------------------------------------------
...
@@ -621,7 +623,7 @@ _test.value
...
@@ -621,7 +623,7 @@ _test.value
// std::istream is_dict(&buffer);
// std::istream is_dict(&buffer);
// cif::
V
alidator validator("test", is_dict);
// cif::
v2::v
alidator validator("test", is_dict);
// cif::File f;
// cif::File f;
// f.setValidator(&validator);
// f.setValidator(&validator);
...
@@ -653,11 +655,11 @@ _test.value
...
@@ -653,11 +655,11 @@ _test.value
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// cat1.erase(cif::
K
ey("id") == "AAP");
// cat1.erase(cif::
v2::k
ey("id") == "AAP");
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// cat1.erase(cif::
K
ey("id") == "noot");
// cat1.erase(cif::
v2::k
ey("id") == "noot");
// BOOST_CHECK(cat1.size() == 2);
// BOOST_CHECK(cat1.size() == 2);
// }
// }
...
@@ -769,7 +771,7 @@ _test.value
...
@@ -769,7 +771,7 @@ _test.value
// std::istream is_dict(&buffer);
// std::istream is_dict(&buffer);
// cif::
V
alidator validator("test", is_dict);
// cif::
v2::v
alidator validator("test", is_dict);
// cif::File f;
// cif::File f;
// f.setValidator(&validator);
// f.setValidator(&validator);
...
@@ -813,7 +815,7 @@ _test.value
...
@@ -813,7 +815,7 @@ _test.value
// // check a rename in parent and child
// // check a rename in parent and child
// for (auto r : cat1.find(cif::
K
ey("id") == 1))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 1))
// {
// {
// r["id"] = 10;
// r["id"] = 10;
// break;
// break;
...
@@ -822,15 +824,15 @@ _test.value
...
@@ -822,15 +824,15 @@ _test.value
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 10).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 10).size() == 2);
// // check a rename in parent and child, this time only one child should be renamed
// // check a rename in parent and child, this time only one child should be renamed
// for (auto r : cat1.find(cif::
K
ey("id") == 2))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 2))
// {
// {
// r["id"] = 20;
// r["id"] = 20;
// break;
// break;
...
@@ -839,25 +841,25 @@ _test.value
...
@@ -839,25 +841,25 @@ _test.value
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 20).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 2).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 2).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::
Key("parent_id") == 2 and cif::K
ey("name2") == "noot").size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::key("parent_id") == 2 and cif::v2::k
ey("name2") == "noot").size() == 0);
// BOOST_CHECK(cat2.find(cif::
Key("parent_id") == 2 and cif::K
ey("name2") == "n2").size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::key("parent_id") == 2 and cif::v2::k
ey("name2") == "n2").size() == 1);
// BOOST_CHECK(cat2.find(cif::
Key("parent_id") == 20 and cif::K
ey("name2") == "noot").size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::key("parent_id") == 20 and cif::v2::k
ey("name2") == "noot").size() == 1);
// BOOST_CHECK(cat2.find(cif::
Key("parent_id") == 20 and cif::K
ey("name2") == "n2").size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::key("parent_id") == 20 and cif::v2::k
ey("name2") == "n2").size() == 0);
// // // --------------------------------------------------------------------
// // // --------------------------------------------------------------------
// // cat1.erase(cif::
K
ey("id") == 10);
// // cat1.erase(cif::
v2::k
ey("id") == 10);
// // BOOST_CHECK(cat1.size() == 2);
// // BOOST_CHECK(cat1.size() == 2);
// // BOOST_CHECK(cat2.size() == 2);
// // BOOST_CHECK(cat2.size() == 2);
// // cat1.erase(cif::
K
ey("id") == 20);
// // cat1.erase(cif::
v2::k
ey("id") == 20);
// // BOOST_CHECK(cat1.size() == 1);
// // BOOST_CHECK(cat1.size() == 1);
// // BOOST_CHECK(cat2.size() == 1);
// // BOOST_CHECK(cat2.size() == 1);
...
@@ -972,7 +974,7 @@ _test.value
...
@@ -972,7 +974,7 @@ _test.value
// std::istream is_dict(&buffer);
// std::istream is_dict(&buffer);
// cif::
V
alidator validator("test", is_dict);
// cif::
v2::v
alidator validator("test", is_dict);
// cif::File f;
// cif::File f;
// f.setValidator(&validator);
// f.setValidator(&validator);
...
@@ -1026,7 +1028,7 @@ _test.value
...
@@ -1026,7 +1028,7 @@ _test.value
// // check a rename in parent and child
// // check a rename in parent and child
// for (auto r : cat1.find(cif::
K
ey("id") == 1))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 1))
// {
// {
// r["id"] = 10;
// r["id"] = 10;
// break;
// break;
...
@@ -1035,13 +1037,13 @@ _test.value
...
@@ -1035,13 +1037,13 @@ _test.value
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 1).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 1).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 10).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 10).size() == 2);
// for (auto r : cat1.find(cif::
K
ey("id") == 2))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 2))
// {
// {
// r["id"] = 20;
// r["id"] = 20;
// break;
// break;
...
@@ -1050,13 +1052,13 @@ _test.value
...
@@ -1050,13 +1052,13 @@ _test.value
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 20).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 2).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 2).size() == 2);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 20).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 20).size() == 2);
// for (auto r : cat1.find(cif::
K
ey("id") == 3))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 3))
// {
// {
// r["id"] = 30;
// r["id"] = 30;
// break;
// break;
...
@@ -1065,13 +1067,13 @@ _test.value
...
@@ -1065,13 +1067,13 @@ _test.value
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 3).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 3).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 30).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 3).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 3).size() == 2);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 30).size() == 1);
// for (auto r : cat1.find(cif::
K
ey("id") == 4))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 4))
// {
// {
// r["id"] = 40;
// r["id"] = 40;
// break;
// break;
...
@@ -1080,11 +1082,11 @@ _test.value
...
@@ -1080,11 +1082,11 @@ _test.value
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat1.size() == 4);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat2.size() == 13);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 4).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 4).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 4).size() == 3);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 4).size() == 3);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 40).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 40).size() == 0);
// }
// }
// // --------------------------------------------------------------------
// // --------------------------------------------------------------------
...
@@ -1193,7 +1195,7 @@ _test.value
...
@@ -1193,7 +1195,7 @@ _test.value
// std::istream is_dict(&buffer);
// std::istream is_dict(&buffer);
// cif::
V
alidator validator("test", is_dict);
// cif::
v2::v
alidator validator("test", is_dict);
// cif::File f;
// cif::File f;
// f.setValidator(&validator);
// f.setValidator(&validator);
...
@@ -1241,7 +1243,7 @@ _test.value
...
@@ -1241,7 +1243,7 @@ _test.value
// // --------------------------------------------------------------------
// // --------------------------------------------------------------------
// // check iterate children
// // check iterate children
// auto PR2set = cat1.find(cif::
K
ey("id") == 2);
// auto PR2set = cat1.find(cif::
v2::k
ey("id") == 2);
// BOOST_ASSERT(PR2set.size() == 1);
// BOOST_ASSERT(PR2set.size() == 1);
// auto PR2 = PR2set.front();
// auto PR2 = PR2set.front();
// BOOST_CHECK(PR2["id"].as<int>() == 2);
// BOOST_CHECK(PR2["id"].as<int>() == 2);
...
@@ -1257,7 +1259,7 @@ _test.value
...
@@ -1257,7 +1259,7 @@ _test.value
// // check a rename in parent and child
// // check a rename in parent and child
// for (auto r : cat1.find(cif::
K
ey("id") == 1))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 1))
// {
// {
// r["id"] = 10;
// r["id"] = 10;
// break;
// break;
...
@@ -1266,17 +1268,17 @@ _test.value
...
@@ -1266,17 +1268,17 @@ _test.value
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 7);
// BOOST_CHECK(cat2.size() == 7);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 1).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id2") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id2") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id3") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id3") == 1).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id2") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id2") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id3") == 10).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id3") == 10).size() == 1);
// for (auto r : cat1.find(cif::
K
ey("id") == 2))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 2))
// {
// {
// r["id"] = 20;
// r["id"] = 20;
// break;
// break;
...
@@ -1285,17 +1287,17 @@ _test.value
...
@@ -1285,17 +1287,17 @@ _test.value
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 7);
// BOOST_CHECK(cat2.size() == 7);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 2).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 20).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 20).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 2).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 2).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id2") == 2).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id2") == 2).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id3") == 2).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id3") == 2).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 20).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 20).size() == 2);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id2") == 20).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id2") == 20).size() == 2);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id3") == 20).size() == 2);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id3") == 20).size() == 2);
// for (auto r : cat1.find(cif::
K
ey("id") == 3))
// for (auto r : cat1.find(cif::
v2::k
ey("id") == 3))
// {
// {
// r["id"] = 30;
// r["id"] = 30;
// break;
// break;
...
@@ -1304,27 +1306,27 @@ _test.value
...
@@ -1304,27 +1306,27 @@ _test.value
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat1.size() == 3);
// BOOST_CHECK(cat2.size() == 7);
// BOOST_CHECK(cat2.size() == 7);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 3).size() == 0);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 3).size() == 0);
// BOOST_CHECK(cat1.find(cif::
K
ey("id") == 30).size() == 1);
// BOOST_CHECK(cat1.find(cif::
v2::k
ey("id") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 3).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 3).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id2") == 3).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id2") == 3).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id3") == 3).size() == 0);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id3") == 3).size() == 0);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id2") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id2") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
K
ey("parent_id3") == 30).size() == 1);
// BOOST_CHECK(cat2.find(cif::
v2::k
ey("parent_id3") == 30).size() == 1);
// // test delete
// // test delete
// cat1.erase(cif::
K
ey("id") == 10);
// cat1.erase(cif::
v2::k
ey("id") == 10);
// BOOST_CHECK(cat1.size() == 2);
// BOOST_CHECK(cat1.size() == 2);
// BOOST_CHECK(cat2.size() == 4);
// BOOST_CHECK(cat2.size() == 4);
// cat1.erase(cif::
K
ey("id") == 20);
// cat1.erase(cif::
v2::k
ey("id") == 20);
// BOOST_CHECK(cat1.size() == 1);
// BOOST_CHECK(cat1.size() == 1);
// BOOST_CHECK(cat2.size() == 1);
// BOOST_CHECK(cat2.size() == 1);
// cat1.erase(cif::
K
ey("id") == 30);
// cat1.erase(cif::
v2::k
ey("id") == 30);
// BOOST_CHECK(cat1.size() == 0);
// BOOST_CHECK(cat1.size() == 0);
// BOOST_CHECK(cat2.size() == 0);
// BOOST_CHECK(cat2.size() == 0);
// }
// }
...
@@ -1349,21 +1351,21 @@ _test.value
...
@@ -1349,21 +1351,21 @@ _test.value
// auto &db = f.front();
// auto &db = f.front();
// for (auto r : db["test"].find(cif::
K
ey("id") == 1))
// for (auto r : db["test"].find(cif::
v2::k
ey("id") == 1))
// {
// {
// const auto &[id, name] = r.get<int, std::string>({"id", "name"});
// const auto &[id, name] = r.get<int, std::string>({"id", "name"});
// BOOST_CHECK(id == 1);
// BOOST_CHECK(id == 1);
// BOOST_CHECK(name == "aap");
// BOOST_CHECK(name == "aap");
// }
// }
// for (auto r : db["test"].find(cif::
K
ey("id") == 4))
// for (auto r : db["test"].find(cif::
v2::k
ey("id") == 4))
// {
// {
// const auto &[id, name] = r.get<int, std::string>({"id", "name"});
// const auto &[id, name] = r.get<int, std::string>({"id", "name"});
// BOOST_CHECK(id == 4);
// BOOST_CHECK(id == 4);
// BOOST_CHECK(name.empty());
// BOOST_CHECK(name.empty());
// }
// }
// for (auto r : db["test"].find(cif::
K
ey("id") == 5))
// for (auto r : db["test"].find(cif::
v2::k
ey("id") == 5))
// {
// {
// const auto &[id, name] = r.get<int, std::string>({"id", "name"});
// const auto &[id, name] = r.get<int, std::string>({"id", "name"});
// BOOST_CHECK(id == 5);
// BOOST_CHECK(id == 5);
...
@@ -1456,7 +1458,7 @@ _test.value
...
@@ -1456,7 +1458,7 @@ _test.value
// }
// }
// }
// }
// const auto &[id, name] = db["test"].find1<int, std::string>(cif::
K
ey("id") == 1, "id", "name");
// const auto &[id, name] = db["test"].find1<int, std::string>(cif::
v2::k
ey("id") == 1, "id", "name");
// BOOST_CHECK(id == 1);
// BOOST_CHECK(id == 1);
// BOOST_CHECK(name == "aap");
// BOOST_CHECK(name == "aap");
...
@@ -1621,7 +1623,7 @@ _test.value
...
@@ -1621,7 +1623,7 @@ _test.value
// } buffer(const_cast<char *>(dict), sizeof(dict) - 1);
// } buffer(const_cast<char *>(dict), sizeof(dict) - 1);
// std::istream is_dict(&buffer);
// std::istream is_dict(&buffer);
// cif::
V
alidator validator("test", is_dict);
// cif::
v2::v
alidator validator("test", is_dict);
// cif::File f;
// cif::File f;
// f.setValidator(&validator);
// f.setValidator(&validator);
...
...
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