view release on metacpan or search on metacpan
* Added dedicated test suite t/amberdb_field_ops.t covering update_field, insert_field, delete_field, and constraint guards.
* Added dedicated test suite xt/amberdb_ramdisk.t covering physical RAM-disk operations, isolated under author tests (xt/) to ensure standard installation tests pass without pre-mounted RAM-disk filesystems.
* Added dedicated test suite t/amberdb_schema_types.t covering all 9 schema types and type conversions.
* Refactored t/amberdb_cache.t to comprehensively test L1 in-memory caching and persistent staging buffers.
* Added default language ('gb') verification tests in t/amberdb_encapsulation.t and t/amberdb-locale_09_gb.t.
* 100% test pass rate across all 57 standard installation test files (534 assertions) and extended author test suite (xt/).
5.24.1 2026-09-05
- Standardized 'offset' pagination parameter with backward-compatible 'start' alias (read_all, field_fetch, search_table, field_filter, bin_decode, bin_crop, facet_menu).
- Added 'update_id' and 'update_list' method aliases for modify_id and modify_list.
- Fixed CPAN POD parsing error by adding =encoding utf8 to AmberDB::Locale.
- Globalized POD documentation: converted code examples in non-locale modules to standard English ASCII.
- Fixed POD list syntax in AmberDB::Base and eliminated whitespace warning in AmberDB.pm.
- Added t/amberdb_offset_update_alias.t unit test suite.
5.24.0 2026-09-05
- [BINARY RECORD SERIALIZATION ARCHITECTURE (ABR v5)] Native Pure Perl Binary Serialization:
* Introduced high-performance native pure Perl binary record serialization format (ABR v5 / Format 5) replacing legacy delimiter and regex text serialization (db_encode / db_decode), aligning format versioning with historical eras (v1: 2003...
* Zero CPAN Dependencies: Built strictly on core built-in Perl primitives (pack, unpack, substr, vec), completely eliminating version brittleness and security vulnerabilities associated with external serializers like Storable.
* Magic Header Architecture: Prefixes binary records with a 5-byte magic sequence (\x00ABR\x05); null-byte prefix guarantees zero collision with legacy plain text or data strings.
* Schema Type Coverage: Transparently maps all 9 AmberDB schema types into 1-byte typed nodes: UNDEF (0x00), SCALAR_RAW (0x01), SCALAR_UTF8 (0x02, via lossless utf8::encode/decode), ARRAY (0x03, 16-bit Big-Endian count), and HASH (0x04, 16-...
* Nested Data Structures: Fully supports arbitrarily nested arrays, hashes, and repeat blocks with strict recursion depth guarding ($depth <= 32) to prevent stack overflow or circular reference hangs.
* Transparent Legacy Fallback: db_decode automatically falls back to _db_decode_legacy for non-ABR records, allowing mixed-version legacy tables to operate without downtime.
* Benchmarks: Achieves ~130,000 encodes/sec (+150% faster) and ~69,000 decodes/sec (+64% faster) on flat records; achieves ~4,300 decodes/sec (+35% faster) on complex deeply nested multi-level records.
- [BINARY INDEX ARCHITECTURE REFACTORING] Complete Migration of All Indexes to 8-Byte Packed Binary Buffers:
* Migrated all secondary index subsystems (.inx, .fld, .src, .fac, .slg, and Tier B Junk .jinx, .jfld, .jsrc) to pure 8-byte fixed-width packed binary buffers (pack "Q>", unpack "(Q>)*").
* Core Binary Primitives in AmberDB::Base: Implemented bin_add, bin_punch, bin_sort, bin_find, and bin_count operating directly on raw byte buffers via substr() and memory-aligned index(), achieving C-level execution speed.
* High-Level Cleanup: Completely eradicated high-level Perl array/hash manipulations (array_nodup, array_punch) from the core engine indexing path.
* Consolidated Pre-Sorted Indexing: Standalone .srt files are formally deprecated and eliminated; sort indexes are directly maintained inside .inx.
* Direct 64-bit Uint Indexing: Non-foreign key numeric fields in .fld bypass synthetic dictionary ID generation, indexing pure 64-bit unsigned integers directly into binary keys.
bin/amberdb_cli.pl view on Meta::CPAN
return unless $opt_time;
return if $opt_help;
return if defined $? && $? != 0;
my $elapsed = eval { tv_interval($t0) } // 0;
my $time_str = sprintf( "%.4fs (%.2f ms)", $elapsed, $elapsed * 1000 );
print "[Time: $time_str]\n";
}
__END__
=encoding utf8
=head1 NAME
amberdb_cli.pl - High-performance Command-Line Console & Embedded Management Utility for AmberDB
=head1 SYNOPSIS
# 1. Overview Dashboard (lists all tables, records, size, engine status)
perl bin/amberdb_cli.pl
perl bin/amberdb_cli.pl format=json
docs/EN.AmberDB-Locale_User-Guide.md view on Meta::CPAN
```perl
my $tr = AmberDB::Locale->new(language => "tr");
$tr->substring("Ãanakkale", 0, 4); # "Ãana" (4 characters, not 4 bytes!)
$tr->substring("İstanbul", 2, 3); # "tan"
# Also safe with raw UTF-8 byte strings:
my $raw = encode('UTF-8', "Åanlıurfa");
$tr->substring($raw, 0, 5); # "Åanlı" (correctly re-encoded)
```
> Checks whether the string is decoded using `Encode::is_utf8()`. If it's raw bytes, the `decode â substr â encode` chain is applied; this prevents multibyte characters from being cut in half.
---
### 5.9 Date/Time Operations
#### `format_date($time [, $pattern_or_style])`
```perl
my $tr = AmberDB::Locale->new(language => "tr");
my $epoch = time(); # e.g.: 2026-08-09
docs/EN.AmberDB-vs-SQL_User-Guide.md view on Meta::CPAN
* **Explanation:** If `sort_block => [2]` is defined in the schema, the engine utilizes pre-sorted binary ID arrays in `.inx` to stream sorted records without runtime in-memory quicksort overhead.
* **Reference:** [User Guide Section 6.4: Sort Index](EN.AmberDB_User-Guide.html#64-sorting-mechanism-and-usage-guide)
---
### 4.2 Multilingual and Turkish Character Collation
* **SQL:**
```sql
SELECT * FROM members
ORDER BY name COLLATE utf8mb4_turkish_ci;
```
* **AmberDB:**
```perl
# Configured language collation applies automatically:
# cfg => { language => 'tr' }
my ($total, @members) = $adb->read_all("members", { offset => 0, limit => 50, sort => { blk => 1 } });
```
* **Explanation:** AmberDB embeds its own multilingual collation engine (`AmberDB::Locale`). Non-ASCII characters (`Ã, Ä, I, İ, Ã, Å, Ã`) are properly alphabetized without external OS libc dependencies.
docs/TR.AmberDB-Locale_Kullanim_Rehberi.md view on Meta::CPAN
```perl
my $tr = AmberDB::Locale->new(language => "tr");
$tr->substring("Ãanakkale", 0, 4); # "Ãana" (4 karakter, 4 byte deÄil!)
$tr->substring("İstanbul", 2, 3); # "tan"
# Raw UTF-8 byte string ile de güvenli:
my $raw = encode('UTF-8', "Åanlıurfa");
$tr->substring($raw, 0, 5); # "Åanlı" (doÄru Åekilde re-encode edilir)
```
> `Encode::is_utf8()` ile string'in decode edilip edilmediÄi kontrol edilir. Raw byte ise `decode â substr â encode` zinciri uygulanır; böylece multibyte karakterler ortadan kesilmez.
---
### 5.9 Tarih/Saat İÅlemleri
#### `format_date($time [, $pattern_or_style])`
```perl
my $tr = AmberDB::Locale->new(language => "tr");
my $epoch = time(); # örn: 2026-08-09
docs/TR.AmberDB-vs-SQL_Kullanim_Rehberi.md view on Meta::CPAN
* **Açıklama:** Tablo Åemasında `sort_block => [2]` tanımlanmıÅsa, motor `.srt` indeksini kullanarak ekstra bellek sıralaması yapmadan veriyi doÄrudan sıralı getirir.
* **Referans:** [Tutorial Bölüm 6.4: Sıralama İndeksleri (.srt)](TR.AmberDB_Veritabani_Sistemi.html#64-sıralama-indeksleri-srt)
---
### 4.2 Türkçe ve Ãok Dilli Karakter Sıralaması (Collation)
* **SQL:**
```sql
SELECT * FROM members
ORDER BY name COLLATE utf8mb4_turkish_ci;
```
* **AmberDB:**
```perl
# Nesne baÅlatılırken belirtilen dil motoru otomatik çalıÅır:
# cfg => { language => 'tr' }
my ($total, @members) = $adb->read_all("members", { offset => 0, limit => 50, sort => { blk => 1 } });
```
* **Açıklama:** AmberDB, harici veritabanı collation paketlerine veya iÅletim sistemi yereline baÄımlı olmadan kendi bünyesindeki `AmberDB::Locale` motorunu çalıÅtırır. Türkçe `Ã, Ä, I, İ, Ã, Å, Ã` harfleri ASCII karmaÅasına uÄ...
lib/AmberDB.pm view on Meta::CPAN
return 1;
}
# Cache and buffer methods have been moved to AmberDB::Cache.
# Transaction methods have been moved to AmberDB::Transact.
1;
__END__
=encoding utf8
=head1 NAME
AmberDB - High-performance embedded NoSQL database engine for Perl
=head1 SYNOPSIS
use AmberDB;
my $adb = AmberDB->new(
cfg => { language => "gb" },
lib/AmberDB/Base.pm view on Meta::CPAN
package AmberDB::Base;
use 5.016;
use warnings;
use Encode qw(is_utf8 encode decode);
use Carp qw(croak cluck);
use File::Spec;
use Fcntl qw(:DEFAULT :flock);
use parent qw(AmberDB::Locale AmberDB::Array);
our $VERSION = '5.25.1';
my $CREATED = '2014-12-20';
# ------------------------------------------------
sub new {
lib/AmberDB/Base.pm view on Meta::CPAN
}
# $data = $adb->set_charset($from, $to, $data);
# Converts between character encoding tables...
# ------------------------------------------------
sub set_charset {
my ( $self, $from, $to, $data ) = @_;
( $from && $to && $data ) or return;
return $data if ( $to eq "utf8" && utf8::is_utf8($data) );
return encode( $to, decode( $from, $data ) );
}
# Extracts search words from string...
# my %words = $self->get_words($string);
# my %words = $self->get_words($string, $write, $table);
# ------------------------------------------------
sub get_words {
my ( $self, $string, $action, $table ) = @_;
lib/AmberDB/Base/Encoder.pm view on Meta::CPAN
# Native Pure Perl Binary Format with Zero CPAN Dependencies
# Format Specification:
# Header: \x00 A B R \x05 (5 bytes: NUL + Magic "ABR" + Version 5)
# Mode: 1 byte (0x00 = multiple fields, 0x01 = single root reference)
# Payload:
# Mode 0x00: 2 bytes unsigned short "n" (field count) + field nodes
# Mode 0x01: single root node
# Node Types (1 byte tag):
# 0x00 -> UNDEF
# 0x01 -> SCALAR_RAW (4-byte "N" length + raw octets, numbers/ASCII/binary)
# 0x02 -> SCALAR_UTF8 (4-byte "N" length + UTF-8 octets, decoded with utf8::decode)
# 0x03 -> ARRAY (2-byte "n" count + child nodes)
# 0x04 -> HASH (2-byte "n" pair count + 2-byte "n" key len + UTF-8 key + child value node)
# =====================================================================
sub _abr_encode_node {
my ( $self, $node, $depth ) = @_;
die "AmberDB ABR: Max nesting depth exceeded (>32)\n" if ( $depth // 0 ) > 32;
if ( !defined $node ) {
return "\x00";
}
my $ref = ref($node);
if ( !$ref ) {
my $is_utf8 = utf8::is_utf8($node);
my $bytes = "$node";
utf8::encode($bytes) if $is_utf8;
return ( $is_utf8 ? "\x02" : "\x01" ) . pack( "N", length($bytes) ) . $bytes;
}
elsif ( $ref eq 'ARRAY' ) {
my $cnt = scalar @$node;
my $out = "\x03" . pack( "n", $cnt );
for my $item (@$node) {
$out .= $self->_abr_encode_node( $item, ( $depth // 0 ) + 1 );
}
return $out;
}
elsif ( $ref eq 'HASH' ) {
my @keys = sort keys %$node;
my $cnt = scalar @keys;
my $out = "\x04" . pack( "n", $cnt );
for my $k (@keys) {
my $k_bytes = "$k";
my $k_utf8 = utf8::is_utf8($k_bytes);
utf8::encode($k_bytes) if $k_utf8;
$out .= pack( "n", length($k_bytes) ) . $k_bytes;
$out .= $self->_abr_encode_node( $node->{$k}, ( $depth // 0 ) + 1 );
}
return $out;
}
else {
my $str = "$node";
return "\x01" . pack( "N", length($str) ) . $str;
}
}
lib/AmberDB/Base/Encoder.pm view on Meta::CPAN
if ( $tag eq "\x01" || $tag eq "\x02" ) {
# SCALAR_RAW / SCALAR_UTF8
return undef if $$pref + 4 > length($$dref);
my $len = unpack( "N", substr( $$dref, $$pref, 4 ) );
$$pref += 4;
return undef unless defined $len;
return undef if $$pref + $len > length($$dref);
my $val = substr( $$dref, $$pref, $len );
$$pref += $len;
utf8::decode($val) if $tag eq "\x02";
return $val;
}
elsif ( $tag eq "\x03" ) {
# ARRAY
return undef if $$pref + 2 > length($$dref);
my $cnt = unpack( "n", substr( $$dref, $$pref, 2 ) );
$$pref += 2;
return undef unless defined $cnt;
my @arr;
for ( 1 .. $cnt ) {
lib/AmberDB/Base/Encoder.pm view on Meta::CPAN
return undef unless defined $cnt;
my %h;
for ( 1 .. $cnt ) {
return undef if $$pref + 2 > length($$dref);
my $klen = unpack( "n", substr( $$dref, $$pref, 2 ) );
$$pref += 2;
return undef unless defined $klen;
return undef if $$pref + $klen > length($$dref);
my $k = substr( $$dref, $$pref, $klen );
$$pref += $klen;
utf8::decode($k);
$h{$k} = $self->_abr_decode_node( $dref, $pref, ( $depth // 0 ) + 1 );
}
return \%h;
}
return undef;
}
# my $record = $adb->db_encode(@fields);
# my $record = $adb->db_encode(\%hash_data);
# ------------------------------------------------
lib/AmberDB/Base/Facet.pm view on Meta::CPAN
ids => $filtered_ids,
groups => \@groups,
groups_by_blk => \%groups_by_blk,
active_counts => \%active_counts,
counts => \%all_counts,
};
return wantarray ? @groups : $res;
}
=encoding utf8
=head1 NAME
AmberDB::Index::Facet - Column-oriented facet indexing, disjunctive counting, and navigation menu generator
=head1 SYNOPSIS
# Querying from AmberDB instance ($adb inherits AmberDB::Index::Facet):
# 1. Generate full-catalog or filtered facet menu with disjunctive counts:
lib/AmberDB/Locale.pm view on Meta::CPAN
package AmberDB::Locale;
use 5.016;
use warnings;
use utf8;
use Encode qw(decode encode);
use Carp qw(croak cluck);
our $VERSION = '5.25.1';
my $CREATED = '2017-07-22';
my %LOCALE_CACHE;
my %WARNED_LOCALES;
# -------------------------------------------------------
lib/AmberDB/Locale.pm view on Meta::CPAN
# PUBLIC API â UTF-8 Encoding / Decoding & String Operations
# =======================================================
# -------------------------------------------------------
# utf_encode: Converts a Perl Unicode string into raw UTF-8 octets (bytes).
# my $bytes = $lang->utf_encode($string);
# -------------------------------------------------------
sub utf_encode {
my ( $self, $string ) = @_;
return unless defined $string;
utf8::encode($string) if utf8::is_utf8($string);
return $string;
}
# -------------------------------------------------------
# utf_decode: Decodes raw UTF-8 bytes into a Perl Unicode character string.
# my $chars = $lang->utf_decode($string);
# -------------------------------------------------------
sub utf_decode {
my ( $self, $string ) = @_;
return unless defined $string;
utf8::decode($string) unless utf8::is_utf8($string);
return $string;
}
# -------------------------------------------------------
# Locale-aware uppercase.
# Applies uc_map substitutions before Perl's CORE::uc().
# my $upper = $lang->uc($string);
# -------------------------------------------------------
sub uc {
my ( $self, $string ) = @_;
lib/AmberDB/Locale.pm view on Meta::CPAN
$offset = 0;
$length = $_[0];
}
else {
( $offset, $length ) = @_;
}
$length //= length($string);
return $string if $offset == 0 && length($string) <= $length;
my $is_raw = !utf8::is_utf8($string);
my $ustr = $self->utf_decode($string);
my $cut = substr( $ustr, $offset, $length );
return $is_raw ? $self->utf_encode($cut) : $cut;
}
# -------------------------------------------------------
# Month names list accessor for current locale (12 elements)
# my $months = $lang->months();
# -------------------------------------------------------
sub months {
lib/AmberDB/Locale.pm view on Meta::CPAN
# -------------------------------------------------------
# Language tag accessor
# my $tag = $lang->language; # "tr", "en", "de" ...
# -------------------------------------------------------
sub language { return $_[0]->{_lang} }
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale - Multilingual text processing, collation, number/currency formatting, and search normalization engine
=head1 SYNOPSIS
# =========================================================================
# 1. DIRECT USAGE VIA AMBERDB INSTANCE ($adb inherits AmberDB::Locale):
# Reads active language from config (default is 'gb' or configured language)
lib/AmberDB/Locale/Currency.pm view on Meta::CPAN
package AmberDB::Locale::Currency;
use 5.016;
use warnings;
use utf8;
use Carp qw(croak cluck);
our $VERSION = '5.25.1';
my $CREATED = '2026-08-06';
# Master ISO 4217 Currency Dictionary
# Value objects: immutable, static, universal data.
my %CURRENCIES = (
'TRY' => { num => '949', name => 'Turkish Lira', symbol => 'âº', digits => 2 },
'USD' => { num => '840', name => 'US Dollar', symbol => '$', digits => 2 },
lib/AmberDB/Locale/Lang/ar.pm view on Meta::CPAN
package AmberDB::Locale::Lang::ar;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-23';
# -------------------------------------------------------
# Arabic locale data for AmberDB::Locale.
# Pure data module â no logic.
# -------------------------------------------------------
sub data {
lib/AmberDB/Locale/Lang/ar.pm view on Meta::CPAN
},
plural_rule => 'zero{n==0}one{n==1}two{n==2}few{n%100>=3&&n%100<=10}many{n%100>=11&&n%100<=99}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::ar - Arabic Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('ar');
lib/AmberDB/Locale/Lang/az.pm view on Meta::CPAN
package AmberDB::Locale::Lang::az;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-23';
# -------------------------------------------------------
# Azerbaijani locale data for AmberDB::Locale.
# Pure data module â no logic.
#
# Casing rules:
lib/AmberDB/Locale/Lang/az.pm view on Meta::CPAN
},
plural_rule => 'one{n==1}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::az - Azerbaijani Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('az');
lib/AmberDB/Locale/Lang/de.pm view on Meta::CPAN
package AmberDB::Locale::Lang::de;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-22';
# -------------------------------------------------------
# German locale data for AmberDB::Locale.
# Pure data module â no logic.
#
# German-specific sort order:
lib/AmberDB/Locale/Lang/de.pm view on Meta::CPAN
},
plural_rule => 'one{n==1}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::de - German Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('de');
lib/AmberDB/Locale/Lang/en.pm view on Meta::CPAN
package AmberDB::Locale::Lang::en;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-22';
# -------------------------------------------------------
# Pure data module â no logic, no methods other than data().
# Returns a hash-ref consumed by AmberDB::Locale.
#
# Global Base (gb) is the default/fallback locale.
lib/AmberDB/Locale/Lang/en.pm view on Meta::CPAN
},
plural_rule => 'one{n==1}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::en - English Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('en');
lib/AmberDB/Locale/Lang/es.pm view on Meta::CPAN
package AmberDB::Locale::Lang::es;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-23';
# -------------------------------------------------------
# Spanish locale data for AmberDB::Locale.
# Pure data module â no logic.
# -------------------------------------------------------
sub data {
lib/AmberDB/Locale/Lang/es.pm view on Meta::CPAN
},
plural_rule => 'one{n==1}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::es - Spanish Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('es');
lib/AmberDB/Locale/Lang/fr.pm view on Meta::CPAN
package AmberDB::Locale::Lang::fr;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-23';
# -------------------------------------------------------
# French locale data for AmberDB::Locale.
# Pure data module â no logic.
# -------------------------------------------------------
sub data {
lib/AmberDB/Locale/Lang/fr.pm view on Meta::CPAN
},
plural_rule => 'one{n<=1}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::fr - French Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('fr');
lib/AmberDB/Locale/Lang/gb.pm view on Meta::CPAN
package AmberDB::Locale::Lang::gb;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-09-03';
# -------------------------------------------------------
# Global Base (gb) Locale Data for AmberDB::Locale.
#
# Pure data module â no logic, no methods other than data().
#
lib/AmberDB/Locale/Lang/gb.pm view on Meta::CPAN
group_sep => ',',
group_size => 3,
},
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::gb - Global Base Language Definition and Default Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('gb');
lib/AmberDB/Locale/Lang/ja.pm view on Meta::CPAN
package AmberDB::Locale::Lang::ja;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-08-12';
# -------------------------------------------------------
# Japanese (æ¥æ¬èª) locale data for AmberDB::Locale.
# Pure data module â no logic.
# Supports Hiragana, Katakana, Kanji, Romaji transliteration,
# JPY currency formatting, Japanese date formats, and Japanese num2text.
lib/AmberDB/Locale/Lang/ja.pm view on Meta::CPAN
},
plural_rule => 'other', # Japanese has no grammatical plurals
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::ja - Japanese Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('ja');
lib/AmberDB/Locale/Lang/ru.pm view on Meta::CPAN
package AmberDB::Locale::Lang::ru;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-23';
# -------------------------------------------------------
# Russian (Cyrillic) locale data for AmberDB::Locale.
# Pure data module â no logic.
# -------------------------------------------------------
sub data {
lib/AmberDB/Locale/Lang/ru.pm view on Meta::CPAN
},
plural_rule => 'one{n%10==1&&n%100!=11}few{n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)}many{n%10==0||(n%10>=5&&n%10<=9)||(n%100>=11&&n%100<=14)}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::ru - Russian Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('ru');
lib/AmberDB/Locale/Lang/tr.pm view on Meta::CPAN
package AmberDB::Locale::Lang::tr;
use 5.016;
use warnings;
use utf8;
our $VERSION = '5.25.1';
my $CREATED = '2026-07-22';
# -------------------------------------------------------
# Turkish locale data for AmberDB::Locale.
# Pure data module â no logic.
#
# Turkish-specific casing rules (dotted/dotless-I):
lib/AmberDB/Locale/Lang/tr.pm view on Meta::CPAN
},
plural_rule => 'one{n==1}other',
};
}
1;
__END__
=encoding utf8
=head1 NAME
AmberDB::Locale::Lang::tr - Turkish Language Definition and Locale Data for AmberDB
=head1 SYNOPSIS
use AmberDB::Locale;
my $loc = AmberDB::Locale->new('tr');
lib/AmberDB/Tools.pm view on Meta::CPAN
push @{ $table_manifest->{files} }, $arch_path;
my $sha256 = Digest::SHA::sha256_hex($dcontent);
$table_manifest->{sha256}->{$arch_path} = $sha256;
}
$manifest->{tables}->{$tid} = $table_manifest;
}
# Add manifest.json to archive
my $json = JSON::PP->new->utf8->pretty->encode($manifest);
$tar->add_data( "manifest.json", $json );
# Write tar.gz archive
unless ( $tar->write( $outfile, Archive::Tar::COMPRESS_GZIP() ) ) {
cluck "[DB_BACKUP] Failed to write archive $outfile: " . $tar->error() . "\n";
return;
}
$self->{say} .= "Archive successfully written to $outfile (" . ( -s $outfile ) . " bytes)\n";
return wantarray ? ( $outfile, $manifest ) : $outfile;
lib/AmberDB/Tools.pm view on Meta::CPAN
return;
}
# 1. Read and parse manifest.json
my $manifest_content = $tar->get_content("manifest.json");
unless ($manifest_content) {
cluck "[DB_RESTORE] Archive $file is missing manifest.json.\n";
return;
}
my $manifest = eval { JSON::PP->new->utf8->decode($manifest_content) };
if ( $@ || ref($manifest) ne 'HASH' ) {
cluck "[DB_RESTORE] Corrupted manifest.json in $file: $@\n";
return;
}
# 2. Check if target DB is empty or force is set
my $schema_dir = $adb->path('schema_dir')
|| ( $adb->path('dbase_dir') ? $adb->path('dbase_dir') . "/schema" : "schema" );
my $table_dir = $adb->path('table_dir')
|| ( $adb->path('dbase_dir') ? $adb->path('dbase_dir') . "/table" : "table" );
t/amberdb-field_matching_with_index.t view on Meta::CPAN
#!/usr/bin/perl
# t/amberdb-field_matching_with_index.t - Tests for AmberDB field_fetch & field matching with index (.fld)
use 5.016000;
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use File::Temp qw(tempdir);
use File::Spec;
use Encode qw(encode);
use_ok('AmberDB') or BAIL_OUT('Cannot load AmberDB');
my $tmpdir = tempdir( CLEANUP => 1 );
my $adb = AmberDB->new(
path => { dbase_dir => $tmpdir },
t/amberdb-field_matching_without_index.t view on Meta::CPAN
#!/usr/bin/perl
# t/amberdb-field_matching_without_index.t - Tests for AmberDB field_fetch & field matching without index (Table Scan)
use 5.016000;
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use File::Temp qw(tempdir);
use File::Spec;
use Encode qw(encode);
use_ok('AmberDB') or BAIL_OUT('Cannot load AmberDB');
my $tmpdir = tempdir( CLEANUP => 1 );
my $adb = AmberDB->new(
path => { dbase_dir => $tmpdir },
t/amberdb-locale_00.t view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use FindBin qw($Bin);
use lib "$Bin/../lib", 'lib';
use AmberDB::Locale;
# ============================================================
# 1. Constructor â Turkish locale
# ============================================================
my $tr = AmberDB::Locale->new( language => 'tr' );
is( $tr->language, 'tr', 'Constructor: language tag stored' );
t/amberdb-locale_00.t view on Meta::CPAN
# ============================================================
# 12. first_char
# ============================================================
is( $tr->first_char('çay'), 'Ã', 'first_char: çay â Ã' );
is( $tr->first_char('arı'), 'A', 'first_char: arı â A' );
is( $tr->first_char('123'), '0-9', 'first_char: number â 0-9' );
# ============================================================
# 13. substring (locale-independent)
# ============================================================
my $utf8_str = Encode::encode('UTF-8', 'Ãaylık bahçe');
my $sub = $tr->substring($utf8_str, 6);
is( Encode::decode('UTF-8',$sub), 'Ãaylık', 'substring: 6 chars UTF-8' );
# ============================================================
# 14. German locale (de)
# ============================================================
my $de = AmberDB::Locale->new( language => 'de' );
is( $de->language, 'de', 'de locale: loaded' );
is( $de->to_ascii('München'), 'Muenchen', 'de->to_ascii: ü â ue' );
is( $de->to_ascii('StraÃe'), 'Strasse', 'de->to_ascii: Ã â ss' );
t/amberdb-locale_01_casing.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use FindBin qw($Bin);
use lib "$Bin/../lib", 'lib';
use_ok('AmberDB::Locale');
subtest 'Initialization & Caching' => sub {
my $tr1 = AmberDB::Locale->new('tr');
my $tr2 = AmberDB::Locale->new(language => 'turkish');
is( ref($tr1), 'AmberDB::Locale', 'Object created successfully' );
is( $tr1->language, 'tr', 'Language tag normalized to tr' );
t/amberdb-locale_02_ascii.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use FindBin qw($Bin);
use lib "$Bin/../lib", 'lib';
use AmberDB::Locale;
subtest 'Turkish to_ascii & Slug' => sub {
my $tr = AmberDB::Locale->new('tr');
is( $tr->to_ascii('Türkçe karakterler: ç, Ä, ı, ö, Å, ü'), 'Turkce karakterler c, g, i, o, s, u', 'to_ascii normal' );
is( $tr->to_ascii('IÄDIR', 1), 'igdir', 'to_ascii slug: IÄDIR -> igdir' );
is( $tr->to_ascii('İZMİR', 1), 'izmir', 'to_ascii slug: İZMİR -> izmir' );
t/amberdb-locale_03_num2text.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use FindBin qw($Bin);
use lib "$Bin/../lib", 'lib';
use AmberDB::Locale;
subtest 'Turkish num2text Basic & Bug Fixes' => sub {
my $tr = AmberDB::Locale->new('tr');
# Bug fix 1: Negative numbers
is( $tr->num2text(-5), 'Eksi BeÅ TL', 'num2text(-5) -> Eksi BeÅ TL' );
t/amberdb-locale_04_sort.t view on Meta::CPAN
use strict;
use warnings;
use utf8;
use open ':std', ':utf8';
use Test::More;
binmode Test::More->builder->output, ':utf8';
binmode Test::More->builder->failure_output, ':utf8';
binmode Test::More->builder->todo_output, ':utf8';
use FindBin qw($Bin);
use lib "$Bin/../lib", 'lib';
use AmberDB::Locale;
subtest 'Turkish Alphabet Collation Sort' => sub {
my $tr = AmberDB::Locale->new('tr');
my @input = qw(Åeker Ankara Ãilek Bursa İstanbul IÄdır Ãrdek Ãzüm);
my @sorted = $tr->sort(\@input);
my @expected = qw(Ankara Bursa Ãilek IÄdır İstanbul Ãrdek Åeker Ãzüm);