Skip to content

Instantly share code, notes, and snippets.

@aneury1
Last active January 29, 2025 19:30
Show Gist options
  • Save aneury1/4fb5210b16301f4b55ef54138282be07 to your computer and use it in GitHub Desktop.
Save aneury1/4fb5210b16301f4b55ef54138282be07 to your computer and use it in GitHub Desktop.
#include <wx/wx.h>
#include <wx/menu.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <sstream>
#include <functional>
#include <sqlite3.h>
struct InternalSqliteResponse
{
int columnCount;
std::vector<std::vector<std::string>> rows;
std::vector<std::string> columnNames;
};
enum DataType
{
Text,
Number,
Boolean
};
enum class Constraint
{
PrimaryKey,
AutoIncrement,
NotNull
};
struct Column
{
std::string name;
int type;
std::string value;
std::vector<Constraint> constraints;
// Constructor
Column() : name(""), type(Text), value("") {}
Column(const std::string &colName, int colType, const std::string &colValue, std::vector<Constraint> colConstraints)
: name(colName), type(colType), value(colValue), constraints(colConstraints) {}
// Generate Table Schema string
std::string toString()
{
std::ostringstream ss;
ss << name << " ";
switch (type)
{
case Text:
ss << "TEXT";
break;
case Number:
ss << "INTEGER";
break;
case Boolean:
ss << "BOOLEAN";
break;
}
for (const auto &constraint : constraints)
{
switch (constraint)
{
case Constraint::PrimaryKey:
ss << " PRIMARY KEY";
break;
case Constraint::AutoIncrement:
ss << " AUTOINCREMENT";
break;
case Constraint::NotNull:
ss << " NOT NULL";
break;
}
}
return ss.str();
}
};
struct SqlTable
{
std::vector<Column> columns;
std::string tableName;
// Constructor: Always contains first ID column as PRIMARY KEY (not AUTOINCREMENT)
SqlTable(const std::string table)
{
columns.push_back(Column("id", Number, "", {Constraint::PrimaryKey}));
tableName = table;
}
void setColumnValue(const std::string& columnName, const std::string& newValue) {
for (auto& col : columns) {
if (col.name == columnName) {
col.value = newValue;
return;
}
}
}
// Generate Table Schema string
std::string toString()
{
std::ostringstream ss;
ss << "CREATE TABLE " << tableName << " (";
for (size_t i = 0; i < columns.size(); ++i)
{
ss << columns[i].toString();
if (i < columns.size() - 1)
ss << ", ";
}
ss << ");";
return ss.str();
}
// Generate SQL INSERT statement
std::string generateInsert()
{
std::ostringstream ss;
ss << "INSERT INTO " << tableName << " (";
for (size_t i = 1; i < columns.size(); ++i)
{
ss << columns[i].name;
if (i < columns.size() - 1)
ss << ", ";
}
ss << ") VALUES (";
for (size_t i = 1; i < columns.size(); ++i)
{
ss << "?";
if (i < columns.size() - 1)
ss << ", ";
}
ss << ");";
return ss.str();
}
// Generate SQL SELECT statement
std::string generateSelect()
{
return "SELECT * FROM " + tableName + ";";
}
// Generate SQL UPDATE statement
std::string generateUpdate()
{
std::ostringstream ss;
ss << "UPDATE " << tableName << " SET ";
for (size_t i = 1; i < columns.size(); ++i)
{
ss << columns[i].name << " = ?";
if (i < columns.size() - 1)
ss << ", ";
}
ss << " WHERE id = ?;";
return ss.str();
}
// Generate SQL DELETE statement
std::string generateDelete()
{
return "DELETE FROM " + tableName + " WHERE id = ?;";
}
};
// SQLite Execution Function with Callback
bool executeSqliteQuery(sqlite3 *db, const std::string &query, std::function<void(int, InternalSqliteResponse)> callback)
{
char *errMsg = nullptr;
InternalSqliteResponse response;
auto internalCallback = [](void *resp, int argc, char **argv, char **colNames) -> int
{
auto &responseRef = *static_cast<InternalSqliteResponse *>(resp);
std::vector<std::string> row;
for (int i = 0; i < argc; ++i)
{
row.push_back(argv[i] ? argv[i] : "NULL");
}
responseRef.rows.push_back(row);
if (responseRef.columnNames.empty())
{
for (int i = 0; i < argc; ++i)
{
responseRef.columnNames.push_back(colNames[i] ? colNames[i] : "");
}
}
return 0;
};
int rc = sqlite3_exec(db, query.c_str(), internalCallback, &response, &errMsg);
if (rc != SQLITE_OK)
{
std::cerr << "SQL Error: " << errMsg << std::endl;
sqlite3_free(errMsg);
}
response.columnCount = response.columnNames.size();
callback(rc, response);
return rc == SQLITE_OK;
}
SqlTable querySqliteTable(sqlite3* db, const std::string& tableName) {
SqlTable table(tableName);
std::string query = "PRAGMA table_info(" + tableName + ");";
executeSqliteQuery(db, query, [&](int result, InternalSqliteResponse response) {
if (result == SQLITE_OK) {
table.columns.clear();
for (const auto& row : response.rows) {
if (row.size() >= 2) {
std::string colName = row[1];
int colType = (row[2] == "INTEGER") ? Number : (row[2] == "TEXT") ? Text : Boolean;
table.columns.push_back(Column(colName, colType, "", {}));
}
}
}
});
return table;
}
std::string generateSelectQuery(const std::string& tableName) {
return "SELECT * FROM " + tableName + ";";
}
std::string generateInsertQuery(const std::string& tableName, const SqlTable& table) {
std::ostringstream ss;
ss << "INSERT INTO " << tableName << " (";
for (size_t i = 1; i < table.columns.size(); ++i) {
ss << table.columns[i].name;
if (i < table.columns.size() - 1) ss << ", ";
}
ss << ") VALUES (";
for (size_t i = 1; i < table.columns.size(); ++i) {
ss << "'" << table.columns[i].value << "'";
if (i < table.columns.size() - 1) ss << ", ";
}
ss << ");";
return ss.str();
}
std::string generateUpdateQuery(const std::string& tableName, const SqlTable& table, const std::string& condition) {
std::ostringstream ss;
ss << "UPDATE " << tableName << " SET ";
for (size_t i = 1; i < table.columns.size(); ++i) {
ss << table.columns[i].name << " = '" << table.columns[i].value << "'";
if (i < table.columns.size() - 1) ss << ", ";
}
ss << " WHERE " << condition << ";";
return ss.str();
}
std::string generateDeleteQuery(const std::string& tableName, const std::string& condition) {
return "DELETE FROM " + tableName + " WHERE " + condition + ";";
}
struct Window : public wxFrame
{
wxPanel *sideMenuContainer = new wxPanel(this, wxID_ANY);
wxPanel *editorContainer = new wxPanel(this, wxID_ANY);
Window() : wxFrame(nullptr, wxID_ANY, wxT("App"))
{
Maximize();
auto sizer = new wxBoxSizer(wxHORIZONTAL);
sqlite3 *db;
if (sqlite3_open("example2.db", &db))
{
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << std::endl;
return;
}
SqlTable table("Usuarios2");
table.columns.push_back(Column("name", Text, "", {}));
table.columns.push_back(Column("age", Number, "", {}));
wxTextCtrl *text = new wxTextCtrl(editorContainer, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
text->SetBackgroundColour(wxColour(0x43, 0x43, 0x43, 255));
wxBoxSizer *sizerM = new wxBoxSizer(wxHORIZONTAL);
sizerM->Add(text, 1, wxEXPAND | wxALL, 0);
editorContainer->SetSizer(sizerM);
text->SetValue(wxString(table.toString() + "\r\n"));
std::string createTableQuery = table.toString();
executeSqliteQuery(db, createTableQuery, [text](int result, InternalSqliteResponse response)
{
if (result == SQLITE_OK) {
std::cout << "Table created successfully." << std::endl;
text->AppendText("\r\nTable Created Successfully");
} else {
text->AppendText("\r\nTable Created with Error");
std::cout << "Failed to create table." << std::endl;
} });
auto tableQueried = querySqliteTable(db, table.tableName);
text->AppendText("\r\nTable Queried:\n\n"+tableQueried.toString());
for(int i=0;i<65536*2;i++)
{
table.setColumnValue("name", std::to_string(i+10)+"Cybord");
table.setColumnValue("age", std::to_string(i+10));
std::string insertQuery = generateInsertQuery(table.tableName, table);
text->AppendText(wxT("Insert Query: [")+ wxString(insertQuery.c_str())+"]\r\n");
executeSqliteQuery(db, insertQuery, [](int result, InternalSqliteResponse response) {
if (result == SQLITE_OK) {
std::cout << "Data inserted successfully." << std::endl;
}
});
}
std::string selectQuery = generateSelectQuery(table.tableName);
executeSqliteQuery(db, selectQuery, [text](int result, InternalSqliteResponse response) {
for (const auto& row : response.rows) {
for (const auto& col : row) {
std::cout << col << " ";
text->AppendText(col+" ");
}
std::cout << std::endl;
text->AppendText("\r\n");
}
});
sqlite3_close(db);
editorContainer->SetBackgroundColour(wxColor(0xff, 0x10, 0x63, 255));
sizer->Add(editorContainer, 20, wxEXPAND | wxALL, 2);
SetSizer(sizer);
}
};
class Application : public wxApp
{
public:
virtual bool OnInit()
{
auto app = new Window();
app->Show(true);
return true;
}
};
wxIMPLEMENT_APP(Application);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment