Computer

Select, Group By, Having

Merhabalar,

Bu yazı, bir Önceki SQL nedir, ne değildir ? adlı yazının devamı şeklinde olacak ve ‘Group By’ ve ‘Having’ ile SELECT sonuçu olarak dÖnen liste üzerinde yapılan işlemlere değineceğiz.

Geçen yazımızdan hatırlayacağınız gibi, SELECT cümlesi geriye bir liste dÖnen bir ve üç ana parçaya ayırabileceğimiz bir komut idi. Bu ana parçalardan kısaca bahsedecek olursak;
– süzme işlemi (WHERE alt cümlesi ile yapılabilen)
– sıralama işlemi (ORDER BY alt cümlesi ile yapılabilen)
– geri dÖnen liste üzerinde yapılan işlemler (GROUP BY, HAVING, MAX, SUM, COUNT, MIN….vs.)

Peki SELECT cümlesinde gerçekleşen olayları biraz daha derinden inceleyelim, bu şekilde GROUP BY ve diğer işlemlerin anlaşılmasını kolaylaştırmaya çalışalım.

SELECT Price
  FROM Customer
 WHERE Price < 100
   AND Price > 50

Bu SQL cümlesinden geriye bir liste gelir, buraya kadar herşey çok normal ve oldukça basit. Ama biz biraz daha analitik bir liste istersek ki iş dünyasında bu çeşit listelere oldukça fazla başvuruluyor.

  SELECT Count(*), Price
    FROM Customer
   WHERE Price < 100
     AND Price > 50
GROUP BY Price

Yukarıdaki cümlede durum biraz karışık ama inanın gÖründüğü kadar değil, şÖyleki; Bu SELECT cümlesi bir üstte belirtiğimiz SELECT cümlesi ile aynı listeyi oluşturur ama son yazılan SELECT cümlesine ‘Count(*)’ ve ‘GRUOP BY’ gibi SELECT’den dÖnen listeyi değiştiren alt cümleleri eklenmiştir. Biz standart listeleme işleminden dÖnen (yani Price bilgisi 100 ile 50 arasında olan Customer listesine) listeye düşük seviyeli liste diyelim. Bu düşük seviyeli listenin üzerine GRUOP BY ve COUNT işlemleri uygulandıktan sonra ortaya çıkan yeni listeye ise sonuç listesi adını verelim.

Veri tabanı uygulamaları, işte bu mantık doğrultusunda Öncelikle düşük seviyeli listeleri oluşturur ve bu düşük seviyeli listeler üzerine yapılan işlemlerle sonuç listesini meydana getirirler. Bu bilgiler ışığında GROUP BY alt cümlesinin tanımı şu şekilde olabilir;
– Cümleden sonra parametre olarak belirtilen alanın veya alanların değerine gÖre düşük seviyeli listeyi parçalara ayırır, belirtilen alanın veya alanların kaç farklı değeri var ise o kadar düşük seviyeli liste oluşturur.

Bu tanım biraz daha aklınıza yattı değil mi.. ?

Peki şimdi bir de COUNT(*), MIN, MAX, AVERAGE gibi fonksiyonların nasıl çalıştıklarını anlatmaya çalışalım;
– Tüm bu fonksiyonlar, düşük seviyeli listenin tamamı üzerine çalışır. Eğer düşük seviyeli liste GRUOP BY ile bÖlünmüş ise, her bir parça için ayrı ayrı çalışırlar.

Yani son SQL cümlesinde yer alan Count(*) işlemi her Price değeri için bÖlünmüş olan düşük seviyeli listenin herbir parçası için çalışır. Ve ortaya sonuç listesi olarak, her parçanın içerisinde yer alan kayıt sayısı ve her parçanın ayıraçı konumundaki Price bilgisi çıkar. Örnek;

Count(*) - Price
    5            60
    7            70
... vb.

Peki biz şu şekilde bir SQL cümlesi yazacak olursak;

  SELECT Count(*), Price, Name
    FROM Customer
   WHERE Price < 100
     AND Price > 50
GROUP BY Price

Veri tabanı bize hata verecektir. Hemen aklınızdan ‘Kardeşimmmm bu ne hatası bÖyleee…. eee Customer üzerinde Name var.. neden gÖrmez bunu bu salak..’ vb. düşünceler geçebilir. Aman geçmesin çünkü veri tabanı manyağı haklı. Peki neden haklı onu inceleyelim;

Şimdi Öncelikle düşük seviyeli listenin ne olduğunu bulalım;
– Price bilgisi 100 ile 50 arasında olan Customer bilgileri.. Id, Price, Name…vs.. vs.. Bu listeye ‘A’ listesi diyelim.

‘GRUOP BY’ işlemi olduğuna gÖre, elimizdeki düşük seviyeli ‘A’ listesi Price bilgisinin değerlerine gÖre bÖlümlere ayrılmıştır. Örnek olarak Price bilgisi 5 farklı değere sahip olsun elimizdeki ‘A’ listesi ‘A1, A2, A3, A4, A5’ şeklinde küçük listelere ayrılır.

