AmberDB

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

          * 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);



( run in 1.335 second using v1.01-cache-2.11-cpan-364913b4093 )