AmberDB
view release on metacpan or search on metacpan
lib/AmberDB.pm view on Meta::CPAN
=head2 insert_links($table_id, @records)
Writes alias link bindings into the table's C<.lnk> routing index. Used specifically when duplicate records are deleted and consolidated/merged into a canonical record (requires C<use_alias =E<gt> 1> in table schema):
# Map deleted duplicate ID 452 to canonical active ID 586
$adb->delete_id("catalog_product", 452);
$adb->insert_links("catalog_product", [ 452, 586 ]);
# Multiple mappings in a single call
$adb->insert_links("catalog_product", [ 452, 586 ], [ 453, 586 ]);
# read_id queries for 452 will automatically/transparently fetch canonical record 586:
my @rec = $adb->read_id("catalog_product", 452);
=head2 update_id($table_id, $record_id, @record)
Updates existing record data (alias: C<modify_id>). It automatically updates the search, match, slug, and facet indexes if they are defined in the table schema. It supports transact operations.
$adb->update_id("catalog_product", 101, "Widget Pro v2", "Electronics", 1300);
=head2 modify_id($table_id, $record_id, @record)
Legacy alias for C<update_id>.
$adb->modify_id("catalog_product", 101, "Widget Pro v2", "Electronics", 1300);
=head2 update_list($table_id, @records)
Modifies multiple records in a single bulk operation (alias: C<modify_list>). Aside from Transact, it processes records, search, match, slug, and facet indexes all at once with high performance.
$adb->update_list("catalog_product",
[ 101, "Item 1 Updated", "Category A", 150 ],
[ 102, "Item 2 Updated", "Category B", 250 ],
);
=head2 modify_list($table_id, @records)
Legacy alias for C<update_list>.
=head2 delete_id($table_id, $record_id)
Deletes specified record from table. Supports transaction logging.
$adb->delete_id("catalog_product", 101);
=head2 delete_list($table_id, @records)
Deletes multiple records in a single bulk operation. Aside from Transact, it processes records, search, match, slug, and facet indexes all at once with high performance.
$adb->delete_list("catalog_product", 101, 102, 103);
=head2 read_id($table_id, [$record_id], [\%options])
Reads a single record by primary key ID (or dynamic positional type) in $O(1)$ time.
Options:
=over 4
=item * C<type>: Positional selector (C<'last'>, C<'first'>, C<'rand'>). When specified, a dummy ID (e.g. C<0>) can be passed to preserve standard 3-argument positional signature consistency: C<< $adb->read_id("products", 0, { type => "last" }) >> (o...
=item * C<sort>: Optional sort block (numeric index, schema block name like C<"price">, C<"price desc">, or hashref C<< { block => "price", dir => "asc" } >>). Used in combination with C<< type => 'first' >> or C<'last'> to retrieve the first or last...
=item * C<range>: Optional numerical/chronological range filter hashref C<< { block => 4, min => 1000, max => 2000 } >> to constrain candidate records before positional selection.
=item * C<inflate>: Boolean (C<1> or string C<"inflate">) to inflate record fields into a named HASH reference based on table schema blocks.
=item * C<counter> / C<use_counter>: Explicit boolean (C<1> or C<0>) or string C<"counter"> to force or disable incrementing the read counter (C<.cnt>).
=item * C<no_counter>: Explicit boolean (C<1>) or string C<"no_counter"> to suppress incrementing the read counter.
=item * C<deleted> / C<force>: Boolean (C<1>) or string C<"deleted"> / C<"force"> to read from soft-deleted archive (C<.del>) if missing from active table.
=item * C<links> / C<alias>: Boolean (C<1>) or string C<"links"> / C<"alias"> to resolve a deleted/merged record ID from alias link index (C<.lnk>) to its canonical record.
=back
# Standard array return: ($id, @fields)
my @record = $adb->read_id("catalog_product", 101);
# Inflate record into named HASH ref
my $record_hash = $adb->read_id("catalog_product", 101, { inflate => 1 });
# or shorthand string:
my $record_hash = $adb->read_id("catalog_product", 101, "inflate");
# Positional reads using type (consistent 3-arg with dummy ID 0 or 2-arg):
my @last_rec = $adb->read_id("catalog_product", 0, { type => "last" });
my @first_rec = $adb->read_id("catalog_product", 0, { type => "first" });
my @rand_rec = $adb->read_id("catalog_product", 0, { type => "rand" });
# with inflate:
my $last_hash = $adb->read_id("catalog_product", 0, { type => "last", inflate => 1 });
# Positional reads with sort by a specific block (first or last):
my @cheapest = $adb->read_id("catalog_product", 0, { type => "first", sort => "price" });
my @priciest = $adb->read_id("catalog_product", 0, { type => "last", sort => "price" });
# Shorthand string options:
my @rec_nc = $adb->read_id("catalog_product", 101, "no_counter");
my @rec_dl = $adb->read_id("catalog_product", 101, "deleted");
# Alias lookup (e.g. duplicate record 452 was deleted and merged/linked to 586):
my @rec_lk = $adb->read_id("catalog_product", 452, "alias");
=head2 read_lastid($table_id, [\%options])
Convenience alias for:
$adb->read_id($table_id, 0, { type => "last", %opts });
Supports passing a sort block directly, e.g.:
$adb->read_lastid("catalog_product", "price");
# or
$adb->read_lastid("catalog_product", { sort => "price" });
=head2 read_firstid($table_id, [\%options])
Convenience alias for:
$adb->read_id($table_id, 0, { type => "first", %opts });
Supports passing a sort block directly, e.g.:
$adb->read_firstid("catalog_product", "price");
# or
lib/AmberDB.pm view on Meta::CPAN
# Tiered query mode: 'A' (Active only), 'B' (Junk only), 'AB' (Active first, then Junk)
my @active_only = $adb->read_all("catalog_product", { jnktype => 'A' });
my ($total_count, @all_tiered) = $adb->read_all("catalog_product", { offset => 0, limit => 20, jnktype => 'AB' });
# Return only scalar record IDs (memory-efficient pipeline)
my ($count, @ids) = $adb->read_all("catalog_product", { offset => 0, limit => 50, keys_only => 1 });
# Numerical / chronological range filtering (min defaults to 0 if omitted; max unbounded if omitted):
my @in_range = $adb->read_all("catalog_product", { range => { block => 4, min => 1000, max => 2000 } });
my @min_only = $adb->read_all("catalog_product", { range => { block => 'price', min => 1800 } });
my @max_only = $adb->read_all("catalog_product", { range => { block => 'price', max => 500 } });
=head2 read_list($table_id, \@id_list)
Reads multiple records matching provided ID list while preserving exact list ordering.
# Read the entire active order list.
my @records = $adb->read_all("order_active");
# Extract customer IDs from block 1 using the map.
my %customer_ids = map { $_->[1] => 1 } @records;
# You've found the customer ID keys, now read them using read_list.
my @customers = $adb->read_list("customers", [ keys %customer_ids ]);
=head2 field_fetch($table_id, $block, $value, [\%options])
Fetches records matching one or more block values using the C<.fld> match index (or sequential table scan fallback if unindexed). Supports multi-value queries, automatic deduplication, sorting, pagination, and C<keys_only>.
B<IMPORTANT (Return Signature Convention):>
When C<$limit> is passed and C<E<gt> 0> (paginated), C<field_fetch> returns C<($total_count, @records)> where the first scalar is the total matching count integer. When C<$limit> is omitted or C<0> (unpaginated), it returns C<@records> directly. Unpa...
# 1. Unpaginated (returns array of record arrayrefs directly)
my @records = $adb->field_fetch("products", 1, "5");
my @sorted_asc = $adb->field_fetch("products", 1, "5", { sort => -10 });
# 2. Paginated (first element is total matching count integer)
my ($total_count, @records) = $adb->field_fetch(
"products", 1, "5",
{ offset => 0, limit => 20, sort => -10 }
);
# Multi-value matching (comma string, semicolon, or ARRAY ref)
my @records = $adb->field_fetch("products", 1, ["5", "8"]);
my @records = $adb->field_fetch("products", 1, "5, 8");
# Return only record IDs: keys_only flag
my @all_ids = $adb->field_fetch("products", 1, "5", { keys_only => 1 });
my ($total_count, @ids) = $adb->field_fetch("products", 1, "5", { offset => 0, limit => 20, keys_only => 1 });
# Tiered Junk query mode
my @active = $adb->field_fetch("products", 1, "5", { jnktype => 'A' }); # Only Active records
# Numerical / chronological range filtering on an auxiliary block:
my @range_prods = $adb->field_fetch("products", 2, "Smartphones", { range => { block => "price", min => 1000, max => 1500 } });
C<field_fetch> uses the C<match_block> definition in the schema and accesses inverted match index files (C<.fld>), providing $O(1)$ average-time lookup per indexed key (total retrieval cost scales with the number of requested values and matching reco...
=head2 search_table($table_id, $query, [\%options])
It performs searches matching query terms using the full-text C<.src> index (or a sorted table scan backup method if unindexed). C<search_table> uses the C<AmberDB::Locale> module. It features advanced language normalization according to the selected...
B<IMPORTANT (Return Signature Convention):>
When C<$limit> is passed and C<E<gt> 0> (paginated), C<search_table> returns C<($total_count, @records)> where the first scalar is the total matching count integer. When C<$limit> is omitted or C<0> (unpaginated), it returns C<@records> directly. Unp...
# 1. Unpaginated (returns array of record arrayrefs directly)
my @records = $adb->search_table("catalog_product", "wireless headphones");
my @sorted_records = $adb->search_table("catalog_product", "headphones", { sort => -5 });
# 2. Paginated (first element is total matching count integer)
my ($total_count, @search) = $adb->search_table("catalog_product", "headphones", { offset => 0, limit => 20 });
my ($total_count, @search) = $adb->search_table(
"catalog_product", "headphones",
{
offset => 0,
limit => 20,
sort => -5,
type => "and",
filter => { field => 6, value => 12 },
range => { block => "price", min => 100, max => 500 },
jnktype => 'AB',
}
);
# Return only scalar record IDs
my @all_ids = $adb->search_table("catalog_product", "headphones", { keys_only => 1 });
my ($total_count, @ids) = $adb->search_table("catalog_product", "headphones", { offset => 0, limit => 50, keys_only => 1 });
=head2 field_filter($table_id, \%filter_options)
Performs multi-block filtered queries (AND / OR) with support for multi-value filters, tier mode selection (C<jnktype>), numerical/chronological range filtering (C<range>), sorting, and pagination:
my $res = $adb->field_filter("catalog_product", {
type => "and",
filter => { 1 => "5", 6 => ["12", "14"] },
range => { block => "price", min => 1000, max => 2500 },
sort => { blk => 5, reverse => 1 },
jnktype => "AB",
offset => 0,
limit => 20,
});
# Returns: { count => $total, ids => \@matching_ids }
=head2 exist_id($table_id, $record_id)
Checks if a single record exists in the specified table. Returns 1 if present, 0 otherwise:
my $exists = $adb->exist_id("catalog_product", 101);
=head2 exist_list($table_id, @record_ids)
Queries the presence of multiple record IDs in a single pass. Returns a hash reference C<{ id =E<gt> 1/0 }>:
my $map = $adb->exist_list("catalog_product", 101, 102, 103);
=head2 exist_table($table_id, [$ext])
Checks whether the physical database table or index file exists on disk. C<$ext> defaults to C<$self-E<gt>{db_ext}> (C<'db'>):
my $has_table = $adb->exist_table("catalog_product");
my $has_index = $adb->exist_table("catalog_product", "inx");
=head2 table_count($table_id)
Returns the total number of records in the specified table. Reads from the primary C<.inx> index if enabled, or scans the main table:
my $total_records = $adb->table_count("catalog_product");
=head2 table_keys($table_id)
Returns an array of all record IDs present in the table (retrieved from memory cache, C<.inx> index, or sequential table scan):
my @all_ids = $adb->table_keys("catalog_product");
=head2 table_lastid($table_id)
Returns the highest / auto-increment primary key ID currently allocated in the table:
my $last_id = $adb->table_lastid("catalog_product");
=head2 table_info($table_id)
Loads and returns the table schema definition (hash reference). Automatically ensures metadata fields:
- C<table>: table identifier (e.g. C<"catalog_product">)
- C<dbase>: database prefix (e.g. C<"catalog">)
my $tb_info = $adb->table_info("catalog_product");
print $tb_info->{table}; # "catalog_product"
print $tb_info->{dbase}; # "catalog"
( run in 0.584 second using v1.01-cache-2.11-cpan-e623d60df62 )