Skip to content

Concept Repeat Blocks

Maruf Çetin edited this page Sep 1, 2026 · 1 revision

Concept: Repeating Extensible Blocks (Repeat Blocks)

Turkce Dokumantasyon | English Documentation

Category: Core Concepts & Architecture
Subsystem: Data Model & Dynamic Tables (AmberDB::Base & AmberDB::Index)
Entry Type: Advanced Data Modeling Guide


1. Definition and Purpose

Repeating Extensible Blocks (Repeat Blocks) is an AmberDB architecture feature designed to eliminate separate relational child tables (e.g. order_items, invoice_lines, product_variants) and the expensive SQL JOIN bottlenecks associated with 1-to-N relationships.

In AmberDB, a parent document (such as an Order) carries arbitrary dynamic sub-rows horizontally across its record array. Based on schema-defined repeat_start and repeat_ids configurations, the engine automatically aggregates, joins, and indexes the IDs of all child items.

Repeating Block Array Architecture (@record)

 [0..14] Fixed Header Fields           [15] Sub-Row 1                [16] Sub-Row 2              [17]...
 ┌───────────────────────────────────┐ ┌───────────────────────────┐ ┌───────────────────────────┐
 │ ID, Customer, Date, Total, ...    │ │ ["101", "MacBook", 1, ..] │ │ ["102", "Mouse", 2, ..]   │
 └───────────────────────────────────┘ └───────────────────────────┘ └───────────────────────────┘
                  │                                  │                             │
                  │                                  └──────────────┬──────────────┘
                  v                                                 v
  [12] repeat_ids (Populated by Engine) ──────────────────────> "101,102"  (Indexed via match_block)

2. Schema Configuration (repeat_start & repeat_ids)

Configured within the table schema file (schema/*.table):

  • repeat_start: The 1-based block index where dynamic repeating rows begin (e.g. repeat_start => 15).
  • repeat_ids: The target block index where the engine automatically joins child item IDs into a comma-separated string (e.g. repeat_ids => 12).
# dbstore/schema/order_master.table
{
    name         => "Orders",
    repeat_ids   => 12,    # Target block where child product IDs are joined ("101,102,103")
    repeat_start => 15,    # Starting block index for dynamic repeating child rows
    
    match_block  => [ 2, 12 ], # Indexing block 12 allows instant lookup by child product ID!
    
    fields => [
        { id => "id",           name => "Order ID",     type => "num" },
        { id => "customer_id",  name => "Customer ID",  type => "num" },     # 1
        { id => "order_date",   name => "Order Date",   type => "date" },    # 2
        # ... (Fixed header fields 3..11) ...
        { id => "product_ids",  name => "Product IDs",  type => "text" },    # 12 (repeat_ids target)
        { id => "order_total",  name => "Total Amount", type => "num" },     # 13
        { id => "status",       name => "Status",       type => "num" },     # 14
        { id => "items",        name => "Order Items",  type => "repeat" },  # 15 (repeat_start template)
    ],
}

3. Automated Engine Pipeline (repeat_fields)

During every insert_id, modify_id, insert_list, or modify_list call, the engine (repeat_fields):

  1. Slices the variable array tail @record[15..$#record].
  2. Extracts the primary identifier (element 0) from each child sub-row.
  3. Joins the non-empty IDs into a comma-separated string ("101,102,103").
  4. Automatically assigns the compiled string to block 12 (repeat_ids) before serialization and indexing.

4. Practical Code Example

use AmberDB;

my $adb = AmberDB->new(path => { dbase_dir => "./dbstore" });

# 1. Define order with fixed fields and repeating items starting at index 15
my @order = (
    0,                      # [0] Auto-increment Order ID
    1001,                   # [1] Customer ID
    "2026-09-01",           # [2] Date
    "", "", "", "", "", "", "", "", "", # [3..11] Fixed header placeholders
    "",                     # [12] repeat_ids (Auto-generated by engine)
    2599.00,                # [13] Total Amount
    1,                      # [14] Status (Confirmed)
    
    # Block 15+: Repeating Order Line Items ([ ItemID, Title, Qty, UnitPrice ])
    [ 101, "MacBook Pro M3", 1, 2399.00 ], # [15] Item 1
    [ 102, "Magic Mouse 3",  1, 200.00  ], # [16] Item 2
);

# 2. Insert order
my $order_id = $adb->insert_id("order_master", @order);

# 3. Read back and verify automated consolidation:
my @fetched = $adb->read_id("order_master", $order_id);
print "Auto-compiled Product IDs: $fetched[12]\n"; # Output: "101,102"

# 4. Instant query by child product ID (Zero JOINs!):
# Find all orders containing Product #101 via inverted match index:
my ($total, @matched_orders) = $adb->field_fetch("order_master", 12 => 101);
print "Found $total orders containing Product #101!\n";

5. Architectural Benefits

  1. Zero SQL JOIN Bottlenecks: The parent document and all child lines are retrieved in a single $O(1)$ disk read.
  2. Instant Inverted Queries: Querying orders containing a specific product executes via fast inverted field index (.fld) lookups.
  3. Atomic Consistency: Parent and child data are committed or rolled back atomically within the same record payload, preventing orphan records.

6. See Also & Related Topics

AmberDB Encyclopedia

Home · A-Z Index


Getting Started & Guides


Core Concepts


Core CRUD Methods


Query, Search & Facets


Transactions & Locks


Cache, Buffer & Low-Level


Locale & Helpers


Maintenance & Tools


Configuration Flags


File Formats


Language

Clone this wiki locally