paint-brush
Git Hooks'u MySQL ile Kullanmakile@yuridanilov
4,711 okumalar
4,711 okumalar

Git Hooks'u MySQL ile Kullanmak

ile Yuri Danilov7m2023/09/30
Read on Terminal Reader
Read this story w/o Javascript

Çok uzun; Okumak

Test veritabanı oluştur Alma sonrası git hook oluştur Push'ta SQL komut dosyalarını yürütün

People Mentioned

Mention Thumbnail
featured image - Git Hooks'u MySQL ile Kullanmak
Yuri Danilov HackerNoon profile picture
0-item
1-item

Sürüm kontrol sistemleri ve özellikle Git, kod değişikliklerini izlemek, ekibinizle işbirliği yapmak ve kod tabanınızın kararlılığını sağlamak için temel araçlardır. Git öncelikle kaynak kodu için tasarlanmış olsa da sürüm kontrolü ve şema değişikliği yönetimi için MySQL veritabanlarıyla birlikte de kullanabilirsiniz.


Bu makalede, Git kancalarını kullanarak sürüm kontrolü için Git'i MySQL ile nasıl entegre edeceğimizi, bir kılavuz formatındaki belirli örneklerle keşfedeceğiz. Listelerde verilen tüm scriptler tamamen işlevsel ve eksiksizdir. Bunları test ortamınızda sırayla çoğaltabilirsiniz.


Öncelikle bir test veritabanı ve kullanıcı oluşturalım:

 create database testdb_remote; create user 'user_remote'@'localhost' identified WITH mysql_native_password by 'remote123'; grant all on testdb_remote.* to 'user_remote'@'localhost'; 


Test veritabanı oluşturma


Daha sonra uzak bir depo oluşturacağız. Bu herhangi bir uzak sunucudaki bir depo olabilir, ancak basitlik açısından onu yerel olarak oluşturacağız. Komutları yürütme kolaylığı için git bash kullanıyorum. Yerel makinemde zaten bir git klasörü var, bu yüzden onu kullanıyorum:

 cd /c/git mkdir testdb.remote cd testdb.remote git init --bare 


Uzak depo oluşturma

Ve uzak deponun kopyası olarak yerel bir depo oluşturun:

 cd /c/git git clone /c/git/testdb.remote testdb.local cd testdb.local git ls-files 


Yerel bir depo oluşturma


Depoda dosya yok; hadi bir tane oluşturalım ve değişikliklerimizi uzak depoya aktaralım:

 echo "Test DB repo" > readme.md git status git add . git commit -m "1st commit" git push 


İlk itme


Uzak havuzun içeriğini kontrol edelim:

 cd /c/git/testdb.remote git ls-tree --full-tree -r HEAD 


Uzak depodaki dosya


Uzak depoda örnekler içeren birkaç dosya içeren bir hooks klasörü vardır:

 ls -1 /c/git/testdb.remote/hooks 


Örnek kancalar


Kancalar, belirli olaylar meydana geldiğinde çalıştırılan komut dosyalarıdır. Git'in istemci tarafı ve sunucu tarafı kancaları vardır. İstemci tarafı kancaları, taahhüt etme ve birleştirme gibi işlemlerle tetiklenir. Sunucu tarafı kancaları, itilmiş taahhütlerin alınması gibi ağ işlemlerinde çalışır. Kancalar burada ayrıntılı olarak açıklanmaktadır. Mantığı uygulamak için farklı seçenekler vardır; Alma sonrası sunucu tarafı kancasının kullanımına bir örnek vereceğim.


Hooks klasöründe "post-receive" adında bir dosya oluşturmamız gerekiyor, bu normal bir bash betiğidir:

 #!/bin/sh while read oval nval ref do echo List of files changed in the commit: git diff --name-only $oval $nval done


Yukarıdaki komut dosyası, bir gönderim başarıyla tamamlandığında sunucuda yürütülecek ve değiştirilen dosyaların bir listesinin çıktısını verecektir. Readme.md dosyasına bir satır ekleyip değişiklikleri uzak depoya aktararak nasıl çalıştığını kontrol edelim:

 cd /c/git/testdb.local echo "New line" >> readme.md git add . git commit -m "Line added" git push 


Alma sonrası kanca komut dosyasını test etme


Git Push komutunu çalıştırırken çıktının artık remote: - bu, sunucuda yürütülen alma sonrası betiğinin çıktısıdır.

