SQLite Wasm ในเบราว์เซอร์ที่สนับสนุนโดยระบบไฟล์ส่วนตัวต้นทาง

ใช้ SQLite เพื่อจัดการพื้นที่เก็บข้อมูลทั้งหมดบนเว็บอย่างมีประสิทธิภาพ

เกี่ยวกับ SQLite

SQLite คือแท็กยอดนิยม โอเพนซอร์ส, ใช้ทรัพยากรน้อย, เชิงสัมพันธ์แบบฝัง ระบบจัดการฐานข้อมูล นักพัฒนาซอฟต์แวร์จำนวนมากใช้แพลตฟอร์มนี้เพื่อจัดเก็บข้อมูลใน มีโครงสร้างและใช้งานง่าย เนื่องจากมีขนาดเล็กและหน่วยความจำต่ำ SQLite มักใช้เป็นเครื่องมือฐานข้อมูลในอุปกรณ์เคลื่อนที่ แอปพลิเคชันบนเดสก์ท็อปและเว็บเบราว์เซอร์

ฟีเจอร์ที่สำคัญอย่างหนึ่งของ SQLite คือฐานข้อมูลแบบ Serverless ทำให้ไม่จำเป็นต้องมีกระบวนการของเซิร์ฟเวอร์แยกต่างหากในการดำเนินการ แต่ จัดเก็บฐานข้อมูลไว้ในไฟล์เดียวบนอุปกรณ์ของผู้ใช้ ทำให้ ผสานรวมไว้ในแอปพลิเคชันต่างๆ

โลโก้ SQLite

SQLite ที่อิงตามการประกอบเว็บ

SQLite เวอร์ชันที่ไม่เป็นทางการมีอยู่จำนวนหนึ่งโดยอิงจาก Web Assembly (Wasm) ที่สามารถใช้ในเว็บเบราว์เซอร์ได้ เช่น sql.js โปรเจ็กต์ย่อย sqlite3 WASM/JS คือ เพื่อเชื่อมโยงอย่างเป็นทางการกับ โปรเจ็กต์ SQLite ที่สร้างไลบรารี Wasm สมาชิกที่ก่อตั้งขึ้นของกลุ่มการส่งมอบ SQLite ที่รองรับ อย่างเป็นรูปธรรม เป้าหมายของโครงการนี้ ได้แก่

  • การผูก sqlite3 API ระดับล่างซึ่งใกล้เคียงกับ API ระดับ C มากที่สุดเท่าที่จะทำได้ ข้อกำหนดในการให้บริการ
  • API ระดับออบเจ็กต์ที่สูงขึ้น คล้ายกับ sql.js และ การติดตั้งใช้งานสไตล์ Node.js ที่ จะสื่อสารกับ API ระดับต่ำได้โดยตรง API นี้ต้องใช้จาก เทรดเป็น API ระดับต่ำ
  • API แบบ Worker ซึ่งพูดคุยกับ API ก่อนหน้านี้ผ่านข้อความของ Worker ช่วงเวลานี้ มีไว้สําหรับใช้ในเทรดหลัก กับ API ระดับล่าง ติดตั้งไว้ในชุดข้อความของผู้ปฏิบัติงาน และพูดคุยกับพวกเขาผ่านข้อความของผู้ปฏิบัติงาน
  • Worker API เวอร์ชันที่อิงตาม Promise ซึ่งซ่อน ด้านการสื่อสารข้ามชุดข้อความจากผู้ใช้
  • การรองรับพื้นที่เก็บข้อมูลฝั่งไคลเอ็นต์แบบถาวรโดยใช้ JavaScript API ที่พร้อมใช้งาน ซึ่งรวมถึง Origin Private File System (OPFS)

การใช้ SQLite Wasm กับแบ็กเอนด์การถาวรของระบบไฟล์ส่วนตัวต้นทาง

การติดตั้งไลบรารีจาก npm

ติดตั้ง @sqlite.org/sqlite-wasm แพ็กเกจจาก npm ด้วยคำสั่งต่อไปนี้

npm install @sqlite.org/sqlite-wasm

ระบบไฟล์ส่วนตัวต้นทาง

