AmberDB

 view release on metacpan or  search on metacpan

docs/TR.AmberDB_Veritabani_Sistemi.md  view on Meta::CPAN


### 5.4 İndekssiz Doğrudan Sorgulama ve Filtreleme

İkincil indeks dosyaları üretilmediği için sorgular doğrudan `.db` veri akışı üzerinden sıralı tarama (`recs_scan`) ile yürütülür:

1. **Tüm Tabloyu Okuma ve Sayfalama (`read_all`):**
   ```perl
   # Tüm kayıtlar veya sayfalama (start => 0, limit => 10)
   my ( $toplam, @kayitlar ) = $adb->read_all( 'items', 0, 10 );
   
   # Sadece anahtar listesi alma
   my @anahtarlar = $adb->read_all( 'items', keys_only => 1 );
   
   # Bellek içi sıralama (Blok 3'e göre artan: -3, azalan: 3)
   my @sirali = $adb->read_all( 'items', sort => -3, keys_only => 1 );
   ```

2. **Alana Göre Eşleştirme (`field_fetch`):**
   ```perl
   # Blok 2: Kategori = 'Giyim' olanları getir
   my @giyimler = $adb->field_fetch( 'catalog', 2, 'Giyim' );
   
   # Çoklu değer eşleme (Blok 3: Renk in ['Mavi', 'Siyah'])
   my ( $adet, @sonuclar ) = $adb->field_fetch( 'catalog', 3, [ 'Mavi', 'Siyah' ], 0, 20, sort => -4 );
   ```

3. **Tam Metin Arama (`search_table`):**
   ```perl
   # Türkçe normalizasyonlu kelime araması (AND mantığı)
   my @haberler = $adb->search_table( 'articles', 'türkiye ekonomi' );
   
   # Alan filtresiyle birlikte arama (Blok 2: Kategori = 'Finans')
   my ( $sayi, @filtrelenmis ) = $adb->search_table( 'articles', 'faiz', 0, 10, filter => [ 2, 'Finans' ] );
   ```

---

### 5.5 İşlemler (Transactions - ACID Desteği)

Basit modda `transact_start`, `transact_commit` ve `transact_rollback` ACID desteği tam olarak çalışır. Geri alma (`rollback`) tetiklendiğinde ham `.db` dosyasındaki ekleme, düzenleme ve silmeler anında eski haline döndürülür:

```perl
$adb->transact_start();
eval {
    $adb->insert_id( 'sessions', 'token_123', 'GeciciVeri', time() );
    # Beklenmeyen bir hata oluÅŸtuÄŸunda:
    die "Kritik islem hatasi" if $hata_var;
    $adb->transact_end();
};
if ($@) {
    $adb->transact_rollback(); # token_123 kaydı .db dosyasından tamamen silinir
}
```

---

### 5.6 Günlük Sürekli Yedekleme Günlükleri (Daily Backup Logs - `recs_back`)

Basit mod şemadan bağımsız olduğundan, **metin tabanlı sürekli denetim ve kurtarma akışı (`recs_back`)** basit modda da varsayılan olarak devrededir.

Basit modun düz dizin yapısı gereği ayrı bir `backup/` veya `YYYY/` alt klasörü oluşturulmaz; yapılan her `insert_id` (`add`), `modify_id` (`edit`) ve `delete_id` (`del`) işlemi doğrudan tablolarla aynı dizinde bulunan **`$dbase_dir/YYYY-...

```text
2026-08-31 14:30:00    admin    add     sessions    sess_token_99999    Aktif\x1f192.168.1.50
2026-08-31 14:31:15    admin    edit    sessions    sess_token_99999    Kapali\x1f192.168.1.50
2026-08-31 14:32:00    admin    del     sessions    sess_token_99999    
```

- İstenirse `cfg => { no_backup => 1 }` veya `$adb->config(no_backup => 1)` ile yedekleme günlükleri devre dışı bırakılabilir.
- Özel bir yedek dizini tanımlanmak istendiğinde `path => { backup_dir => "/harici/yedek/yolu" }` verilebilir.

---

### 5.7 Basit Modda RAM-Disk Mimarisi ve Önbellekleme

AmberDB standart modda RAM-disk önbelleğini şemadaki `use_cache => 2` kuralı ile `dbstore/cache` alt dizinine kopyalayarak yönetir.

**Basit modda ise RAM-disk kullanımı çok daha doğrudan ve esnektir:**  
Basit mod şemaya ihtiyaç duymadığından, yüksek performanslı bir bellek önbelleği / geçici oturum deposu oluşturmak için ikinci bir AmberDB basit nesnesi doğrudan RAM-disk yoluna bağlanır:

```perl
# 1. Kalıcı disk nesnesi (Kalıcı veriler için)
my $db_kalici = AmberDB->new(
    path => { dbase_dir => "/var/data/eticaret/dbstore/tables" },
    cfg  => { simple => 1 },
);

# 2. RAM-Disk nesnesi (Sıfır gecikmeli hızlı oturum/önbellek tabloları için)
# (Linux: /dev/shm veya tmpfs, Windows: ImDisk / RamDisk sürücüsü)
my $db_ramdisk = AmberDB->new(
    path => { dbase_dir => "/dev/shm/amber_cache" },
    cfg  => { simple => 1, no_backup => 1 }, # Önbellek için yedekleme kapatılabilir
);

