C++ DBI 类 - 最佳/开发人员最友好的风格

发布于 2024-11-18 12:06:09 字数 905 浏览 3 评论 0原文

在我们当前的项目中,我们需要一些针对不同数据库的高级 DBI。它应该提供以下功能:

  • 内存缓存 - DBI 应该能够缓存所有读取,并在写入调用时更新缓存(我们正在编码的应用程序是重线程的,需要快速访问)始终为当前数据)。内存缓存将基于 boost::multi_index
  • 自动 sql 构建 - 我们不想解析 sql 语句以在内存缓存中查找,

因为我们需要提供功能:定义表布局,执行选择,执行插入,执行更新,连接,...,界面将变得非常复杂。

我们需要一个好的方法来调用接口函数。

周围有很多样式,但我们找不到任何对我们的使用有用的样式。

这里有几个例子:

SOCI

sql << "select name, salary from persons where id = " << id, into(name), into(salary);

我们不需要一些 SQL 语句,因此我们必须以不同的方式定义 whatfrom

pqxx

Conn.prepare("select_salary",
    "select name, salary from persons where id = $1")
    ((string)"integer",prepare::treat_direct);

重载的 operator() 的大量使用很丑陋,但它也对我们有用。

对于如何设计界面有什么建议吗?

In our current project, we need some high level DBI for different databases. It should provide the following features:

  • in memory cache - the DBI should be able to cache all reads, and update the cache on writing calls (the application we are coding on is heavy threaded, and needs fast access to the current data all the time). The memory cache will be based on boost::multi_index
  • automatic sql building - We don't want to parse a sql statement to lookup in the memory cache

As we need to provide functions for: defining a table layout, do selects, do inserts, do updates, joins, ..., the interface will get very complex.

We need a good way to invoke the interface function.

There are many styles around, but we could not find any useful for our usage.

Here a few examples:

SOCI

sql << "select name, salary from persons where id = " << id, into(name), into(salary);

We don't want some SQL statements, so we would have to define what and from a different way.

pqxx

Conn.prepare("select_salary",
    "select name, salary from persons where id = $1")
    ((string)"integer",prepare::treat_direct);

The heavy usage of the overloaded operator() is just ugly, but it could work for us too.

Any suggestions how to design the interface?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一直在等你来 2024-11-25 12:06:09

使用对象关系映射怎么样?以下是我脑海中浮现出的一些代码片段想法 - 我只在 Python 中完成过此操作,从未在 C++ 中完成过,并且仅针对相当简单的数据库。维基百科上有一个框架列表,应该避免太多轮子相关研发。

class people: public dbi_table
{
    // id column handled by dbi_table.
    name: string_column;
    salary: money_column;
};

class cost_center: public dbi_table
{
    name: string_column;
    office: foreign_key<offices>;
};

class people_cost_center_link: public link_table
{
    // Many-many relationships.
};

然后您可以将记录作为对象进行操作,所有关系内容都由框架处理。查询是通过定义查询对象然后获取结果的迭代器来完成的(请参阅 ODB 维基百科页面 的代码示例)。

How about using object relational mapping? Here's some code fragment ideas off the top of my head - I've only done this in Python, never in C++, and only for fairly simple databases. There's a list of frameworks on Wikipedia that should avoid too much wheel-related R&D.

class people: public dbi_table
{
    // id column handled by dbi_table.
    name: string_column;
    salary: money_column;
};

class cost_center: public dbi_table
{
    name: string_column;
    office: foreign_key<offices>;
};

class people_cost_center_link: public link_table
{
    // Many-many relationships.
};

Then you can manipulate records as objects, all the relational stuff is handled by the framework. Querying is done by defining a query object and then getting an iterator to the results (see the ODB wikipedia page for a code example).

半寸时光 2024-11-25 12:06:09

我会这样做(从 C++ 的角度来看,这会很好,不知道它是否是正确的数据库内容):

struct Handle { int id; }
class DBI 
{
public:
   virtual Handle select(int column_id)=0;
   virtual Handle select(int column1, int column2)=0;
   virtual Handle id(int id)=0;
   virtual Handle join(Handle i1, Handle i2)=0;
   virtual void execute_query(Handle i)=0;
};

通常这些函数会像这样实现:

Handle select(int column_id) {
   return new_handle(new SelectNode(column_id));
}

其中 new_handle 函数只会将 SelectNode 插入到 std::vector 或 std ::映射并为其创建一个句柄。

I would do it like this (and it'd be good in c++ point of view, dunno if it's correct database stuff):

struct Handle { int id; }
class DBI 
{
public:
   virtual Handle select(int column_id)=0;
   virtual Handle select(int column1, int column2)=0;
   virtual Handle id(int id)=0;
   virtual Handle join(Handle i1, Handle i2)=0;
   virtual void execute_query(Handle i)=0;
};

Usually these functions would be implemented like this:

Handle select(int column_id) {
   return new_handle(new SelectNode(column_id));
}

where new_handle function would just insert SelectNode to std::vector or std::map and create an handle for it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文