Makale Özeti

NET ortamında geliştirdiğimiz uygulamaların çoğunda ihtiyacımız olmuştur veritabanı kullanımına.. Peki projelerimizin kullandığı bu veritabanlarını kurulum yaptığımız makinaya nasıl taşıyacağız? Sanırım en çok kullanılan yöntem, ilk akla gelen veritabanının MDB dosyasını alıp kurulum yapılacak makinaya kopyalamak ve daha sonra SQL de Attach yapmak.. Tabi bu birçok client a kurulması gereken projelerdeki kurulumu bu konuda tecrübesi olmayan birilerinin yapacağı durumlarda pek kolay olmayacak. Bu durumda yapılabilecek en güzel şey, veritabanımızın oluşturulmasını da setup projemize eklemek. Bu yazımızda bunu nasıl yapabileceğimizi göreceğiz.

Makale

NET ortamında geliştirdiğimiz uygulamaların çoğunda ihtiyacımız olmuştur veritabanı kullanımına.. Peki projelerimizin kullandığı bu veritabanlarını kurulum yaptığımız makinaya nasıl taşıyacağız? Sanırım en çok kullanılan yöntem, ilk akla gelen veritabanının MDB dosyasını alıp kurulum yapılacak makinaya kopyalamak ve daha sonra SQL de Attach yapmak.. Tabi bu birçok client a kurulması gereken projelerdeki kurulumu bu konuda tecrübesi olmayan birilerinin yapacağı durumlarda pek kolay olmayacak. Bu durumda yapılabilecek en güzel şey, veritabanımızın oluşturulmasını da setup projemize eklemek. Bu yazımızda bunu nasıl yapabileceğimizi göreceğiz.

Installer Classın oluşturulması

Öncelikle veritabanını oluşturarak, gerekli tableları ekleyecek olan Installer Classımızı ekleyelim.
Veritabanı ve Setup projesi oluşturalacak proje Visual Studio içinde açık iken;

- Solution Explorerda Solution üzerine sağ tıklayarak Add > New Project dediğimizde gelen ekranda project type olarak “Visual Basic Projects” Template olarak ta Class Library seçeneğini seçiyoruz. Name kısmınada projemizin ismini yazıyoruz. örneğimiz için “MyDBSetup” ismini kullanıyorum ben.

- New project penceresinde “OK” diyerek projemizi başlattıktan sonra Solution Explorerda “MyDBSetup” üzerine sağ tıklayarak Add > Add New Item dialog kutusundan Installer Class seçerek Name kısmına “MyDBSetup” yazdıktan sonra Open diyerek classımızı ekliyoruz.

Şimdi oluşturacağımız database için bağlantımızı oluşturalım. Bunu kendi bağlantı yöntemlerimizi kullanarak da yapabildiğimiz gibi basit olarak şöyle yaparız.

- Server Explorer penceresinde Data connectionsı sağ tıklayarak New Connection ile gelen pencerede

- Kullanılacak Server adını yazıyoruz, Use windows NT Integrated Security seçeneğini seçiyoruz, ve database kısmındada Master seçerek OK diyerek penceremizi kapatıyoruz. Oluşan Connectionı tutup sürükleyerek açık olan MyDBSetup[Design] penceremize bıraktığımızda bağlantımız yaratılmış olur.

Oluşacak Veritabanı Bilgilerinin eklenmesi
Şimdi kurulum esnasında oluşturmak istediğimiz veritabanının tablolarını, procedureleri ve gerekli bileşenlerini oluşturacak sorgularımızın bulunduğu, okuyacağımız dosyayı ekleyelim.
Bu sorguyu kendimiz oluşturabileceğimiz gibi daha basit bir şekilde şöyle elde edebiliriz.

- SQL2000 Enterprise Manager ile istediğimiz Databese üzerine gelerek sağ tıkladığımızda All Tasks > Generate SQL Script ile gelen pencereden istediğimiz nesneleri seçerek Formatting ve Options kısmında da belirleyebileceğimiz bazı ayarlarla veritabanını oluşturmak için gereken scriptimizi oluşturabiliriz.

- Oluşturduğumuz scripti projeye eklerken ise projeyede CreateDB.sql isimli yeni bir dosya ekleyerek oluşan script kodumuzu içine kopyalayabileceğimiz gibi, Solution Explorerda Proje üzerine sağ tıklayarak Add > Existing Item ile scripti oluşturduğumuz yerden seçerek ekleyebiliriz.

- Solution Explorer penceresinde CreateDB.sql (bu örnek için kullandığım isim tabi) seçili iken Properties penceresinde Build Action özelliğini Embedded Resource yapıyoruz.

