diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1cec96a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "3rdparty/nlohmann_json"] + path = 3rdparty/nlohmann_json + url = https://github.com/nlohmann/json.git diff --git a/3rdparty/CMakeLists.txt b/3rdparty/CMakeLists.txt new file mode 100644 index 0000000..6b4425b --- /dev/null +++ b/3rdparty/CMakeLists.txt @@ -0,0 +1,4 @@ +if(NOT KIMA2_USE_EXTERNAL_JSON) + set(JSON_BuildTests OFF CACHE INTERNAL "") + add_subdirectory(nlohmann_json) +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 9619113..a6869b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,13 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +option(KIMA2_USE_EXTERNAL_JSON "Use an external JSON library" OFF) + +if(KIMA2_USE_EXTERNAL_JSON) + find_package(nlohmann_json REQUIRED) +endif() + +add_subdirectory(3rdparty) add_subdirectory(src) if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE MATCHES Debug) @@ -57,7 +64,7 @@ else(WIN32 AND NOT UNIX) set(CPACK_SOURCE_GENERATOR "TBZ2") set(CPACK_GENERATOR "RPM;DEB") set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE amd64) - set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5printsupport5 (>= 5.4), libjsoncpp1, libusb-1.0-0") + set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5printsupport5 (>= 5.4), libusb-1.0-0") set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/share/applications" "/usr/share/icons" @@ -90,7 +97,6 @@ if( MINGW ) ${MINGW_PATH}/libicuuc62.dll ${MINGW_PATH}/libicuin62.dll ${MINGW_PATH}/libicudt62.dll - ${MINGW_PATH}/libjsoncpp-20.dll ${MINGW_PATH}/libpcre2-16-0.dll ${MINGW_PATH}/zlib1.dll ${MINGW_PATH}/libharfbuzz-0.dll diff --git a/README.md b/README.md index ac147dc..7e2bc98 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,10 @@ Ubuntu, Windows) angeboten. Bitte die Hinweise dort beachten. ### Selbst compilieren KIMA2 benötigt folgende Libraries: * Qt5 -* jsoncpp -* xlnt >= 1.3.0 * boost >= 1.62 * libusb-1.0 +* xlnt >= 1.3.0 +* nlohmann-json (als 3rdparty submodule vorhanden) Da Features aus C++17 verwendet werden sowie std::filesystem, sollte als Compiler mindestens GCC 8 verwendet werden. diff --git a/misc/PKGBUILD b/misc/PKGBUILD index 2902c23..9ecb737 100644 --- a/misc/PKGBUILD +++ b/misc/PKGBUILD @@ -1,12 +1,12 @@ # Maintainer: Martin Brodbeck pkgname=kima2 -pkgver=0.9.0 +pkgver=0.12.0 pkgrel=1 pkgdesc="A small cash point program for children's things markets (German only)" arch=('i686' 'x86_64') url="http://www.rustysoft.de/?01_kima2" license=('custom') -depends=('glibc' 'libusb' 'qt5-base' 'sqlite3' 'xlnt' 'jsoncpp') +depends=('glibc' 'libusb' 'qt5-base' 'sqlite3' 'xlnt') makedepends=('boost>=1.62') source=($pkgname-$pkgver.tar.gz) md5sums=('') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 55543d5..cb0d4c1 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -2,13 +2,12 @@ set(Boost_USE_STATIC_LIBS ON) find_package(Boost 1.62 COMPONENTS date_time REQUIRED) find_package(SQLite3 REQUIRED) + if (MINGW) find_package(XLNT REQUIRED STATIC) - find_package(JSONCPP REQUIRED) else (MINGW) find_package(PkgConfig REQUIRED) pkg_check_modules(XLNT REQUIRED xlnt>=1.3) - pkg_check_modules(JSONCPP REQUIRED jsoncpp) endif (MINGW) set(CORE_SOURCES @@ -24,11 +23,12 @@ set(CORE_SOURCES ) add_library(core STATIC ${CORE_SOURCES}) + if (WIN32) - target_link_libraries(core printer Boost::boost Boost::date_time sqlite3 ${XLNT_LIBRARY} ${JSONCPP_LIBRARY}) - target_link_libraries(core bcrypt) + target_link_libraries(core PRIVATE printer Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARY}) + target_link_libraries(core PRIVATE bcrypt) else() - target_link_libraries(core printer Boost::boost Boost::date_time sqlite3 ${XLNT_LIBRARIES} ${JSONCPP_LIBRARIES}) + target_link_libraries(core PRIVATE printer Boost::boost Boost::date_time sqlite3 nlohmann_json::nlohmann_json ${XLNT_LIBRARIES}) endif() target_include_directories(core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/core/jsonutil.cpp b/src/core/jsonutil.cpp index ab4f86c..dddf79a 100644 --- a/src/core/jsonutil.cpp +++ b/src/core/jsonutil.cpp @@ -1,54 +1,48 @@ #include "jsonutil.h" #include "database.h" -#include +#include #include namespace fs = std::filesystem; +using json = nlohmann::json; -void JsonUtil::exportSellers(const fs::path& filePath, Marketplace* market) +void JsonUtil::exportSellers(const std::filesystem::path& filePath, Marketplace* market) { - Json::Value root; + json root; std::ofstream file(filePath); - Json::StreamWriterBuilder builder; - builder["commentStyle"] = "None"; - builder["indentation"] = " "; - - std::unique_ptr writer(builder.newStreamWriter()); - for (const auto& seller : market->getSellers()) { - Json::Value newEntry; + json newEntry; newEntry["uuid"] = seller->getUuidAsString(); newEntry["seller_no"] = seller->getSellerNo(); newEntry["last_name"] = seller->getLastName(); newEntry["first_name"] = seller->getFirstName(); newEntry["num_offered_articles"] = seller->numArticlesOffered(); - root["sellers"].append(newEntry); + root["sellers"].push_back(newEntry); } - writer->write(root, &file); + file << root.dump(4) << std::endl; } -void JsonUtil::importSellers(const fs::path& filePath, Marketplace* market) +void JsonUtil::importSellers(const std::filesystem::path& filePath, Marketplace* market) { for (auto& seller : market->getSellers()) { seller->setState(Seller::State::DELETE); } market->storeToDb(true); - Json::Value jsonValues; std::ifstream file(filePath); - file >> jsonValues; + json jsonValues = json::parse(file); for (auto val : jsonValues["sellers"]) { auto seller = std::make_unique(); - seller->setUuidFromString(val["uuid"].asString()); - seller->setSellerNo(val["seller_no"].asInt()); - seller->setLastName(val["last_name"].asString()); - seller->setFirstName(val["first_name"].asString()); - seller->setNumArticlesOffered(val["num_offered_articles"].asInt()); + seller->setUuidFromString(val["uuid"]); + seller->setSellerNo(val["seller_no"]); + seller->setLastName(val["last_name"]); + seller->setFirstName(val["first_name"]); + seller->setNumArticlesOffered(val["num_offered_articles"]); market->getSellers().push_back(std::move(seller)); } @@ -69,29 +63,23 @@ void JsonUtil::importSellers(const fs::path& filePath, Marketplace* market) market->storeToDb(); } -void JsonUtil::exportSales(const fs::path& filePath, Marketplace* market, int cashPointNo) +void JsonUtil::exportSales(const std::filesystem::path& filePath, Marketplace* market, int cashPointNo) { - Json::Value root; + json root; std::ofstream file(filePath); - Json::StreamWriterBuilder builder; - builder["commentStyle"] = "None"; - builder["indentation"] = " "; - - std::unique_ptr writer(builder.newStreamWriter()); - root["source_no"] = cashPointNo; for (const auto& sale : market->getSales()) { if (sale->getSourceNo() != cashPointNo) continue; - Json::Value newSale; + json newSale; newSale["uuid"] = sale->getUuidAsString(); newSale["timestamp"] = sale->getTimestamp(); for (const auto& article : sale->getArticles()) { - Json::Value newArticle; + json newArticle; newArticle["uuid"] = article->getUuidAsString(); newArticle["seller_uuid"] = article->getSeller()->getUuidAsString(); newArticle["desc"] = article->getDescription(); @@ -99,43 +87,42 @@ void JsonUtil::exportSales(const fs::path& filePath, Marketplace* market, int ca // newArticle["source_no"] = article->getSourceNo(); newArticle["article_no"] = article->getArticleNo(); - newSale["articles"].append(newArticle); + newSale["articles"].push_back(newArticle); } - root["sales"].append(newSale); + root["sales"].push_back(newSale); } - writer->write(root, &file); + file << root.dump(4) << std::endl; } -void JsonUtil::importSales(const fs::path& filePath, Marketplace* market, int cashPointNo) +void JsonUtil::importSales(const std::filesystem::path& filePath, Marketplace* market, int cashPointNo) { - Json::Value jsonValues; std::ifstream file(filePath); - file >> jsonValues; + json jsonValues = json::parse(file); - int source_no = jsonValues["source_no"].asInt(); + int source_no = jsonValues["source_no"]; if (source_no == cashPointNo) { throw std::runtime_error("Die Kassen-Nr. der zu imporierenden Daten wird von dieser Kasse " "hier bereits verwendet."); } - market->setSalesToDelete(jsonValues["source_no"].asInt()); + market->setSalesToDelete(jsonValues["source_no"]); market->storeToDb(); for (const auto& valSale : jsonValues["sales"]) { auto sale = std::make_unique(); - sale->setUuidFromString(valSale["uuid"].asString()); - sale->setSourceNo(jsonValues["source_no"].asInt()); - sale->setTimestamp(valSale["timestamp"].asString()); + sale->setUuidFromString(valSale["uuid"]); + sale->setSourceNo(jsonValues["source_no"]); + sale->setTimestamp(valSale["timestamp"]); for (const auto& valArticle : valSale["articles"]) { auto article = std::make_unique
(); - article->setUuidFromString(valArticle["uuid"].asString()); - article->setSourceNo(jsonValues["source_no"].asInt()); - article->setArticleNo(valArticle["article_no"].asInt()); - article->setDescription(valArticle["desc"].asString()); - article->setPrice(valArticle["price"].asInt()); - auto seller = market->findSellerWithUuid(valArticle["seller_uuid"].asString()); + article->setUuidFromString(valArticle["uuid"]); + article->setSourceNo(jsonValues["source_no"]); + article->setArticleNo(valArticle["article_no"]); + article->setDescription(valArticle["desc"]); + article->setPrice(valArticle["price"]); + auto seller = market->findSellerWithUuid(valArticle["seller_uuid"]); if (seller == nullptr) { throw std::runtime_error( "Die zu importierenden Daten verweisen auf einen nicht vorhandenen Verkäufer. "