HTML5 storage الجزء الثانى


السلام عليكم و رحمه الله تعالى و بركاته

فى هذا الجزء أتناول كيفيه تخزين البيانات فى قاعده بيانات SQLite من خلال local JavaScript Database api

مقدمه
إنشاء و فتح قاعده البيانات
إنشاء جدول جديد
إضافه بيانات للجدول
إستخدام العبارات الجاهزه
إختيار بيانات من الجدول
التعامل مع اخطاء تنفيذ ال SQL
أرقام الأخطاء و مدلولاتها
التعامل مع اخطاء ال transaction
التعامل مع اصدارات قاعده البيانات
الدعم من المتصفحات
للمزيد

مقدمه

تحتوى مواصفات HTML5 على وصف ل Local JavaScript Database قاعده بيانات محليه تمكنك من تخزين البيانات داخل متصفح المستخدم فى قاعده بيانات SQlite بدلا من الكوكيز التى تقتصر مساحتها التخزينيه على 4 كيلو فقط ، قاعده البيانات SQLite على ملايين اجهزه المحمول و الاجهزه الكفيه و السيرفر و الكثير من تطبيقات سطح المكتب لصغر حجمها و مرونتها و تدعيمها شبه الكامل ل SQL ANSI ، للمزيد عن SQL و SQLite داخل المتصفح من هنا ، العمليات التى تتم على قاعده البيانات تكون غير تزامنيه asynchronous اى تتطلب كل عمليه تسجيل وظيفه تستمع لحدث نجاح العمليه او حدوث خطأ ، كما ان العمليات كلها تتم بنظام transaction لأن بيئه المتصفح غير مستقره ، يمكن لأى عمليه ان يقطعها refresh او اغلاق نافذه المتصفح ، اى انه إذا حدث خطأ فى عمليه مكونه من عده خطوات فإن قاعده البيانات لن تتأثر بأى من هذه الخطوات ، مثلا اذا كنت تغير بعض البيانات من جدول A ثم تضيف بيانات فى جدول B و تحذف بيانات من جدول C و قمت بإغلاق المتصفح فى منتصف خطوه اضافه البيانات للجدول B ، فإن خطوه تغيير البيانات من الجدول A سيتم التراجع عنها و لن يحدث اى تأثير ، إلا اذا تمت جميع عمليات ال transaction بنجاح .

إنشاء و فتح قاعده بيانات

قبل ان تتمكن من إستخدام قاعده البيانات عليك اولا فتح اتصال بها ، عندما تقوم بفتح اتصال سيتم انشاء قاعده بيانات جديده فارغه اذا لم يتم انشائها من قبل ، لذلك فإن عمليه فتح و انشاء قاعده البيانات متماثله ، يتم فتح الاتصال بقاعده البيناات عن طريق عن طريق الوظيفه openDatabase التى تقبل اربع عبارات : العباره الاولى هى إسم قاعده البيانات ، العباره التانيه هى إصدار قاعده البيانات للمزيد انظر الجزء الخاص بالتعامل مع اصدارات قاعد البيانات ، العباره الثالثه هى الإسم الذى يستخدمه المتصفح للتفاعل مع المستخدم مثلا عند طلب إذن بزياده الحجم المتاح لقاعده البيانات ، العباره الرابعه هى الحجم الذى تتوقع ان تشغله قاعده البيانات التى تقوم بالعمل عليها و اذا تعدت هذا الحجم المتفق عليه سيتم أخذ إذن المستخدم بأعطاء المزيد من الحجم لقاعده البيانات ، المثال التالى يوضح إنشاء قاعده بيانات بإسم keepondev إصدار 1.0 و حجمها 64 كيلوبايت و لها الإسم keepondev database لإستخدامه عند التفاعل مع المستخدم :

var db = openDatabase("keepondev", "1.0", "Keepondev database", 65536);

إنشاء جدول جديد

بقيه امثله هذا الموضوع تعتمد على جدول بإسم goals يحتوى على عمودين id و name :

CREATE TABLE IF NOT EXISTS goals (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL
);

