移动复制 and/or 分配一个 mongodb cxx 游标
move copy and/or assign a mongodb cxx cursor
我正在编写一系列 classes 环绕 mongodb-cxx classes 以使它们符合 API 的存储我的应用程序的其余部分是用 Qt 编写的。
我不需要Mongo的完整功能集,基本上只是CRUD:创建、读取、更新、删除和查找,也许还有一些更高级的参数传入(read/write 担忧等)。
我想在 mongocxx::cursor 周围创建一个包装器 class,这样可以迭代 find() 的结果 "later",存储 "later" 使用的数据格式 API。 "later" 我的意思是(包装的)游标被 returned 到一个抽象 class 可以迭代结果并根据模式验证数据,或者可以跳过条目,或者结果可以成组(异步)发送给最终客户端等
例如,如果我有:(为了这个例子,这被简化了一点)
using namespace mongocxx;
class QMongoClient
{
static instance _instance;
QMongoClient(QString url) : _client( uri( qPrintable(url) ) );
client _client;
QMongoDatabase operator[](QString d);
};
class QMongoDatabase
{
QMongoDatabase(database db) : _database(db);
database _database;
QMongoCollection operator [](QString c);
};
class QMongoCollection
{
QMongoCollection(collection c) : _collection(c);
collection _collection;
//create... same as insert()
//read... same as find_one()
//update... same as upsert() or update()
//delete...
//find... a query will be provided
QMongoCursor findAll() { cursor c = _collection.find({}); return QMongoCursor(c); };
};
class QMongoCursor
{
QMongoCursor(cursor c) : _cursor(c);
//copy/move/assign constructors needed, probably
cursor _cursor;
QString data(); //return document contents as JSON string, for instance
//begin() <-- iterator
//end() <-- iterator
};
我曾希望这种方法能奏效,而且它确实奏效了,直到出现游标,这会引发编译器错误:
error: call to implicitly-deleted copy constructor of 'mongocxx::v_noabi::cursor'
我的想法是做这样的事情:
QMongoClient client("mongodb://url...");
QMongoDatabase db = client["somedbname"];
QMongoCollection coll = db["somecollection"];
QMongoCursor c = coll.findAll();
//or more abbreviated:
QMongoCursor c = client["somedbname"]["somecollection"].findAll();
//iterate over c here as needed, or send it to another abstraction layer...
我认为这是因为 mongocxx::cursor 对象不应该被传递,当它们超出范围时它们就会被销毁。
例如,当 QMongoCursor::findAll() 完成时,returned 游标将被销毁,并且不能在 QMongoCursor 构造函数中复制。
findAll() 函数在那一刻检索所有文档并 return 它们(结果集的大小可能未知)似乎非常低效。例如,我希望能够一次检索 10 个结果,并通过网络将它们异步分组发送到最终客户端。
所以问题is/are:
- 如果游标在超出范围并且没有 copy/move 构造函数
时被销毁,我如何让游标保持活动状态
- 或者我如何创建一个指向游标的指针并知道它的寿命是多少以及何时删除它
- 我是否缺少另一种方法?我一直在查看文档,但没有找到它。
我想我缺少一些 C++ 语法或机制,比如移动分配或类似的东西。
有什么想法吗?
好吧,mongocxx::cursor
objects 是 可移动的,但您没有要求移动它,您是要一份副本。尝试:
QMongoCursor(cursor c) : _cursor(std::move(c));
您可能也想为您的 QDatabase 和 QCollection 构造函数执行此操作。
你还应该考虑的一件事是,如果你正在构建更高级别的工具包,你需要密切注意与 client
、database
、[=14= 相关的生命周期规则],以及 cursor
objects。您可能会发现构建类似 shared_ptr
的抽象以确保类型系统强制执行适当的生命周期对您的 usec-case.
是有利的
我们没有让 driver 那样工作,因为我们不想将这个决定强加于人。相反,我们认为它可以而且应该委托给更高级别的抽象,可能就像您正在构建的那样。
我正在编写一系列 classes 环绕 mongodb-cxx classes 以使它们符合 API 的存储我的应用程序的其余部分是用 Qt 编写的。
我不需要Mongo的完整功能集,基本上只是CRUD:创建、读取、更新、删除和查找,也许还有一些更高级的参数传入(read/write 担忧等)。
我想在 mongocxx::cursor 周围创建一个包装器 class,这样可以迭代 find() 的结果 "later",存储 "later" 使用的数据格式 API。 "later" 我的意思是(包装的)游标被 returned 到一个抽象 class 可以迭代结果并根据模式验证数据,或者可以跳过条目,或者结果可以成组(异步)发送给最终客户端等
例如,如果我有:(为了这个例子,这被简化了一点)
using namespace mongocxx;
class QMongoClient
{
static instance _instance;
QMongoClient(QString url) : _client( uri( qPrintable(url) ) );
client _client;
QMongoDatabase operator[](QString d);
};
class QMongoDatabase
{
QMongoDatabase(database db) : _database(db);
database _database;
QMongoCollection operator [](QString c);
};
class QMongoCollection
{
QMongoCollection(collection c) : _collection(c);
collection _collection;
//create... same as insert()
//read... same as find_one()
//update... same as upsert() or update()
//delete...
//find... a query will be provided
QMongoCursor findAll() { cursor c = _collection.find({}); return QMongoCursor(c); };
};
class QMongoCursor
{
QMongoCursor(cursor c) : _cursor(c);
//copy/move/assign constructors needed, probably
cursor _cursor;
QString data(); //return document contents as JSON string, for instance
//begin() <-- iterator
//end() <-- iterator
};
我曾希望这种方法能奏效,而且它确实奏效了,直到出现游标,这会引发编译器错误:
error: call to implicitly-deleted copy constructor of 'mongocxx::v_noabi::cursor'
我的想法是做这样的事情:
QMongoClient client("mongodb://url...");
QMongoDatabase db = client["somedbname"];
QMongoCollection coll = db["somecollection"];
QMongoCursor c = coll.findAll();
//or more abbreviated:
QMongoCursor c = client["somedbname"]["somecollection"].findAll();
//iterate over c here as needed, or send it to another abstraction layer...
我认为这是因为 mongocxx::cursor 对象不应该被传递,当它们超出范围时它们就会被销毁。
例如,当 QMongoCursor::findAll() 完成时,returned 游标将被销毁,并且不能在 QMongoCursor 构造函数中复制。
findAll() 函数在那一刻检索所有文档并 return 它们(结果集的大小可能未知)似乎非常低效。例如,我希望能够一次检索 10 个结果,并通过网络将它们异步分组发送到最终客户端。
所以问题is/are:
- 如果游标在超出范围并且没有 copy/move 构造函数 时被销毁,我如何让游标保持活动状态
- 或者我如何创建一个指向游标的指针并知道它的寿命是多少以及何时删除它
- 我是否缺少另一种方法?我一直在查看文档,但没有找到它。
我想我缺少一些 C++ 语法或机制,比如移动分配或类似的东西。
有什么想法吗?
好吧,mongocxx::cursor
objects 是 可移动的,但您没有要求移动它,您是要一份副本。尝试:
QMongoCursor(cursor c) : _cursor(std::move(c));
您可能也想为您的 QDatabase 和 QCollection 构造函数执行此操作。
你还应该考虑的一件事是,如果你正在构建更高级别的工具包,你需要密切注意与 client
、database
、[=14= 相关的生命周期规则],以及 cursor
objects。您可能会发现构建类似 shared_ptr
的抽象以确保类型系统强制执行适当的生命周期对您的 usec-case.
我们没有让 driver 那样工作,因为我们不想将这个决定强加于人。相反,我们认为它可以而且应该委托给更高级别的抽象,可能就像您正在构建的那样。