# RAM üzerinde nanosaniye hızında oturum okuma/yazma:
$db_ramdisk->insert_id( "oturumlar", $session_token, $user_id, time() );
my @oturum = $db_ramdisk->read_id( "oturumlar", $session_token );
```

Bu çift nesneli mimari sayesinde:
- RAM-disk üzerindeki tablolar disk I/O darboğazına takılmadan bellek hızında çalışır.
- Kalıcı tablolar ana depolama alanında güvenle tutulmaya devam eder.
- Şema dosyası hazırlama zorunluluğu olmadan saniyeler içinde dinamik önbellek tabloları açılabilir.

---

### 5.8 Basit Mod: Yetenekler ve Kısıtlamalar Karşılaştırması

| Özellik / Mekanizma | Standart Mod (`simple => 0`) | Basit Mod (`simple => 1`) |
| :--- | :---: | :---: |
| **Şema Dosyaları (`.table`, `.dbase`)** | Zorunlu / Kullanılır | Yok / Şemasız |
| **Özel ve Uzun ID'ler (UUID, E-posta, vb.)** | 8 Bayt / ASCII Kısıtlı | **Tamamen Serbest** |
| **Tekil CRUD (`insert_id`, `read_id`, vb.)** | $O(1)$ | **$O(1)$ (Maksimum Hız)** |
| **Toplu İşlemler (`insert_list`, vb.)** | Desteklenir | Desteklenir |
| **Tüm Tablo Okuma (`read_all`)** | `.inx` veya doğrudan | Doğrudan Dosya Taraması |
| **Sayfalama (`start`/`limit`) ve `keys_only`** | Desteklenir | Desteklenir |
| **Bellek İçi Sıralama (`sort => 2`)** | Desteklenir | Desteklenir |
| **Alana Göre Filtre (`field_fetch`)** | `.fld` İndeksli $O(1)$ | Sıralı Dosya Taraması |
| **Tam Metin Arama (`search_table`)** | `.src` Ters İndeksli | Sıralı Dosya Taraması (Türkçe Normalizasyonlu) |
| **ACID İşlemler (`transact_*`)** | Desteklenir (İndeks Geri Alma Dahil) | **Desteklenir (Ham Veri Geri Alma)** |
| **Sürekli Yedekleme Akışı (`recs_back`)** | Desteklenir (`backup/YYYY/`) | **Desteklenir (Aynı Dizinde `YYYY-MM-DD.csv`)** |
| **İkincil İndeksler (`.inx, .fld, .src, .srt, .fac`)** | Oluşturulur ve Güncellenir | **Oluşturulmaz (Sıfır İndeks Maliyeti)** |
| **URL Slug Rewrite (`.slg`)** | Otomatik Üretilir | Devre Dışı |
| **Denetim İzi (`.aut`) ve Arşiv (`.del`)** | Şema Kuralına Göre Tutulur | Devre Dışı |
| **Dizin Yapısı** | `tables/`, `schema/`, `backup/` vb. | **Düz Kök Dizin (`$dbase_dir/<tablo>.db`)** |
| **İkincil İndeksler (`.inx, .fld, .src, .srt, .fac`)** | Oluşturulur ve Güncellenir | **Oluşturulmaz (Sıfır İndeks Maliyeti)** |
| **URL Slug Rewrite (`.slg`)** | Otomatik Üretilir | Devre Dışı |
| **Denetim İzi (`.aut`) ve Arşiv (`.del`)** | Şema Kuralına Göre Tutulur | Devre Dışı |
| **Dizin Yapısı** | `tables/`, `schema/`, `backup/` vb. | **Düz Kök Dizin (`$dbase_dir/<tablo>.db`)** |

---

## 6. İndeksleme ve Arama Mekanizması

AmberDB, tablolara hızlı erişim sağlamak için veriyi şemada tanımlanan kurallara göre ikili (binary) indeks dosyalarına yazar.

### 6.1 İndeks Türleri

| Dosya Uzantısı | İndeks Türü | Açıklama |
|---|---|---|
| `.inx` | Kayıt İndeksi | Tablodaki tüm aktif ID'lerin sıralı ikili dizisi, toplam kayıt ve son ID bilgisi. |
| `.fld` | Eşleştirme (Match) | Blok bazlı değer eşleştirmesi (`field_fetch`). Değer → ID ikili dizisi. |
| `.str` | Alan Sözlüğü (Dictionary) | `.fld` eşlikçisi; serbest metinleri sayısal ID'lere bağlayan çift yönlü sözlük (`_${blk}.str`). |
| `.src` | Tam Metin (Search) | Kelime bazlı ters indeks (`search_table`). Kelime → ID ikili dizisi. |
| `.srt` | Sıralama (Sort) | Belirlenen bloklara göre önceden sıralanmış ikili RID dizisi (`sort_block`). |
| `.fac` | Facet İndeksi | E-ticaret filtreleme panelleri için kayıt başına aktiflik ve özellik haritası. |
| `.slg` | Slug Haritası | `_0.slg` (ID → Slug) ve `_1.slg` (Slug → ID) çift yönlü URL eşleştiricisi. |

### 6.2 8-Bayt İkili (Binary) Paketleme Standardı

AmberDB, indeks dosyalarında maksimum performans ve minimum disk boyutu elde etmek için **8-baytlık homojen ikili paketleme** kullanır:
- **Sayısal ID'ler (`id_type => "num"`):** `Q*` (64-bit unsigned integer) olarak paketlenir.
- **Metin ID'ler (`id_type => "ascii"`):** `a8*` (8 bayt sabit uzunluklu) olarak paketlenir.

Bu sayede milyonlarca kayıt içeren indeks dosyalarında sayfalama (`LIMIT/OFFSET`), belleğe tüm listeyi yüklemeden doğrudan `substr` ile $O(1)$ zero-copy ikili ofset dilimleme yöntemiyle gerçekleştirilir.

### 6.3 Eşleştirme İndeksi (`.fld`) ve Çift Yönlü Alan Sözlüğü (`.str`)

AmberDB'de `match_block` içinde tanımlanan alanlar için indeksleme iki tamamlayıcı katmanda gerçekleşir:

1. **İkili Eşleştirme İndeksi (`.fld`):**  
   Her bir alan için `<tablo>_<blok>.fld` dosyası tutulur. Bu dosya, tekil değer anahtarları karşılığında ilgili kayıt ID'lerini 8-baytlık ikili paketlenmiş diziler (`Q*` / `a8*`) olarak saklar. `field_fetch` sorguları bu dosyadan doğru...

2. **Çift Yönlü Alan Sözlüğü (`.str`):**  
   Eğer indekslenen alan serbest metin (kategori adı, marka adı, yazar, etiket vb.) içeriyorsa, motor otomatik olarak `<tablo>_<blok>.str` sözlük dosyasını yönetir:
   * **İleri Yön (`s:<metin>` $\rightarrow$ `$nid`):** Metin ifadelerine benzersiz artan sayısal bir kimlik (`$nid`) atar.
   * **Geri Yön (`n:$nid` $\rightarrow$ `<metin>`):** Sayısal kimlikten orijinal metin etiketine anında dönüş sağlar.
   * **Otomatik Çözümleme:** `field_fetch` veya `field_filter` çağrıldığında geliştirici ister sayısal ID (`12`) ister metin dizesi (`"Sony"`) versin, motor `.str` sözlüğünden değeri otomatik çözümler ve `.fld` üzerinden anında e...

### 6.4 Sıralama Mekanizması ve Kullanım Rehberi

AmberDB, tablolardaki belirli bloklara göre yüksek performanslı ve önceden indekslenmiş sıralama yeteneği sunar.

#### 6.4.1 Şema Yapılandırması (`sort_block`)
Sıralama yapılacak alanlar tablo şema dosyasında (`.table`) tanımlanır. Sadece blok numarası verilebileceği gibi (`4`), sayısal veya tarihsel alanlar için tip (`type`) belirtilebilir:

```perl
# dbstore/schema/catalog_product.table
{
    id_type    => 'num',
    sort_block => [
        4,                             # Blok 4: Başlık (Metin sıralaması)
        { blk => 10, type => 'num' },  # Blok 10: Fiyat (Sayısal sıralama)
        { blk => 12, type => 'date' }, # Blok 12: Tarih sıralaması (YYYYMMDDHHMMSS)
    ],
}
```

#### 6.4.2 Sorgularda Sıralama Kullanımı

docs/TR.AmberDB_Veritabani_Sistemi.md  view on Meta::CPAN

my @yeni_urunler = (
    [ 0, "5",    "3", "Kablosuz Kulaklık", "149.90", "2026-08-28", "1" ],
    [ 0, "5,12", "8", "Mekanik Klavye",    "299.00", "2026-08-28", "1" ],
    [ 0, "12",   "3", "Oyuncu Faresi",     "89.50",  "2026-08-28", "1" ],
    # ... yüzlerce kayıt ...
);

my $statu = $adb->insert_list("catalog_product", @yeni_urunler);
# $statu hashref döner: { 101 => 1, 102 => 1, 103 => 1, ... }
```

