Interbase zaafları ve VTYS sistemleri hakkında söyleşi (2)
Otomatik Sayı sorunu, tetikleyicinin birincil anahtarlarla uyumsuz olması.
- Tablolar oluşturulurken birbirlerini lego gibi tamamlar nitelikte tasarlanırlar. Örneğin müşteriyi her seferinde ismini ve bilgilerini girmek yerine ayrı bir tablodan referans numarası verilerek ihtiyaç duyulduğunda bu referans numarasıyla çağrılması tüm tasarlanan tablo yapılarında vardır. Otomatik sayı alanlarının değerini veritabanları otomatik olarak verirler. Bazı veritabanı sistemleri bunun için Autoincrement (otomatik artan sayı) alanı kullanırlar. Fakat bu interbase içerinde alan türü olarak yer almamaktadır. En çok ihtiyaç duyulan alan türlerinden birisi Boolean, 7.x sürümünden sonra eklenmiştir. Otomatik artan sayı alanları için tetikleyici yazmanız gerekmektedir. Örneğin aşağıdaki gibi:
URUN_NO=GEN_ID(URUN_NO,1);
Bunu yaptığınızda ihtiyacınızı görecektir fakat birincil anahtar oluşturduğunuzda, çakışma yarattığını göreceksiniz. İsterseniz böyle bir tablo oluşturup birincil anahtar alanları olan ve otomatik artan sayı alanı için bir tetikleyiciye sahip olan örnek tablo tasarlayın. Delphi içinden kayıt işlemi yapmak istediğinizde ekrana hata mesajı belirecek işlem başarısız olacaktır. Bu sorunu aşmak için çözüm yöntemi; otomatik artan sayı alanı için tetikleyici yazmak yerine depolanmış yordam ile yapmaktır. Böylece hiçbir çakışma yaşanmayacaktır. Depolanmış yordam kayıt eklendiğinde otomatik çalıştırılmaz çünkü tablodan bağımsızdır. Bunun için Datasetin AfterInsert() olayının içerisine IBStoredProc bileşeniyle çalıştırmaktır. Tabii bu işlemleri yaparken üretecin (generator) daha önceden oluşturulmuş olması gerekir. Depolanmış yordam geriye çıkış değeri gönderecektir. Bu sayı değerini kod yordamıyla tablodaki alana aktarmanız gerekir. Örnek olarak:
--------------------------------------
"Urun_No" (Double Precision) Not Null,
"Urun_Adı" (Char(20)),
Primary Key ("Urun_No")
--------------------------------------
Alanları bulunan ve "urunno" isimli bir üretecin var olduğunu düşünerekten anlatılanları yorumlayabilirsiniz. Sunucu üzerinde ilgili işlemleri yaptığınızda sorun yaşanacaktır. Bunun için yukarıdaki yönergeyi dikkate almanızda fayda var.
Depolanmış yordam ise şu şekilde olacaktır. Yani tetikleyiciye yazacağımız kodu buraya yazıyoruz:
--------------------------------------
CREATE PROCEDURE "otomatik_sayi_uret"
RETURNS
(
"URUN_NO" DOUBLE PRECISION
)
AS
BEGIN
URUN_NO=GEN_ID(URUN_NO,1);
END;
--------------------------------------
Delphi içerisinde dataset (IBQuery,IBtable v.b.) içerisinde AfterInsert() olayına aşağıdaki kodu uyarlayınız:
--------------------------------------
procedure TForm1.IBTable1AfterInsert(DataSet: TDataSet);
begin
IBStoredProc1.Prepare;
try
IBStoredProc1.ExecProc;
IBTable1.FieldByName('URUN_NO')Value := IBStoredProc1.ParamByName('URUN_NO').Value;
finally
IBStoredProc1.UnPrepare;
end;
end;
--------------------------------------
Yeni kayıt eklenip kaydedildiğinde otomatik sayı alan değerinin istemciye yansımaması.
- Interbase IBX bileşenlerinden dataset sınıfının en büyük zaafı kayıt saklandığında çalışan tetikleyiciden dönen değerin istemciye gönderilmemesi. Örnek olarak yukarıdaki tablo yapısında ve bir adet tetikleyici ile otomatik sayı değerinin verildiği bir tabloyu "IBTable" bileşeni ile bağlanmayı deneyin. Yeni bir kayıt ekleyin ve ürün adı alanını doldurun, ardından kaydedin. Dikkatle baktığınızda bu alan değerini okuyamayacaksınız ve değer kısmının boş olduğunu göreceksiniz. Fakat sunucuda bu değer verilmiştir. Ancak yenile (refresh), veya ekleme (insert) metotları uygulandığınızda, yeni bir işleme geçildiğinden referans alanındaki sayı değerini okuyabilirsiniz. Ayrıca ekrandaki kayıt sırası kaybolarak ilk kayda gidilecektir. Bu işlem ise milyonlarca hatta yüzlerce kayıt bulunan bir tabloda ne kadar kod yazsanız da 7-8 saniyelik sinir bozucu bekleme sürelerine yol açar. Kaydın referans alanında bulunan değer alt tablolarda saklanmak istendiğinde null bir alan gibi görünen ama sunucuda var olan değere ulaşamayıp gereksiz kodlamalara yol açacaktır. Borland, bu hata ile ilgili bir çözüm hala üretmedi. Ama yukarıdaki yöntemi kullanarak bu sorunun üstesinden gelebilirsiniz.
IBDataSet bileşenin GeneratorField özeliğini kullanarak da bu işi yapabilirsiniz. Ayrıca tetikleyici yazmanıza da gerek kalmayacaktır. Fakat çok değil kayıt sayısı bin değerine ulaşmadan işlemlerin yavaşlamaya başladığını fark edeceksiniz. Bunun sebebi dataset her hareketi yaparken içerisindeki SQL sorgusunu çalıştırması. İlişkili tablolarda gözle görülür derecede yavaşlama olur. Hele ki bir dataset bileşeninde gözat (lookup) alanları ortalama 5 inüzerinde ise bu can sıkıcı yavaşlamalara yol açıyor. Yavaş bilgisayarlarda çalışıyorsanız bu çok fazla göze çarpar.
Hatalı tarih biçimi
- Diğer karşılaştığımız bir hata ise interbase konsol programının verileri ihraç komutu verdiğinizde (extract table data - tablo özelliklerinden baktığınızda alttaki onay kutusu) tarih alanlarının sistemde tanımlı olan tarih biçiminde değil de, amerikan tarih biçiminde verildiğini göreceksiniz. İşin ilginç tarafı aynı verileri tekrar eklemek istediğinizde bu sefer sistem tarih biçimini temel alarak tarih biçimini uygun bulmaması ve hata üretmesi ..
Hesaplanabilir alanlar
- Interbase, tabloları içerisinde hesaplanabilir alanlar (delphi deki calculated gibi) oluşturulmasına imkan verir. Bunu computed by deyimiyle alan isminden sonra tanımlayabilirsiniz. Fakat bu delphi içerisindeki hesaplanabilir alanlar gibi etkileşimli çalışmaz. Yani düzenleme, ekleme vb. gibi işlemlerde, alan değeri gösterilmez. Ancak gezinti modundayken bu alanların hesaplanarak, sunucudan istemci programa gönderildiğini göreceksiniz. Tablolarınızı tasarlarken bu durumu göze almanızda fayda var. Programı hazırlamaya başladıktan sonra fark etmeniz sizin için yapıyı tekrar tasarlamanız konusunda zaman kaybına yol açabilir.
Delphi - .....................................
Interbase zaafları ve VTYS sistemleri hakkında söyleşi (2)
Otomatik Sayı sorunu, tetikleyicinin birincil anahtarlarla uyumsuz olması.
- Tablolar oluşturulurken birbirlerini lego gibi tamamlar nitelikte tasarlanırlar. Örneğin müşteriyi her seferinde ismini ve bilgilerini girmek yerine ayrı bir tablodan referans numarası verilerek ihtiyaç duyulduğunda bu referans numarasıyla çağrılması tüm tasarlanan tablo yapılarında vardır. Otomatik sayı alanlarının değerini veritabanları otomatik olarak verirler. Bazı veritabanı sistemleri bunun için Autoincrement (otomatik artan sayı) alanı kullanırlar. Fakat bu interbase içerinde alan türü olarak yer almamaktadır. En çok ihtiyaç duyulan alan türlerinden birisi Boolean, 7.x sürümünden sonra eklenmiştir. Otomatik artan sayı alanları için tetikleyici yazmanız gerekmektedir. Örneğin aşağıdaki gibi:
URUN_NO=GEN_ID(URUN_NO,1);
Bunu yaptığınızda ihtiyacınızı görecektir fakat birincil anahtar oluşturduğunuzda, çakışma yarattığını göreceksiniz. İsterseniz böyle bir tablo oluşturup birincil anahtar alanları olan ve otomatik artan sayı alanı için bir tetikleyiciye sahip olan örnek tablo tasarlayın. Delphi içinden kayıt işlemi yapmak istediğinizde ekrana hata mesajı belirecek işlem başarısız olacaktır. Bu sorunu aşmak için çözüm yöntemi; otomatik artan sayı alanı için tetikleyici yazmak yerine depolanmış yordam ile yapmaktır. Böylece hiçbir çakışma yaşanmayacaktır. Depolanmış yordam kayıt eklendiğinde otomatik çalıştırılmaz çünkü tablodan bağımsızdır. Bunun için Datasetin AfterInsert() olayının içerisine IBStoredProc bileşeniyle çalıştırmaktır. Tabii bu işlemleri yaparken üretecin (generator) daha önceden oluşturulmuş olması gerekir. Depolanmış yordam geriye çıkış değeri gönderecektir. Bu sayı değerini kod yordamıyla tablodaki alana aktarmanız gerekir. Örnek olarak:
--------------------------------------
"Urun_No" (Double Precision) Not Null,
"Urun_Adı" (Char(20)),
Primary Key ("Urun_No")
--------------------------------------
Alanları bulunan ve "urunno" isimli bir üretecin var olduğunu düşünerekten anlatılanları yorumlayabilirsiniz. Sunucu üzerinde ilgili işlemleri yaptığınızda sorun yaşanacaktır. Bunun için yukarıdaki yönergeyi dikkate almanızda fayda var.
Depolanmış yordam ise şu şekilde olacaktır. Yani tetikleyiciye yazacağımız kodu buraya yazıyoruz:
--------------------------------------
CREATE PROCEDURE "otomatik_sayi_uret"
RETURNS
(
"URUN_NO" DOUBLE PRECISION
)
AS
BEGIN
URUN_NO=GEN_ID(URUN_NO,1);
END;
--------------------------------------
Delphi içerisinde dataset (IBQuery,IBtable v.b.) içerisinde AfterInsert() olayına aşağıdaki kodu uyarlayınız:
--------------------------------------
procedure TForm1.IBTable1AfterInsert(DataSet: TDataSet);
begin
IBStoredProc1.Prepare;
try
IBStoredProc1.ExecProc;
IBTable1.FieldByName('URUN_NO')Value := IBStoredProc1.ParamByName('URUN_NO').Value;
finally
IBStoredProc1.UnPrepare;
end;
end;
--------------------------------------
Yeni kayıt eklenip kaydedildiğinde otomatik sayı alan değerinin istemciye yansımaması.
- Interbase IBX bileşenlerinden dataset sınıfının en büyük zaafı kayıt saklandığında çalışan tetikleyiciden dönen değerin istemciye gönderilmemesi. Örnek olarak yukarıdaki tablo yapısında ve bir adet tetikleyici ile otomatik sayı değerinin verildiği bir tabloyu "IBTable" bileşeni ile bağlanmayı deneyin. Yeni bir kayıt ekleyin ve ürün adı alanını doldurun, ardından kaydedin. Dikkatle baktığınızda bu alan değerini okuyamayacaksınız ve değer kısmının boş olduğunu göreceksiniz. Fakat sunucuda bu değer verilmiştir. Ancak yenile (refresh), veya ekleme (insert) metotları uygulandığınızda, yeni bir işleme geçildiğinden referans alanındaki sayı değerini okuyabilirsiniz. Ayrıca ekrandaki kayıt sırası kaybolarak ilk kayda gidilecektir. Bu işlem ise milyonlarca hatta yüzlerce kayıt bulunan bir tabloda ne kadar kod yazsanız da 7-8 saniyelik sinir bozucu bekleme sürelerine yol açar. Kaydın referans alanında bulunan değer alt tablolarda saklanmak istendiğinde null bir alan gibi görünen ama sunucuda var olan değere ulaşamayıp gereksiz kodlamalara yol açacaktır. Borland, bu hata ile ilgili bir çözüm hala üretmedi. Ama yukarıdaki yöntemi kullanarak bu sorunun üstesinden gelebilirsiniz.
IBDataSet bileşenin GeneratorField özeliğini kullanarak da bu işi yapabilirsiniz. Ayrıca tetikleyici yazmanıza da gerek kalmayacaktır. Fakat çok değil kayıt sayısı bin değerine ulaşmadan işlemlerin yavaşlamaya başladığını fark edeceksiniz. Bunun sebebi dataset her hareketi yaparken içerisindeki SQL sorgusunu çalıştırması. İlişkili tablolarda gözle görülür derecede yavaşlama olur. Hele ki bir dataset bileşeninde gözat (lookup) alanları ortalama 5 inüzerinde ise bu can sıkıcı yavaşlamalara yol açıyor. Yavaş bilgisayarlarda çalışıyorsanız bu çok fazla göze çarpar.
Hatalı tarih biçimi
- Diğer karşılaştığımız bir hata ise interbase konsol programının verileri ihraç komutu verdiğinizde (extract table data - tablo özelliklerinden baktığınızda alttaki onay kutusu) tarih alanlarının sistemde tanımlı olan tarih biçiminde değil de, amerikan tarih biçiminde verildiğini göreceksiniz. İşin ilginç tarafı aynı verileri tekrar eklemek istediğinizde bu sefer sistem tarih biçimini temel alarak tarih biçimini uygun bulmaması ve hata üretmesi ..
Hesaplanabilir alanlar
- Interbase, tabloları içerisinde hesaplanabilir alanlar (delphi deki calculated gibi) oluşturulmasına imkan verir. Bunu computed by deyimiyle alan isminden sonra tanımlayabilirsiniz. Fakat bu delphi içerisindeki hesaplanabilir alanlar gibi etkileşimli çalışmaz. Yani düzenleme, ekleme vb. gibi işlemlerde, alan değeri gösterilmez. Ancak gezinti modundayken bu alanların hesaplanarak, sunucudan istemci programa gönderildiğini göreceksiniz. Tablolarınızı tasarlarken bu durumu göze almanızda fayda var. Programı hazırlamaya başladıktan sonra fark etmeniz sizin için yapıyı tekrar tasarlamanız konusunda zaman kaybına yol açabilir.
Delphi - .....................................
Interbase zaafları ve VTYS sistemleri hakkında söyleşi (1)
Merhaba arkadaşlar.
Uzun bir yoğunluk döneminden sonra nihayet zaman ayırabildim ve makale yazma fırsatım oldu. Umarım size yardımcı olabilir. Yazı Interbase veritabanı yönetim sisteminde karşılaştığımız sorunlar ve çözümleri üzerine olacaktır.
Bildiğimiz üzere dünyada tüm kullanılan programlar, verileri saklamak için veritabanı kullanıyorlar. Bunlar verilerimizi saklayabildiğimiz yönetim sistemleri... Bütün verilerimiz önemlidir. Kimse önemsiz, daha sonra tekrardan ihtiyaç duymadığı bir veriyi saklamak istemez herhalde... Bu veriler kimi zaman; parasal bilgilerin saklandığı çok önemli banka verileri, bir gsm operatörünün abone verileri, detaylı güvenlik verileri, sağlık detay verileri, kredi işlemlerinin takibinin bulunduğu veriler gibi çeşitli dallarda hemen her sektörde ihtiyaç duyulan verileri saklamak için bilgisayar yazılımları kullanılır ve bu yazılımlar taban olarak veritabanı yönetim sistemlerine ihtiyaç duyarlar.
Peki, kullandığımız veritabanı yönetim sistemleri ne derecede düzenli ve hatasız çalışabiliyorlar? Canımızı sıkan veri kayıpları mutlaka başımıza geliyor ve bunun sorumlusu olarak kimseyi gösteremiyoruz. Bugün hatasız, istikrarlı, hızlı çalışan veritabanı yönetim sistemleri olduğu gibi orta düzeyde az hata ile çalışan sistemler de bulunuyor. Büyük veri sistemleri denilince ilk akla Microsoft SQL Server, Oracle Database, Informix, IBM DB2 gibi dev yazılım firmalarının büyük arge masrafları kullanarak oluşturulmuş sistemler akla geliyor. Tabii yüksek performans, donanım hızı, dolayısıyla artan masrafları göz önüne getirmektedir. Verileri saklarken kullanma amacımıza göre sistemleri seçiyoruz. Bunun yanında en büyük neden, binlerce doları bulan lisans bedelleri... Küçük bir stok programı için Oracle kullanmanızın uygun olamayacağı gibi, büyük çok kullanıcılı bir otomasyon sistemi içinde Paradox kullanmanız beklenemez. Bizim amacımız sistemi en iyi şekilde, hızlı, kayıpsız, hatasız ve kullanılır olarak tasarlamaktır.
Bu makalede değineceğimiz konu Interbase/FireBird gibi orta düzeyli SQL Sunucu; veritabanı yönetim sistemlerinin zaafları olacaktır. Interbase, SQL komut kümesi her sürümünde genişletilen, ek fonksiyonlar eklenen, programlama hataları (bug) düzeltilen Delphi ile kullanıldığında etkili çalışan bir veritabanı sistemi. Şu an itibariyle ulaştığı 7.5 sürümüyle çok aşama kaydetti fakat bir MS-SQL Server, Oracle Database olgunluğuna ulaşmadı. Delphi içerisinden başarımı yüksek bir şekilde bağlanıp veri işlemek için IBX bileşenleri kullanılabilir. Veya FIBPlus gibi alternatif bileşenler kullanılabilir. Fakat bu bileşenlerin interbase vtys i tam anlamıyla yönetebildiği söylenemez. Ayrıca Interbase in kendi içerisinde de tutarlı çalışmayan bölümleri maalesef mevcut.
Bununla beraber MySQL açık kaynak kodlu ve GNU lisansıyla dağıtılmasının avantajını kullanıyor, gönüllü programcılar tarafından gün geçtikçe yeni yeni özellikler kazandırılıyor. Son 5.x serisinde; depolanmış yordam (stored procedure), tetikleyici (trigger), görüntü (view) ve yeni eklenmiş onlarca yararlı komut bunların göstergesi. En büyük avantajı ise ücretsiz olmasıdır. Interbase kategorisindeki tek rakibi MySQL...
Interbase içerisinde karşılaştığımız bazı sorunlardan bahsedeyim. Bazen bunlar çok can sıkıcı bir hale dönüşüyor ve programcıyı zor durumda bırakıyor. Aklıma gelen birkaç tanesine değineyim.
Delphi - .....................................
Interbase zaafları ve VTYS sistemleri hakkında söyleşi (1)
Merhaba arkadaşlar.
Uzun bir yoğunluk döneminden sonra nihayet zaman ayırabildim ve makale yazma fırsatım oldu. Umarım size yardımcı olabilir. Yazı Interbase veritabanı yönetim sisteminde karşılaştığımız sorunlar ve çözümleri üzerine olacaktır.
Bildiğimiz üzere dünyada tüm kullanılan programlar, verileri saklamak için veritabanı kullanıyorlar. Bunlar verilerimizi saklayabildiğimiz yönetim sistemleri... Bütün verilerimiz önemlidir. Kimse önemsiz, daha sonra tekrardan ihtiyaç duymadığı bir veriyi saklamak istemez herhalde... Bu veriler kimi zaman; parasal bilgilerin saklandığı çok önemli banka verileri, bir gsm operatörünün abone verileri, detaylı güvenlik verileri, sağlık detay verileri, kredi işlemlerinin takibinin bulunduğu veriler gibi çeşitli dallarda hemen her sektörde ihtiyaç duyulan verileri saklamak için bilgisayar yazılımları kullanılır ve bu yazılımlar taban olarak veritabanı yönetim sistemlerine ihtiyaç duyarlar.
Peki, kullandığımız veritabanı yönetim sistemleri ne derecede düzenli ve hatasız çalışabiliyorlar? Canımızı sıkan veri kayıpları mutlaka başımıza geliyor ve bunun sorumlusu olarak kimseyi gösteremiyoruz. Bugün hatasız, istikrarlı, hızlı çalışan veritabanı yönetim sistemleri olduğu gibi orta düzeyde az hata ile çalışan sistemler de bulunuyor. Büyük veri sistemleri denilince ilk akla Microsoft SQL Server, Oracle Database, Informix, IBM DB2 gibi dev yazılım firmalarının büyük arge masrafları kullanarak oluşturulmuş sistemler akla geliyor. Tabii yüksek performans, donanım hızı, dolayısıyla artan masrafları göz önüne getirmektedir. Verileri saklarken kullanma amacımıza göre sistemleri seçiyoruz. Bunun yanında en büyük neden, binlerce doları bulan lisans bedelleri... Küçük bir stok programı için Oracle kullanmanızın uygun olamayacağı gibi, büyük çok kullanıcılı bir otomasyon sistemi içinde Paradox kullanmanız beklenemez. Bizim amacımız sistemi en iyi şekilde, hızlı, kayıpsız, hatasız ve kullanılır olarak tasarlamaktır.
Bu makalede değineceğimiz konu Interbase/FireBird gibi orta düzeyli SQL Sunucu; veritabanı yönetim sistemlerinin zaafları olacaktır. Interbase, SQL komut kümesi her sürümünde genişletilen, ek fonksiyonlar eklenen, programlama hataları (bug) düzeltilen Delphi ile kullanıldığında etkili çalışan bir veritabanı sistemi. Şu an itibariyle ulaştığı 7.5 sürümüyle çok aşama kaydetti fakat bir MS-SQL Server, Oracle Database olgunluğuna ulaşmadı. Delphi içerisinden başarımı yüksek bir şekilde bağlanıp veri işlemek için IBX bileşenleri kullanılabilir. Veya FIBPlus gibi alternatif bileşenler kullanılabilir. Fakat bu bileşenlerin interbase vtys i tam anlamıyla yönetebildiği söylenemez. Ayrıca Interbase in kendi içerisinde de tutarlı çalışmayan bölümleri maalesef mevcut.
Bununla beraber MySQL açık kaynak kodlu ve GNU lisansıyla dağıtılmasının avantajını kullanıyor, gönüllü programcılar tarafından gün geçtikçe yeni yeni özellikler kazandırılıyor. Son 5.x serisinde; depolanmış yordam (stored procedure), tetikleyici (trigger), görüntü (view) ve yeni eklenmiş onlarca yararlı komut bunların göstergesi. En büyük avantajı ise ücretsiz olmasıdır. Interbase kategorisindeki tek rakibi MySQL...
Interbase içerisinde karşılaştığımız bazı sorunlardan bahsedeyim. Bazen bunlar çok can sıkıcı bir hale dönüşüyor ve programcıyı zor durumda bırakıyor. Aklıma gelen birkaç tanesine değineyim.
Delphi - .....................................
MySQL+ZEOS Veritabanı açma, kullanıcı tanımlama, izin yönetimi, SQL scriplerinin atılması
ZEOS kullanarak yaptığım kullanıcı tanımlama, kullanıcının hangi DB yi kullanacağını tanımlama ve SQL dosyasında hazır olan script in seçilen DB ye aktarılması. Bazı arkadaşların işine yarayabilir.
procedure TForm1.Button1Click(Sender: TObject);
begin
ZConnection1.Connect;
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('CREATE DATABASE bsbuzlu');
ExecSQL;
end;
memo1.Lines.Add('Bağlantı Kuruldu. Veritabanı açıldı.');
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('USE mysql;');
ExecSQL;
end;
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('INSERT INTO user (Host,User,Password)');
SQL.Add('VALUES (''%'',''deneme'',PASSWORD(''123''))');
ExecSQL;
end;
memo1.Lines.Add('Kullanıcı Eklendi');
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,');
SQL.Add('Update_priv,Delete_priv,Create_priv,Drop_priv,Lock_tables_priv)');
SQL.Add('VALUES (''%'',''bsbuzlu'',''deneme'',''Y'',''Y'',''Y'',''Y'',''Y'',''Y'',''Y'')');
ExecSQL;
end;
memo1.Lines.Add('Kullanıcının veritabanı belirlendi.');
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('FLUSH PRIVILEGES');
ExecSQL;
end;
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('USE bsbuzlu;');
ExecSQL;
end;
ZSQLProcessor1.LoadFromFile(ExtractFilePath(Application.ExeName) + 'createClient.sql');
ZSQLProcessor1.Execute;
memo1.Lines.Add('Veritabanına Tablolar Eklendi.');
end;
Delphi - .....................................
MySQL+ZEOS Veritabanı açma, kullanıcı tanımlama, izin yönetimi, SQL scriplerinin atılması
ZEOS kullanarak yaptığım kullanıcı tanımlama, kullanıcının hangi DB yi kullanacağını tanımlama ve SQL dosyasında hazır olan script in seçilen DB ye aktarılması. Bazı arkadaşların işine yarayabilir.
procedure TForm1.Button1Click(Sender: TObject);
begin
ZConnection1.Connect;
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('CREATE DATABASE bsbuzlu');
ExecSQL;
end;
memo1.Lines.Add('Bağlantı Kuruldu. Veritabanı açıldı.');
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('USE mysql;');
ExecSQL;
end;
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('INSERT INTO user (Host,User,Password)');
SQL.Add('VALUES (''%'',''deneme'',PASSWORD(''123''))');
ExecSQL;
end;
memo1.Lines.Add('Kullanıcı Eklendi');
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,');
SQL.Add('Update_priv,Delete_priv,Create_priv,Drop_priv,Lock_tables_priv)');
SQL.Add('VALUES (''%'',''bsbuzlu'',''deneme'',''Y'',''Y'',''Y'',''Y'',''Y'',''Y'',''Y'')');
ExecSQL;
end;
memo1.Lines.Add('Kullanıcının veritabanı belirlendi.');
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('FLUSH PRIVILEGES');
ExecSQL;
end;
with ZQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('USE bsbuzlu;');
ExecSQL;
end;
ZSQLProcessor1.LoadFromFile(ExtractFilePath(Application.ExeName) + 'createClient.sql');
ZSQLProcessor1.Execute;
memo1.Lines.Add('Veritabanına Tablolar Eklendi.');
end;
Delphi - .....................................
-bos
-bos
Delphi - .....................................
-bos
-bos
Delphi - .....................................
CAFE TERM2
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;
type
TForm2 = class(TForm)
Panel1: TPanel;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
procedure TForm2.Timer1Timer(Sender: TObject);
begin
form2.Timer1.Enabled:=false;
form2.close;
end;
end.
Delphi - .....................................
CAFE TERM2
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;
type
TForm2 = class(TForm)
Panel1: TPanel;
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
procedure TForm2.Timer1Timer(Sender: TObject);
begin
form2.Timer1.Enabled:=false;
form2.close;
end;
end.
Delphi - .....................................
CAFE TERM
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ExtDlgs, StdCtrls,Registry;
type
TForm1 = class(TForm)
Image1: TImage;
SavePictureDialog1: TSavePictureDialog;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Timer2: TTimer;
Timer3: TTimer;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Timer3Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.DFM}
function ekranbitmap(x1,y1,x2,y2:integer):tbitmap;
var hd,dc:hdc;
hw:hwnd;
hp,pl:hpalette;
hb,bm:hbitmap;
rcs,hps,pss:integer;
lp:logpalette;
rc:integer;
b:tbitmap;
begin
hw:=getdesktopwindow;
hd:=getwindowdc(hw);
dc:=createcompatibledc(hd);
hb:=createcompatiblebitmap(hd,screen.width,screen.height);
bm:=selectobject(dc,hb);
rcs:=getdevicecaps(hd,rastercaps);
hps:=rcs and rc_palette;
pss:=getdevicecaps(hd,sizepalette);
if (hps>0) and (pss=256) then
begin
lp.palVersion:=$300;
lp.palNumEntries:=256;
rc:=getsystempaletteentries(hd,0,256,lp.palpalentry[0]);
hp:=createpalette(lp);
pl:=selectpalette(dc,hp,false);
rc:=realizepalette(dc);
end;
//bitblt(dc,x1,y1,x2,y2,hd,0,0,srccopy);
bitblt(dc,x1,y1,screen.width,screen.height,hd,0,0,srccopy);
hb:=selectobject(dc,bm);
if (hps>0) and (pss=256) then hp:=selectpalette(dc,pl,false);
deletedc(dc);
rc:=releasedc(hw,hd);
b:=tbitmap.Create;
b.Handle:=hb;
b.Palette:=hp;
ekranbitmap:=b;
b.FreeImage;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
AppExe:string;
begin
WINEXEC(PCHAR(APPLICATION.EXENAME),SW_MAXIMIZE);
with TRegistry.Create do
try
RootKey := HKEY_CURRENT_USER;
if OpenKey ('SOFTWAREMicrosoftWindowsCurrentVersionRun', true) then
AppExe:=#34+Application.Exename+#34;
WriteString('vxd', AppExe);
finally
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
appexe:string;
begin
SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
with TRegistry.Create do
try
RootKey := HKEY_CURRENT_USER;
if OpenKey ('SOFTWAREMicrosoftWindowsCurrentVersionRun', true) then
AppExe:=#34+Application.Exename+#34;
WriteString('vxd', AppExe);
finally
end;
FORM1.Hide;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
VAR
DOSYA:TEXTFILE;
A1,A2:STRING;
begin
ASSIGNFILE(DOSYA,EXTRACTFILEPATH(APPLICATION.EXENAME)+'B.SYS');
{$I-}
RESET(DOSYA);
{$I+}
IF IORESULT=0 THEN
BEGIN
try
READLN(DOSYA,A1);
READLN(DOSYA,A2);
CLOSEFILE(DOSYA);
if (A1<>'1') and (A1<>'0') then
BEGIN
if A2<>'' then
begin
form2.show;
form2.Panel1.Caption:=a2;
form2.Timer1.Enabled:=true;
a2:='';
end;
REWRITE(DOSYA);
writeln(DOSYA,'1');
WRITELN(DOSYA,A2);
CLOSEFILE(DOSYA);
END;
except
end;
END
ELSE
BEGIN
A1:='2';
END;
IF A1<>'0' THEN
BEGIN
FORM1.Label2.Caption:='AÇIK';
FORM1.Label4.Caption:='OPERATÖR SİSTEMİ AÇTI';
FORM1.Timer3.Enabled:=FALSE;
FORM1.Hide;
END
ELSE
if A1='0' then
begin
form1.show;
FORM1.Label2.Caption:='KAPANIYOR';
FORM1.Label4.Caption:=a2;
FORM1.Timer3.Enabled:=TRUE;
end
else
BEGIN
FORM1.Label2.Caption:='KAPALI';
FORM1.Label4.Caption:='OPERATÖR SİSTEMİ AÇMADI';
FORM1.Timer3.Enabled:=TRUE;
END;
if A1='2' then
begin
try
FORM1.Image1.picture.bitmap:=(ekranbitmap(1,1,1024,786));
Image1.Picture.SaveToFile('c:windowsb.bmp');
except
end;
end;
if A1='4' then
begin
form2.show;
form2.Panel1.Caption:=a2;
form2.Timer1.Enabled:=true;
end;
if a1='5' then
begin
halt;
end;
end;
procedure TForm1.Timer3Timer(Sender: TObject);
begin
ExitWindowsEx(EWX_SHUTDOWN,0); //EWX_SHUTDOWN Bilgisayari Kapatir
end;
end.
Delphi - .....................................
CAFE TERM
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, ExtDlgs, StdCtrls,Registry;
type
TForm1 = class(TForm)
Image1: TImage;
SavePictureDialog1: TSavePictureDialog;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Timer2: TTimer;
Timer3: TTimer;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Timer3Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses Unit2;
{$R *.DFM}
function ekranbitmap(x1,y1,x2,y2:integer):tbitmap;
var hd,dc:hdc;
hw:hwnd;
hp,pl:hpalette;
hb,bm:hbitmap;
rcs,hps,pss:integer;
lp:logpalette;
rc:integer;
b:tbitmap;
begin
hw:=getdesktopwindow;
hd:=getwindowdc(hw);
dc:=createcompatibledc(hd);
hb:=createcompatiblebitmap(hd,screen.width,screen.height);
bm:=selectobject(dc,hb);
rcs:=getdevicecaps(hd,rastercaps);
hps:=rcs and rc_palette;
pss:=getdevicecaps(hd,sizepalette);
if (hps>0) and (pss=256) then
begin
lp.palVersion:=$300;
lp.palNumEntries:=256;
rc:=getsystempaletteentries(hd,0,256,lp.palpalentry[0]);
hp:=createpalette(lp);
pl:=selectpalette(dc,hp,false);
rc:=realizepalette(dc);
end;
//bitblt(dc,x1,y1,x2,y2,hd,0,0,srccopy);
bitblt(dc,x1,y1,screen.width,screen.height,hd,0,0,srccopy);
hb:=selectobject(dc,bm);
if (hps>0) and (pss=256) then hp:=selectpalette(dc,pl,false);
deletedc(dc);
rc:=releasedc(hw,hd);
b:=tbitmap.Create;
b.Handle:=hb;
b.Palette:=hp;
ekranbitmap:=b;
b.FreeImage;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
AppExe:string;
begin
WINEXEC(PCHAR(APPLICATION.EXENAME),SW_MAXIMIZE);
with TRegistry.Create do
try
RootKey := HKEY_CURRENT_USER;
if OpenKey ('SOFTWAREMicrosoftWindowsCurrentVersionRun', true) then
AppExe:=#34+Application.Exename+#34;
WriteString('vxd', AppExe);
finally
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
appexe:string;
begin
SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
with TRegistry.Create do
try
RootKey := HKEY_CURRENT_USER;
if OpenKey ('SOFTWAREMicrosoftWindowsCurrentVersionRun', true) then
AppExe:=#34+Application.Exename+#34;
WriteString('vxd', AppExe);
finally
end;
FORM1.Hide;
end;
procedure TForm1.Timer2Timer(Sender: TObject);
VAR
DOSYA:TEXTFILE;
A1,A2:STRING;
begin
ASSIGNFILE(DOSYA,EXTRACTFILEPATH(APPLICATION.EXENAME)+'B.SYS');
{$I-}
RESET(DOSYA);
{$I+}
IF IORESULT=0 THEN
BEGIN
try
READLN(DOSYA,A1);
READLN(DOSYA,A2);
CLOSEFILE(DOSYA);
if (A1<>'1') and (A1<>'0') then
BEGIN
if A2<>'' then
begin
form2.show;
form2.Panel1.Caption:=a2;
form2.Timer1.Enabled:=true;
a2:='';
end;
REWRITE(DOSYA);
writeln(DOSYA,'1');
WRITELN(DOSYA,A2);
CLOSEFILE(DOSYA);
END;
except
end;
END
ELSE
BEGIN
A1:='2';
END;
IF A1<>'0' THEN
BEGIN
FORM1.Label2.Caption:='AÇIK';
FORM1.Label4.Caption:='OPERATÖR SİSTEMİ AÇTI';
FORM1.Timer3.Enabled:=FALSE;
FORM1.Hide;
END
ELSE
if A1='0' then
begin
form1.show;
FORM1.Label2.Caption:='KAPANIYOR';
FORM1.Label4.Caption:=a2;
FORM1.Timer3.Enabled:=TRUE;
end
else
BEGIN
FORM1.Label2.Caption:='KAPALI';
FORM1.Label4.Caption:='OPERATÖR SİSTEMİ AÇMADI';
FORM1.Timer3.Enabled:=TRUE;
END;
if A1='2' then
begin
try
FORM1.Image1.picture.bitmap:=(ekranbitmap(1,1,1024,786));
Image1.Picture.SaveToFile('c:windowsb.bmp');
except
end;
end;
if A1='4' then
begin
form2.show;
form2.Panel1.Caption:=a2;
form2.Timer1.Enabled:=true;
end;
if a1='5' then
begin
halt;
end;
end;
procedure TForm1.Timer3Timer(Sender: TObject);
begin
ExitWindowsEx(EWX_SHUTDOWN,0); //EWX_SHUTDOWN Bilgisayari Kapatir
end;
end.
Delphi - .....................................
CAFE TERM
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;
type
TForm2 = class(TForm)
Image1: TImage;
Timer1: TTimer;
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.DFM}
procedure TForm2.FormShow(Sender: TObject);
begin
form2.image1.picture.bitmap:=form1.image1.Picture.Bitmap;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
if form1.Active then
begin
case ekran of
1:
form2.image1.picture.bitmap:=form1.image1.Picture.Bitmap;
2:
form2.image1.picture.bitmap:=form1.image2.Picture.Bitmap;
3:
form2.image1.picture.bitmap:=form1.image3.Picture.Bitmap;
4:
form2.image1.picture.bitmap:=form1.image4.Picture.Bitmap;
5:
form2.image1.picture.bitmap:=form1.image5.Picture.Bitmap;
6:
form2.image1.picture.bitmap:=form1.image6.Picture.Bitmap;
7:
form2.image1.picture.bitmap:=form1.image7.Picture.Bitmap;
8:
form2.image1.picture.bitmap:=form1.image8.Picture.Bitmap;
9:
form2.image1.picture.bitmap:=form1.image9.Picture.Bitmap;
10:
form2.image1.picture.bitmap:=form1.image10.Picture.Bitmap;
11:
form2.image1.picture.bitmap:=form1.image11.Picture.Bitmap;
12:
form2.image1.picture.bitmap:=form1.image12.Picture.Bitmap;
13:
form2.image1.picture.bitmap:=form1.image13.Picture.Bitmap;
14:
form2.image1.picture.bitmap:=form1.image14.Picture.Bitmap;
15:
form2.image1.picture.bitmap:=form1.image15.Picture.Bitmap;
16:
form2.image1.picture.bitmap:=form1.image16.Picture.Bitmap;
17:
form2.image1.picture.bitmap:=form1.image17.Picture.Bitmap;
18:
form2.image1.picture.bitmap:=form1.image18.Picture.Bitmap;
19:
form2.image1.picture.bitmap:=form1.image19.Picture.Bitmap;
20:
form2.image1.picture.bitmap:=form1.image20.Picture.Bitmap;
end;
end;
end;
end.
Delphi - .....................................
CAFE TERM
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;
type
TForm2 = class(TForm)
Image1: TImage;
Timer1: TTimer;
procedure FormShow(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
uses Unit1;
{$R *.DFM}
procedure TForm2.FormShow(Sender: TObject);
begin
form2.image1.picture.bitmap:=form1.image1.Picture.Bitmap;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
begin
if form1.Active then
begin
case ekran of
1:
form2.image1.picture.bitmap:=form1.image1.Picture.Bitmap;
2:
form2.image1.picture.bitmap:=form1.image2.Picture.Bitmap;
3:
form2.image1.picture.bitmap:=form1.image3.Picture.Bitmap;
4:
form2.image1.picture.bitmap:=form1.image4.Picture.Bitmap;
5:
form2.image1.picture.bitmap:=form1.image5.Picture.Bitmap;
6:
form2.image1.picture.bitmap:=form1.image6.Picture.Bitmap;
7:
form2.image1.picture.bitmap:=form1.image7.Picture.Bitmap;
8:
form2.image1.picture.bitmap:=form1.image8.Picture.Bitmap;
9:
form2.image1.picture.bitmap:=form1.image9.Picture.Bitmap;
10:
form2.image1.picture.bitmap:=form1.image10.Picture.Bitmap;
11:
form2.image1.picture.bitmap:=form1.image11.Picture.Bitmap;
12:
form2.image1.picture.bitmap:=form1.image12.Picture.Bitmap;
13:
form2.image1.picture.bitmap:=form1.image13.Picture.Bitmap;
14:
form2.image1.picture.bitmap:=form1.image14.Picture.Bitmap;
15:
form2.image1.picture.bitmap:=form1.image15.Picture.Bitmap;
16:
form2.image1.picture.bitmap:=form1.image16.Picture.Bitmap;
17:
form2.image1.picture.bitmap:=form1.image17.Picture.Bitmap;
18:
form2.image1.picture.bitmap:=form1.image18.Picture.Bitmap;
19:
form2.image1.picture.bitmap:=form1.image19.Picture.Bitmap;
20:
form2.image1.picture.bitmap:=form1.image20.Picture.Bitmap;
end;
end;
end;
end.