Author Topic: SQLite  (Read 627 times)

Ahmed Youssef

  • Helping Freak
  • Administrator
  • Active Member
  • *****
  • Posts: 242
    • View Profile
    • WWW
    • Email
SQLite
« on: October 26, 2008, 05:55:31 PM »


المتطلبات : خلفية بسيطة فى 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 كالتالى
Code: [Select]
gem install sqlite3-ruby 

طبعا بالصلاحيات المناسبة
3- اعمل import ل sqlite3 كالتالى
Code: [Select]
require 'sqlite3' 

4- تصميم ال Class سيكون كالتالى
Code: [Select]
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 نستخدم التالى
Code: [Select]
SQLite3::Database.new(DBNAME) 

مثل مافعلنا فى ال Constructor كالتالى
Code: [Select]
  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 المعرفة كالتالى
Code: [Select]
  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 رقم ؟! عادى اهل المريخ بعيدين شوية :D

نحاول ننفذ ال جملة ال SQL لإنشاء الجدول إذا لم يكن موجود ولكن فى حال وجوده سيقدح raise ل Exception ونحن نرشده بإن نطبع رسالة بإن الجدول موجود..

*اضافة مستخدم سيتم عن طريق add_user method المعرفة كالتالى
Code: [Select]
  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

*عرض بيانات مستخدم
Code: [Select]
  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 متعرف كالتالى
Code: [Select]
id | username | phonenum 

تقدر توصل لقيمة كل column بالتعامل معاه كأنه hash بما إننا حددنا هكذا فى بداية انشاء ال Connection Object لو تذكر
Code: [Select]
    @db.results_as_hash=true #record['username'] 


*الإستعلام عن مستخدمين
Code: [Select]
  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

*حذف مستخدم
Code: [Select]
  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

*تحديث بيانات مستخدم
Code: [Select]
  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

*حذف الكل
Code: [Select]
  def delete_all 
    delstmt="DROP TABLE users"
    @db.execute(delstmt)
    #create new one
    puts "Table Dropped!"
    create_table
  end

 
انا أرى انه من الاسرع انك تعمل DROP للجدول كله :)

*عرض الكل
Code: [Select]
  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 مثلا كالتالى
Code: [Select]
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

جميل،  مبروك على انهائك التطبيق!

Logged

Life is just a chance to grow a soul. - A. Powell
Weblog: http://ahmedyoussef.wordpress.com/