الفرق بين المراجعتين لصفحة: «Cordova/storage»

من موسوعة حسوب
أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE: التخزين في Cordova}}</noinclude> تصنيف: Cordova تتوفر العديد من واجهات برمجة التطبيقات...'
 
لا ملخص تعديل
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE:  التخزين في  Cordova}}</noinclude>
<noinclude>{{DISPLAYTITLE:  التخزين في  Cordova}}</noinclude>
[[تصنيف: Cordova]]
[[تصنيف: Cordova]]
تتوفر العديد من واجهات برمجة التطبيقات (APIs) المتخصصة للتخزين لأجل لتطبيقات Cordova. راجع html5rocks [http://www.html5rocks.com/en/features/storage  storage overview] و [http://www.html5rocks.com/en/tutorials/offline/storage/  tutorial] لمزيد من المعلومات والأمثلة.  
تتوفر العديد من واجهات برمجة التطبيقات (APIs) المتخصصة في التخزين لأجل تطبيقات Cordova.


لكل واجهة برمجية مزايا وعيوب، والتي سنلخصها هنا. وعليك اختيار ما يناسب احتياجاتك. يمكنك أيضًا استخدام عدة مقاربات في نفس التطبيق لخدمة أغراض مختلفة.  
لكل واجهة برمجية مزايا وعيوب، والتي سنلخصها في هذه الصفحة. وعليك اختيار ما يناسب احتياجاتك. يمكنك أيضًا استخدام عدة مقاربات في نفس التطبيق لخدمة أغراض مختلفة.
==التخزين المحلي (LocalStorage)==
يوفر التخزين المحلي ( Local storage) تخزينًا بسيطًا ومتزامنًا للبيانات على شكل أزواج مفتاح/قيمة (key/value)، هذه المقاربة مدعومة من <code>WebView</code> في جميع منصات كوردوفا.
===ملخص الاستخدام===
يمكن الوصول إلى ميزة التخزين المحلي عبر <code>window.localStorage</code>. تعرض الشيفرة التالية أهم توابع الكائن <code>Storage</code> المعاد:<syntaxhighlight lang="javascript">var storage = window.localStorage;
var value = storage.getItem(key); // تمرير مفتاح لاستعادة قيمته
storage.setItem(key, value) // تمرير مفتاح وقيمته لإضافة أو تحديث المفتاح
storage.removeItem(key) // تمرير مفتاح لإزالة ذلك المفتاح من المخزن
</syntaxhighlight>لمزيد من المعلومات، راجع:
* [https://html.spec.whatwg.org/multipage/webstorage.html W3C:  المواصفات]
* [https://developer.mozilla.org/en-US/docs/Web/API/Storage MDN: Storage API]
* [https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API MDN: Storage Guide]


== التخزين المحلي ==  
===المزايا===
*مدعومة من جميع منصات Cordova.
*بساطة وتزامنية الواجهة البرمجية تعني أنها سهلة الاستخدام.
===العيوب===
*تخزن السلاسل النصية فقط، لذلك، فالبيانات المعقدة يجب أن تُسَلسَل (serialized)، هذا يعني أنه لا يمكن تخزين إلا البيانات القابلة للسَّلسَّلة.
*أداؤها سيء مع البيانات ذات الأحجام الكبيرة. بالخصوص:
**عدم وجود فهرسة يعني أن عمليات البحث تتطلب تكرارا يدويا (manually iterating) على جميع البيانات.
**تخزين البيانات الكبيرة أو المعقدة بطيء بسبب الحاجة إلى السَّلسَّلة/الفك (serialize/de-serialize).
**الواجهة البرمجية المتزامنة تقنضي أن الاستدعاءات ستعيق (lock) واجهة المستخدم.
*محدودية المساحة الإجمالية للتخزين (5MB في العادة).
*تُخزّن منصة iOS بيانات <code>localStorage</code> في موضع قد يتم تنظيفه من قبل نظام التشغيل عند الحاجة لتحرير المساحة.
==WebSQL==
توفر <code>WebSQL</code> واجهة برمجية لتخزين البيانات في قاعدة بيانات مُهيكلة، والتي يمكن الاستعلام منها باستخدام صيغ [[SQL]] العادية (على وجه التحديد، [https://www.sqlite.org/ SQLite]). وهكذا فهي توفر إمكانية الاستفادة من قوة (وتعقيد) لغة [[SQL]].


يوفر التخزين المحلي (Local storage) تخزينًا بسيطًا ومتزامنًا لبيانات على شكل أزواج مفتاح/قيمة (key/value)، هذه المقاربة مدعومة من تقديمات WebView على جميع منصات كوردوفا.
هذه الميزة مدعومة من <code>WebView</code> على منصات Cordova التالية:
=== ملخص الاستخدام ===  
*أندرويد
*iOS
===ملخص الاستخدام===
المدخل إلى إنشاء أو فتح قاعدة بيانات هي عبر التابع <code>window.openDatabase()‎</code><syntaxhighlight lang="javascript">var db = window.openDatabase(name, version, displayName, estimatedSize);‎</syntaxhighlight>


يمكن الوصول إلى ميزة التخزين المحلي عبر <code>window.localStorage</code>. تعرض الشيفرة التالية أهم توابع الكائن <code>Storage</code> المعاد:
==== المعاملات ====
<syntaxhighlight>var storage = window.localStorage;
*'''name''' (سلسلة نصية): يمثل الاسم المميز لقاعدة البيانات، الذي ستُخزّن به على القرص.
var value = storage.getItem(key); // Pass a key name to get its value.
*'''version''' (سلسلة نصية): إصدار قاعدة البيانات.
storage.setItem(key, value) // Pass a key name and its value to add or update that key.
*'''displayName''' (سلسلة نصية): اسم مبسط ومفهوم لقاعدة البيانات، والذي سيستخدمه النظام إن كان بحاجة إلى وصف قاعدة بياناتك للمستخدم (على سبيل المثال، عند طلب الإذن لزيادة حجم قاعدة البيانات).
storage.removeItem(key) // Pass a key name to remove that key from storage.‎</syntaxhighlight>
*'''estimatedSize''' (عدد): الحجم الأقصى المتوقع لقاعدة البيانات، بالبايت (byte). فمع تزايد حجم قاعدة البيانات، قد يُطالَب المستخدم بالحصول على إذن. إذا اخترت قيمة مناسبة، فمن المحتمل أن تقلل من وثيرة مطالبة المستخدم بالإذن.
 
يوفر كائن <code>Database</code> المُعاد التابع <code>transaction()</code> (أو <code>readTransaction()</code> لتحسين أداء معاملَات القراءة فقط [read-only]) الذي يمكنك من إنشاء معاملات آمنة:<syntaxhighlight lang="javascript">var db = window.openDatabase(name, version, displayName, estimatedSize);
لمزيد من المعلومات، راجع:
[https://html.spec.whatwg.org/multipage/webstorage.html  W3C: Spec]
[https://developer.mozilla.org/en-US/docs/Web/API/Storage  MDN: Storage API]
[https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API  MDN: Storage Guide]
=== المزايا ===
* مدعومة من جميع منصات Cordova.
* الواجهة البرمجية البسيطة والمتزامنة تعني أنها سهلة الاستخدام.
=== العيوب ===
* تخزن السلاسل النصية فقط، لذلك، فالبيانات المعقدة يجب أن تُسَلسَل (serialized)، هذا يعني أنه لا يمكن تخزين إلا البيانات القابلة للسَّلسَّلة.
* أداؤها سيء مع البيانات ذات الأحجام الكبيرة. بالخصوص:
* عدم وجود فهرسة يعني أن عمليات البحث تتطلب تكرار اليدوي على جميع البيانات.
* تخزين البيانات الكبيرة أو المعقدة بطيء بسبب الحاجة إلى السلسلة/الفك (serialize/de-serialize).
* الواجهة البرمجية المتزامنة تقنضي أن الاستدعاءات ستقفل (lock) واجهة المستخدم.
* محدودية المساحة الإجمالية للتخزين (حوالي 5MB عادة).
* تخزن منصة iOS بيانات <code>localStorage</code> في موقع قد يتم تنظيفه من قبل نظام التشغيل عند الحاجة لتحرير المساحة.
 
== WebSQL ==
 
يوفر WebSQL واجهة برمجية لتخزين البيانات في قاعدة بيانات مُهيكلة، والتي يمكن الاستعلام منها باستخدام صيغ SQL عادية (على وجه التحديد، [https://www.sqlite.org/  SQLite]). وهكذا فهي توفر إمكانية الاستفادة من قوة (وتعقيد) SQL.
 
هذه الميزة مدعومة من WebView على منصات Cordova التالية:
*أندرويد
*iOS
=== ملخص الاستخدام ===  
 
المدخل إلى إنشاء أو فتح قاعدة بيانات هي عبر التابع <code>window.openDatabase()</code>:
<syntaxhighlight>var db = window.openDatabase(name, version, displayName, estimatedSize);‎</syntaxhighlight>
* '''name''' (سلسلة نصية): يمثل الاسم المميز لقاعدة البيانات، الذي ستُخزّن به على القرص.  
* '''version''' (سلسلة نصية): إصدار قاعدة البيانات.  
* '''displayName''' (سلسلة نصية): اسم مبسط ومفهوم لقاعدة البيانات، والذي سيستخدمه النظام إن كان بحاجة إلى وصف قاعدة بياناتك للمستخدم (على سبيل المثال، عند الاستئذان لزيادة حجم قاعدة البيانات).  
* '''estimatedSize''' (عدد): الحجم الأقصى المتوقع لقاعدة البيانات، بالبايت (byte). مع تزايد حجم قاعدة البيانات، قد يُطالب المستخدم بالحصول على إذن. إذا اخترت قيمة مناسبة، فمن المحتمل أن يُطالب المستخدم بالإذن بمعدل أقل.  
 
يوفر كائن <code>Database</code> المُعاد التابع <code>transaction()</code> (أو <code>readTransaction()</code> لتحسين أداء معاملَات القراءة فقط [read-only]) التي تمكنك من إنشاء معاملات آمنة:  
<syntaxhighlight>var db = window.openDatabase(name, version, displayName, estimatedSize);
db.transaction(function (tx) {
db.transaction(function (tx) {
     tx.executeSql(sqlStatement, valueArray, function (tx, result) {
     tx.executeSql(sqlStatement, valueArray, function (tx, result) {
سطر 56: سطر 48:
         console.log(error);
         console.log(error);
     });
     });
});‎</syntaxhighlight>  
});‎</syntaxhighlight>لمزيد من المعلومات، راجع صفحة  [http://dev.w3.org/html5/webdatabase/ مواصفات W3C]
===إصدارات قواعد البيانات===
عند فتح قاعدة بيانات قائمة، إن كان الإصدار المحدد لا يتطابق مع إصدار قاعدة البيانات، فسيُطلق استثناء، ولن تُفتح قاعدة البيانات. لكن إن قمت بتحديد سلسلة فارغة مكان الإصدار، فستُفتح قاعدة البيانات بغض النظر عن إصدارها الحالي (يمكنك الاستعلام عن الإصدار الحالي عبر <code>db.version</code>). لكن كن حذرًا، لأنه في حال إنشاء قاعدة البيانات، فستعيّن سلسلة فارغة لإصدارها.
===المزايا===
*أداء جيد - يمكن فهرسة البيانات لتسريع عمليات البحث، كما أنّ الواجهة البرمجية غير المتزامنة تعني أنها لا تعوق (lock) واجهة المستخدم.
*المتانة (Robustness) النانجة عن استخدام نموذج قاعدة بيانات معاملاتي (transactional database model).
*دعم الإصدارات (Support for versioning).
===العيوب===
*لا تدعمها كل منصات Cordova.
*أكثر تعقيدا من <code>LocalStorage</code> أو <code>IndexedDB</code>.


لمزيد من المعلومات، راجع:
*الواجهة البرمجية مُتجاوزة. من المستبعد أن تُدعم على المنصات التي لا تدعمها حاليًا، وقد تُزال من المنصات التي تدعمها.
[http://dev.w3.org/html5/webdatabase/ W3C: Spec]
*تفرض بنية جامدة، والتي يتوجب تعريفها مقدمًا.
*محدودية مساحة التخزين (5MB في العادة).
==IndexedDB==
الهدف من الواجهة البرمجية لـ <code>IndexedDB</code> هو دمج نقاط قوة الواجهتين البرمجيتين <code>LocalStorage</code> و <code>WebSQL</code>، مع تجنب نقاط ضعفهما.


للحصول على مدخل تقديمي جيد للغة SQL، راجع:
تتيح لك <code>IndexedDB</code> تخزين كائنات جافا سكريبت (بشرط أن تكون مدعومة من قبل خوارزمية النسخ المهيكل ([http://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data structured clone algorithm)]) مُفهرَسَة بمفتاح. كما توفر بعضًا من فوائد جداول [[SQL]]، دون تقييد البنية، أو الحاجة إلى تعريفها في المقدمة.
[http://www.w3schools.com/sql/sql_intro.asp w3schools: Introduction to SQL]  
=== إصدارات قواعد البيانات ===


عند فتح قاعدة بيانات قائمة، إن كان الإصدار المحدد لا يتطابق مع إصدار قاعدة البيانات، فسيُطلق استثناء، ولن تُفتح قاعدة البيانات. لكن إن قمت بتحديد سلسلة فارغة لأجل الإصدار، فستُفتح قاعدة البيانات بغض النظر عن إصدارها الحالي (ويمكنك الاستعلام عن الإصدار الحالي عبر <code>db.version</code>). لكن كن حذرًا، لأنه في حال إنشاء قاعدة البيانات، فستعيّن سلسلة فارغة لإصدارها.
توفر <code>IndexedDB</code> نموذج بيانات بسيط وسهل الفهم، تمامًا مثل <code>LocalStorage</code>. ولكن على خلاف <code>LocalStorage</code>، ذيمكنك إنشاء عدة قواعد بيانات، مع عدة مخازن (stores) في كل قاعدة بيانات، كما تحسن واجهتها البرمجية غير المتزامنة والبحث المفهرس أداءها.
=== المزايا ===
* أداء جيد - يمكن فهرسة البيانات لتسريع عمليات البحث، كما أنّ الواجهة البرمجية غير المتزامنة تعني أنها لا تعطل (lock) واجهة المستخدم.
* المتانة النانجة عن استخدام نموذج قاعدة بيانات معاملاتي (transactional database model).
* دعم الإصدارات (Support for versioning).
=== العيوب ===
* لا تدعمها كل منصات Cordova.
* أكثر تعقيدا من
LocalStorage أو
IndexedDB.
* الواجهة البرمجية مُتجاوزة. من المستبعد أن تُدعم على المنصات التي لا تدعمها حاليًا، وقد تُزال من المنصات التي تدعمها مستقبلا.
* تفرض بنية جامدة، والتي يتوجب تعريفها مقدمًا.
* محدودية مساحة التخزين (حوالي 5MB في العادة).  


== IndexedDB ==
<code>IndexedDB</code> مدعومة من <code>WebView</code> على منصات Cordova التالية:
 
*ويندوز (مع بعض القيود)
الهدف من الواجهة البرمجية IndexedDB هو دمج نقاط قوة في الواجهتين البرمجيتين LocalStorage و WebSQL، مع تجنب نقاط ضعفهما. تتيح لك IndexedDB تخزين كائنات جافا سكريبت (بشرط أن تكون مدعومة من قبل [http://w3c.github.io/html/infrastructure.html#safe-passing-of-structured-data  structured clone algorithm])، مع فهرستها بمفتاح. كما توفر بعض فوائد جداول SQL، دون تقييد البنية أو الحاجة إلى تعريفها في المقدمة.
*أندرويد (4.4 فما فوق)
 
===قيود ويندوز===
توفر IndexedDB نموذج بيانات بسيط وسهل الفهم، تمامًا مثل LocalStorage. ولكن بخلاف LocalStorage، فيمكنك إنشاء عدة قواعد بيانات، مع عدة مخازن (stores) في كل قاعدة بيانات، كما تحسن واجهتها البرمجية غير المتزامنة والبحث المفهرس أداءها.
دعم منصة ويندوز لـ <code>IndexedDB</code> غير كامل. على سبيل المثال:
 
*غير متوفرة في عاملات الشبكة (web workers).
IndexedDB مدعومة من WebView على منصات Cordova التالية:  
*لا تدعم المفاتيح المسارية في المصفوفات (array keyPaths).
* ويندوز (مع بعض القيود)  
*لا تدعم مفاتيح المصفوفات (array keys).
* أندرويد (4.4 فما فوق)  
*لا تدعم البحث عن الكائنات عبر الفهارس المركبة.
=== قيود ويندوز ===  
===ملخص الاستخدام===
 
*تعمل <code>IndexedDB</code> بشكل غير متزامن - إذ تقوم بطلب عملية معينة على قاعدة بيانات، ثم يتم إعلامك بالنتيجة عبر حدث دوم (DOM event).
دعم منصة ويندوز لـ IndexedDB غير كامل. على سبيل المثال، يفتقر إلى الميزات التالية:  
*عندما تقوم بتقديم طلب، ستحصل على كائن طلب (request object)، والذي يوفر الحدثين <code>onerror</code> و <code>onsuccess</code>، بالإضافة إلى خصائص مثل <code>result</code> و <code>error</code> و <code>readyState</code>.
* غير متوفر في عاملات الشبكة (web workers).  
توضح الشيفرة التالية بعض الاستخدامات البسيطة لـ <code>IndexedDB</code>:<syntaxhighlight lang="javascript">var db;
* لا تدعم المفاتيح المسارية في المصفوفات (array keyPaths).  
* لا تدعم المفاتيح في المصفوفات (array keys).  
* لا تدعم البحث عن الكائنات عبر فهرس مركب.  
=== ملخص الاستخدام ===  
* تعمل IndexedDB بشكل غير متزامن - إذ تطلب عملية معينة على قاعدة بيانات، ثم يتم إعلامك بالنتيجة عبر حدث دوم (DOM event).  
* عند تقوم بتقديم طلب، ستحصل على كائن طلب (request object)، والذي يوفر الحدثين <code>onerror</code> و <code>onsuccess</code>، بالإضافة إلى خصائص مثل <code>result</code> و <code>error</code> و <code>readyState</code>.  
 
توضح الشيفرة التالية بعضالاستخدامات البسيطة لـ IndexedDB:  
<syntaxhighlight>var db;
var databaseName = 'myDB';
var databaseName = 'myDB';
var databaseVersion = 1;
var databaseVersion = 1;
سطر 108: سطر 89:
};
};
openRequest.onsuccess = function (event) {
openRequest.onsuccess = function (event) {
     // Database is open and initialized - we're good to proceed.
     // قاعدة البيانات مفتوحة ومهيئة، كل شيء جاهز للبدء
     db = openRequest.result;
     db = openRequest.result;
     displayData();
     displayData();
};
};
openRequest.onupgradeneeded = function (event) {
openRequest.onupgradeneeded = function (event) {
     // This is either a newly created database, or a new version number
     // هذه إما قاعدة بيانات منشأة حديثا، أو رقم إصدار جديد
     // has been submitted to the open() call.
     // open() تم تسليمها إلى استدعاء
     var db = event.target.result;
     var db = event.target.result;
     db.onerror = function () {
     db.onerror = function () {
         console.log(db.errorCode);
         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
     // keyPath  كائن التخزين. الخيار 
     // 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).
     // autoIncrement خاصية بنفس اسم مفتاح المسار، إلا إن كان الخيار
    // true يساوي 
     var store = db.createObjectStore('customers', { keyPath: 'customerId' });
     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]);
     // syntax: store.createIndex(indexName, keyPath[, parameters]);
     //
     //
     // All these values could have duplicates, so set unique to false
     // unique كل هذه القيم يمكن أن تكون مكررة، لذا عين قيمة   
    // false عند القيمة
     store.createIndex('firstName', 'firstName', { unique: false });
     store.createIndex('firstName', 'firstName', { unique: false });
     store.createIndex('lastName', 'lastName', { unique: false });
     store.createIndex('lastName', 'lastName', { unique: false });
سطر 138: سطر 121:
     store.createIndex('zipCode', 'zipCode', { unique: false });
     store.createIndex('zipCode', 'zipCode', { unique: false });
     store.createIndex('country', 'country', { unique: false });
     store.createIndex('country', 'country', { unique: false });
     // Once the store is created, populate it
     // بمجرد إنشاء المخزن، قم بملئه
     store.transaction.oncomplete = function (event) {
     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
      // transaction يأخذ التابع
        // 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
      // readwrite المعاملة للقراءة فقط إلا في حال تحديد الوسيط الاختياري
        // to access one of the object stores that are in the scope of this
      // objectStore يعيد كائن معاملات، والذي يوفر التابع
        //transaction.
      //للدخول إلى أحدا كائنات التخزين الموجودة في نطاق هذه المعاملة
 
         var customerStore = db.transaction('customers', 'readwrite').objectStore('customers');
         var customerStore = db.transaction('customers', 'readwrite').objectStore('customers');
         customers.forEach(function (customer) {
         customers.forEach(function (customer) {
سطر 154: سطر 138:
};
};
function displayData() {
function displayData() {
}‎</syntaxhighlight>  
}‎</syntaxhighlight>لمزيد من المعلومات، راجع:
 
* [http://www.w3.org/TR/IndexedDB/ مواصفات W3C]
لمزيد من المعلومات، راجع:  
* [https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API توثيق : IndexedDB]
[http://www.w3.org/TR/IndexedDB/ W3C: Spec]  
* [https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB مفاهيم أساسية حول IndexedDB]
[https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API MDN: IndexedDB API Reference]  
* [https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB دليل استخدام] [https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB IndexedDB]
[https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB MDN: IndexedDB Basic Concepts]  
[https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB MDN: Using IndexedDB Guide]  
=== المزايا ===
* الأداء الجيد - لن تعيق الواجهة البرمجية غير المتزامنة واجهة المستخدم، كما ستوفر الفهرسة أداءً جيدًا في عمليات البحث.
* نموذج بيانات بسيط أسهل في التعلم من SQL.
* بنية أكثر مرونة من WebSQL.
* يوفر تعدد قواعد البيانات ومخازن الكائنات (object stores) بنية أكثر تفصيلا من LocalStorage.
* المتانة نتيجة استخدام نموذج بيانات معاملاتي (transactional database model).
* دعم الإصدارات.
=== العيوب ===
* غير مدعومة على منصة iOS.
* واجهة برمجية معقدة تحتوي على استدعاءات متشعبة.
* محدودية مساحة التخزين (حوالي 5MB في العادة).
 
== إضافات ==
=== FileSystem API ===
 
كانت FileSystem API جزءًا من مواصفات W3C، والتي تم تتزيلها من قبل Chrome دون بقية المتصفحات. توفر هذه الإضافة واجهات برمجية لتخزين واسترجاع البيانات على نظام الملفات المحلي (يمكنك معرفة المزيد من المقال المفصل [http://www.html5rocks.com/en/tutorials/file/filesystem/ html5rocks article]). على الرغم من أن الواجهة البرمجية غير مدعومة من قبل أي منصة من منصات كوردوفا، يوفر [https://github.com/apache/cordova-plugin-file/blob/master/README.md  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 أو تحت رخصة تجارية.
=== إضافات أخرى ===


===المزايا===
*الأداء الجيد - لن تعيق الواجهة البرمجية غير المتزامنة واجهة المستخدم، كما ستوفر الفهرسة أداءً جيدًا في عمليات البحث.
*نموذج بيانات بسيط أسهل في التعلم من SQL.
*بنية أكثر مرونة من WebSQL.
*يوفر تعدد قواعد البيانات ومخازن الكائنات (object stores) بنية أكثر تفصيلا من LocalStorage.
*المتانة نتيجة استخدام نموذج بيانات معاملاتي (transactional database model).
*دعم الإصدارات.
===العيوب===
*غير مدعومة على منصة iOS.
*واجهة برمجية معقدة تحتوي على استدعاءات متشعبة.
*محدودية مساحة التخزين (حوالي 5MB في العادة).
==إضافات==
===FileSystem API===
كانت FileSystem API جزءًا من مواصفات W3C، والتي تم تتزيلها من قبل Chrome دون بقية المتصفحات. توفر هذه الإضافة واجهات برمجية لتخزين واسترجاع البيانات على نظام الملفات المحلي (يمكنك معرفة المزيد من المقال المفصل [http://www.html5rocks.com/en/tutorials/file/filesystem/ html5rocks article]). على الرغم من أن الواجهة البرمجية غير مدعومة من قبل أي منصة من منصات كوردوفا، يوفر [https://github.com/apache/cordova-plugin-file/blob/master/README.md 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] لأجل إضافات أخرى توفر خيارات تخزين بديلة.
ابحث عن [/plugins  Cordova plugins] لأجل إضافات أخرى توفر خيارات تخزين بديلة.
==مصادر==
==مصادر==
*[https://cordova.apache.org/docs/en/latest/cordova/storage/storage.html قسم التخزين في التوثيق الرسمي لكوردوفا.]
*[https://cordova.apache.org/docs/en/latest/cordova/storage/storage.html قسم التخزين في التوثيق الرسمي لكوردوفا.]

مراجعة 02:12، 19 نوفمبر 2018

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

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

التخزين المحلي (LocalStorage)

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

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

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

var storage = window.localStorage;
var value = storage.getItem(key); // تمرير مفتاح لاستعادة قيمته
storage.setItem(key, value) // تمرير مفتاح وقيمته لإضافة أو تحديث المفتاح
storage.removeItem(key) // تمرير مفتاح لإزالة ذلك المفتاح من المخزن

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

المزايا

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

العيوب

  • تخزن السلاسل النصية فقط، لذلك، فالبيانات المعقدة يجب أن تُسَلسَل (serialized)، هذا يعني أنه لا يمكن تخزين إلا البيانات القابلة للسَّلسَّلة.
  • أداؤها سيء مع البيانات ذات الأحجام الكبيرة. بالخصوص:
    • عدم وجود فهرسة يعني أن عمليات البحث تتطلب تكرارا يدويا (manually iterating) على جميع البيانات.
    • تخزين البيانات الكبيرة أو المعقدة بطيء بسبب الحاجة إلى السَّلسَّلة/الفك (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

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

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

المزايا

  • أداء جيد - يمكن فهرسة البيانات لتسريع عمليات البحث، كما أنّ الواجهة البرمجية غير المتزامنة تعني أنها لا تعوق (lock) واجهة المستخدم.
  • المتانة (Robustness) النانجة عن استخدام نموذج قاعدة بيانات معاملاتي (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) {
    // قاعدة البيانات مفتوحة ومهيئة، كل شيء جاهز للبدء
    db = openRequest.result;
    displayData();
};
openRequest.onupgradeneeded = function (event) {
    // هذه إما قاعدة بيانات منشأة حديثا، أو رقم إصدار جديد
    // open() تم تسليمها إلى استدعاء
    var db = event.target.result;
    db.onerror = function () {
        console.log(db.errorCode);
    };
    //تنشئ كائن تخزين وفهارس، المفاتيح هي قيم بيانات تُستخدم لتنظيم واستعادة القيم من 
    // keyPath  كائن التخزين. الخيار  
    //يحدد موضع تخزين المفتاح. في حال تحديد مفتاح المسار، فلن
    //بحتوي المخزن إلا على كائنات جافاسكريبت، وينبغي أن تكون لكل الكائنات المخزنة 
    // autoIncrement  خاصية بنفس اسم مفتاح المسار، إلا إن كان الخيار
    // true  يساوي  
    var store = db.createObjectStore('customers', { keyPath: 'customerId' });

    //تعرف الفهارس التي نريد استخدامها. الكائنات التي نضيف إلى المخزن لا ينبغي 
    //بالضرورة أن تحتوي هذه الخاصيات. ولكنها ستظهر فقط في الفهرس المحدد
    //
    // syntax: store.createIndex(indexName, keyPath[, parameters]);
    //
    // unique  كل هذه القيم يمكن أن تكون مكررة، لذا عين قيمة    
    // 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 });
    // بمجرد إنشاء المخزن، قم بملئه
    store.transaction.oncomplete = function (event) {

       // transaction  يأخذ التابع 
       // مصفوفة مؤلفة من أسماء كائنات التخزين والفهارس التي ستكون في 
       //نطاق المعاملة، أو سلسلة نصية واحدة للدخول إلى كائن تخزين واحد. ستكون 
       // readwrite المعاملة للقراءة فقط إلا في حال تحديد الوسيط الاختياري 
       // objectStore  يعيد كائن معاملات، والذي يوفر التابع 
       //للدخول إلى أحدا كائنات التخزين الموجودة في نطاق هذه المعاملة

        var customerStore = db.transaction('customers', 'readwrite').objectStore('customers');
        customers.forEach(function (customer) {
            customerStore.add(customer);
        });
    };
};
function displayData() {
}

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

المزايا

  • الأداء الجيد - لن تعيق الواجهة البرمجية غير المتزامنة واجهة المستخدم، كما ستوفر الفهرسة أداءً جيدًا في عمليات البحث.
  • نموذج بيانات بسيط أسهل في التعلم من 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] لأجل إضافات أخرى توفر خيارات تخزين بديلة.

مصادر