Joey Cadieux
Joey Cadieux

Reputation: 1

How can I ensure my SQLite database is initialized before interacting with it in a web app using sql.js and IndexedDB

I'm building a web app using sql.js with WebAssembly to manage a SQLite database in the browser. I'm storing the SQLite database in IndexedDB and need to ensure that the database is loaded and initialized properly before performing any SQL operations.

Here's the current setup:

When the page loads, I try to load the database from IndexedDB or create a new one if it doesn't exist. I’m using async/await to load the database, but I’m still running into issues where I try to interact with the database before it has been fully initialized.

When I attempt to insert data into the SQLite database or run queries, I sometimes encounter the error: "Database is not initialized."

let db;
const dbName = "db_transactions.db"; // Your specific database name

// Function to load the database from IndexedDB
async function loadDatabaseFromIndexedDB() {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open('sqliteDBs', 1); // Open IndexedDB database
    request.onupgradeneeded = () => {
      const dbStore = request.result.createObjectStore('databases', {
        keyPath: 'name'
      });
    };

    request.onsuccess = () => {
      const dbStore = request.result.transaction('databases', 'readwrite').objectStore('databases');
      const getRequest = dbStore.get(dbName);

      getRequest.onsuccess = function() {
        const data = getRequest.result;
        if (data) {
          // Import the saved database binary data
          db = new SQL.Database(new Uint8Array(data.dbBinary));
          resolve(db);
        } else {
          // If no saved database, create a new one
          db = new SQL.Database();
          resolve(db);
        }
      };
      getRequest.onerror = reject;
    };

    request.onerror = reject;
  });
}

// Function to save the database to IndexedDB
async function saveDatabaseToIndexedDB(db) {
  const binaryData = db.export(); // Export the SQLite database to binary format

  return new Promise((resolve, reject) => {
    const request = indexedDB.open('sqliteDBs', 1); // Open IndexedDB database
    request.onupgradeneeded = () => {
      const dbStore = request.result.createObjectStore('databases', {
        keyPath: 'name'
      });
    };

    request.onsuccess = () => {
      const dbStore = request.result.transaction('databases', 'readwrite').objectStore('databases');
      const putRequest = dbStore.put({
        name: dbName,
        dbBinary: binaryData
      });

      putRequest.onsuccess = resolve;
      putRequest.onerror = reject;
    };

    request.onerror = reject;
  });
}

// Function to initialize the database
async function initializeDatabase() {
  try {
    // Wait for the database to be loaded
    await loadDatabaseFromIndexedDB();
    console.log("Database loaded from IndexedDB or created.");

    // Create table if not exists
    db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT);");
    console.log("Table 'users' created or already exists.");
  } catch (err) {
    console.error("Failed to initialize database:", err);
  }
}

// Wait for the database to initialize before allowing interactions
initializeDatabase().then(() => {
  console.log("Database is initialized.");
});

// Handle form submission
document.getElementById('dataForm').addEventListener('submit', async function(event) {
  event.preventDefault();

  // Ensure db is initialized before proceeding
  if (!db) {
    console.error("Database is not initialized.");
    return;
  }

  // Get form data
  const name = document.getElementById('name').value;
  const email = document.getElementById('email').value;

  // Insert data into the SQLite database
  try {
    db.run("INSERT INTO users (name, email) VALUES (?, ?);", [name, email]);

    // Save the updated database to IndexedDB
    await saveDatabaseToIndexedDB(db);
    console.log('Database saved to IndexedDB.');

    // Retrieve and display data from the database
    const result = db.exec("SELECT * FROM users;");
    document.getElementById('output').textContent = JSON.stringify(result, null, 2);
  } catch (err) {
    console.error("Error while inserting data or saving database:", err);
  }
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>SQLite with WebAssembly</title>
  <!-- Correct inclusion of sql.js -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/sql-wasm.js"></script>
</head>

<body>
  <h1>SQLite with WebAssembly (Persistent Database)</h1>

  <form id="dataForm">
    <label for="name">Name:</label>
    <input type="text" id="name" name="name" required><br><br>

    <label for="email">Email:</label>
    <input type="email" id="email" name="email" required><br><br>

    <button type="submit">Submit</button>
  </form>

  <h2>Database Output</h2>
  <pre id="output"></pre>


</body>

</html>

Upvotes: 0

Views: 42

Answers (0)

Related Questions