Nedir? Neden? Nasıl?
Merhaba değerli arkadaşlar,
bu yazıda sizlerle birlikte posix uyumlu bir shell kullanarak basit SQLite işlemleri gerçekleştireceğiz. Malumunuz SQLite diğer SQL sağlayıcılarına kıyasla çok daha minimal bir yapıya sahiptir; ne bir daemon, ne bir sunucu, ne de karmaşık bir veri formatı barındırır. Tek başına çalışan bir binary olarak gelir ve aldığı parametrelerle veritabanını doğrudan ikili (binary) bir dosyaya yazar. Bunları örneklerle birlikte göreceğiz.
İşte tam da bu yüzden, özellikle minimal programlar yazarken SQLite’a ihtiyaç duymamız gayet olası.
Peki nerelerde işimize yarar?
Basit migrasyon işlemleri, varsayılan değer atamaları (defaulting), CI/CD süreçleri ya da arka planda otomasyon gerektiren ama göz önünde olmayan işlerde vakit ve efor kazanmak istediğimiz her yerde SQLite tercih edilebilir.
Ayrıca isterseniz, burada yapacağımız işlemleri sadece dash
değil; tercihinize göre bash
, fish
, hatta powershell
gibi farklı kabuklarla da gerçekleştirebilirsiniz.
Bugün, bu işin en sade ve genel kabul görmüş yöntemine beraber bakacağız.
Kurulum.
SQLite görece kolay bir kuruluma sahiptir, çalıştırılabilir ikili dosyayı path'e göndermek yeterli. Ben bu işlemleri Linux Mint dağıtımında yapacağım için Ubuntu kurulumunu yaptım 👇.
Debian / Ubuntu.
sudo apt update
sudo apt install -y sqlite3
Arch Linux
sudo pacman -Sy sqlite
Fedora
sudo dnf install sqlite
Windows (winget ile)
winget install --id=SQLite.sqlite --source=winget
Ilk Veritabanı.
artık SQLite kuruldu ve pathe gönderildi sqlite3 --version
yazdığımda 3.37.2 2022-01-06 ....
gibi bir çıktı alıyorum.
Şimdi boş bir veritabanı dosyası oluşturalım, bunun için;
> sqlite3 mydb.db " " ; echo $?
< 0
yazdığımızda 0 çıktısını aldıysak ve mydb.db dosyasını çalıştırma dizininde görebiliyorsak sorun yok demektir, file komutu ile
dosyayı kontrol edelim;
> file mydb.db
< mydb.db: empty
boş bir dosya oluşturmuş olduk şimdi headerı da ekleyelim.
> sqlite3 mydb.db "VACUUM;" ; echo $?
< 0
tekrardan file ile kontrol edelim;
> file mydb.db
< mydb.db: SQLite 3.x database, last written using SQLite version 30....
şeklinde devam eden bir çıktı var ise temel olarak yapmamız gereken işlemleri öğrendik demektir, sqlite komutunun ilk parametresi veritabanı dosyasıdır ikinci parametresi ise SQL kodudur, sqlite programının diğer SQL sağlayıcılarına göre daha operasyonel ifadesi ve daha az veri tipi vardır bu yüzden kafamız rahat. Artık script yazma kısmına geçebiliriz.
Kullanıcı tablosu.
Artık ilk scriptimizi yazalım, örnek senaryo üzerinden gidelim, kullanıcı tablomuz olsun kullanıcı adı, mail ve parola yer alsın, ön tanımlı kullanıcılarımız olsun. Öncelikle bize gerekli olacak fonksiyonları oluşturalım.
read_file() {
if [ ! -f "${1}" ] ; then
echo "file \"${1}\" not found."
return 1
fi
while IFS= read -r line ; do
echo "$line"
done < "${1}"
}
sqlite_comm() {
if [ "${#}" -lt 2 ] ; then
echo "sqlite_comm: required 2 parameters which is file and sql context, usage: sqlite_comm <file> <sql>"
return 1
fi
if ! command -v sqlite3 > /dev/null ; then
echo "sqlite not found in your path, please install or link it as sqlite3"
return 1
fi
sqlite3 "${1}" "${2}"
}
Basit bir sql çalıştırma kodumuz var dosyayı da sabit yapacağız şimdi.
DATABASE="${1:-mydb.db}"
sqlite_wrapper() {
_default_comm="VACUUM;"
sqlite_comm "${DATABASE}" "${1:-$_default_comm}"
}
Artık tabloları oluşturabiliriz, bunu yapmanın farklı yolları var elbette lakin biz raw sql şeklinde yazılan dosyaları arayacağız ve onları sqlite_wrapper
fonksiyonumuz ile birlikte çalıştıracağız, bunun için schemes
diye bir dizin ekliyoruz.
mkdir -p schemes
Artık proje yapımız şu şekilde:
.
├── sqlite.sh
├── scheme/
└── mydb.db
Şimdi kullanıcı tablomuzu scheme
dizininin altına oluşturalım ben user.sql
adında bir dosya oluşturacağım.
CREATE TABLE IF NOT EXISTS user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL,
email TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
created_at TEXT DEFAULT CURRENT_TIMESTAMP
);
Harika, artık .sql dosyalarımızı alıp çalıştıralım, burada unutmamamız gereken bir husus var sql kodunu type-safe yazmamız gerekli yoksa sqlite bize kızabilir, kızmazsa bu sefer projede sorunlar ortaya çıkabilir.
for s in "scheme/"*".sql" ; do
if [ -f "${s}" ] ; then
printf "${s##*/}...["
sqlite_wrapper "$(read_file ${s})"
echo "done]"
fi
done
Mükemmel, hadi ufak bir deneme yapalım bakalım nasıl gidiyoruz;
> ls
< mydb.db scheme sqlite.sh
> sh sqlite.sh
< user.sql...[done]
# Elle kontrol edelim
> sqlite3 "mydb.db" ".tables"
< user
Gibi bir çıktı alıyorsanız doğru yoldasınız demektir, artık defaulting yapabiliriz bunu shell scriptleri ile sağlayacağız, scripts
diye bir dizin oluşturalım.
mkdir -p scripts
, artık proje dizin yapımız şu şekilde gözükecek:
.
├── mydb.db
├── scheme
│ └── user.sql
├── scripts
└── sqlite.sh
Şimdi ise ön tanımlı kullanıcılar oluşturmak için dosyalarımızı ayarlayalım, ben admin ve ahmet isimli iki adet kullanıcı ekleyeceğim bu yüzden scripts
dizini içerisine ahmet_user.sh
ve admin_user.sh
ekliyorum, burada basit bir dosya formatı kullanmamız gerekli oldu her seferinde tüm scriptleri çalıştırmaktan ziyade gerekli olanları çalıştıracağız, _user.sh şeklinde bir yapı takip edelim, diğerlerinde daha farklı formatlar uydurabiliriz, şimdi defaulting için fonksiyonumuzu ekleyelim:
default_user() {
if [ "${#}" -lt 3 ] ; then
echo "default_user: need to specify 3 parameters: <username> <mail> <password>."
return 1
fi
printf "%s...[" "${1}"
if ! sqlite_comm "$DATABASE" "SELECT 1 FROM user WHERE username = '${1}' LIMIT 1;" | grep -q 1 > /dev/null ; then
sqlite_wrapper "INSERT INTO user (username, email, password) VALUES ('${1}', '${2}', '${3}');"
echo "added]"
else
echo "exists]"
fi
}
for d in "scripts/"*"_user.sh" ; do
( . "./${d}" )
done
Artık ön tanımlı kullanıcılarımızı ekleyebiliriz;
scripts/admin_user.sh
dosyamızın içeriği şu şekilde:
# File: scripts/admin_user.sh
default_user "admin" "admin@mail.domain" "1234"
scripts/ahmet_user.sh
dosyamızın içeriği şu şekilde:
# File: scripts/ahmet_user.sh
default_user "ahmet" "ahmet@mail.domain" "password"
Test zamanı geldi, projemizin son yapısı şu şekilde:
.
├── mydb.db
├── scheme
│ └── user.sql
├── scripts
│ ├── admin_user.sh
│ └── ahmet_user.sh
└── sqlite.sh
Hadi çalıştıralım.
> sh sqlite.sh
< user.sql...[done]
< admin...[added] # veya exists
< ahmet...[added] # veya exists
yukarıdaki gibi bir çıktı alıyorsak büyük ihtimalle başarılı olduk, emin olmak için veritabanını kontrol edelim:
> sqlite3 mydb.db "SELECT * FROM user;"
< 1|admin|admin@mail.domain|1234|2025-07-20 15:40:38
< 2|ahmet|ahmet@mail.domain|password|2025-07-20 15:40:38
Harika oldu! SQLite öğrenmek ve scriptin tam haline erişmek için kaynaklar kısmına bakabilirsiniz, hoşçakalın ☺️.
Top comments (0)