• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / edge-runtime / 16258210110

14 Jul 2025 04:48AM UTC coverage: 51.236% (-0.5%) from 51.727%
16258210110

Pull #557

github

web-flow
Merge b17bea00d into 92d91b5b5
Pull Request #557: feat: add v2.2.0 `node:sqlite` support

0 of 336 new or added lines in 2 files covered. (0.0%)

2 existing lines in 2 files now uncovered.

18222 of 35565 relevant lines covered (51.24%)

5523.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/ext/node/ops/sqlite/database.rs
1
// Copyright 2018-2025 the Deno authors. MIT license.
2

3
use std::cell::Cell;
4
use std::cell::RefCell;
5
use std::rc::Rc;
6

7
use deno_core::anyhow;
8
use deno_core::anyhow::anyhow;
9
use deno_core::op2;
10
use deno_core::GarbageCollected;
11
use serde::Deserialize;
12

13
use super::StatementSync;
14

NEW
15
#[derive(Deserialize)]
×
16
#[serde(rename_all = "camelCase")]
17
struct DatabaseSyncOptions {
18
  #[serde(default = "true_fn")]
19
  open: bool,
20
  #[serde(default = "true_fn")]
21
  enable_foreign_key_constraints: bool,
22
}
23

NEW
24
fn true_fn() -> bool {
×
NEW
25
  true
×
NEW
26
}
×
27

28
impl Default for DatabaseSyncOptions {
NEW
29
  fn default() -> Self {
×
NEW
30
    DatabaseSyncOptions {
×
NEW
31
      open: true,
×
NEW
32
      enable_foreign_key_constraints: true,
×
NEW
33
    }
×
NEW
34
  }
×
35
}
36

37
pub struct DatabaseSync {
38
  conn: Rc<RefCell<Option<rusqlite::Connection>>>,
39
  options: DatabaseSyncOptions,
40
  location: String,
41
}
42

43
impl GarbageCollected for DatabaseSync {}
44

45
// Represents a single connection to a SQLite database.
NEW
46
#[op2]
×
47
impl DatabaseSync {
48
  // Constructs a new `DatabaseSync` instance.
49
  //
50
  // A SQLite database can be stored in a file or in memory. To
51
  // use a file-backed database, the `location` should be a path.
52
  // To use an in-memory database, the `location` should be special
53
  // name ":memory:".
54
  #[constructor]
55
  #[cppgc]
NEW
56
  fn new(
×
NEW
57
    #[string] location: String,
×
NEW
58
    #[serde] options: Option<DatabaseSyncOptions>,
×
NEW
59
  ) -> Result<DatabaseSync, anyhow::Error> {
×
NEW
60
    let options = options.unwrap_or_default();
×
61

NEW
62
    let db = if options.open {
×
NEW
63
      let db = rusqlite::Connection::open(&location)?;
×
NEW
64
      if options.enable_foreign_key_constraints {
×
NEW
65
        db.execute("PRAGMA foreign_keys = ON", [])?;
×
NEW
66
      }
×
NEW
67
      Some(db)
×
68
    } else {
NEW
69
      None
×
70
    };
71

NEW
72
    Ok(DatabaseSync {
×
NEW
73
      conn: Rc::new(RefCell::new(db)),
×
NEW
74
      location,
×
NEW
75
      options,
×
NEW
76
    })
×
NEW
77
  }
×
78

79
  // Opens the database specified by `location` of this instance.
80
  //
81
  // This method should only be used when the database is not opened
82
  // via the constructor. An exception is thrown if the database is
83
  // already opened.
84
  #[fast]
NEW
85
  fn open(&self) -> Result<(), anyhow::Error> {
×
NEW
86
    if self.conn.borrow().is_some() {
×
NEW
87
      return Err(anyhow!("Database is already open"));
×
NEW
88
    }
×
89

NEW
90
    let db = rusqlite::Connection::open(&self.location)?;
×
NEW
91
    if self.options.enable_foreign_key_constraints {
×
NEW
92
      db.execute("PRAGMA foreign_keys = ON", [])?;
×
NEW
93
    }
×
94

NEW
95
    *self.conn.borrow_mut() = Some(db);
×
NEW
96

×
NEW
97
    Ok(())
×
NEW
98
  }
×
99

100
  // Closes the database connection. An exception is thrown if the
101
  // database is not open.
102
  #[fast]
NEW
103
  fn close(&self) -> Result<(), anyhow::Error> {
×
NEW
104
    if self.conn.borrow().is_none() {
×
NEW
105
      return Err(anyhow!("Database is already closed"));
×
NEW
106
    }
×
NEW
107

×
NEW
108
    *self.conn.borrow_mut() = None;
×
NEW
109
    Ok(())
×
NEW
110
  }
×
111

112
  // This method allows one or more SQL statements to be executed
113
  // without returning any results.
114
  //
115
  // This method is a wrapper around sqlite3_exec().
116
  #[fast]
NEW
117
  fn exec(&self, #[string] sql: &str) -> Result<(), anyhow::Error> {
×
NEW
118
    let db = self.conn.borrow();
×
NEW
119
    let db = db.as_ref().ok_or(anyhow!("Database is already in use"))?;
×
120

NEW
121
    let mut stmt = db.prepare_cached(sql)?;
×
NEW
122
    stmt.raw_execute()?;
×
123

NEW
124
    Ok(())
×
NEW
125
  }
×
126

127
  // Compiles an SQL statement into a prepared statement.
128
  //
129
  // This method is a wrapper around `sqlite3_prepare_v2()`.
130
  #[cppgc]
NEW
131
  fn prepare(
×
NEW
132
    &self,
×
NEW
133
    #[string] sql: &str,
×
NEW
134
  ) -> Result<StatementSync, anyhow::Error> {
×
NEW
135
    let db = self.conn.borrow();
×
NEW
136
    let db = db.as_ref().ok_or(anyhow!("Database is already in use"))?;
×
137

138
    // SAFETY: lifetime of the connection is guaranteed by reference
139
    // counting.
NEW
140
    let raw_handle = unsafe { db.handle() };
×
NEW
141

×
NEW
142
    let mut raw_stmt = std::ptr::null_mut();
×
NEW
143

×
NEW
144
    // SAFETY: `sql` points to a valid memory location and its length
×
NEW
145
    // is correct.
×
NEW
146
    let r = unsafe {
×
NEW
147
      libsqlite3_sys::sqlite3_prepare_v2(
×
NEW
148
        raw_handle,
×
NEW
149
        sql.as_ptr() as *const _,
×
NEW
150
        sql.len() as i32,
×
NEW
151
        &mut raw_stmt,
×
NEW
152
        std::ptr::null_mut(),
×
NEW
153
      )
×
NEW
154
    };
×
NEW
155

×
NEW
156
    if r != libsqlite3_sys::SQLITE_OK {
×
NEW
157
      return Err(anyhow!("Failed to prepare statement"));
×
NEW
158
    }
×
NEW
159

×
NEW
160
    Ok(StatementSync {
×
NEW
161
      inner: raw_stmt,
×
NEW
162
      db: self.conn.clone(),
×
NEW
163
      use_big_ints: Cell::new(false),
×
NEW
164
    })
×
NEW
165
  }
×
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc