الكورس

Advertisements

HTML5 IndexedDB API


IndexedDB هي طريقة يمكنك من خلالها تخزين البيانات باستمرار داخل متصفح المستخدم.


 

مثال – IndexedDB

IndexedDB Example


 


 

ما هو IndexedDB؟

 

indexedDB هو مفهوم HTML5 جديد لتخزين البيانات داخل متصفح المستخدم ومفيد للتطبيقات التي تتطلب تخزين كمية كبيرة من البيانات.

يمكن تشغيل هذه التطبيقات بكفاءة أكبر وتحميل أسرع.

أعلن W3C أن قاعدة بيانات الويب SQL هي مواصفات تخزين محلية مهملة ، لذا يجب ألا يستخدم مطور الويب هذه التقنية بعد الآن، indexeddb هو بديل لقاعدة بيانات الويب SQL وأكثر فاعلية من التقنيات القديمة.

 

النمط الأساسي – IndexedDB

 

النمط الأساسي الذي تشجعه IndexedDB هو ما يلي:

  1. فتح قاعدة بيانات (open Database).
  2. تكوين كائن لتخزين العناصر في قاعدة البيانات (Create an object).
  3. إضافة البيانات أو استرجاعها (adding/retrieving).
  4. الإنتظار حتى تكتمل العملية من خلال الاستماع إلى النوع الصحيح من أحداث DOM.

 


 

استخدام نسخة تجريبية من IndexedDB

 

قبل الدخول في IndexedDB، إذا كنت ترغب في اختبار الكود الخاص بك في المتصفحات التي لا تزال تستخدم بادئات التنفيذ (prefix)، يمكنك استخدام الكود التالي:

// you should include the prefixes of implementations you want to test!
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"};
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

// Test Browser Support 
if (!window.indexedDB) {
    window.alert("Your browser doesn't support a version of IndexedDB.");
}
السطر الثالث يكون ضروريًا فقط إذا كان مطلوبًا لدعم ثوابت الكائن للمتصفحات القديمة.

 

فتح أو إنشاء قاعدة بيانات – IndexedDB

 

لفتح أو إنشاء قاعدة بيانات بإستخدام IndexedDB، يمكنك القيام بذلك كالتالى:

// Open our database
var request = window.indexedDB.open("testDB", 3);

توضيح الكود السابق:

  • يؤدي استدعاء الدالة ()open إلى إرجاع كائن IDBOpenDBRequest مع نتيجة (success) أو قيمة (error) تعالجها كحدث.
  • المعلمة (parameter) الأولى هى إسم قاعدة البيانات.
  • المعلمة (parameter) الثانية هي إصدار قاعدة البيانات.

 

لا يفتح الطلب open قاعدة البيانات أو يبدأ الـ transaction مباشرًا.
إذا لم تكن قاعدة البيانات موجودة بالفعل ، فسيتم إنشاؤها من خلال طريقة open، ثم يتم تشغيل حدث جديد وإنشاء مخطط قاعدة البيانات في المعالج لهذا الحدث.

 

إنشاء معالجات – Handlers

 

أول شيء تريد القيام به مع جميع الطلبات (requests) تقريبًا هو إضافة معالجات النجاح والأخطاء (success & error handlers)، كالتالى:

// If Exist Errors!
request.onerror = function(event) {
  // Do Any thing with request.errorCode!
};

// If Not Exist Errors (mean => success)!
request.onsuccess = function(event) {
  // Do Any thing with request.result!
};

توضيح الكود السابق:

  • دالة ()onerror يتم إستدعاؤها عند وجود أى مشكلة (أي حدث DOM يتم تعيين خاصية type على “error“) عند الطلب.
  • دالة ()onsuccess يتم إستدعاؤها عند نجاح العملية (أي حدث DOM يتم تعيين خاصية type على “success“) عند الطلب.

 

💡 إذا تم إنشاء قاعدة بيانات، وتلقيت حدثًا ناجحًا (success) لبدء رد الاتصال بنجاح؛ فى هذا الوقت تم إنشاء طلب باستدعاء ()indexedDB.open ، لذا فإن request.result هو طلب IDBDatabase، ولحفظ ذلك لوقت لاحق، سيكون كودك كالتالى:

var request = indexedDB.open("testDB");
var db;

request.onerror = function(event) {
  window.alert("Something get error!");
};

request.onsuccess = function(event) {
  db = event.target.result;
};

 

معالجات أخطاء – Handling Errors

 

إذا كنت تريد تجنب إضافة معالجات الأخطاء إلى كل طلب ، فيمكنك بدلاً من ذلك إضافة معالج خطأ واحد على كائن قاعدة البيانات ، كالتالى:

db.onerror = function(event) {
  // Error handler for all errors in database
  window.alert("Database error is: " + event.target.errorCode);
};

 

