Giter VIP home page Giter VIP logo

tinyorm's Introduction

TinyORM Logo TinyORM

MSVC2019 Qt5.15 MSVC2022 Qt6.7 Linux GCC/Clang Qt5.15 Linux GCC/Clang Qt6.2 MSYS2 UCRT64 GCC/Clang clang-cl MSVC2022 Clang-Tidy/Clazy Qt5.15/6.7 Vcpkg Windows Vcpkg Linux MSVC2022 Qt6.7 TinyDrivers Linux GCC/Clang Qt6.2 TinyDrivers

TinyORM - www.tinyorm.org License MIT
TinyORM v0.37.3 tom v0.9.1 TinyDrivers v0.1.1 TinyMySql v0.1.1

TinyORM is a modern ORM library that makes interacting with a database extremely simple.

The code is written in the modern c++20 way and is heavily tested with 3366 unit and functional tests. Almost all the query builder methods are unit tested. The TinyORM's query builder code and the code which is responsible for obtaining relationships, is tested by functional tests against all supported databases. The code coverage is good enough to guarantee API and behavior compatibility.

Donations ❤️

Bitcoin address  1NiF2cTvYxUj8FTZJnGn1ycN4yisWfo1vJ
PayPal                 https://paypal.me/silverzachara

Documentation

Whole library is documented as markdown documents:

www.tinyorm.org

Features Summary

The following list summarizes all the TinyDrivers and TinyMySql libraries' features. 🆕

  • both, normal and prepared statements are supported
  • TLS/SSL connections using MYSQL_OPT_SSL_MODE (verify_ca, verify_identity) 🔥
  • setting many other connection options (see mysqldriver_p.cpp)
  • building and linking against the MariaDB Connector/C
  • transactions
  • re-using the current SqlQuery instance to re-execute the same or another query
  • detaching from the result set (associated to release memory)
  • query size, number of affected rows, last inserted ID, testing isNull(), ...
  • all 3366 unit tests passed 😮

The following list fastly summarizes all the TinyORM features.

  • simple database connections management 🧬
    • database manager that helps with the database connections management
    • Orm::DB facade class for nicer and shorter syntax
    • MySQL, MariaDB, SQLite, and PostgreSQL support for all features 💎
    • multi-threading support 👀
    • SSL connections support 🔒
  • impressive query builder 🔧
    • allows passing sub-queries and raw expressions practically everywhere, to column names, values, and to every SQL clause as select, where, joins, group by, having, order by 🔥
    • a logical grouping that offers to wrap logical groups in parenthesis
    • chunked results for lower memory footprint ✨
    • raw methods for all SQL clauses
    • all join types (left, right, cross, inner) and also join where clause support 🫤
    • aggregate methods min, max, sum, increment, decrement, ...
    • whereExists and exists methods for an existence queries
    • transactions and pessimistic locking 🔒
    • of course, insert, update, and delete SQL clauses support
    • correct QDateTime time zone using the qt_timezone connection configuration option 📅 (returned QDateTime instances will have the correct time zone, and also works for an ORM)
      • this feature allows you to set up the database server time zone to the UTC and all returned QDateTime instances will have the correct UTC time zone
  • clever ORM with all relation types support 🎉
    • one-to-one, one-to-many, and many-to-many relation types (also inverse relationships) 🧨
    • eager and lazy loading with custom select and constraints 🚀
    • fluent ModelsCollection that expose a variety of map / reduce operations that may be chained using an intuitive interface ✨
    • all query builder methods are proxied from the model instances and also from the relation instances back to the query builder 🤯 (everything that can be called on the query builder can also be called on the model and relation instances)
    • clean active record pattern
    • advanced features like timestamps, touching parent timestamps, soft deleting, default models, default model attributes, and attribute casting 🤓
    • querying relationships existence/absence using the has, whereHas, and hasNested methods (using dot notation for selecting nested relationships users.posts.comments)
    • serializing models and collection of models including all nested relations to JSON and converting to vectors and maps 🪡
      • supports controlling a custom date format during serialization
      • supports hiding and appending attributes
  • compiled database migrations and seeders 🕺
    • create, update, drop, and rename database tables
    • create, drop, and rename table columns
    • extensive schema builder that allows creating of all possible column types
    • terser syntax for creating foreign keys and foreign key constraints
    • supports creating, and dropping column indexes (primary, unique, fulltext, spatial)
  • the tom console application with tab completion for all shells (pwsh, bash, zsh) 🥳
    • scaffolding of models, migrations, and seeders
    • impressive models scaffolding, every feature that is supported by models can be generated using the tom make:model cli command
  • a huge amount of code is unit tested, currently 3366 unit tests 🤯
  • C++20 only, with all the latest features used like concepts/constraints, ranges, smart pointers (no new keyword in the whole code 😎), folding expressions
  • qmake and CMake build systems support
    • CMake FetchContent module support 🤙
  • vcpkg support (also the vcpkg port, currently not committed to the vcpkg repository ☹️)
  • it's really fast, you can run 1000 complex queries in 500ms (heavily DB dependant, the PostgreSQL is by far the fastest) ⌚
  • extensive documentation 📃
  • ...

Showcase Images

Tom console application

Tom console application

Passed all unit tests 🥳

Passed all unit tests

TinyOrmPlayground single-threaded

Invoked TinyOrmPlayground single-threaded

TinyOrmPlayground multi-threaded

Invoked TinyOrmPlayground multi-threaded

tinyorm's People

Contributors

schaichalonso avatar silverqx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tinyorm's Issues

compilation error

I completed the build of the project and compiled the tinyorm library. When running a test sample, the compilation reports an error. This seems to be related to the qt5 library, perhaps this requires a qmake build. I don't know much about QT applications and I'm not sure which libraries to import.
I have built the Qt5 library on ubuntu, but there is no .cmake file. So I chose to import the qt libraries manually. I have seen some people say that qt dependencies need to be built with qmake, I didn't understand those and I used the following way build.

  • source code
#include <orm/db.hpp>

using Orm::DB;

