?
DragonRaider schrieb:
1. Seid ihr nicht eigentlich dagegen, dass man fertigen Code postet, anstatt es einfach zu erklären?
Ich kann Dir Deinen Code nicht erklären. Ich verstehe ihn nicht - und ich habe auch keine Zeit/Lust mich einzuarbeiten.
Das sind 120 Zeilen und an jeder kann man wahrscheinlich was aussetzen.
const char *pointersChar = (const char*)pointersVoid;
int addresses[3];
int *numOfResultsP;
char ***resultsP;
char ***columnNamesP;
scanf(pointersChar, "%i, %i, %i", addresses[0], addresses[1], addresses[2]);
Was soll das werden? in Zeile 6 und 7 kommen mir die Tränen. In Zeile 8 dem Compiler!
Oder das:
int *numOfResults = new int;
char ***results = new char**;
char ***columnNames = new char**;
bool result = execute(query, numOfResults, results, columnNames);
delete numOfResults;
delete results;
delete columnNames;
Du bist völlig verwirrt durch die Zeiger des C-APIs von sqlite und schmeisst Sternchen und casts in den Code, damit es kompiliert.
Da ist nichts zu erklären, das ist Fubar!
Deswegen - und das ist durchaus üblich - habe ich Dir ein Minimalbeispiel gebaut. Fast ohne Sternchen und Casts, ohne new und delete, damit Du Dir vielleicht was abgucken kannst.
DragonRaider schrieb:
2. Wie soll ich jetzt an die Daten aus der DB kommen?
Nun: Du bastelst Dir einen Callback, der irgendwas macht. Z.B. könntest Du Die Datenbankeinträge in einen vector blasen
#include <iostream>
#include <string>
#include <vector>
#include <sqlite3.h>
struct texture{
std::string name;
std::string path;
};
std::ostream& operator<<(std::ostream& out, const texture& t){
return out << '(' << t.name << " @ " << t.path << ')';
}
class sqlite3_db{
sqlite3* db;
public:
typedef std::vector<texture> t_vec;
sqlite3_db(const char* path){
sqlite3_open(path, &db);
}
~sqlite3_db() { sqlite3_close(db); }
sqlite3_db(const sqlite3_db&) = delete;
sqlite3_db(sqlite3_db&&) = delete;
sqlite3_db& operator=(const sqlite3_db&) = delete;
sqlite3_db& operator=(const sqlite3_db&&) = delete;
void execute(const std::string& stmt){
char* errmsg;
int e = sqlite3_exec(db, stmt.c_str(), nullptr, nullptr, &errmsg);
if( e!= SQLITE_OK){
std::cerr << "Error in sqlite3_db::execute(): " << errmsg << '\n';
sqlite3_free(errmsg);
}
}
t_vec give_textures(){
// mein callback (gegen die Langeweile mal ein Lambda)
auto filler = [](void* vec, int argc, char** cols, char** col_names) -> int{
t_vec* target = static_cast<t_vec*>(vec);
target->push_back({cols[0], cols[1]});
return 0;
};
char*errmsg;
t_vec ret;
if(sqlite3_exec(db, "SELECT * FROM textures;", filler, (void*)&ret, &errmsg) != SQLITE_OK){
std::cerr << "Cannot give textures. Error is: " << errmsg << '\n';
sqlite3_free(errmsg);
}
return ret;
}
};
int main(){
std::string create =
"CREATE TABLE textures (name TEXT, path TEXT);"
"INSERT INTO textures VALUES('texture1', 'texture1_path');"
"INSERT INTO textures VALUES('texture2', 'texture2_path');"
"INSERT INTO textures VALUES('texture3', 'texture3_path');";
sqlite3_db db(":memory:");
db.execute(create);
auto vec = db.give_textures();
for(const auto& t : vec)
std::cout << t << '\n';
}
Gutes Gelingen!