Daha sonra COUNT(*) işlemi ile bu her bir küçük listenin adet bilgisi ile Price ve Name bilgisi sonuç listesine verilmiştir. Peki burada ki gariplik ne, neden hata veriyor. Sorun şu A listesinden A1’e geçiş sırasında her bir Price’a karşılık ‘n’ adet Name bilgisi oluşmuştur bu nedenle sonuç listesi oluşturulurken, Count bilgisi hesaplanmış, Price bilgisi tek olduğu için alınmış fakat hangi Name bilgisinin kullanılacağına karar verilememiştir.

Düşük Seviyeli Liste’nin son hali..

Id Price Name
1 60 Test60-1
2 60 Test60-2
3 70 Test70-1
4 70 Test70-2
5 80 Test80-1
6 90 Test90-1

‘Group By’ uygulandıktan sonraki düşük seviyeli listenin hali;

Price Alt Kümeler
60
Id Name
1 Test60-1
2 Test60-2
70
Id Name
1 Test70-1
2 Test70-2
80
Id Name
1 Test80-1
90
Id Name
1 Test90-1

İşte bu da son ipucu; SQL programlama dilinde herhangi bir liste oluşturabilmek için bir kademe altta yer alan listenin elemanları direkt olarak kullanılabilir ya da fonksiyonlar yardımı ile alt listelere ulaşılıp, toplam, en küçük, en büyük, ortalama.. vb. değerler elde edilebilir.

Kolay gelsin.

SQL nedir, ne değildir ?

Merhabalar arkadaşlar,

“Uzun bir aradan sonra tekrar birlikteyiz ben …” şeklinde bir cümle kurmayacağım, ben de biliyorum bu aralar tembelleştim, Önceden ne güzeldi sık sık ve güzel güzel yazıyordum ama ya şimdi aradan aylar geçmesi gerekiyor, elime kalem alabilmem için :P (Duyan da gerçek yazar zannedecek :) ) Neyse bugün ki konumuz “SQL nedir, ne değildir ?”

Şimdi aklınızda şÖyle bir soru olabilir “beee adam canın mı sıkıldı oturuyorsun SQL hakkında yazı yazıyorsun ?”. Olabilir diyorum ya olabilir, illa olacak diye bir kaide yok. Ben size genede nedenini sÖyleyeyim, memleketimin yazılımcılarının SQL ile arasının pek olmaması nedeni ile bu yazıyı yazıyorum. Açıklayıcı olması için ve gerçek Örneklerle bu yazıyı yazmaya çalışacağım, gariplikler gÖrürseniz şaşırmayın.

Öncelikle bu SQL ne değildir ? sorusuna cevap arayalım. SQL programlama dili animasyon yapımında, gelişkin matematiksel işlemlerde veya işletim sistemi yazımında kullanılmaz, kullanan var ise hemen anlından Öpeyim bitsin bu çile.

Peki nedir bu SQL ? diye soracak olursanız;
– Sadece veriler üzerinde işlem yapmak için tasarlanmıştır. Bu nedenle basit anlamda 4 adet işlemden oluşur. Bu işlemler listeleme, güncelleme, ekleme ve silmedir. (SELECT, UPDATE, INSERT, DELETE)
– Kendi kendine herhangi bir şekilde çalışamaz, veri tabanı uygulamaları tarafından veriler üzerinde işlemler yapabilmek için kullanılırlar. (Maalesef tüm veri tabanı uygulamaları üç aşağı beş yukarı, ufak da olsa bir takım farklılıklarla SQL dilini destekler.)
– Sonuç olarak, SQL programlama dili veri tabanı uygulamaları tarafından derlenen ve çalıştırılan (bu nedenle veri tabanı uygulamasına gÖre çalışması değişebilen), sadece verilere hükmetmek için kullanılan, evrensel bir programlama dilidir.

http://en.wikipedia.org/wiki/SQL adresinden daha fazla bilgiye ulaşabilirsiniz. Hemen belirtmem gereki ki; SQL programlama dilinin versiyonları vardır, veri tabanı uygulamaları hangi SQL versiyonuna destek verdiklerini belirtirler. Bu versiyonları tarif etmek gerekir ise;
SQL-86: Bildiğimiz standart SQL cümlelerinden oluşur, herhangi bir ek yoktur. Kısaca tüm dünyanın ~%95’i sadece bu kadarlık kısmını kullanılır.
SQL-1999: Bildiğimiz SQL cümlelerinin üzerine birçok yeni Özellik eklenmiştir ki saymakla bitmez, kısaca SQL programlama dilinin programlama dili olduğu versiyon bu versiyondur.
SQL-2003: Tüm bu Özelliklere XML ile çalışabilme Özelliği eklenmiş ve ortaya bu versiyon çıkmıştır.
SQL-2006: Artık bu versiyonda XML entegrasyonu konusunda ‘Yok artık lÖbran ceyms’ konumuna ulaşmış ve XQuery (XML Query Language)’de desteklemeye başlanmıştır.

Sizleri çok endişelendirmeden hemen konumuza girelim; Biz bu yazımızda sadece; SQL-86’yı inceleyeceğiz. İşe sizlere küçük bir ipucu vermek ile başlayacağız, (bu belirteceğim ipucu SELECT cümlesi içerisinde listeme sırasında veri üzerinde herhangi bir değişikliğin yapılmadığı durumlarda geçerlidir) aslında ‘INSERT’ hariç tüm cümleler bir çeşit ‘SELECT’ cümlesidir tek bir farkla ‘UPDATE’ kayıtları ekrana yazmak yerine güncellerken, ‘DELETE’ ise kayıtları siler. INSERT’in durumu ise, çok vahimdir işi gücü belirtilen tek kaydı veya SELECT cümlesi ile bulunmuş bir kümeyi tabloya eklemektir.

Örnek vermek gerekir ise;

SELECT *
   FROM Customer
-- OR
DELETE *
   FROM Customer
-- OR
UPDATE Customer
     SET Name = 'Hebele'
-- Farklı olan INSERT
 INSERT 
    INTO Customer (Name) 
VALUES ('Hebele2')

Yukarıda belirtiğim gibi aslında sizler SELECT cümlesini Öğrendiğinizde geri kalan tüm işlemleri aşağı yukarı Öğrenmiş olursunuz. Şimdi bu nedenle bizler SQL programlama dilinin en Önemli Özelliği olan SELECT cümlesi üzerine yoğunlaşacağız.
Hemen ikinci ipucunu verelim; SELECT cümleleri içerisinde yer alan komutlar üçe ayrılır. Bunlardan birincisi verileri süzme işlemidir bu işlem WHERE alt cümlesi ile yapılır, başka bir komut ile süzme işlemi yapılmaz. İkinci komut sıralama işlemidir, sadece ‘ORDER BY’ alt cümlesi ile yapılır. İşte işin zor kısmı listeme sırasında yapılacak işlemler için ise ‘GROUP BY, HAVING, ROWNUM, LIMIT, TOP, COUNT, MAX, MIN, AVARAGE……’ ve daha zilyon tane alt cümle kullanılabilir, tüm bunların hepsi yani WHERE ve ORDER BY haricindekiler, oluşan liste üzerinde değişiklik yapar veya liste üzerinden farklı listeler, farklı veriler elde etmeye yararlar.

Örnek vermek gerekir ise; Yeri gelmişken SQL cümleleri nasıl okunmalıdır, bunun da Örneğini yapalım.

SELECT Name, Price -- Name ve Price alanlarını gÖster
  FROM Customer -- Customer'ın
WHERE Price < 100 -- Price'ı 100'den küçük olanların
ORDER BY Price DESC -- Price bilgisi büyükten küçüğe doğru sıralanmış olsun.
-- Peki biz 100'un altında kaç tane kayıt olduğunu Öğrenmek istersek
SELECT COUNT(*)
  FROM Customer
WHERE Price < 100
-- Peki biz 100'ün altında yer alan fiyatlardan hangisinden kaç tane bulunduğunu Öğrenmek istersek;
SELECT Count(*), Price
  FROM Customer
WHERE Price < 100
GROUP BY Price

Bir sonraki yazımızda SELECT konusuna daha fazla değineceğiz.

Kolay gelsin.

Ruby Değişken Özellikleri

Merhabalar,

Öncelikle bu kadar uzun bir süre yazı yazmak ilginç oluyor. Bir aydan fazla bir süredir, nokta koymadığım bu günlüğe birşeyler yazmak biraz yabancı geldi açıkcası.

Bu yazıyı yazmam için beni birazcıkta olsa gaza getiren sevgili Mehmet DURAN kardeşime buradan teşekkür etmek isterim.. şak şakk şakk şakk.. javaayyyyy diyorum sana Mehmet.. :)

Öncelikle bu yazıdaki konumuzu belirteyim; Ruby programlama dilinde değişkenlerin nasıl tanımlandığı ve değişkenler üzerinde tip dÖnüşümlerinin nasıl olduğu.

Ruby’de değişkenler tanımlanırken herhangi bir şekilde tip belirtmenize gerek yoktur. İsterseniz Java veya C#’da yaptığınız gibi yapabilirsiniz ama o zaman biraz ayıp olur.. yuhananırsınız.. ohaa artık diyenler olabilir. ŞÖyledir yani;

intValue = 5
strValue = 'Hobaaa'
arrValue = []
hashValue = {}
regValue = \.*\
classValue = MyClass.new

Öncelikle programlama dillerinde değişken tiplerinin dÖnüşümü ve bu tiplerin ele alınmasını iki soru altında toplanabiliriz; Bu sorular
1. Tipler arasındaki dÖnüşüm nasıl gerçekleşir?
2. Değişken üzerinde işlem yaparken tip Önemlimidir?

Öncelikle 1. soruyu ele alalım; “1. Tipler arasındaki dÖnüşüm nasıl gerçekleşir?”
El cevap: Eğer değişkeninizi bir tipten Öteki tipe hÖdÖÖ hÖdÖÖ diye gÖnderiyorsanız, kullandığınız dil dinamik tip dÖnüşümüne sahiptir demektir. Eğer hÖdÖ hÖdÖÖ diye değil de, daha efendi bir şekilde (Örnek: ‘String.valueOf(55)’) yapıyorsanız durağan tip dÖnüşümüne sahipsiniz demektir. Değişkenlerinizi bir tipten Öteki tipe değiştiremiyorsanız, ohaaa sizin o kullandığınız şey programa dili değil çin işkencesi demektir.

Programlama dillerine gÖre dinamik ve durağan tip dÖnüşümüne sahip olan diller;
Dinamik: Ruby, Python..vb.
Durağan: Java(yyyy), C#….vb.

