Switch indexeddb backend to sqlite and improve IPC messaging (#38187)

- Use sqlite instead of heed. (one indexed database = one sqlite
database)
- Implement the backend for indexes
- Use keyranges where needed (as specified by the spec)
- Implement `getKey`
- Fix channel error messaging (led to a bunch of changes to how async
requests are handled)

Note: `components/net/indexeddb/engines/sqlite/serialize.rs` is unused;
I can delete it if needed.

Testing: Switching to sqlite eliminated many panics (exposing some new
failures).
Fixes: #38040

---------

Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
This commit is contained in:
Ashwin Naren 2025-08-16 00:27:17 -07:00 committed by GitHub
parent f4bbdf8010
commit fc3feceee5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 2002 additions and 818 deletions

View file

@ -0,0 +1,59 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
pub(crate) fn create_tables(conn: &rusqlite::Connection) -> Result<(), rusqlite::Error> {
conn.execute(
r#"create table database
(
name varchar not null
primary key,
origin varchar not null,
version bigint default 0 not null
);"#,
[],
)?;
conn.execute(
r#"create table object_store
(
id integer not null
primary key autoincrement,
name varchar not null
unique,
key_path varbinary_blob,
auto_increment boolean default FALSE not null
);"#,
[],
)?;
conn.execute(
r#"create table object_data
(
object_store_id integer not null
references object_store,
key blob not null,
data blob not null,
constraint "pk-object_data"
primary key (object_store_id, key)
);"#,
[],
)?;
conn.execute(
r#"create table object_store_index
(
id integer not null
primary key autoincrement,
object_store_id integer not null
references object_store,
name varchar not null
unique,
key_path varbinary_blob not null,
unique_index boolean not null,
multi_entry_index boolean not null
);"#,
[],
)?;
Ok(())
}

View file

@ -0,0 +1,22 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use sea_query::Iden;
#[derive(Iden)]
#[expect(unused)]
pub enum Column {
Table,
Name,
Origin,
Version,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Model {
pub name: String,
pub origin: String,
pub version: i64,
// TODO: Hold timestamp for vacuuming
// TODO: implement vacuuming
}

View file

@ -0,0 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use rusqlite::Row;
use sea_query::Iden;
#[derive(Iden)]
pub enum Column {
Table,
ObjectStoreId,
Key,
Data,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Model {
pub object_store_id: i32,
pub key: Vec<u8>,
pub data: Vec<u8>,
}
impl TryFrom<&Row<'_>> for Model {
type Error = rusqlite::Error;
fn try_from(value: &Row) -> Result<Self, Self::Error> {
Ok(Self {
object_store_id: value.get(0)?,
key: value.get(1)?,
data: value.get(2)?,
})
}
}

View file

@ -0,0 +1,25 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use sea_query::Iden;
#[derive(Iden)]
#[expect(unused)]
pub enum Column {
Table,
ObjectStoreId,
Name,
KeyPath,
UniqueIndex,
MultiEntryIndex,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Model {
pub id: i32,
pub object_store_id: i32,
pub name: String,
pub key_path: Vec<u8>,
pub unique_index: bool,
pub multi_entry_index: bool,
}

View file

@ -0,0 +1,36 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use rusqlite::Row;
use sea_query::Iden;
#[derive(Iden)]
#[expect(unused)]
pub enum Column {
Table,
Id,
Name,
KeyPath,
AutoIncrement,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Model {
pub id: i32,
pub name: String,
pub key_path: Option<Vec<u8>>,
pub auto_increment: bool,
}
impl TryFrom<&Row<'_>> for Model {
type Error = rusqlite::Error;
fn try_from(value: &Row) -> Result<Self, Self::Error> {
Ok(Self {
id: value.get(0)?,
name: value.get(1)?,
key_path: value.get(2)?,
auto_increment: value.get(3)?,
})
}
}