التخزين في Cordova

من موسوعة حسوب
مراجعة 00:57، 19 نوفمبر 2018 بواسطة محمد-بغات (نقاش | مساهمات) (أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE: التخزين في Cordova}}</noinclude> تصنيف: Cordova تتوفر العديد من واجهات برمجة التطبيقات...')
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

 تتوفر العديد من واجهات برمجة التطبيقات (APIs) المتخصصة للتخزين لأجل لتطبيقات Cordova. راجع html5rocks storage overview و tutorial لمزيد من المعلومات والأمثلة.

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

التخزين المحلي

يوفر التخزين المحلي (Local storage) تخزينًا بسيطًا ومتزامنًا لبيانات على شكل أزواج مفتاح/قيمة (key/value)، هذه المقاربة مدعومة من تقديمات WebView على جميع منصات كوردوفا.

ملخص الاستخدام

يمكن الوصول إلى ميزة التخزين المحلي عبر window.localStorage. تعرض الشيفرة التالية أهم توابع الكائن Storage المعاد:

var storage = window.localStorage;
var value = storage.getItem(key); // Pass a key name to get its value.
storage.setItem(key, value) // Pass a key name and its value to add or update that key.
storage.removeItem(key) // Pass a key name to remove that key from storage.‎

لمزيد من المعلومات، راجع: W3C: Spec MDN: Storage API MDN: Storage Guide

المزايا

  • مدعومة من جميع منصات Cordova.
  • الواجهة البرمجية البسيطة والمتزامنة تعني أنها سهلة الاستخدام.

العيوب

  • تخزن السلاسل النصية فقط، لذلك، فالبيانات المعقدة يجب أن تُسَلسَل (serialized)، هذا يعني أنه لا يمكن تخزين إلا البيانات القابلة للسَّلسَّلة.
  • أداؤها سيء مع البيانات ذات الأحجام الكبيرة. بالخصوص:
  • عدم وجود فهرسة يعني أن عمليات البحث تتطلب تكرار اليدوي على جميع البيانات.
  • تخزين البيانات الكبيرة أو المعقدة بطيء بسبب الحاجة إلى السلسلة/الفك (serialize/de-serialize).
  • الواجهة البرمجية المتزامنة تقنضي أن الاستدعاءات ستقفل (lock) واجهة المستخدم.
  • محدودية المساحة الإجمالية للتخزين (حوالي 5MB عادة).
  • تخزن منصة iOS بيانات localStorage في موقع قد يتم تنظيفه من قبل نظام التشغيل عند الحاجة لتحرير المساحة.

WebSQL

يوفر WebSQL واجهة برمجية لتخزين البيانات في قاعدة بيانات مُهيكلة، والتي يمكن الاستعلام منها باستخدام صيغ SQL عادية (على وجه التحديد، SQLite). وهكذا فهي توفر إمكانية الاستفادة من قوة (وتعقيد) SQL.

هذه الميزة مدعومة من WebView على منصات Cordova التالية:

  • أندرويد
  • iOS

ملخص الاستخدام

المدخل إلى إنشاء أو فتح قاعدة بيانات هي عبر التابع window.openDatabase():

var db = window.openDatabase(name, version, displayName, estimatedSize);‎
  • name (سلسلة نصية): يمثل الاسم المميز لقاعدة البيانات، الذي ستُخزّن به على القرص.
  • version (سلسلة نصية): إصدار قاعدة البيانات.
  • displayName (سلسلة نصية): اسم مبسط ومفهوم لقاعدة البيانات، والذي سيستخدمه النظام إن كان بحاجة إلى وصف قاعدة بياناتك للمستخدم (على سبيل المثال، عند الاستئذان لزيادة حجم قاعدة البيانات).
  • estimatedSize (عدد): الحجم الأقصى المتوقع لقاعدة البيانات، بالبايت (byte). مع تزايد حجم قاعدة البيانات، قد يُطالب المستخدم بالحصول على إذن. إذا اخترت قيمة مناسبة، فمن المحتمل أن يُطالب المستخدم بالإذن بمعدل أقل.

يوفر كائن Database المُعاد التابع transaction() (أو readTransaction() لتحسين أداء معاملَات القراءة فقط [read-only]) التي تمكنك من إنشاء معاملات آمنة:

var db = window.openDatabase(name, version, displayName, estimatedSize);
db.transaction(function (tx) {
    tx.executeSql(sqlStatement, valueArray, function (tx, result) {
        console.log(result);
    }, function (error) {
        console.log(error);
    });
});‎

لمزيد من المعلومات، راجع: W3C: Spec

للحصول على مدخل تقديمي جيد للغة SQL، راجع: w3schools: Introduction to SQL

إصدارات قواعد البيانات

عند فتح قاعدة بيانات قائمة، إن كان الإصدار المحدد لا يتطابق مع إصدار قاعدة البيانات، فسيُطلق استثناء، ولن تُفتح قاعدة البيانات. لكن إن قمت بتحديد سلسلة فارغة لأجل الإصدار، فستُفتح قاعدة البيانات بغض النظر عن إصدارها الحالي (ويمكنك الاستعلام عن الإصدار الحالي عبر db.version). لكن كن حذرًا، لأنه في حال إنشاء قاعدة البيانات، فستعيّن سلسلة فارغة لإصدارها.

المزايا

  • أداء جيد - يمكن فهرسة البيانات لتسريع عمليات البحث، كما أنّ الواجهة البرمجية غير المتزامنة تعني أنها لا تعطل (lock) واجهة المستخدم.
  • المتانة النانجة عن استخدام نموذج قاعدة بيانات معاملاتي (transactional database model).
  • دعم الإصدارات (Support for versioning).

العيوب

  • لا تدعمها كل منصات Cordova.
  • أكثر تعقيدا من

LocalStorage أو IndexedDB.

  • الواجهة البرمجية مُتجاوزة. من المستبعد أن تُدعم على المنصات التي لا تدعمها حاليًا، وقد تُزال من المنصات التي تدعمها مستقبلا.
  • تفرض بنية جامدة، والتي يتوجب تعريفها مقدمًا.
  • محدودية مساحة التخزين (حوالي 5MB في العادة).

IndexedDB

الهدف من الواجهة البرمجية IndexedDB هو دمج نقاط قوة في الواجهتين البرمجيتين LocalStorage و WebSQL، مع تجنب نقاط ضعفهما. تتيح لك IndexedDB تخزين كائنات جافا سكريبت (بشرط أن تكون مدعومة من قبل structured clone algorithm)، مع فهرستها بمفتاح. كما توفر بعض فوائد جداول SQL، دون تقييد البنية أو الحاجة إلى تعريفها في المقدمة.

توفر IndexedDB نموذج بيانات بسيط وسهل الفهم، تمامًا مثل LocalStorage. ولكن بخلاف LocalStorage، فيمكنك إنشاء عدة قواعد بيانات، مع عدة مخازن (stores) في كل قاعدة بيانات، كما تحسن واجهتها البرمجية غير المتزامنة والبحث المفهرس أداءها.

IndexedDB مدعومة من WebView على منصات Cordova التالية:

  • ويندوز (مع بعض القيود)
  • أندرويد (4.4 فما فوق)

قيود ويندوز

دعم منصة ويندوز لـ IndexedDB غير كامل. على سبيل المثال، يفتقر إلى الميزات التالية:

  • غير متوفر في عاملات الشبكة (web workers).
  • لا تدعم المفاتيح المسارية في المصفوفات (array keyPaths).
  • لا تدعم المفاتيح في المصفوفات (array keys).
  • لا تدعم البحث عن الكائنات عبر فهرس مركب.

ملخص الاستخدام

  • تعمل IndexedDB بشكل غير متزامن - إذ تطلب عملية معينة على قاعدة بيانات، ثم يتم إعلامك بالنتيجة عبر حدث دوم (DOM event).
  • عند تقوم بتقديم طلب، ستحصل على كائن طلب (request object)، والذي يوفر الحدثين onerror و onsuccess، بالإضافة إلى خصائص مثل result و error و readyState.

توضح الشيفرة التالية بعضالاستخدامات البسيطة لـ IndexedDB:

var db;
var databaseName = 'myDB';
var databaseVersion = 1;
var openRequest = window.indexedDB.open(databaseName, databaseVersion);
openRequest.onerror = function (event) {
    console.log(openRequest.errorCode);
};
openRequest.onsuccess = function (event) {
    // Database is open and initialized - we're good to proceed.
    db = openRequest.result;
    displayData();
};
openRequest.onupgradeneeded = function (event) {
    // This is either a newly created database, or a new version number
    // has been submitted to the open() call.
    var db = event.target.result;
    db.onerror = function () {
        console.log(db.errorCode);
    };
    // Create an object store and indexes. A key is a data value used to organize
    // and retrieve values in the object store. The keyPath option identifies where
    // the key is stored. If a key path is specified, the store can only contain
    // JavaScript objects, and each object stored must have a property with the
    // same name as the key path (unless the autoIncrement option is true).
    var store = db.createObjectStore('customers', { keyPath: 'customerId' });
    // Define the indexes we want to use. Objects we add to the store don't need
    // to contain these properties, but they will only appear in the specified
    // index of they do.
    //
    // syntax: store.createIndex(indexName, keyPath[, parameters]);
    //
    // All these values could have duplicates, so set unique to false
    store.createIndex('firstName', 'firstName', { unique: false });
    store.createIndex('lastName', 'lastName', { unique: false });
    store.createIndex('street', 'street', { unique: false });
    store.createIndex('city', 'city', { unique: false });
    store.createIndex('zipCode', 'zipCode', { unique: false });
    store.createIndex('country', 'country', { unique: false });
    // Once the store is created, populate it
    store.transaction.oncomplete = function (event) {
        // The transaction method takes an array of the names of object stores
        // and indexes that will be in the scope of the transaction (or a single
        // string to access a single object store). The transaction will be
        // read-only unless the optional 'readwrite' parameter is specified.
        // It returns a transaction object, which provides an objectStore method
        // to access one of the object stores that are in the scope of this
        //transaction.
        var customerStore = db.transaction('customers', 'readwrite').objectStore('customers');
        customers.forEach(function (customer) {
            customerStore.add(customer);
        });
    };
};
function displayData() {
}‎

لمزيد من المعلومات، راجع: W3C: Spec MDN: IndexedDB API Reference MDN: IndexedDB Basic Concepts MDN: Using IndexedDB Guide

المزايا

  • الأداء الجيد - لن تعيق الواجهة البرمجية غير المتزامنة واجهة المستخدم، كما ستوفر الفهرسة أداءً جيدًا في عمليات البحث.
  • نموذج بيانات بسيط أسهل في التعلم من SQL.
  • بنية أكثر مرونة من WebSQL.
  • يوفر تعدد قواعد البيانات ومخازن الكائنات (object stores) بنية أكثر تفصيلا من LocalStorage.
  • المتانة نتيجة استخدام نموذج بيانات معاملاتي (transactional database model).
  • دعم الإصدارات.

العيوب

  • غير مدعومة على منصة iOS.
  • واجهة برمجية معقدة تحتوي على استدعاءات متشعبة.
  • محدودية مساحة التخزين (حوالي 5MB في العادة).

إضافات

FileSystem API

كانت FileSystem API جزءًا من مواصفات W3C، والتي تم تتزيلها من قبل Chrome دون بقية المتصفحات. توفر هذه الإضافة واجهات برمجية لتخزين واسترجاع البيانات على نظام الملفات المحلي (يمكنك معرفة المزيد من المقال المفصل html5rocks article). على الرغم من أن الواجهة البرمجية غير مدعومة من قبل أي منصة من منصات كوردوفا، يوفر File plugin تقديما شاملاً ومتوفرًا على جميع منصات Cordova.

إضافة SQLite

توفر الإضافة SQLite واجهة برمجية شبه مطابقة لواجهة WebSQL الموضحة أعلاه. الاختلافات الرئيسية هي:

  • مدعومة من منصة ويندوز.
  • ليس لها فعليا قيود على الحجم.

كما أنها متاحة في التشكيلات التالية:

  • cordova-sqlite-storage - الإصدار الأساسي الذي يتضمن تقديمها (implementation) الخاص لـ sqlite3. وهو مدعوم من منصات iOS و أندرويد وويندوز.
  • cordova-sqlite-ext - إصدار موسع مع ميزات إضافية بما في ذلك دعم التعبيرات النمطية (REGEXP) على أندرويد و iOS.
  • cordova-sqlite-evfree - مماثلة ل

Cordova-sqlite-ext ولكن مع تحسين التعامل مع الذاكرة. متاحة تحت رخصة GPL v3 أو تحت رخصة تجارية.

إضافات أخرى

ابحث عن [/plugins Cordova plugins] لأجل إضافات أخرى توفر خيارات تخزين بديلة.

مصادر