vwh / sqlite-viewer

View and query SQLite databases in the browser
https://sqlite3.online
MIT License
49 stars 4 forks source link

Use in app? #50

Closed mustafa0x closed 1 month ago

mustafa0x commented 1 month ago

Hi, awesome project!

Question: I have a svelte app, and would like to embed this sqlite viewer. Is there a package that I can add that exposes an API that accepts a binary blob (Uint8Array)?

vwh commented 1 month ago

Hello.

I don't think so but you can make your own really easily use sql.js https://github.com/sql-js/sql.js

mustafa0x commented 1 month ago

Thanks @vwh. It'll work if a method (similar to loadDatabase) is added to window (or globalThis) that accepts bytes. Then I could use in the following manner.

<iframe id="sql-viewer" src="sqlviewer.html"></iframe>
<script>
const iframe = document.getElementById('sql-viewer')
iframe.contentWindow.loadDatabaseBytes(Uint8Array)
</script>

(Side note: this would be easier if vite was configured to only create a single bundle.)

vwh commented 1 month ago

Sorry for late response.

That's a nice feature for sure. I will try to make it soon or if you want to add it your self feel free to do so would be a great addition

vwh commented 1 month ago

@mustafa0x I have added it!

Example:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>SQLite Viewer</title>
    <style>
      iframe {
        width: 100%;
        height: 500px;
        border: 1px solid #ccc;
      }
    </style>
  </head>
  <body>
    <iframe id="sql-viewer" src="https://sqlite3.online"></iframe>
    <script>
      // Function to fetch the database file and convert it to Uint8Array
      async function fetchDatabaseFile(url) {
        try {
          const response = await fetch(url);
          if (!response.ok) {
            throw new Error("Failed to fetch database file");
          }
          const arrayBuffer = await response.arrayBuffer();
          return new Uint8Array(arrayBuffer); // Convert to Uint8Array
        } catch (error) {
          console.error("Error fetching the database file:", error);
          return null;
        }
      }

      const iframe = document.getElementById("sql-viewer");
      iframe.onload = async () => {
        const win = iframe.contentWindow;

        // Fetch the static database file from the same host
        const databaseFileBytes = await fetchDatabaseFile("./chinook.db");

        if (databaseFileBytes) {
          // Sending the database file bytes to the iframe
          win.postMessage(
            {
              type: "invokeLoadDatabaseBytes",
              bytes: databaseFileBytes, // Send Uint8Array to iframe
            },
            "https://sqlite3.online"
          );
        } else {
          console.error("Failed to load the database file");
        }
      };

      // Listen for responses from the iframe
      window.addEventListener("message", (event) => {
        if (event.origin !== "https://sqlite3.online") return;

        if (event.data.type === "loadDatabaseBytesSuccess") {
          console.log("Successfully loaded database bytes in the iframe");
        }

        if (event.data.type === "loadDatabaseBytesError") {
          console.error(
            "Failed to load database bytes in the iframe:",
            event.data.error
          );
        }
      });
    </script>
  </body>
</html>
mustafa0x commented 1 month ago

Awesome, thank you so much!