Tem.20

HTML5 API’leri ile Çalışmak – Ders 13 : IndexedDB API ve Dexie.JS – PART 2

Web SQL konusunu işlerken fonksiyonel bir not defteri oluşturmuştuk. O not defterinin arayüzünü kullanarak, yani HTML ve Bootstrap yapısını hazır olarak kullanarak aynı örneği IndexedDB 2 ve Dexie.js kütüphanesini kullanarak yeniden yapalım. (Bir önceki makaleyi ve Web SQL makalesini inceleyin…)

HTML sayfamızda sadece ek olarak Dexie.js kütüphanesini ekliyoruz.

<script src="https://unpkg.com/dexie@latest/dist/dexie.js"></script>

script.js dosyamızı ise sıfırdan yazmaya başlayabiliriz.

$(document).ready(function(){
    // IndexedDB VERİTABANI OLUŞTURULUYOR
    if (window.indexedDB || window.window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB){
        console.log("IndexedDB destekliyor.")
        var veritabani = new Dexie("not_defteri");
        veritabani.version(1).stores({
            notlar: "++id,baslik,metin,tarih"
        })
        veritabani.open().then(function(){
           console.log("Veritabanı açıldı.")
           kayitlariOku();
        }).catch (function (hata) {
           console.error('Veritabanı açılamadı: ' + hata);
        });
    }else{
        alert("Maalesef tarayıcınızda IndexedDB desteği bulunmamaktadır.")
    }

    // TABLO SİL BUTONUNA TIKLANINCA TABLOYU TEMİZLE
    $("#tabloTemizle").click(function(){
        veritabani.notlar.clear().then(function(){
           console.log("Tablo temizlendi.");
           $("#tablo").empty();
        }).catch (function(hata){
           console.log("Tablo temizlenemedi.");
        });
    });

    // KAYDET BUTONUNA TIKLANINCA YENİ BİR KAYIT GİRİLİYOR
    $("#notKaydet").click(function(){
        var _baslik = $("#notBasligi").val();
        var _metin = $("#notMetini").val();
        var _tarih = new Date().getTime();
        // EĞER İKİ DEĞER DE GİRİLMİŞSE...
        if(_baslik && _metin){
            veritabani.notlar.put({
                baslik:_baslik,
                metin:_metin,
                tarih:_tarih
            }).then(function(){
                // VERİLER TEKRAR OKUNUYOR VE TABLO GÜNCELLENİYOR
                console.log("Kayıt girildi.");
                $("#notBasligi").val("");
                $("#notMetini").val("");
                kayitlariOku();
            }).catch(function(hata) {
               console.log("Kayıt eklenemedi: " + hata);
            });
        }
    });

    // KAYITLARI OKUYAN VE TABLOYU OLUŞTURAN FONKSİYON
    function kayitlariOku(){
        $("#tablo").empty();
        veritabani.notlar.orderBy("tarih").reverse().each(function(kayit){
            $("#tablo").append(
                "<tr>" +
                     "<td>"+kayit.id+"</td>"+
                     "<td><input type='text' id='baslik"+kayit.id+"' value='"+kayit.baslik+"' /></td>"+
                     "<td><textarea id='metin"+kayit.id+"' >"+kayit.metin+"</textarea></td>"+
                     "<td>"+ new Date(kayit.tarih).toLocaleString()+"</td>"+
                     "<td><button type='button' data-index='"+kayit.id+"' class='guncelle btn btn-light'>Güncelle</button>&nbsp&nbsp<button type='button' data-index='"+kayit.id+"' class='sil btn btn-light' >Sil</button></td>"+
                "</tr>");
        });
    }

    /* GÜNCELLE BUTONU DİNAMİK OLUŞTURULDUĞU İÇİN FARKLI BİR METOT İLE TRIGGER EDİYORUZ */
    /* CLASS İSMİ guncelle OLAN BUTONA TIKLANDIĞINDA KAYDI GÜNCELLİYORUZ */
    $(document).on('click','.guncelle',function(){
        var _index = Number($(this).attr('data-index'));
        var _baslik = $("#baslik"+_index).val();
        var _metin = $("#metin"+_index).val();
        if(_baslik && _metin){
            veritabani.notlar.update(_index, {
                baslik: _baslik,
                metin: _metin
            })
            .then(function () {
                console.log(_index + " id'li kayıt güncellendi.");
                kayitlariOku();
            });
        }
    });

    // CLASS İSMİ sil OLAN BUTONA TIKLANDIĞINDA KAYDI SİLİYORUZ
    $(document).on('click','.sil',function(){
        var _index = Number($(this).attr('data-index'));
        veritabani.notlar.where('id').equals(_index).delete()
        .then(function () {
            console.log(_index + " id'li kayıt silindi.");
            kayitlariOku();
        });
    });
});

Öncelikle kodlar arasında yer alan açıklama satırlarına ve console.log()’larına bakıp yorum getirmeye çalışın.

Kodlarımızı kısaca inceleyelim…

İlk olarak tarayıcının IndexedDB destekleyip desteklemediğine bir if koşulu ile bakıyoruz. Eğer destekliyorsa not_defteri isminde bir IndexedDB oluşturuyoruz ve bir değişken olarak veritabani’na atıyoruz, artık not_defteri isimli veritabanımıza veritabani ismi ile ulaşacağız. Bu veritabanında da notlar isminde bir tablo oluşturuyoruz. notlar tablosunda da 4 adet key tanımlıyoruz. Bunlar; ++id, baslik, metin ve tarih. Dikkatinizi çekmiş olabilir, id’yi tanımlarken başına ++ işaretleri koyduk. Bunun anlamı, bu key’in primary key olarak tanımlanmasıdır. Yani Dexie bizim yerimize id’yi primary key olarak tanımlayacak. Veritabanını tanımladıktan sonra da .open() metodu ile veritabanına bağlantı kuruyoruz. Bağlantı kurarken de .then() ve .catch() yapıları ile durum kontrolü yapıyoruz. Her işlemimizde bunu yapmakta fayda var, böylelikle işleminiz başarılı mı oldu başarısız mı oldu bilirseniz, ona göre programın akışına yön verebilirsiniz. Eğer .then()’e girerse, yani veritabanıyla başarılı bir şekilde bağlantı kurulursa hemen kayıtları okumamız gerekiyor. Şimdi ilk defa kayıt açıyoruz, ancak programı bir sonraki açışımızda eğer daha öncesinden kayıt girmişsek, veritabanına bağlandığımızda otomatik olarak kayıtları çekip göstermemiz gerekiyor. Kayıtları çeken fonksiyonumuz da kayitlariOku fonksiyonudur.

kayitlariOku fonksiyonuna bakacak olursak, ilk olarak jQuery ile tabloyu sıfırlıyoruz. Sebebi de, eğer bir kayıt silinirse tabloyu yeniden güncellemek gerekecek. Eğer tabloyu sıfırlamazsak, yeni okunan değerler de tabloya eski verilerle birlikte eklenecektir, bunun önüne geçmek için tablo sıfırlanmalıdır. Ardından Dexie’nin veri okuma metodunu kullanıyoruz. Bu metotta .orderBy() ile tarih parametresini kullanarak tarihe göre verileri sıralayarak çekmesini istiyoruz. Ardından .reverse() metodunu ekliyoruz. Böylece son eklenen en başta gösterilecek. Onun da peşine .each() metodunu ekliyoruz. Bu metot, isminden de anlaşılacağı üzere for each döngüsü gibi davranacak. Parametre olarak bir fonksiyon, fonksiyon da her bir kaydı parametre olarak alıyor. Alacağı parametreye kayit ismini verdik. Yani döngü boyunca her bir satır kayıt, JSON olarak kayit değişkeni ile fonksiyona atanacak. Fonksiyon içinde de kayit.id, kayit.baslik, kayit.metin ve kayit.tarih ile değerlere erişiyoruz. Eriştiğimiz değerleri de jQuery kullanarak bir döngü ile tablo içine ekliyoruz (Web SQL konusunda detaylıca anlatılmıştı).

Kayıt eklerken jQuery ile metin kutularından değerleri id isimlerine göre alıp _baslik ve _metin değişkenlerine atıyoruz. Ek olarak kendimiz de _tarih değişkeni tanımlayıp o anki zaman milisaniye cinsinden elde ediyoruz. Verilerimizi eklerken ilk olarak veritabanı ve tabloyu tanımlayıp, sonra da Dexie’nin .put() metodunu kullanarak JSON formatını tanımlayıp veritabanına ekliyoruz. Dikkat edin, id key’ini tanımlamadık ve bir değer girmedik. Çünkü id key’i primary key olduğu için otomatik olarak her kayıtta kendisi 1 artacaktır. Ekleme işlemi başarılı olunca form’daki input’ların içeriklerini sıfırlıyor ve kayıtları tekrar kayitlariOku fonksiyonu ile çağırıyoruz. Eğer kayıt ekleme sırasında bir hata olursa da konsolda gösteriyoruz.

Listede var olan bir kaydı güncellerken de o kaydın id’sinden faydalanarak veritabanında hangi satırda olduğunu tespit ediyoruz. Dexie’nin .update() metodu 2 parametre alır. Birinci parametre nümerik olarak id değeridir (veya başka bir key’i belirttiyseniz onun veri tipi olur). Bizim primary key’imiz nümerik olduğu için jQuery ile aldığımız index değerini Number() ile nümerik değere çeviriyoruz, aksi halde string olarak algılayacak ve sorgu çalışmayacak. .update() metodunun ilk parametresi _index oluyor. İkinci parametresi de bu index’te yer alan hangi key’lere hangi value’ların atanacağını belirten Object’tir. Kayıt başarılı olunca tekrar kayitlariOku fonksiyonu ile güncel veriyi tabloya çekiyoruz.

Var olan bir kaydı silerken de yine index numarasından faydalanıyoruz. Bu sefer de yine index değerini jQuery ile aldıktan sonra Number() ile nümerik değişkene çeviriyoruz. Silme işlemini yaparken de zincirleme metot kullanıyoruz. İlk olarak .where() metoduna hangi key’e göre arama yapılacağı tanımlanıyor. İkinci metot ise equal(), yani eşit anlamını vererek parametre olarak da index numaramızı veriyoruz ( .equal() dışında çok fazla karşılaştırma metodu bulunmaktadır, Dexie’nin referanslarını inceleyebilirsiniz) . Yani sorgumuzda id key’inde index numaramıza eşit olanı bul diyoruz. Son olarak da .delete() metodunu uyguluyoruz. Silme başarılı olunca tekrar tabloyu yeniliyoruz.

Son olarak tabloyu temizlemek için de Dexie’nin .clear() metodundan faydalanıyoruz.

Web SQL ve IndexedDB örneklerini karşılaştırın ve projenizde ihtiyacınız olan en doğru API’yi seçerek projelerinizi yapılandırın. Eğer çok fazla veritabanı manipülasyonu yapacaksanız SQL sorgularına ihtiyacınız olacaktır ve Web SQL daha avantajlıdır. Ancak çok fazla manipülasyon yoksa ve veri okuma yazma hızı lazımsa (çok fazla veri düşünüldüğünde) IndexedDB daha avantajlı olacaktır.

İçeriği paylaş:
  • facebook
  • twitter

Leave a comment

Yorum