### 8.3 Toplu Kayıt Güncelleme (`modify_list`)

```perl
my @guncellemeler = (
    [ 101, "5",    "3", "Kablosuz Kulaklık Pro", "179.90", "2026-08-28", "1" ],
    [ 102, "5,12", "8", "Mekanik Klavye RGB",    "329.00", "2026-08-28", "1" ],
);

my $statu = $adb->modify_list("catalog_product", @guncellemeler);
```

### 8.4 Toplu Kayıt Silme (`delete_list`)

```perl
# Silinecek ID'ler doğrudan liste veya dizi referansı olarak verilebilir
my $statu = $adb->delete_list("catalog_product", 101, 102, 103);
# veya:
# $adb->delete_list("catalog_product", [101, 102, 103]);
```

### 8.5 Büyük Veri Yüklemelerinde (ETL) Chunk (Dilimleme) Stratejisi

Çok büyük veri setlerinde (örn. 50.000+ kayıt), RAM tüketimini optimize etmek ve disk buffer'ını rahatlatmak için verileri 500-1000'lik parçalara bölerek aktarmak en iyi pratiktir:

```perl
my $chunk_size = 1000;
for (my $i = 0; $i < @buyuk_veri; $i += $chunk_size) {
    my $end = $i + $chunk_size - 1;
    $end = $#buyuk_veri if $end > $#buyuk_veri;
    my @chunk = @buyuk_veri[$i .. $end];
    $adb->insert_list("catalog_product", @chunk);
}
```

---

## 9. Şema Yapılandırması (.table ve Kod İçi / In-Memory)

AmberDB şema güdümlü (schema-driven) bir veritabanı motorudur. Tablo şemaları; birincil anahtar kısıtlamalarını, alan tiplerini, çok boyutlu indeksleri, otomatik slug kaydı üretimini, facet filtrelerini, yaşam döngüsü (junk) kuralla...

### 9.1 Veritabanı ve Tablo Dizin Yapısı

AmberDB tabloları, şemaları ve geçici/kalıcı dosyaları, belirlenen `dbstore` ana veri dizini altında fiziksel klasörlere ayrılarak saklanır:

| Dizin | Görevi |
|---|---|
| `dbstore/tables/` | Kalıcı `.db` ana veri, `.inx` kayıt indeksi, `.fld` eşleştirme, `.src` arama, `.fac` facet, `.srt` sıralama ve `.slg` slug dosyaları |
| `dbstore/schema/` | Kalıcı `.table` tablo şemaları ve `.dbase` grup yapılandırma dosyaları |
| `dbstore/conf/` | Kalıcı `.conf` düz metin ayar ve konfigürasyon dosyaları |
| `dbstore/backup/` | Günlük CSV denetim yedekleri (`dbgun/YYYYMMDD/`) |
| `dbstore/cache/` | **Birleşik RAM-Disk (ImDisk/tmpfs) Kök Dizini:** |
| `dbstore/cache/tables/` | `use_cache => 1 & 2` için RAM'e aynalanmış sıcak `.db` ve `.inx` tabloları |
| `dbstore/cache/conf/` | Derlenmiş hızlı yapılandırma önbelleği (`*.pl` hash referansları) |
| `dbstore/cache/schema/` | RAM'de önbelleğe alınmış / derlenmiş tablo şemaları (`*.table`, `*.dbase`) |
| `dbstore/cache/lock/` | Yalnızca RAM'de yaşayan kayıt ve tablo seviyesi `flock` kilitleri (`*.lock`) |
| `dbstore/cache/pids/` | Yalnızca RAM'de yaşayan süreç kilitleri, login attempt hataları (`*.pid`, `*.error`) |

> [!IMPORTANT]
> **Sürüm 5.21.0 Geçiş Uyarısı:** Eski projelerden yükseltme yaparken yapmanız gereken tek fiziksel işlem; veritabanı dizininizdeki `dbstore/scheme/` klasörünün adını **`dbstore/schema/`** olarak yeniden adlandırmaktır. Kod ve API ta...

### 9.2 Şemanın Rolü ve Esnekliği: Zorunlu mu, İsteğe Bağlı mı?

AmberDB'de şema tasarımı **tamamen esnek ve katmanlıdır**:

* **Minimalist / Hafif Kullanım:** Şema dosyasında `blocks` (alan listesi) tanımlamak **zorunlu değildir**. Sadece hangi blokların indeksleneceğini belirten `record_index`, `match_block`, `search_block` ve `sort_block` tanımlanarak ultra hafi...

```perl
# dbstore/schema/catalog_product.table
{
    name         => "Ürün Kataloğu",
    id_type      => "num",                  # "num" (64-bit uint) veya "ascii" (max 8 bayt)
    record_index => 1,                      # .inx birincil indeksini ve auto-increment sayacını açar
    match_block  => [ 1, 2, 3, 11 ],        # .fld Birebir eşleşme (Kategori, Marka, Yazar, Statü)
    search_block => [ 4, 5, 7, 9 ],         # .src Tam metin arama (Ad, Alt Başlık, Açıklama, Barkod)
    sort_block   => [ 4, { blk => 10, type => 'num' } ], # .srt Önceden sıralanmış binary ID indeksleri
    keep_deleted => 1,                      # Silinenleri .del dosyasında sakla (Soft-delete)
    log_owner    => 1,                      # Değişiklikleri yapan kullanıcıyı .aut dosyasına yaz
    
}
```

* **Gelişmiş / Form ve Doğrulama Destekli Kullanım:** `blocks` dizisi tanımlandığında; alan veri tipleri (`type`), form arayüz giriş bileşenleri (`input`), zorunlu/geçerli alan doğrulamaları (`valid`) ve ilişkili tablo eşleşmeleri (`...

### 9.3 Şema Tanımlama ve Okuma Yöntemleri (`table_info` & `table_attr`)

AmberDB'de şema iki şekilde tanımlanabilir ve programatik olarak okunabilir:

1. **Fiziksel Dosya Tabanlı Şema (Önerilen):**  
   Tablo şemaları `dbstore/schema/<tablo_adi>.table` dosyasına yerleştirilir. AmberDB ilk erişimde bu dosyayı otomatik olarak okur ve ayrıştırır.

2. **Bellek İçi Dinamik Şema (Programmatic / In-Memory):**  
   Disk dosyasına gerek kalmadan doğrudan `$adb->table_attr("tablo_adi", { ... })` metoduyla çalışma zamanında tanımlanır.

3. **Yüklü Şemayı Okuma (`table_info`):**  
   Tanımlı bir tablonun tüm şema konfigürasyonunu bellekten veya diskten hash referansı olarak almak için `$adb->table_info($tablo_adi)` kullanılır:
   ```perl
   my $schema = $adb->table_info("catalog_product");
   print "Tablo Adı: $schema->{name}\n";
   print "Arama Blokları: " . join(", ", @{ $schema->{search_block} || [] }) . "\n";
   ```

> [!IMPORTANT]
> **Şema Dosyaları (`.table` ve `.dbase`) Doğal Perl Kodudur (Hash Reference)**  
> AmberDB'de `.table` ve `.dbase` dosyaları JSON veya YAML değil, doğrudan Perl sözdizimiyle (`{ ... }`) yazılmış doğal Perl hash referansı yapılarıdır. Motor bu dosyaları çalışma zamanında Perl'in yerel `do` ifadesi ile dinamik olar...
>
> * **Sözdizimi Hatası Koruması:** Dosyada eksik virgül (`,`), kapatılmamış parantez (`}` veya `]`), hatalı tırnak işareti veya geçersiz bir Perl karakteri bulunursa `do` işlemi `undef` döner ve motor şemayı **kesinlikle yükleyemez** ...
> * **Doğrulama İpucu:** Şema dosyalarınızı kaydettikten sonra terminalden `perl -c dbstore/schema/tablo.table` komutuyla derleme kontrolü yaparak sözdizimi hatalarını anında görebilirsiniz.

### 9.4 Şema Dosyası Eşleşme Kuralları

docs/TR.AmberDB_Veritabani_Sistemi.md  view on Meta::CPAN

```

### Önbellek Seviyeleri (`use_cache`)
* **`0` (Kapalı):** Önbellekleme yapılmaz.
* **`1` (Soft Cache):** `lastid`, `keys`, `count` meta verileri `cache/${tablo}.inx` dosyasında önbelleklenir. Manuel çağrılan `$adb->cache_write` ve `$adb->cache_read` sorguları çalışır. Tekil okumalarda diske gereksiz dosya yazılmaz.
* **`2` (Hard Cache - Tam Tablo RAM Aynası):** Tablo verileri `cache/${tablo}.db` ve index dosyaları RAM üzerinde tutulur. Okumalar (`read_id`, `read_list`) doğrudan RAM'den döner. Sunucu çalıştığı sürece veriler RAM'den paylaşımlı ola...

