RBN Core - Framework v0.9.7 76 belge

Core/Database — bağlantı yönetimi, sorgu motoru, model ve repository katmanı

Doğrulanan kod tabanı: 1d89c431 (dal feat/fw-license-master) · Tarih: 2026-10-05 · Yayın: 0.9.7 = bu commit + sonrası; belge yalnız doğrulama anındaki kodu anlatır
Kaynak klasör: Core/Database/ — 74 *.php.
Envanter: 74 dosyanın 74'ü aşağıda anlatıldı (alt dal belgelerinde dağınık).

1. Ne işe yarar, kim kullanır

Framework'ün veri katmanıdır. Üç katmanı vardır ve katmanlar arasına
taşmak kuraldır:

Katman Soyut sınıf Görev
Bağlantı Database (singleton) database_project / database_master / database_common bağlantılarını yönetir, PDO verir, transaction açar
Sorgu QueryBuilder (+ 7 query trait'i) SQL üretimi; Database üzerinde kendi bağlantısında çalışır
Veri BaseModel / BaseRepository Sorgu builder'ı sarmalar; model satır, repository iş kuralıdır

Anayasa §8 gereği yalnız Repository katmanı doğrudan SQL yazabilir;
model katmanı şemaya değil, hazır builder API'sine dayanır.

Kimler çağırır: Core/Base/Data/BaseModel, tüm Core/Services ve
Bundles/* repository/model sınıfları, CLI handler'ları (rbn db:*).

2. Klasör/dosya envanteri

Tam dosya listesi ve her dosyanın tek cümlelik görevi alt dal belgelerindedir:

Alt dal belge Kapsam Dosya sayısı
Engine.md Database.php, Engine/ (Collection, Providers, Traits, Traits/Query) 16
Models.md Models/ (kök + Common + Master + Project) 34
Repositories.md Repositories/ (Common + Master + Project) 20
Migrations.md Migrations/ (Master + Tenant) 3
Services/DatabaseService.php (aşağıda, bu belge) 1
Toplam 74

Bu ana belgese ait tek dosya:

Dosya Görev Önemli public yöntemler
Services/DatabaseService.php Panelin/CLI'nin veritabanı yönetim yüzü: tablo listesi, satır gösterme, satır silme, optimize, collation dönüşümü, SQL dışa aktarım, temiz kurulum, admin seed. static get(): self, table(string $name): self, entire(): self, getDashboardInfo(): array, optimize(): bool, convert(string $collation='utf8mb4_unicode_ci'): array, cleanInstall(): bool, seedAdmin(): bool, executeQuery(string $sql): array, getTableContent(string $table,int $limit=100): array, getTables(): array, getRows(?string $table=null,int $limit=100): array, getTableMetadata(?string $table=null): array, deleteRow(?string $table=null,$id=null): bool, bulkDeleteRows(?string $table=null,array $ids=[]): bool, dropTable(?string $table=null): bool, changeTableCollation(?string $table=null,string $collation=...): bool, exportTableSql(?string $table=null,?array $ids=null): string, sanitizeTableName(string $table): string (protected)

3. Akış — bir model okumasından satıra

Controller/Service → $this->model('project.user')->where(...)->get()
 ├─ BaseComponent::__get('user'/'model') → component('model', …) keşif motoru   BaseComponent.php:194
 │   → Core/Base/Data/BaseModel örneği
 ├─ BaseModel::__construct() → BaseComponent → bootBaseContext()            BaseModel.php:210
 └─ QueryModelTrait::query()                                   QueryModelTrait.php:44
     ├─ logModelScopeVisibility()  (LOG-ONLY ölçüm)             :49
     ├─ new QueryBuilder($this->db, $this->table)              :67
     ├─ $builder->connection($this->connection)                :71-73
     ├─ $builder->setModelClass(static::class)                 :77-79
     └─ $scoped ise → where(project_key, aktif) veya whereIn(..., projectScopeIncludes)  :88-108
        (aktif anahtar boşsa kapsam UYGULANMAZ)
 └─ where/orderBy/limit... → get()
     └─ Query\ExecutionTrait::get()                            ExecutionTrait.php:17
         └─ onConnection(fn) → Database::connectionScoped($connectionName, …)  QueryBuilder.php:97
             └─ Database::query()/raw()/execute()              ExecutionTrait.php:46,131,151
                 └─ ConnectionTrait::getProvider($name) → MySqlProvider → getPdo()  MySqlProvider.php:60

Yazma yolu aynıdır; ayrıca MassAssignmentTrait süzgeci
(create/update/save üzerinden) devreye girer.

4. Yapılandırma / ayar anahtarları

Anahtar / sabit Yer Not
KNOWN_CONNECTIONS ConnectionTrait.php:29 database_project, database_master, database_common
CONNECTION_ALIASES ConnectionTrait.php:43 default → database_project
security.mass_assignment MassAssignmentTrait.php:42 on|enforce zorlar; diğer her şey off (varsayılan on)
security.protected_field_log MassAssignmentTrait.php:50 on → korumalı alan denemesi loglanır
security.model_not_scoped_log QueryModelTrait.php:39 on → kapsam dışı model görünürlük logu (saatlik)
MASTER_DB_* / DB_* ortam anahtarları MasterDbData::KEYS_MAP, ProjectDbData::KEYS_MAP Değerler Secrets üzerinden gelir
MasterDbData::REQUIRED_TABLES MasterDbData.php:54 developers, ip_whitelist, ip_blocks, projects, z_sys_heartbeats

5. Tuzaklar ve kurallar

  1. Geçersiz bağlantı adı istisna atar (fail-closed). MySqlProvider'ın
    önceki "bilinmeyen her adı sessizce database_project'e düşür" davranışı
    kaldırıldı; artık normalizeConnectionName() InvalidArgumentException
    atar (ConnectionTrait.php:68). Geriye uyum yalnız default alias'ıyla.
  2. default ve database_project aynı sağlayıcıyı paylaşır — aynı
    veritabanına iki PDO açılmaz (ConnectionTrait.php:43).
  3. Sorgu kendi bağlantısında çalışır, global durum kirlenmez.
    QueryBuilder::onConnection() → Database::connectionScoped()
    (QueryBuilder.php:97, ConnectionTrait.php:123).
  4. Boş proje bağlamında kapsam uygulanmaz. $activeKey === '' iken
    where('project_key','') yazmak tüm tabloyu sıfıra indirirdi; bu yüzden
    kapsam atlanır (QueryModelTrait.php:90).
  5. Kiraci izolasyonu varsayılanı KAPALI. BaseModel::$scoped = false
    (BaseModel.php:57); her model kendi kararını dosyasında yazar
    (@tenant-scope etiketiyle). Açmak 7 veritabanında kırılma ölçülmüştür.
  6. PDO, ayar değiştiğinde düşürülür. getPdo() her çağrıda Config'i
    okur; host/veritabanı/kullanıcı/parola farklıysa bağlantı yenilenir
    (MySqlProvider.php:60).
  7. CLI'da ölü bağlantı yoklanır. 10 sn'den eskiyse SELECT 1 atılır;
    PDOException yetmez, Throwable yakalanır (MySqlProvider.php:81).
  8. SchemaDoctorModel tablosuzdur. getTable(): string yerine
    getTableOrNull() kullanılmalıdır (strict_types altında null dönmek
    TypeError'dir) (SchemaDoctorModel.php:11).
  9. İç içe transaction dış yüzeyi kullanmaz. Database::transaction()
    zaten transaction içindeyse içeriği çalıştırır ve commit/rollback yapmaz
    (Database.php:57).
  10. Sıfırlama API'leri yalnız test içindir. BaseService::forgetInstance(),
    StorageContextTrait::forgetStorage() üretimde çağrılmaz.

6. Örnek (gerçek koddan)

Repository katmanından okuma/yazma (Repositories/Project/UserRepository.php
imzası):

$user = $this->repository('project.user')->findByIdentity('ornek@site.example');
$ok   = $this->repository('project.user')->updatePassword($id, $hash, 'user');

Model katmanında kiracı kapsamını daraltma (QueryModelTrait.php:88):

$model = $this->model('project.user')->withProjectScope('proje-anahtari');
$rows  = $model->where('is_active', 1)->orderBy('id', 'DESC')->limit(20)->get();

7. İlgili belgeler