-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add sqlite_dbpage extension build tag #1320
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||
| // | ||
| // Use of this source code is governed by an MIT-style | ||
| // license that can be found in the LICENSE file. | ||
|
|
||
| //go:build sqlite_dbpage | ||
| // +build sqlite_dbpage | ||
|
|
||
| package sqlite3 | ||
|
|
||
| /* | ||
| #cgo CFLAGS: -DSQLITE_ENABLE_DBPAGE_VTAB | ||
| #cgo LDFLAGS: -lm | ||
| */ | ||
| import "C" |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,89 @@ | ||||||||||||
| // Copyright (C) 2019 Yasuhiro Matsumoto <mattn.jp@gmail.com>. | ||||||||||||
| // | ||||||||||||
| // Use of this source code is governed by an MIT-style | ||||||||||||
| // license that can be found in the LICENSE file. | ||||||||||||
|
|
||||||||||||
| //go:build sqlite_dbpage && cgo | ||||||||||||
| // +build sqlite_dbpage,cgo | ||||||||||||
|
|
||||||||||||
| package sqlite3 | ||||||||||||
|
|
||||||||||||
| import ( | ||||||||||||
| "database/sql" | ||||||||||||
| "os" | ||||||||||||
| "testing" | ||||||||||||
| ) | ||||||||||||
|
|
||||||||||||
| func TestDbpage(t *testing.T) { | ||||||||||||
| sourceFilename := TempFilename(t) | ||||||||||||
| defer os.Remove(sourceFilename) | ||||||||||||
|
|
||||||||||||
| destFilename := TempFilename(t) | ||||||||||||
| defer os.Remove(destFilename) | ||||||||||||
|
|
||||||||||||
| db, err := sql.Open("sqlite3", sourceFilename) | ||||||||||||
| if err != nil { | ||||||||||||
| t.Fatal("Failed to open database:", err) | ||||||||||||
| } | ||||||||||||
| defer db.Close() | ||||||||||||
|
|
||||||||||||
| if _, err = db.Exec("PRAGMA journal_mode=WAL"); err != nil { | ||||||||||||
| t.Fatal("Failed to Exec PRAGMA journal_mode:", err) | ||||||||||||
| } else if _, err := db.Exec("CREATE TABLE foo(data TEXT)"); err != nil { | ||||||||||||
| t.Fatal("Failed to create table:", err) | ||||||||||||
| } else if _, err := db.Exec("INSERT INTO foo(data) VALUES(?)", "hello sqlite_dbpage"); err != nil { | ||||||||||||
| t.Fatal("Failed to create table:", err) | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| rows, err := db.Query("SELECT data FROM sqlite_dbpage ORDER BY pgno") | ||||||||||||
| if err != nil && err.Error() == "no such table: sqlite_dbpage" { | ||||||||||||
| t.Skip("sqlite_dbpage not supported") | ||||||||||||
| } else if err != nil { | ||||||||||||
| t.Fatal("Unable to query sqlite_dbpage table:", err) | ||||||||||||
| } | ||||||||||||
| defer rows.Close() | ||||||||||||
|
|
||||||||||||
| destFile, err := os.OpenFile(destFilename, os.O_CREATE|os.O_WRONLY, 0600) | ||||||||||||
| if err != nil { | ||||||||||||
| t.Fatal("Unable to open file for writing:", err) | ||||||||||||
| } | ||||||||||||
| defer destFile.Close() | ||||||||||||
|
|
||||||||||||
| for rows.Next() { | ||||||||||||
| var page []byte | ||||||||||||
| if err := rows.Scan(&page); err != nil { | ||||||||||||
| t.Fatal("Unable to scan results:", err) | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| if _, err := destFile.Write(page); err != nil { | ||||||||||||
| t.Fatal("Unable to write page to file:", err) | ||||||||||||
| } | ||||||||||||
|
Comment on lines
+52
to
+60
|
||||||||||||
| } | ||||||||||||
|
||||||||||||
| } | |
| } | |
| if err := rows.Err(); err != nil { | |
| t.Fatal("Error iterating over rows:", err) | |
| } |
Copilot
AI
Mar 4, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test mixes defer Close() with explicit Close() calls later. That results in double-closes (especially for the file), and the deferred closes ignore any error. Prefer a single close strategy (typically defers that check errors in a deferred func) to avoid masking issues and reduce confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enabling
SQLITE_ENABLE_DBPAGE_VTABallows reading and (on newer SQLite versions) writing/deleting raw pages via SQL, which is unsafe when executing untrusted SQL. Consider adding a short warning in this README entry about the security implications and that it should only be enabled for trusted use-cases.