TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 229 subscribers
Post #24776 16
Lightweight: Almost-zero-overhead C++23 SQL library with DataMapper ORM, migrations, and backup/restore

Hi r/cpp,

We're excited to share **Lightweight**, a modern C++23 ODBC wrapper we've been building to solve our need for high-level SQL access without runtime overhead.

**Philosophy:** Down-to-zero runtime cost is mandatory requirement. We reduce high-level API into near-raw ODBC calls during compilation by using compile-time reflection techniques.

**GitHub:** https://github.com/LASTRADA-Software/Lightweight/
**Docs:** https://lastrada-software.github.io/Lightweight/

---

## Low-Level API: SqlStatement & SqlConnection

For those who want direct control, the core API is clean and minimal:

```cpp
auto stmt = SqlStatement {};

// Direct execution
stmt.ExecuteDirect("SELECT * FROM Users WHERE age > 21");
while (stmt.FetchRow())
std::println("{}: {}", stmt.GetColumn<int>(1), stmt.GetColumn<std::string>(2));

// Prepared statements with type-safe binding
stmt.Prepare(R"(INSERT INTO Employees (name, department, salary) VALUES (?, ?, ?))");
stmt.Execute("Alice", "Engineering", 85'000);
stmt.Execute("Bob", "Sales", 72'000);

// Output column binding
std::string name(50, '\0');
int salary {};
stmt.Prepare("SELECT name, salary FROM Employees WHERE id = ?");
stmt.BindOutputColumns(&name, &salary);
stmt.Execute(42);
```

### Bulk Insertions

Insert thousands of rows efficiently with a single call:

```cpp
stmt.Prepare(R"(INSERT INTO Employees (name, department, salary) VALUES (?, ?, ?))");

// Works with mixed container types
auto names = std::array { "Alice"sv, "Bob"sv, "Charlie"sv };
auto depts = std::list { "Eng"sv, "Sales"sv, "Ops"sv }; // even non-contiguous!
unsigned salaries[] = { 85'000, 72'000, 68'000 };

stmt.ExecuteBatch(names, depts, salaries); // Single ODBC batch call
```

Three batch methods for different scenarios:
- `ExecuteBatchNative()` - Fastest, requires contiguous memory
- `ExecuteBatchSoft()` - Works with any range (std::list, etc.)
- `ExecuteBatch()` - Auto-selects the best method

---

## DataMapper: High-Level ORM

Define your schema as C++ structs, and the DataMapper handles the rest:

```cpp
struct Person
{
Field<SqlGuid, PrimaryKey::AutoAssign> id;
Field<SqlAnsiString<25>> name;
Field<bool> is_active { true };
Field<std::optional<int>> age;
};

void Example(DataMapper& dm)
{
dm.CreateTable<Person>();

auto person = Person { .name = "John", .is_active = true, .age = 30 };
dm.Create(person); // INSERT - id auto-assigned

person.age = 31;
dm.Update(person); // UPDATE

// Fluent query API
auto active = dm.Query<Person>()
.Where(FieldNameOf<&Person::is_active>, "=", true)
.OrderBy(FieldNameOf<&Person::name>)
.All();

dm.Delete(person); // DELETE
}
```

---

## Relationships with Lazy Loading

```cpp
struct User
{
Field<SqlGuid, PrimaryKey::AutoAssign> id;
Field<SqlAnsiString<30>> name;
HasMany<Email> emails; // One-to-many
};

struct Email
{
Field<SqlGuid, PrimaryKey::AutoAssign> id;
Field<SqlAnsiString<100>> address;
BelongsTo<&User::id, SqlRealName{"user_id"}> user; // <--- Foreign key relation
};

// Navigate relationships naturally
auto email = dm.QuerySingle<Email>(emailId).value();
auto userName = email.user->name; // Lazy-loaded

// Or iterate
user.emails.Each([](Email const& e) {
std::println("Email: {}", e.address.Value());
});
```

Also supports `HasManyThrough` for many-to-many relationships via join tables.

---

## Database Migrations in Pure C++

No external tools or SQL files - define migrations as C++ code:

```cpp
LIGHTWEIGHT_SQL_MIGRATION(20240115120000, "create users table")
{
using namespace SqlColumnTypeDefinitions;

plan.CreateTable("users")
.PrimaryKey("id", Guid())
.RequiredColumn("name", Varchar(50)).Unique().Index()
.RequiredColumn("email", Varchar(100)).Unique()
.Column("password", Varchar(100))
.Timestamps(); // created_at, updated_at
}

// Apply pending migrations
auto& manager =
GitHub GitHub - LASTRADA-Software/Lightweight: thin and lightweight, fast, ODBC API wrapper for modern C++ uses thin and lightweight, fast, ODBC API wrapper for modern C++ uses - LASTRADA-Software/Lightweight
More from @r_cpp
  1. Oct 7, 2026Escaping `CreateProcess()` arguments on Windows https://holyblackcat.github.io/blog/2026/0…
  2. Oct 7, 2026flat_map internals https://quantdev.blog/posts/flat-map-internals/index.html https://redd.…
  3. Oct 7, 2026New C++ Conference Videos Released This Month - September 2026 C++Now 2026-08-31 - 2026-09…
  4. Oct 7, 2026Jean Frantz René: C++ Memory safety for safety-critical and non-safety critical applicatio…
  5. Oct 7, 2026Full Meeting C++ 2026 program released https://meetingcpp.com/mcpp/schedule/#2026 https://…
  6. Oct 7, 2026Qt moc now can handle basic C++ modules (Qt 6.12) https://codereview.qt-project.org/c/qt/q…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →