mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-05 06:25:52 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06f1a308c3 | ||
|
|
1aed6a593c | ||
|
|
b969df1194 | ||
|
|
8f5b9eb631 | ||
|
|
73f18a4da2 | ||
|
|
7a9d94bc57 | ||
|
|
a3ba760ab5 | ||
|
|
510e336306 | ||
|
|
ffff2479d2 |
@@ -32,7 +32,7 @@ endif()
|
||||
# set the project name
|
||||
project(
|
||||
libcifpp
|
||||
VERSION 9.0.5
|
||||
VERSION 9.0.6
|
||||
LANGUAGES CXX C)
|
||||
|
||||
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
@@ -130,13 +130,6 @@ if(MSVC)
|
||||
# make msvc standards compliant...
|
||||
add_compile_options(/permissive- /bigobj)
|
||||
add_link_options(/NODEFAULTLIB:library)
|
||||
|
||||
# This is dubious...
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
else()
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Libraries
|
||||
@@ -171,15 +164,21 @@ endif()
|
||||
|
||||
# Using fast_float for float parsing, but only if needed
|
||||
try_compile(STD_CHARCONV_COMPILING
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-charconv.cpp)
|
||||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-charconv.cpp
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(NOT STD_CHARCONV_COMPILING)
|
||||
message(NOTICE "libcifpp: Using fast_float for std::from_chars")
|
||||
FetchContent_Declare(fastfloat
|
||||
GIT_REPOSITORY "https://github.com/fastfloat/fast_float"
|
||||
GIT_TAG v8.0.2
|
||||
EXCLUDE_FROM_ALL)
|
||||
FetchContent_MakeAvailable(fastfloat)
|
||||
find_package(FastFloat 8.0 QUIET CONFIG)
|
||||
if(NOT FastFloat_FOUND)
|
||||
message(STATUS "FastFloat not found in system, fetching from GitHub")
|
||||
FetchContent_Declare(fastfloat
|
||||
GIT_REPOSITORY "https://github.com/fastfloat/fast_float"
|
||||
GIT_TAG v8.0.2
|
||||
EXCLUDE_FROM_ALL)
|
||||
FetchContent_MakeAvailable(fastfloat)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(Threads)
|
||||
@@ -262,7 +261,6 @@ set(project_sources
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/point.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/symmetry.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/model.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/cql/transaction.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/cif2pdb.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb2cif.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/pdb/pdb_record.hpp
|
||||
@@ -299,7 +297,6 @@ set(project_headers
|
||||
include/cif++/row.hpp
|
||||
include/cif++/symmetry.hpp
|
||||
include/cif++/text.hpp
|
||||
include/cif++/cql/transaction.hpp
|
||||
include/cif++/utilities.hpp
|
||||
include/cif++/validate.hpp
|
||||
)
|
||||
@@ -349,7 +346,7 @@ else()
|
||||
endif()
|
||||
|
||||
if(NOT STD_CHARCONV_COMPILING)
|
||||
target_link_libraries(cifpp PUBLIC FastFloat::fast_float)
|
||||
target_link_libraries(cifpp PRIVATE FastFloat::fast_float)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
Version 9.0.6
|
||||
- Various small fixes
|
||||
|
||||
Version 9.0.5
|
||||
- Added exists to compound_factory
|
||||
- Added sub_matrix, fix and extend determinant calculation
|
||||
|
||||
@@ -1,451 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cif++/category.hpp"
|
||||
#include "cif++/condition.hpp"
|
||||
#include "cif++/datablock.hpp"
|
||||
#include "cif++/item.hpp"
|
||||
#include "cif++/row.hpp"
|
||||
#include "cif++/validate.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
namespace cif::cql
|
||||
{
|
||||
|
||||
class result;
|
||||
class row;
|
||||
class transaction;
|
||||
class view;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
struct column
|
||||
{
|
||||
std::string name;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
using column_list = std::vector<column>;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class field_ref
|
||||
{
|
||||
public:
|
||||
std::string_view name() const &
|
||||
{
|
||||
return m_col->name;
|
||||
}
|
||||
|
||||
constexpr size_t num() const noexcept
|
||||
{
|
||||
return m_col->index;
|
||||
}
|
||||
|
||||
std::string_view text() const &
|
||||
{
|
||||
return m_row[m_col->index].text();
|
||||
}
|
||||
|
||||
/** Return the contents of this item as type @tparam T */
|
||||
template <typename T = std::string>
|
||||
auto as() const -> T
|
||||
{
|
||||
return m_row[m_col->index].as<T>();
|
||||
}
|
||||
|
||||
/** Return the contents of this item as type @tparam T or, if not
|
||||
* set, use @a dv as the default value.
|
||||
*/
|
||||
template <typename T>
|
||||
auto value_or(const T &dv) const
|
||||
{
|
||||
return m_row[m_col->index].value_or(dv);
|
||||
}
|
||||
|
||||
field_ref(row_handle rh, column_list::const_iterator col)
|
||||
: m_row(rh)
|
||||
, m_col(col)
|
||||
{
|
||||
}
|
||||
|
||||
field_ref(const field_ref &) = default;
|
||||
field_ref(field_ref &&) = default;
|
||||
|
||||
field_ref &operator=(const field_ref &) = default;
|
||||
field_ref &operator=(field_ref &&) = default;
|
||||
|
||||
private:
|
||||
row_handle m_row;
|
||||
column_list::const_iterator m_col;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class row_ref final
|
||||
{
|
||||
public:
|
||||
class const_field_iterator
|
||||
{
|
||||
public:
|
||||
friend class result;
|
||||
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = const field_ref;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
|
||||
const_field_iterator(const const_field_iterator &) = default;
|
||||
const_field_iterator(const_field_iterator &&) = default;
|
||||
|
||||
const_field_iterator &operator=(const const_field_iterator &) = default;
|
||||
const_field_iterator &operator=(const_field_iterator &&) = default;
|
||||
|
||||
reference operator*()
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
pointer operator->()
|
||||
{
|
||||
return &m_current;
|
||||
}
|
||||
|
||||
const_field_iterator &operator++()
|
||||
{
|
||||
if (m_row)
|
||||
{
|
||||
++m_col;
|
||||
m_current = field_ref(m_row, m_col);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_field_iterator operator++(int)
|
||||
{
|
||||
const_field_iterator result(*this);
|
||||
this->operator++();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const const_field_iterator &rhs) const
|
||||
{
|
||||
return m_row == rhs.m_row and m_col == rhs.m_col;
|
||||
}
|
||||
|
||||
bool operator!=(const const_field_iterator &rhs) const
|
||||
{
|
||||
return m_row != rhs.m_row or m_col != rhs.m_col;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class row_ref;
|
||||
|
||||
const_field_iterator(const row_handle &row, column_list::const_iterator col)
|
||||
: m_row(row)
|
||||
, m_col(col)
|
||||
, m_current(m_row, m_col)
|
||||
{
|
||||
}
|
||||
|
||||
row_handle m_row;
|
||||
column_list::const_iterator m_col;
|
||||
field_ref m_current;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
row_ref() = default;
|
||||
|
||||
row_ref(row_handle rh, const column_list &cols)
|
||||
: m_row(rh)
|
||||
, m_cols(&cols)
|
||||
{
|
||||
}
|
||||
|
||||
row_ref(row_ref r, const column_list &cols)
|
||||
: m_row(r.m_row)
|
||||
, m_cols(&cols)
|
||||
{
|
||||
}
|
||||
|
||||
row_ref(const row_ref &) = default;
|
||||
row_ref &operator=(const row_ref &) = default;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const_field_iterator cbegin() const noexcept { return const_field_iterator(m_row, m_cols->cbegin()); }
|
||||
const_field_iterator begin() const noexcept { return const_field_iterator(m_row, m_cols->cbegin()); }
|
||||
const_field_iterator cend() const noexcept { return const_field_iterator(m_row, m_cols->cend()); }
|
||||
const_field_iterator end() const noexcept { return const_field_iterator(m_row, m_cols->cend()); }
|
||||
|
||||
field_ref front() const noexcept { return field_ref(m_row, m_cols->cbegin()); }
|
||||
field_ref back() const noexcept { return field_ref(m_row, m_cols->cend()); }
|
||||
|
||||
size_t size() const noexcept { return m_cols->size(); }
|
||||
bool empty() const noexcept { return m_cols->empty(); }
|
||||
|
||||
field_ref operator[](size_t index) const noexcept;
|
||||
field_ref operator[](std::string_view name) const noexcept;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
bool operator==(const row_ref &rhs) const { return m_row == rhs.m_row and m_cols == rhs.m_cols; }
|
||||
bool operator!=(const row_ref &rhs) const { return m_row != rhs.m_row or m_cols != rhs.m_cols; }
|
||||
|
||||
private:
|
||||
row_handle m_row;
|
||||
const column_list *m_cols = nullptr;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class view : public std::enable_shared_from_this<view>
|
||||
{
|
||||
public:
|
||||
virtual ~view() = default;
|
||||
|
||||
class const_row_iterator
|
||||
{
|
||||
public:
|
||||
friend class view;
|
||||
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using value_type = const row_ref;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type *;
|
||||
using reference = value_type &;
|
||||
|
||||
// const_row_iterator() = default;
|
||||
|
||||
const_row_iterator(const const_row_iterator &) = default;
|
||||
const_row_iterator(const_row_iterator &&) = default;
|
||||
|
||||
// const_row_iterator &operator=(const const_row_iterator &) = default;
|
||||
// const_row_iterator &operator=(const_row_iterator &&) = default;
|
||||
|
||||
reference operator*()
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
pointer operator->()
|
||||
{
|
||||
return &m_current;
|
||||
}
|
||||
|
||||
const_row_iterator &operator++()
|
||||
{
|
||||
++m_index;
|
||||
if (m_index < m_data.size())
|
||||
m_current = m_data.at(m_index);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_row_iterator operator++(int)
|
||||
{
|
||||
const_row_iterator result(*this);
|
||||
this->operator++();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const const_row_iterator &rhs) const
|
||||
{
|
||||
return &m_data == &rhs.m_data and m_index == rhs.m_index;
|
||||
}
|
||||
|
||||
bool operator!=(const const_row_iterator &rhs) const
|
||||
{
|
||||
return &m_data != &rhs.m_data or m_index != rhs.m_index;
|
||||
}
|
||||
|
||||
private:
|
||||
const_row_iterator(const view &result, size_t index, row_ref current)
|
||||
: m_data(result)
|
||||
, m_index(index)
|
||||
, m_current(current)
|
||||
{
|
||||
}
|
||||
|
||||
const view &m_data;
|
||||
size_t m_index = 0;
|
||||
row_ref m_current;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const_row_iterator begin() const noexcept { return const_row_iterator(*this, 0, at(0)); }
|
||||
const_row_iterator cbegin() const noexcept { return const_row_iterator(*this, 0, at(0)); }
|
||||
|
||||
const_row_iterator end() const noexcept { return const_row_iterator(*this, size(), row_ref{}); }
|
||||
const_row_iterator cend() const noexcept { return const_row_iterator(*this, size(), row_ref{}); }
|
||||
|
||||
virtual row_ref front() const noexcept = 0;
|
||||
virtual row_ref back() const noexcept = 0;
|
||||
|
||||
virtual size_t size() const noexcept = 0;
|
||||
bool empty() const noexcept { return size() == 0; }
|
||||
|
||||
virtual row_ref at(size_t index) const = 0;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::vector<std::string> columns() const
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
for (const auto &[name, ignore] : m_columns)
|
||||
result.emplace_back(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class const_row_iterator;
|
||||
|
||||
view(const column_list &cols)
|
||||
: m_columns(cols)
|
||||
{
|
||||
}
|
||||
|
||||
view(column_list &&cols)
|
||||
: m_columns(std::forward<column_list>(cols))
|
||||
{
|
||||
}
|
||||
|
||||
column_list m_columns;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class simple_view : public view
|
||||
{
|
||||
public:
|
||||
simple_view(const category &cat)
|
||||
: view(get_column_list_for_category(cat))
|
||||
, m_cat(cat)
|
||||
{
|
||||
}
|
||||
|
||||
simple_view(const simple_view &) = default;
|
||||
simple_view(simple_view &&) = default;
|
||||
|
||||
virtual size_t size() const noexcept override { return m_cat.size(); }
|
||||
|
||||
virtual row_ref front() const noexcept override;
|
||||
virtual row_ref back() const noexcept override;
|
||||
|
||||
virtual row_ref at(size_t index) const override;
|
||||
|
||||
protected:
|
||||
|
||||
static column_list get_column_list_for_category(const category &cat);
|
||||
|
||||
const category &m_cat;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class result
|
||||
{
|
||||
public:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
using const_row_iterator = view::const_row_iterator;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
result();
|
||||
result(result const &rhs) noexcept = default;
|
||||
result(result &&rhs) noexcept = default;
|
||||
result &operator=(result const &rhs) noexcept = default;
|
||||
result &operator=(result &&rhs) noexcept = default;
|
||||
|
||||
result(view &vw, const std::string &query = "");
|
||||
|
||||
row_ref one_row() const;
|
||||
field_ref one_field() const;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
const_row_iterator begin() const noexcept;
|
||||
const_row_iterator cbegin() const noexcept;
|
||||
|
||||
const_row_iterator end() const noexcept;
|
||||
const_row_iterator cend() const noexcept;
|
||||
|
||||
row_ref front() const noexcept;
|
||||
row_ref back() const noexcept;
|
||||
|
||||
size_t size() const noexcept;
|
||||
bool empty() const noexcept;
|
||||
|
||||
size_t column_count() const;
|
||||
|
||||
private:
|
||||
friend class transaction;
|
||||
friend class SelectStatement;
|
||||
|
||||
result expect_columns(size_t cols) const
|
||||
{
|
||||
if (auto actual = column_count(); cols != actual)
|
||||
throw std::runtime_error("Unexpected number of columns");
|
||||
return *this;
|
||||
}
|
||||
|
||||
row_ref at(size_t index) const;
|
||||
|
||||
std::string m_query;
|
||||
std::shared_ptr<view> m_view;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
class transaction
|
||||
{
|
||||
public:
|
||||
transaction(const datablock &db)
|
||||
: m_db(const_cast<datablock &>(db))
|
||||
{
|
||||
}
|
||||
|
||||
result exec(std::string_view query);
|
||||
|
||||
private:
|
||||
datablock &m_db;
|
||||
};
|
||||
|
||||
} // namespace cif::cql
|
||||
@@ -64,7 +64,7 @@ file read(std::istream &is);
|
||||
* @brief Read a file in legacy PDB format from std::istream @a is and
|
||||
* put the data into @a cifFile
|
||||
*/
|
||||
file read_pdb_file(std::istream &pdbFile);
|
||||
void read_pdb_file(std::istream &pdbFile, cif::file &cifFile);
|
||||
|
||||
// mmCIF to PDB
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,12 +27,11 @@
|
||||
#include "cif++/validate.hpp"
|
||||
#include "cif++/category.hpp"
|
||||
#include "cif++/dictionary_parser.hpp"
|
||||
#include "cif++/gzio.hpp"
|
||||
#include "cif++/utilities.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
// The validator depends on regular expressions. Unfortunately,
|
||||
// the implementation of std::regex in g++ is buggy and crashes
|
||||
@@ -75,6 +74,7 @@ struct regex_impl
|
||||
private:
|
||||
pcre2_code *m_rx = nullptr;
|
||||
pcre2_match_data *m_data = nullptr;
|
||||
mutable std::mutex m_mutex;
|
||||
};
|
||||
|
||||
regex_impl::regex_impl(std::string_view rx)
|
||||
@@ -95,6 +95,8 @@ regex_impl::regex_impl(std::string_view rx)
|
||||
|
||||
regex_impl::~regex_impl()
|
||||
{
|
||||
std::unique_lock lock(m_mutex);
|
||||
|
||||
if (m_data)
|
||||
pcre2_match_data_free(m_data);
|
||||
|
||||
@@ -104,6 +106,8 @@ regex_impl::~regex_impl()
|
||||
|
||||
bool regex_impl::match(std::string_view v) const
|
||||
{
|
||||
std::unique_lock lock(m_mutex);
|
||||
|
||||
bool result = false;
|
||||
|
||||
if (int rc = pcre2_match(m_rx, (PCRE2_SPTR)v.data(), v.length(), 0, 0, m_data, nullptr); rc >= 0)
|
||||
|
||||
@@ -49,7 +49,6 @@ list(
|
||||
spinner
|
||||
reconstruction
|
||||
validate-pdbx
|
||||
cql
|
||||
matrix
|
||||
)
|
||||
|
||||
|
||||
@@ -1,157 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2025 NKI/AVL, Netherlands Cancer Institute
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "test-main.hpp"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <cif++.hpp>
|
||||
#include <cif++/cql/transaction.hpp>
|
||||
#include <stdexcept>
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
cif::file operator""_cf(const char *text, std::size_t length)
|
||||
{
|
||||
struct membuf : public std::streambuf
|
||||
{
|
||||
membuf(char *text, std::size_t length)
|
||||
{
|
||||
this->setg(text, text, text + length);
|
||||
}
|
||||
} buffer(const_cast<char *>(text), length);
|
||||
|
||||
std::istream is(&buffer);
|
||||
return cif::file(is);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("cql-1")
|
||||
{
|
||||
cif::file f(gTestDir / ".." / "examples" / "1cbs.cif.gz");
|
||||
auto &db = f.front();
|
||||
|
||||
cif::cql::transaction tx(db);
|
||||
|
||||
// CHECK(tx.exec("SELECT COUNT(*) FROM entry").one_field().as<int>() == 1);
|
||||
// CHECK(tx.exec("SELECT COUNT(*) FROM entry WHERE id = '1CBS'").one_field().as<int>() == 1);
|
||||
// CHECK(tx.exec("SELECT COUNT(*) FROM entry WHERE id = 'XXXX'").one_field().as<int>() == 0);
|
||||
|
||||
// CHECK(tx.exec("SELECT COUNT(*) FROM citation").one_field().as<int>() == 4);
|
||||
// CHECK(tx.exec("SELECT COUNT(page_last) FROM citation").one_field().as<int>() == 1);
|
||||
|
||||
const char *kPrimaryAuthors[] = {
|
||||
"Kleywegt, G.J.",
|
||||
"Bergfors, T.",
|
||||
"Senn, H.",
|
||||
"Le Motte, P.",
|
||||
"Gsell, B.",
|
||||
"Shudo, K.",
|
||||
"Jones, T.A."
|
||||
};
|
||||
|
||||
auto r = tx.exec("SELECT name, ordinal FROM citation_author WHERE citation_id = 'primary';");
|
||||
CHECK(r.size() == 7);
|
||||
|
||||
for (size_t ix = 0; auto row : r)
|
||||
{
|
||||
REQUIRE(ix < (sizeof(kPrimaryAuthors) / sizeof(char *)));
|
||||
|
||||
CHECK(row[0].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
CHECK(row[1].as<size_t>() == ix);
|
||||
|
||||
// CHECK(row["name"].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
// CHECK(row["ordinal"].as<int>() == ix);
|
||||
}
|
||||
|
||||
r = tx.exec("SELECT ordinal, name FROM citation_author WHERE citation_id = 'primary';");
|
||||
CHECK(r.size() == 7);
|
||||
|
||||
for (size_t ix = 0; auto row : r)
|
||||
{
|
||||
REQUIRE(ix < (sizeof(kPrimaryAuthors) / sizeof(char *)));
|
||||
|
||||
CHECK(row[1].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
CHECK(row[0].as<size_t>() == ix);
|
||||
|
||||
// CHECK(row["name"].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
// CHECK(row["ordinal"].as<int>() == ix);
|
||||
}
|
||||
|
||||
r = tx.exec("SELECT * FROM citation_author WHERE citation_id = 'primary';");
|
||||
CHECK(r.size() == 7);
|
||||
|
||||
for (size_t ix = 0; auto row : r)
|
||||
{
|
||||
REQUIRE(ix < (sizeof(kPrimaryAuthors) / sizeof(char *)));
|
||||
|
||||
for (auto fld : row)
|
||||
{
|
||||
switch (fld.num())
|
||||
{
|
||||
case 0:
|
||||
CHECK(fld.name() == "citation_id");
|
||||
CHECK(fld.as<std::string>() == "primary");
|
||||
break;
|
||||
case 1:
|
||||
CHECK(fld.name() == "name");
|
||||
CHECK(fld.as<std::string>() == kPrimaryAuthors[ix]);
|
||||
break;
|
||||
case 2:
|
||||
CHECK(fld.name() == "ordinal");
|
||||
CHECK(fld.as<int>() == ix);
|
||||
break;
|
||||
default:
|
||||
REQUIRE(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++ix;
|
||||
|
||||
// CHECK(row[0].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
// CHECK(row[1].as<int>() == ix);
|
||||
|
||||
CHECK(row["name"].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
CHECK(row["ordinal"].as<size_t>() == ix);
|
||||
}
|
||||
|
||||
// CHECK(tx.query_value<int>("SELECT COUNT(*) FROM citation_author WHERE citation_id = 'primary';") == 7);
|
||||
|
||||
// for (size_t ix = 0; auto row : r)
|
||||
// {
|
||||
// REQUIRE(ix < (sizeof(kPrimaryAuthors) / sizeof(char*)));
|
||||
// // CHECK(row["name"].as<std::string>() == kPrimaryAuthors[ix++]);
|
||||
// // CHECK(row["ordinal"].as<int>() == ix);
|
||||
// }
|
||||
|
||||
// for (size_t ix = 0; const auto &[name, ordinal] : tx.stream<std::string, int>("SELECT name FROM citation_author WHERE citation_id = 'primary'"))
|
||||
// {
|
||||
// REQUIRE(ix < (sizeof(kPrimaryAuthors) / sizeof(char*)));
|
||||
// CHECK(name == kPrimaryAuthors[ix++]);
|
||||
// CHECK(ordinal == ix);
|
||||
// }
|
||||
}
|
||||
Reference in New Issue
Block a user