找回密码
 立即注册
搜索
查看: 50|回复: 4

C++ Web 开发框架 Paozhu 发布 1.16.0,添加 PostgreSQL SQLite 支持

[复制链接]

主题

0

回帖

0

积分

积分
0
发表于 3 天前 | 显示全部楼层 |阅读模式
C++ web开发框架 paozhu 发布1.16.0发布,ORM添加PostgreSQL SQLite支持,纯自研客户端。PostgreSQL客户端框架来自MySQL成熟流程架构,支持socket,ssl,unix.sock三种模式
业务代码无缝在三个数据库切换,同时支持同步、异步(协程)模式。
Paozhu ORM 目前支持MySQL MariaDB PostgreSQL SQLite 四种数据库,同时支持同步和C++20标准协程,支持文本模式和预编译语句(Prepared Statements)模式。
整个项目无需使用官方客户端,而且稳定支持协程。

• 采用自研数据库连接协议,支持 MySQL PostgreSQL 和 SQLite,无需额外安装 MySQL Connector/C++ 或 libpq
• 支持 MySQL 8.0.4 以上版本(支持 caching_sha2_password 认证插件)
• 支持 MariaDB 12.1+(12.1 版本开始支持 caching_sha2_password 认证插件,与 MySQL 8.0 默认认证方式兼容)
• 自研协议同时支持 C++20 协程(异步)同步两种调用方式,可在同一项目中混用
• 使用 CLI 工具在数据库类型之间迁移数据(如 MySQL/CMS 迁移到 PostgreSQL),目标库的表会被自动创建:数据库之间迁移( MySQL <=> PostgreSQL <=> SQLite)

  1. # 从 cms 迁移到 pg (cms是mysql标签,pg是PostgreSQL配置标签)
  2. ./bin/paozhu_cli dbconver cms pg
复制代码





自动支持foreign keys 外键关系,支持one many模式。

  1. //@urlpath(null,test_ormfk_one)
  2. std::string test_ormfk_one(std::shared_ptr<httppeer> peer)
  3. {
  4.     httppeer &client = peer->get_peer();

  5.     auto child = orm::FkChild();
  6.     child.where(orm::fk_child_info::cols::id, 1);
  7.     child.fetch_one();
  8.     client << "<p>child id:" << child.data.id << " parent_id:" << child.data.parent_id << "</p>";

  9.     // outgoing: fk_child.parent_id -> fk_parent.id, scoped by current row data
  10.     auto parent = child.oneFkParent();
  11.     parent.fetch_one();
  12.     client << "<p>oneFkParent sql:" << parent.sqlstring << "</p>";
  13.     client << "<p>oneFkParent name:" << parent.data.name << "</p>";

  14.     // explicit id overload
  15.     auto parent2 = child.oneFkParent(2);
  16.     parent2.fetch_one();
  17.     client << "<p>oneFkParent(2) name:" << parent2.data.name << "</p>";

  18.     // overload that decorates an existing model, so extra conditions still chain
  19.     auto decorated = orm::FkParent();
  20.     child.oneFkParent(decorated);
  21.     decorated.select("id,name");
  22.     decorated.fetch_one();
  23.     client << "<p>oneFkParent(obj&) sql:" << decorated.sqlstring << "</p>";
  24.     return "";
  25. }
复制代码

多对多模式

  1. //@urlpath(null,test_ormfk_many)
  2. std::string test_ormfk_many(std::shared_ptr<httppeer> peer)
  3. {
  4.     httppeer &client = peer->get_peer();

  5.     auto parents = orm::FkParent();
  6.     parents.fetch();
  7.     client << "<p>parents:" << parents.record.size() << "</p>";

  8.     // incoming: fk_child.parent_id -> fk_parent.id, scoped by every id in record
  9.     auto children = parents.manyFkChild();
  10.     children.fetch();
  11.     client << "<p>manyFkChild sql:" << children.sqlstring << "</p>";
  12.     client << "<p>manyFkChild rows:" << children.record.size() << "</p>";

  13.     // group in memory to avoid the N+1 round trip
  14.     std::vector<int> child_count;
  15.     for (auto &p : parents.record)
  16.     {
  17.         int n = 0;
  18.         for (auto &c : children.record)
  19.         {
  20.             if (c.parent_id == p.id)
  21.             {
  22.                 n++;
  23.             }
  24.         }
  25.         child_count.emplace_back(n);
  26.     }
  27.     for (size_t i = 0; i < parents.record.size(); i++)
  28.     {
  29.         client << "<p>parent " << parents.record&#91;i&#93;.id << " name:" << parents.record&#91;i&#93;.name
  30.                << " children:" << child_count&#91;i&#93; << "</p>";
  31.     }

  32.     auto decorated = orm::FkChild();
  33.     parents.manyFkChild(decorated);
  34.     decorated.where(orm::fk_child_info::cols::extra, orm::wq::nq, "");
  35.     decorated.fetch();
  36.     client << "<p>manyFkChild(obj&) sql:" << decorated.sqlstring << "</p>";
  37.     return "";
  38. }