İkinci soruyu ele alırsak; “2. Değişken üzerinde işlem yaparken tip Önemlimidir?”
El cevap: Eğer siz bir karakter ile sayiyi toplamak isterseniz veya benim bir değerim var ama inan ben bile bilmiyorum ne olduğunu Öyle yanar dÖnerli birşey işte.. (Basic’den Variant, C’den void) diyebiliyor iseniz, sizin için değişkenin tipi pekde Önemli değildir. Yani değişkenler ile değişken tipleri arasındaki bağlantı ‘zayıf’tır. Her değişkenin veya her işlemin tipi olmasına gerek yoktur, diyebilirsiniz. Ama dersenizki ‘hadeee canım, tipsiz tipsiz değişkenmi olur, tipli adamın tipsiz değişkeni olmaz’ derseniz, tüm değişkenleriniz ile değişken tipleri arasında ‘güçlü’ bir bağlantınız var demektir.

Güçlü: Ruby, Java(yyyy), C#, C++…vb.
Zayıf: C, Basic, Java(yyy)Script….vb.

Peki Ruby’de bunlar nasıl oluyor da oluryor diyeceksiniz şimdi; İşte bÖyle oluyor..;

intValue = 5
puts 5 + intValue # problem yok.
puts "5" + intValue # büüürrrstt nereye biraderr..
puts "5" * "5" # bürrsttt yok daha neler..
# bir string(a) ile numarayı(b) çarptığınızda, ruby sizin a'yi b kez tekrarlamak istediğinizi zanneder.
puts "5" * intValue # Olur, bunun ruby'de karşılığı vardır.

Kolay gelsin..!

JRuby 1.0 RC3

Merhabalar arkadaşlar,

Küçük bir yazı olacak, sadece sizlere JRuby’nin 1.0 Release Candidate 3 sürümünü duyurmak için bu yazıyı yazıyorum. Evet doğru duydunuz, JRuby takımı Microsoft’tan daha hızlı davranarak (yarış halen bitmedi, gerçi ortada bir yarış var mı onu da bilmiyorum ama :) ) RC3’de olsa 1.0 sürümünü dünyaya *nihayet* duyurdu.

Şimdi aklınızda soru işaretleri olabilir, Hemen sizlere JRuby’nin ne olduğunu anlatmaya çalışayım. Aslında sizler normal Ruby uygulamalarınızı yazıyorsunuz, çalıştırıyorsunuz..vs..vs. Fakat sonra canınız sıkılıyor, neden sıkılıyor bilmiyorum ama birden Ruby’de yazdığınız kodların Ruby’nin doğal ortamında değil de, Java Virtual Machine (JVM) üzerinde çalışmasını istiyorsunuz, nedenleriz şunlar olabilir;
– Performans amaçlı olabilir (bu konu tartışılır)
– Ruby’nin çalışmadığı fakat java’nın çalıştığı bir ortamda çalıştırmak için (Hangi ortam o ?? belki vardır, bilen varsa yazsın…)
– Müşterinizi ‘ben programı Java’da yazdım’ diye kandırmak için :)

galiba en geçerli neden bu sonuncusu :).

Ama sonuçta güzel, hoş ve desteklenmesi gereken bir olay. Ruby dili çok güzel ve akıcı bir yapıya sahip neden JVM’yi kullanmak istiyenler bu güzel dili kullanmaktan mahrum kalsınlar ki.. ciddiyim, espiri falan yapmıyorum, tamamiyle destekliyorum.

Rails kullanıcılarına Önemli bir not, RoR altyapısı tamamiyle Ruby’de yazıldığı için JRuby yoluyla JVM üzerinde de dolayısı ile Java Application Server’lar üzerinde çalışabilir hale gelmiştir. Özellikle sağlam veri tabanı Özelliklerini kullanan uygulamalarda bu sayede hız artışı sağlanabilir. (Henüz 1.0 RC3’ü inceleyemedim ama bazı kısıtlardan bahsediliyor fakat kesin bir şey sÖyleyemiyorum.)

Kolay gelsin…

Ruby ile Struct

Merhaba arkadaşlar,

Bugünkü yazımızda Struct ve OpenStruct yapılarından bahsedeceğiz. “Bu yapılara neden ihtiyacımız var ?”, “Var olan ‘class’ yapısı veya bu işlemlere benzer olan ‘Array’ ve ‘Hash’ yapılarını neden kullanmıyoruz ?”, “Bu kadar fazla Öğrenmemiz gereken sınıf, yapı ve işlev varken neden bir de başımıza bu ikisi çıktı ?”, ve son olarak “Ne işimiz var kardeşim Struct ile falan, bunlar boş iş.. ne yapacan Öğrenip de..!?” gibi soruları cevaplamak gerekir. Ama tüm bu sorulardan Önce ben neden bu yazıyı yazıyorum onu anlatmalıyım sanırım. Bu yazıyı bu linkte yer alan bir yazıyı gÖrdükten sonra yazmaya karar verdim. Bu yazıda blog sahibi arkadaş Ruby on Rails’de ActionMailler kullanımı sırasında kullanmış, çok da güzel kullanmış. Ben de kendi kendime ‘Ben de bunu bizimkilerle paylaşayım’ dedim. İyi ettim di mi ? ettim ettim.. :)

Hatta ve hatta çok da güzel bir snippet’da mevcut. Bir gÖz atmanızı tavsiye ederim.

