|
<< İçindekileri Görüntülemek İçin Tıklayın >> Yer: Teknik Kılavuzlar > IVEDI SQL Kullanıcı Kılavuzu > 6. Veri tanımlama (DDL) > 6.9 Veritabanı kimlik kartı (IVD$DATABASE), ALTER DATABASE … SET STATE ve başlangıç betiği |
Her veritabanında tek satırlık bir
ivd$database tablosu vardır; CREATE DATABASE yazar (MASTER'ınkini sunucu açılışı):
GUID, ad, MASTER'daki kayıt kimliği (ivd$master_object_id; MASTER'ın kendi kartında 0), durum,
katalog biçim sürümü (ivd$catalog_version; değeri 23), motor sürümü, uygulama (işlemci, bayt sırası,
işletim sistemi, derleyici), depo motoru ile sürümü ve disk biçimi (ör. SQLite 3.53.3 /
SQLite format 3, Firebird'de ODS 13.1), karakter kümesi, makine adı, yaratan login,
yaratılış zamanı (UTC), başlangıç betiği (ivd$startup_script), görev zamanlayıcı bayrağı
(ivd$task_scheduler), açıklama (ivd$description) ve seviye damgaları
(ivd$level3_version / ivd$level3_generated ile ivd$level4_version /
ivd$level4_generated — aşağıda kendi bölümü var). Satır yalnız şu
yollardan değişir: veritabanı MASTER'a bağlanırken
(CREATE ve OPEN DATABASE MASTER kimliğini tazeler), COMMENT ON DATABASE
(açıklama; aynı metin veritabanının kendi ivd$objects satırına ve MASTER'daki kayıt satırına da
yazılır), başlangıç betiği komutları, durum komutu ve seviye damgalarını yazan komutlar. Bu komutlar her ALTER DATABASE gibi yalnız
geçerli veritabanında çalışır ve COMMIT'te uygulanır:
SET CATALOG rop_db;
ALTER DATABASE rop_db SET STATE READ_ONLY;
-- ACTIVE | RESTRICTED | READ_ONLY | OFFLINE
-- (CREATING / UPGRADING / LEVEL3_UPDATE motorundur, SET STATE ile verilemez; MASTER hep ACTIVE)
COMMIT;Tabloya doğrudan yazılamaz (katalog tablosu, INSUFFICIENT_PRIVILEGE). Durumlar motorca
uygulanır; durum bir yetkiyle aşılmaz, ALTER DATABASE ise her durumda çalışır
(durumu geri almanın yolu odur):
| Durum | Etkisi |
|---|---|
ACTIVE | Kısıt yok. |
READ_ONLY | Okuma ve çağrı serbest; her yazma ve DDL DATABASE_READ_ONLY
(SQLSTATE 25006) — SYSDBA dahil herkes için. |
RESTRICTED | Yalnız sahip, SYSDBA, SYSADMIN üyesi (ve kimliksiz sistem bağlantısı)
kullanabilir, açabilir, SET CATALOG ile geçebilir; diğerleri
DATABASE_NOT_AVAILABLE (55000). |
OFFLINE | Herkes için her erişim DATABASE_NOT_AVAILABLE; yalnız ayrıcalıklı
kimlik açabilir ve geçebilir, orada yalnız ALTER DATABASE … SET STATE çalışır. Katalog okunur
kalır. |
UPGRADING | Katalog yükseltmesi sürerken ya da yarım kaldıysa; yalnız SYSDBA açabilir ve orada yalnız yükseltme komutu çalışır (bkz. “Katalog sürümü ve ALTER DATABASE … UPGRADE”). |
LEVEL3_UPDATE | Katalog yükseltildi, seviye 3 yeniden üretilmeyi bekliyor;
RESTRICTED gibi. ALTER DATABASE … SET LEVEL 3 VERSION … GENERATED … kendiliğinden
ACTIVE'e döndürür. |
CREATING | Yaratılış sürerken; yarım kalmış yaratılış açılamaz. |
Kartın ivd$startup_script kolonu bir MQL betiğinin metnini tutar. Betik,
veritabanı sunucuya her bağlandığında o veritabanında koşar: OPEN DATABASE başarıyla bittiğinde
ve MASTER'da kayıtlı bir veritabanı ilk kullanımda tembel açıldığında, açan bağlantıda ve işlemde, arama yolu
SYS iken. MASTER'ın betiği sunucu açılışında kendi sistem bağlantısında koşar. Betiğin hataları
açan deyimin hatası olarak raporlanır; betik her bağlanışta yeniden koştuğu için idempotent yazılmalıdır.
CREATE DATABASE ve yükseltme bekleyen bir açılış betiği koşturmaz.
SET CATALOG rop_db;
ALTER DATABASE rop_db SET STARTUP SCRIPT 'insert into acilis_log(n) values (1);';
ALTER DATABASE rop_db SET STARTUP SCRIPT FROM FILE 'rop_db_startup.sql';
ALTER DATABASE rop_db DROP STARTUP SCRIPT;
COMMIT;FROM FILE dosyayı derleme anında okur ve metnini karta yazar; dosya sonradan
değişirse komut yeniden çalıştırılmalıdır. UTF-8 okunur, baştaki BOM atılır. Göreli yol, komutu içeren betik
dosyasının dizinine göredir (#include gibi; client: / server: önekleri de
#include'daki gibi geçerlidir — bkz. bölüm 10, “Dosya dahil etme”); betik dosyasından
gelmeyen bir komutta çalışma dizinine göredir. ${APPDIR}, ${CONFIGDIR}, ${TEMP} gibi yer tutucular
çözülür. Bulunamayan dosya SYNTAX_ERROR verir.DROP STARTUP SCRIPT kolonu NULL yapar.msql ile verilir; dosya sunucudaysa
server: öneki yazılır:
ALTER DATABASE MASTER SET STARTUP SCRIPT FROM FILE 'server:${APPDIR}/lsp_startup.sql';Ajanın belge havuzu (müşteri belgeleri: NetsimApp'in /ClientREST/Doc* uçları, MCP'nin
doc_* araçları, IMPORTDOC) her veritabanı için ayrı tanımlanır. INTERNAL
havuzu veritabanının kendi deposuna, DATABASE <ad> ilişkili başka bir kayıtlı veritabanının
deposuna bağlar; OFF bağı kaldırır. Değer COMMIT'te yalnız MASTER'daki kayıt satırının
DOCUMENTS niteliğine yazılır (kart değişmez). İlişkili veritabanı kayıtlı olmalı ve veritabanının
kendisi olmamalıdır; MASTER için verilemez. Havuz SQLite, PostgreSQL (katalog dışındaki ivd$docs
şemasında) ya da Firebird (doc$ tabloları; tam metin dizini ajanın belleğinde) depolu olabilir.
SET CATALOG musteri_1;
ALTER DATABASE musteri_1 SET DOCUMENTS INTERNAL;
COMMIT;
SET CATALOG musteri_2;
ALTER DATABASE musteri_2 SET DOCUMENTS DATABASE musteri_2_belge;
COMMIT;ALTER DATABASE <ad> SET PARAMETERS '<bağlantı dizesi>' MASTER'daki kayıt satırının
ENGINE PARAMETERS niteliğini yeniden yazar (sunucu, port, depo adı, kimlik…). Değeri ******
olan bir anahtar kayıtlı değerini korur (yönetim arayüzü kullanıcı adı ve parolayı böyle maskeler); dizede
yazılmayan anahtar düşer. Parola kayıt satırına açık metin olarak yazılmaz, mühürlenerek
(Password=enc:…) saklanır. Yeni değerler veritabanı yeniden açıldığında geçerli olur — bağlanmamış işçi
süreç, CLOSE DATABASE + OPEN DATABASE ya da ajanın yeniden başlatılması; açık depo bağlantıları
eskisiyle sürer, deyim bunu bir uyarıyla söyler. MASTER için verilemez; Recreate
reddedilir.
Açılamayan kaydın onarımı. Depoya bağlanılamayan bir kayda (parola değişmiş, sunucu taşınmış)
SET CATALOG geçemez. Böyle bir kayda iki öğe herhangi bir veritabanından (örneğin MASTER'dan) verilir ve
yalnız kayıt satırını yazar; veritabanı bir sonraki kullanımda açılır. Açılana kadar her biri tek başına verilmelidir,
öteki ALTER DATABASE öğeleri açık veritabanı ister. SET ENGINE USER açık olduğu halde depoya
artık bağlanamayan kayda da (servis kullanıcısının parolası ajan çalışırken depoda değişmiş) böyle verilir: kayıt satırıyla
birlikte açık veritabanının bağlantı parametreleri de yenilenir, ajanı yeniden başlatmak gerekmez.
ALTER DATABASE <ad> SET ENGINE USER [PASSWORD '…'] — servis kullanıcısının parolası depoda
değiştiyse (önerilen yol): oturumda SET STORAGE CREDENTIALS ile verilen süper kullanıcıyla servis
kullanıcısı yeniden kurulur, kayıt onun mühürlü parolasını alır. Süper kullanıcı parolası kayda yazılmaz.ALTER DATABASE <ad> SET PARAMETERS '…' — sunucu, port ya da veritabanı adı değiştiyse.set storage credentials user 'postgres' password '***';
alter database satis set engine user;
commit;
set storage credentials none;SET CATALOG musteri_1;
ALTER DATABASE musteri_1 SET PARAMETERS 'Server Name=10.5.7.4; Port=5432; Database Name=musteri_1; User Name=******; Password=******; Catalog Schema=netsim';
COMMIT;ALTER DATABASE <ad> SET ENGINE USER [PASSWORD '<parola>'] kayıt satırındaki depo kimliğini
motorun kendi servis kullanıcısına çevirir (yapılandırmadaki engineUser; öndeğer IVD$ENGINE,
boş bırakılırsa özellik kapalıdır). CREATE DATABASE ve OPEN DATABASE kaydı açarken bu işi
kendiliğinden yapar: deyimde verilen kullanıcı adı ve parola yalnız kurulum kimliğidir, servis kullanıcısı deponun
süper kullanıcısıyla kurulur (PostgreSQL'de LOGIN SUPERUSER rolü, Firebird'de ADMIN ROLE'lü
kullanıcı) ve kayda o yazılır; kurulamazsa verilen kimlik kalır ve bir uyarı yazılır. Bu komut var olan bir kaydı
sonradan geçirmek ya da kurulumu yinelemek içindir ve oturumda önce SET STORAGE CREDENTIALS USER
'<süper kullanıcı>' PASSWORD '<parola>' verilmesini ister (bkz. “Oturum ayarları”).
Parola verilmezse aynı depo sunucusundaki başka bir kaydın parolası, o da yoksa üretilen bir parola kullanılır;
verilen parola aynı sunucudaki öteki kayıtlara da yazılır (sunucu başına tek parola). Kayıt satırı ve açık motorun
bağlantı parametreleri yeniden yazılır, her süreç depoyu sonraki kullanımda yeni kimlikle açar. MASTER
için verilemez; kimlik doğrulaması olmayan depolarda (sqlite, bellek) ve OS Authentication ile açılan
bağlantıda iş yapmaz.
SET STORAGE CREDENTIALS USER 'postgres' PASSWORD 'masterkey';
SET CATALOG musteri_1;
ALTER DATABASE musteri_1 SET ENGINE USER;
COMMIT;
SET STORAGE CREDENTIALS NONE;Kartın ivd$task_scheduler kolonu, hizmetin görev zamanlayıcısının bu veritabanı için çalışıp
çalışmayacağını söyler: hem ürünün ZMGOREV döngüsü hem de SYS.Scheduler paketiyle tanımlanan işler
(ivd$scheduler_jobs) buna bakar. Değer COMMIT'te karta ve MASTER'daki kayıt satırının
TASK SCHEDULER niteliğine birlikte yazılır; hizmet kayıtları MASTER'dan okur. Öndeğer kapalıdır
(NULL). MASTER için de verilebilir — motorun kendi işleri orada da çalışır.
Zamanlayıcı açıkken her iş kendi alt sürecinde ve SYSTEM kimliğiyle koşar; aynı işin
önceki koşusu bitmeden yenisi başlamaz, farklı işler paralel gider. İş listesi attachJob /
enableJob / disableJob / startJob / resetJob /
detachJob çağrılarından hemen sonra, en geç de beş dakikada bir yeniden okunur; yeni bir iş için hizmeti
yeniden başlatmak gerekmez. Bir iş tipi (Scheduler.Job'dan türeyen TYPE) düşürülünce o
tipe bağlı işler de ivd$scheduler_jobs'tan silinir. SET TASK SCHEDULER ON | OFF da çalışan hizmette izlenir: dağıtıcı kümesi
birkaç saniye içinde yeniden kurulur, açılan veritabanı için dağıtıcı eklenir, kapananınki kaldırılır. Koşu sonunda
ivd$last_status, ivd$run_count, ivd$failure_count ve sıradaki zaman
(ivd$next_run) yazılır.
SET CATALOG rop_db;
ALTER DATABASE rop_db SET TASK SCHEDULER ON;
COMMIT;
SELECT upper(a.ivd$value)
FROM master.sys.ivd$object_attributes a
JOIN master.sys.ivd$objects o ON o.ivd$object_id = a.ivd$object_id
WHERE o.ivd$type = 'DATABASE' AND o.ivd$object_name = 'ROP_DB'
AND a.ivd$attribute_name = 'TASK SCHEDULER'; -- TRUEVeritabanı yeniden kaydedilirken (OPEN DATABASE) nitelik karttan yeniden yazılır.
Veritabanının çalışma kipini (IVEDI ya da STORAGE, bkz. CREATE DATABASE)
değiştirir. Değer COMMIT'te karta yazılır ve o andan sonraki deyimlerde geçerlidir.
SET CATALOG urun_db;
ALTER DATABASE urun_db SET EXECUTION STORAGE;
COMMIT;
SELECT execution FROM urun_db.sys.ivd$v_database; -- STORAGENATIVE_SQL, deponun kendi lehçesinde yazılmış bir metni taşır. Motor metni
değerlendirmez; depoya gönderilen SQL'e olduğu gibi yazar. İki biçimi vardır — bir değerin
beklendiği yere giren ifade biçimi ve bir deyimin beklendiği yere giren deyim
biçimi. Her ikisinde de depo başına ayrı metin verilebilir:
NATIVE_SQL ( [<depo>] '<metin>' {, [<depo>] '<metin>'} [ AS <tip> ] )<depo> yerine POSTGRESQL, FIREBIRD, SQLITE, ODBC gibi
bir depo motoru adı yazılır; depo adı verilmeyen metin öndeğerdir ve adı geçmeyen bütün depolar onu
kullanır. IVEDI adıyla verilen metin motorun kendi lehçesindedir ve depoya hiç gitmez:
kodu motorun kendisi çalıştırdığında kullanılır (aşağıda). AS <tip> ifadenin tipini söyler ve sonuç o tipe çevrilir; verilmezse ifade
VARIANT derlenir ve değer deponun döndürdüğü tipte kalır. Bir koşulda (IF,
WHERE, CHECK) tipin derleme anında belli olması için AS BOOLEAN yazın.
Depoya ya da işletim sistemine doğrudan inen her şey yalnız SYSADMIN login'ine (ve
SYSDBA'ya) açıktır: NATIVE_SQL, EXECUTE STATEMENT … ON EXTERNAL,
#SHELL yönergeleri, FileSystem ve OS paketleri ve
ALTER DATABASE … SET STARTUP SCRIPT. Denetim derlemede yapılır: başka bir login bunları
yazarsa deyim INSUFFICIENT_PRIVILEGE ile reddedilir. SYSADMIN'in yazdığı bir yordam, görünüm ya da
başlangıç betiği bunları kullanıyorsa, onu çağırma hakkı olan her kullanıcıda çalışır.
Yordam ve tetikleyici gövdesinde. NATIVE_SQL metin dönüşümünde anlam taşır: kod
deponun lehçesine çevrilirken (EXECUTION STORAGE veritabanında depoya kurulan yordam, tetikleyici, kısıt,
hesaplanan kolon; #MODE CONVERT TO) depoya uyan metin, ifadenin durduğu yere olduğu gibi
yazılır. Aşağıdaki koşul Firebird'e IF (RDB$GET_CONTEXT('SYSTEM', 'DB_NAME') NOT CONTAINING 'flymetadata')
THEN olarak gider; metin dönüştürülen gövdenin parçası olduğu için gövdenin değişkenlerini ve
NEW. / OLD. alanlarını deponun kendi yazımıyla kullanabilir. AS <tip> yalnız
ifadenin IVEDI'deki derleme tipini verir, depoya giden metne eklenmez.
IF (NATIVE_SQL(FIREBIRD 'RDB$GET_CONTEXT(''SYSTEM'', ''DB_NAME'') NOT CONTAINING ''flymetadata''',
POSTGRESQL 'TRUE',
IVEDI 'a > 3'
AS BOOLEAN)) THEN
...Kodu motor çalıştırdığında. Kod depoya kurulmayıp motorda çalışıyorsa — EXECUTION IVEDI
veritabanı, üst düzey EXECUTE BLOCK, IVEDI_ONLY nesne — sıra şudur:
EXECUTION STORAGE veritabanında bu depo için metin varsa depoda çalışır: ifade o veritabanının depo
bağlantısında SELECT <metin> ile hesaplanır (Firebird'de her SELECT'in bir kaynağı
olması gerektiğinden … FROM RDB$DATABASE), deyim aynı bağlantıda çalıştırılır. Metin depoda kendi
başına çalıştığı için gövdenin değişkenlerini göremez; depo oturumunun bağlamını görür.IVEDI metni varsa motor onu EXECUTE EMBEDDED gibi, bulunduğu yerin bağlamında
derleyip çalıştırır: yerel değişkenler, parametreler ve tetikleyicinin NEW. / OLD.
alanları görünür; ifadenin değeri AS <tip>'e çevrilir.CREATE TABLE kural
(
id integer not null,
adet integer,
fiyat numeric(15,2),
-- hesaplanan kolon: her depo kendi yazımıyla
toplam numeric(15,2) generated always as
(NATIVE_SQL(POSTGRESQL 'adet * fiyat', FIREBIRD 'adet * fiyat', 'adet * fiyat' AS NUMERIC(15,2))),
constraint kural_pk primary key (id),
-- depo tarafında denetlenecek kısıt
constraint kural_adet_chk check (NATIVE_SQL('adet > 0' AS BOOLEAN))
);Nerede işe yarar. EXECUTION STORAGE kipinde CHECK kısıtlarını ve hesaplanan kolonları
depo çalıştırır; motorun bunları anlaması gerekmez, yalnızca doğru metni göndermesi gerekir. ADOPT TABLE
de depodan okuduğu CHECK ve hesaplanan kolon ifadelerini böyle saklar — ifade kaybolmaz, benimsenen tablo yeniden
kurulduğunda aynı metin geri gider.
Sınırı. EXECUTION IVEDI kipinde IVEDI metni verilmemiş bir
NATIVE_SQL bir uyarı verir ve değeri NULL'dur; o kipte bir IVEDI metni
ekleyin ya da kısıtı ve hesaplanan kolonu doğrudan IVEDI ifadesiyle yazın. Metin depoya olduğu gibi gittiği için içeriği depo reddederse hata deponun hatasıdır.
Aynı yapı bir deyim olarak da yazılır: bir yordamın ya da tetikleyicinin gövdesinde, ya da üst
düzeyde. Metinler ve seçim kuralı ifade biçimiyle aynıdır; tek fark AS <tip> kabul
edilmemesidir — bir deyim değer üretmez.
NATIVE_SQL ( [<depo>] '<metin>' {, [<depo>] '<metin>'} )Asıl işi, lehçe farkının bir ifade değil bir deyim olduğu durumdur. #IFDEF dalı
derleme anında ve bütün akış için seçer; tek bir katalog nesnesi iki lehçenin metnini birden taşıyamaz.
Deyim biçiminde iki dal da nesnenin kendi gövdesinde durur ve hangisinin ineceğini hedef seçer:
CREATE PROCEDURE oturum_degeri_yaz(ad varchar(30), deger varchar(30))
AS
BEGIN
NATIVE_SQL(POSTGRESQL 'PERFORM set_config(''netsim_sess.'' || ad, deger, false)',
FIREBIRD 'RDB$SET_CONTEXT(''USER_SESSION'', :ad, :deger)');
END;Sınırı. EXECUTION IVEDI kipinde bu deyim hiçbir şey yapmaz — motor
depo lehçesindeki bir metni çalıştıramaz. Derleyici bunu bir uyarıyla söyler; sessizce hiçbir şey yapan bir deyim
kusurları saklar. #MODE CONVERT'te uyarı verilmez: orada metin hedefe iner.
Sonlandırıcı. Üretilen metinde deyimin sonuna ; konur, üç durum dışında:
; da yazılmaz;; ile bitiyorsa ikincisi yazılmaz;END ile bitiyorsa yazılmaz — bileşik bloktan (FOR … DO BEGIN … END)
sonra ; Firebird PSQL'inde geçersizdir. END ile biten bir ifade deyimi
(x = CASE … END) sonlandırıcı ister: onu metnin sonuna ; yazarak verin.Metinde makro. Dizgi içindeki {$MAKRO} dizginin her satırında açılır —
çok satırlı düz dizgide ve q'{…}' biçiminde de. Dizgi içindeki çıplak makro adı açılmaz.
Bir görünümün sorgusu yalnız deponun kendi sistem tablolarıyla yazılabiliyorsa (Firebird'de MON$ /
SEC$, PostgreSQL'de pg_stat_activity / pg_roles), gövde AS'tan
sonra tek bir NATIVE_SQL olur. Motor bu metni ayrıştırmaz; bu yüzden kolon listesinde her kolonun
tipi yazılır ve kolonlar kataloğa bu bildirimden girer:
CREATE VIEW fly$atta (att_id integer, usr varchar(63))
AS NATIVE_SQL(FIREBIRD 'select mon$attachment_id, mon$user from mon$attachments',
POSTGRESQL 'select pid, usename from pg_stat_activity');EXECUTION STORAGE veritabanında görünüm depoda, o depo için seçilen metinle kurulur ve satırları
depodan okunur.EXECUTION IVEDI kipindeki veritabanında görünüm kataloğa girer ama okunamaz: sorgu
UNSUPPORTED_FEATURE ile adıyla reddedilir.#MODE CONVERT TO <hedef> çıktısına hedefin metni yazılır; hedefin metni verilmemişse
hata verir.; yazılmaz.NATIVE_SQL görünümü, AS SELECT
görünümünde kolon tipi ve WITH CHECK OPTION derlemede hatadır; görünüm güncellenemez.Bir IVEDI veritabanındaki nesneler nesne kimliklerine göre dört düzeye ayrılır. Düzey, nesnenin kime ait olduğunu ve onu kimin değiştirebileceğini söyler:
| Düzey | Kimlik aralığı | Ne | Kim yazar |
|---|---|---|---|
| 1 | 5001 – 5499 | Katalog tabloları (ivd$objects, ivd$database …) |
Yalnız motor; SQL ile yazılamaz |
| 2 | 5501 – 5999 (tablolar), 6001 – 6499 (görünümler) | Sistem uygulama tabloları ve IVD$V_* sistem görünümleri |
Motor kurar; tablolara kullanıcı kodu sıradan DML ile yazar |
| 3 | 10.000.000 – | İşletme uygulamasının nesneleri (ürünün tabloları, yordamları, görünümleri) | Ürünün veritabanı kurulum betiği |
| 4 | 20.000.000 – | Kullanıcının kendi nesneleri | Son kullanıcı |
Yeni bir veritabanında kimlik dizisi (SYS.IVD$OBJECT_ID) seviye 3'ün başındadır, yani ilk yaratılan
nesne 10.000.000 alır. Seviye 3 ile 4 arasındaki sınırı iki komut çizer ve bunlar
kaynak veritabanı kurulurken çalışır:
SET CATALOG urun_db;
ALTER DATABASE urun_db BEGIN LEVEL 3 VERSION '5.2.0.1540'; -- seviye 3 kurulumu başlıyor
-- ... ürünün bütün tabloları, domainleri, yordamları, görünümleri ...
ALTER DATABASE urun_db END LEVEL 3; -- bundan sonrası kullanıcının
COMMIT;ALTER DATABASE <db> BEGIN LEVEL 3 VERSION '<sürüm>' [PRODUCT '<kod>']PRODUCT seviyelerin kimin olduğunu
karta yazar (ivd$product); paketle taşınır ve yükseltmede karşılaştırılır.ALTER DATABASE <db> END LEVEL 3ALTER DATABASE <db> BEGIN LEVEL 4 VERSION '<sürüm>' [PRODUCT '<kod>']END LEVEL 3'ün dizi işini yapar, yani sınırı da çizer: kullanıcı/müşteri nesnelerini üreten bir
betik tek deyimle hem “buradan sonrası seviye 4” der hem de kendi sürümünü damgalar.END LEVEL 4 yoktur: seviye 4 son seviyedir, dizinin taşınacağı bir yer yoktur.
İkisi de ALTER DATABASE'in birer dalıdır: adı yazılan veritabanı geçerli katalog
olmalıdır (önce SET CATALOG) ve başka bir değişiklikle aynı deyimde birleştirilemezler. Yalnız
üst düzey deyimdirler — saklı bir yordam veritabanının kimlik kartını sessizce değiştiremez — ve
ALTER DATABASE yetkisini isterler (sahip, SYSDBA ya da SYSADMIN üyesi). İkisi de COMMIT'te
uygulanır.
Kurulmuş bir ürün veritabanı yükseltildiğinde seviye 1–2 motorun güncel metadatasına gelir, seviye 3 ise ürün
tarafından yeniden üretilmeyi bekler. Motor bunu kendisi işaretler: seviye 3 damgası taşıyan bir
veritabanı başarılı bir ALTER DATABASE … UPGRADE sonunda LEVEL3_UPDATE durumuna geçer ve o
durumda yalnız sahibine, SYSDBA'ya ve SYSADMIN üyelerine açıktır. Seviye 3 güncellemesi bittiğinde son adım şudur:
SET CATALOG urun_db;
ALTER DATABASE urun_db SET LEVEL 3 VERSION '5.2.0.1541' GENERATED '2026-09-18 01:02:03';
COMMIT;Aynı komutun seviye 4 yazımı da vardır — ALTER DATABASE <db> SET LEVEL 4 VERSION '<sürüm>'
GENERATED '<zaman>' — ve aynı işi yapar. İkisi de sonuna PRODUCT '<kod>' alabilir. Tek farkı durum: LEVEL3_UPDATE seviye 3'ün yeniden
üretilmeyi beklediği anlamına geldiği için o durumu yalnız seviye 3 damgası kaldırır.
Burada iki değer de açıkça verilir ve ikisi de kaynak veritabanının kartından kopyalanır;
motor kendi saatini yazmaz. Sebebi şudur: iki veritabanının seviye 3'ünün aynı olup olmadığı ancak aynı damgayı
taşımalarıyla anlaşılır — hedefin kendi güncelleme zamanını yazması bu karşılaştırmayı yok ederdi. Komut aynı kart
güncellemesinde durumu da ACTIVE'e çeker, yani ayrıca SET STATE yazmak gerekmez. (Daha kısıtlı
bir durum — RESTRICTED, READ_ONLY, OFFLINE — işletmecinin kendi kararıdır ve
korunur.)
Damgayı okumanın yolu IVD$V_DATABASE görünümüdür:
SELECT database_name, catalog_version, state, product,
level3_version, level3_generated, level4_version, level4_generated
FROM ivd$v_database;İki seviyenin damgası birbirinden bağımsızdır: EXPORT LEVEL 3|4 taşıdığı seviyenin damgasını pakete
koyar, UPGRADE LEVEL 3|4 onu hedefe birebir kopyalar ve sürüm karşılaştırmasını (yön, gerileme kapısı,
ivd$upgrade komutlarının sürüm aralığı) o seviyenin damgasıyla yapar, DROP LEVEL 3|4 ise o
seviyenin damgasını temizler.
Seviye 3'ün (ve 4'ün) bir sürümden ötekine taşınması için motorun dört aracı vardır: kaynaktan bir paket yazmak, hedefi paketle karşılaştırmak, kataloğu olmayan depo tablolarını kataloğa benimsemek ve tek bir tabloyu yeni tanımına yükseltmek.
Burada komutların kendisi anlatılır: sözdizimi, seçenekler ve her birinin ne yaptığı. Bir üretim veritabanını hangi durumda hangi sırayla yükselteceğiniz — kataloğu hiç olmayan eski bir veritabanı, sürümler arası geçiş, seviyeyi baştan kurmak, benimseme sırası ve yükseltmenin reddettiği durumlar — işletme konusudur ve Netsim System Agent Kurulum ve Yönetim Kılavuzu belgesinin “Bakım ve yükseltme” bölümünde, örnek betikleriyle birlikte durur.
SET CATALOG kaynak_db;
EXPORT LEVEL 3 TO 'urun_5.2.0.1541.ivdpkg' MIN VERSION '5.1.1.1532';
EXPORT LEVEL 3 TO 'client:urun_5.2.0.1541.ivdpkg'; --// msql'in makinesine, çalışma dizinineHedef 'client:<yol>' ise paket sunucuda geçici bir dizinde üretilip istemciye gönderilir
(msql yazar; var olan dosyanın üstüne yazmaz); aynı önek UPGRADE LEVEL … FROM'da paketi
istemciden okur. Sonuç kümesinin son satırı PACKAGE | INFO olarak aktarılan bayt sayısını yazar.
Kaynağın o seviyedeki katalog satırlarını bir pakete yazar. Paketin içeriği motorun kendi kurduğu bir
sqlite veritabanıdır: içinde taze seviye 1–2 kataloğu, kaynağın seviye 3 (ya da 4) nesnelerinin katalog satırları,
o seviyenin ivd$upgrade komutları, tohum verisi ve kartın o seviyeye ait
damgası bulunur. Seviyenin tabloları varsayılan olarak satırlarıyla birlikte pakete girer; bir tablo
ATTRIBUTES ("ns.seed" = 'N') ile dışarıda kalır. Birincil anahtarı olmayan tablonun ve anahtarı
GENERATED ALWAYS AS IDENTITY olan tablonun verisi taşınmaz (SKIPPED satırı).
Satırı olmayan tablo pakette yer kaplamaz: yapısı zaten katalogla taşınır, rapor da boş tabloları
ayrıca sayar.
Dosyanın biçimi önek + zip'tir. İlk 1024 bayt IVDPKG1 imzası ve tek satırlık bir JSON
başlıktır; gerisi, tek girdisi package.sqlite olan bir zip arşividir. Başlık, sürüm denetimi için gereken
her şeyi paketi açmadan verir: biçim numarası, ürün kodu, seviye, o seviyenin sürümü ve üretim
damgası, kaynak veritabanının adı, katalog sürümü, üreten motorun sürümü, paketin üretim zamanı (UTC), açılmış ve
sıkıştırılmış boyutlar ve açılmış içeriğin SHA-256 özeti — özet, paket her açıldığında doğrulanır. Zip'in kendi
konumları mutlak olduğundan dosya, sıradan bir zip aracıyla da açılır.
MIN VERSION '<v>' paketin uygulanabileceği en eski hedef sürümünü başlığa yazar
(minFromVersion). UPGRADE LEVEL, kartındaki damgası bundan eski olan — ya da damga taşımayan —
hedefi hiçbir şey uygulamadan reddeder. Alt sınır paketin kendi seviye sürümünden yeni olamaz.
Paket saydam okunur: sqlite motoru Database Name değerinin önekli bir paket olduğunu
tanır, içeriği geçici bir dosyaya açar ve onu açar. Böylece hem UPGRADE LEVEL … FROM hem de düz bir
OPEN DATABASE … STORAGE ENGINE SQLITE paketi doğrudan okur; geçici dosya CLOSE'da silinir ve
böyle bir veritabanı süreçler arasında paylaşılmaz (her süreç kendi kopyasını açar). Önekli olmayan bir dosya paket
sayılmaz ve reddedilir — böyle bir dosyayı EXPORT LEVEL ile yeniden üretin.
Seviye 3 10.000.000 – 19.999.999, seviye 4 20.000.000 ve üstü kimlikleri kapsar. Bir nesnenin sahip şeması başka bir
seviyede olabilir (müşterinin tablosu ürünün şemasında durabilir); paket o şemanın satırını ad
çözümlemesi için taşır, ama karşılaştırmaya sokmaz — başka seviyenin şeması ne yaratılır ne düşürülür. Üst düzey deyimdir, ALTER DATABASE
yetkisi ve ayrıcalıklı kimlik ister, deyim anında çalışır.
Hedefin o seviyesini paketle karşılaştırır. Eşleme adla yapılır (sahip zinciri ve tür); nesne
kimlikleri veritabanları arasında aynı değildir. Eylem listesi CREATE, DROP, ALTER
(ayrıntıda neyin değiştiği), ATTRIBUTES, paketin bu hedefte çalışacak ivd$upgrade komutları
(COMMAND), SUMMARY ve VERSION satırlarından oluşur. Komutlar etkin olanlardır, depo
motoru kapısından geçenlerdir ve hedefin seviye 3 sürümü komutun sürüm aralığındaysa listelenir. PREVIEW
ile hiçbir şey yazılmaz.
Hedefin sürümü yalnız kartından okunur. Yükseltme komutlarının sürüm penceresi,
gerileme ve alt sınır denetimleri hedefin ivd$database kartındaki seviye damgasına dayanır; başka bir
kaynaktan sürüm okunmaz ve tahmin edilmez. Kartında seviye 3 damgası olmayan hedefe UPGRADE LEVEL 3
uygulanmaz: önizleme VERSION satırını gösterir, uygulama reddedilir. Böyle bir veritabanının (örneğin
ADOPT LEVEL 3 ile benimsenmiş ya da DROP LEVEL 3 ile boşaltılmış) damgası
ALTER DATABASE ... SET LEVEL 3 VERSION '<v>' GENERATED '<zaman>' ile yazılır; benimseme damga
yazmaz. Seviye 4'te damga yoksa yükseltme uygulanır ama hiçbir yükseltme komutu koşmaz (WARNING satırı).
Paketin alt sınırı (EXPORT LEVEL ... MIN VERSION) varsa damgası ondan eski hedef MINIMUM
satırıyla reddedilir.
Seviye 3 boşken seviye 4 yüklenmez. Katalogda seviye 3 bandından hiçbir nesne yoksa
UPGRADE LEVEL 4 — PREVIEW dahil, paket dosyasına bakılmadan — reddedilir ve önce
UPGRADE LEVEL 3 koşulması gerektiğini söyler: seviye 4 nesneleri seviye 3'e dayanır (tablolarına yabancı
anahtar, yordamlarına çağrı). Ölçüt katalogdaki seviye 3 nesne sayısıdır, damga değil. ADOPT bu kapıya
tabi değildir — paket yüklemez, depoda zaten duran tabloyu kataloğa yazar.
Kolon kaybının kapısı seviyeye göre değişir. Seviye 4 kullanıcının kendi nesnelerini taşır: kazayla düşürülen bir kolonun geri dönüşü olmadığı için orada açık onay istenir. Seviye 3 ürünün kataloğudur ve denetimden geçmeden yayınlanmaz, yani değişiklik zaten bilerek yapılmıştır; orada rapor uyarır ve koşu durmaz. Uyarı satırları önizlemede de görünür, yani uygulamadan önce okunabilir.
Yanlış ürünün paketi uygulanmaz. Kartta ürün kodu varsa (ivd$product)
ve paketinki farklıysa yükseltme hiçbir şey uygulamadan durur — bu bir onay sorusu değil, yanlış dosyadır; geçiş yolu
yoktur. Hedefte kod yoksa paketinki yazılır, pakette yoksa karşılaştırılacak bir şey olmaz. Önizleme reddedilmez,
PRODUCT satırında iki kodu da gösterir.
Tabloları veritabanıyla örtüşmeyen seviye 3 paketi uygulanmaz. Ürün kodu aynı ürünün
iki derlemesini ayırmaz: güvenlikli derleme tablolarını NS_ önekiyle kurar, normal derleme öneksiz.
Veritabanı boş değilse (katalogda ya da depoda en az 20 ürün tablosu) ve paketin seviye 3 tablolarının yarısından azı
veritabanında adıyla bulunuyorsa yükseltme hiçbir şey uygulamadan durur; geçiş yolu yoktur. Önizleme reddedilmez,
MISMATCH satırında iki sayıyı gösterir. Seviye 4 paketleri ve boş veritabanı bu denetimin dışındadır.
Koşu boyunca veritabanı bakımdadır. ACTIVE bir veritabanı uygulama
evresinin başında LEVEL3_UPDATE durumuna çekilir — o sırada yalnız sahibi, SYSDBA ve SYSADMIN üyeleri
kullanabilir — ve koşu hatasız biterse ACTIVE'e döner. Seviye 3'te hata varsa orada bırakılır; anlamı
zaten "seviye 3 yeniden üretilmeyi bekliyor"dur. Daha kısıtlı bir duruma (RESTRICTED,
READ_ONLY, OFFLINE) dokunulmaz. Aynı veritabanında ikinci bir yükseltme
başlatılamaz: koşan yükseltmenin süreci canlıysa ikincisi reddedilir.
Sürüm gerilemesi ALLOW DOWNGRADE ister. Paketin sürümü
veritabanınınkinden eskiyse yükseltme uygulanmaz; önizleme reddedilmez, raporuna DOWNGRADE satırı düşer.
Karşılaştırma yükseltilen seviyenin kendi damgasıyla, iki damga da doluyken yapılır; parça parça sayısaldır (harfler
yok sayılır, 2.0.0-beta ile 2.0.0 eşit sayılır) ve eşit sürüm serbesttir. ALLOW DOWNGRADE
ayrı bir cümleciktir: CONFIRMED veri kaybını onaylar, bu ise sürümün geriye gitmesini — biri ötekinin
yerine geçmez.
Kod nesneleri tablolardan önce düşer, paketten yeniden kurulur. Uygulama evresinde tanımlar ve
tablolar kataloğa alındıktan sonra o seviyenin katalogdaki bütün kod nesneleri (görünüm, yordam, işlev, tetikleyici)
bağımlılık sırasıyla motorun DROP'uyla düşürülür — bu depodan da düşürür — ve tablo değişiklikleri ancak
ondan sonra uygulanır; paketin kodu ardından temiz CREATE ile kurulur. Böylece depoda kalan eski kod,
paketin kaldırdığı bir kolona bağlı olduğu için tablo değişikliğini engellemez. Düşürülemeyen bir paket nesnesi (örneğin
seviye 4'te bir bağımlısı var) yerinde kalır, raporda KEPT satırıyla görünür ve paketin metniyle yeniden
tanımlanır. Depoda olup katalogda olmayan kod nesneleri için ADOPT CODE karar verir:
yazılmazsa (öndeğer) bunlar depodan doğrudan düşürülür (DROP satırı, ayrıntısı storage only;
PREVIEW aynı satırları gösterir); yazılırsa önce kataloğa benimsenir, sonra katalogdakilerle birlikte
düşürülür. Yalnız paketin nesne taşıdığı şemalara bakılır: hedefin başka şemalarındaki ve paketin boş açtığı
şemalardaki (ürünün EKLENTI'si gibi) nesnelere dokunulmaz. Yordam ve işlev tek
ad kümesidir (PostgreSQL'de tek çıkışlı yordam depoda işlev olarak durur). İşlevi tablonun şeması dışında duran bir
tetikleyici, paketin tablosuna bağlı olsa da düşürülmez (KEPT satırı). Birbirini çağırdığı için depodan
düşmeyen yordam, işlev ve tetikleyicilerin (Firebird) gövdesi bildirimleri korunarak boşaltılır (STUB
satırı; seçilebilir yordam SUSPEND'i, işlev RETURN NULL'u korur) ve düşürme yeniden denenir;
yine de düşmeyen (örneğin bir tablo kolonunun kullandığı işlev) benimsenip paketin metniyle yeniden tanımlanır.
Paketin birbirini çağıran kodu da aynı yolla kurulur: önce boş gövdeli bildirimler, sonra tam metin.
Tek başına kullanım. Yükseltme her adımı kendi COMMIT'iyle uygular; koşu boyunca veritabanını başka oturum kullanmamalıdır. Kart durumu koşu boyunca LEVEL3_UPDATE'tir (yalnız sahip, SYSDBA ve SYSADMIN girer). Ayrıca: veritabanını kullanan başka bir IVEDI kullanıcı oturumu varsa 10 saniye beklenir, kalırsa yükseltme reddedilir. Depo yeni oturumlara kapatılır — PostgreSQL'de CONNECT yetkisi PUBLIC'ten ve depo kullanıcısı dışındaki rollerden geri alınır (süper kullanıcılar bağlanabilir; depo kullanıcısı veritabanının sahibi ya da süper kullanıcı değilse kapı kurulamaz ve rapora WARNING düşer), Firebird'de geçici bir ON CONNECT tetikleyicisi (IVD$UPGRADE_GATE) depo kullanıcısı ve SYSDBA dışındaki bağlantıyı reddeder. Depoya doğrudan bağlı açık oturumlar (uygulama, psql, isql; motorun kendi bağlantıları sayılmaz) 10 saniye beklenir; kalanlar TERMINATE SESSIONS yazılmışsa kapatılır, yazılmamışsa yükseltme reddedilir. Kapı koşu bitince — hata ya da ret dahil — açılır; süreç koşu ortasında çökerse kapı MASTER kaydında kalır ve ajan bir sonraki açılışta onu açar. Önizleme açık oturumları SESSION / WARNING satırları olarak listeler.
Depo karşılaştırması. UPGRADE LEVEL hedefin kataloğundaki seviye nesnelerini depodakilerle de karşılaştırır: tablolar ve kolonları, domain'ler, diziler, görünümler ve EXECUTION STORAGE veritabanında yordam, fonksiyon ve tablo tetikleyicileri. Katalogda olup depoda olmayan her biri önizlemede WARNING satırıdır. Yükseltme, paket adımlarından önce eksik kolonu katalog tanımıyla depoya ekler (öndeğeri sabitse mevcut satırlara yazılır); depoda olmayan bir tablo, domain, dizi ya da kod nesnesi pakette varsa onu yalnız katalogdan düşürür (katalogdaki bağımlılarıyla birlikte, depoya dokunmadan) ve paketin olağan adımları onu yeni nesne olarak depoyla birlikte kurar. Pakette olmayan eksik nesneye dokunulmaz.
Depodaki kolon sırası katalogdakinden farklıysa (kolon depoya elle sona eklenmiş) WARNING yazılır; Firebird
deposunda kolonlar kataloğun sırasına taşınır (PostgreSQL kolon sırasını değiştiremez). Katalogda bir domain'le tanımlı
kolon depoda o domain'e bağlı değilse (elle tip değişikliği, adsız sistem domain'i) WARNING yazılır ve
kolon domain'e bağlanır (Firebird ve PostgreSQL): boş değerler domain'in öndeğerini alır, PostgreSQL'de kolonun
NOT NULL'u geri gelir; kolona bağlı kod nesneleri düşürülüp paketten yeniden kurulur. Depoda olup katalogda olmayan kolona dokunulmaz, paketin düşürdüğü nesneler karşılaştırılmaz. Veritabanı Metadata Operations=OFF ile açıksa ve paket yapıyı değiştiriyor ya da depo kataloğun gerisinde kalmışsa yükseltme reddedilir (önizlemede MISMATCH satırı): o seçenekle depo DDL'i gönderilmez, değişiklik yalnız kataloğa yazılırdı.
Güvenlik yapısı. Ürünün güvenlikli derlemesi tablolarını NS_X adıyla kurar ve her birinin üstüne X görünümünü koyar; normal derlemede X tablodur. Veritabanının hangisi olduğu kimlik kartındaki bayraktır: ALTER DATABASE <db> SET SECURITY ON | OFF (ivd$v_database.security). EXPORT LEVEL kaynağın bayrağını pakete yazar ve UPGRADE LEVEL paketin bayrağı hedefinkinden farklıysa uygulamayı reddeder (önizlemede MISMATCH satırı): güvenlikli paket normal veritabanına, normal paket güvenlikli veritabanına uygulanmaz. Bayrağı taşımayan eski bir pakette karşılaştırma yapılmaz, tablo örtüşmesi denetimi kalır. Normal bir veritabanını güvenlikliye çevirmenin yolu CONVERT TO SECURITY'dir: güvenlikli paket normal veritabanına uygulanır, her X tablosunun satırları (ortak kolonlar; NS_X'in ek güvenlik kolonları kendi öndeğerleriyle) NS_X'e kopyalanır, X tablosu düşer, X görünümü kurulur ve hatasız biterse kart SECURITY ON olur. Ters yön CONVERT TO NORMAL'dır: normal derlemenin paketi güvenlikli veritabanına uygulanır, X görünümü (pakette olmadığı için) kod adımında düşer, X tablosu kurulur, her NS_X tablosunun satırları (ortak kolonlar; NS_X'in ek güvenlik kolonları bırakılır) X'e kopyalanır, NS_X veri kaybı onayı istemeden düşer, komutlardaki $(NS_) boş açılır ve hatasız biterse kart SECURITY OFF olur. İkisi de yalnız seviye 3'te çalışır; birincisi yalnız normal hedefe güvenlikli paketle, ikincisi yalnız güvenlikli hedefe normal paketle. ivd$upgrade komutlarındaki (EXECUTE SQL, EXECUTE SQL FOR, OPEN SQL) $(NS_) ifadesi komut çalışmadan hemen önce açılır: güvenlikli hedefte (ve dönüşümde) NS_, normal hedefte boş; NATIVE_SQL sarmalının içi dahil. Paket metni $(NS_)'yi açılmadan taşır.
PREVIEW yazılmazsa, listenin ardından şema nesneleri uygulanır:
SKIPPED raporlanır.Table.Insert aralığında hedefte olmayan tablolar CREATE TABLE ile kurulur ve var olan
bütün tabloların eksik kolonları eklenir (UPGRADE TABLE … WITH DEFAULTS ADD ONLY);
Table.Update aralığında tip, NULL'luk, öndeğer, kısıt ve kolon sırası paketinkine
getirilir (UPGRADE TABLE … WITH DEFAULTS; yalnız sırası farklı tablo da işlenir);
Table.Delete aralığında pakette olmayan kolonlar düşürülür. Satır verisi korunur; her olay bir ve
yalnız bir kez çalışır. Tablolar yabancı anahtar sırasıyla (hedef önce) işlenir; kurulmamış bir tabloya başvuran
anahtar ikinci geçişte eklenir. Katalogda olmayan ama depoda aynı adla duran bir kolon (elle eklenmiş) düşürülmez,
benimsenip paketin tipine çevrilir.
Pakette olup katalogda olmayan bir tablo depoda duruyorsa önce benimsenir: yükseltme fiziksel
şekli okur, ADOPT TABLE'ın yolundan kataloğa yazar (depoya DDL gitmez, kimlik seviyenin bandından
gelir) ve farkı UPGRADE TABLE … WITH DEFAULTS ile uygular — satırlar korunur. Kataloğu
DROP LEVEL ile boşaltılmış bir veritabanının seviyesi bu sayede tek deyimle, elle şema kurmadan ve
ADOPT çağırmadan yeniden kurulur. Yalnızca paketin adını taşıdığı tablolar benimsenir;
kataloğun hiç bilmediği bir tabloya dokunulmaz.CONFIRMED ister: boş tablo sessizce düşer, dolu olan önizlemede satır sayısıyla birlikte
CONFIRM satırı olarak listelenir ve onaysız koşu reddedilir. Satır sayısı okunamayan tablo dolu
sayılır.NOT NULL eklenmesi (boşluklar WITH DEFAULTS ile
doldurulur) — seviye 4'te CONFIRMED ister, seviye 3'te yalnızca uyarı olarak
raporlanır. Denetim satır sayar: boş tablo ve sığan veri sessizce geçer; yalnız sayısal
daraltmada şema farkı yeterli sayılır. Satır sayısı okunamayan kolon riskli sayılır.CREATE ile, değişmiş ya da geçersiz olanlar CREATE OR ALTER ile (kimlik,
haklar ve öznitelikler korunur). Değişmeyenlere dokunulmaz. Birbirine bağlı nesneler, ilerleme durana kadar
yinelenen turlarla sıralanır. Önizleme, hedefte geçersiz damgalı (IVD$VALID = 'N') seviye
nesnelerini, katalogda saklanan ilk geçersizlik nedeniyle (IVD$INVALID_REASON) birlikte
WARNING satırı olarak gösterir.SEED / SEQUENCE satırı) — yoksa ilk gerçek INSERT tohum satırıyla çakışırdı. Hedefte zaten bulunan satır güncellenmez; tablo
ATTRIBUTES ("ns.seed.update" = 'Y') taşıyorsa paketteki değerlerle güncellenir. Paketin sahip
olduğu satırları bir koşulla belirten tablo (ATTRIBUTES ("ns.seed.scope" = 'GUVENLIK_SINIF_NO < 0'),
tablonun kolonlarıyla, nitelemesiz) o kapsamda hedefi pakete eşitler: olmayan satır eklenir,
değeri farklı olan güncellenir (yalnız farklı olanlar), pakette olmayan silinir; kapsam dışındaki satırlara
(müşterinin kayıtları) dokunulmaz. Silmeler yabancı anahtar sırasının tersiyle, eklemeler ebeveynden başlar.
Rapor tablo başına eklenen / güncellenen / silinen satırı yazar; fark yoksa satır UNCHANGED'dır.
Tetikleyiciler bu
adımda kuruludur ama öndeğerde susturulur; tetikleyicilerinin çalışmasını isteyen tablo
ATTRIBUTES ("ns.seed.triggers" = 'Y') yazar. Depoda koşan tetikleyiciler (PostgreSQL, Firebird)
ürünün kendi kalıbıyla susar: motor bağlantıyı bakım kipine alır
(SetUtilityMode(1)), tetikleyici gövdeleri de GetUtilityMode() <> 1 ile korunduğu
için kendileri çekilir. Bu işlevleri taşımayan bir veritabanında ya da bakım kipine geçmeye yetkisi olmayan bir
bağlantıda uyarı yazılır ve tetikleyiciler açık kalır.COMMENT ON), yerelleştirme satırları (FOR LOCALE) ve haklar da paketle taşınır:
önizleme nesne başına DESCRIPTION, LOCALIZATION ve PRIVILEGES satırları verir,
uygulama hedefteki karşılıklarını kaynağınkiyle değiştirir. Hak satırının alıcısı adla eşlenir; hedefte
o adda bir kullanıcı ya da rol yoksa satır SKIPPED raporlanır, veren ise hedefin SYSTEM
kullanıcısıdır.LEVEL3_UPDATE
durumu kalkar.Yeni nesneler seviyenin kimlik aralığından kimlik alır. Her deyim kendi COMMIT'iyle çalışır; bir nesnenin hatası
ötekileri durdurmaz ve deyimin metniyle birlikte ERROR satırı olur. Son satır (APPLY) kaç
deyimin uygulandığını ve kaç hata olduğunu verir.
Yükseltme komutları. Paketin ivd$upgrade satırları (bu seviye, etkin, bu depo motoru,
hedefin eski sürümü aralıkta) adlarıyla eşleşen olayda, ivd$position sırasıyla çalışır. Olay adları
<Nesne>.<Olay>.<Before|After> biçimindedir ve her olay kendi adımında bir kez çalışır:
| Olay | Ne zaman |
|---|---|
Upgrade.Run.Before | Her şeyden önce |
Privilege|Role|Generator|Exception|Function.Delete.Before/After,
Trigger|View|Procedure|Function.Destroy.Before/After | Düşürme pencereleri; kod nesneleri ön evrede düşürüldüğü için bu olaylar yalnız komutları için art arda çağrılır |
Domain|Generator|Exception|Function.Insert|Update.Before/After | Yeni domain, dizi, istisna ve dış işlevlerin kurulmasının önünde ve ardında (bu sırayla) |
Table.Insert|Update.Before | Tablolar kurulmadan / yükseltilmeden önce |
Table.Insert.After | Yeni tablolar kurulduktan ve var olan bütün tabloların yeni kolonları eklendikten sonra; tip ve sıra henüz değişmedi, düşecek kolonlar hâlâ yerinde — bir alanı ikiye bölen ya da iki alanı birleştiren dönüştürücü eski ve yeni kolonu burada birlikte görür |
Table.Update.After | Tip, NULL'luk, öndeğer, kısıt ve kolon sırası değiştikten sonra — düşecek kolonlar hâlâ yerinde |
Index.Insert|Update|Delete.Before/After | İndekslerin önünde ve ardında |
Table.Delete.Before/After | Kolon ve tablo düşürmelerinin önünde ve ardında; eski kolondan
yenisine veri göçü Table.Delete.Before'da yazılır |
Domain.Delete.Before/After | Tablo düşürmelerinin ardından; pakette olmayan domainler düşürülmediği için yalnız komutları çalışır |
Trigger|View|Procedure|Function.Insert|Update.Before/After | Kod nesnelerinin kurulmasının önünde ve ardında |
Privilege.Update.Before/After, Upgrade.Run.After | En sonda, damgadan önce |
EXECUTE SQLivd$data'daki SQL'i çalıştırır.EXECUTE SQL FORivd$data: 1) satırından sonra satırları veren bir
SELECT, 2) satırından sonra her satır için çalışan SQL; %KOLON% o satırın
değeriyle değiştirilir.OPEN SQLMESSAGE, WARNINGCONFIRMCONFIRM satırı taşıyorsa önizlemesiz
yükseltme CONFIRMED yazılmadan reddedilir.Bir komut hata verirse: ivd$abort_on_error = 'Y' ise yükseltme o noktada durur — o
ana kadar yapılanlar kalır, sonraki adımlar çalışmaz, damga yazılmaz ve yükseltme düzeltme sonrası yeniden
çalıştırılabilir; aksi halde hata bir WARNING satırı olur ve yükseltme sürer.
Şema farkının kendi başına çözemediği işler (kolon yeniden adlandırma, tablo birleştirme/ayırma, öndeğer atama) bu seviye 2 tablosunun satırlarıyla yazılır; satırlar seviye paketiyle taşınır.
| Kolon | Anlamı |
|---|---|
ivd$level | Komutun seviyesi: 3 ya da 4 |
ivd$event, ivd$position | Komutun bağlandığı yükseltme olayı ve olay içindeki sırası |
ivd$command | EXECUTE SQL, EXECUTE SQL FOR, OPEN SQL,
CONFIRM (önizlemede de çalışır), MESSAGE, WARNING |
ivd$data | Komutun metni (IVEDI lehçesi). Depo motoruna göre ayrı satır
yoktur: iki lehçede aynı işi yapan bir komut tek satırdır ve iki metni de
NATIVE_SQL deyimiyle taşır — NATIVE_SQL(POSTGRESQL '…', FIREBIRD '…'). Metin
verilmeyen bir depoda deyim sessizce boş geçer, hata vermez. |
ivd$start_version, ivd$end_version | Hedefin eski seviye 3 sürümü bu aralıktaysa
çalışır: başlangıç dahil, bitiş hariç (start ≤ eski < end; bitiş, değişikliğin yapıldığı
sürümdür). Noktalı parçalar sayı olarak karşılaştırılır. Damgasız hedefte bütün komutlar çalışır. |
ivd$utility_mode | Komutun deponun hangi utility mode'unda çalışacağı (ürünün
SetUtilityMode / GetUtilityMode işlevleri): 0 Normal, 1 Bakım, 2 Dönüşüm, 3 Veri düzeltme,
4 Veri iyileştirme, 5 Geliştirici; boş ise kipe dokunulmaz. EXECUTE SQL, EXECUTE SQL FOR
ve OPEN SQL bu kipte çalışır, komut bitince önceki kip geri yazılır; ürünün tetikleyicileri
GetUtilityMode() <> n ile kendilerini çeker. Kip yalnız depo yürütmeli (Firebird, PostgreSQL) ve
bu işlevleri taşıyan veritabanında vardır; kurulamazsa rapora uyarı düşer ve komut geçerli kipte çalışır. |
ivd$abort_on_error, ivd$active, ivd$description, ivd$creation |
Hata davranışı, etkinlik, açıklama, satırın girildiği an |
Depoda var olan ama katalogda karşılığı olmayan bir tabloyu kataloğa alır; depoya dokunmaz. Seviye 4 kullanıcısı tabloyu depoda kendi aracıyla açar ve mevcut hâlini böyle IVEDI'ye tanıtır:
SET CATALOG urun_db;
SET SEARCH_PATH TO app;
ADOPT TABLE musteri_notu; -- seviye 4 (öndeğer)
ADOPT TABLE fatura_ek LEVEL 3; -- ürünün bandı: ayrıcalıklı kimlik isterDepo motoru tablonun şeklini kendi kataloğundan okur; motor bundan kendi CREATE TABLE ve
CREATE INDEX metnini üretir ve yalnız kataloğa yazar. Kolonlar, tipler, öndeğerler, NOT NULL, birincil
anahtar, UNIQUE kısıtları, indeksler (azalan olanlar dahil) ve yabancı anahtarlar (ON UPDATE / ON DELETE eylemleriyle)
alınır. Depodaki bir domain'e bağlı kolon, katalogda aynı adlı bir domain varsa onu, yoksa temel tipi kullanır. Kimlik
istenen seviyenin aralığından verilir. Hedefi katalogda olmayan bir yabancı anahtar atlanır ve raporlanır: önce hedef
benimsenmelidir. EXECUTION STORAGE kipinde deponun kendi değer ürettiği kolonlar kimlik kolonu olarak, CHECK kısıtları ve
hesaplanan (COMPUTED BY / GENERATED ALWAYS AS) kolonlar ise ifadeleri NATIVE_SQL içinde
korunarak alınır — ifade deponun kendi lehçesindedir ve oraya olduğu gibi geri gider. EXECUTION IVEDI kipinde
bunlar atlanır ve SKIPPED satırıyla raporlanır (motor deponun ifadesini değerlendiremez). İfade ya da koşullu
indeksler her iki kipte de atlanır. Sonunda motor, kataloğun bu tablo için hesapladığı fiziksel adın depodaki tabloyla aynı olduğunu doğrular;
değilse benimseme geri alınır.
| Depo motoru | Tablo nerede aranır |
|---|---|
| sqlite, Firebird | Tablo adıyla (şemasız) |
| PostgreSQL | IVEDI şemasının aynı adlı (küçük harf) ad alanında, yoksa varsayılan şemada |
| ODBC (PostgreSQL üzerinden) | Bağlantının varsayılan şemasında |
Üst düzey deyimdir, deyim anında çalışır ve COMMIT eder.
Depoda var olan bir yordamı, işlevi ya da tetikleyiciyi kataloğa alır; depoya dokunmaz. İmza (parametreler,
dönüş tipi, tetikleyicinin tablosu, olayı, konumu ve etkinliği, SQL SECURITY) deponun kataloğundan,
gövde deponun sakladığı metinden gelir. Firebird deposunda Firebird 4 veya üstü gerekir
(RDB$SQL_SECURITY); daha eski bir sürümde deyim bunu söyleyen bir hatayla reddedilir.
| Depo | Okunanlar |
|---|---|
| Firebird | yordam, işlev (PSQL), tetikleyici |
| PostgreSQL, ODBC | plpgsql yordam ve işlevleri, tetikleyiciler; arama yolunun ilk şemasına ait ad
alanından. Küme döndüren işlev (RETURNS TABLE) IVEDI'de RETURNS'lü yordamdır.
Tetikleyicinin gövdesi bağlı olduğu işlevin gövdesidir; IVEDI'nin kurduğu <ad>_00000 /
<ad>_trigger adları IVEDI adına ve konumuna geri çözülür. LANGUAGE SQL işlevleri ve
eklentilere ait işlevler okunmaz. |
| sqlite | yalnız tetikleyici (sqlite'ta yordam yoktur), CREATE TRIGGER metninden.
WHEN koşulu ve UPDATE OF <kolonlar> IVEDI'de karşılıksızdır ve tetikleyicinin
anlamını değiştirir; böyle bir tetikleyici adıyla reddedilir. |
EXECUTION IVEDI kipindeki bir veritabanında (sqlite'ın öntanımlısı) tetikleyiciyi motor çalıştırır;
depodaki fiziksel tetikleyici de yerinde kaldığı için ikisi birden tetiklenir. Benimseme bunu bir NOTE
satırıyla bildirir: fiziksel tetikleyiciyi depodan kaldırın ya da EXECUTION STORAGE kullanın.
SET CATALOG urun_db;
ADOPT TABLE musteri; -- gövdeler tablolara başvurur: önce tablolar
ADOPT PROCEDURE musteri_bakiye;
ADOPT FUNCTION tutar_yuvarla;
ADOPT TRIGGER musteri_bi LEVEL 3;Gövde önce MQL olarak derlenir. Derlenirse nesne sıradan bir IVEDI nesnesidir: analiz edilir,
başka lehçelere çevrilir. Derlenmezse — gövde Firebird'e özgü bir yapı kullanıyorsa (Firebird'ün kendi sistem
tabloları, SET BIND gibi oturum deyimleri) — gövdenin tamamı deponun metni olarak saklanır:
CREATE PROCEDURE rol_var_mi (p_ad VARCHAR(50)) RETURNS (var_mi CHAR(1)) AS
NATIVE_SQL(FIREBIRD '
begin
var_mi = ''H'';
if (exists(select 1 from rdb$auth_mapping where rdb$map_name = :p_ad)) then
var_mi = ''E'';
suspend;
end')Böyle bir nesne aynı depoya olduğu gibi geri kurulabilir, ama başka bir lehçeye çevrilemez ve
ALTER DATABASE … VERIFY LEVEL onu bildirir. Rapor iki durumu ayırır: ADOPT (MQL olarak
derlendi) ve ADOPT NATIVE (depo metni olarak saklandı; ayrıntı sütunu derlemenin neden düştüğünü
söyler). İkisi de düşerse benimseme durur ve iki nedeni birden bildirir. Katalogda zaten bulunan bir nesne ikinci kez
benimsenmez.
Paket içindeki yordamlar ve işlevler ile kısıtların kendi tetikleyicileri bu deyimin kapsamı dışındadır; dış
işlevler (UDF) ADOPT EXTERNAL FUNCTION ile alınır.
Depodaki öteki nesne türlerini kataloğa alır; depoya dokunmaz. Tanım deponun kataloğundan okunur ve motorun kendi
CREATE deyimiyle kataloğa yazılır. SEQUENCE yerine GENERATOR da yazılabilir.
Adın son parçası depodaki ad, öncesi (varsa) IVEDI şemasıdır — yazılmazsa arama yolunun ilk şeması.
| Depo | Okunanlar |
|---|---|
| Firebird | harmanlama, dizi, domain, dış işlev (UDF), istisna, görünüm. Kimlik kolonunun üreteci
tablonun parçasıdır, ayrıca okunmaz. Firebird'ün harmanlamaya kendiliğinden eklediği COLL-VERSION ve
ICU-VERSION ögeleri alınmaz. Dizi (array) ve hesaplanan domain reddedilir. |
| PostgreSQL, ODBC | ICU harmanlaması, dizi, domain, görünüm; arama yolunun ilk şemasına ait ad
alanından. Bir kolona bağlı dizi (serial, kimlik) ve eklentilere ait nesneler okunmaz. ICU yerel
ayarının -u-ks-level1, -u-ks-level2, -kc-true, -ka-shifted
ögeleri ACCENT INSENSITIVE, CASE INSENSITIVE, PAD SPACE olarak geri çözülür;
başka bir öge ya da ICU dışı harmanlama reddedilir. Domain'in birden çok CHECK'i
AND ile birleşir. |
| sqlite | yalnız görünüm (sqlite'ta öteki türler yoktur), CREATE VIEW metninden. |
Deponun ifadesi (domain'in CHECK'i, görünümün SELECT'i) önce MQL olarak derlenir.
Derlenmezse EXECUTION STORAGE kipindeki bir veritabanında depo metniyle benimsenir — görünüm
CREATE VIEW v (kolon tip, …) AS NATIVE_SQL(<depo> '…'), domain
CHECK (NATIVE_SQL(<depo> '…' AS BOOLEAN)) olarak; rapor bunu ADOPT NATIVE diye ayırır.
EXECUTION IVEDI kipinde ifadeyi motor değerlendireceği için böyle bir nesne adıyla reddedilir.
ADOPT COLLATION harman_ci; -- domain ve kolonlar harmanlamaya başvurur: önce o
ADOPT SEQUENCE sq_fatura;
ADOPT DOMAIN d_tutar;
ADOPT EXTERNAL FUNCTION u_yuvarla;
ADOPT EXCEPTION e_kayit_yok;
ADOPT VIEW v_acik_fatura LEVEL 3;Bir yordamın, işlevin ya da tetikleyicinin gövdesi AS'tan sonra tek bir NATIVE_SQL
olabilir. Metin AS'tan sonraki her şeydir: bildirimler ve kendi
BEGIN … END'i. Üretilen metinde çevresine blok yazılmaz. Motorun kendi koşusunda gövde hiçbir şey
yapmaz — NATIVE_SQL deyiminin kuralı.
Kataloğa ya da bir seviyeye dokunan her işlem bu tabloya bir satır yazar:
ALTER DATABASE … UPGRADE (IVD$OPERATION = UPGRADE),
UPGRADE LEVEL, DROP LEVEL ve ADOPT LEVEL. Önizleme yazmaz.
| Kolon | Ne tutar |
|---|---|
ivd$operation, ivd$level | İşlem ve seviyesi (katalog yükseltmesinde seviye boştur) |
ivd$started, ivd$finished | İşlemin başlangıcı ve bitişi (UTC) — kartın damgasındaki zaman kaynağın üretim zamanıdır, bu ise bu veritabanında ne zaman koşulduğu |
ivd$login | Çalıştıran kimlik |
ivd$package | Paket dosyası (UPGRADE'de yedek yolu) |
ivd$from_version, ivd$to_version | Önceki ve yeni sürüm; katalog yükseltmesinde katalog biçim numaraları |
ivd$options | Verilen onaylar ve seçenekler: CONFIRMED, ALLOW DOWNGRADE, ADOPT CODE, CONVERT TO SECURITY, CONVERT TO NORMAL |
ivd$created, ivd$dropped, ivd$altered, ivd$errors |
Eylem sayıları ve hata sayısı |
ivd$result | OK | ERROR | STOPPED |
ivd$engine_version | İşlemi yapan motorun sürümü |
ivd$report | Raporun tamamı (eylem satırları) standart bir ZIP
dosyası olarak: ilk girdi upgrade-report.txt; işlemde hata satırı varsa ikinci girdi
agent-log.txt işlemin başından bu yana ajan günlüğüne yazılanları (en çok son 4 MB) taşır. Kolonu indiren herhangi bir araç
açabilir; SQL'den metne çevirmek için Metadata.UpgradeReportText(ivd$report), boyutu
octet_length(ivd$report) verir |
SELECT ivd$started, ivd$operation, ivd$level, ivd$from_version, ivd$to_version, ivd$result, ivd$login
FROM sys.ivd$upgrade_history ORDER BY ivd$history_id DESC;
SELECT Metadata.UpgradeReportText(ivd$report) -- bir koşunun raporunun tamamı
FROM sys.ivd$upgrade_history WHERE ivd$history_id = 3;Metadata.UpgradeReportText(<ikili>) arşivin ilk girdisini metin olarak verir; zip olmayan bir
değere hata atar, boş değere boş döner. Genel amaçlı bir açıcı değildir — adı bu yüzden dardır. Kolonun kendisi
indirilebilir: .zip olarak kaydedilen içerik her araçta açılır.
Geçmiş hedef veritabanının içindedir: veritabanı kopyalandığında geçmişi de gider. Satır bir izdir, işin kendisi değil — yazılamazsa işlem başarısız sayılmaz, günlüğe bir uyarı düşer.
O seviyenin katalog bilgisini siler ve depoya dokunmaz: tablolar, indeksler,
satır verileri ve motorun dışında kurulmuş her şey olduğu gibi kalır. ADOPT'un tersidir — benimseme
depodaki tabloyu kataloğa alır, bu komut katalogdan çıkarır. Ürünün katalog geçişini baştan koşturmak için kullanılır.
SET CATALOG urun_db;
ALTER DATABASE urun_db DROP LEVEL 4 PREVIEW; -- ne silinecek, yazmadan
ALTER DATABASE urun_db DROP LEVEL 4;
ALTER DATABASE urun_db DROP LEVEL 3;Kapsam kimlik aralığıdır: seviye 3 = 10.000.000 – 19.999.999, seviye 4 = 20.000.000 ve üstü. Ürünün
şemaları da bu aralıktadır ve silinir. Seviye 4 nesnesi dururken seviye 3 silinmez; önce
DROP LEVEL 4 koşulur (seviye 4 nesneleri seviye 3'e dayanabilir). Silinenler: IVD$OBJECTS
ve nesneye bağlı bütün satırlar (kolonlar, öznitelikler, yerelleştirme, bağımlılıklar — iki yön de, haklar — nesne,
alıcı ya da veren o aralıktaysa, indeks kolonları) ve o seviyenin ivd$upgrade komutları. Kartın
o seviyeye ait damgası da temizlenir; seviye 3'te ayrıca ACTIVE bir veritabanı
LEVEL3_UPDATE durumuna geçer — o durumun anlamı zaten "seviye 3 yeniden üretilmeyi
bekliyor"dur. Seviye 4 silmek durumu değiştirmez.
Seviyenin bellekte yüklü nesneleri de ayrılır (raporda UNLOAD); aynı adlarla şema ve nesneler
hemen yeniden kurulabilir. Seviye 3 silinince nesne kimlik dizisi 10.000.000'e döner (raporda SEQUENCE),
yeniden kurulan seviye 3 nesneleri yine seviye 3 aralığında kimlik alır. Tablolar depoda kaldığından silinen seviyeyi
depodan geri almak için şemayı kurup ALTER DATABASE … ADOPT LEVEL koşun.
ALTER DATABASE yetkisi ve ayrıcalıklı kimlik ister; üst düzey deyimdir.
O seviyenin nesnelerini hedef lehçeye çevirmeyi dener ve çeviremediklerini listeler.
Hiçbir şey yazmaz, hiçbir şey çalıştırmaz: üretilen metin atılır, ölçülen şey üretimin başarısıdır. Hedef adları
#MODE CONVERT TO ile aynıdır.
SET CATALOG urun_db;
ALTER DATABASE urun_db VERIFY LEVEL 3 FOR FIREBIRD;
ALTER DATABASE urun_db VERIFY LEVEL 4 FOR POSTGRESQL;Çevrim katı kipte (STRICT) yapılır, yani yoruma indirilen işlevsel bir yapı da
kusur sayılır. Cevap alışılmış eylem sonuç kümesidir: çevrilemeyen her nesne için bir FAILED
satırı (nesne, tür, neden) ve sonda bir özet. Çevrilebilen nesneler rapora girmez.
Denenenler, nesnenin motorda duran deyimleridir: yordam / işlev / tetikleyici gövdesi,
görünüm SELECT'i, kolon öndeğeri ve üretilen kolon ifadesi, CHECK ifadesi; ayrıca
hedefte hiç karşılığı olmayan nesne türleri (özel durum, paket).
Önce COMMIT. Bir DDL'in nesne kimliği işlendiğinde kesinleşir; işlenmemiş
DDL'i olan bir oturumda o nesneler seviyenin dışında görünür ve doğrulanmaz. Rapor bunu bir
NOTE satırıyla sayısıyla birlikte söyler.
ALTER DATABASE yetkisi ve ayrıcalıklı kimlik ister; üst düzey deyimdir.
Kaynak şema arama yolundan alınmaz. Seviye 3 yalnız ürünün NETSIM şemasından benimser (SCHEMA
başka bir ad verirse sözdizimi hatası). Seviye 4 SCHEMA ile verilen şemadan, verilmezse ürünün müşteri
kodu için açtığı EKLENTI'den benimser; seviye 4 NETSIM'den benimseyemez. Şema katalogda
bulunmalıdır, yoksa önce CREATE SCHEMA gerekir. Koşu boyunca arama yolunun başına bu şema konur; seviye
4'te hemen arkasına NETSIM gelir (müşteri kodu ürünün domain ve tablolarına başvurur), en sonda oturumun
yolu kalır. Benimsenen nesneler kaynak şemaya kurulur.
Kaynak şemaya ait, depoda olup katalogda olmayan bütün nesneleri benimser
(IVD$ ile başlayan motor nesneleri hariç): önce harmanlama, dizi, domain, dış işlev ve istisna (tablolar
onlara başvurur), sonra tablolar, en son işlev, görünüm, yordam ve tetikleyici — bu sırayla. Tablolar yabancı anahtar sırasıyla alınır — hedef önce. Birbirine başvuran tabloların
anahtarı DEFERRED raporlanır ve bütün tablolar alındıktan sonra yalnız kataloğa eklenir. Bir nesnenin
hatası ötekileri durdurmaz (ERROR satırı). PREVIEW sırayı ve sayıyı verir, yazmaz.
Ayrıcalıklı kimlik ister.
Kod nesnelerinin gövdesi ve görünümlerin SELECT'i önce MQL olarak derlenir. Derlenmeyen bir tanım hemen
depo metnine düşmez: çoğu zaman yalnızca sırası gelmemiş, daha benimsenmemiş bir nesneye başvurduğu içindir. Bu yüzden bütün nesneler denendikten sonra yeniden denenir;
ancak bir tur hiç ilerleme sağlamazsa kalanlar NATIVE_SQL gövdeyle benimsenir. Birbirini çağıran iki
yordam bu yüzden depo metni olarak kalır.
Tek bir tabloyu, CREATE TABLE yazımıyla verilen yeni tanımına getirir. Motor yeni tanımı canlı tabloyla
kolon adına göre karşılaştırır ve farkı uygular; satır verisi korunur. NOT NULL ve DEFAULT
etkin değerleriyle karşılaştırılır: kolonun kendisininki, yoksa domain'ininki. Domain'i NOT NULL DEFAULT 'G'
olan bir kolonu gövdede yalnız domain adıyla yazmak, canlı tabloda kolonun kendi NOT NULL DEFAULT 'G''si
olsa da değişiklik sayılmaz; gövdedeki kolonun kendi öndeğeri farklıysa SET DEFAULT, öndeğeri yoksa ve
canlı kolonun kendi öndeğeri varsa DROP DEFAULT (domain'inki görünür) uygulanır.
RENAME COLUMN <eski> TO <yeni>, gövdedeki <yeni> kolonunun canlı
tablodaki <eski> kolon olduğunu söyler. Bu olmadan adla karşılaştırma yeniden adlandırmayı
"eskisini düşür, yenisini ekle" diye görür ve veri kaybolur. Kolonun tip, öndeğer ve
NULL'luk farkları eski kolon üzerinden uygulanır, ad en sonda değişir. Eski adı anan bir kısıt imzasıyla eşleşmez:
düşer ve yeni adla yeniden eklenir. Bir kolon en çok bir kez yeniden adlandırılabilir ve hedef ad tabloda
bulunmamalıdır.
UPGRADE TABLE musteri WITH DEFAULTS (
id integer not null,
ad varchar(80) not null, -- NULL'lar '' olur (WITH DEFAULTS)
kod varchar(10) not null upgrade default 'YOK', -- bu kolonun NULL'ları 'YOK' olur
bakiye numeric(15,2) default 0 not null, -- tip değişir, NULL'lar DEFAULT'tan 0 alır
yeni integer not null, -- yeni kolon, var olan satırlarda 0
constraint musteri_pk primary key (id),
constraint musteri_kod_uq unique (kod),
check (bakiye >= 0)
);ivd$objects.ivd$position değerinde (0'dan başlar) saklanır — kataloğu
doğrudan okuyan istemci kolonları buna göre dizer; değeri boş olan eski satırlarda sıra nesne kimliği
sırasıdır. Firebird deposunda kolonlar yerine taşınır (ALTER COLUMN … POSITION), sqlite
tabloyu yeni sırayla kurar; PostgreSQL kolon sırasını değiştiremez, orada sıra yalnız kataloğa yazılır.
IDENTITY ya da GENERATED kolon eklenemez ve değiştirilemez. RENAME COLUMN ile
bildirilmeyen bir ad değişikliği yeniden adlandırma sayılmaz: yeni adla yazılan kolon eklenir, eski ad
düşürülür.ADD ONLYUPGRADE LEVEL var olan tablolara
kolonları Table.Insert aralığında bununla ekler.CREATE TABLE'ın parçası olmadığı için dokunulmaz.UPGRADE DEFAULT <ifade>WITH DEFAULTSUPGRADE DEFAULT'u,
yeni tanımdaki kolonun ya da domain'inin DEFAULT'u (LOCALTIMESTAMP gibi bir ifade de
olabilir; ifade doldurma sırasında hesaplanır), tipin sıfır değeridir (sayı 0, metin '', mantıksal
false). DEFAULT'u olmayan ve sıfır değeri olmayan bir tipte (tarih gibi) kolona
UPGRADE DEFAULT yazılmalıdır.NOT_NULL_VIOLATION ile reddedilir ve değişiklik
geri alınır.PREVIEWOBJECT_NAME, OBJECT_KIND, ACTION,
DETAIL) döndürür. Eylemler: kolon için ADD, DROP, ALTER,
FILL, ATTRIBUTES; kısıt için ADD, DROP; sonda
SUMMARY.Üst düzey deyimdir; ALTER TABLE yetkisi ister. ALTER TABLE gibi çağıranın
transaction'ında çalışır ve COMMIT etmez. Firebird'de DDL COMMIT'e ertelendiği için yeni kısıtlar eklenmeden önce
COMMIT edilir; NOT NULL reddi de orada COMMIT anında gelir. Var olan kolonların NULL doldurması bir UPDATE
ile yapılır, dolayısıyla tablonun satır tetikleyicileri çalışır.
Her veritabanı, kataloğunu motordan bağımsız okumaya yarayan on sistem görünümüyle doğar. Bunlar seviye 2 nesnelerdir (kimlikleri 6001–6010), önyükleme betiğinden kurulurlar, herkese okunur, yazılamaz ve yalnız seviye 3 ile 4 nesnelerini gösterirler — motorun kendi katalog nesneleri ve yerleşik paketlerin iç nesneleri bu yüzeyin dışındadır.
| Görünüm | Ne verir |
|---|---|
IVD$V_TABLES | Tablolar ve görünümler; açıklama, GUID ve ns.* /
sec.* / web.* / doc.* öznitelikleri |
IVD$V_COLUMNS | Kolonlar; tip ölçüleri, öndeğer metni, etkin açıklama ve
öznitelikler (kolon > kaynak kolon > ad kuralı > domain), kolonun kendi değerleri
(OWN_DESCRIPTION, OWN_DOC_SUMMARY) ve görünüm kolonunun kaynağı
(BASE_TABLE, BASE_COLUMN, BASE_ALIAS) |
IVD$V_DOMAINS | Domainler ve öznitelikleri |
IVD$V_PROCEDURES | Yordamlar, işlevler ve tetikleyiciler; kaynak metni, geçerlilik |
IVD$V_RELATIONS | Kısıtlar ve başvurdukları nesneler (yabancı anahtar hedefleri) |
IVD$V_INDEXES | İndeksler ve anahtar kısıtları (PRIMARY KEY, UNIQUE, FOREIGN KEY) tek listede: tekil / azalan / etkin bayrakları, anahtar kolon sayısı |
IVD$V_INDEX_COLUMNS | İndeks ve anahtar kısıtı kolonları, kolon başına bir satır
(IVD$INDEX_COLUMNS katalog tablosu); yabancı anahtarın başvurduğu kolonlar
KEY_ROLE = 'R', ifade indeksinde ifade metni EXPRESSION |
IVD$V_OBJECTS | Her nesne bir satır: sahibinin adı ve türü, temel nesnesi (kolonun / parametrenin tipi — domain ya da yerleşik tip), konumu, kaynağı, açıklaması, geçerliliği |
IVD$V_DEPENDENCIES | Bağımlılıklar: nesne ve kullandığı nesne, ikisinin adı ve türüyle
(bir kolonu okuyan yordamın hem kolon hem tablo satırı vardır); ACCESS_MODE W: kod kolonu
yazar (INSERT listesi, UPDATE / MERGE SET, tetikleyicide NEW.<kolon> = …), R: yalnız okur |
IVD$V_ATTRIBUTES | Bütün öznitelik satırları, koşul metniyle birlikte |
IVD$V_LOCALIZATION | COMMENT ON … FOR LOCALE ile yazılmış dil sürümleri |
IVD$V_DATABASE | Kimlik kartının tek satırı: katalog sürümü ve özeti, depo motoru, karttaki durum, ürün kodu, seviye 3 ve seviye 4 damgaları, çalışma kipi, güvenlik bayrağı |
IVD$V_ATTRIBUTES ile öteki görünümlerin farkı önemlidir: bir öznitelik birden çok satır taşıyabilir
(her birinin kendi koşulu vardır, FILTER_TEXT). Öteki görünümlerin öznitelik kolonları yalnız
koşulsuz taban satırı verir; koşullu değerlendirme için IVD$V_ATTRIBUTES okunur ya da
METADATA.ATTRIBUTE(nesne, ad) USING (…) çağrılır (en özgül eşleşen koşul kazanır).
Depoda da vardırlar. EXECUTION STORAGE kipindeki bir Firebird ya da PostgreSQL
veritabanında motor bu görünümleri depoya da kurar ve PUBLIC'e SELECT hakkı verir; depoya
doğrudan bağlanan bir okuyucu (Netsim.WEB, ajanın /crud/METADATA?source=ivd ucu, MCP ivd__
araçları) onları sıradan görünüm gibi sorgular. Katalog kurulurken ve her ALTER DATABASE … UPGRADE /
UPGRADE LEVEL sonunda yenilenirler (rapor satırı CATALOG VIEWS). Böyle bir veritabanında motor da
bu görünümleri depodaki kopyalarından okur: sorgunun koşulu ve okuduğu kolonlar depoya gider. Görünümler yalnız depoda
olan bilgiyi gösterir; IVD$V_DATABASE.STATE karttaki durumdur. Veritabanının canlı durumu (yükseltme bekleyen
katalogda UPGRADING) ve yükseltme nedeni IVD_DATABASE_STATE(guid) /
IVD_UPGRADE_REASON(guid) işlevleriyle okunur:
SELECT IVD_DATABASE_STATE(ivd$database_guid), IVD_UPGRADE_REASON(ivd$database_guid)
FROM sys.ivd$database;Kart katalog biçim sürümünü (ivd$catalog_version; değeri 23) ve meta betiklerinin özetini
(ivd$catalog_hash) taşır. OPEN DATABASE kartı kullanıcı nesnelerini yüklemeden önce
okur. Kart yoksa ("damgasız" katalog), sürüm ya da özet motorunkinden farklıysa ya da önceki yükseltme yarım
kaldıysa veritabanı "yükseltme bekliyor" durumunda açılır: kullanıcı nesneleri yüklenmez, yalnız SYSDBA
açabilir, bir uyarı verilir ve orada yalnız yükseltme komutu çalışır. Daha yeni bir sürüm ve yarım kalmış yaratılış
reddedilir.
OPEN DATABASE eski_db STORAGE ENGINE sqlite PARAMETERS 'Database Name=eski.db';
SET CATALOG eski_db;
ALTER DATABASE eski_db UPGRADE PREVIEW; -- ne yapılacağını listeler, yazmaz
ALTER DATABASE eski_db UPGRADE BACKUP TO 'eski.bak.db'; -- önce yedek, sonra yükseltme
-- kısayol: OPEN DATABASE ... UPGRADEİkisi de OBJECT_NAME, OBJECT_KIND, ACTION, DETAIL kolonlu bir sonuç kümesi döndürür; güncel bir
katalogda küme boştur. Yükseltme:
IVD$ tablosu düşürülür (katalogda kullanıcı tablosu
olarak kayıtlı olan hariç). Kimlik dizileri kurulur ya da en büyük kimliğin üstüne çekilir.IVD$SOURCE'tan derlenir, olmazsa IVD$VALID = 'N' olur. Yüklenen kullanıcı nesnelerine
dokunulmaz.Yükseltme veritabanını tek başına ister: başka bir bağlantı o veritabanındaysa reddedilir. Yükseltme bir
işlem değildir (Firebird'ün DDL'i işlemsel değildir); yarıda kalırsa kart UPGRADING kalır ve komut
yeniden çalıştırılır. Sınama modülü: sqltest/ddl/test28-open_database.sql.
BACKUP TO '<yol>' yedeği yükseltmeden önce alır; yedek alınamazsa yükseltme hiç
başlamaz. Depoya göre: sqlite VACUUM INTO (dosya ajanın makinesinde); Firebird sunucunun Services
API'si ile gbak (yedek sunucunun dosya sisteminde yazılır, uzak sunucuda da çalışır,
araç yolu gerekmez; gbak'ın satırları DEBUG1 günlüğüne düşer); PostgreSQL pg_dump -Fc (dosya ajanın
makinesinde; pg_dump conf backupTools.pgBinDir'den, yoksa libpq'nun dizininden,
Windows'ta PostgreSQL kurulum kaydından, en son PATH'ten bulunur; parola komut satırına değil ortama gider).
Var olan dosya her depoda reddedilir; bellek, EMR ve ODBC motorlarında seçenek desteklenmez. Sınama modülü:
sqltest/ddl/test43-backup.sql.
ALTER DATABASE urun_db UPGRADE BACKUP CYCLE;
ALTER DATABASE urun_db UPGRADE LEVEL 3 FROM 'urun.xnsdbs' CONFIRMED TERMINATE SESSIONS BACKUP CYCLE;
ALTER DATABASE urun_db BACKUP CYCLE STATUS; -- yarım kalan döngünün durumu
ALTER DATABASE urun_db BACKUP CYCLE CONTINUE; -- kaldığı adımdan sürdür
ALTER DATABASE urun_db BACKUP CYCLE ROLLBACK; -- döngü öncesi hâle dön
BACKUP CYCLE yükseltmeyi veritabanının kopyasında yapar (PREVIEW ile yazılmaz):
1) önceki urun_db_yedek1 ve artık urun_db_yedek0 silinir — yalnız urun_db
varken; 2) oturumlar kapatılır (IVEDI oturumlarına 10 saniye, depo oturumları sonlandırılır) ve veritabanı MASTER
kaydı korunarak ayrılır — depodaki öteki bağlantılar, başka bir ajanınkiler dahil, kapatılır; yalnız bu ajanın kendi
süreçleri boşaltmayla bırakılır; 3) urun_db urun_db_yedek1 adını alır (dosya yine de açık kalıp
adlandırma düşerse döngü kendiliğinden geri alınır, hiçbir şey değişmez); 4) ondan
urun_db_yedek0 kopyası üretilir; 5) kayıt kopyayı gösterir ve yükseltme kopyada koşar; 6) başarılıysa
kopya, başarısızsa urun_db_yedek1 yeniden urun_db olur. Depoya göre: sqlite ve Firebird
ajanın makinesindeki dosya üzerinde (uzak Firebird sunucusunda döngü reddedilir), PostgreSQL sunucuda
(ALTER DATABASE … RENAME, CREATE DATABASE … TEMPLATE; sahip, haklar ve veritabanı
düzeyindeki ayarlar kopyaya taşınır).
Adım, koşan süreç, son bilgi ve sonuç MASTER'daki kaydın BACKUP CYCLE … özniteliklerinde tutulur;
STATUS bunları STEP, RUNNING (Y = döngü bir süreçte koşuyor),
INFO, RESULT, LAST satırlarıyla verir. Bağlantı koparsa koşu sürer; süreç
çökerse ya da durdurulursa CONTINUE kaldığı adımdan sürdürür, ROLLBACK önceki hâli
(urun_db_yedek1) geri koyar. Üç komut da MASTER'dan (her güncel veritabanından) çalışır; döngü yarımken
veritabanı yalnız döngünün kendisi için açılır, öteki açılışlar reddedilir. Döngü yarımken yeni döngü başlatılamaz.