Query Dosyasını Okuyup çalıştıracak kodun oluşturulması

Solution Explorer
da MyDBSetup.vb dosyamızı seçerek sağ tık > View code ile kod penceremizi aktif hale getiriyoruz.
En üst kısımda System.IO ve System.Reflection sınıflarını kodumuzda kullanmak üzere import ediyoruz.

Imports System.IO
Imports System.Reflection

Ve son olarak asıl Sql dosyamızı okuyarak veritabanımızı oluştaracak fonksiyonları ekliyoruz projeye.

Kurulum esnasında bizim eklediğimiz kodun çalışmaya başladığı kısım

Public Overrides Sub Install(ByVal stateSaver As System.Collections.IDictionary)

MyBase.Install(stateSaver)

CreateDB(Me.Context.Parameters.Item("dbname"))

End Sub

Kurulum esnasında bizim eklediğimiz kodun çalışmaya başladığı kısım

Bu kısımda “Me.Context.Parameters.Item("dbname")” kodu ile aldığımız değeri ilerleyen bölümlerde Custom Action kısmında nasıl alacağımızı göreceğiz.

Veritabanı ve tableları oluşturmak için ilgili Procedurelere yönlendirir.

Protected Sub CreateDB(ByVal strDBName As String)

Try

Veritabanını oluşturur.

ExecuteSql("master", "CREATE DATABASE " + strDBName)

Tableları oluşturur.

CreateObje(strDBName, "table")

Proceruleri oluşturur.

CreateObje(strDBName, "procedure")

Catch ex As Exception

Oluşan hataları raporlar.

MsgBox("In exception handler: " & ex.Message)

Throw ex

End Try

End Sub

Veritabanı ve tableları oluşturmak için ilgili Procedurelere yönlendirir.

Daha önce oluşturulan connection da yeni dbir command oluşturarak

parametre olarak gelen stringi çalıştırı.

Private Sub ExecuteSql(ByVal DatabaseName As String, ByVal Sql As String)

Dim Command As New SqlClient.SqlCommand(Sql, SqlConnection1)

Command.Connection.Open()

Command.Connection.ChangeDatabase(DatabaseName)

Try

Command.ExecuteNonQuery()

Finally

Finally blokları bağlantının kapatıldığından emin olmak için iyi bir alandır

is always closed.

Command.Connection.Close()

End Try

End Sub

Yukarıdaki procedure ile bildiğimiz veritabanı üzerinde geriye değer döndürmeyecek olan querylerimizi (insert,update,delete) çalıştırmak için kullandığımız Command.ExecuteNonQuery() fonxiyonunu kullanarak nesnelerimizi gelen sql parametresine göre oluştururuz.

Name parametresi ile gelen dosyanın içinde yazılanları

(Veritabanımızı oluşturan kodlar) String olarak geri döndürür.

Private Function GetSql(ByVal Name As String) As String

Try

Gets the current assembly.

Dim Asm As [Assembly] = [Assembly].GetExecutingAssembly()

Resources are named using a fully qualified name.

Dim strm As Stream

Strm= Asm.GetManifestResourceStream(Asm.GetName().Name + "." + Name)

Reads the contents of the embedded file.

Dim reader As StreamReader = New StreamReader(strm)

Return reader.ReadToEnd()

Catch ex As Exception

MsgBox("In GetSQL: " & ex.Message)

Throw ex

End Try

End Function

Bu Fonksiyon Name parametresi ile gelen dosyanın içinde yazılanları

(Veritabanımızı oluşturan kodlar) String olarak geri döndürür.

Burada normal dosya okuma yöntemlerini kullanmamamızın nedeni, kullandığımız sql dosyasının Setup projemizin içinde gömülü olması. Farklı şekilde veri okumayı denediğimiz takdirde “CreateDB.sql ” dosyasını “C:\winnt\system32\” klasöründe arayacağından hata verecektir.

Gelen Nesne parametresine göre Table yada Procedure oluşturmak için

CreateDB.sql içindeki verileri ayrıştırarak, uygun kısmı çalıştırır

ve Veritabanı üzerinde Table ya da Procedure oluşturur

Sub CreateObje(ByVal DBName As String, ByVal Nesne As String)

Dim str, sqlcik As String

Dim baslangic, bitis As Integer

str = GetSql("CreateDB.sql") Dosyanın içeriğini str değişkenine atar.

Select Case nesne

Case "table"

Do While str.Length - 1 <> 0

baslangic = InStr(1, str, "CREATE TABLE ")

If bitis <> -1 Then

If baslangic = 0 Then

Exit Do

End If

