AmberDB

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

          * Removed legacy internal _hash_diff from AmberDB::Tools and switched to $adb->hash_diff directly.
          * Added unit test coverage for hash_diff in t/amberdb_array.t.

5.22.2  2026-09-01
        - [CROSS-PLATFORM & CI] Universal GitHub Actions CI Matrix:
          * Configured multi-platform CI matrix testing on Linux (ubuntu-latest), macOS (macos-latest), and Windows (windows-latest) across Perl 5.16 through 5.40.
          * Configured official Strawberry Perl distribution in CI for native Berkeley DB / DB_File binary compatibility and prevented Git Bash PATH collisions.
        - [STORAGE & TRANSACTIONS] Safe Directory Scanner and Windows File Sharing:
          * Introduced dir_files($dir, [$pattern], [%opts]) helper method in AmberDB::Base for cross-platform, safe file discovery supporting wildcards (*.db, txn_*.txn) and compiled regular expressions (qr/../).
          * Refactored AmberDB::Transact and AmberDB::Tools (dir_tables, all_tables, del_table) to use dir_files, completely removing fragile glob usage.
          * Fixed Windows NTFS file sharing collision in transact_recover: journal lines are now read directly from open locked handles, preventing secondary open permission denied errors.
        - [TESTS & STABILITY] Test Concurrency and Monotonic Sequence:
          * Hardened t/amberdb_transact.t orphan recovery subtest to use strictly monotonic table_autoid record IDs (65) and authentic transaction lifecycle simulation.
          * Guaranteed complete handle and lock cleanup with $adb->close_all() in crash recovery test scenarios.

5.22.1  2026-09-01
        - [DOCS] Documentation and Synopsis Fixes:
          * Fixed synopsis and API example signatures across documentation and POD.
          * Updated README.md installation instructions with streamlined CPAN/cpanm cross-platform support.
          * Fixed character encoding and wide-character warnings in test suite schemas.

Changes  view on Meta::CPAN

        - Declared missing core dependencies (Archive::Tar, Digest::SHA, JSON::PP, Hash::Util) in Makefile.PL and cpanfile.

