מ-Web SQL ל-SQLite Wasm: המדריך להעברת מסדי נתונים

עם SQLite Wasm שמגובה על ידי מערכת הקבצים הפרטית של המקור, יש תחליף רב-תכליתי לטכנולוגיית מסד הנתונים Web SQL שהוצאה משימוש. במאמר הזה מוסבר איך להעביר נתונים מ-Web SQL ל-SQLite Wasm.

רקע נדרש

בפוסט הוצאה משימוש והסרה של Web SQL הודענו על הוצאה משימוש של טכנולוגיית מסד הנתונים Web SQL. הטכנולוגיה עצמה אולי הוצאה משימוש, אבל תרחישי השימוש שהיא נועדה לתת להם מענה עדיין רלוונטיים מאוד. לכן, בפוסט ההמשך SQLite Wasm in the browser backed by the Origin Private File System מפורטות טכנולוגיות חלופיות שמבוססות על מסד הנתונים SQLite, שעבר קומפילציה ל-Web Assembly‏ (Wasm), ומגובה על ידי מערכת הקבצים הפרטית של המקור. כדי להשלים את המעגל, במאמר הזה נסביר איך להעביר מסדי נתונים מ-Web SQL ל-SQLite Wasm.

העברת מסדי הנתונים

ארבעת השלבים הבאים מדגימים את הרעיון של העברת מסד נתונים של Web SQL ל-SQLite Wasm, כאשר מסד הנתונים של SQLite מגובה על ידי מערכת הקבצים הפרטית של המקור. הקוד הזה יכול לשמש כבסיס לקוד משלכם שמותאם לצרכים שלכם במיגרציה של Web SQL.

מסדי הנתונים של Web SQL שרוצים להעביר

ההנחה הבסיסית במדריך הזה היא שיש לכם מסד נתונים אחד (או כמה) של Web SQL שמכיל נתונים שרלוונטיים לאפליקציה שלכם. בצילום המסך שלמטה אפשר לראות מסד נתונים לדוגמה בשם mydatabase עם טבלה של סערות גשם שממפה מצבי רוח לדרגות חומרה. כלי הפיתוח ל-Chrome מאפשרים לצפות במסדי נתונים של Web SQL לצורך ניפוי באגים, כמו שמוצג בצילום המסך הבא.

מסד נתונים של Web SQL שנבדק בכלי הפיתוח של Chrome. מסד הנתונים נקרא mydatabase והוא מארח טבלה עם שלוש עמודות: row ID,‏ mood ו-severity. יש שלוש שורות של נתוני מדגם.

תרגום מסד הנתונים של Web SQL להצהרות SQL

כדי להעביר את הנתונים בצורה שקופה למשתמש, כלומר בלי לדרוש ממנו לבצע בעצמו את שלבי ההעברה, צריך לתרגם בחזרה את חלקי הנתונים במסד הנתונים להצהרות ה-SQL המקוריות שיצרו אותם מלכתחילה. האתגר הזה עלה בעבר, וסקריפט ההעברה שמופיע במאמר הזה – mywebsqldump.js – מבוסס על ספרייה של הקהילה שנקראת websqldump.js, עם כמה שינויים קלים. דוגמת הקוד הבאה מציגה את הקוד שנדרש כדי לתרגם את מסד הנתונים mydatabase של Web SQL לקבוצה של הצהרות SQL.

websqldump.export({
  database: 'mydatabase',
  version: '1.0',
  success: function(sql) {
    // The SQL statements.
  },
  error: function(err) {
    // Handle the error.
  }
});

הפעלת הקוד הזה יוצרת את מחרוזת פקודות ה-SQL שמופיעה בהמשך.

CREATE TABLE IF NOT EXISTS rainstorms (mood text, severity int);
INSERT INTO rainstorms(mood,severity) VALUES ('somber','6');
INSERT INTO rainstorms(mood,severity) VALUES ('rainy','8');
INSERT INTO rainstorms(mood,severity) VALUES ('stormy','2');

ייבוא הנתונים ל-SQLite Wasm

כל מה שנותר הוא להריץ את פקודות ה-SQL האלה בהקשר של SQLite Wasm. לכל הפרטים בנוגע להגדרת SQLite Wasm, אפשר לעיין במאמר SQLite Wasm בדפדפן עם גיבוי של מערכת הקבצים הפרטית של המקור. תקציר המאמר מופיע בהמשך. חשוב לזכור שהקוד הזה צריך לפעול ב-Worker (שהספרייה יוצרת אוטומטית בשבילכם), עם כותרות ה-HTTP הנדרשות שהוגדרו בצורה נכונה. אפשר להתקין את חבילת @sqlite.org/sqlite-wasm מ-npm.

import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';