bitis = Microsoft.VisualBasic.InStr(baslangic, str, "ON [PRIMARY]") + 12

sqlcik = Microsoft.VisualBasic.Mid(str, baslangic, bitis - baslangic)

MsgBox(sqlcik)

ExecuteSql(DBName, sqlcik)

str = str.Remove(baslangic, bitis - baslangic)

End If

Loop

Case "procedure"

Do While str.Length - 1 <> 0

baslangic = InStr(1, str, "CREATE PROCEDURE")

If baslangic <> -1 Then

If baslangic = 0 Then

Exit Do

End If

bitis = Microsoft.VisualBasic.InStr(baslangic, str, "RETURN") + 6

sqlcik = Microsoft.VisualBasic.Mid(str, baslangic, bitis - baslangic)

MsgBox(sqlcik)

ExecuteSql(DBName, sqlcik)

If bitis < str.Length - 2 Then

str = str.Remove(baslangic, bitis - baslangic)

Else

Exit Do

End If

End If

Loop

End Select

End Sub

CreateObje() Fonksiyonu ise “CreateDB.sql" dosyasının içeriğini atadığımız str değişkeni üzerinde bazı işlemler yaparak, gelen Nesne parametresine göre Procedure yada Tableları oluşturur.

Artık Build Menusünü kullanarak projemizi derleyebiliriz.

Setup Projesini Oluşturmak

- File > Add Project > New Project adımlarıyla ulaştığımız Project Dialog kutusunda “Setup and Deployement” tipi altındaki “Setup Project” Template ini seçerek Name kısmına “MyDBSetup Installer” yazarak kurulum projesini ekleyelim.

- Properties penceresinde ProductName kısmına yazacağımız “DB Installer” projemizin ismini belirler.

- Database kurulum projesini Setup projesine eklemek için File Sistem Editor > Application Folder üzerinde sağ tık > Add > Project Output ile gelen pencere de Project kısmında “MyDBSetup” projemizi seçerek OK butonu ile penceremizi kapatıyoruz.

- Kurmamız gereken temel programı da bir önceki adımda olduğu gibi eklemeliyiz. Yani File Sistem Editor > Application Folder üzerinde sağ tık > Add > Project Output ile gelen pencere de Project kısmında “KurmakIstedigimizProje” projemizi ekleriz

- Kurulum esnasında Projemiz için masaüstünde kısayol oluşturmak istiyorsak

Bir önceki adımda Application folder içinde oluşturduğumuz “Primary output from “KurmakIstedigimizProje” (Active) üzerinde sağ tıklarak “Create Shortcut…” seçeriz. Ve oluşan Shortcut ı sürükleyerek User’s Desktop a bırakırız. Tabi ismi,Açıklaması, Iconu gibi bazı özelliklerini Properties penceresinden değiştirebiliriz.

Veritabanı İsminin Alınacağı Dialog Kutusunun Oluşturulması

Setup Projelerinde bulunan User Interface menusu ile kurulum aşamasında ekrana gelen sihirbazın arayüzünde değişiklikler yapabiliriz. Bunu ekranda görülen kurulum adımlarını seçerek Properties penceresinde değişiklikler yaparak, yada yeni pencereler ekleyerek sağlarız.

Bizim şu anda yapacağımız şey ise oluşturacağımız database için kullanıcıdan bir isim almak .

- Solution Explorer da MyDBSetupInstaller Projemiz seçili iken View > Editor > User Interface penceresini açarız

- Install altındaki Start düğümü üzerine sağ tıklayarak > Add Dialog la gelen pencereden Textboxes(A) seçeneğini seçerek OK ile ekliyoruz

- Textboxes Installation Folder ın üzerine gelene kadar Sağ tık > Move Up ile yukarı taşıyoruz.

- Properties penceresinde Banner Text özelliğini “Database Adı” Olarak değiştiriyoruz. Body text özelliğini ise “Bu dialog kutusu oluşturacağınız Database için isim belirlemenizi sağlar.” yazıyoruz.

- Edit1Label özelliğini de “Database Adı” ile değiştiriyoruz.

- Properties bölümünde daha sonra girilen ismi almamızı sağlayacak özellik ise Edit1Property. Ona da DBEDIT yazıyoruz.

- Son olarak kullanmadığımız Edit2, Edit3 ve Edit4 için visible özelliklerini False yaparak görünmelerini engelleyelim

Custom Action ile Özel Eylem Oluşturulması ;