يمكنك انشاء هذا الجدول من خلال تنفيذ جمله ال SQL السابقه على قاعده البيانات keepondev عن طريق الوظيفه executeSql التابعه للكائن SQLtransaction – فى المثال بإسم tx – الذى يتم تمريره للوظيفه التى تمرر للوظيفه transaction 8O التابعه للكائن الناتج من openDatabase كما يوضح الكود التالى :

var db = openDatabase("keepondev", "1.0", "Keepondev database", 65536);

function resultHandler(){
    alert("success");
};
function errorHandler(){
    alert("fail");
};
db.transaction(function(tx){
    var sql = "CREATE TABLE IF NOT EXISTS goals(";
    sql += "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
    sql += "name TEXT NOT NULL DEFAULT 'secret goal');";
    tx.executeSql(sql, [], resultHandler, errorHandler);
});

الوظيفه transaction تقبل وظيفه يمرر لها كائن من نوع SQLTransaction بإسم tx فى المثال السابق ، الكائن tx يحتوى الوظيفه executeSql التى تقبل اربع عبارات ، العباره الاولى هى جمله ال SQL التى قمت بوضعها فى المتغير sql و كتبتها على اكثر من سطر حتى لا تخرج عن عرض المدونه ، العباره التانيه مصفوفه تقبل قيم العبارت الجاهزه للمزيد انظر الجزء الخاص بإستخدام العبارات الجاهزه prepared statements ، العباره الثالثه وظيفه يتم إستدعائها اذا تم تنفيذ جمله ال SQL بنجاح ، و العباره الرابعه وظيفه يتم إستدعائها اذا حدث خطأ اثناء تنفيذ جمله ال SQL ، تلك الوظيفتين ستقوم بإظهار نافذه منبثقه ب success او fail فقط ، للمزيد انظر الجزء الخاص بأخطاء تنفيذ ال SQL و الجزء الخاص بأخطاء ال transaction ، يمكنك التأكد من انشاء الجدول و قاعده البيانات بنجاح داخل المتصفح Safari 4 من خلال فتح ال tab الخاص ب database الذى يمكن الحصول عليه من Sesstings > preferences > advanced > show develop menu in menu bar ، ستجد قائمه جديده بإسم develop دخلت فى القائمه file ، قم بقتح tab ال database كما توضح الصوره التاليه :

Safari Database tab

داخل tab ال database ستجد قاعده بيانات بإسم keepondev تحتوى على جدول فارغ بإسم goals ، يالا بينا نملاه .

إضافه بيانات للجدول

إضافه بيانات للجدول ماهى إلا تنفيذ جمله SQL من نوع INSERT بعد فتح قاعده البيانات و عمل transaction بنفس ترتيب الخطوات السابقه ، كما يوضح المثال البسيط التالى :

var db = openDatabase("keepondev", "1.0", "Keepondev database", 65536);
db.transaction(function(tx){
    var sql = "INSERT INTO goals (name) VALUES ('world domination')";
    tx.executeSql(sql, [], resultHandler, errorHandler);
});

الشىء الوحيد المختلف فى المثال السابق هى جمله ال INSERT التى تقوم بإضافه صف جديد فى الجدول goals و تظبط قيمه العمود name الى world domination اما العمود id فيأخذ رقم تلقائى ، هناك مأخذ على طريقه الاضافه السابقه : لو احتوت القيمه على ‘ سيحدث error و يمكن ايضا حقن جمله SQL و عمل هجمه من نوع SQL injection ، الطريقه الافضل لإضافه البيانات هى إستخدام العبارت الجاهزه .

إستخدام العبارات الجاهزه

إستخدام العباره الجاهزه يمكنك من إستخدام ال ‘ و ال ” داخل القيم بدون الخوف على كسر جمله ال SQL ، ثم انه يستحيل حقن SQL داخل العبارت الجاهزه و عليه لا يمكن حدوث هجمات SQL injection ، و تزيد كفائه تنفيذ عمليه اضافه اكثر من صف فى الجدول .

قم بوضع علامه استفهام ؟ بدلا من وضع قيمه العمود فى جمله ال SQL ، و بداخل المصفوفه [] التى هى العباره التانيه للوظيفه executeSql قم بإضافه القيمه ، او ضيفها من ناتج مدخل المستخدم كما يوضح الكود البسيط التالى :

var db = openDatabase("keepondev", "1.0", "Keepondev database", 65536);
db.transaction(function(tx){
    var sql = "INSERT INTO goals (name) VALUES (?)";
    tx.executeSql(sql, ["Conference speaker"], resultHandler, errorHandler);
    tx.executeSql(sql, ["technology innovator"], resultHandler, errorHandler);
    tx.executeSql(sql, ["JavaScript evangelist"], resultHandler, errorHandler);
    tx.executeSql(sql, ["most infeluence person of all time"], resultHandler
    , errorhandler);
    tx.executeSql(sql, ["space trip"], resultHandler, errorhandler);
});

يمكنك منع التكرار فى الكود بإستخدام partial function و النتيجه كما تظهر فى الصوره التاليه :

database tab showing keepondev goals table

إختيار بيانات من الجدول

اختيار بيانات من الجدول عباره عن استخدام جمله SQL من نوع SELECT بالإضافه إلى إستقبال البيانات من خلال الوظيفه resultHandler التى كانت وظيفتها فى الامثله السابقه عمل alert بالنص Success فقط ، عند نجاح تنفيذ جمله ال SQL على قاعده البيانات ، يتم تمرير عبارتين للوظيفه resultHandler ، العباره الاولى هى كائن من نوع SQLtTansaction و العباره التانيه كائن من نوع SQLResultSet يحتوى على الصفوف الناتجه من تنفيذ جمله ال SQL ، حيث يحتوى على الخاصيه rows التى هى بمثابه مصقوفه تمثل صفوف الجدول التى رجعت ، يمكننا استخلاص البيانات منها كما يوضح المثال البسيط التالى :

function resultHandler(tx, result){
    var rows = result.rows;
    var rowsLen = rows.length;
    for(var i = 0; i < rowsLen; i += 1){
        var row = rows.item(i);
        var id = row["id"];
        var name = row["name"];
        alert(id + " : " + name);
    }
};

var db = openDatabase("keepondev", "1.0", "Keepondev database", 65536);
db.transaction(function(tx){
    var sql = "SELECT * FROM goals";
    tx.executeSql(sql, [], resultHandler, errorHandler);
});

فى المثال السابق قمت بإستخلاص جميع البيانات من الجدول goals و استقبلت الناتج داخل الوظيفه resultHandler و قمت بعمل alert للصف لكن يمكنك حقنه فى ال DOM و عمل pagination و عمل LIMIT داخل جمله ال SQL حتى لا تتأثر كفائه التطبيق .

إذا كانت الجمله السابقه INSERT يمكنك معرفه ال id الجديد للصف من خلال result.insertId و عدد الصفوف التى تأثرت من result.rowsModified من داخل resultHandler .

التعامل مع اخطاء تنفيذ ال SQL

يتم إستدعاء الوظيفه errorHandler عند حدوث خطأ فى تنفيذ جمله ال SQL مع تمرير عبارتين لها ، العباره الاولى هى كائن من نوع SQLTransaction ، و العباره التانيه كائن من نوع SQLError يحتوى على معلومات عن الخطأ الذى حدث ، الوظيفه errorHandler اذا قامت بإرجاع true سيتم الغاء جميع العمليات فى ال transaction الحالى ، و اذا قامت ب return false سيتم التغاضى عن الخطأ و لن يتم الغاء ال transaction ، الكائن SQLError يحتوى على خاصيتين ، الخاصيه الاولى message و هى رساله توضح الخطأ الذى حدث يمكنك استخدامها فى ال debugging ، اما الخاصيه التانيه هى code فهى رقم يدل على الخطأ الذى حدث ، انظر الجزء الخاص بأرقام الاخطاء .

function errorHandler(tx, error){
    alert(error.message); // unrecognized token: 3awzo
    alert(error.code); // 1
};
db.transaction(function(tx){
    var sql = "SELECT elly ana 3awzo yabni";
    tx.executeSql(sql, [], resultHandler, errorHandler);
});