### Manuel Önbellek Yönetimi
Tablo şemasında use_cache değeri 1 olduğunda cache_write, cache_read, cache_delete gibi metodları manuel kullanarak istediğiniz kayıtları cachelemenize izin verir.

```perl
# 1. Önbelleğe Manuel Veri Yazma (cache/${tablo}.inx içine yazar)
$adb->cache_write("catalog_product", "vitrin_urunleri", @vitrin_listesi);

# 2. Önbellekten Okuma
my @vitrin = $adb->cache_read("catalog_product", "vitrin_urunleri");

# 3. Hard Cache Tablo Preload (Tüm tabloyu RAM'e kopyalar)
$adb->cache_preload("catalog_category");

# 4. Önbellek Temizleme (Tabloda modify veya delete yapıldığında otomatik temizlenir)
$adb->cache_delete("catalog_product", "vitrin_urunleri"); # Tek anahtar
$adb->cache_delete("catalog_product");                    # Tüm tablo önbelleği (.db ve .inx)

# 5. RAM-Disk Tanı ve Bağlantı Durumu Kontrolü
my $cache_tanisi = $adb->cache_setup();
# Dönen hashref: { is_mounted => 1, mount_desc => "...", cache_dir => "...", cache_size => "512M" }
```

### Otomatik RAM Önbellek
Tablo şemasında use_cache değeri 2 olarak belirtilmişse tablonun ve indexlerinin bir kopyasını RAM üzerine kopyalar ve okuma yazma RAM üzerinden çok hızlı bir şekilde gerçekleşir. Redis gibi. Ancak AmberDB bu tabloya yazdığı zaman ca...

Ayrıca AmberDB motorun bazı işlemlerini de cache üzerinde gerçekleştirir. .lock dosyaları, .pid dosyaları, sessionlar, konfig dosyaları ve şemalar da RAM disk üzerinden okunur.

### Önbellek Süresi (`cache_ttl`) ve Çalışma Zamanı Yönetimi
`cache_ttl` değeri tablo bazında doğrudan şemada tanımlanır (örn: `cache_ttl => 1800`). Session veya PID gibi geçici tabloların önbellek süreleri şemada belirtilebileceği gibi, çalışma zamanında `table_attr` ile dinamik olarak da tan...

```perl
# Session tablosunun önbellek süresini 30 dakikaya (1800 sn) ayarlama
$adb->table_attr("session", { use_cache => 1, cache_ttl => 1800 });
```

### Disk Tabanlı Geçici Buffer
Büyük veri aktarımlarında veya raporlama işlemlerinde geçici disk buffer'ı kullanılır:
```perl
$adb->buffer_write("rapor_gecici", @buyuk_veri);  # yaz
my @veri = $adb->buffer_read("rapor_gecici");     # oku
$adb->buffer_delete("rapor_gecici");              # sil
```

---

## 14. Yapılandırma ve Deterministik Bayrak Yönetimi (`config`)

AmberDB'nin çalışma modunu değiştirmek ve yapılandırma bayraklarını güvenli bir şekilde yönetmek için `$adb->config()` metodu kullanılır:

```perl
# Toplu veya tekli yapılandırma ataması (Önerilen)
$adb->config(
    no_write   => 1,              # Bakım modu: Tüm yazma işlemlerini engelle
    no_backup  => 1,              # Tüm tablolar için günlük CSV denetim yedeklerini kapat
    simple     => 1,              # İndekssiz doğrudan yazım modu (İkincil indeksler devre dışı bırakılır)
    keys_only  => 1,              # read_all çağrılarında sadece ID'leri döndür
    cache_size => '1024M',        # RAM-Disk / tmpfs önbellek boyutu (Varsayılan: 512M)
);

# Tekil okuma:
my $no_write = $adb->config('no_write');

# Toplu okuma (Güvenli kopya döner):
my $cfg = $adb->config();
```

---

## 15. Veri Yapıları, Düşük Seviyeli Tablo ve Akış İşlemleri

AmberDB, standart CRUD katmanının altında doğrudan `DB_File` C seviyesi optimizasyonlarına ve ham akış işlemlerine erişim sunar:

### 15.1 Veri Yapıları ve Serialization (`db_encode`, `db_decode`)

AmberDB, karmaşık Perl yapılarını özel ayıraçlarla yüksek hızda dizgeleştirir (serialize eder):

```perl
# Encode: Perl Verisi → String
my $str = $adb->db_encode("Metin", [ 1, 2, 3 ], { key => "val" });

# Decode: String → Perl Verisi
my ($metin, $dizi_ref, $hash_ref) = $adb->db_decode($str);
```

### 15.2 Düşük Seviyeli Tablo ve Akış Yönetimi (`table_read`, `table_write`, `table_close`)

Büyük veri aktarımlarında veya özel toplu işlerde dosya oturumu açıp kapatmak için kullanılır:

```perl
my $tablo_yolu = $adb->table_path("catalog_product") . ".db";

# 1. Yazma/Okuma Modunda Tablo Açma ve Kilit Uygulama (flock LOCK_EX)
my $db_obj = $adb->table_write($tablo_yolu);

# 2. Salt-Okunur Modda Tablo Açma (O_RDONLY)
my $db_ro  = $adb->table_read($tablo_yolu);

# 3. Tabloyu Senkronize Etme (sync), Kilidi Çözme ve Kapatma
$adb->table_close($tablo_yolu);
```

### 15.3 Ham Kayıt İşleme Metodları (`recs_get`, `recs_put`, `recs_del`, `recs_exist`, `recs_keys`, `recs_scan`, `table_readid`)

Açık veya otomatik açılan dosya oturumu üzerinde doğrudan `$db->get()`, `$db->put()`, `$db->del()` çağrıları yaparak maksimum performans sağlar:

