sqlite3-fiddle 1.0.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,290 @@
1
+ module SQLite3
2
+ class Statement
3
+ include Enumerable
4
+
5
+ # This is any text that followed the first valid SQL statement in the text
6
+ # with which the statement was initialized. If there was no trailing text,
7
+ # this will be the empty string.
8
+ attr_reader :remainder
9
+
10
+ def initialize(db, sql)
11
+ raise TypeError, 'sql has to be a string' unless sql.is_a? String
12
+ raise ArgumentError, 'db has to be open' if db.closed?
13
+ @db = db
14
+ sql = sql.strip.encode(Encoding::UTF_8)
15
+ @prepared_stmt = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
16
+ remainder = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP)
17
+ @db.check Driver.sqlite3_prepare_v2(db.handle, sql, -1,
18
+ @prepared_stmt.ref,
19
+ remainder.ref)
20
+ @remainder = remainder.to_s
21
+ @sql = sql
22
+ @done = false
23
+ remainder.free
24
+ end
25
+
26
+ def column_count
27
+ Driver.sqlite3_column_count(@prepared_stmt)
28
+ end
29
+
30
+ def column_name(index)
31
+ column = Driver.sqlite3_column_name(@prepared_stmt, index.to_i)
32
+ column.to_s unless column.null?
33
+ end
34
+
35
+ def column_decltype(index)
36
+ column = Driver.sqlite3_column_decltype(@prepared_stmt, index.to_i)
37
+ column.to_s unless column.null?
38
+ end
39
+
40
+ def database_name(index)
41
+ name = Driver.sqlite3_column_database_name(@prepared_stmt, index.to_i)
42
+ name.to_s unless name.null?
43
+ end
44
+
45
+ def table_name(index)
46
+ name = Driver.sqlite3_column_table_name(@prepared_stmt, index.to_i)
47
+ name.to_s unless name.null?
48
+ end
49
+
50
+ def origin_name(index)
51
+ name = Driver.sqlite3_column_origin_name(@prepared_stmt, index.to_i)
52
+ name.to_s unless name.null?
53
+ end
54
+
55
+ def bind_parameter_count
56
+ Driver.sqlite3_bind_parameter_count(@prepared_stmt)
57
+ end
58
+
59
+ # Binds the given variables to the corresponding placeholders in the SQL
60
+ # text.
61
+ #
62
+ # See Database#execute for a description of the valid placeholder
63
+ # syntaxes.
64
+ #
65
+ # Example:
66
+ #
67
+ # stmt = db.prepare( "select * from table where a=? and b=?" )
68
+ # stmt.bind_params( 15, "hello" )
69
+ #
70
+ # See also #execute, #bind_param, Statement#bind_param, and
71
+ # Statement#bind_params.
72
+ def bind_params( *bind_vars )
73
+ index = 1
74
+ bind_vars.flatten.each do |var|
75
+ if Hash === var
76
+ var.each { |key, val| bind_param key, val }
77
+ else
78
+ bind_param index, var
79
+ index += 1
80
+ end
81
+ end
82
+ end
83
+
84
+ def bind_param(index, var)
85
+ must_be_open!
86
+ unless index.is_a? Fixnum
87
+ name = index.to_s
88
+ name = ":#{name}" unless name.start_with? ':'
89
+ # if name !=~ /^[:@?$].*/
90
+ index = Driver.sqlite3_bind_parameter_index(@prepared_stmt, name)
91
+ if index == 0
92
+ raise Exception, "index #{name} unknown for [#{@sql}]"
93
+ end
94
+ end
95
+ @db.check case var
96
+ when Blob
97
+ var = var.force_encoding(Encoding::ASCII_8BIT)
98
+ Driver.sqlite3_bind_blob(@prepared_stmt, index, var.to_s,
99
+ var.size, nil)
100
+ when String
101
+ # if UTF_16BE was passed we have to convert it anyway, than we use
102
+ # the UTF-8 conversion much like the c implementation does.
103
+ # TODO: check if this is slow because the sqlite than has to convert to?
104
+ if var.encoding == Encoding::UTF_16LE
105
+ Driver.sqlite3_bind_text16(@prepared_stmt, index, var, -1, nil)
106
+ else # this string behaves like a blob, so we bind it as such
107
+ if var.encoding == Encoding::ASCII_8BIT
108
+ Driver.sqlite3_bind_blob(@prepared_stmt, index, var.to_s,
109
+ var.size, nil)
110
+ else
111
+ unless var.encoding == Encoding::UTF_8
112
+ var = var.encode(Encoding::UTF_8)
113
+ end
114
+ Driver.sqlite3_bind_text(@prepared_stmt, index, var, -1, nil)
115
+ end
116
+ end
117
+ when Fixnum, Bignum
118
+ Driver.sqlite3_bind_int64(@prepared_stmt, index, var)
119
+ when Float
120
+ Driver.sqlite3_bind_double(@prepared_stmt, index, var)
121
+ when NilClass
122
+ Driver.sqlite3_bind_null(@prepared_stmt, index)
123
+ when TrueClass, FalseClass
124
+ Driver.sqlite3_bind_int(@prepared_stmt, index, var ? 1 : 0)
125
+ else
126
+ Driver.sqlite3_bind_blob(@prepared_stmt, index, var.to_s,
127
+ var.to_s.size, nil)
128
+ end
129
+ end
130
+
131
+ def clear_bindings!
132
+ @db.check Driver.sqlite3_clear_bindings(@prepared_stmt)
133
+ end
134
+
135
+ def reset!
136
+ @db.check Driver.sqlite3_reset(@prepared_stmt)
137
+ @done = false
138
+ end
139
+ #
140
+ # def execute(*bind_vars, &handler)
141
+ # must_be_open!
142
+ # reset! if active? || done?
143
+ # bind_params *bind_vars unless bind_vars.empty?
144
+ # if block_given?
145
+ # each &handler
146
+ # else
147
+ # ResultSet.new(@db, self)
148
+ # end
149
+ # end
150
+ def execute( *bind_vars )
151
+ reset! if active? || done?
152
+
153
+ bind_params(*bind_vars) unless bind_vars.empty?
154
+ @results = ResultSet.new(@db, self)
155
+
156
+ step if 0 == column_count
157
+
158
+ yield @results if block_given?
159
+ @results
160
+ end
161
+
162
+ def each
163
+ loop do
164
+ val = step
165
+ break self if done?
166
+ yield val
167
+ end
168
+ end
169
+
170
+ def step
171
+ must_be_open!
172
+ case Driver.sqlite3_step(@prepared_stmt)
173
+ when SQLITE_ROW
174
+ row = []
175
+ column_count.times do |i|
176
+ case Driver.sqlite3_column_type(@prepared_stmt, i)
177
+ when SQLITE_INTEGER
178
+ row << Driver.sqlite3_column_int64(@prepared_stmt, i)
179
+ when SQLITE_FLOAT
180
+ row << Driver.sqlite3_column_double(@prepared_stmt, i)
181
+ when SQLITE_TEXT
182
+ text = (Driver.sqlite3_column_text(@prepared_stmt, i)[
183
+ 0, Driver.sqlite3_column_bytes(@prepared_stmt, i)
184
+ ])
185
+ default = Encoding.default_internal || Encoding::UTF_8
186
+ row << text.encode(default, Encoding::UTF_8)
187
+ when SQLITE_BLOB
188
+ data = Driver.sqlite3_column_blob(@prepared_stmt, i)[
189
+ 0, Driver.sqlite3_column_bytes(@prepared_stmt, i)
190
+ ]
191
+ row << Blob.new(data.force_encoding(Encoding::ASCII_8BIT))
192
+ when SQLITE_NULL
193
+ row << nil
194
+ else
195
+ fail Exception, "bad type"
196
+ end
197
+ end
198
+ return row
199
+ when SQLITE_DONE
200
+ @done = true
201
+ return nil
202
+ else
203
+ reset!
204
+ @done = false
205
+ end
206
+ end
207
+
208
+ # Execute the statement. If no block was given, this returns an array of
209
+ # rows returned by executing the statement. Otherwise, each row will be
210
+ # yielded to the block.
211
+ #
212
+ # Any parameters will be bound to the statement using #bind_params.
213
+ #
214
+ # Example:
215
+ #
216
+ # stmt = db.prepare( "select * from table" )
217
+ # stmt.execute! do |row|
218
+ # ...
219
+ # end
220
+ #
221
+ # See also #bind_params, #execute.
222
+ def execute!( *bind_vars, &block )
223
+ execute(*bind_vars)
224
+ block_given? ? each(&block) : to_a
225
+ end
226
+
227
+ # Returns true if the statement has been closed.
228
+ def closed?
229
+ @prepared_stmt.nil?
230
+ end
231
+
232
+ # returns true if all rows have been returned.
233
+ def done?
234
+ @done
235
+ end
236
+
237
+ def close
238
+ must_be_open!
239
+ @db.check Driver.sqlite3_finalize(@prepared_stmt)
240
+ @prepared_stmt.free
241
+ @prepared_stmt = nil
242
+ end
243
+
244
+
245
+ # Return an array of the data types for each column in this statement. Note
246
+ # that this may execute the statement in order to obtain the metadata; this
247
+ # makes it a (potentially) expensive operation.
248
+ def types
249
+ must_be_open!
250
+ get_metadata unless @types
251
+ @types
252
+ end
253
+
254
+ # Return an array of the column names for this statement. Note that this
255
+ # may execute the statement in order to obtain the metadata; this makes it
256
+ # a (potentially) expensive operation.
257
+ def columns
258
+ must_be_open!
259
+ get_metadata unless @columns
260
+ return @columns
261
+ end
262
+
263
+ # Returns true if the statement is currently active, meaning it has an
264
+ # open result set.
265
+ def active?
266
+ !done?
267
+ end
268
+
269
+ # Performs a sanity check to ensure that the statement is not
270
+ # closed. If it is, an exception is raised.
271
+ def must_be_open! # :nodoc:
272
+ if closed?
273
+ raise Exception, "cannot use a closed statement"
274
+ end
275
+ end
276
+
277
+ private
278
+ # A convenience method for obtaining the metadata about the query. Note
279
+ # that this will actually execute the SQL, which means it can be a
280
+ # (potentially) expensive operation.
281
+ def get_metadata
282
+ @columns = Array.new(column_count) do |column|
283
+ column_name column
284
+ end
285
+ @types = Array.new(column_count) do |column|
286
+ column_decltype column
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,71 @@
1
+ require 'sqlite3/constants'
2
+
3
+ module SQLite3
4
+
5
+ class Value
6
+ attr_reader :handle
7
+
8
+ def initialize(db, handle)
9
+ @handle = handle
10
+ end
11
+
12
+ def null?
13
+ type == :null
14
+ end
15
+
16
+ def to_blob
17
+ bytes = size
18
+ Blob.new(Driver.sqlite3_value_blob(@handle).to_s(bytes))
19
+ end
20
+
21
+ def length(utf16=false)
22
+ if utf16
23
+ Driver.sqlite3_value_bytes16(@handle)
24
+ else
25
+ Driver.sqlite3_value_bytes(@handle)
26
+ end
27
+ end
28
+
29
+ alias_method :size, :length
30
+
31
+ def to_f
32
+ Driver.sqlite3_value_double(@handle)
33
+ end
34
+
35
+ def to_i
36
+ Driver.sqlite3_value_int(@handle)
37
+ end
38
+
39
+ def to_int64
40
+ Driver.sqlite3_value_int64(@handle)
41
+ end
42
+
43
+ def to_s(utf16=false)
44
+ if utf16
45
+ Driver.sqlite3_result_text16(@handle).to_s
46
+ else
47
+ Driver.sqlite3_value_text(@handle).to_s
48
+ end
49
+ end
50
+
51
+ def type
52
+ case Driver.sqlite3_value_type(@handle)
53
+ when SQLITE_INTEGER then :int
54
+ when SQLITE_FLOAT then :float
55
+ when SQLITE_TEXT then :text
56
+ when SQLITE_BLOB then :blob
57
+ when SQLITE_NULL then :null
58
+ end
59
+ end
60
+
61
+ def native
62
+ case Driver.sqlite3_value_type(@handle)
63
+ when SQLITE_INTEGER then to_int64
64
+ when SQLITE_FLOAT then to_f
65
+ when SQLITE_TEXT then to_s
66
+ when SQLITE_BLOB then to_blob
67
+ when SQLITE_NULL then nil
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,10 @@
1
+ module SQLite3
2
+ MAJOR = 1
3
+ MINOR = 0
4
+ PATCH = 0
5
+ VERSION = [MAJOR, MINOR, PATCH].join('.')
6
+
7
+ def self.libversion
8
+ Driver.sqlite3_libversion().to_s
9
+ end
10
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sqlite3/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sqlite3-fiddle"
8
+ spec.version = SQLite3::VERSION
9
+ spec.authors = ["Vincent Landgraf"]
10
+ spec.email = ["vilandgr+sqlite@googlemail.com"]
11
+
12
+ spec.summary = %q{Ruby bindings for the SQLite3 embedded database - without compiling}
13
+ spec.description = %q{Ruby bindings for the SQLite3 embedded database - without compiling}
14
+ spec.homepage = "https://github.com/threez/sqlite3-fiddle"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "minitest", "~> 5.0"
25
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sqlite3-fiddle
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Vincent Landgraf
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: Ruby bindings for the SQLite3 embedded database - without compiling
56
+ email:
57
+ - vilandgr+sqlite@googlemail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".ruby-version"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - lib/.DS_Store
70
+ - lib/sqlite3.rb
71
+ - lib/sqlite3/backup.rb
72
+ - lib/sqlite3/constants.rb
73
+ - lib/sqlite3/database.rb
74
+ - lib/sqlite3/driver.rb
75
+ - lib/sqlite3/pragmas.rb
76
+ - lib/sqlite3/resultset.rb
77
+ - lib/sqlite3/statement.rb
78
+ - lib/sqlite3/value.rb
79
+ - lib/sqlite3/version.rb
80
+ - sqlite3-fiddle.gemspec
81
+ homepage: https://github.com/threez/sqlite3-fiddle
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.4.3
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Ruby bindings for the SQLite3 embedded database - without compiling
105
+ test_files: []