Language: CPP
Database
SOCI (The C++ Database Access Library) was started in 2004 by Maciej Sobczak to provide a modern alternative to traditional C database APIs like ODBC and libpq. It focuses on safety, readability, and minimal boilerplate while avoiding the complexity of full ORM frameworks. It supports multiple backends including PostgreSQL, MySQL, SQLite, Oracle, and ODBC.
SOCI is a C++ database access library that provides a clean, type-safe, and object-oriented abstraction over SQL databases. It acts like a lightweight ORM but retains full SQL control, offering both simplicity and flexibility.
sudo apt install libsoci-devbrew install socivcpkg install soci or build from source with CMakeSOCI allows developers to write queries in natural SQL while providing type-safe bindings to C++ variables. It eliminates manual binding and fetching of data, making database interaction safer and cleaner.
#include <soci/soci.h>
#include <iostream>
int main() {
try {
soci::session sql(soci::postgresql, "dbname=mydb user=myuser password=mypass");
std::cout << "Connected successfully!" << std::endl;
} catch (std::exception const &e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}Opens a connection to a PostgreSQL database using SOCI.
int count;
sql << "SELECT COUNT(*) FROM users", soci::into(count);
std::cout << "User count: " << count << std::endl;Executes a query and stores the result directly into a C++ variable.
soci::rowset<soci::row> rs = (sql.prepare << "SELECT id, name FROM users");
for (auto const &r : rs) {
int id = r.get<int>(0);
std::string name = r.get<std::string>(1);
std::cout << id << ": " << name << std::endl;
}Iterates over query results using SOCI’s rowset abstraction.
std::string name = "John";
int age;
sql << "SELECT age FROM users WHERE name = :name", soci::into(age), soci::use(name);Binds C++ variables safely to SQL query parameters.
{
soci::transaction tr(sql);
sql << "INSERT INTO logs(message) VALUES('test')";
tr.commit();
}Executes queries inside a transaction with explicit commit or rollback.
Use parameter binding (`soci::use`) to avoid SQL injection.
Wrap multiple statements in transactions for safety and efficiency.
Catch exceptions from SOCI queries to handle runtime errors gracefully.
Use `rowset` for large result sets to stream data instead of loading all at once.
Leverage backend-specific options (e.g., PostgreSQL vs MySQL) for performance tuning.