‘Struct’ ruby içerisinde yer alan ‘Class’ benzeri bir yapı, aslında Class’dan türemiş farklı bir yapı. ŞÖyleki normalde yeni bir ‘class’ yaratmak istediğimiz de

class YeniSinif
attr_reader ...
attr_writer ...
attr_accessor ...

def ...
end

...
end

şeklinde ‘YeniSinif’ı yaratır ve bu sınıftan nesneler üretmeye başlayabiliriz. Struct, sadece veri taşımak için tasarlandığı için şu şekilde bir tanımlamaya ihtiyaç duyar;

# Temel Struct tanımı...
Adres = Struct.new(:posta_kodu, :sehir, :ilce, :semt, :mahalle, :apt_no, :apt_isim, :daire)

anlaşılacağı üzere, herhangi bir şekilde erişim belirleyicisi tanımlanamaz (private, protected, public gibi) tüm üyeler public’dir. Önemle belirtmem gerekirki, bu yeni oluşturduğum ‘Adres’ bir nesne değildir, bir sınıftır yani yeni bir türdür(type). Peki biz neden ruby içerisinde yeni bir tür(type) yaratmak istedik ? Örnekten de anlaşılacağı gibi, normal hayatta adres bilgisinde posta kodu, şehir, ilçe…vb bilgiler birbirlerinden ayrılamazlar ve mantıksal anlamda da bir birliktelikleri vardır. Elbette kullanmazsak programlarımızda çok büyük problemler çıkmaz ama bazı durumlarda bize çok büyük kolaylıklar sağlayabilir; Örnek vermek gerekir ise; Struct kullanmadan adres yapısının kopyalanması;

yeni_posta_kodu = posta_kodu
yeni_sehir = sehir
yeni_ilce = ilce
yeni_semt = semt
...
...

peki Adres diye bir tür kullansaydık ve işlemleri bu tür üzerinden yürütseydik;

yeni_adres = adres.clone # Bu kadar.. :)

şeklinde küçücük bir kod parçası ile bu işlemi yapabilirdik. Peki hemen aklınıza gelebilir, zaten sınıf(class) yapısı mevcut ben struct yerine class kullanamazmıyım ? Elbette kullanabilirsin, class, struct’ın yapabileceği tüm Özelliklere sahip temel ve en genel yapıdır. Struct sadece verileri tutmak için yapılmış ve bu iş üzerine yÖnelmiş class’ın alt sınıfıdır. Yukarıda da bahsettiğim snippet incelenecek olursa, bu konu daha rahat anlaşılır diye tahmin ediyorum.

Peki “Struct sadece verileri tutmak için yapılmış ve bu iş üzerine yÖnelmiş class’ın alt sınıfıdır” dedik, bu veri tutma işinde bizlere hangi Özellikleri vermektedir. Struct, class’lardan farklı olarak bizlere bir Array veya Hash nesnesine erişir gibi içerisinde yer alan Özelliklere erişimimizi sağlayabilir. ŞÖyleki;

adres = Adres.new()
# veya
# adres = Adres.new(34300, "İstanbul", "Fatih", "Cerrahpaşa", "ZZZZ ZZZ ZZZZ ZZ", 1, "Gonca", 18)
adres.posta_kodu = 34300
adres.sehir = "İstanbul"
puts adres[:posta_kodu] # 34300
puts adres["sehir"] # İstanbul
puts adres[1] # İstanbul
puts adres.members # üyelerin isimlerini verir.
puts adres.values # üyelerin değerlerini verir.

adres.each_pair do |key,value| 
	puts key.to_s + ":" + value.to_s
end

Bir sonraki yazımda OpenStruct’u anlatmaya çalışacağım… :)

Kolay gelsin :)

Ruby Yedekleme Sistemi Detayları

Merhabalar arkadaşlar,

Bir Önceki yazımda Ruby ile gerçekleştirdiğim yedekleme sisteminden bahsetmiş ve tanımlarının nasıl yapılması gerektiğini anlatmıştım. Bu yazımda ise kod bloğunu sizlerle paylaşarak bazı ipuçları vermek istiyorum. BÖylece eğer isterseniz, uygulamayı kendinize gÖre değiştirmeniz daha kolay hale gelecektir.

Diğer tüm yazılarımda olduğu gibi hemen konumuza geçelim. Rackup.rb dosyasını parça parça işleyeceğiz.

$stdout.sync = true
require 'yaml'
begin
	require "zip/zip"
rescue Exception => err
	puts "Error: You should execute 'gem install rubyzip --include-dependencies' command, before run this program.."
	puts err.message
	exit
end

Bu bÖlümde, eğer ‘rubyzip’ kütüphanesi yok ise, oluşan hata program tarafından yakalanır ve kullanıcıya sorunu nasıl giderebileceği belirtilir.

begin
	config = YAML::load(IO.read(ARGV[0] || "rackup_config.yaml"))
rescue Exception => err
	puts "Error: Configuration file can not be found.."
	puts err.message
	exit
end

Bu bÖlümde ayar dosyası disk üzerinden okunmaya çalışılır.

IO.read(ARGV[0] || "rackup_config.yaml")

ARGV[0]: Gelen ilk parametre anlamındadır.
Eğer gelen bir parametre var ise onu, eğer gelen herhangi bir parametre yok ise “rackup_config.yaml”yi yani standart ayar dosyasını kullanmasını sÖyler.

