Skip to content

Table structur

Neon32eeee edited this page Feb 25, 2026 · 8 revisions

The Table type is provided as a struct that represents a named collection of rows (elements) in the database, with the following fields:

  • rows — dynamic list that holds all elements/rows of this table (std.ArrayList(Types.Element))
  • allocator — memory allocator used for rows list and internal allocations
  • tname — name of the table (also used as type tag for validation of appended elements)
  • data_buffer — optional buffer for serialized data (used during save/load operations)

Function breakdown (Table)

  • init Purpose: creates an empty table with given name
    Signature:

    init(tname: []const u8, allocator: std.mem.Allocator) Table
  • append Purpose: adds new element (row) to the end of the table
    Signature:

    append(self: *Table, item: Types.Element) !void

    Checks that item.tname matches table name, otherwise returns error.InvalidType

  • appendMany Purpose: adds multiple elements (rows) to the end of the table efficiently
    Signature:

    appendMany(self: *Table, items: []const Types.Element) !void

    Pre-allocates required memory and iterates through items. Validates that each item.tname matches the table name, returning error.InvalidType on the first mismatch.

  • remove Purpose: removes element at specified index and calls its deinit
    Signature:

    remove(self: *@This(), index: usize) !void

    Returns error.InvalidIndex if the index does not exist

  • clear Purpose: clears the table completely
    Signature:

    clear(self: *@This()) void
  • get Purpose: returns element at given index (or null if index is out of bounds)
    Signature:

    get(self: Table, idx: usize) ?Types.Element
  • iterator Purpose: returns iterator that allows walking through all rows
    Signature:

    iterator(self: *@This()) Types.TableIterator
  • len Purpose: returns rows len
    Signature:

    len(self: @This()) usize
  • deinit Purpose: deinitializes all contained elements and frees internal structures
    Signature:

    deinit(self: *@This()) void

Examples

1. Creating table manually and adding rows

var table = Table.init("users", allocator);
defer table.deinit();

var elem1 = Types.Element{ .tname = "users", .field = std.StringHashMap(Types.FieldType).init(allocator) };
defer elem1.deinit();
try elem1.setInt("id", 1);
try elem1.setStr("name", "Alice");

var elem2 = Types.Element{ .tname = "users", .field = std.StringHashMap(Types.FieldType).init(allocator) };
defer elem2.deinit();
try elem2.setInt("id", 2);
try elem2.setStr("name", "Bob");

try table.appendMany(&.{elem1, elem2})

2. Reading rows using get and convenience getters

// assuming table already contains data
if (table.get(0)) |row| {
    const id   = row.getInt("id")   orelse 0;
    const name = row.getStr("name") orelse "unknown";

    std.debug.print("First row: {s} (id {d})\n", .{name, id});
}

if (table.get(1)) |row| {
    const name = row.getStr("name") orelse "?";
    std.debug.print("Second row name: {s}\n", .{name});
}

3. Iterating over all rows

var iter = table.iterator();
while (iter.next()) |*row| {
    const id   = row.*.getInt("id")   orelse continue;
    const name = row.*.getStr("name") orelse continue;

    std.debug.print("→ id: {d:>4} | name: {s}\n", .{id, name});
}

4. Removing a row by index

if (table.rows.items.len > 0) {
    table.remove(0);           // removes first row
    std.debug.print("First row removed, now {d} rows left\n", .{table.rows.items.len});
}

Clone this wiki locally