5.21.0  2026-08-28
        - Fixed schema cache poisoning in restore() and hardened dbase_info()/table_info() against caching empty parse results.
        - Standardized instance variable naming across codebase, test suites, and documentation to $adb (AmberDB Handle):
          * Introduced $adb->config() method supporting scalar get, defensive copy bulk get, and side-effect hook execution (locale reloading, path cache invalidation).
          * Introduced $adb->path() method for standardized path retrieval and modification across core modules and scripts.
          * Enhanced $adb->table_attr() with unified getter/setter and automatic path refresh on schema changes (year, section, lang).
          * Protected $adb->table_info() by returning shallow copies to prevent external reference leaking and unauthorized in-memory state mutations.
          * Refactored all internal core modules (lib/AmberDB.pm, lib/AmberDB/Base.pm, lib/AmberDB/Tools.pm, lib/AmberDB/Transact.pm, lib/AmberDB/Cache.pm, lib/AmberDB/Index/Junk.pm) to interact strictly through accessor methods ($adb->config, $adb->...
          * Enforced restricted hash key access via Hash::Util::lock_keys with private internal naming (_cfg, _path, _table, _dbase, _cache, _db, _txn) and locked container references (Hash::Util::lock_value) against typo/unauthorized overwrites.
          * Added comprehensive unit test suite t/amberdb_encapsulation.t covering all 10 encapsulation scenarios.
        - [MIGRATION NOTICE / BREAKING CHANGE] Standardized schema terminology across the entire codebase and directory layout:
          * UPGRADE ACTION REQUIRED: Existing projects must rename their physical 'dbstore/scheme/' directory to 'dbstore/schema/'.
          * Updated RAM-disk setup scripts (setup_ramdisk.sh, setup_ramdisk.ps1, setup_ramdisk.pl, setup_ramdisk.bat) to mount 'schema/'.
        - Upgraded transaction engine specification to full ACID-Compliance with Strict Two-Phase Locking (Strict 2PL):
          * Enforced Lock-Before-Write and Lock-Before-Read ordering across insert_id, modify_id, and delete_id for true serializable isolation.
          * Introduced 'no_transact => 1' schema attribute and table_attr() support to exempt auxiliary tables from abort cascades while preserving LIFO rollback consistency.
        - Added comprehensive ACID architectural guarantees section to documentation (README.md, Turkish and English User Guides).
        - Clarified architectural distinction between high-throughput batch ETL imports and atomic business transactions.
        - Standardized file open error diagnostics and OS-level reporting ($!) across all core modules:

docs/EN.AmberDB_User-Guide.md  view on Meta::CPAN

the system state becomes corrupted. To eliminate these anomalies, the entire sequence must be unified within a **single transaction spine (`transact_start` $\rightarrow$ `transact_end`)**. If any step encounters an error or if the process crashes, Am...

### 7.2 ACID Guarantees in AmberDB

AmberDB guarantees the four classical ACID properties through embedded flat-file database mechanics:

| ACID Property | Implementation Mechanism & Guarantees |
| :--- | :--- |
| **Atomicity** | **Disk-Backed Undo-Journaling:** When `transact_start()` is called, a microsecond-stamped `.txn` journal is created. Every `insert_id`, `modify_id`, and `delete_id` call appends reverse undo instructions. If a critical base error oc...
| **Consistency** | **Schema, Index, and State Integrity:** Inbound records are validated against schema field rules, data types, and byte limits. Primary keys (`autoid`), inverted word indexes, columnar facets, and URL slugs are synchronized in real...
| **Isolation** | **Strict Two-Phase Locking (Strict 2PL):** Every record modified within an active transaction acquires an exclusive OS-level lock (`flock LOCK_EX`). Locks are held throughout the entire transaction duration, preventing concurrent wo...
| **Durability** | **Synchronous Journaling & Crash Recovery (`transact_recover`):** All journal writes invoke `$fh->flush`. When configured with `cfg => { txn_sync => 1 }`, AmberDB triggers OS/kernel `fsync` (`$fh->sync`) and Berkeley DB cache flush...

> **Architectural Note: Batch ETL Imports vs. Business Transactions**  
> Methods such as `insert_list`, `modify_list`, and `delete_list` are specialized for high-throughput batch imports (e.g., ingesting large XML/JSON product catalogs). Since list records are typically independent entities without cross-dependencies, d...

### 7.3 Transaction Workflow

In the public API, transaction workflows are driven by 3 primary methods:

1. **`transact_start()`**: Opens a microsecond-stamped undo journal (`txn_*`) in `$dbase_dir/journal/` and recovers any orphaned transactions left by dead processes (`transact_recover`).

lib/AmberDB/Base/Transact.pm  view on Meta::CPAN

            cluck "[DB_TXN] Orphan transaction rollback: $orphan\n";
            seek( $ofh, 0, 0 );
            my @lines = <$ofh>;
            flock( $ofh, LOCK_UN );
            close $ofh;

            $self->_txn_apply_rollback(\@lines);
            unlink $orphan;
        }
        else {
            # File is actively locked by a living process — skip safely (race-condition free)
            close $ofh;
            next;
        }
    }

    return 1;
}

# $ts = $adb->_txn_timestamp();
# ------------------------------------------------

t/amberdb_backup.t  view on Meta::CPAN