هيكل قاعدة البيانات – IndexedDB

 

لهيكلة قاعدة البيانات يستخدم IndexedDB مخازن الكائنات بدلاً من الجداول ، ويمكن أن تحتوي قاعدة البيانات الفردية على أي عدد من مخازن العناصر.

مثال لتوضيح بعض المفاهيم:

// Users Data
const usersData = [
  { id: "10", username: "Mohamed", email: "mohamed2020@gmail.com", gender: "Male" },
  { id: "20", username: "Noor", email: "noor2004@gmail.com", gender: "Female" }
];

الآن سنقوم بإنشاء قاعدة بيانات بإستخدام (IndexedDB) لتخزين البيانات:

var dbName = "users";
var request = indexedDB.open(dbName, 3);

request.onerror = function(event) {
  // Handle errors
  window.alert("Database error is: " + event.target.errorCode);
};

request.onupgradeneeded = function(event) {
  var db = event.target.result;

  // Create an objectStore to hold information about our users!
  // "id" => Is unique
  var objectStore = db.createObjectStore("users", { keyPath: "id" });

  // Create an index to search users by username!
  // "username" => Not unique
  objectStore.createIndex("username", "username", { unique: false });

  // Create an index to search users by email!
  // "email" => Is unique
  objectStore.createIndex("email", "email", { unique: true });

  // Create an index to search users by gender!
  // "gender" => Not unique
  objectStore.createIndex("gender", "gender", { unique: false });

  objectStore.transaction.oncomplete = function(event) {
    // Store values in objectStore.
    var userObjectStore = db.transaction("users", "readwrite").objectStore("users");
    userData.forEach(function(user) {
      user.ObjectStore.add(user);
    });
  };
};

توضيح الكود السابق:

  • فى البداية تم إنشاء متغير (dbName) لتخزين إسم قاعدة البيانات، ثم إنشاء متغير أخر لتخزين الطلب (request).
  • بعد ذلك أنشأنا دالة لمعالجة جميع الأخطاء فى قاعدة البيانات (فى حالة حدوث خطأ).
  • نستخدم حدث onupgradeneeded لتغيير بنية قاعدة البيانات (إنشاء وحذف مخازن الكائنات).
  • نستخدم طريقة ()createObjectStore لإنشاء مخازن الكائنات، وتقبل معلمتين إسم المخزن وكائن transaction (إختيارى)، في المثال السابق، طلبنا مخزن كائنات يسمى “users” وحددنا keyPath ، وهي الخاصية التي تجعل الكائن الفردي في المتجر فريدًا (أى unique) والخاصية في هذا المثال هي “id” لأن رقم المعرف مضمون (لأنه دائمًا فريدًا فى قواعد البيانات).
  • ثم طلبنا أيضًا index (فهرس) باسم “username” يبحث في خاصية name للكائنات المخزنة.
  • تأخذ طريقة ()createObjectStore و ()createIndex كائن options (اختياريًا) يعمل على تحسين نوع الفهرس الذي تريد إنشاءة.
  • تستمر عملية إضافة الكائنات التي ليس لها خاصية name بالنجاح ، ولكن لن تظهر الكائنات في فهرس “name“.
  • الآن يمكنك استرداد كائنات المستخدم المخزنة باستخدام id من مخزن العناصر مباشرة ، أو باستخدام إما (name أو email أو gender) عن طريق الفهرس (index).

 

فى طريقة ()createObjectStore على الرغم من أن المعلمة الثانية (كائن الـ transaction) اختياري إلا أنه مهم جدًا ، لأنه يتيح لك تحديد خصائص اختيارية مهمة وتنقيح نوع تخزين العناصر الذي تريد تكوينه.
يجب أن يكون “id” موجودًا في كل كائن يتم تخزينه في objectStore.
استخدم الـ transaction عند اكتمالها بإستخدام حدث oncomplete للتأكد من إنتهاء إنشاء كائن التخزين (objectStore) قبل إضافة البيانات إليه.

 

إضافة بيانات – Add data

 

بعد إنشاء قاعدة بيانات، سوف تحتاج إلى إضافة بيانات إلى قاعدة البيانات، وللقيام بذلك إتبع ما يلى:

function addUser() {
  var request = db.transaction(["users"], "readwrite").objectStore("users")
  .add({ id: "30", username: "Esam", email: "esam1980@yahoo.com", gender: "Male"});

  request.onsuccess = function(event) {
    alert("Done! New user added to your database.");
  };

  request.onerror = function(event) {
    alert("Something get wrong!");
  }
}

 

جلب البيانات – Retrieve Data

 

يمكننا استرداد أو جلب البيانات من قاعدة البيانات باستخدام ()get :

