sqlite3-ffi 0.1.0

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,190 @@
1
+ require "sqlite3/errors"
2
+ require "sqlite3/resultset"
3
+
4
+ class String
5
+ def to_blob
6
+ SQLite3::Blob.new(self)
7
+ end
8
+ end
9
+
10
+ module SQLite3
11
+ # A statement represents a prepared-but-unexecuted SQL query. It will rarely
12
+ # (if ever) be instantiated directly by a client, and is most often obtained
13
+ # via the Database#prepare method.
14
+ class Statement
15
+ include Enumerable
16
+
17
+ # This is any text that followed the first valid SQL statement in the text
18
+ # with which the statement was initialized. If there was no trailing text,
19
+ # this will be the empty string.
20
+ attr_reader :remainder
21
+
22
+ # call-seq: SQLite3::Statement.new(db, sql)
23
+ #
24
+ # Create a new statement attached to the given Database instance, and which
25
+ # encapsulates the given SQL text. If the text contains more than one
26
+ # statement (i.e., separated by semicolons), then the #remainder property
27
+ # will be set to the trailing text.
28
+ def initialize(db, sql)
29
+ raise ArgumentError, "prepare called on a closed database" if db.closed?
30
+
31
+ sql = sql.encode(Encoding::UTF_8) if sql && sql.encoding != Encoding::UTF_8
32
+
33
+ @connection = db
34
+ @columns = nil
35
+ @types = nil
36
+ @remainder = prepare db, sql
37
+ end
38
+
39
+ # Binds the given variables to the corresponding placeholders in the SQL
40
+ # text.
41
+ #
42
+ # See Database#execute for a description of the valid placeholder
43
+ # syntaxes.
44
+ #
45
+ # Example:
46
+ #
47
+ # stmt = db.prepare( "select * from table where a=? and b=?" )
48
+ # stmt.bind_params( 15, "hello" )
49
+ #
50
+ # See also #execute, #bind_param, Statement#bind_param, and
51
+ # Statement#bind_params.
52
+ def bind_params(*bind_vars)
53
+ index = 1
54
+ bind_vars.flatten.each do |var|
55
+ if Hash === var
56
+ var.each { |key, val| bind_param key, val }
57
+ else
58
+ bind_param index, var
59
+ index += 1
60
+ end
61
+ end
62
+ end
63
+
64
+ # Execute the statement. This creates a new ResultSet object for the
65
+ # statement's virtual machine. If a block was given, the new ResultSet will
66
+ # be yielded to it; otherwise, the ResultSet will be returned.
67
+ #
68
+ # Any parameters will be bound to the statement using #bind_params.
69
+ #
70
+ # Example:
71
+ #
72
+ # stmt = db.prepare( "select * from table" )
73
+ # stmt.execute do |result|
74
+ # ...
75
+ # end
76
+ #
77
+ # See also #bind_params, #execute!.
78
+ def execute(*bind_vars)
79
+ reset! if active? || done?
80
+
81
+ bind_params(*bind_vars) unless bind_vars.empty?
82
+ results = @connection.build_result_set self
83
+
84
+ step if column_count == 0
85
+
86
+ yield results if block_given?
87
+ results
88
+ end
89
+
90
+ # Execute the statement. If no block was given, this returns an array of
91
+ # rows returned by executing the statement. Otherwise, each row will be
92
+ # yielded to the block.
93
+ #
94
+ # Any parameters will be bound to the statement using #bind_params.
95
+ #
96
+ # Example:
97
+ #
98
+ # stmt = db.prepare( "select * from table" )
99
+ # stmt.execute! do |row|
100
+ # ...
101
+ # end
102
+ #
103
+ # See also #bind_params, #execute.
104
+ def execute!(*bind_vars, &block)
105
+ execute(*bind_vars)
106
+ block ? each(&block) : to_a
107
+ end
108
+
109
+ # Returns true if the statement is currently active, meaning it has an
110
+ # open result set.
111
+ def active?
112
+ !done?
113
+ end
114
+
115
+ # Return an array of the column names for this statement. Note that this
116
+ # may execute the statement in order to obtain the metadata; this makes it
117
+ # a (potentially) expensive operation.
118
+ def columns
119
+ get_metadata unless @columns
120
+ @columns
121
+ end
122
+
123
+ def each
124
+ loop do
125
+ val = step
126
+ break self if done?
127
+ yield val
128
+ end
129
+ end
130
+
131
+ # Return an array of the data types for each column in this statement. Note
132
+ # that this may execute the statement in order to obtain the metadata; this
133
+ # makes it a (potentially) expensive operation.
134
+ def types
135
+ must_be_open!
136
+ get_metadata unless @types
137
+ @types
138
+ end
139
+
140
+ # Performs a sanity check to ensure that the statement is not
141
+ # closed. If it is, an exception is raised.
142
+ def must_be_open! # :nodoc:
143
+ if closed?
144
+ raise SQLite3::Exception, "cannot use a closed statement"
145
+ end
146
+ end
147
+
148
+ # Returns a Hash containing information about the statement.
149
+ # The contents of the hash are implementation specific and may change in
150
+ # the future without notice. The hash includes information about internal
151
+ # statistics about the statement such as:
152
+ # - +fullscan_steps+: the number of times that SQLite has stepped forward
153
+ # in a table as part of a full table scan
154
+ # - +sorts+: the number of sort operations that have occurred
155
+ # - +autoindexes+: the number of rows inserted into transient indices
156
+ # that were created automatically in order to help joins run faster
157
+ # - +vm_steps+: the number of virtual machine operations executed by the
158
+ # prepared statement
159
+ # - +reprepares+: the number of times that the prepare statement has been
160
+ # automatically regenerated due to schema changes or changes to bound
161
+ # parameters that might affect the query plan
162
+ # - +runs+: the number of times that the prepared statement has been run
163
+ # - +filter_misses+: the number of times that the Bloom filter returned
164
+ # a find, and thus the join step had to be processed as normal
165
+ # - +filter_hits+: the number of times that a join step was bypassed
166
+ # because a Bloom filter returned not-found
167
+ def stat key = nil
168
+ if key
169
+ stat_for(key)
170
+ else
171
+ stats_as_hash
172
+ end
173
+ end
174
+
175
+ private
176
+
177
+ # A convenience method for obtaining the metadata about the query. Note
178
+ # that this will actually execute the SQL, which means it can be a
179
+ # (potentially) expensive operation.
180
+ def get_metadata
181
+ @columns = Array.new(column_count) do |column|
182
+ column_name column
183
+ end
184
+ @types = Array.new(column_count) do |column|
185
+ val = column_decltype(column)
186
+ val&.downcase
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,54 @@
1
+ require "sqlite3/constants"
2
+
3
+ module SQLite3
4
+ class Value
5
+ attr_reader :handle
6
+
7
+ def initialize(db, handle)
8
+ @driver = db.driver
9
+ @handle = handle
10
+ end
11
+
12
+ def null?
13
+ type == :null
14
+ end
15
+
16
+ def to_blob
17
+ @driver.value_blob(@handle)
18
+ end
19
+
20
+ def length(utf16 = false)
21
+ if utf16
22
+ @driver.value_bytes16(@handle)
23
+ else
24
+ @driver.value_bytes(@handle)
25
+ end
26
+ end
27
+
28
+ def to_f
29
+ @driver.value_double(@handle)
30
+ end
31
+
32
+ def to_i
33
+ @driver.value_int(@handle)
34
+ end
35
+
36
+ def to_int64
37
+ @driver.value_int64(@handle)
38
+ end
39
+
40
+ def to_s(utf16 = false)
41
+ @driver.value_text(@handle, utf16)
42
+ end
43
+
44
+ def type
45
+ case @driver.value_type(@handle)
46
+ when Constants::ColumnType::INTEGER then :int
47
+ when Constants::ColumnType::FLOAT then :float
48
+ when Constants::ColumnType::TEXT then :text
49
+ when Constants::ColumnType::BLOB then :blob
50
+ when Constants::ColumnType::NULL then :null
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,4 @@
1
+ module SQLite3
2
+ # (String) the version of the sqlite3 gem, e.g. "2.1.1"
3
+ VERSION = "2.6.0"
4
+ end
@@ -0,0 +1,17 @@
1
+ module SQLite3
2
+ # a hash of descriptive metadata about the current version of the sqlite3 gem
3
+ VERSION_INFO = {
4
+ ruby: RUBY_DESCRIPTION,
5
+ gem: {
6
+ version: SQLite3::VERSION
7
+ },
8
+ sqlite: {
9
+ compiled: SQLite3::SQLITE_VERSION,
10
+ loaded: SQLite3::SQLITE_LOADED_VERSION,
11
+ packaged: SQLite3::SQLITE_PACKAGED_LIBRARIES,
12
+ precompiled: SQLite3::SQLITE_PRECOMPILED_LIBRARIES,
13
+ sqlcipher: SQLite3.sqlcipher?,
14
+ threadsafe: SQLite3.threadsafe?
15
+ }
16
+ }
17
+ end
data/lib/sqlite3.rb ADDED
@@ -0,0 +1,19 @@
1
+ # support multiple ruby version (fat binaries under windows)
2
+ begin
3
+ RUBY_VERSION =~ /(\d+\.\d+)/
4
+ require "sqlite3/#{$1}/sqlite3_native"
5
+ rescue LoadError
6
+ require "sqlite3/sqlite3_native"
7
+ end
8
+
9
+ require "sqlite3/database"
10
+ require "sqlite3/version"
11
+
12
+ module SQLite3
13
+ # Was sqlite3 compiled with thread safety on?
14
+ def self.threadsafe?
15
+ threadsafe > 0
16
+ end
17
+ end
18
+
19
+ require "sqlite3/version_info"
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqlite3-ffi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jamis Buck
8
+ - Luis Lavena
9
+ - Aaron Patterson
10
+ - Mike Dalessio
11
+ - Andrew Kane
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+ date: 2025-04-26 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: ffi
19
+ requirement: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: '0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ description:
32
+ email: andrew@ankane.org
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - CHANGELOG.md
38
+ - LICENSE.txt
39
+ - README.md
40
+ - lib/sqlite3.rb
41
+ - lib/sqlite3/constants.rb
42
+ - lib/sqlite3/database.rb
43
+ - lib/sqlite3/errors.rb
44
+ - lib/sqlite3/ffi.rb
45
+ - lib/sqlite3/ffi/aggregator.rb
46
+ - lib/sqlite3/ffi/backup.rb
47
+ - lib/sqlite3/ffi/c_api.rb
48
+ - lib/sqlite3/ffi/core_ext.rb
49
+ - lib/sqlite3/ffi/database.rb
50
+ - lib/sqlite3/ffi/exception.rb
51
+ - lib/sqlite3/ffi/functions.rb
52
+ - lib/sqlite3/ffi/sqlite3.rb
53
+ - lib/sqlite3/ffi/statement.rb
54
+ - lib/sqlite3/ffi/utils.rb
55
+ - lib/sqlite3/ffi/version.rb
56
+ - lib/sqlite3/fork_safety.rb
57
+ - lib/sqlite3/pragmas.rb
58
+ - lib/sqlite3/resultset.rb
59
+ - lib/sqlite3/sqlite3_native.rb
60
+ - lib/sqlite3/statement.rb
61
+ - lib/sqlite3/value.rb
62
+ - lib/sqlite3/version.rb
63
+ - lib/sqlite3/version_info.rb
64
+ homepage: https://github.com/ankane/sqlite3-ffi
65
+ licenses:
66
+ - BSD-3-Clause
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '3.1'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 3.5.16
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: A drop-in replacement for sqlite3 for JRuby
87
+ test_files: []