المتطلبات : خلفية بسيطة فى SQL
الآن SQLite أصبحت جزء شبه أساسي من مكتبات معظم اللغات ، وتوجد بشكل افتراضي في عدة بيئات تطويرية ، مثل rails حاليا
ما الذي يميز SQLite ؟
1- الحجم الصغير
2- لا تحتاج إلى خادم فهى Serverless Database Engine
3- لا تحتاج لإعدادات Zero-Configurations
SQLite مستخدمة فى عدد كبير جدا من التطبيقات ك backend Databse
http://www.sqlite.org/mostdeployed.html انا أفضل استخدم SQLite ويليها MySQL او Postgres وهذا ايضا يعتمد على حسب التطبيق ولكن SQLite will just cut it!
1- حمل
http://www.sqlite.org/download.html 2- ثبت ال gem كالتالى
طبعا بالصلاحيات المناسبة
3- اعمل import ل sqlite3 كالتالى
4- تصميم ال Class سيكون كالتالى
require 'sqlite3'
class PhonerLite
def initialize(dbname)
@dbname=dbname
@db=SQLite3::Database.new(dbname)
@db.results_as_hash=true #row['username']
create_table
end
def create_table
#Create table.
begin
sqlstmt="CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(55) UNIQUE, phonenum VARCHAR(55))"
@db.execute(sqlstmt)
#puts "Table Created.."
rescue Exception => e
#puts "Table exists."
puts e.message
#e.backtrace
end
end
def display_user(user)
puts "----------------------"
id=user['id'].to_s
puts "ID: #{id}"
puts "Name: #{user['username']}"
puts "Phone: #{user['phonenum']}"
puts "----------------------"
end
def find_user(username)
begin
@db.execute("SELECT * FROM users WHERE username LIKE '#{username}%'") do |user|
display_user(user)
end
rescue Exception => e
puts "Not found!"
end
end
def delete_user(username)
begin
delstmt="DELETE FROM users WHERE username='#{username}'"
@db.execute(delstmt)
puts "#{username} is deleted."
rescue Exception => e
puts e.message
end
end
def add_user(username, phonenum)
begin
@db.execute("INSERT INTO users (username, phonenum) VALUES(?,?)", username, phonenum)
puts "#{username} is added!"
rescue Exception => e
puts e.message
end
end
def select_all
selectstmt="SELECT * FROM users"
begin
@db.execute(selectstmt) do |rec|
display_user(rec)
end
rescue Exception => e
puts e.message
end
end
def delete_all
delstmt="DROP TABLE users"
@db.execute(delstmt)
#create new one
puts "Table Dropped!"
create_table
end
def update_user(username, newphone)
updatestmt="UPDATE users SET phonenum='#{newphone}' WHERE username='#{username}'"
begin
@db.execute(updatestmt)
puts "#{username} is updated!"
rescue Exception => e
puts e.message
end
end
end
للحصول على اتصال مع قاعدة بيانات SQLite نستخدم التالى
SQLite3::Database.new(DBNAME)
مثل مافعلنا فى ال Constructor كالتالى
def initialize(dbname)
@dbname=dbname
@db=SQLite3::Database.new(dbname)
@db.results_as_hash=true #row['username']
create_table
end
بننشئ instance variable بإسم db من ال SQLite3::Database class ونمرر له اسم قاعدة البيانات المطلوبة فى حال وجودها سيتم عمل اتصال وفى حال عدم وجودها سيتم إنشاءها
استخدام results_as_hash لإمكانية الوصول لل data كأنها فى hash مثلا بإستخدام اسم ال Column
record['username']
بمجرد ما يتم الإتصال سنحاول ننشئ جدول نخزن فيه البينات باستخدام ال create_table method المعرفة كالتالى
def create_table
#Create table.
begin
sqlstmt="CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username VARCHAR(55) UNIQUE, phonenum VARCHAR(55))"
@db.execute(sqlstmt)
#puts "Table Created.."
rescue Exception => e
puts "Table exists."
puts e.message
#e.backtrace
end
end
ال Database Connection Object اللى هو @db ليه امكانية تنفيذ أوامر على الجدول باستخدام ال execute method
هذا الجدول يتكون من 3 columns
1- هو ال id وهو PrimaryKey و بيزداد تلقائيا
2- ال username وهو VARCHAR(55) ولازم يكون UNIQUE
3- ال phonenum وهو VARCHAR(55) .. هل يمكن أن يكون تليفون من 55 رقم ؟! عادى اهل المريخ بعيدين شوية
نحاول ننفذ ال جملة ال SQL لإنشاء الجدول إذا لم يكن موجود ولكن فى حال وجوده سيقدح raise ل Exception ونحن نرشده بإن نطبع رسالة بإن الجدول موجود..
*اضافة مستخدم سيتم عن طريق add_user method المعرفة كالتالى
def add_user(username, phonenum)
begin
@db.execute("INSERT INTO users (username, phonenum) VALUES(?,?)", username, phonenum)
puts "#{username} is added!"
rescue Exception => e
puts e.message
end
end
عملية insert بسيطة جدا
لاحظ بأنه سيتم استبدل علمات الإستفهام ب المتغيرات username, phonenum
*عرض بيانات مستخدم
def display_user(user)
puts "----------------------"
id=user['id'].to_s
puts "ID: #{id}"
puts "Name: #{user['username']}"
puts "Phone: #{user['phonenum']}"
puts "----------------------"
end
لاحظ ان ال user الذي ستأخذه هذه الطريقة عبارة عن row من قاعدة البيانات
ال row متعرف كالتالى
تقدر توصل لقيمة كل column بالتعامل معاه كأنه hash بما إننا حددنا هكذا فى بداية انشاء ال Connection Object لو تذكر
@db.results_as_hash=true #record['username']
*الإستعلام عن مستخدمين
def find_user(username)
begin
@db.execute("SELECT * FROM users WHERE username LIKE '#{username}%'") do |user|
display_user(user)
end
rescue Exception => e
puts "Not found!"
end
end
جملة SELECT/LIKE بسيطة أليس كذلك ؟
هنا سيجلب كل ال rows التي فيها ال username column مشابه ل username
*حذف مستخدم
def delete_user(username)
begin
delstmt="DELETE FROM users WHERE username='#{username}'"
@db.execute(delstmt)
puts "#{username} is deleted."
rescue Exception => e
puts e.message
end
end
*تحديث بيانات مستخدم
def update_user(username, newphone)
updatestmt="UPDATE users SET phonenum='#{newphone}' WHERE username='#{username}'"
begin
@db.execute(updatestmt)
puts "#{username} is updated!"
rescue Exception => e
puts e.message
end
end
*حذف الكل
def delete_all
delstmt="DROP TABLE users"
@db.execute(delstmt)
#create new one
puts "Table Dropped!"
create_table
end
انا أرى انه من الاسرع انك تعمل DROP للجدول كله
*عرض الكل
def select_all
selectstmt="SELECT * FROM users"
begin
@db.execute(selectstmt) do |rec|
display_user(rec)
end
rescue Exception => e
puts e.message
end
end
جملة select بسيطة أليس كذلك ؟
اخيرا كل ما عليك هو استخدام ال class مثلا كالتالى
def get_user
print("Username: ")
return gets.chomp!
end
def get_phone
print("Phone: ")
return gets.chomp!
end
def entry_point
plite=PhonerLite.new("mydb")
mnu=<<M
1-Add User
2-Delete User
3-Update
4-View All
5-Clear
6-Quit
M
while true
puts mnu
opt=gets.chomp.to_i
if not (1..6).include?(opt)
puts "Unknown Option"
end
if opt==1
plite.add_user(get_user, get_phone)
elsif opt==2
plite.delete_user(get_user)
elsif opt==3
plite.update_user(get_user, get_phone)
elsif opt==4
plite.select_all
elsif opt==5
plite.delete_all
elsif opt==6
exit
end
end
end
entry_point
جميل، مبروك على انهائك التطبيق!