复制代码

预处理模式,有exec_标志

  1. namespace orm::cust
  2. {
  3.     struct WorldRowStruct : orm::Base<WorldRowStruct>
  4.     {
  5.         unsigned int id;
  6.         int randomnumber;
  7.         ORM_NAMES(id, randomnumber);
  8.     };
  9. }// namespace orm::cust

  10. namespace http
  11. {
  12. //@urlpath(null,test_ormprepared_exec)
  13. std::string test_ormprepared_exec(std::shared_ptr<httppeer> peer)
  14. {
  15.     httppeer &client = peer->get_peer();

  16.     auto world = orm::World();
  17.     world.AND("id", orm::wq::be, 1)
  18.          .AND("id", orm::wq::le, 200)
  19.          .orsub()
  20.          .AND("randomnumber", orm::wq::bt, 5000)
  21.          .OR("randomnumber", orm::wq::lt, 200)
  22.          .endsub();

  23.     unsigned int total = world.exec_count();
  24.     client << "<p>count:" << total << "</p>";

  25.     world.select("id,randomnumber");
  26.     std::vector<orm::cust::WorldRowStruct> rows;
  27.     world.exec_fetch_to(rows);

  28.     client << "<p>" << world.sqlstring << "</p>";
  29.     client << "<p>fetched:" << rows.size() << " error:" << world.error_msg << "</p>";
  30.     for (auto &row : rows)
  31.     {
  32.         client << "<p>" << row.to_json() << "</p>";
  33.     }
  34.     return "";
  35. }
  36. }
复制代码

预编译路径(值作为参数绑定)—— 每个 exec_ 方法都有一个签名与返回值完全 一致的 async_exec_ 版本:


同步方法         异步方法

exec_count()         async_exec_count()

exec_page()         async_exec_page()

exec_fetch()         async_exec_fetch()

exec_fetch_to(rows)         async_exec_fetch_to(rows)

exec_fetch_append()         async_exec_fetch_append()

exec_one()         async_exec_one()

exec_one_to(rec)         async_exec_one_to(rec)

exec_one_append(vec)         async_exec_one_append(vec)

exec_insert()         async_exec_insert()

exec_insert_batch()         async_exec_insert_batch()

exec_update()         async_exec_update()

exec_update_dirty()         async_exec_update_dirty()

exec_update_col()         async_exec_update_col()

exec_replace_col()         async_exec_replace_col()

exec_remove()         async_exec_remove()


新加入脏检查
exec_update_dirty() async_exec_update_dirty() 自动更新需要更新的字段

文本路径(值被转义进语句):


同步方         异步方法         说明

fetch()         async_fetch()         查询所有匹配记录

fetch_one()         async_fetch_one()         查询单条记录

fetch_append()         async_fetch_append()         查询并追加到现有结果集

count()         async_count()         统计匹配记录数

save()         async_save()         新增记录

update()         async_update()         更新记录

update_dirty()

         async_update_dirty()

         只更新经生成的逐字段 setter 写过的列

remove()         async_remove()         删除


官方地址
https://github.com/hggq/paozhu

原文链接

打赏作者

当前余额:0 Token,打赏后立即到账

主题

0

回帖

0

积分

积分
0
发表于 3 天前 | 显示全部楼层
学到了,Paozhu这块之前一直似懂非懂,看完这篇清晰多了。

主题

0

回帖

0

积分

积分
0
发表于 3 天前 | 显示全部楼层
支持一下,希望后面多写写Web相关的实战内容。

主题

0

回帖

0

积分

积分
0
发表于 3 天前 | 显示全部楼层
补充一点个人体会:Web这块不同场景下表现差异挺大的,选型还是要结合自己的业务。

主题

0

回帖

0

积分

积分
0
发表于 3 天前 | 显示全部楼层
整个项目无需使用官方客户端,而且稳定支持协程。
这段深有同感,C++确实是这样。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

{ template common/footer}