```perl
# 1. Ham DeÄŸerleri Toplu Okuma (recs_get)
my $ham_veriler = $adb->recs_get($tablo_yolu, 5001, 5002);
# $ham_veriler döner: { 5001 => "ham_veri_stringi", 5002 => "..." }

# 2. Otomatik Dosya Oturumu ile Tek Kayıt Okuma (table_readid)
my ($rid, @kayit) = $adb->table_readid($tablo_yolu, 5001);

# 3. Ham Kayıtları Toplu Yazma (recs_put)

docs/TR.AmberDB_Veritabani_Sistemi.md  view on Meta::CPAN

    \%secilen_filtreler,
    $table_info->{facet_block},
    { limit => 10, sort => "count" } # En çok ürünü olan ilk 10 filtreyi göster
);

# $menu çıktısı doğrudan şablona gönderilmeye hazırdır:
{
    count         => 42,                         # Filtrelere uyan toplam ürün sayısı
    ids           => [ 101, 105, 120, ... ],     # Ekranda listelenecek ürünlerin ID'leri
    active_counts => { 1 => 1, 2 => 2 },         # Blok bazında aktif filtre sayısı
    groups        => [                           # HTML sol menüsü için hazır gruplar:
        {
            blk          => 2,
            name         => "Marka",
            active       => "1",
            active_count => 2,
            records      => [
                { uid => "fc_2_12", param => "f2", val => 12, label => "İthaki", count => 28, checked => "1" },
                { uid => "fc_2_14", param => "f2", val => 14, label => "Can",    count => 14, checked => "1" },
                { uid => "fc_2_19", param => "f2", val => 19, label => "YKY",    count => 6,  checked => ""  },
            ]
        },
        ...
    ]
}
```

#### B. Arama Sonuçları Sayfasında Dinamik Filtre Üretme
Arama yapıldığında, bulunan ürünlerin ID listesini `base_ids` olarak vererek filtrenin sadece arama sonuçlarını kapsamasını sağlarsınız:

```perl
# 1. Ziyaretçinin arama terimiyle ürünleri bul (keys_only ile limitsiz ID listesi)
my @bulunan_idler = $adb->search_table("catalog_product", "bilim kurgu", keys_only => 1);

# 2. Sadece bulunan bu ürünler arasından filtre menüsü üret
my $arama_menusu = $adb->facet_menu(
    "catalog_attributes",
    \%secilen_filtreler,
    $table_info->{facet_block},
    { base_ids => \@bulunan_idler }
);
```

---

## 17. Kullanıcı Denetim İzi (Audit) ve Yedekleme

### 17.1 Kullanıcı İşlem Geçmişi (`log_owner`)
Şemada `log_owner => 1` aktif olduğunda, kaydın tüm geçmişi `.aut` dosyasında tutulur:

```perl
# Bir kaydın kimler tarafından ne zaman değiştirildiğini HTML olarak alma
my $gecmis_html = $adb->auth_view("catalog_product", 5001);
print $gecmis_html;
# Çıktı:
#     add     2026-08-14 10:15    admin_maruf
#     edit    2026-08-14 11:30    editor_ali
```

### 17.2 Sürekli Değişiklik Akışı (Continuous Recovery Stream — `YYYY-MM-DD.csv`)
AmberDB yapılan her `insert`, `modify` ve `delete` işlemini kronolojik zaman-serisi olarak `backup/YYYY/YYYY-MM-DD.csv` dosyasına otomatik olarak ekler (append-only).

Her satır tab ayrılmış (`\t`) olarak şu sütun yapısında yazılır:
`[Zaman Damgası] \t [Kullanıcı] \t [İşlem] \t [Tablo] \t [Kayıt ID] \t [Paketlenmiş Değerler]`

Bu akışı devre dışı bırakmak için:
* **Tablo Şemasında (Tablo Bazlı):** Şema dosyasına `no_backup => 1` eklenirse sadece o tablo için yedekleme kapatılır.
* **Genel Düzeyde (Tüm Tablolar):** `$adb->config(no_backup => 1);` tanımlanırsa tüm tablolar için yedekleme kapatılır.

### 17.3 Native Veritabanı Arşivi (`.amberdb` Dump & Restore)
AmberDB, tüm şemaları (`schema/*.table`, `schema/*.dbase`) ve otoriter veri dosyalarını (`tables/*.db`, `tables/*.del`, `tables/*.aut`, `tables/*.cnt`) SHA-256 doğrulama özetleriyle birlikte fiziksel dizin yapısıyla birebir örtüşen sıkı...

Türetilmiş indeks dosyaları (`.inx`, `.src`, `.fld`, `.fac`, `.srt`) boyuttan tasarruf etmek için arşiv içine konmaz; `restore` esnasında şema kurallarına göre `set_index` ile deterministik olarak sıfırdan üretilir.

```perl
use AmberDB;
use AmberDB::Tools;

my $adb   = AmberDB->new(path => { dbase_dir => "./dbstore" });
my $tools = AmberDB::Tools->new($adb);

# 1. Tüm veritabanının tam yedeğini alma (.amberdb)
my $arsiv = $tools->dump();
# Çıktı: dbstore/backup/2026/amberdb_2026-08-28_180000.amberdb

# 2. Belirli tabloların snapshot yedeğini alma
$tools->dump(
    file   => "backup/2026/katalog_yedek.amberdb",
    tables => ["catalog_product", "catalog_category"]
);

# 3. Yedeği geri yükleme ve tüm indeksleri otomatik inşa etme
$tools->restore(
    file    => "backup/2026/katalog_yedek.amberdb",
    force   => 1, # Var olan tabloların üzerine yazma izni
    reindex => 1  # İndeksleri sıfırdan üret
);
```