source_folder = config["source"]
source_include_sub_folders = (["true", "yes", "evet", "yeah", "y", "e", "1"].include?(config["include_subfolders"].to_s) ? true : false)
source_file_extension = config["file_extension"] || "*"

target_folder = config["target"]
target_prefix = config["prefix"]
target_postfix = config["postfix"]

bu bÖlümde ise ‘yaml’ içersinden yedekleme işlemi ile ilgili bilgiler okunur.

# Tüm evet anlamına gelen ifadeler kullanılmıştır..
(["true", "yes", "evet", "yeah", "y", "e", "1"].include?(config["include_subfolders"].to_s) ? true : false)

config[“include_subfolders”] bilgisine “true”, “yes”, “evet”, “yeah”, “y”, “e”, “1” bilgilerinden herhangi birinin yazılsının ‘true’ olacağını ifade eder.

source_files = nil
if source_file_extension.include?(",")
	source_files = File.join("**", "*.{#{source_file_extension}}")
else
	source_files = File.join("**", "*.#{source_file_extension}")
end

puts "Source dir is #{source_folder}"
puts "Target dir is #{target_folder}"
puts "File type is #{source_files.to_s}"

if File.directory?(source_folder) == false || File.directory?(target_folder) == false
	puts "Error: Source or target folder can not be found..!"
	exit
end

Bu bÖlümde ise birden fazla dosya uzantısı (file_extension) tanımlandı ise farklı bir takım işlemler yapar. Hedef ve kaynak dizin ile dosya uzantılarını ekrana yazar. Hedef ve kaynak dizinlerin varlığını kontrol eder.
Continue reading…

Ruby Backup (Rackup)

Merhaba arkadaşlar,

Bu yazımda daha Önceden de bahsetmiş olduğum ve son iki yazımda da alt yapısını oluşturduğum Ruby Backup (Rackup) uygulamasını sizlere tanıtacağım.

Öncelikle belirtmem gerekir ki; Bu uygulamayı ben kendim için geliştirdim, nedenlerini anlatayım;
– Paranoyaklığımdan Ötürü (ve elbetteki kodları kaybetmenin mazereti olmayacağını bildiğim için) kullandığım versiyon kontrol yazılımının yetmeyeceğini, birgün bana inat çok Önemli bir dÖnemde çÖkebileceğini düşünerek yazdığım programların kopyasını almaya başladım.
– Diğer neden ise tembelim.. evet evet tembelim, her seferinde klasÖrleri tek tek seçip sıkıştır daha sonra sıkıştırma işlemi ile oluşturduğun dosyayı nispeten daha güvenli olduğuna inandığım bir aygıta kopyalamak yerine… :) oturdum bu işleri benim yerime yapacak Rackup uygulamasını geliştirdim. İyi de ettim diye düşünüyorum. Hatta iş arkadaşlarım kullanmaya başladılar bile. Elbette onlar için de birkaç geliştirme yapmak ve hata düzeltmek zorunda kaldım. ‘Bırak olduğu gibi kalsın kardeşim ne hatası ne düzeltmesi’ diyecek oldum.. ama diyemedim.. :D siz de demeyin. bulduğunuz hataları bana iletin.. ben de sizlere peşin peşin teşekkür edeyim :)

Neyse konuyu şimdiden uzattım bile. Hemen Rackup uygulamasının içeriğine başlayalım.
Öncelikle projenin dosyalarına buradan ulaşabilirsiniz.

Programı çalıştırabilmek için bazı işlemleri yerine getirmeniz gerekli, bunlar;

  • Ruby kurulu olmalı, ruby programları çalıştırabiliyor olmalısınız.
  • RubyZip kütüphanesi kurulu olmalı, eğer değil ise, ‘gem install rubyzip –include-dependencies’ ile kurulabilir.
  • rackup_config.yaml dosyasının hazırlanması;
    • source: kaynak dizininin ve dosyaların bilgilerini taşır
    • include_subfolders: Kaynak dizinin yedeklenmesinde alt dizinler de dikkate alınacak mı?
    • file_extension: Kaynak dizinin altında yer alan hangi dosya uzantılı dosyaların yedekleri alınacak. Eğer belirtilmez ise tüm dosyaların yedeği alınır.
    • target: Hedef dizinin bilgilerini ve oluşturulacak dosyanın bilgilerini taşır.
    • prefix: Sıkıştırılarak oluşturulmuş dosyanın Ön ekini belirtir.Oluşturulacak olan dosyanın yapısı [prefix][Tarihsel ayırac][postfix].zip şeklindedir. [Tarihsel ayırac] kısmı değiştirilemez, prefix ve postfix bÖlümleri değiştirilebilir.
    • postfix: Sıkıştırılarak oluşturulmuş dosyanın son ekini belirtir.
    • Tüm Özelliklerin kümesi bir Örnekle example_config_file.yaml’de açıklanmıştır.
  • config dosyasında belirtilen target ve source dizinleri daha Önceden yaratılmalıdır
  • Programın çalıştırılması Rackup.rb’nin çalıştırılması ile gerçekleşir.
  • Rackup.rb çalıştırılırken eğer parametre olarak herhangi bir ‘yaml’ dosyası verilmez ise, aynı dizindeki rackup_config.yaml dosyası config dosyası olarak alınır. Eğer parametre olarak herhangi bir config dosyası verilir ise Örneğin; “Rackup.rb example_config_file.yaml” şeklinde çalıştırılır ise ‘example_config_file.yaml’ içerisinde yer alan ayarlar ise işlemleri gerçekleştirir. BÖylece birden fazla ‘cron’ veya ‘at’ veya ‘schedule job’ tanımlayarak istediğimiz zaman istediğimiz dizindeki, istediğimiz dosyaların yedeklerini alabiliriz.