Temel değişikliklerden bahsetmişken, dosyalar eklenebilir, değiştirilebilir ve silinebilir. Bu değişikliklerin veritabanına nasıl uygulanacağı konusunda farklı yaklaşımlar kullanabilirsiniz:


  1. Veritabanında yalnızca yeni dosyalar eklerken değişiklik yapın. Bu durumda, belirli bir göreve ilişkin tüm değişiklikleri tek bir dosyaya kaydedebilirsiniz. Bu dosya, hata izleme sistemindeki görevin adını içerebilir. Bu, geliştirme sırasında pek uygun olmayabilir, ancak bu tür değişikliklerin üstesinden gelmek daha kolaydır.
  2. Her nesne (tablolar, prosedürler) için depoda ayrı bir dosya tutun ve dosyaları değiştirirken veya eklerken değişiklikleri veritabanına uygulayın.
  3. Daha kapsamlı bir yaklaşım, her görev (değişiklik isteği) için ayrı bir klasör oluşturmak ve belirli bir sürümün kurulumunun bir parçası olarak yürütülmesi gereken dosyaları bu klasöre yerleştirmektir. Aynı zamanda, dosyaların listesini ve kurulmaları gereken sırayı açıklayan ek bir dosya oluşturun. Bu yaklaşım daha esnektir ancak aynı zamanda hem geliştirme hem de boru hattının uygulanması açısından daha karmaşıktır.


İkinci seçeneği seçtiğinizi varsayalım, dolayısıyla eklenen veya değiştirilen dosyaları yürütmeniz gerekiyor. --diff-filter=AM parametresini ekleyerek bu tür dosyaları burada açıklandığı gibi filtreleyebiliriz:

 #!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: git diff --name-only --diff-filter=AM $oval $nval done


Birkaç dosya ekleyin ve ayrıca readme.md dosyasını tekrar değiştirin:

 echo "SELECT 1;" > test1.sql echo "SELECT 2;" > test2.sql echo "SELECT 3;" > test3.sql echo "New line 2" >> readme.md git add . git commit -m "New files" git push


Hook betiğinin çıktısı 4 dosya içerir:

Değiştirilen tüm dosyaların listesi


test1.sql ve readme.md dosyalarını düzenliyoruz, test2.sql'i siliyoruz ve başka bir dosya ekliyoruz:

 echo "SELECT 11;" > test1.sql echo "New line 2" >> readme.md rm test2.sql echo "SELECT 4;" > test4.sql git add . git commit -m "Modify, remove and add" git push


Yalnızca değiştirilen ve eklenen dosyalar görüntülenir:

Yalnızca eklenen veya değiştirilen dosyalar


Amacımız her başarılı gönderimden sonra SQL komut dosyalarını çalıştırmaktır, bu nedenle yalnızca bu türdeki dosyaları filtrelememiz gerekir; bizim durumumuzda hepsinin “.sql” uzantısına sahip olması şartını koyacağız. Filtrelemek için git diff komutuna -- "*.sql" parametresini ekleyin:

 #!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: git diff --name-only --diff-filter=AM $oval $nval -- "*.sql" done


Komut dosyalarını yürütmek için veritabanına da bağlanabilmemiz gerekir. Bunun için kimlik bilgileri oluşturup bağlantıyı test edeceğiz:

 mysql_config_editor set --login-path=testdb_remote --host=localhost --port=3306 --user=user_remote --password mysql --login-path=testdb_remote --database=testdb_remote 


MySQL için kredi oluşturma


“.sql” dosyalarında yineleme yapmak, her dosyayı yürütmek ve sonucu kontrol etmek için betiğimizi değiştirin. Ayrıca dosyaları gereken sırayla yürütmek için liste çıktısını da sıralamamız gerekir. Git show komutuyla SQL betiğinin içeriğini görüntülüyor ve bunu MySQL tarafından yürütülmek üzere kanaldan geçiriyoruz.

Değişken "$?" SQL betiği başarıyla yürütüldüyse 0 değerini, bir hata varsa başka bir değeri içerecektir:

 #!/bin/sh while read oval nval ref do echo List of files added or changed in the commit: for file in $(git diff --name-only --diff-filter=AM $oval $nval -- "*.sql" | sort); do git show master:${file} | mysql --login-path=testdb_remote --database=testdb_remote echo "FILE: ${file} - result $?" done done