#### CLI Komut Satırı Aracı (`bin/amberdb_backup.pl`)
```bash
# Veritabanını yedekleme
perl bin/amberdb_backup.pl --dump --file backup/2026/tam_yedek.amberdb

# Belirli tabloları yedekleme
perl bin/amberdb_backup.pl --dump --tables products,orders

# Yedeği güvenli şekilde geri yükleme
perl bin/amberdb_backup.pl --restore --file backup/2026/tam_yedek.amberdb --force
```

---

## 18. Bakım ve Onarım Araçları (AmberDB::Tools)

Veritabanı indekslerini sıfırdan yeniden oluşturmak, veri doğrulaması yapmak veya tabloları optimize etmek için `AmberDB::Tools` kullanılır:

```perl
use AmberDB;
use AmberDB::Tools;

my $adb   = AmberDB->new(path => { dbase_dir => "./dbstore" });
my $tools = AmberDB::Tools->new($adb);

# 1. Bir tablonun tüm indekslerini sıfırdan oluşturma (Re-Index)
$tools->set_index("catalog_product");

# 2. Tüm veritabanındaki bütün tabloları yeniden indeksleme
$tools->index_alltables();

# 3. İndeks Tutarlılık Kontrolü
my @kayitlar = $adb->read_all("catalog_product", 0, 0, no_index => 1);
my $fark = $tools->check_readall("catalog_product", @kayitlar);

# 4. Tablo Vakumlama (Fragmentasyonu temizler ve dosyayı küçültür)
$tools->vacuum("catalog_product", 1); # 1 = işlem sonrası reindex yap

# 5. DB_File tablosunu CSV'ye aktarma veya CSV'den geri yükleme
$tools->tie2csv("catalog_product");
$tools->csv2tie("catalog_product");

# 6. Tüm Veritabanı Tablolarını Toplu Yeniden İndeksleme / Dönüştürme
my $donusum_raporu = $tools->convert_tables();

# 7. Tabloyu ve İlişkili Tüm İkincil İndeks Dosyalarını Diskten Silme
$tools->del_table("eski_tablo");

# 8. Bağımsız / Geçici Dizinler için Hafif Ad-Hoc AmberDB Örneği
my $basit_adb = $tools->db_simple("/path/to/data/dir");
```

---

## 19. Dosya Uzantıları Haritası

AmberDB dosya uzantıları rollerine ve yeniden üretilebilirlik durumlarına göre 3 grupta toplanır:

| Uzantı | Rol / Sınıf | Yeniden Üretilebilir mi? | Açıklama |
|---|---|---|---|
| **Temel & Otoriter Veriler** | | | |
| `.db` | Birincil Veri (Source of Truth) | ❌ **Hayır** (Otoriter) | Berkeley DB ana döküman tablosu (`DB_File` Hash). |
| `.del` | Silinen Kayıtlar Arşivi | ❌ **Hayır** (Otoriter) | Silinen (soft-delete) kayıtların arşivi (`keep_deleted`). |
| `.aut` | Kullanıcı Denetim İzi (Audit) | ❌ **Hayır** (Otoriter) | Kimin ne zaman hangi kaydı değiştirdiğinin logu (`log_owner`). |
| `.str` | Metin Sözlük Eşleştirmesi | ❌ **Hayır** (Otoriter) | Serbest metinleri sayısal foreign key ID'lerine bağlayan çift yönlü sözlük (`_${blk}.str`). |
| **Türetilmiş İndeks Dosyaları** | | | |
| `.inx` | Birincil Kayıt İndeksi |  **Evet** (`set_index`) | Tüm aktif ID listesi, kayıt sayısı ve son ID ikili indeksi. |
| `.fld` | Eşleştirme İndeksi (Match) |  **Evet** (`set_index`) | Alan bazlı tersine eşleştirme indeksi (`match_block`). |
| `.src` | Tam Metin Arama (Search) |  **Evet** (`set_index`) | Kelime bazlı tersine arama indeksi (`search_block`). |
| `.srt` | Sıralama İndeksi (Sort) |  **Evet** (`set_index`) | Belirlenen bloklara göre sıralı ID ikili indeksi (`sort_block`). |
| `.fac` | Facet Filtreleme İndeksi |  **Evet** (`set_index`) | E-ticaret filtre sayaç ve durum haritası (`facet_block`). |
| `.slg` | Slug Haritası |  **Evet** (`set_index`) | `_0.slg` (ID→Slug) ve `_1.slg` (Slug→ID) çift yönlü eşleştirici. |
| `.jinx`| Junk Birincil Kayıt İndeksi |  **Evet** (`set_index`) | Pasif/arşiv kayıtların ID ikili indeksi (`use_junk`). |
| `.jfld`| Junk Eşleştirme İndeksi |  **Evet** (`set_index`) | Pasif kayıtların alan eşleştirme indeksi (`jnktype => 'B'/'AB'`). |
| `.jsrc`| Junk Tam Metin Arama |  **Evet** (`set_index`) | Pasif kayıtların arama ters indeksi (`jnktype => 'B'/'AB'`). |
| **Çalışma Zamanı ve Geçici Dosyalar** | | | |
| `.cnt` | Sayaç Dosyası | ⚠️ Sayaç verisi | Kayıt görüntülenme/tıklanma sayaçları (`use_counter`). |
| `.txn` | İşlem Günlüğü (Undo Log) | ⚠️ Geçici (Runtime) | Aktif işlem undo-journal geri alma dosyası (`txn/`). |
| `.cache`| Önbellek Dosyası |  Evet (RAM-Disk) | RAM-Disk paylaşımlı önbellek dosyası (`cache/`). |
| `.tmp` | Disk Buffer Dosyası | ⚠️ Geçici (Staging) | `dbstore/buffer/` altında geçici aktarım/ETL dosyası (`buffer_write`). |
| `.lock` | Süreç Kilit Dosyası | ⚠️ Geçici (Mutex) | İşletim sistemi `flock` process senkronizasyon dosyası. |