Origin Private File System (OPFS, ส่วนหนึ่งของ File System Access API) ได้รับการเสริมด้วย แพลตฟอร์มพิเศษที่ให้การเข้าถึงข้อมูลได้อย่างมีประสิทธิภาพ แพลตฟอร์มใหม่นี้ แตกต่างจากที่มีอยู่เดิมโดยให้สิทธิ์การเขียนที่มีอยู่ใน ของเนื้อหาของไฟล์ การเปลี่ยนแปลงนี้ พร้อมกับความสามารถในการอ่าน การแก้ไขที่ไม่ได้ล้างและความพร้อมใช้งานของตัวแปรแบบพร้อมกันใน ผู้ปฏิบัติงานที่ทุ่มเท ปรับปรุงประสิทธิภาพการทำงานและเลิกบล็อกผู้ใช้ใหม่ๆ ได้อย่างมาก กรณี

คุณคงพอนึกออกว่า ประเด็นสุดท้ายของเป้าหมาย ของโครงการคือการสนับสนุนสำหรับ พื้นที่เก็บข้อมูลฝั่งไคลเอ็นต์แบบคงที่โดยใช้ JavaScript API ที่มีให้ใช้งาน ข้อกำหนดด้านประสิทธิภาพที่เข้มงวดเกี่ยวกับการคงข้อมูลไว้ในไฟล์ฐานข้อมูล ซึ่งเป็นตำแหน่งที่ระบบไฟล์ส่วนตัวต้นทาง (กล่าวอย่างเจาะจงคือ createSyncAccessHandle() วิธีการ FileSystemFileHandle ต่างๆ จะปรากฏขึ้นมา วิธีนี้จะแสดง "คำสัญญา" ซึ่งระบุเป็น FileSystemSyncAccessHandle ที่สามารถใช้เพื่ออ่านและเขียนไฟล์พร้อมกัน การทำงานของวิธีการนี้ที่ให้ผลพร้อมกัน มีข้อดีด้านประสิทธิภาพ แต่ สามารถใช้ได้ภายใน Web Workers สำหรับ ไฟล์ภายในระบบไฟล์ส่วนตัวต้นทาง เพื่อไม่ให้บล็อกเทรดหลัก

การตั้งค่าส่วนหัวที่จำเป็น

นอกเหนือจากไฟล์อื่นๆ ที่เก็บถาวร SQLite Wasm ที่ดาวน์โหลดมี sqlite3.js และ sqlite3.wasm ไฟล์ ซึ่งเป็นบิลด์ sqlite3 WASM/JS jswasm ไดเรกทอรีมีการส่งมอบ sqlite3 หลักและไดเรกทอรีระดับบนสุด มีแอปสาธิตและการทดสอบ เบราว์เซอร์จะไม่แสดงไฟล์ Wasm จาก file:// URL ดังนั้นแอปที่คุณสร้างด้วยสิ่งนี้จึงต้องใช้เว็บเซิร์ฟเวอร์ เซิร์ฟเวอร์ต้องมีส่วนหัวต่อไปนี้ในการตอบสนองเมื่อแสดง ไฟล์:

  • Cross-Origin-Opener-Policy ตั้งค่าเป็น คำสั่ง same-origin, ซึ่งจะแยกบริบทการท่องเว็บออกมาจากเอกสารต้นทางเดียวกันโดยเฉพาะ เอกสารข้ามต้นทางไม่ได้โหลดในบริบทการท่องเว็บเดียวกัน
  • Cross-Origin-Embedder-Policy ตั้งค่าเป็น คำสั่ง require-corp, ดังนั้นเอกสารจะโหลดได้เฉพาะทรัพยากรจากต้นทางเดียวกัน หรือจากแหล่งข้อมูลเดียวกัน มีการทำเครื่องหมายอย่างชัดแจ้งว่าโหลดได้จากต้นทางอื่น

เหตุผลสำหรับส่วนหัวเหล่านี้คือ SQLite Wasm ขึ้นอยู่กับ SharedArrayBuffer และการตั้งค่าส่วนหัวเหล่านี้เป็นส่วนหนึ่งของ ข้อกำหนดด้านความปลอดภัย

หากคุณตรวจสอบการเข้าชมด้วยเครื่องมือสำหรับนักพัฒนาเว็บ คุณจะพบสิ่งต่อไปนี้ ข้อมูล:

ส่วนหัว 2 รายการที่กล่าวถึงข้างต้น ได้แก่ Cross-Origin-Embedder-Policy และ Cross-Origin-Opener-Policy ที่ไฮไลต์ในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

Speedtest

ทีม SQLite ได้ใช้ตัวเปรียบเทียบในการใช้งาน WebAssembly แล้ว เมื่อเทียบกับ Web SQL ที่เลิกใช้งานแล้ว การเปรียบเทียบเหล่านี้แสดงให้เห็นว่า SQLite Wasm มีการ โดยทั่วไปแล้วเร็วเท่ากับ Web SQL ในบางครั้งก็ช้ากว่าเล็กน้อย บางครั้ง จะเร็วขึ้นเล็กน้อย ดูรายละเอียดทั้งหมดเกี่ยวกับ หน้าผลการค้นหา

ตัวอย่างโค้ดการเริ่มต้นใช้งาน

ดังที่กล่าวไว้ก่อนหน้านี้ SQLite Wasm ที่มีระบบไฟล์ส่วนตัวต้นทาง ต้องเรียกใช้แบ็กเอนด์ของความต่อเนื่องจากบริบทของ Worker ข่าวดีก็คือ ไลบรารีจะดูแลทั้งหมดนี้ให้คุณโดยอัตโนมัติ และคุณสามารถใช้ จากเทรดหลักโดยตรง

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

(async () => {
  try {
    console.log('Loading and initializing SQLite3 module...');

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

    console.log('Done initializing. Running demo...');

    let response;

    response = await promiser('config-get', {});
    console.log('Running SQLite3 version', response.result.version.libVersion);

    response = await promiser('open', {
      filename: 'file:worker-promiser.sqlite3?vfs=opfs',
    });
    const { dbId } = response;
    console.log(
      'OPFS is available, created persisted database at',
      response.result.filename.replace(/^file:(.*?)\?vfs=opfs$/, '$1'),
    );

    await promiser('exec', { dbId, sql: 'CREATE TABLE IF NOT EXISTS t(a,b)' });
    console.log('Creating a table...');

    console.log('Insert some data using exec()...');
    for (let i = 20; i <= 25; ++i) {
      await promiser('exec', {
        dbId,
        sql: 'INSERT INTO t(a,b) VALUES (?,?)',
        bind: [i, i * 2],
      });
    }

    console.log('Query data with exec()');
    await promiser('exec', {
      dbId,
      sql: 'SELECT a FROM t ORDER BY a LIMIT 3',
      callback: (result) => {
        if (!result.row) {
          return;
        }
        console.log(result.row);
      },
    });

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

สาธิต

ดูการทำงานของโค้ดข้างต้นในการสาธิต อย่าลืมดู ซอร์สโค้ด ใน Glitch โปรดสังเกตวิธีที่เวอร์ชันที่ฝังไว้ด้านล่างไม่ใช้แบ็กเอนด์ OPFS แต่เมื่อเปิดการสาธิตใน แท็บแยกต่างหากกัน

การแก้ไขข้อบกพร่องของระบบไฟล์ส่วนตัวต้นทาง

หากต้องการแก้ไขข้อบกพร่องเอาต์พุตระบบไฟล์ส่วนตัวต้นทางของ SQLite Wasm ให้ใช้เมธอด โปรแกรมสำรวจ OPFS ส่วนขยาย Chrome

OPFS Explorer ใน Chrome เว็บสโตร์

หลังจากติดตั้งส่วนขยายแล้ว ให้เปิดเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แล้วเลือก OPFS Explorer เท่านี้ก็พร้อมจะตรวจสอบสิ่งที่ SQLite Wasm เขียนไปยังฟังก์ชัน ระบบไฟล์ส่วนตัวต้นทาง

ส่วนขยาย OPFS Explorer ใน Chrome ที่แสดงโครงสร้างระบบไฟล์ส่วนตัวต้นทางของแอปเดโม

หากคลิกไฟล์ใดก็ได้ในหน้าต่าง OPFS Explorer ใน DevTools คุณจะ สามารถบันทึกลงในดิสก์ในเครื่องได้ จากนั้นคุณสามารถใช้แอปอย่างเช่น โปรแกรมดู SQLite เพื่อตรวจสอบฐานข้อมูลเพื่อให้คุณ ยืนยันตัวเองว่า SQLite Wasm ทำงานได้ตามที่สัญญาไว้จริงๆ

แอป SQLite Viewer ที่ใช้เปิดไฟล์ฐานข้อมูลจากการสาธิต SQLite Wasm

การรับความช่วยเหลือและการแสดงความคิดเห็น

SQLite Wasm ได้รับการพัฒนาและดูแลโดยชุมชน SQLite รับความช่วยเหลือและ แสดงความคิดเห็นด้วยการค้นหาและโพสต์ใน ฟอรัมสนับสนุน ภาพรวม เอกสารประกอบมีอยู่ในเว็บไซต์ SQLite

กิตติกรรมประกาศ

รูปภาพหลักโดย Tobias Fischer ใน หน้าจอแนะนํา