(async () => {
  try {
    const promiser = await new Promise((resolve) => {
      const _promiser = sqlite3Worker1Promiser({
        onready: () => {
          resolve(_promiser);
        },
      });
    });

    let response;

    response = await promiser('open', {
      filename: 'file:mydatabase.db?vfs=opfs',
    });
    const { dbId } = response;

    const sql = `
      CREATE TABLE IF NOT EXISTS rainstorms (mood text, severity int);
      INSERT INTO rainstorms(mood,severity) VALUES ('somber','6');
      INSERT INTO rainstorms(mood,severity) VALUES ('rainy','8');
      INSERT INTO rainstorms(mood,severity) VALUES ('stormy','2');`
    await promiser('exec', { dbId, sql });

    await promiser('close', { dbId });
  } catch (err) {
    if (!(err instanceof Error)) {
      err = new Error(err.result.message);
    }
    console.error(err.name, err.message);
  }
})();

אחרי שמריצים את הקוד הזה, בודקים את קובץ מסד הנתונים המיובא באמצעות התוסף OPFS Explorer בכלי הפיתוח ל-Chrome. עכשיו יש שני קבצים, אחד עם מסד הנתונים בפועל ואחד עם פרטי היומן. שימו לב: שני הקבצים האלה נמצאים במערכת הקבצים הפרטית של המקור, ולכן צריך להשתמש בתוסף OPFS Explorer כדי לראות אותם.

בדיקת מערכת הקבצים הפרטית של המקור באמצעות כלי OPFS Explorer בכלי הפיתוח ל-Chrome. יש שני קבצים, אחד בשם mydatabase.db ואחד בשם mydatabase.db-journal.

כדי לוודא שהנתונים שיובאו זהים לנתוני Web SQL המקוריים, לוחצים על הקובץ mydatabase.db ומופיע תיבת דו-שיח של שמירת קובץ בתוסף OPFS Explorer, שמאפשרת לשמור את הקובץ במערכת הקבצים שגלויים למשתמש. אחרי ששומרים את קובץ מסד הנתונים, אפשר להשתמש באפליקציה לצפייה ב-SQLite כדי לבדוק את הנתונים. בProject Fugu API Showcase יש כמה אפליקציות לעבודה עם SQLite בדפדפן. לדוגמה, Sqlime — SQLite Playground מאפשר לכם לפתוח קובץ מסד נתונים של SQLite מהדיסק הקשיח ולהריץ שאילתות במסד הנתונים. כפי שאפשר לראות בצילום המסך שלמטה, הטבלה של סופת הגשם יובאה אל SQLite בצורה נכונה.

בדיקת הקובץ mydatabase.db בכלי Sqlime SQLite Playground. האפליקציה מוצגת עם שאילתת SQL select star from rainstorms limit 10 שמופעלת, והתוצאה היא שלוש השורות מנתוני המדגם הראשוניים מ-Web SQL.

פינוי נפח אחסון ב-Web SQL

אי אפשר למחוק מסד נתונים של Web SQL (אולי זה מפתיע), אבל עדיין כדאי לפנות מקום באחסון על ידי הסרת טבלאות Web SQL שכבר לא רלוונטיות אחרי העברת הנתונים ל-SQLite Wasm. כדי להציג רשימה של כל הטבלאות במסד נתונים של Web SQL ולהסיר אותן באמצעות JavaScript, משתמשים בקוד כמו בקטע הקוד הבא:

const dropAllTables = () => {
  try {
    db.transaction(function (tx) {
      tx.executeSql(
        "SELECT name FROM sqlite_master WHERE type='table' AND name !='__WebKitDatabaseInfoTable__'",
        [],
        function (tx, result) {
          const len = result.rows.length;
          const tableNames = [];
          for (let i = 0; i < len; i++) {
            const tableName = result.rows.item(i).name;
            tableNames.push(`'${tableName}'`);
            db.transaction(function (tx) {
              tx.executeSql('DROP TABLE ' + tableName);
            });
          }
          console.log(`Dropped table${tableNames.length > 1 ? 's' : ''}: ${tableNames.join(', ')}.`);
        }
      );
    });
  } catch (err) {
    console.error(err.name, err.message);
  }
};

עבודה עם הנתונים אחרי ההעברה

אחרי העברת הנתונים, אפשר לעבוד עם הנתונים כמו שמתואר בדוגמת הקוד הזו לתחילת העבודה. פרטים נוספים זמינים במאמר SQLite Wasm API reference. שוב נזכיר שצריך לגשת אל SQLite Wasm מ-Worker אם משתמשים במערכת קבצים פרטית של מקור כקצה העורפי של האחסון.

מסקנות

אפשר להעביר את מסדי הנתונים של Web SQL ל-SQLite Wasm שנתמך על ידי מערכת הקבצים הפרטית של המקור, באופן שקוף למשתמשים. הם לא ישימו לב שהנתונים שלהם מאוחסנים עכשיו במערכת קבצים פרטית של מקור בבסיס נתונים של SQLite, ולא ב-Web SQL. בסך הכול, מעבר מ-Web SQL ל-SQLite הוא שלב הכרחי למפתחי אתרים שרוצים להבטיח את היציבות וההתאמה לשינויים של האפליקציות שלהם בטווח הארוך. יכול להיות שהתהליך ידרוש מאמץ ראשוני, אבל היתרונות של פתרון מסד נתונים חזק וגמיש, ובעיקר כזה שמתאים לשימוש גם בעתיד, הופכים את ההשקעה לכדאית.