function read() {
   var transaction = db.transaction(["users"]);
   var objectStore = transaction.objectStore("users");
   var request = objectStore.get("30");
   
   request.onerror = function(event) {
      alert("Oops! Unable to retrieve data from database!");
   };
   
   request.onsuccess = function(event) {
      
      if(request.result) {
         alert("Username: " + request.result.username + " & gender: " + request.result.gender + " & Email: " + request.result.email);
      } else {
         alert("Not found in your database!");  
      }

   };
}

 

إزالة البيانات – Remove Data

 

يمكننا إزالة البيانات من قاعدة البيانات بإستخدام ()remove، كالتالى:

function remove() {
   var request = db.transaction(["users"], "readwrite").objectStore("users")
   .delete("30");
   
   request.onsuccess = function(event) {
      alert("Done! User Removed from your database!");
   };
}
</s

 

مثال كامل – IndexedDB

HTML Code:

<!DOCTYPE html>

<html>
   <head>
      <meta charset="UTF-8" />
      <title>IndexedDB Example</title>
   </head>
   
   <body>
      <button onclick = "read()">Read Data</button>
      <button onclick = "readAll()">Read All Data</button>
      <button onclick = "add()">Add Data</button>
      <button onclick = "remove()">Remove Data</button>
   </body>
</html>

JavaScript Code:

// Prefixes of implementations you want to test!
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {
    READ_WRITE: "readwrite"
};
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;


// Test Browser Support 
if (!window.indexedDB) {
    window.alert("Your browser doesn't support a version of IndexedDB.");
}

const usersData = [{
    id: "10",
    username: "Esam",
    email: "esam2020@gmail.com",
    gender: "Male"
}, {
    id: "20",
    username: "Noor",
    email: "noor2004@gmail.com",
    gender: "Female"
}];

var db;
var dbName = "users";
var req = window.indexedDB.open(dbName, 3);

req.onerror = function(evn) {
    // Handle errors
    console.log("Database error: " + evn.target.errorCode);
};

req.onsuccess = function(evn) {
    db = req.result;
    console.log("Success: " + db);
};

req.onupgradeneeded = function(evn) {
    var db = evn.target.result;
    var objectStore = db.createObjectStore("users", {
        keyPath: "id"
    });

    for (var i in usersData) {
        objectStore.add(usersData[i]);
    }
}


function read() {
    var transaction = db.transaction(["users"]);
    var objectStore = transaction.objectStore("users");
    var req = objectStore.get("10");

    req.onerror = function(evn) {
        alert("Oops! Unable to retrieve data from database!");
    };

    req.onsuccess = function(evn) {

        if (req.result) {
            alert("Username: " + req.result.username + " & gender: " + req.result.gender + " & Email: " + req.result.email);
        } else {
            alert("Not found records in your database!");
        }

    };
}


function readAll() {
    var objectStore = db.transaction("users").objectStore("users");

    objectStore.openCursor().onsuccess = function(evn) {
        var cursor = evn.target.result;

        if (cursor) {
            alert("Name id: " + cursor.key + " & Username: " + cursor.value.username + " & Gender is: " + cursor.value.gender + " & Email is: " + cursor.value.email);
            cursor.continue();
        } else {
            alert("Not found other entries in database!o more entries!");
        }
    };
}

function add() {
    var req = db.transaction(["users"], "readwrite").objectStore("users")
        .add({
            id: "40",
            username: "Mohamed",
            email: "mohamed@yahoo.com",
            gender: "Male"
        });

    req.onsuccess = function(evn) {
        alert("Done! New user 'Mohamed' added to your database.");
    };

    req.onerror = function(evn) {
        alert("Unable to add data, because 'Mohamed' is already exist in your database!");
    }
}


function remove() {
    var req = db.transaction(["users"], "readwrite").objectStore("users")
        .delete("40");

    req.onsuccess = function(evn) {
        alert("Done! User 'Mohamed' Removed from your database!");
    };
}

IndexedDB Example

لا يمكن لمحتوى نافذة الطرف الثالث (مثل محتوى iframe) الوصول إلى IndexedDB إذا تم تعيين المتصفح على عدم قبول ملفات تعريف ارتباط الطرف الثالث مطلقًا.

 

دعم المتصفحات – IndexedDB

 

firefox - الباشمبرمجCHROME - الباشمبرمجIE - الباشمبرمجsafari - الباشمبرمجopera - الباشمبرمج
مدعوممدعوممدعوممدعوممدعوم


الإبلاغ عن خطأ

×

إذا وجد خطأ وتريد الإبلاغ عن هذا الخطأ، أو إذا كنت تريد تقديم اقتراح على شىء معين، فلا تتردد في إرسال بريد إلكتروني إلينا:

info@albashmoparmeg.com

شكرًا لك على مساعدتك لنا!

Advertisements