3 #include <boost/filesystem.hpp>
4 #include <boost/range/iterator_range.hpp>
30 InsertImpl(DatabaseHandler &_db_handler) :
db_handler(_db_handler) {}
37 notstd::make_unique<jsonDatabase<T> >(
db_handler.primclex()));
44 struct InsertPropsImpl {
45 InsertPropsImpl(DatabaseHandler &_db_handler)
53 const DirectoryStructure &
dir;
58 for (
auto calc_type :
dir.all_calctype()) {
59 fs::path location =
json_dir.props_list<T>(calc_type);
61 notstd::make_unique<jsonPropertiesDatabase>(
78 template <
typename DataObject>
84 template <
typename DataObject>
91 return std::string(
"calctype.") +
calctype;
111 this->read_aliases();
119 throw std::runtime_error(
120 "Error in jsonDatabase<Supercell>::commit(): CASM project has no root "
127 for (
const auto &scel : *
this) {
128 json[
"supercells"][scel.name()] = scel.transf_mat();
134 fs::create_directories(
dir.obj_list<
Supercell>().parent_path());
139 this->write_aliases();
141 handler.set_selected(master_selection());
142 master_selection().write(
143 handler.dict(),
primclex().
dir().
template master_selection<Supercell>(),
155 throw std::runtime_error(
156 "Error in jsonDatabase<Supercell>::_read_scel_list(): CASM project has "
157 "no root directory.");
165 throw std::runtime_error(
166 std::string(
"Error jsonDB version mismatch: found: ") +
167 json[
"version"].get<std::string>() +
172 throw std::runtime_error(std::string(
"Error invalid format: ") +
176 auto it = json[
"supercells"].
begin();
177 auto end = json[
"supercells"].
end();
178 for (; it != end; ++it) {
187 throw std::runtime_error(
188 "Error in jsonDatabase<Supercell>::_read_SCEL(): CASM project has no "
209 while (!stream.eof()) {
210 std::getline(stream,
s);
212 std::getline(stream,
s);
237 if (!fs::exists(config_list_path)) {
246 throw std::runtime_error(std::string(
"Error invalid format: ") +
247 config_list_path.string());
253 throw std::runtime_error(
254 std::string(
"Error jsonDB version mismatch: found: ") +
255 json[
"version"].get<std::string>() +
260 auto scel_it = json[
"supercells"].
begin();
261 auto scel_end = json[
"supercells"].
end();
264 for (; scel_it != scel_end; ++scel_it) {
265 auto config_it = scel_it->begin();
266 auto config_end = scel_it->end();
271 .
find(scel_it.name());
273 for (; config_it != config_end; ++config_it) {
275 from_json(configuration.configdof(), (*config_it)[
"dof"]);
277 auto source_it = config_it->find(
"source");
278 if (source_it != config_it->end()) {
279 configuration.set_source(*source_it);
281 auto cache_it = config_it->find(
"cache");
282 if (cache_it != config_it->end()) {
283 configuration.set_initial_cache(*cache_it);
286 this->clear_name(configuration);
288 this->set_id(configuration, config_it.name());
290 auto result = m_config_list.emplace(configuration);
291 _on_insert_or_emplace(result,
is_new);
296 from_json(m_config_id, json[
"config_id"]);
298 this->read_aliases();
306 throw std::runtime_error(
307 "Error in jsonDatabase<Configuration>::commit(): Database not open");
310 throw std::runtime_error(
311 "Error in jsonDatabase<Configuration>::commit(): CASM project has no "
318 fs::remove(config_list_path);
323 if (fs::exists(config_list_path)) {
324 json.
read(config_list_path);
331 for (
const auto &
config : m_config_list) {
333 json[
"supercells"][
config.supercell().name()][
config.id()];
337 if (
config.cache_updated()) {
342 json[
"config_id"] = m_config_id;
345 fs::create_directories(config_list_path.parent_path());
346 file.
open(config_list_path);
349 json_spirit::write_stream((json_spirit::mValue &)json, file.
ofstream(),
353 this->write_aliases();
355 handler.set_selected(master_selection());
357 bool write_json =
false;
358 bool only_selected =
false;
359 master_selection().write(
361 primclex().
dir().
template master_selection<Configuration>(), write_json,
366 m_name_to_config.clear();
367 m_config_list.clear();
368 m_scel_range.clear();
375 return _iterator(m_config_list.begin());
379 return _iterator(m_config_list.end());
384 return m_config_list.size();
387 std::pair<jsonDatabase<Configuration>::iterator,
bool>
389 auto result = m_config_list.insert(
config);
391 return _on_insert_or_emplace(result,
true);
394 std::pair<jsonDatabase<Configuration>::iterator,
bool>
396 auto result = m_config_list.insert(std::move(
config));
398 return _on_insert_or_emplace(result,
true);
404 return insert(
config).first;
413 m_name_to_config.erase(base_it->name());
414 master_selection().data().erase(base_it->name());
416 auto _scel_range_it = m_scel_range.find(base_it->supercell().name());
417 if (_scel_range_it->second.first == _scel_range_it->second.second) {
418 m_scel_range.erase(_scel_range_it);
419 }
else if (_scel_range_it->second.first == base_it) {
420 ++(_scel_range_it->second.first);
421 }
else if (_scel_range_it->second.second == base_it) {
422 --(_scel_range_it->second.second);
426 return _iterator(m_config_list.erase(base_it));
430 const std::string &name_or_alias)
const {
431 auto it = m_name_to_config.find(this->
name(name_or_alias));
432 if (it == m_name_to_config.end()) {
433 return _iterator(m_config_list.end());
435 return _iterator(it->second);
441 auto it = m_scel_range.find(
scelname);
442 if (it == m_scel_range.end()) {
443 return boost::make_iterator_range(end(), end());
445 auto &res = it->second;
446 return boost::make_iterator_range(_iterator(res.first),
447 _iterator(std::next(res.second)));
459 auto res = m_config_list.find(
config);
460 if (res == m_config_list.end()) {
463 return _iterator(res);
468 std::pair<jsonDatabase<Configuration>::iterator,
bool>
470 std::pair<base_iterator, bool> &result,
bool is_new) {
474 "jsonDatabase<Configuration>::_on_insert_or_emplace primclex does "
479 auto _config_id_it = m_config_id.find(
config.supercell().name());
480 if (_config_id_it == m_config_id.end()) {
482 m_config_id.insert(std::make_pair(
config.supercell().name(), 0))
485 this->set_id(
config, _config_id_it->second++);
489 m_name_to_config.insert(std::make_pair(
config.name(), result.first));
492 auto _scel_range_it = m_scel_range.find(
config.supercell().name());
495 if (_scel_range_it == m_scel_range.end()) {
496 m_scel_range.emplace(
config.supercell().name(),
497 std::make_pair(result.first, result.first));
500 else if (_scel_range_it->second.first == std::next(result.first)) {
501 _scel_range_it->second.first = result.first;
504 else if (_scel_range_it->second.second == std::prev(result.first)) {
505 _scel_range_it->second.second = result.first;
508 master_selection().data().emplace(
config.name(), 0);
511 return std::make_pair(_iterator(result.first), result.second);
517 #define INST_jsonDB(r, data, type) \
518 template fs::path jsonDB::DirectoryStructure::obj_list<type>() const;
520 #define INST_jsonDB_config(r, data, type) \
521 template fs::path jsonDB::DirectoryStructure::props_list<type>( \
522 std::string calctype) const;
std::set< std::string > & s
#define CASM_DB_CONFIG_TYPES
Provides access to all databases.
DatabaseIterator for implementations using std::set<ValueType>
virtual iterator erase(iterator pos)=0
fs::path obj_list() const
std::string _calctype(std::string calctype) const
fs::path props_list(std::string calctype) const
DirectoryStructure(const fs::path _root)
PrimClex is the top-level data structure for a CASM project.
Write to a temporary file to ensure a good write, then rename.
void close()
Closes stream, and if not a failed write, removes "file" and renames "file.tmp" to "file".
void open(fs::path name, std::string tmp_ext="tmp")
Opens "file.tmp" for writing, with intended final target "file".
fs::ofstream & ofstream()
Access underlying stream.
Represents a supercell of the primitive parent crystal structure.
static jsonParser object()
Returns an empty json object.
iterator begin()
Returns const_iterator to beginning of JSON object or JSON array.
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
iterator end()
Returns iterator to end of JSON object or JSON array.
bool read(std::istream &stream)
Reads json from the stream.
jsonParser & put_obj()
Puts new empty JSON object.
bool is_obj() const
Check if object type.
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
void commit(ProjectSettings const &set)
std::string scelname(const Structure &prim, const Lattice &superlat)
Make supercell name name [deprecated].
T get(Args &&... args) const
Get data from json, using one of several alternatives.
const PrimClex & primclex
const DirectoryStructure & dir
#define INST_jsonDB_config(r, data, type)
#define INST_jsonDB(r, data, type)
jsonDB::DirectoryStructure json_dir
DatabaseHandler & db_handler
GenericDatumFormatter< std::string, ConfigEnumDataType > name()
GenericDatumFormatter< bool, ConfigEnumDataType > is_new()
ConfigIO::GenericConfigFormatter< jsonParser > config()
jsonParser & to_json(ImportSettings const &_set, jsonParser &_json)
jsonParser const & from_json(ImportSettings &_set, jsonParser const &_json)
void for_each_config_type(F f)
GenericDatumFormatter< std::string, DataObject > name()
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
Matrix< long int, 3, 3 > Matrix3l
static void insert(DatabaseHandler &)
static const std::string version
Database format version, incremented separately from casm –version.
static const std::string name