// Ownership of a shared_ptr()
auto manager = DB::create({
    {"driver",          "QMYSQL"},
    {"host",            qEnvironmentVariable("DB_HOST", "127.0.0.1")},
    {"port",            qEnvironmentVariable("DB_PORT", "3306")},
    {"database",        qEnvironmentVariable("DB_DATABASE", "")},
    {"username",        qEnvironmentVariable("DB_USERNAME", "root")},
    {"password",        qEnvironmentVariable("DB_PASSWORD", "")},
    {"charset",         qEnvironmentVariable("DB_CHARSET", "utf8mb4")},
    {"collation",       qEnvironmentVariable("DB_COLLATION", "utf8mb4_0900_ai_ci")},
    {"timezone",        "+00:00"},
    // Specifies what time zone all QDateTime-s will have
    {"qt_timezone",     QVariant::fromValue(Qt::UTC)},
    {"prefix",          ""},
    {"prefix_indexes",  false},
    {"strict",          true},
    {"engine",          "InnoDB"},
    {"options",         QVariantHash()},
});
int main(){
  return 0;
}
  • Makefile
# app is cpp filename above

CC = /usr/bin/gcc-11
CXX = /usr/bin/g++-11

Iinclude = -I/home/wcx/gitProject/cpp_interview/TinyORM/include
Iinclude += -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/range-v3/include
Iinclude += -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/tabulate/include
Iinclude += -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include
Iinclude += -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtCore
Iinclude += -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtSql

INCPATH       = -I. -I. -I../TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include -I../TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtGui -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtGui -I../TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtCore -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtCore -I. -I/usr/include/libdrm -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/mkspecs/linux-g++
Iinclude += $(INCPATH)

Llib = -L/home/wcx/gitProject/cpp_interview/TinyORM/build
Llib += -L/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/lib

libs = /home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/lib/libQt5Gui.so /home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/lib/libQt5Core.so -lGL -lpthread
libs += -lTinyOrm -lQt5Sql -lQt5Core

CFLAGS = -Werror -fPIC -Wall -Wextra -pedantic -std=c++20 -O0 $(libs) $(Iinclude) $(Llib) 


all: $(app)

$(app): $(app).cpp
	$(CXX) $(CFLAGS) -o $(app) $(app).cpp 
  • compilation error information
