SQL error: (null)
SQL error: (null) - Что это значит? Программа на с++ с использованием gtk4. Ubuntu, g++ 17. После нескольких таких ошибок происходит Segmentation fault (core dumped). Ошибка в функции GetProduct. Помогите, пожалуйста
#include <iostream>
#include <sqlite3.h>
#include <string>
#include <map>
#include <vector>
#include <gtk/gtk.h>
#include <typeinfo>
#include <fstream>
using namespace std;
class MainDB
{
public:
sqlite3 *db;
MainDB()
{
if (sqlite3_open("main.db", &db))
{
cout << "Can't open database: " << sqlite3_errmsg(db) << endl;
}
else
{
sqlite3_enable_load_extension(db, 1);
char *ErrMsg;
string sql = "SELECT load_extension('./fileio.so')";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
cout << "Opened database successfully" << endl;
}
}
~MainDB()
{
sqlite3_enable_load_extension(db, 0);
sqlite3_close(db);
}
void first_launch()
{
char *ErrMsg;
const char *sql = "CREATE TABLE PRODUCT (id INTEGER PRIMARY KEY AUTOINCREMENT, photo BLOB, name TEXT,\
materials TEXT, place_of_storage TEXT, count INTEGER, weight INTEGER, height INTEGER, width INTEGER,\
cost_price INTEGER, price INTEGER)";
sqlite3_exec(db, sql, callback, NULL, &ErrMsg);
sql = "CREATE TABLE MATERIAL (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER,\
count INTEGER, photo BLUB, supplier_id INTEGER)";
sqlite3_exec(db, sql, callback, NULL, &ErrMsg);
sql = "CREATE TABLE SUPPLIER (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, numbers TEXT,\
URL TEXT, address TEXT, mail TEXT)";
sqlite3_exec(db, sql, callback, NULL, &ErrMsg);
}
static int callback(void *unused, int count, char **data, char **columns) {
return 0;
}
void AddProduct(string photo, string name, string materials, string place_of_storage,
int count, int weight, int height, int width, int cost_price, int price)
{
char *ErrMsg;
string sql = "INSERT INTO PRODUCT (photo, name, materials, place_of_storage, count, weight, height, width, \
cost_price, price) VALUES (readfile('" +
photo + "'), '" + name + "', '" + materials + "', '" +
place_of_storage + "', " + to_string(count) + ", " + to_string(weight) + ", " + to_string(height) + ", " + to_string(width) + ", " + to_string(cost_price) + ", " + to_string(price) + " );";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void RedProduct(int id, string name_of_field, string value)
{
char *ErrMsg;
string sql = "UPDATE PRODUCT SET " + name_of_field + " = '" + value + "' WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void RedProduct(int id, string name_of_field, int value)
{
char *ErrMsg;
string sql = "UPDATE PRODUCT SET " + name_of_field + " = " + to_string(value) + " WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void DelProduct(int id)
{
char *ErrMsg;
string sql = "DELETE FROM PRODUCT WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void AddMaterial(string name, int price, int count, string photo, int supplier_id)
{
char *ErrMsg;
string sql = "INSERT INTO MATERIAL (name, price, count, photo, supplier_id) VALUES ('" + name + "', " + to_string(price) + ", " + to_string(count) + ", readfile('" + photo + "'), " + to_string(supplier_id) + ");";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void RedMaterial(int id, string name_of_field, string value)
{
char *ErrMsg;
string sql = "UPDATE MATERIAL SET " + name_of_field + " = '" + value + "' WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void RedMaterial(int id, string name_of_field, int value)
{
char *ErrMsg;
string sql = "UPDATE MATERIAL SET " + name_of_field + " = " + to_string(value) + " WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void DelMaterial(int id)
{
char *ErrMsg;
string sql = "DELETE FROM MATERIAL WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void AddSupplier(string name, string numbers, string URL, string address, string mail)
{
char *ErrMsg;
string sql = "INSERT INTO SUPPLIER (name, numbers, URL, address, mail) VALUES ('" + name + "', '" + numbers + "', '" + URL + "', '" + address + "', '" + mail + "');";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void RedSupplier(int id, string name_of_field, string value)
{
char *ErrMsg;
string sql = "UPDATE SUPPLIER SET " + name_of_field + " = '" + value + "' WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void RedSupplier(int id, string name_of_field, int value)
{
char *ErrMsg;
string sql = "UPDATE MATERIAL SET " + name_of_field + " = " + to_string(value) + " WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
void DelSupplier(int id)
{
char *ErrMsg;
string sql = "DELETE FROM SUPPLIER WHERE id=" + to_string(id) + " ;";
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
}
map<int, string> GetProduct(int id){
id += 1;
cout << id << endl;
map<int, string> m;
char *ErrMsg;
sqlite3_stmt *stmt;
string sql = "SELECT * FROM PRODUCT WHERE id=" + to_string(id);
int rc = sqlite3_prepare_v2(this->db, sql.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK){
fprintf(stderr, "SQL error: %s\n", ErrMsg);
cout << ErrMsg << endl;
sqlite3_free(ErrMsg);
}
else{
while ((rc = sqlite3_step(stmt) == SQLITE_ROW)){
for (int i = 0; i < 11; i++){
if (i != 1)
{
string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
m.insert(pair<int, string>(i, new_req));
}
}
}
}
return m;
}
string GetProductImg(int id)
{
char *ErrMsg;
string sql = "SELECT writefile('img.jpg', photo) FROM PRODUCT WHERE id=" + to_string(id);
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
return "./img.jpg";
}
map<int, string> GetMaterial(int id)
{
map<int, string> m;
char *ErrMsg;
sqlite3_stmt *stmt;
string sql = "SELECT * FROM MATERIAL WHERE id=" + to_string(id);
int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
fprintf(stderr, "SQL error: %s\n", ErrMsg);
sqlite3_free(ErrMsg);
}
else
{
while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
{
for (int i = 0; i < 6; i++)
{
if (i != 4)
{
string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
m.insert(pair<int, string>(i, new_req));
}
}
cout << endl;
}
}
return m;
}
string GetMaterialImg(int id)
{
char *ErrMsg;
string sql = "SELECT writefile('img.jpg', photo) FROM MATERIAL WHERE id=" + to_string(id);
sqlite3_exec(db, sql.c_str(), callback, NULL, &ErrMsg);
return "./img.jpg";
}
map<int, string> GetSupplier(int id)
{
map<int, string> m;
char *ErrMsg;
sqlite3_stmt *stmt;
string sql = "SELECT * FROM SUPPLIER WHERE id=" + to_string(id);
int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
fprintf(stderr, "SQL error: %s\n", ErrMsg);
sqlite3_free(ErrMsg);
}
else
{
while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
{
for (int i = 0; i < 6; i++)
{
string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
m.insert(pair<int, string>(i, new_req));
}
cout << endl;
}
}
return m;
}
vector<map<int, string>> GetProducts()
{
vector<map<int, string>> v;
map<int, string> m;
char *ErrMsg;
sqlite3_stmt *stmt;
string sql = "SELECT * FROM PRODUCT";
int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
fprintf(stderr, "SQL error: %s\n", ErrMsg);
sqlite3_free(ErrMsg);
}
else
{
while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
{
for (int i = 0; i < 11; i++)
{
if (i != 1)
{
string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
m.insert(pair<int, string>(i, new_req));
}
}
v.push_back(m);
m.clear();
}
}
return v;
}
vector<map<int, string>> GetMaterials()
{
vector<map<int, string>> v;
map<int, string> m;
char *ErrMsg;
sqlite3_stmt *stmt;
string sql = "SELECT * FROM MATERIAL";
int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
fprintf(stderr, "SQL error: %s\n", ErrMsg);
sqlite3_free(ErrMsg);
}
else
{
while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
{
for (int i = 0; i < 6; i++)
{
if (i != 4)
{
string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
m.insert(pair<int, string>(i, new_req));
}
}
v.push_back(m);
m.clear();
}
}
return v;
}
vector<map<int, string>> GetSuppliers()
{
vector<map<int, string>> v;
map<int, string> m;
char *ErrMsg;
sqlite3_stmt *stmt;
string sql = "SELECT * FROM SUPPLIER";
int rc = sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, NULL);
if (rc != SQLITE_OK)
{
fprintf(stderr, "SQL error: %s\n", ErrMsg);
sqlite3_free(ErrMsg);
}
else
{
while ((rc = sqlite3_step(stmt) == SQLITE_ROW))
{
for (int i = 0; i < 6; i++)
{
string new_req = reinterpret_cast<const char *>(sqlite3_column_text(stmt, i));
m.insert(pair<int, string>(i, new_req));
}
v.push_back(m);
m.clear();
}
}
return v;
}
};
class Window
{
private:
MainDB db;
GtkWidget *window;
GtkWidget *notebook;
GtkWidget *boxes[3];
GtkWidget *grids[3];
GtkWidget *view_panels[3];
typedef struct
{
GtkWidget *my_grid;
int page;
int n;
} MyData;
public:
std::string product_keys[11] = {"id", "Фото", "Наименование", "Материалы", "Место хранения",
"Количество", "Ширина", "Высота", "Вес", "Цена товара", "Себестоимость"};
std::string material_keys[6] = {"id", "Наименование", "Себестоимость", "Количество", "Фото", "Номер продавца (id)"};
std::string supplier_keys[6] = {"id", "Наименование", "Номер телефона", "URL", "Адрес", "Почта"};
Window(GtkApplication *app, gpointer user_data)
{
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Модная пчела");
gtk_window_set_default_size(GTK_WINDOW(window), 1400, 500);
this->settings();
gtk_widget_show(window);
}
~Window() {}
void settings()
{
this->notebook = gtk_notebook_new();
GtkWidget *scroll_wins[] = {gtk_scrolled_window_new(), gtk_scrolled_window_new(), gtk_scrolled_window_new()};
this->boxes[0] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous(GTK_BOX(this->boxes[0]), TRUE);
this->boxes[1] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous(GTK_BOX(this->boxes[1]), TRUE);
this->boxes[2] = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous(GTK_BOX(this->boxes[2]), TRUE);
this->grids[0] = gtk_grid_new();
gtk_grid_set_column_homogeneous(GTK_GRID(this->grids[0]), TRUE);
this->grids[1] = gtk_grid_new();
gtk_grid_set_column_homogeneous(GTK_GRID(this->grids[1]), TRUE);
this->grids[2] = gtk_grid_new();
gtk_grid_set_column_homogeneous(GTK_GRID(this->grids[2]), TRUE);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll_wins[0]), this->grids[0]);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll_wins[1]), this->grids[1]);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll_wins[2]), this->grids[2]);
gtk_window_set_child(GTK_WINDOW(this->window), this->notebook);
gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook), boxes[0], gtk_label_new_with_mnemonic("Продукты"));
gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook), boxes[1], gtk_label_new_with_mnemonic("Материалы"));
gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook), boxes[2], gtk_label_new_with_mnemonic("Поставщики"));
gtk_box_append(GTK_BOX(this->boxes[0]), scroll_wins[0]);
gtk_box_append(GTK_BOX(this->boxes[1]), scroll_wins[1]);
gtk_box_append(GTK_BOX(this->boxes[2]), scroll_wins[2]);
// view panels
this->view_panels[0] = gtk_grid_new();
this->view_panels[1] = gtk_grid_new();
this->view_panels[2] = gtk_grid_new();
gtk_box_append(GTK_BOX(this->boxes[0]), this->view_panels[0]);
gtk_box_append(GTK_BOX(this->boxes[1]), this->view_panels[1]);
gtk_box_append(GTK_BOX(this->boxes[2]), this->view_panels[2]);
gtk_grid_set_column_homogeneous(GTK_GRID(this->view_panels[0]), TRUE);
gtk_grid_set_column_homogeneous(GTK_GRID(this->view_panels[1]), TRUE);
gtk_grid_set_column_homogeneous(GTK_GRID(this->view_panels[2]), TRUE);
//
std::vector<std::map<int, std::string>> products = this->db.GetProducts();
std::vector<std::map<int, std::string>> materials = this->db.GetMaterials();
std::vector<std::map<int, std::string>> suppliers = this->db.GetSuppliers();
// products
for (int i = 0; i < products.size(); i++)
{
for (int g = 0; g < 11; g++)
{
if (g != 1)
{
if (g > 1)
{
gtk_grid_attach(GTK_GRID(this->grids[0]), gtk_label_new_with_mnemonic(products.at(i)[g].c_str()), g - 1, i, 1, 1);
}
else
{
gtk_grid_attach(GTK_GRID(this->grids[0]), gtk_label_new_with_mnemonic(products.at(i)[g].c_str()), g, i, 1, 1);
}
}
}
// my struct
MyData *data = static_cast<MyData *>(g_new(MyData, 1));
data->my_grid = this->view_panels[0];
data->page = 0;
data->n = i;
//
GtkWidget *button_red = gtk_button_new_from_icon_name("document-edit");
g_signal_connect(button_red, "clicked", G_CALLBACK(&Window::button_clicked), data);
gtk_grid_attach(GTK_GRID(this->grids[0]), button_red, 11, i, 1, 1);
}
// materials
for (int i = 0; i < materials.size(); i++)
{
for (int g = 0; g < 6; g++)
{
if (g != 4)
{
if (g > 4)
{
gtk_grid_attach(GTK_GRID(this->grids[1]), gtk_label_new_with_mnemonic(materials.at(i)[g].c_str()), g - 1, i, 1, 1);
}
else
{
gtk_grid_attach(GTK_GRID(this->grids[1]), gtk_label_new_with_mnemonic(materials.at(i)[g].c_str()), g, i, 1, 1);
}
}
}
// my struct
MyData *data = static_cast<MyData *>(g_new(MyData, 1));
data->page = 1;
data->n = i;
//
GtkWidget *button_red = gtk_button_new_from_icon_name("document-edit");
g_signal_connect(button_red, "clicked", G_CALLBACK(&Window::button_clicked), data);
gtk_grid_attach(GTK_GRID(this->grids[1]), button_red, 6, i, 1, 1);
}
// suppliers
for (int i = 0; i < suppliers.size(); i++)
{
for (int g = 0; g < 6; g++)
{
gtk_grid_attach(GTK_GRID(this->grids[2]), gtk_label_new_with_mnemonic(suppliers.at(i)[g].c_str()), g, i, 1, 1);
}
// my struct
MyData *data = static_cast<MyData *>(g_new(MyData, 1));
data->page = 2;
data->n = i;
//
GtkWidget *button_red = gtk_button_new_from_icon_name("document-edit");
g_signal_connect(button_red, "clicked", G_CALLBACK(&Window::button_clicked), data);
gtk_grid_attach(GTK_GRID(this->grids[2]), button_red, 6, i, 1, 1);
}
}
void button_clicked(GtkButton *button, gpointer user_data)
{
MyData *data = static_cast<MyData *>(user_data);
GtkWidget *my_grid = data->my_grid;
int page = data->page;
int n = data->n;
// main
//cout << n << endl;
map<int, string> m = db.GetProduct(n);
//map<int, string> m;
//if (page == 0) m = this->db.GetProduct(n);
//else if (page == 1) m = this->db.GetMaterial(n);
//else if (page == 2) m = this->db.GetSupplier(n);
GtkWidget *image = gtk_image_new_from_file(this->db.GetProductImg(n).c_str());
gtk_image_set_icon_size(GTK_IMAGE(image), GTK_ICON_SIZE_LARGE);
gtk_grid_attach(GTK_GRID(my_grid), image, 0, 0, 3, 3);
gtk_grid_attach(GTK_GRID(my_grid), gtk_label_new_with_mnemonic("HI, dear"), 3, 3, 1, 1);
g_free(data);
}
};
static void activate(GtkApplication *app, gpointer user_data)
{
Window window = Window(app, user_data);
}
int main(int argc, char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new("org.gtk.example", G_APPLICATION_DEFAULT_FLAGS);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), argc, argv);
g_object_unref(app);
return status;
}