sqlite3 c++ client选择; c++环境搭建 : abseil-cpp | fnc12/sqlite_orm
sqlite3 c++ client选择
今日20250305
- 2.4K星: 7月前最后提交核心: SRombauts/SQLiteCpp.git : 薄封装、命令式sql、非orm、支持事务
- 2.4K星: 1月前最后提交核心: fnc12/sqlite_orm.git : 厚封装、非侵入、真orm、真泛型、类型复杂、支持事务、报错信息不完整(启动事务失败,断点调试大致是 一个空表的unique约束失败,但这不该失败)
因真泛型导致DbInstance必须放在x.h中,否则无法引出DbInstance的类型, 若x.h被多方包含而总链接过程可能诱发重复函数报错
(笨办法是 将auto类型 打印出来 而手工填回x.h内,从而改造为 x.h和x.cpp配合的正常形式,避免总链接重复函数报错)
因真泛型导致类型复杂而必须大量使用auto - 0.9K星: 3年前最后提交核心: SqliteModernCpp/sqlite_modern_cpp.git: 薄封装、sql+流操作符、非orm、支持事务
- 0.7星: 7年前最后提交核心: paulftw/hiberlite.git : 厚封装、宏侵入、半orm、类型简单、未见事务
- 0.6星: 7年前最后提交核心: iwongu/sqlite3pp.git : 薄封装、命令式sql、字段名绑定、类型简单、支持事务
fnc12/sqlite_orm.git
将auto类型 打印出来 而手工填回x.h内,从而改造为 x.h和x.cpp配合的正常形式,避免总链接重复函数报错
//{c++复杂类型文本打印 开始
//注意模板实例必须让编译器看到
#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
template <typename T>
void CxxPrintType( const T& value) {
int status = 0;
char* demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status);
if (status == 0) {
std::cout << "类型Sqlite3Db:【 " << demangled << "】" << std::endl;
free(demangled); // 必须手动释放内存
} else {
std::cout << "Failed_to_demangle_name." << std::endl;
}
}
//c++复杂类型文本打印 结束}
std::string db_path = "/tmp/insert.sqlite3.db";
using namespace sqlite_orm;
auto tb_TypeDef= make_table("tb_TypeDef",
make_column("typeId", &TbTypeDef::typeId, primary_key().autoincrement()),
make_column("typeName", &TbTypeDef::typeName,unique()),
make_column("category", &TbTypeDef::category)
);
auto tb_TypeDefLoc= make_table("tb_TypeDefLoc",...);
auto tb_StructDef= make_table("tb_StructDef",...);
auto tb_UnionDef= make_table("tb_UnionDef",...);
auto tb_ClassDef= make_table("tb_ClassDef",...);
auto db = make_storage(db_path, tb_TypeDef,tb_TypeDefLoc,tb_StructDef,tb_UnionDef,tb_ClassDef );
CxxPrintType( db); // 类型Sqlite3DbType由此行打印出来, 打印结果 作为 手工放到 宏 Sqlite3DbType 右边
#define Sqlite3DbType sqlite_orm::internal::storage_t<sqlite_orm::internal::table_t<TbTypeDef, false, sqlite_orm::internal::column_t<int TbTypeDef::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::primary_key_with_autoincrement<sqlite_orm::internal::primary_key_t<> > >, sqlite_orm::internal::column_t<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > TbTypeDef::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::unique_t<> >, sqlite_orm::internal::column_t<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > TbTypeDef::*, sqlite_orm::internal::empty_setter> >, sqlite_orm::internal::table_t<TbTypeDefLoc, false, sqlite_orm::internal::column_t<int TbTypeDefLoc::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::unique_t<> >, sqlite_orm::internal::column_t<int TbTypeDefLoc::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::unique_t<> >, sqlite_orm::internal::column_t<int TbTypeDefLoc::*, sqlite_orm::internal::empty_setter>, sqlite_orm::internal::column_t<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > TbTypeDefLoc::*, sqlite_orm::internal::empty_setter> >, sqlite_orm::internal::table_t<TbStructDef, false, sqlite_orm::internal::column_t<int TbStructDef::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::unique_t<> > >, sqlite_orm::internal::table_t<TbUnionDef, false, sqlite_orm::internal::column_t<int TbUnionDef::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::unique_t<> > >, sqlite_orm::internal::table_t<TbClassDef, false, sqlite_orm::internal::column_t<int TbClassDef::*, sqlite_orm::internal::empty_setter, sqlite_orm::internal::unique_t<> > > >
fnc12/sqlite_orm
问题:fnc12/sqlite_orm.git理想情况下需要将DbConn放在x.h中,可能导致链接时有重复函数
优势:真泛型、真orm
参考 README.md#installation
编译步骤
#ubuntu22.04
#source /app/bash-simplify/gitproxy.sh && gitproxy_set
git config --global http.proxy socks5://westgw:7890 ;
git config --global https.proxy socks5://westgw:7890 ;
git --no-pager config --list | grep proxy
#http.proxy=socks5://westgw:7890
#https.proxy=socks5://westgw:7890
sudo apt install -y libsqlite3-dev
repoD=/app3/sqlite_orm__fnc12
bldD=${repoD}__build
installD=${repoD}__install
repoUrl=https://github.com/fnc12/sqlite_orm.git
repoTag=v1.9.1
git clone -b $repoTag $repoUrl $repoD
#展开:git clone -b v1.9.1 https://github.com/fnc12/sqlite_orm.git /app3/sqlite_orm__fnc12
cmake -S $repoD -B $bldD -DCMAKE_INSTALL_PREFIX=$installD
#展开: cmake -S /app3/sqlite_orm__fnc12 -B /app3/sqlite_orm__fnc12__build -DCMAKE_INSTALL_PREFIX=/app3/sqlite_orm__fnc12__install
#列出目标
cmake --build $bldD --target help | grep -i build
#... rebuild_cache
#... ContinuousBuild
#... ExperimentalBuild
#... NightlyBuild
cmake --build $bldD --target install -j 4
#展开: cmake --build /app3/sqlite_orm__fnc12__build --target install -j 4
ls $bldD/cmake_install.cmake #安装脚本
#(展开):安装脚本为: /app3/sqlite_orm__fnc12__build/cmake_install.cmake
#安装目录 CMAKE_INSTALL_PREFIX 写在此 安装脚本 cmake_install.cmake 内
编译产物
( cd $installD ; find . -type f )
#展开: cd /app3/sqlite_orm__fnc12__install ; find . -type f
/app3/sqlite_orm__fnc12__install/
目录下为编译产物
./include/sqlite_orm/sqlite_orm.h
./lib/cmake/SqliteOrm/SqliteOrmConfig.cmake
./lib/cmake/SqliteOrm/SqliteOrmConfigVersion.cmake
./lib/cmake/SqliteOrm/SqliteOrmTargets.cmake
报错记录
1. 需要libsqlite3-dev
cmake -S /app3/sqlite_orm__fnc12 -B /app3/sqlite_orm__fnc12__build
:报错:
CMake Error at /usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
Could NOT find SQLite3 (missing: SQLite3_INCLUDE_DIR SQLite3_LIBRARY)
Call Stack (most recent call first):
/usr/share/cmake-3.22/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
/usr/share/cmake-3.22/Modules/FindSQLite3.cmake:54 (find_package_handle_standard_args)
dependencies/CMakeLists.txt:28 (find_package)
解决: sudo apt install -y libsqlite3-dev
abseil-cpp
参考: https://abseil.io/docs/cpp/quickstart-cmake
abseil-cpp.git/dd4c89b == abseil-cpp.git/20240722.1
1. clone代码仓库、编译
git clone https://github.com/abseil/abseil-cpp.git /app/abseil-cpp/
#/app/abseil-cpp/.git/config
git checkout 20240722.1
git rev-parse HEAD
#dd4c89bd657f1e247ce5111a5c89ffe6ccfd0c92
cmake -S /app/abseil-cpp -B /app/abseil-cpp/build -DABSL_BUILD_TESTING=OFF -DABSL_USE_GOOGLETEST_HEAD=ON -DCMAKE_CXX_STANDARD=14
cmake --build /app/abseil-cpp/build --target all
ls /app/abseil-cpp/absl/strings/str_split.h
2. test.cpp
#include <string>
#include <vector>
#include "absl/strings/str_split.h"
#include <stdio.h>
int main(int argc, char** argv){
std::vector<std::string> v = absl::StrSplit("a,b,c", ',');
printf("v[0]=%s\n",v[0].c_str());
return 0;
}
3. 编译运行
/app/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4/bin/clang++ -v -L /app/abseil-cpp/build/absl/base/ -L /app/abseil-cpp/build/absl/strings/ -l absl_base -l absl_raw_logging_internal -l absl_throw_delegate -l absl_string_view -l absl_strings_internal -l absl_strings -I /app/abseil-cpp/ test.cpp -o test.elf && ./test.elf
正常运行,并输出a
3A. 当少给 .a时 链接报错举例
/app/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4/bin/clang++ -v -L /app/abseil-cpp/build/absl/base/ -L /app/abseil-cpp/build/absl/strings/ -L /app/abseil-cpp/build/absl/log/ -l absl_base -l absl_log_internal_format -l absl_string_view -l absl_strings_internal -l absl_strings -I /app/abseil-cpp/ test.cpp -o test.elf && ./test.elf
报错
"/usr/bin/ld" -pie -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test.elf /lib/x86_64-linux-gnu/Scrt1.o /lib/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/app/abseil-cpp/build/absl/base/ -L/app/abseil-cpp/build/absl/strings/ -L/app/abseil-cpp/build/absl/log/ -L/app/llvm_release_home/clang+llvm-15.0.0-x86_64-linux-gnu-rhel-8.4/bin/../lib/x86_64-unknown-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/12 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib/../lib64 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/lib -L/lib -L/usr/lib -labsl_base -labsl_log_internal_format -labsl_string_view -labsl_strings_internal -labsl_strings /tmp/test-9d0c36.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/12/crtendS.o /lib/x86_64-linux-gnu/crtn.o
mold: error: undefined symbol: /app/abseil-cpp/build/absl/strings/libabsl_strings.a(str_split.cc.o): absl::lts_20240722::raw_log_internal::RawLog(absl::lts_20240722::LogSeverity, char const*, int, char const*, ...)
mold: error: undefined symbol: /app/abseil-cpp/build/absl/strings/libabsl_strings.a(str_split.cc.o): absl::lts_20240722::base_internal::ThrowStdOutOfRange(char const*)
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
3B. 报错探索并解决: nushell 在*.a中查找给定函数所在.a
nushell
== /app5/nu-0.102.0-x86_64-unknown-linux-gnu/nu
3A报错缺少函数
absl::lts_20240722::raw_log_internal::RawLog
absl::lts_20240722::base_internal::ThrowStdOutOfRange
以下用nushell查找这些函数所在.a
/usr/bin/find /app/abseil-cpp/build/absl/ -name "*.a" | lines|each { |f| nm --defined-only -C $f } | str contains "absl::lts_20240722::base_internal::ThrowStdOutOfRange" | /usr/bin/grep true
# │ 8 │ true │
/usr/bin/find /app/abseil-cpp/build/absl/ -name "*.a" | lines|each { |f| $f } | /usr/bin/grep " 8 "
#│ 8 │ /app/abseil-cpp/build/absl/base/libabsl_throw_delegate.a │
/usr/bin/find /app/abseil-cpp/build/absl/ -name "*.a" | lines|each { |f| nm --defined-only -C $f } | str contains "absl::lts_20240722::raw_log_internal::RawLog" | /usr/bin/grep true
# │ 4 │ true │
/usr/bin/find /app/abseil-cpp/build/absl/ -name "*.a" | lines|each { |f| $f } | /usr/bin/grep " 4 "
# │ 4 │ /app/abseil-cpp/build/absl/base/libabsl_raw_logging_internal.a │