Bir sonraki yazımda Rackup.rb’yi daha detaylı bir şekilde açıklamaya çalışacağım.

Kolay gelsin :)

Ruby ile konfigürasyon dosyaları (YAML)

Merhabalar arkadaşlar,

Bugünkü yazımızda ‘.yaml’ (YAML A’int Markup Language) uzantılı dosyalar nasıl okunur, nasıl işlenir gibi konuları ele alacağız. Bir Önceki Ruby Zip Kütüphanesi adlı yazıda belirttiğim Ruby Backup (Rackup) uygulaması için gerekli bir konu olduğu için Öncelikle bu konuyu inceleyeceğiz.

Peki YAML dosyalarına neden ihtiyacımız var. XML ile bu işlem yapılamaz mı ? Elbette yapılabilir. Ama Ruby on Rails’de (RoR) veri tabanı bağlantılarını kontrol eden dosya bir yaml dosyası ‘database.yaml‘. Neden ? Cevap; Okunabilirlik.

XML dosyalarına gÖre YAML dosyalarını değiştirmek, bazı durumlarda, çok daha kolay ve hızlı olabiliyor. Elbetteki bunun tersi durumlarda sÖz konusu fakat Önemli olan alternatif olması ve bazı durumlarda da avantajının olduğunun bilincine vararak kullanmak. Özellikle bir sonraki yazımda yazmayı planladığım Ruby Backup projesinde kullanıcıların fazladan herhangi bir bilgiye ihtiyaç duymadan bazı ayarları değiştirmeleri ve/veya eklemeleri gerektiğinde kullanılabilirliği XML’den fazla olduğu bir gerçek. Neyse lafı fazla uzatmadan hemen konumuza geçelim;

Kuruluma ihtiyacı yoktur. Ruby’nin çekirdek sınıfı içerisinde yer alır. Öncelikle YAML dosyaları neye benzer bir Örneğini verelim;

# Standart yorum satırı
kaynak:
  dizin: c:\Document And Settings
  alt_dizinler: yes
  dosya_uzantılari: doc,xls,txt,msg,html

hedef:
  dizin: c:\Backup
  Ön_ek: Document
  son_ek: Office

GÖrüldüğü gibi türkçe karakterleri kullandık.. :) Yukarıda belirtiğimiz dosyayı ‘config.yaml’ olarak bir dizine kayıt ettikten sonra, aynı dizinde
Continue reading…

Ruby Zip Kütüphanesi (RubyZip)

Merhabalar arkadaşlar,

Uzun ama çok uzun bir aradan sonra tekrar merhaba :). Evlilik hazırlıkları, nikah sonrası dinlenme derken nihayet bugün ilk blog yazımı yazma fırsatı buldum. Öncelikle nikah tÖrenimde beni yanlız bırakmayan tüm arkadaşlara teşekkürlerimi tekrar iletmek isterim. Gerçekten insan bu gibi günlerde etrafında arkadaşlarını gÖrmek istiyor. Şimdi ben bu şekilde yazı yazdım ya.. gelemeyenleri hemen bir telaş almış olabilir :) merak etmesinler, korkacak birşey yok hiç birini Öldürmeyeceğim… yani şimdilik :)

Lafı uzatmadan bu yazımızın konusu olan RubyZip’i (Ruby için sıkıştırma kütüphanesi) incelemeye başlayım. Kullanımı diğer tüm Ruby kütüphaneleri gibi oldukça kolay olan bu sıkıştırma kütüphanesinin kurulumuda oldukça basit….
gem install rubyzip –include-dependencies
şeklinde kurulumu gerçekleştirililyor.
Continue reading…

Şişirme Veri Girişi / Bulk Data Creation

Merhaba arkadaşlar,

Bugün sizlerle acayip, acayip olduğu kadar da zor bir konuyu paylaşacağum. Son bir haftadır çalıştığım firmada ‘Şişirme Veri Girişi’ (Bulk Data Creation) ile uğraşmaktayım. Uzun bir süre değil mi ? evet uzun :) ama yapacak birşey yok uzun sürüyor işte :)

Aklınızda hemen, bu konu neden Önemli, üzerinde neden çalışıyoruz şeklinde sorular oluşabilir, oluşmalıdır da :) bu nedenle sizlere Öncelikle müşterilerin şişirme veri girişini neden istediklerini izah etmeye çalışayım;
– İlk Örneğimiz Microsoft’un Windows işletim sisteminden; işletim sistemine çok fazla program ekleyip kaldırdığımızda sistemin yavaşladığını Registery dosyasının şişmesine bağlarız. Zamanında Microsoft’da çalışan arkadaşlar, bu durumu test etmemiş veya test etmiş fakat sonuçlarını dikkate almamışlar ki biz halen ‘Windows’u nasıl hızlı kurarım’ gibi işlerle uğraşıyoruz.
– 3~5 yıldır kullanılan yazılımlarınızda, çok uyduruk işlemlerin bile artık çok fazla zaman aldığına şahit olabilirsiniz. Bunun nedeni başlangıç verinin çok küçük olacağını düşünüp, veri tabanında uygun indeksleri kullanmamız veya yazdığımız algoritmaların p = n^2 (buradaki ‘n’ veri adedi, ‘p’ performans) veya buna benzer bir şekilde çalışması olabilir. Örnek vermek gerekir ise; n = 1 ise, p = 1, n = 2 ise p = 4, n = 3 ise p = 9, n = 4 ise p = 16 olur… bu durumda 3~5 sene sonra n = 100 olduğunda p = 10.000 olur ki… sistem artık çalışmıyor demektir. Elbetteki Örnekler daha da arttırılabilir.

Akıllı yazılım müşterilerinin artık bu soruyu sormaya başlamalarının nedeni işte bunun gibi nedenler arkadaşlar. Peki biz yazılımcılar bu durumda neler yapabiliriz. Aklınıza ‘Veri boyutu 2 katına çıkarsa sistemin bunu işleme süresi de 2 katına çıkar.’ gibi bir yaklaşım gelebilir. Bu yanlıştır, bu şekilde olmamalıdır. Günümüzdeki veri tabanı uygulamalarını akılcı kullanmak ve eğer bu da yetmiyor ise, yazılıma arvişleme yeteneği eklemek gerekir.

Veri tabanı performansı günümüzde çok büyük problemler teşkil etmemektedir. Asıl problem, programın yazıldığı algoritmanın ve yapılan dizaynın getirdiği kısıtlamalardır. İşte bu tür kısıtlamaları ve bunlara bağlı performans düşüşlerini daha rahat yakalamak için uzun vadeli çalışacak olan sistemlerde şişirme veri girişi(bulk data creation) işlemi ile beraber performans sınaması gerçekleştirilmelidir.

Evet tanımı yaptıktan sonra aklınızda oluşan bazı karışıklıkları gidermek gerekir. Öncelikle Örnek Veri Girişi ile Şişirme Veri Girişi arasındaki farkı sizlere tarif etmem gerekiyor. Örnek veri girişi; sistemin olanaklarını çok zorlamayacak şekilde, Örnek teşkil edecek çoklukta veri girmektir. En fazla sistemde oluşabilecek bir aylık verinin oluşturulmasıdır. Şişirme Veri Girişi ise; Sistemde stres test yapmak ve data boyutlarının hangi sevilere doğru çıktığını, en kÖtü koşullarda veri tabanı üzerinde yapılacak işlemlerin veya yazılmış algoritmaların ne kadar süreceklerini gÖrebilmek için yapılan işlemdir. Tahmini 2 veya 3 seneden daha az olmamak kaydı ile veri giriş yapılmalıdır. Diğer bir deyişle Örnek Veri Girişinin 30 veya 40 katı kadar veri girilmesi gerekir. Girilen bilgiler en az Örnek veri girişinde olduğu kadar mantıklı ve kendi içerisinde tutarlı olmalıdır.

Bu aşamadan sonra sizlere nasıl hızlı ve mantıklı şişirme veya Örnek veri girişi nasıl yaparsınız onları tarif etmeye çalışacağım. Bu işlem için elbetteki Ruby’yi :) kullanacağız(.NET veya Java’yı da kullanabilirdik ama henüz onlarda bu işlemler kolaylaşmadı.).

Bu işlemi Microsoft SQL Server için gerçekleştireceğiz. BÖylece Microsoft SQL Server için ActiveRecord bağlantısını da incele fırsatı bulmuş oluruz. Öncelikle sizlere neden ActiveRecord kullandığımızı açıklamam gerekir, daha Önceki ODBC yazılarımda (1,2,3,4) belirtiğim kütüphane ile değilde, neden ActiveRecord ile gerçekleştiriyoruz. Çünkü ODBC düşük seviyeli bir bağlantı prokolüdür. Fakat ActiveRecord yüksek seviyeli bir veri tabanı ile Ruby arasında bir eşleme kütüphanesidir. Yani ActiveRecord’da veri tabanında bulunan tablolardan Ruby sınıfları oluşturulabilir, bu sınıflar üzerinde ‘Insert’, ‘Delete’, ‘Update’ ve ‘Select’ gibi SQL işlemleri birkaç küçük hareket ile gerçekleştirilebiliriz. Fakat ODBC bize bu şekilde bir yardımda bulunmaz, aynı işlemleri ODBC kullanarak bizlerde gerçekleştirebiliriz, ama bunun için kod yazmamız gerekir ki :) tembel adamın istiyeceği en son şeydir :). Hazırı var işte ActiveRecord :). Eğer ActiveRecord üzerinde hoşumuza gitmeyen bÖlümler olursa Ruby’nin esnekliğinden faydalanarak bunları değiştirebiliriz. Ayrıca ActiveRecord, ODBC gibi bir bağlantı kütüphanesi değildir, tek başına herhangi bir veri tabanına bağlanamaz fakat ODBC, ADO, DBI, OCI gibi birçok bağlantı kütüphanesini kullanabilir.
Continue reading…