/usr/bin/g++-11 -Werror -fPIC -Wall -Wextra -pedantic -std=c++20 -O0 /home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/lib/libQt5Gui.so /home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/lib/libQt5Core.so -lGL -lpthread -lTinyOrm -lQt5Sql -lQt5Core -I/home/wcx/gitProject/cpp_interview/TinyORM/include -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/range-v3/include -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/tabulate/include -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtCore -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtSql -I. -I. -I../TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include -I../TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtGui -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtGui -I../TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtCore -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/include/QtCore -I. -I/usr/include/libdrm -I/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/mkspecs/linux-g++ -L/home/wcx/gitProject/cpp_interview/TinyORM/build -L/home/wcx/gitProject/cpp_interview/TinyORM/dep/qt5/qt-everywhere-src-5.15.2/qtbase/lib  -o connect connect.cpp 
/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/tmp/cciGGVit.o: In function `__static_initialization_and_destruction_0(int, int)':
connect.cpp:(.text+0x301f): undefined reference to `qEnvironmentVariable(char const*, QString const&)'
connect.cpp:(.text+0x307f): undefined reference to `qEnvironmentVariable(char const*, QString const&)'
connect.cpp:(.text+0x30df): undefined reference to `qEnvironmentVariable(char const*, QString const&)'
connect.cpp:(.text+0x313f): undefined reference to `qEnvironmentVariable(char const*, QString const&)'
connect.cpp:(.text+0x319f): undefined reference to `qEnvironmentVariable(char const*, QString const&)'
/tmp/cciGGVit.o:connect.cpp:(.text+0x31ff): more undefined references to `qEnvironmentVariable(char const*, QString const&)' follow
/tmp/cciGGVit.o: In function `__static_initialization_and_destruction_0(int, int)':
connect.cpp:(.text+0x3430): undefined reference to `Orm::DB::create(QHash<QString, QVariant> const&, QString const&)'
connect.cpp:(.text+0x3485): undefined reference to `QVariant::~QVariant()'
connect.cpp:(.text+0x35ec): undefined reference to `QVariant::~QVariant()'
/tmp/cciGGVit.o:(.qtversion[qt_version_tag]+0x0): undefined reference to `qt_version_tag'
/tmp/cciGGVit.o: In function `QArrayData::data()':
connect.cpp:(.text._ZN10QArrayData4dataEv[_ZN10QArrayData4dataEv]+0x4c): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QArrayData::sharedNull()':
connect.cpp:(.text._ZN10QArrayData10sharedNullEv[_ZN10QArrayData10sharedNullEv]+0x7): undefined reference to `QArrayData::shared_null'
/tmp/cciGGVit.o: In function `QString::QString(char const*)':
connect.cpp:(.text._ZN7QStringC2EPKc[_ZN7QStringC5EPKc]+0x36): undefined reference to `QString::fromAscii_helper(char const*, int)'
/tmp/cciGGVit.o: In function `QString::QString(QLatin1String)':
connect.cpp:(.text._ZN7QStringC2E13QLatin1String[_ZN7QStringC5E13QLatin1String]+0x41): undefined reference to `QString::fromLatin1_helper(char const*, int)'
/tmp/cciGGVit.o: In function `QString::QString(QString const&)':
connect.cpp:(.text._ZN7QStringC2ERKS_[_ZN7QStringC5ERKS_]+0x42): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QHashData::willGrow()':
connect.cpp:(.text._ZN9QHashData8willGrowEv[_ZN9QHashData8willGrowEv]+0x34): undefined reference to `QHashData::rehash(int)'
/tmp/cciGGVit.o: In function `qt_getQtMetaObject()':
connect.cpp:(.text._Z18qt_getQtMetaObjectv[_Z18qt_getQtMetaObjectv]+0x7): undefined reference to `QObject::staticQtMetaObject'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::~pair()':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantED2Ev[_ZNSt4pairI7QString8QVariantED5Ev]+0x18): undefined reference to `QVariant::~QVariant()'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [7], char const (&) [7], true>(char const (&) [7], char const (&) [7])':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC1IRA7_KcS6_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC1IRA7_KcS6_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(char const*)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [9], char const (&) [7], true>(char const (&) [9], char const (&) [7])':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC1IRA9_KcRA7_S4_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC1IRA9_KcRA7_S4_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(char const*)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [7], char const (&) [1], true>(char const (&) [7], char const (&) [1])':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC1IRA7_KcRA1_S4_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC1IRA7_KcRA1_S4_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(char const*)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [15], bool, true>(char const (&) [15], bool&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC1IRA15_KcbLb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC1IRA15_KcbLb1EEEOT_OT0_]+0x50): undefined reference to `QVariant::QVariant(bool)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [7], bool, true>(char const (&) [7], bool&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC1IRA7_KcbLb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC1IRA7_KcbLb1EEEOT_OT0_]+0x50): undefined reference to `QVariant::QVariant(bool)'
/tmp/cciGGVit.o: In function `QTypedArrayData<char>::deallocate(QArrayData*)':
connect.cpp:(.text._ZN15QTypedArrayDataIcE10deallocateEP10QArrayData[_ZN15QTypedArrayDataIcE10deallocateEP10QArrayData]+0x1e): undefined reference to `QArrayData::deallocate(QArrayData*, unsigned long, unsigned long)'
/tmp/cciGGVit.o: In function `QTypedArrayData<unsigned short>::deallocate(QArrayData*)':
connect.cpp:(.text._ZN15QTypedArrayDataItE10deallocateEP10QArrayData[_ZN15QTypedArrayDataItE10deallocateEP10QArrayData]+0x1e): undefined reference to `QArrayData::deallocate(QArrayData*, unsigned long, unsigned long)'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::QHash()':
connect.cpp:(.text._ZN5QHashI7QString8QVariantEC2Ev[_ZN5QHashI7QString8QVariantEC5Ev]+0xf): undefined reference to `QHashData::shared_null'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::reserve(int)':
connect.cpp:(.text._ZN5QHashI7QString8QVariantE7reserveEi[_ZN5QHashI7QString8QVariantE7reserveEi]+0x56): undefined reference to `QHashData::rehash(int)'
/tmp/cciGGVit.o: In function `QStaticStringData<1>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi1EE8data_ptrEv[_ZNK17QStaticStringDataILi1EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QStaticStringData<2>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi2EE8data_ptrEv[_ZNK17QStaticStringDataILi2EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QStaticStringData<5>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi5EE8data_ptrEv[_ZNK17QStaticStringDataILi5EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QStaticStringData<4>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi4EE8data_ptrEv[_ZNK17QStaticStringDataILi4EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QStaticStringData<3>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi3EE8data_ptrEv[_ZNK17QStaticStringDataILi3EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o:connect.cpp:(.text._ZNK17QStaticStringDataILi10EE8data_ptrEv[_ZNK17QStaticStringDataILi10EE8data_ptrEv]+0x36): more undefined references to `qt_assert(char const*, char const*, int)' follow
/tmp/cciGGVit.o: In function `int qRegisterMetaType<Qt::TimeSpec>(char const*, Qt::TimeSpec*, QtPrivate::MetaTypeDefinedHelper<Qt::TimeSpec, QMetaTypeId2<Qt::TimeSpec>::Defined&&(!QMetaTypeId2<Qt::TimeSpec>::IsBuiltIn)>::DefinedType)':
connect.cpp:(.text._Z17qRegisterMetaTypeIN2Qt8TimeSpecEEiPKcPT_N9QtPrivate21MetaTypeDefinedHelperIS4_Xaasr12QMetaTypeId2IS4_E7DefinedntsrS9_9IsBuiltInEE11DefinedTypeE[_Z17qRegisterMetaTypeIN2Qt8TimeSpecEEiPKcPT_N9QtPrivate21MetaTypeDefinedHelperIS4_Xaasr12QMetaTypeId2IS4_E7DefinedntsrS9_9IsBuiltInEE11DefinedTypeE]+0x32): undefined reference to `QMetaObject::normalizedType(char const*)'
/tmp/cciGGVit.o: In function `QStaticStringData<17>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi17EE8data_ptrEv[_ZNK17QStaticStringDataILi17EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QStaticStringData<12>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi12EE8data_ptrEv[_ZNK17QStaticStringDataILi12EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QStaticStringData<26>::data_ptr() const':
connect.cpp:(.text._ZNK17QStaticStringDataILi26EE8data_ptrEv[_ZNK17QStaticStringDataILi26EE8data_ptrEv]+0x36): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QVariant QVariant::fromValue<Qt::TimeSpec>(Qt::TimeSpec const&)':
connect.cpp:(.text._ZN8QVariant9fromValueIN2Qt8TimeSpecEEES_RKT_[_ZN8QVariant9fromValueIN2Qt8TimeSpecEEES_RKT_]+0x28): undefined reference to `QVariant::QVariant(int, void const*, unsigned int)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [5], QString, true>(char const (&) [5], QString&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC2IRA5_KcS0_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC5IRA5_KcS0_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(QString const&)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [9], QString, true>(char const (&) [9], QString&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC2IRA9_KcS0_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC5IRA9_KcS0_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(QString const&)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [8], QString, true>(char const (&) [8], QString&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC2IRA8_KcS0_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC5IRA8_KcS0_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(QString const&)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [10], QString, true>(char const (&) [10], QString&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC2IRA10_KcS0_Lb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC5IRA10_KcS0_Lb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(QString const&)'
/tmp/cciGGVit.o: In function `std::pair<QString, QVariant>::pair<char const (&) [8], QHash<QString, QVariant>, true>(char const (&) [8], QHash<QString, QVariant>&&)':
connect.cpp:(.text._ZNSt4pairI7QString8QVariantEC2IRA8_Kc5QHashIS0_S1_ELb1EEEOT_OT0_[_ZNSt4pairI7QString8QVariantEC5IRA8_Kc5QHashIS0_S1_ELb1EEEOT_OT0_]+0x4b): undefined reference to `QVariant::QVariant(QHash<QString, QVariant> const&)'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::QHash(std::initializer_list<std::pair<QString, QVariant> >)':
connect.cpp:(.text._ZN5QHashI7QString8QVariantEC2ESt16initializer_listISt4pairIS0_S1_EE[_ZN5QHashI7QString8QVariantEC5ESt16initializer_listISt4pairIS0_S1_EE]+0x27): undefined reference to `QHashData::shared_null'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::freeData(QHashData*)':
connect.cpp:(.text._ZN5QHashI7QString8QVariantE8freeDataEP9QHashData[_ZN5QHashI7QString8QVariantE8freeDataEP9QHashData]+0x22): undefined reference to `QHashData::free_helper(void (*)(QHashData::Node*))'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::findNode(QString const&, unsigned int*) const':
connect.cpp:(.text._ZNK5QHashI7QString8QVariantE8findNodeERKS0_Pj[_ZNK5QHashI7QString8QVariantE8findNodeERKS0_Pj]+0x44): undefined reference to `qHash(QString const&, unsigned int)'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::createNode(unsigned int, QString const&, QVariant const&, QHashNode<QString, QVariant>**)':
connect.cpp:(.text._ZN5QHashI7QString8QVariantE10createNodeEjRKS0_RKS1_PP9QHashNodeIS0_S1_E[_ZN5QHashI7QString8QVariantE10createNodeEjRKS0_RKS1_PP9QHashNodeIS0_S1_E]+0x32): undefined reference to `QHashData::allocateNode(int)'
/tmp/cciGGVit.o: In function `int qRegisterNormalizedMetaType<Qt::TimeSpec>(QByteArray const&, Qt::TimeSpec*, QtPrivate::MetaTypeDefinedHelper<Qt::TimeSpec, QMetaTypeId2<Qt::TimeSpec>::Defined&&(!QMetaTypeId2<Qt::TimeSpec>::IsBuiltIn)>::DefinedType)':
connect.cpp:(.text._Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE[_Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE]+0x3c): undefined reference to `QMetaObject::normalizedType(char const*)'
connect.cpp:(.text._Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE[_Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE]+0x7b): undefined reference to `qt_assert_x(char const*, char const*, char const*, int)'
connect.cpp:(.text._Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE[_Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE]+0xb4): undefined reference to `QMetaType::registerNormalizedTypedef(QByteArray const&, int)'
connect.cpp:(.text._Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE[_Z27qRegisterNormalizedMetaTypeIN2Qt8TimeSpecEEiRK10QByteArrayPT_N9QtPrivate21MetaTypeDefinedHelperIS5_Xaasr12QMetaTypeId2IS5_E7DefinedntsrSA_9IsBuiltInEE11DefinedTypeE]+0x107): undefined reference to `QMetaType::registerNormalizedType(QByteArray const&, void (*)(void*), void* (*)(void*, void const*), int, QFlags<QMetaType::TypeFlag>, QMetaObject const*)'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::insert(QString const&, QVariant const&)':
connect.cpp:(.text._ZN5QHashI7QString8QVariantE6insertERKS0_RKS1_[_ZN5QHashI7QString8QVariantE6insertERKS0_RKS1_]+0xd6): undefined reference to `QVariant::operator=(QVariant const&)'
/tmp/cciGGVit.o: In function `QHashNode<QString, QVariant>::~QHashNode()':
connect.cpp:(.text._ZN9QHashNodeI7QString8QVariantED2Ev[_ZN9QHashNodeI7QString8QVariantED5Ev]+0x18): undefined reference to `QVariant::~QVariant()'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::detach_helper()':
connect.cpp:(.text._ZN5QHashI7QString8QVariantE13detach_helperEv[_ZN5QHashI7QString8QVariantE13detach_helperEv]+0x39): undefined reference to `QHashData::detach_helper(void (*)(QHashData::Node*, void*), void (*)(QHashData::Node*), int, int)'
/tmp/cciGGVit.o: In function `QHash<QString, QVariant>::findNode(QString const&, unsigned int) const':
connect.cpp:(.text._ZNK5QHashI7QString8QVariantE8findNodeERKS0_j[_ZNK5QHashI7QString8QVariantE8findNodeERKS0_j]+0x91): undefined reference to `qt_assert(char const*, char const*, int)'
/tmp/cciGGVit.o: In function `QHashNode<QString, QVariant>::QHashNode(QString const&, QVariant const&, unsigned int, QHashNode<QString, QVariant>*)':
connect.cpp:(.text._ZN9QHashNodeI7QString8QVariantEC2ERKS0_RKS1_jPS2_[_ZN9QHashNodeI7QString8QVariantEC5ERKS0_RKS1_jPS2_]+0x5b): undefined reference to `QVariant::QVariant(QVariant const&)'
/tmp/cciGGVit.o: In function `QHashNode<QString, QVariant>::same_key(unsigned int, QString const&) const':
connect.cpp:(.text._ZNK9QHashNodeI7QString8QVariantE8same_keyEjRKS0_[_ZNK9QHashNodeI7QString8QVariantE8same_keyEjRKS0_]+0x32): undefined reference to `operator==(QString const&, QString const&)'
collect2: error: ld returned 1 exit status
Makefile:26: recipe for target 'connect' failed
make: *** [connect] Error 1

Classify Logs

TinyORM currently uses the QMessageLogger global singleton instance to emit diagnostics, which can be considered a pain on applications doing a lot of queries along alot of qDebug output in TinyORM-unrelated code. While per general policy, QMessageLogger's debug message emission can be turned off, disabling DEBUG level will shut it off for all unclassified qDebug statements in the application, whether originating from TinyORM or elsewhere.

Presumably for this reason, TinyORM does not emit diagnostics in release mode.

Swapping the TinyORM libraries, especially on MSVC builds which have varying ITERATOR_DEBUG_LEVEL breaking the compatibiliy between debug and release DLLs, however, might be unfeasible.

Qt Supports logging categories, which can be used to granularily turn on / off diagnostics per category, without having to recompile the corresponding code, and can also can help to classify the diagnostics in case a more sophisticated logging backend (nagios and friends) is configured .

Invent a log sink name for TinyORM, convert all qDebug to qCDebug and uncoditionally have them be generated. There's only 4-ish of them within library code, so it should be straightforward.

Note, however, that in order to be able to reconfigure the category on the fly, or to use it to emit messegas from an out-of-DLL context (tom-tool or the test suite messages), it needs to be declared using Q_DECLARE_EXPORTED_LOGGING_CATEGORY, with the second argument yielding the dllexport/dllimport declaring macro.

Assertive TinyOrmConfig.cmake breaks static builds

When searching for a TinyORM installation via find_package(TinyORM), the TinyORMConfig.cmake script generated from cmake/TinyOrmConfig.cmake.in will assert on the existance of ${TinyORM_ROOT}/bin in line 21 of it's source script and store the result into a variable that isn't referenced by the find_package logic.

If a static-only TinyORM is installed, the corresponding path will not be created during installation as the static library resides in lib rather then bin, causing find_package invokations by consuming projects to fail.

Extra ';' in several QT Macros prevent build

I've been trying to get the project to build; I have a server setup with all of the appropriate dependencies but it fails to build. I've been able to get it to build with TOM off since it's a much smaller build, and only two files throw errors.

/usr/src/TinyORM/src/orm/databaseconnection.cpp:494:30
/usr/src/TinyORM/src/orm/utils/string.cpp:80:40

Here are the versions of everything that I'm using, followed by the errors:

  • Debian 11 Bullseye up to date as of 2023-02-04
  • MySQL Connector libmysqlcppconn9_8.0.32-1debian10_amd64
  • MySQL Connector Dev libmysqlcppconn-dev_8.0.32-1debian10_amd64
  • QT 5.15.2 from source via git commit 047db969c50ecd0654a99cc6be6705960a4e61b8
  • QT 6.2.0 from source via git commit 61b6f0373c6d13c9b45f22d939e81c669275a5fb
  • vkpkg latest commit 17030920aa97f2dc17a0bdc314344b5ca2807fdf
  • TinyORM latest commit ccef0e5
  • Cmake from source version 3.25.1
  • clang from apt version 11.0.1-2
  • GCC from apt version (Debian 10.2.1-6) 10.2.1 20210110
  • ninja from apt version 1.10.1
FAILED: CMakeFiles/TinyOrm.dir/src/orm/databaseconnection.cpp.o
/usr/bin/c++ -DPROJECT_TINYORM -DQT_CORE_LIB -DQT_DISABLE_DEPRECATED_BEFORE=0x060000 -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_CAST_TO_ASCII -DQT_NO_KEYWORDS -DQT_SQL_LIB -DQT_STRICT_ITERATORS -DQT_USE_QSTRINGBUILDER -DTINYORM_BUILDING_SHARED -DTINYORM_DEBUG -DTINYORM_DEBUG_SQL -DTINYORM_DISABLE_TOM -DTINYORM_EXTERN_CONSTANTS -DTINYORM_MYSQL_PING -DTINYORM_USING_PCH -DTinyOrm_EXPORTS -I/usr/src/TinyORM/TinyORM-builds-cmake/build-debug/TinyOrm_autogen/include -I/usr/src/TinyORM/include -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt5/QtSql -isystem /usr/src/TinyORM/TinyORM-builds-cmake/build-debug/vcpkg_installed/x64-linux/include -isystem /usr/include/mysql -g -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -Wall -Wextra -Weffc++ -Werror -Wfatal-errors -Wcast-qual -Wcast-align -Woverloaded-virtual -Wold-style-cast -Wshadow -Wundef -Wfloat-equal -Wformat-security -Wdouble-promotion -Wconversion -Wzero-as-null-pointer-constant -Wuninitialized -pedantic -pedantic-errors -pipe -Wstrict-null-sentinel -std=c++2a -Winvalid-pch -include /usr/src/TinyORM/TinyORM-builds-cmake/build-debug/CMakeFiles/TinyOrm.dir/cmake_pch.hxx -MD -MT CMakeFiles/TinyOrm.dir/src/orm/databaseconnection.cpp.o -MF CMakeFiles/TinyOrm.dir/src/orm/databaseconnection.cpp.o.d -o CMakeFiles/TinyOrm.dir/src/orm/databaseconnection.cpp.o -c /usr/src/TinyORM/src/orm/databaseconnection.cpp
/usr/src/TinyORM/src/orm/databaseconnection.cpp:494:30: error: extra ';' [-Wpedantic]
  494 |                           }));
      |                              ^
compilation terminated due to -Wfatal-errors.
FAILED: CMakeFiles/TinyOrm.dir/src/orm/utils/string.cpp.o
/usr/bin/c++ -DPROJECT_TINYORM -DQT_CORE_LIB -DQT_DISABLE_DEPRECATED_BEFORE=0x060000 -DQT_NO_CAST_FROM_BYTEARRAY -DQT_NO_CAST_TO_ASCII -DQT_NO_KEYWORDS -DQT_SQL_LIB -DQT_STRICT_ITERATORS -DQT_USE_QSTRINGBUILDER -DTINYORM_BUILDING_SHARED -DTINYORM_DEBUG -DTINYORM_DEBUG_SQL -DTINYORM_DISABLE_TOM -DTINYORM_EXTERN_CONSTANTS -DTINYORM_MYSQL_PING -DTINYORM_USING_PCH -DTinyOrm_EXPORTS -I/usr/src/TinyORM/TinyORM-builds-cmake/build-debug/TinyOrm_autogen/include -I/usr/src/TinyORM/include -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -isystem /usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++ -isystem /usr/include/x86_64-linux-gnu/qt5/QtSql -isystem /usr/src/TinyORM/TinyORM-builds-cmake/build-debug/vcpkg_installed/x64-linux/include -isystem /usr/include/mysql -g -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -Wall -Wextra -Weffc++ -Werror -Wfatal-errors -Wcast-qual -Wcast-align -Woverloaded-virtual -Wold-style-cast -Wshadow -Wundef -Wfloat-equal -Wformat-security -Wdouble-promotion -Wconversion -Wzero-as-null-pointer-constant -Wuninitialized -pedantic -pedantic-errors -pipe -Wstrict-null-sentinel -std=c++2a -Winvalid-pch -include /usr/src/TinyORM/TinyORM-builds-cmake/build-debug/CMakeFiles/TinyOrm.dir/cmake_pch.hxx -MD -MT CMakeFiles/TinyOrm.dir/src/orm/utils/string.cpp.o -MF CMakeFiles/TinyOrm.dir/src/orm/utils/string.cpp.o.d -o CMakeFiles/TinyOrm.dir/src/orm/utils/string.cpp.o -c /usr/src/TinyORM/src/orm/utils/string.cpp
/usr/src/TinyORM/src/orm/utils/string.cpp:80:40: error: extra ';' [-Wpedantic]
   80 | Q_GLOBAL_STATIC(SnakeCache, snakeCache);

Here are the build commands:

cd /usr/src/
git clone https://github.com/silverqx/TinyORM.git
mkdir -p TinyORM/TinyORM-builds-cmake/build-debug
cd TinyORM/TinyORM-builds-cmake/build-debug
cmake \
    -S "/usr/src/TinyORM" \
    -B "/usr/src/TinyORM/TinyORM-builds-cmake/build-debug" \
    -G 'Ninja' \
    -D CMAKE_BUILD_TYPE:STRING='Debug' \
    -D CMAKE_TOOLCHAIN_FILE:FILEPATH="/usr/src/vcpkg/scripts/buildsystems/vcpkg.cmake" \
    -D CMAKE_INSTALL_PREFIX:PATH="/usr/src/TinyORM/tmp" \
    -D VERBOSE_CONFIGURE:BOOL=ON \
    -D BUILD_TESTS:BOOL=OFF \
    -D MYSQL_PING:BOOL=ON \
    -D TOM:BOOL=OFF \
    -D TOM_EXAMPLE:BOOL=OFF \
    -D MATCH_EQUAL_EXPORTED_BUILDTREE:BOOL=ON \
    -D Qt5_DIR=/usr/src/qt5/qt-build/qtbase/lib/cmake/Qt5/
cmake --build . --target all

I'll update on the issues I'm having building it with TOM set to ON. That's just a trickier fix since some non-ASCII characters in one of the files are preventing me from navigating the file in vim, so I'll need to download it to my local machine and use an IDE.

I can clone the repo and fix the thrown errors temporarily, but that's not a sane fix. Any thoughts?

Let me know if I missed something or you need anything else!

vcpkg ports error

PS H:\Proglib\c\vcpkg\vcpkg> .\vcpkg.exe install tinyorm --overlay-ports="H:\Proglib\c\vcpkg\TinyORM\cmake\vcpkg\ports\tinyorm"
Computing installation plan...
libmysql[core]:x86-windows is only supported on '!(windows & x86) & !uwp'

[cmake] Installing mdx documentation

TInyORM use Docusaurus for documentation so all files in the docs/ folder are *.mdx files, what means they also contain javascript, or they contain also images which are in the assets/ folders.

Should I install this type of documentation with CMake? Should be installed also in vcpkg port?

Tom application referenced in TinyORM: Getting Started but not getting installed

The TinyORM: Getting Started page of the documentation is referring a tom binary.

This tom binary can be compiled by passing -DTOM_EXAMPLE=On to cmake before building TinyORM, but after compilation won't be installed along with TinyORM. Further, it will be placed into

${${TinyOrm_ns}_BINARY_DIR}/examples/tom/$<CONFIG>

of the build path, while the TinyORM DLL resides in

${${TinyOrm_ns}_BINARY_DIR}/$<CONFIG>

i.e. requires PATH / LD_LIBRARY_PATH to be modified to contain the DLL path.

If TOM_EXAMPLE is set, the tom binary should be installed as part of TinyORM to use a standardized binary path, resolve the DLL issue, and not require a TinyORM build directory in order to progress through the getting started section.

Tests don't compile if ORM is disabled

The querybuilders' unit tests fail to compile if ORM compilation is disabled via cmake

PS D:\projects\TinyORM> git reflog -n 1
    1cc4dd18 (HEAD -> main, origin/main, origin/develop, origin/HEAD) HEAD@{0}: pull: Fast-forward
PS D:\projects\TinyORM> cmake -B build -DORM=off -DBUILD_TESTS=on "-DCMAKE_TOOLCHAIN_FILE=d:/vcpkg/scripts/buildsystems/vcpkg.cmake" .
PS D:\projects\TinyORM> cmake --build build
    [...]
D:\Projects\TinyORM\tests\auto\unit\orm\schema\mysql_schemabuilder\tst_mysql_schemabuilder.cpp(31,24): error C2039: 'LogicError': is not a member of 'Orm::Exceptions' [D:\Projects\TinyORM\build\tests\auto\unit\orm\schema\mysql_schemabuilder\mysql_schemabuilder.vcxproj]
D:\Projects\TinyORM\include\orm/exceptions/queryerror.hpp(16,11): message : see declaration of 'Orm::Exceptions' [D:\Projects\TinyORM\build\tests\auto\unit\orm\schema\mysql_schemabuilder\mysql_schemabuilder.vcxproj]
D:\Projects\TinyORM\tests\auto\unit\orm\schema\mysql_schemabuilder\tst_mysql_schemabuilder.cpp(31,1): error C2873: 'LogicError': symbol cannot be used in a using-declaration [D:\Projects\TinyORM\build\tests\auto\unit\orm\schema\mysql_schemabuilder\mysql_schemabuilder.vcxproj]
D:\Projects\TinyORM\tests\auto\unit\orm\schema\mysql_schemabuilder\tst_mysql_schemabuilder.cpp(828,5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [D:\Projects\TinyORM\build\tests\auto\unit\orm\schema\mysql_schemabuilder\mysql_schemabuilder.vcxproj]
D:\Projects\TinyORM\tests\auto\unit\orm\schema\mysql_schemabuilder\tst_mysql_schemabuilder.cpp(828,5): error C2143: syntax error: missing ',' before '&' [D:\Projects\TinyORM\build\tests\auto\unit\orm\schema\mysql_schemabuilder\mysql_schemabuilder.vcxproj]

build attempt was done on windows using SDK 10.0.19041.0 and vcpkg fba81a6a5 which is the same as the current github actions use, though it also reproduces on very different platforms.

The missing exceptions are actually being built as part of the querybuilder. The problem instead is that the tests deep-end on models/user.hpp to include the header files for the exception classes they are using, but the corresponding include directive is skipped for builds that disable ORM.

[cmake] Can't build using FetchContent

I cannot get this to work with cmake, I get the following error:

[cmake] CMake Error at build/_deps/tinyorm-build/TinyOrmConfig.cmake:61 (include):
[cmake]   include could not find requested file:
[cmake] 
[cmake]     /workspaces/cssudii/build/_deps/tinyorm-build/TinyOrmTargets.cmake
[cmake] Call Stack (most recent call first):
[cmake]   CMakeLists.txt:43 (find_package)
[cmake] 
[cmake] 
[cmake] CMake Error at build/_deps/tinyorm-build/TinyOrmConfig.cmake:75 (set_target_properties):
[cmake]   set_target_properties can not be used on an ALIAS target.
[cmake] Call Stack (most recent call first):
[cmake]   CMakeLists.txt:43 (find_package)

CMake Version: 3.22
In my CMakeLists.txt

FetchContent_Declare(TinyORM GIT_REPOSITORY https://github.com/silverqx/TinyORM.git GIT_TAG origin/main)
FetchContent_MakeAvailable(TinyORM)

...

find_package(TinyOrm 0.15.1.0 CONFIG REQUIRED)

target_link_libraries(${PROJECT_NAME}
    PRIVATE
        Qt${QT_VERSION_MAJOR}::Core
        TinyOrm::TinyOrm
)

I'm not sure if I'm missing something.

Many-to-many and wrong detach() overload?

Hi. I don't think I should open an issue because of this because maybe I'm doing something wrong. But i have a small confusion with Many To Many Relationships. I set everything up according to the documentation and then I had to delete Many To Many relationships. I found it in the documentation and there is an example.

// Detach a single role from the user...
user->roles()->detach(roleId);

// Detach all roles from the user...
user->roles()->detach();

But when I tried to make the same in my code

int32_t song_id = std::stoi(pkeysData[1]);
	artist->songs()->detach(song_id);

The wrong overload of detach function is called. I started debugging and this function was called

template<class Model, class Related, class PivotType>
int
InteractsWithPivotTable<Model, Related, PivotType>::detach(const bool touch) const
{
    return detach(true, {}, touch);
}

So I provided a second argument

artist->songs()->detach(song_id, false);

and then a correct overload of function was called

    template<class Model, class Related, class PivotType>
    int InteractsWithPivotTable<Model, Related, PivotType>::detach(
            const QVariant &id, const bool touch) const
    {
        return detach(QVector<QVariant> {id}, touch);
    }

I'm wondering if I'm doing something wrong or if it's a bug in the documentation? By @SkaLe3

VCPKG upstream integration

microsoft/vcpkg#31087 is requesting to integrate tinyorm into upstream vcpkg's centralized ports repository.

I have prepared a vcpkg fork which contains a tinyorm port deriving from the overlay port that is part of TinyORM as well as a TinyORM consumer project that uses the tinyorm package generated with the vcpkg fork. It can run the simplistic test on all primary supported vcpkg platforms other then Mac OS X using GitHub hosted runners.

The patches applied address

Further, I modified the microsoft CI ruleset to assert Mac OS X builds fail ( #28 ). However I'm not sure what to do about the other targets blacklisted in vcpkg.json:9 (which is copy-pasted from the manifest variant's same line). Are these platforms known not to work, or just untested?

Aggressive "warnings" flags exported by the TinyOrm::TinyOrm target

Hi

Currently, the TinyOrm::TinyOrm target is populated with properties that are transcended to consuming targets by code in cmake/CommonModules/TinyCommon.cmake.

Most of those properties seem to be "cosmetic" i.e. not affecting the ABI. Transcending -Werror to consumers, however, is almost guaranteed to break things, as is the transcendance of the QT API Macros.

I take it that these compiler options are supposed to emit diagnostics when TinyOrm is being compiled. However, the INTERFACE mode of cmake's target properties causes these flags to be propagated to all consumers of the TinyOrm::TinyOrm target instead of being used by TinyOrm::TinyOrm itself ( https://cmake.org/cmake/help/v3.27/manual/cmake-buildsystem.7.html#transitive-usage-requirements ). Most of those flags should likely be PRIVATE, i.e. not transcend to consumers at all, with the exception of the c++20 standard requirement, which should be PUBLIC as tiny uses c++20 itself and also passes stl datatypes / exceptions through the DLL interface, i.e. requires consumers also to use c++20 .

To excemplify the problem

main.cpp

int main() {
    return 7.5;
}

doesn't even use TinyOrm, however associating it to TinyOrm via

CMakeLists.txt

cmake_minimum_required(VERSION 3.24)

project(MyProject CXX)

find_package(TinyOrm CONFIG REQUIRED)

add_executable(MyTestApplication)
target_sources(MyTestApplication PRIVATE main.cpp)
target_link_libraries(MyTestApplication PRIVATE TinyOrm::TinyOrm)

will cause TinyOrm::TinyOrm's -Werror transcedence to break the compilation as the diagnostic about 7.5 not being an int in the return statement is turned into an error:

[ 50%] Building CXX object CMakeFiles/MyTestApplication.dir/main.cpp.o
/tmp/main.cpp:2:16: fatal error: implicit conversion from 'double' to 'int' changes value from 7.5 to 7 [-Wliteral-conversion]
        return 7.5;
        ~~~~~~ ^~~
1 error generated.

VCPKG misplaces debug target export file

VCPKG uses cmake/vcpkg/ports/tinyorm/cmake/tiny_cmake_config_fixup.cmake to "move" the debug target file into another directory.

Assuming the ${TinyOrm_ns} is the subdirectory containing targets, the release file will also be in ${TinyOrm_ns} rather then ${PORT}, unless ${PORT} happens to be identical to ${TinyOrm_ns}, but even then only one of those names should be used for simplicity.

${PORT} will expand to tinyorm, while ${TinyOrm_ns} expands to TinyOrm. On filesystems that support uppercase characters to be differenciated from lowercase characters (or any other variations), this causes the debug target export file to reside in a different path then the release export file:

vcpkg/packages/tinyorm_x64-linux/share/cmake
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm/TinyOrmTargets.cmake
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm/Modules
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm/Modules/TinyPackageConfigHelpers.cmake
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm/TinyOrmConfig.cmake
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm/TinyOrmConfigVersion.cmake
vcpkg/packages/tinyorm_x64-linux/share/cmake/TinyOrm/TinyOrmTargets-release.cmake
vcpkg/packages/tinyorm_x64-linux/share/cmake/tinyorm
vcpkg/packages/tinyorm_x64-linux/share/cmake/tinyorm/TinyOrmTargets-debug.cmake

DB::beginTransaction assert()-ing

Currently, TinyORM is asserting no other transaction on the same connection is in partially commited state when beginTransaction is invoked.

However, the Q_ASSERT statements are disabled when QT_NO_DEBUG is defined during compilation, i.e. when compiling in release mode. If TinyORM needs it's consumers to explicit distinction between top level transactions and truely nested transactions / savepoints, exceptions provide a more reliable error handling mechanism then assertions do

Column and Table alias assigning

For non-trivial queries, it is often advantageous - if not required - to be able to assign aliases.

While TinyORM does not explicitly mention supporting alias assignments, the first example in the Select Statement Documentation, namely

auto users = DB::table("users")
	->select({"name", "email as user_email"})
	.get();

hints the email column is to be assigned the user_email alias, as the statement could be imagined to become something like

SELECT name, email as user_email FROM "users"

However, TinyORM escapes the column specifiers that were passed through the initializer list, resulting in

SELECT "name", "email as user_email" FROM "users"

being generated, which selects the name along with echo-ing the escaped string constant provided in the second argument.

This Test executes the line that is provided in the Select Statement Documentation , then iterates the returned query result to emit this diagnostic indicating SQLite is echo-ing the SELECT parameter rather then assigning a column alias.

While cosmetic in trivial select statements like the one in the example, the ability to assign aliases in JOIN queries is crucial. For example, a user might "follow" other users, which could be implemented using a transitioning table storing follows and followers in twitter-speak, identifying a user's followers with a statement like

SELECT follower.name, follow.name FROM users AS follower JOIN follow_relationship ON follow_relationship.follower_id=follower.id JOIN users AS follow ON follow_relationship.id=follow.id

where the alias assignments are non-optional, as the follow and the followers are both users and need to be distinguished by using their aliases. However, as TinyORM escapes the string, it will cause an invalid SQL query if an "alias assignment" is used in a select query to a join expression.

I don't think "pasting" sql code into a column or table specifier is a scalable solution in case it was intentional. Instead, TinyORM should provide an API to specify aliases in a safe and backend independent way.

compilation error in interactswithio.cpp

I wanted to give TinyORM a go but I got this error while compiling master branch:

tom/src/tom/concerns/interactswithio.cpp line 276

cannot convert const TableRow ..................... to const Row_t&

Here's the full cmake log:

[ 88%] Building CXX object CMakeFiles/TinyOrm.dir/tom/src/tom/concerns/guesscommandname.cpp.o
[ 89%] Building CXX object CMakeFiles/TinyOrm.dir/tom/src/tom/concerns/interactswithio.cpp.o
/home/nurettin/code/qt_test/TinyORM/tom/src/tom/concerns/interactswithio.cpp: In member function ‘const Tom::Concerns::InteractsWithIO& Tom::Concerns::InteractsWithIO::table(const TableRow&, const std::vector<std::vector<std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const char*, tabulate::Table> > >&, Tom::Concerns::InteractsWithIO::Verbosity) const’:
/home/nurettin/code/qt_test/TinyORM/tom/src/tom/concerns/interactswithio.cpp:276:19: error: cannot convert ‘const TableRow’ {aka ‘const std::vector<std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const char*, tabulate::Table> >’} to ‘const Row_t&’ {aka ‘const std::vector<std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const char*, std::basic_string_view<char, std::char_traits<char> >, tabulate::Table> >&’}
  276 |     table.add_row(headers);
      |                   ^~~~~~~
      |                   |
      |                   const TableRow {aka const std::vector<std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const char*, tabulate::Table> >}
compilation terminated due to -Wfatal-errors.
make[2]: *** [CMakeFiles/TinyOrm.dir/build.make:1709: CMakeFiles/TinyOrm.dir/tom/src/tom/concerns/interactswithio.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/TinyOrm.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Tag the releases

Hi

Git supports tagging commits in order to give them "human readable" labels (rather then sha256) which can be checked out like the commit hashes, but since only a few commits are "release" commits, the number of tags is quite limited compared to the number of commits.

Tagging the commits also enables git describe, which can be used to annotate documentation by the commit it relates to, to do a "better" job.

Further, GitHub will enable quickly looking up tagged commits by listing the tags next to the branches in the code overview and in the branch selection dropdown. While a tag isn't a release, in projects that have no formal releases, tags will be shown on the code overview's "Releases" tab.

image

Currently TinyORM, TinyORM has to push a commit to bump the Changelog (e.g. dddc80c), and then add the commit hash that is generated only when this commit is done into vcpkg's port (e.g. bc58b56). Tagging the commit that finishes the release phase will enable quickly reverting/forwaring rather then having to look up the git commit history to find commits increasing the tinyorm version, then looking "behind" the commits to find the commit that concludes the release.

Also, once pushed, git tags can be turned into GitHub Releases within a few clicks only.

Most users will only want to use "released" code, so the tags / releases will help them identify whether there is a new release available in case vcpkg isn't used (e.g. by submodule-ing TinyORM into the consumer repository and add_subdirectory-ing it in order to integrate it into the consumers' build process, or by checking it out elsewhere and manually installing it).

Support for Mac OS X, *BSD, and other libc++ environment

libc++ has started supporting the <ranges> library of c++20, which TinyORM uses, in libc++-13, which is part of llvm-13.

Although libc++-13 has <ranges>, the implementation is incomplete and therefore disabled by default. The incomplete implementation can be enabled by passing the -fexperimental-library option to clang.

While <ranges> support is still incomplete in libc++-15, it is sufficient to build TinyORM's querybuilder and run the querybuilder's test cases w/o detecting flaws.

llvm-16's libc++ has full ranges support, and the -fexperimental-library option is no longer required. All of TinyORM can be built and tests run w/o detecting flaws on libc++-16 (TinyORM d98ee5c on FreeBSD edd0014)

On libc++ systems, the _LIBCPP_VERSION macro can be used to investigate the libc++ version being used, which is not required to be the same as the compiler's and will default to the Operating System's one if a compiler was manually installed. As TinyORM's dependencies link against libc++, care needs to be taken the dependencies use the same libc++ or a compatible version to the one used by TinyORM, making it unfeasible to attempt using a custom libc++ with operating system provided dependencies.

At this point, GitHub offers no hosted runners that are capable of building TinyORM using libc++.

This issue will likely resolve on its' own as Operating Systems update their libc++ in their future releases.

Compilation Error

/home/abayomi/TinyORM/tom/src/tom/commands/migrations/statuscommand.cpp: In lambda function:
/home/abayomi/TinyORM/tom/src/tom/commands/migrations/statuscommand.cpp:78:22: error: cannot convert ‘’ to ‘const TableRow&’ {aka ‘const std::vector<std::vector<std::variant<std::__cxx11::basic_string<char, std::char_traits, std::allocator >, const char*, std::basic_string_view<char, std::char_traits >, tabulate::Table> > >&’}
78 | table({"Ran?", "Migration", "Batch"}, migrations);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
make[2]: *** [CMakeFiles/TinyOrm.dir/build.make:1613: CMakeFiles/TinyOrm.dir/tom/src/tom/commands/migrations/statuscommand.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:84: CMakeFiles/TinyOrm.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

I run into the error above while compiling TinyORM on my Ubuntu 22.04 machine.
I pull the code from the repo with:
git clone https://github.com/silverqx/TinyORM.git
then i cd into the project directory
cd TinyORM
then I made and cd into buidl directory
mkdir build && cd build
I ran the cmake command which was successful i.e. it did not return any error
cmake ..
After which I then ran the make command
make
And I got the error above at exactly 85%

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.