C ++ populate向量从sqlite3回调函数? [英] C++ populate vector from sqlite3 callback function?

查看:120
本文介绍了C ++ populate向量从sqlite3回调函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个sqlite3表地址像这样:

  + ---- + + -------- + 
| ID |名称|数字|
+ ---- + ------ + -------- +
| 1 | John | 413434 |
+ ---- + ------ + -------- +

而我想填充全局向量,我将能够使用别的地方,并与其他一些数据连接。
到目前为止,我有这个:

  ... 
#include< sqlite3.h>

using namespace std;

static int callbackDB(void * NotUsed,int argc,char ** argv,char ** szColName)
{
for(int i = 0; i cout<< szColName [i]< =<< argv [i]<< endl;

return 0;
}

int main(int argc,char * argv []){
vector< vector< string& >表;
for(int i = 0; i <2; i ++)
table.push_back(std :: vector< std :: string>());


sqlite3 * db;
char * szErrMsg = 0;

//打开数据库
int rc = sqlite3_open(database.db,& db);

const char * query;
query =SELECT * FROM addresses;

rc = sqlite3_exec(db,query,callbackDB,0,& szErrMsg);

return 0;
}

如何获得矢量或其他方式的结果,

解决方案

sqlite3_exec的第四个参数可以用来传递信息到回调。
在您的情况下,指向的指针将非常有用:

  typedef vector< vector< string> > table_type; 
static int callbackDB(void * ptr,int argc,char * argv [],char * cols [])
{
table_type * table = static_cast< table_type *>(ptr)
vector< string>行;
for(int i = 0; i row.push_back(argv [i]?argv [i]:(NULL)
table-> push_back(row);
return 0;
}
...
rc = sqlite3_exec(db,query,callbackDB,& table,& errmsg);但是,使用像这样的回调并不是非常有用,因为你只是一串裸体字符串。
您应该直接使用prepare / step / finalize接口,以便可以使用正确的数据类型:

 地址{
public:
Address(int id,const string& name,const string& number);
...
}

...
矢量<地址>地址;
sqlite3_stmt * stmt;
rc = sqlite3_prepare_v2(db,SELECT id,name,number FROM addresses,
-1,& stmt,NULL);
if(rc!= SQLITE_OK){
cerr<< SELECT failed:<< sqlite3_errmsg(db)< endl;
return ...; //或throw
}
while((rc = sqlite3_step(stmt))== SQLITE_ROW){
int id = sqlite3_column_int(stmt,0);
const char * name = reinterpret_cast< const char *>(sqlite3_column_text(stmt,1));
const char * number = reinterpret_cast< const char *>(sqlite3_column_text(stmt,2));
//让我们假设number可以为NULL:
addresses.push_back(Address(id,name,number?number:));
}
if(rc!= SQLITE_DONE){
cerr<< SELECT failed:<< sqlite3_errmsg(db)< endl;
//如果你返回/抛出这里,不要忘记finalize
}
sqlite3_finalize(stmt);


I have a sqlite3 table "addresses" like this:

+----+------+--------+
| ID | name | number |
+----+------+--------+
| 1  | John | 413434 |
+----+------+--------+

And i want to populate global vector, which i would be able to use somewhere else and join it with some other data. So far, i have this:

...
#include <sqlite3.h>

using namespace std;

static int callbackDB(void *NotUsed, int argc, char **argv, char **szColName)
{
    for(int i = 0; i < argc; i++)
        cout << szColName[i] << " = " << argv[i] << endl;

    return 0;
}

int main(int argc, char* argv[]) {
    vector<vector<string> > table;
    for( int i = 0; i < 2; i++ )
        table.push_back(std::vector< std::string >());


    sqlite3 *db;
    char *szErrMsg = 0;

    // open database
    int rc = sqlite3_open("database.db", &db);

    const char *query;
    query = "SELECT * FROM addresses";

    rc = sqlite3_exec(db, query, callbackDB, 0, &szErrMsg);

    return 0;
}

How could i get results in vector or in some other way so that i'll be able to use it easier?

解决方案

The fourth parameter of sqlite3_exec can be used to pass information to the callback. In your case, a pointer to the table would be useful:

typedef vector<vector<string> > table_type;
static int callbackDB(void *ptr, int argc, char* argv[], char* cols[])
{
    table_type* table = static_cast<table_type*>(ptr);
    vector<string> row;
    for (int i = 0; i < argc; i++)
        row.push_back(argv[i] ? argv[i] : "(NULL)");
    table->push_back(row);
    return 0;
}
...
    rc = sqlite3_exec(db, query, callbackDB, &table, &errmsg);

However, using callbacks like this is not very useful because you get just a bunch of naked strings. You should rather use the prepare/step/finalize interface directly so that you can use proper data types:

class Address {
public:
    Address(int id, const string& name, const string& number);
    ...
}

    ...
    vector<Address> addresses;
    sqlite3_stmt *stmt;
    rc = sqlite3_prepare_v2(db, "SELECT id, name, number FROM addresses",
                            -1, &stmt, NULL);
    if (rc != SQLITE_OK) {
        cerr << "SELECT failed: " << sqlite3_errmsg(db) << endl;
        return ...; // or throw
    }
    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
        int id = sqlite3_column_int(stmt, 0);
        const char* name = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
        const char* number = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 2));
        // let's assume number can be NULL:
        addresses.push_back(Address(id, name, number ? number : ""));
    }
    if (rc != SQLITE_DONE) {
        cerr << "SELECT failed: " << sqlite3_errmsg(db) << endl;
        // if you return/throw here, don't forget the finalize
    }
    sqlite3_finalize(stmt);

这篇关于C ++ populate向量从sqlite3回调函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