Bir test daha yapın - önceden oluşturulmuş tüm ".sql" dosyalarını silin ve aşağıdakiler için komut dosyaları oluşturun:


  • tablo oluşturma
  • tabloya veri ekleme
  • tablodan veri almak için bir prosedür oluşturmak
  • hata içeren komut dosyası


Ayrıca dosyaların istenen yürütme sırasını sağlamak için her dosya adına bir önek (1_, 2_ vb.) eklememiz gerekir:

 rm *.sql echo "DB Initialization" >> readme.md echo " DROP TABLE IF EXISTS customers; CREATE TABLE customers ( id int UNSIGNED NOT NULL AUTO_INCREMENT, name varchar(255) DEFAULT NULL, PRIMARY KEY (id) ); " > 1_customers.sql echo " INSERT INTO customers (id, name) VALUES (1, 'John Doe'), (2, 'Jane Smith') AS new ON DUPLICATE KEY UPDATE customers.name = new.name; " > 2_customers_init.sql echo " DROP PROCEDURE IF EXISTS get_customer; DELIMITER $$ CREATE PROCEDURE get_customer(IN customer_id int UNSIGNED) BEGIN SELECT c.id, c.name FROM customers c WHERE c.id = customer_id; END $$ " > 3_get_customer.sql echo "SELECT FROM customers;" > 4_error_select.sql ls -1


Yani yürütülmesi gereken dört “.sql” dosyamız var:

Dosya listesi

Depoda değişiklikler yapıyoruz:

Yalnızca SQL dosyaları yürütülür


Ve git push gerçekleştirildiğinde dosyaların sırayla yürütüldüğünü ve her dosyanın yürütme sonucunun (MySQL komut çıkış kodu) görüntülendiğini görüyoruz. “4_error_select.sql” dosyası bir sözdizimi hatası içeriyor, dolayısıyla yürütülmesinin sonucu 1'dir.


Son olarak veritabanımızda nelerin bulunduğunu kontrol edelim:

 mysql --login-path=testdb_remote --database=testdb_remote show tables; call get_customer(1); call get_customer(2); 


Veritabanında oluşturulan nesneleri test etme


Gördüğünüz gibi tablo ve prosedür uzak veritabanında oluşturuldu. Prosedür başarıyla yürütülür ve verileri döndürür.


Kanca betiği çıktısının okunabilirliğini geliştirmek için MySQL CLI çıktısını bastırabilir veya onu bir günlük dosyasına yönlendirebilirsiniz. Ayrıca MySQL komutunun yürütülmesinin sonucunu analiz edebilir ve hook betiğine daha fazla mantık ekleyebilirsiniz.


Örneğin, bir test veritabanında SQL komut dosyalarını çalıştırabilir ve ardından üzerinde bazı testler çalıştırabilirsiniz ( burada anlattığım gibi). Testler test veritabanında başarıyla tamamlanırsa, üretim veritabanında SQL komut dosyalarını çalıştırın ve muhtemelen üzerinde bazı testler de çalıştırın.

Her adımın sonuçlarını analiz ederek herhangi bir konfigürasyonda işlem hatları oluşturabilirsiniz.


Elbette her yaklaşımın bir takım avantajları ve sınırlamaları vardır. İkinci yaklaşımda, komut dosyalarının yürütülme sırasını sağlamak gerekir çünkü örneğin bir tablo oluşturuluncaya kadar veri ekleyemeyiz. Ayrıca komut dosyalarını yeniden çalıştırabildiğinizden, yani oluşturulan nesnenin zaten veritabanında olduğu veya veritabanının zaten eklenecek verileri içerdiği durumlarda doğru şekilde çalışabildiğinizden emin olmanız gerekir.


Bir sürüm oluşturma sistemi kullanıldığında, geliştirme süreci biraz daha karmaşık hale gelir çünkü önceden belirlenmiş bir formattaki komut dosyalarındaki değişiklikleri ek olarak resmileştirmek gerekir. Ancak bir yükleme dosyası kullanarak bir miktar esneklik elde edebilirsiniz.


Açıklanan tekniğin temel avantajı, veritabanında sürüm oluşturmanın çok az çabayla uygulanmasının yanı sıra CI/CD işlem hatlarını uygulama yeteneğidir.

Bunun sizin için yararlı olup olmayacağını değerlendirmek için kendinize şu soruyu sorarak başlayabilirsiniz: Doğrudan üretimde ne sıklıkla kod yazıyorsunuz?