Custom Action hazırladığımız projenin setup kısmında çalışmasını istediğimiz bazı programlar,özel eylemler varsa bunları eklemek için kullanılabilen bir bölümdür. Örneğin büyük bir veritabanı projesinin sistem bölümü olarak hazırladığımız ufak bir yönetim programında, kullanılacak serverın IP sini, Sql server kullanıcı adı, şifresini kaydediyorsak, bu programı kurulum esnasında da çalıştırarak programın ilk çalışması için gerekli bazı bilgileri sisteme kaydedebiliriz.

Bizim bu örneğimizde ise Veritabanımızı oluşturan örnek projeyi çalıştırmak için kullanacağız.

Bunu yapmak için ;

- Solution explorer da SetupProjemiz üzerinde sağ tık > view > Custom actions (Yada menuden View > Editor > Custom Actions) ile Custom Actions penceremizi açarız

- Install düğümü üzerinde sağ tıklayarak “Add Custom Action” I tıkladığımızda gelen Dialog kutusu bizden özel olarak çalışmasını istediğimiz projeyi seçmemizi ister. Bizde daha once bu amaçla Application folder altına eklediğimiz Primary Output From MyDBSetup… Outputunu seçerek ok ile ekleme işlemini tamamlarız.

Şimdi yapmamız gereken şey ise seçtiğimiz programa parameter olarak göndereceğimiz database ismini bu kısımda belirtmek. Bunun içinde properties penceresinde CustomActionData özelliğine /dbname=[DBEDIT] yazıyoruz. Burada dbname ile gösterilen değer kod bölümünde ki (Me.Context.Parameters.Item("dbname")) ) dbname parametresidir.

DBEDIT değeri ise bir önceki arayüz oluşturduğumuz bölümde Textbox ın Edit1Property özelliğine yazdığımız değer olmalı.

Bu örneğimizde eklediğimiz Custom Action için yapmamız gerekenler bunlar. Ancak daha öncede bahsettiğimiz gibi “Insteller Class” olmayan herhangi bir projeyi de kurulum dosyamıza ekleyebiliriz. Bunun için yapmamız gereken ek bir şey

Properties penceresinde InstallerClass özelliğini False yapmak. Aksi durumda eklediğiniz projenin çalışmadığını göreceksiniz.

Projemizi Build menusunu kullanarak derlediğimizde Kurulum dosyamız hazırlanmış olacak.

Projeyi geliştirdiğimiz bilgisayarda kurulumu yapmak için Project menusundeki Install seçeneğini kullanabiliriz. Farklı makinalarda kullanmak içinse Setup projesini oluşturduğumuz klasor altındaki Debug klasorunde bulunan .MSI I kullanmalıyız.

Oluşabilecek Hatalardan Bazıları :

- “In exception handler: Line 1 : Incorret syntax near "DATABASE" “

hatası ile karşılaşıyorsanız DB ismini aldığınız Textbox ve Custom Action kısmında onu belirttiğimiz yer ile ilgili bir sorundur. Tekrar gözden geçilmeli.

- “In GetSQL: Değer null olamaz. Parametre adı: stream” Hatası veritabanı bilgilerinin alındığı sql dosyasının property kısmında Build Action özelliiğini “Embedded Resource” olmalı.

- “In exception handler: Database ‘VerdiginizIsim’ alredy exist

Hata mesajı Varolan bir veritabanı ismi vererek yeniden oluşturmaya çalıştığımızda karşılaşacağımız hatadır.

Bunu önlemek için öncelikle kurulum esnasında Veritabanı sistemde zaten varsa onu silip yeniden kurmak istiyor muyuz buna karar vermeliyiz. Eğer cevabımız evet ise yapmamız gereken şey;

Kod kısmında

ExecuteSql("master", "CREATE DATABASE " + strDBName)

Satırını aşağıdaki ile değiştirmek.

Dim crt As String

crt = "IF EXISTS (SELECT name FROM master.dbo.sysdatabases "

crt += " WHERE name = N" & strDBName & ") "

crt += " DROP DATABASE [" & strDBName & "]"

crt += " CREATE DATABASE " + strDBName

ExecuteSql("master", crt)

Böylece veritabanını “Create Database” ile sadece oluşturmak yerine, sistemde olup olmadığını kontrol ederek, eğer var ise Silip yeniden oluşturmuş oluruz.

Artık hazırladığımız Setup dosyasını çalıştırdığımızda, User Interface ile hazırladığımız arabirim sayesinde bizden veritabanı ismini isteyecek, Custom Action kullanarak eklediğimiz proje ile de istediğimiz özelliklerdeki veritabanını kurulum yaptığımız sisteme ekleyebileceğiz. Proje ile ilgili örnek kodları burayı tıklayarak download edebilirsiniz.

Nurten Çoban