# =========================================================================
# SUBTEST 4: Tools->restore() and Deterministic Index Rebuilding
# =========================================================================
subtest "4. Database Restore and Index Reconstruction" => sub {
    plan tests => 17;

    my $dump_file = "$tmpdir/backup/test_dump.amberdb";

    # 4.1 Safety check: Restore into non-empty database without force should fail
    my $tools = AmberDB::Tools->new($adb);
    my $blocked_res = $tools->restore( file => $dump_file, force => 0 );
    ok( !defined $blocked_res, "restore() without force on non-empty database returns undef" );

    # 4.2 Create a completely clean staging database directory
    my $stagedir = tempdir( CLEANUP => 1 );
    $stagedir =~ s{\\}{/}g;

    my $stage_adb = AmberDB->new(
        path => { dbase_dir => $stagedir },
        cfg  => { user => "admin", language => "tr" },
    );
    my $stage_tools = AmberDB::Tools->new($stage_adb);

t/amberdb_cli.t  view on Meta::CPAN

};

# ---------------------------------------------------------------------------
subtest '5. CRUD operations & no_write protection' => sub {
    plan tests => 8;

    my $out_conn = `"$perl_bin" -Ilib "$cli_path" connect path-dbase_dir="$test_dbdir" cfg-no_write=1 format=json`;
    my $token = decode_json($out_conn)->{token};

    # Attempt insert when no_write is 1
    my $ins_blocked = `"$perl_bin" -Ilib "$cli_path" token=$token action=insert_id table=cli_items id=1 data='["Book",15]' 2>&1`;
    like($ins_blocked, qr/no_write aktif/, "insert_id blocked when no_write=1");

    # Enable writes in session
    `"$perl_bin" -Ilib "$cli_path" token=$token cfg-no_write=0`;

    # Insert record
    my $ins_ok = `"$perl_bin" -Ilib "$cli_path" token=$token action=insert_id table=cli_items id=1 data='["Book",15]' format=json`;
    my $ins_data = eval { decode_json($ins_ok) };
    is($ins_data->{status}, 'ok', "insert_id succeeded after enabling writes");
    is($ins_data->{id}, 1, "Inserted record ID is 1");

t/amberdb_security_paths.t  view on Meta::CPAN

    is( $res->{errors}->[0]->{context}, "test_table.db", "Correct error context captured" );
};

# ---------------------------------------------------------------------------
subtest '5. _eval_plural_rule hardening' => sub {
    plan tests => 4;

    ok( $adb->_eval_plural_rule("n == 1", 1), "n == 1 true for 1" );
    ok( !$adb->_eval_plural_rule("n == 1", 5), "n == 1 false for 5" );
    ok( !$adb->_eval_plural_rule("n / 0 == 1", 2), "Division by zero returns 0 safely without dying" );
    ok( !$adb->_eval_plural_rule("system('dir')", 1), "Code injection strictly blocked by whitelist" );
};

done_testing();

t/amberdb_transact.t  view on Meta::CPAN

    ok( -e $orphan_file, 'Orphan journal file created for test' );

    # Call recover orphans
    $adb->transact_recover();

    ok( !-e $orphan_file, 'Orphan journal file removed after recovery' );

    my @rec65 = $adb->read_id( 'test_table', 65 );
    is( scalar(@rec65), 0, 'Orphaned insert was rolled back' );

    # 2. Test active locked journal protection
    my $locked_file = File::Spec->catfile( $journal_dir, 'txn_locked_test_888888' );
    open my $lfh, '+>>', $locked_file or die "Cannot create locked test file: $!";
    use Fcntl qw(:flock);
    flock( $lfh, LOCK_EX ); # Actively lock file

    $adb->transact_recover();
    ok( -e $locked_file, 'Actively locked journal file is NOT removed by orphan recovery' );

    flock( $lfh, LOCK_UN );
    close $lfh;
    unlink $locked_file;
    ok( !-e $locked_file, 'Locked test file cleaned up' );
};

# ---------------------------------------------------------------------------
subtest 'Transaction Durability with txn_sync' => sub {
    plan tests => 4;

    my $sync_adb = AmberDB->new(
        cfg  => { language => 'tr', txn_sync => 1 },
        path => { dbase_dir => $tmpdir }
    );



( run in 1.230 second using v1.01-cache-2.11-cpan-800906f7e73 )