AmberDB

 view release on metacpan or  search on metacpan

lib/AmberDB.pm  view on Meta::CPAN

All submodules (except C<AmberDB::Tools> which takes an C<$adb> handle) can also be instantiated and used independently in standalone scripts.

=head1 TABLE NAMING CONVENTIONS

AmberDB enforces a strict, deterministic lowercase snake_case table naming convention:

=over 4

=item * B<Format:> All table identifiers must consist of lowercase alphanumeric characters in snake_case, structured as C<E<lt>databaseE<gt>_E<lt>table_nameE<gt>> (e.g. C<catalog_product>, C<member_address>, C<orders_item>).

=item * B<Database Prefix Resolution:> The segment before the first underscore (C<_>) represents the logical database/schema group (mapped to C<E<lt>databaseE<gt>.dbase>).

=item * B<Schema Files:> A table C<catalog_product> automatically resolves its schema from C<catalog_product.table> and its database group settings from C<catalog.dbase>.

=item * B<Constraint:> Uppercase or mixed-case table names (e.g. C<Catalog_Product>) are not supported and will fail database group extraction.

=back

=head1 SCHEMA DEFINITION & CONFIGURATION (.table & IN-MEMORY)

AmberDB is schema-driven. Table schemas define primary key constraints, field blocks, multi-dimensional indexes, automatic URL slug generation, facet filters, lifecycle junk rules, and repeating nested items.

Schemas can be defined in two ways:

=over 4

=item 1. B<Disk-Based Schema Files:> Placed in the C<dbstore/schema/E<lt>table_nameE<gt>.table> directory. AmberDB loads and parses them automatically upon first access.

=item 2. B<Programmatic In-Memory Schemas:> Defined directly on the AmberDB instance via C<$adb-E<gt>table_attr('table_id', { ... })>.

=back

=head2 Example Table Schema (C<catalog_product.table>)

Defining blocks in the schema is not mandatory. However, `record_index`, `match_block`, `search_block`, and `sort_block` are crucial, especially for the automatic creation of indexes during record keeping. `record_index` only takes the value 0/1. `ma...

  {
      name         => "Product Catalog",
      record_index => 1,                      # Enable .inx primary record index
      match_block  => [1, 2, 3, 11],          # .fld exact field match indexes (Category, Brand, etc.)
      search_block => [4, 5, 7],              # .src full-text search fields (Title, Subtitle, Description)
      sort_block   => [ 4, { blk => 10, type => 'num' } ], # .inx pre-sorted ID buffers
      keep_deleted => 1,                      # Enable soft-delete audit log (.del)
      log_owner    => 1,                      # Enable change audit logging (.aut)
  }

=head2 Dynamic Runtime Schema Manipulation (C<table_attr>)

Schemas can be dynamically reconfigured in-memory at runtime without modifying disk files or requiring table migrations:

  # Dynamically change full-text search fields on the fly
  $adb->table_attr("catalog_product", { search_block => [ 4, 9 ] });

  # Toggle caching or soft-delete modes dynamically
  $adb->table_attr("catalog_product", { use_cache => 0, keep_deleted => 0 });

=head2 Expandable Records without SQL JOINs (Repeating Blocks)

AmberDB supports hierarchical, JSON-like extensible records without the need for child tables or relational C<JOIN> queries. Multiple repeating child items (e.g., order lines, cart items, invoice lines) can be appended directly to the parent record. ...

  # Schema configuration for expanding order table
  {
      name         => "Customer Orders",
      record_index => 1,
      match_block  => [1, 2, 4],    # Customer ID, Order Date, Products
      repeat_ids   => 4,            # products field: item ids, separated by comma
      repeat_start => 5,            # repeat block begin at block 5
      blocks       => [
          { id => "id",          name => "Order ID",     type => "auto_id" },
          { id => "customer_id", name => "Customer ID",  type => "text" },
          { id => "order_date",  name => "Order Date",   type => "text" },
          { id => "total_price", name => "Total Amount", type => "num" },
          { id => "products",    name => "Products",     type => "text" },
          # Repeating line items:
          { id => "item_id",     name => "Item ID",      type => "text" },
          { id => "item_title",  name => "Product Title",type => "text" },
          { id => "item_qty",    name => "Quantity",     type => "num" },
          { id => "item_price",  name => "Unit Price",   type => "num" },
      ],
  }

=head1 TRANSACTIONS

Transactions provide multi-table atomic updates backed by undo-log journals (C<.txn> files).
If a database error occurs (e.g. file lock failure, duplicate ID), or if custom business validation fails (e.g. insufficient stock),
all base records and indexes across all affected tables are restored to their exact pre-transaction state.

=head2 Checkout / Stock Deduction Example

  $adb->transact_start();

  # 1. Check & update stock
  my @product = $adb->read_id("product", $product_id);
  my $current_stock = $product[4];

  if ($current_stock < $quantity) {
      # Operational condition (out of stock): Directly roll back and release locks
      $adb->transact_rollback();
      return { success => 0, error => "Out of stock" };
  }

  $product[4] -= $quantity;
  $adb->modify_id("product", $product_id, @product);

  # 2. Insert order record
  my $order_id = $adb->insert_id("orders", 0, $user_id, $product_id, $quantity, time());

  # 3. Finalize transaction (auto-rollbacks if base error occurred)
  my $txn = $adb->transact_end();
  if ($txn->{status} eq 'commit') {
      return { success => 1, order_id => $order_id };
  } else {
      return { success => 0, error => "The operation failed, the changes were reverted." };
  }

B<Note / Limitations:> Bulk/list operations (C<insert_list>, C<modify_list>, C<delete_list>) do not support the transact operation. There is a fundamental reason for this. Junk operations are designed for loading, editing, or deleting a list containi...

Furthermore, if the user truly wants to perform an operation on the list using transact, they can put it in a loop and use the individual C<insert_id>, C<modify_id>, C<delete_id> operations.

=head1 SIMPLE MODE (SCHEMA-LESS FLAT STORE)



( run in 1.714 second using v1.01-cache-2.11-cpan-302cb4679cc )