أرقام الاخطاء و مدلولاتها

داخل الوظيفه errorHandler ناتج error.code رقم يوضح طبيعه الخطأ ، ال 0 يوضح ان الخطأ غير متعلق بقاعده البيانات ، و 1 يوضح ان الخطأ له علاقه بقاعده البيانات ، 2 يوضح ان الخطأ اصدار قاعده البيانات ليس اصدار القاعده التى طلبتها للمزيد انظر الجزء الخاص بإصدارات قاعده البيانات ، و 3 يوضح ان نتيجه جمله ال SQL كبيره جدا و فى هذه الحاله عليك إستخدام LIMIT و OFFSET حتى تحدد عد الصفوف الناتجه من جمله ال SQL ، و 4 توضح ان الحجم المتاح لقاعده البيانات قد تعدى و ان المستخدم رفض اعطاء المزيد من الحجم عند سؤال المتصفح له ، و 5 يدل على ان الخطأ من نوع lock contention error و عليك اعاده تنفيذ ال transaction ، و 6 يل على constraint error مثلا عند تكرار قيمه فى صفين لعمود معلم ك UNIQUE او عدم اعطاء قيمه لعمود NOT NULL .

التعامل مع اخطاء ال transaction

كما تمكننا من التعامل مع اخطاء تنفيذ جمله ال SQL ، يمكنك ايضا اتخاذ اجراءات عند وقوع خطأ فى تنفيذ ال transaction الذى قد يحتوى على تنفيذ عده جمل SQL ، الوظيفه transaction تقبل ثلاث عبارات ، فى الامثله السابقه كلها رأينا العباره الاولى فقط و هى عباره عن وظيفه يمرر لها الكائن SQLTransaction ، اما العباره الثانيه التى تمرر للوظيفه transaction هى وظيفه يتم استدعائها عند حدوث خطأ فى ال transaction و العباره الثالثه يتم استدعائها عند نجاح ال transaction كما يوضح المثال البسيط التالى :

function txError(error){
    alert(error.message);
    alert(error.code);
};
function txSuccess(){
    alert("transaction succeed");
};

db.transaction(function(tx){ 
    // execute some sql queries here
}, txError, txSuccess);

فى المثال السابق سيتم استدعاء txSuccess اذا نجح ال transaction بدوت اى اخطاء ، و سيتم استدعاء الوظيفه txError مع تمرير كائن SQLError لها ، يمكن استخلاص بيانات منها من خلال error.message او error.code للمزيد انظر أرقام الاخطاء و مدلولاتها .

التعامل مع اصدارات قاعده البيانات

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

var db = openDatabase("keepondev", "", "Keepondev database", 65536);

يمكنك معرفه اصدار قاعده البيانات بعد ذلك من خلال الخاصيه verison كما يلى

alert(db.version); // 1.0

الكود السابق نتج عنه 1.0 لأنه لا يوجد إصدارات من قاعده بيانات بإسم keepondev إلا الاصدار 1.0 الذى قمنا بإنشاءه و اضافه فيه بيانات من قبل .

يمكنك ترقيه قاعده البيانات إلى اصدار احدث مع الحفاظ على البيانات بداخها كما هى او تغيرها من خلال الوظيفه changeVersion التى تقبل اربع عبارات ، العباره الاولى هى اصدار قاعده البيانات التى تريد تغيرها ، العباره التانيه هى الاصدار الجديد ، العباره التالته هى الوظيفه التى تقوم بتغير الجداول او تغير ال schema و تقبل كائن من نوع SQLTransaction ، العباره الرابعه هى الوظيفه التى يتم استدعائها اذا حدث خطأ اثناء الترقيه مع تمرير الكائن SQLError لها ، اما العباره الخامسه و الاخيره هى الوظيفه التى يتم استدعائها اذا نجحت عمليه الترقيه ، كما يوضح المثال البسيط التالى :

function upgrade(tx){
    var sql = "ALTER TABLE goals RENAME TO targets";
    tx.executeSql(sql, [], resultHandler, errorHandler);
};
function upgradeError(error){
    alert("upgrade error :" + error.message);
};
function upgradeSuccess(){
    alert("upgrade completed");
}
db.changeVersion("1.0", "2.0", upgrade, upgradeError, upgradeSuccess);

