sqlite_web_vfs 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rbconfig'
4
+
5
+ module SQLiteWebVFS
6
+ module Loader
7
+ module_function
8
+
9
+ # Absolute path to the built native extension (.bundle/.so)
10
+ def built_extension_path
11
+ # The compiled extension is installed under this logical name by extconf.rb
12
+ require_path = File.join('sqlite_web_vfs', 'sqlite_web_vfs')
13
+ # Find the actual full path Ruby would use for this require
14
+ $LOAD_PATH.each do |lp|
15
+ Dir[File.join(lp, "#{require_path}.{so,bundle,dll}")].each do |p|
16
+ return p if File.file?(p)
17
+ end
18
+ # Ruby might place it in a versioned directory under lp/sqlite_web_vfs
19
+ Dir[File.join(lp, 'sqlite_web_vfs', 'sqlite_web_vfs.{so,bundle,dll}')].each do |p|
20
+ return p if File.file?(p)
21
+ end
22
+ end
23
+ nil
24
+ end
25
+
26
+ # Load the HTTP VFS into the process (auto-applied to connections).
27
+ # This only requires the compiled extension; it registers itself via sqlite3_auto_extension.
28
+ # Security note: Loading extensions can execute native code. Only load trusted code.
29
+ def load(db = nil)
30
+ begin
31
+ require 'sqlite_web_vfs/sqlite_web_vfs'
32
+ rescue LoadError
33
+ raise_load_error(<<~MSG)
34
+ Could not locate the sqlite_web_vfs native extension. Ensure the gem built correctly.
35
+ - macOS: brew install sqlite curl
36
+ - Amazon Linux 2023: sudo dnf install sqlite-devel libcurl-devel
37
+ If SQLite is installed but detection failed, rebuild with:
38
+ gem uninstall sqlite_web_vfs && gem install sqlite_web_vfs -- --with-sqlite3-dir=/path/to/prefix
39
+ To force building with a bundled SQLite amalgamation (advanced):
40
+ WEBVFS_FORCE_BUNDLED=1 gem install sqlite_web_vfs
41
+ MSG
42
+ end
43
+
44
+ # Determine loaded extension path, if any
45
+ dlex = %w[so bundle dll]
46
+ so = $LOADED_FEATURES.find do |f|
47
+ dlex.any? { |ext| f.end_with?("/sqlite_web_vfs/sqlite_web_vfs.#{ext}") }
48
+ end
49
+
50
+ # Ensure the current connection loads the extension too (auto-extension affects future opens)
51
+ if db
52
+ db.enable_load_extension(true) if db.respond_to?(:enable_load_extension)
53
+ if db.respond_to?(:load_extension)
54
+ db.load_extension(so) if so
55
+ elsif db.respond_to?(:api) && db.api.respond_to?(:load_extension)
56
+ if so
57
+ rc = db.api.load_extension(db.handle, so, nil, nil)
58
+ raise_load_error("sqlite3-ffi load_extension failed with code #{rc}") unless rc.zero?
59
+ end
60
+ end
61
+ end
62
+ so
63
+ end
64
+
65
+ def raise_load_error(msg)
66
+ raise LoadError, "SQLiteWebVFS::Loader: #{msg}"
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'sqlite_web_vfs/loader'
4
+
5
+ module SQLiteWebVFS
6
+ # Requiring the compiled extension ensures the VFS registers via sqlite3_auto_extension.
7
+ begin
8
+ require 'sqlite_web_vfs/sqlite_web_vfs'
9
+ rescue LoadError
10
+ # The loader will surface clearer installation instructions when used.
11
+ end
12
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require_relative '../spec_helper'
5
+ require 'sqlite_web_vfs'
6
+
7
+ RSpec.describe SQLiteWebVFS do
8
+ let(:chinook_url) { 'https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite' }
9
+ let(:encoded_url) { URI.encode_www_form_component(chinook_url) }
10
+ let(:web_uri) { "file:/__web__?vfs=web&mode=ro&immutable=1&web_url=#{encoded_url}" }
11
+
12
+ it 'loads and queries remote DB via sqlite3 gem' do
13
+ begin
14
+ require 'sqlite3'
15
+ rescue LoadError
16
+ skip 'sqlite3 gem not available'
17
+ end
18
+ db = SQLite3::Database.new(':memory:')
19
+ SQLiteWebVFS::Loader.load(db)
20
+ db.execute('ATTACH DATABASE ? AS remote', [web_uri])
21
+ count = db.get_first_value('SELECT COUNT(*) FROM remote.Album')
22
+ expect(count).to be_a(Integer)
23
+ ensure
24
+ db&.close
25
+ end
26
+
27
+ it 'loads and queries remote DB via sqlite3-ffi gem' do
28
+ begin
29
+ begin
30
+ require 'sqlite3-ffi'
31
+ rescue LoadError
32
+ require 'sqlite3/ffi'
33
+ end
34
+ rescue LoadError
35
+ skip 'sqlite3-ffi gem not available'
36
+ end
37
+ db = SQLite3::Database.new(':memory:')
38
+ SQLiteWebVFS::Loader.load(db)
39
+ db.execute('ATTACH DATABASE ? AS remote', [web_uri])
40
+ count = db.execute('SELECT COUNT(*) FROM remote.Album').first.first
41
+ expect(count).to be_a(Integer)
42
+ ensure
43
+ db&.close
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+ require_relative '../spec_helper'
5
+ require 'sqlite_web_vfs'
6
+
7
+ RSpec.describe SQLiteWebVFS do
8
+ let(:chinook_url) { ENV['CHINOOK_URL'] || 'https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite' }
9
+ let(:encoded_url) { URI.encode_www_form_component(chinook_url) }
10
+ let(:web_uri) { "file:/__web__?vfs=web&mode=ro&immutable=1&web_url=#{encoded_url}" }
11
+
12
+ it 'loads and queries remote DB via sqlite3 gem' do
13
+ begin
14
+ require 'sqlite3'
15
+ rescue LoadError
16
+ skip 'sqlite3 gem not available'
17
+ end
18
+ db = SQLite3::Database.new(':memory:')
19
+ SQLiteWebVFS::Loader.load(db)
20
+ db.execute('ATTACH DATABASE ? AS remote', [web_uri])
21
+ count = db.get_first_value('SELECT COUNT(*) FROM remote.Album')
22
+ expect(count).to be_a(Integer)
23
+ ensure
24
+ db&.close
25
+ end
26
+
27
+ it 'loads and queries remote DB via sqlite3-ffi gem' do
28
+ begin
29
+ begin
30
+ require 'sqlite3-ffi'
31
+ rescue LoadError
32
+ require 'sqlite3/ffi'
33
+ end
34
+ rescue LoadError
35
+ skip 'sqlite3-ffi gem not available'
36
+ end
37
+ db = SQLite3::Database.new(':memory:')
38
+ SQLiteWebVFS::Loader.load(db)
39
+ db.execute('ATTACH DATABASE ? AS remote', [web_uri])
40
+ count = db.execute('SELECT COUNT(*) FROM remote.Album').first.first
41
+ expect(count).to be_a(Integer)
42
+ ensure
43
+ db&.close
44
+ end
45
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.configure do |config|
4
+ config.expect_with :rspec do |c|
5
+ c.syntax = :expect
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqlite_web_vfs
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Denis Sablic
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Builds and loads the HTTP VFS from mlin/sqlite_web_vfs for SQLite, enabling
13
+ remote DB access over HTTP(S) via Range requests.
14
+ email: denis.sablic@gmail.com
15
+ executables: []
16
+ extensions:
17
+ - ext/sqlite_web_vfs/extconf.rb
18
+ extra_rdoc_files: []
19
+ files:
20
+ - LICENSE-3RD-PARTY.md
21
+ - README.md
22
+ - examples/sqlite3_example.rb
23
+ - examples/sqlite3_ffi_example.rb
24
+ - ext/sqlite_web_vfs/Makefile
25
+ - ext/sqlite_web_vfs/_wrap_web_vfs.o
26
+ - ext/sqlite_web_vfs/extconf.rb
27
+ - ext/sqlite_web_vfs/readerwriterqueue.h
28
+ - ext/sqlite_web_vfs/shim.c
29
+ - ext/sqlite_web_vfs/shim.o
30
+ - ext/sqlite_web_vfs/upstream/HTTP.h
31
+ - ext/sqlite_web_vfs/upstream/SQLiteVFS.h
32
+ - ext/sqlite_web_vfs/upstream/ThreadPool.h
33
+ - ext/sqlite_web_vfs/upstream/atomicops.h
34
+ - ext/sqlite_web_vfs/upstream/dbi.h
35
+ - ext/sqlite_web_vfs/upstream/readerwriterqueue.h
36
+ - ext/sqlite_web_vfs/upstream/web_vfs.cc
37
+ - ext/sqlite_web_vfs/upstream/web_vfs.h
38
+ - lib/sqlite_web_vfs.rb
39
+ - lib/sqlite_web_vfs/loader.rb
40
+ - spec/integration/sq_lite_web_vfs_integration_spec.rb
41
+ - spec/integration/sqlite_web_vfs_integration_spec.rb
42
+ - spec/spec_helper.rb
43
+ homepage: https://github.com/dsablic/sqlite_web_vfs
44
+ licenses:
45
+ - BSD-3-Clause
46
+ metadata:
47
+ rubygems_mfa_required: 'true'
48
+ source_code_uri: https://github.com/dsablic/sqlite_web_vfs
49
+ bug_tracker_uri: https://github.com/dsablic/sqlite_web_vfs/issues
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 3.2.0
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 4.0.6
65
+ specification_version: 4
66
+ summary: Loadable SQLite HTTP VFS (Ruby loader)
67
+ test_files: []