---

## 20. Dizin Yapısı

```text
dbstore/
├── schema/                      ← Şema ve Grup Tanımları
│   ├── catalog.dbase            ← Grup tanımı
│   ├── catalog_product.table    ← Ürün tablosu şeması
│   └── catalog_category.table   ← Kategori tablosu şeması
├── tables/                      ← Ana Veri ve İndeks Dosyaları
│   ├── catalog_product.db       ← Ana veri
│   ├── catalog_product.inx      ← İkili kayıt indeksi
│   ├── catalog_product_1.fld    ← Kategori eşleştirme indeksi
│   ├── catalog_product_4.src    ← Ürün adı arama indeksi
│   ├── catalog_product_10.srt   ← Fiyat sıralama indeksi
│   ├── catalog_product.fac      ← Facet indeksi
│   ├── catalog_product_0.slg    ← ID → Slug Haritası
│   ├── catalog_product_1.slg    ← Slug → ID Haritası
│   ├── catalog_product.aut      ← Denetim logu
│   └── catalog_product.del      ← Silinen kayıtlar
├── cache/                       ← RAM-Disk Paylaşımlı Önbellek Dosyaları
├── buffer/                      ← Geçici Disk Buffer / Staging Dosyaları
├── txn/                         ← Aktif Transaction Günlükleri
├── pids/                        ← Dosya ve Kayıt Kilitleri
└── backup/                      ← Günlük CSV Yedekleri
```

---

## 21. Geliştirici Tavsiyeleri ve En İyi Pratikler

1. **Toplu Veri Girişinde `insert_list` Kullanın:** Yüzlerce kaydı tek tek döngüde `insert_id` ile eklemek yerine tek seferde `insert_list` ile ekleyin; disk I/O ve indeksleme süresi 10 kat hızlanacaktır.
2. **Kritik İş Mantıklarında `transact_start` Kullanın:** Stok düşme, bakiye güncelleme ve sipariş onaylama gibi adımları mutlaka transaction bloğu içine alın.
3. **Şemalarda Gereksiz Blokları İndekslemeyin:** Yalnızca filtrelenecek alanları `match_block`, aranacak alanları `search_block` olarak tanımlayın.
4. **Sayfalama Dönen Değer İmzasını Doğru Karşılayın:** `read_all`, `field_fetch` ve `search_table` metotlarında `$limit > 0` verildiğinde dönen listenin ilk elemanının `$toplam` tamsayısı olduğunu unutmayın. Asla `my @kayitlar = $a...
5. **Kayıt ID Tipi Seçimi:** Standart tablolar için `id_type => "num"` (sayısal) tercih edin; hem daha az yer kaplar hem de ikili sabit boyutlu ofsetler üzerinde en yüksek dilimleme hızını sunar.
6. **Kayıt Dizisinde ID Standartı:** Kayıt dizilerinde (`@record`) her zaman 0. indisi Kayıt ID'si (`$record[0]`) olarak konumlandırın. Yeni kayıtta `0` verip `my $id = $record[0] = $adb->insert_id("tablo", @record);` şeklinde atayın. Okuma ...

---

## 22. Kapsamlı Uygulama Örneği (Sipariş & Stok Senaryosu)

Aşağıdaki örnek; ana tabloların oluşturulması, ürünün ilişkisel ID'ler ve çoklu kategorilerle eklenmesi, URL slug ile okuma, filtreli arama, sıralama ve güvenli bir sipariş transaction'ını baştan sona gösterir:

```perl
use strict;
use warnings;
use AmberDB;

# 1. Motoru baÅŸlat
my $adb = AmberDB->new(
    cfg  => { language => "tr", user => "kasiyer_1" },
    path => { dbase_dir => "./dbstore" }
);

# 2. Ana Tanım Tablolarına Kayıt Ekleme (Master Tables)
my $kat_bilgisayar = $adb->insert_id("catalog_category", undef, "Bilgisayar & BiliÅŸim", 1); # ID: 5
my $kat_tasinabilir = $adb->insert_id("catalog_category", undef, "Taşınabilir Cihazlar", 1);# ID: 12

my $marka_apple    = $adb->insert_id("catalog_brand", undef, "Apple", "ABD");                # ID: 8
my $yazar_tasarim  = $adb->insert_id("catalog_author", undef, "Donanım Ekibi", "Ar-Ge");   # ID: 7

# 3. Yeni Ürün Ekle (İlişkisel alanlara ID verilir; kategori "5,12" olarak çoklu tutulur)
my @urun = (
    "5,12",                         # [1] Kategori ID'leri (5: Bilgisayar, 12: Taşınabilir)
    "8",                            # [2] Marka ID: Apple (8)
    "7",                            # [3] Yazar / Katkıda Bulunan ID: 7
    "MacBook Pro M3",               # [4] Ürün Adı
    "16GB RAM 512GB SSD Uzay Grisi",# [5] Açıklama
    "", "", "",
    10,                             # [8] Stok: 10 adet
    "195949123456",                 # [9] Barkod
    "64999.00",                     # [10] Fiyat
    "1"                             # [11] Satışta: 1
);

my $urun_id = $adb->insert_id("catalog_product", undef, @urun);
print "1. Ürün Eklendi -> ID: $urun_id\n";

# 4. Otomatik Üretilen URL Slug'ı Oku
my $slug_harita = $adb->get_slug("catalog_product", 0, $urun_id);
print "2. OluÅŸan URL -> /urun/$slug_harita->{$urun_id}\n";

# 5. Çoklu Kategoriden (Örn: 12 nolu Taşınabilir) Fiyat Sıralı Listeleme, ilk 20 kayıt
my ($toplam, @urunler) = $adb->field_fetch(



( run in 0.685 second using v1.01-cache-2.11-cpan-4ef0a570458 )