فى المثال السابق تم ترقيه قاعده البيانات إلى الاصدار 2.0 مع تغيير إسم الجدول goals إلى targets مع الاحتفاظ بالبيانات كما هى كما توضح الصوره التاليه :

keepondev database version 2.0 and goals table converted to targets

الدعم من المتصفحات

وقت كتابه التدوينه ال local javascript database api مدعم فى safari 3.1+ و iphone os 2.0+ و المتصفحات الاخرى قريبا ان شاء الله .

للمزيد

ADC > using JavaScript Databases

About these ads

الأوسمة: , , , , , ,

11 تعليقات to “HTML5 storage الجزء الثانى”

  1. almhajer Says:

    شكرا جزيلا من اعماق القلب وبارك الله فيك وجعلها في ميزان حسناتك
    والله ها html5 رح بيغير اشياء كثيرة الله بيعين عليها

  2. NoName4Me Says:

    شكراً لكـ يا مصطفى :)

    جعله الله في ميزان حسناتكـ

    يا ريت نشوف اكثر منكـ

  3. سلسة دروس عن HTML5 و CSS3 بمناسبة رمضان - سوالف سوفت Says:

    [...] HTML5 storage الجزء الثانى __________________ Keepondev | مدونه شديد التخصص فى الجافاسكربت جافاسكربت الموجهه بالكائنات | أنماط تصميم جافاسكربت [...]

  4. اخبار تقنية Says:

    بالفعل شرح لا يوصف قمة
    الله يعطيك العافية

  5. أبو محمد اللحياني Says:

    جزاك الله خيراً على الشرح المتيّز

    زادك الله علماً.

    عندما أردت تطبيق الدرس على فايرفوكس وجدت اختلاف في طريقة دعم هذه الميزة فبحثت عن إضافة لـ jQuery فالحمد لله وجدتها :

    http://plugins.jquery.com/project/jStore

    وهي تدعم جميع أنواع التخزين على طرف المتصفح

  6. abd Says:

    الله يعطيك العافة اخ مصطفى
    بس ممكن شرح كيف اربط الجافا سكريبت مع الاس كيو ال لايت
    يعني رح حطو بالوكال هوست الا كيف
    بتمنى التوضيح
    والله يعطيك العافة

    • mostafa farghaly Says:

      قواعد بيانات المتصقح لا تتفاعل مع ملفات سكولايت كما هو الحال خارج المتصفح ، لكن يتم إنشاء قاعدة البيانات إن لم يتم إنشائها من قبل عن طريق SQL ، ثم التفاعل معها كما وضحت فى المقال أيضا عن طريق SQL بالإضافة إلى JavaScript local database api

  7. مها Says:

    الله يعطيك العافية

    بس عندي سؤال : كيف احصل على ال DB ?

    هل يمكن استخدام MS SQL 2008?
    هل يمكننى الحصول على المثال كامل ؟

    • mostafa farghaly Says:

      الموضوع يتحدث عن ال local database اللى موجودة فى المتصفحات ضمن مواصفات HTML5 و هى من نوع SQLite ، بالطبع لا يمكنك إستخدام MS SQL08 فى المتصفح لكن يمكنك إستخدامها فى السيرفر بإستخدام ASP.net مع C# مثلا

  8. waleed Says:

    شكرااا

  9. haneen Says:

    عاوز اعرف مفهوم ال real time transaction في ال data base

أضف تعليق

إملأ الحقول أدناه بالمعلومات المناسبة أو إضغط على إحدى الأيقونات لتسجيل الدخول:

WordPress.com Logo

You are commenting using your WordPress.com account. تسجيل الخروج / تغيير )

Twitter picture

You are commenting using your Twitter account. تسجيل الخروج / تغيير )

Facebook photo

You are commenting using your Facebook account. تسجيل الخروج / تغيير )

Google+ photo

You are commenting using your Google+ account. تسجيل الخروج / تغيير )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: