sqlite3-ruby 0.6.0 → 0.9.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.

Potentially problematic release.


This version of sqlite3-ruby might be problematic. Click here for more details.

@@ -249,12 +249,12 @@ module SQLite3
249
249
  # This always returns +nil+, making it unsuitable for queries that return
250
250
  # rows.
251
251
  def execute_batch( sql, *bind_vars )
252
- loop do
252
+ sql = sql.strip
253
+ until sql.empty? do
253
254
  prepare( sql ) do |stmt|
254
255
  stmt.execute( *bind_vars )
255
- sql = stmt.remainder
256
+ sql = stmt.remainder.strip
256
257
  end
257
- break if sql.length < 1
258
258
  end
259
259
  nil
260
260
  end
@@ -299,8 +299,7 @@ module SQLite3
299
299
 
300
300
  # Interrupts the currently executing operation, causing it to abort.
301
301
  def interrupt
302
- result = @driver.interrupt( @handle )
303
- Error.check( result, self )
302
+ @driver.interrupt( @handle )
304
303
  end
305
304
 
306
305
  # Register a busy handler with this database instance. When a requested
@@ -345,9 +344,9 @@ module SQLite3
345
344
  #
346
345
  # db.create_function( "maim", 1 ) do |func, value|
347
346
  # if value.nil?
348
- # func.set_value nil
347
+ # func.result = nil
349
348
  # else
350
- # func.set_value value.split(//).sort.join
349
+ # func.result = value.split(//).sort.join
351
350
  # end
352
351
  # end
353
352
  #
@@ -359,7 +358,7 @@ module SQLite3
359
358
  begin
360
359
  block.call( FunctionProxy.new( @driver, func ),
361
360
  *args.map{|v| Value.new(self,v)} )
362
- rescue Exception => e
361
+ rescue StandardError, Exception => e
363
362
  @driver.result_error( func,
364
363
  "#{e.message} (#{e.class})", -1 )
365
364
  end
@@ -513,8 +512,8 @@ module SQLite3
513
512
  ctx[ :handler ] ||= handler.new
514
513
  begin
515
514
  ctx[ :handler ].step( FunctionProxy.new( @driver, func, ctx ),
516
- *args )
517
- rescue Exception => e
515
+ *args.map{|v| Value.new(self,v)} )
516
+ rescue Exception, StandardError => e
518
517
  ctx[ :__error ] = e
519
518
  end
520
519
  end
@@ -548,6 +547,9 @@ module SQLite3
548
547
  # by SQLite, so attempting to nest a transaction will result in a runtime
549
548
  # exception.
550
549
  #
550
+ # The +mode+ parameter may be either <tt>:deferred</tt> (the default),
551
+ # <tt>:immediate</tt>, or <tt>:exclusive</tt>.
552
+ #
551
553
  # If a block is given, the database instance is yielded to it, and the
552
554
  # transaction is committed when the block terminates. If the block
553
555
  # raises an exception, a rollback will be performed instead. Note that if
@@ -557,8 +559,8 @@ module SQLite3
557
559
  # If a block is not given, it is the caller's responsibility to end the
558
560
  # transaction explicitly, either by calling #commit, or by calling
559
561
  # #rollback.
560
- def transaction
561
- execute "begin transaction"
562
+ def transaction( mode = :deferred )
563
+ execute "begin #{mode.to_s} transaction"
562
564
  @transaction_active = true
563
565
 
564
566
  if block_given?
@@ -48,7 +48,7 @@ class DL::PtrData
48
48
  def to_object
49
49
  n = to_s(4).unpack("L").first
50
50
  return nil if n < 1
51
- ObjectSpace._id2ref(n)
51
+ ObjectSpace._id2ref(n) rescue self.to_s
52
52
  end
53
53
 
54
54
  def set_object(obj)
@@ -170,7 +170,7 @@ module SQLite3 ; module Driver ; module DL
170
170
 
171
171
  unless @trace_handler_callback
172
172
  @trace_handler_callback = ::DL.callback( "IPS" ) do |cookie,sql|
173
- @trace_handler.call( cookie, sql ) || 0
173
+ @trace_handler.call( cookie ? cookie.to_object : nil, sql ) || 0
174
174
  end
175
175
  end
176
176
 
@@ -218,7 +218,7 @@ module SQLite3 ; module Driver ; module DL
218
218
  def aggregate_context( context )
219
219
  ptr = API.sqlite3_aggregate_context( context, 4 )
220
220
  ptr.free = nil
221
- obj = ptr.to_object
221
+ obj = ( ptr ? ptr.to_object : nil )
222
222
  if obj.nil?
223
223
  obj = Hash.new
224
224
  ptr.set_object obj
@@ -237,6 +237,21 @@ module SQLite3 ; module Driver ; module DL
237
237
  API.send( method, stmt, index, s, s.length, TRANSIENT )
238
238
  end
239
239
 
240
+ def column_text( stmt, column )
241
+ result = API.sqlite3_column_text( stmt, column )
242
+ result ? result.to_s : nil
243
+ end
244
+
245
+ def column_name( stmt, column )
246
+ result = API.sqlite3_column_name( stmt, column )
247
+ result ? result.to_s : nil
248
+ end
249
+
250
+ def column_decltype( stmt, column )
251
+ result = API.sqlite3_column_decltype( stmt, column )
252
+ result ? result.to_s : nil
253
+ end
254
+
240
255
  def self.api_delegate( name )
241
256
  define_method( name ) { |*args| API.send( "sqlite3_#{name}", *args ) }
242
257
  end
@@ -250,13 +265,12 @@ module SQLite3 ; module Driver ; module DL
250
265
  api_delegate :busy_timeout
251
266
  api_delegate :changes
252
267
  api_delegate :close
268
+ api_delegate :column_bytes
269
+ api_delegate :column_bytes16
253
270
  api_delegate :column_count
254
- api_delegate :column_decltype
255
271
  api_delegate :column_double
256
272
  api_delegate :column_int
257
273
  api_delegate :column_int64
258
- api_delegate :column_name
259
- api_delegate :column_text
260
274
  api_delegate :column_type
261
275
  api_delegate :data_count
262
276
  api_delegate :errcode
@@ -0,0 +1,218 @@
1
+ #--
2
+ # =============================================================================
3
+ # Copyright (c) 2004, Jamis Buck (jgb3@email.byu.edu)
4
+ # All rights reserved.
5
+ #
6
+ # Redistribution and use in source and binary forms, with or without
7
+ # modification, are permitted provided that the following conditions are met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright notice,
10
+ # this list of conditions and the following disclaimer.
11
+ #
12
+ # * Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ #
16
+ # * The names of its contributors may not be used to endorse or promote
17
+ # products derived from this software without specific prior written
18
+ # permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ # =============================================================================
31
+ #++
32
+
33
+ require 'sqlite3_api'
34
+
35
+ module SQLite3 ; module Driver ; module Native
36
+
37
+ class Driver
38
+
39
+ def initialize
40
+ @callback_data = Hash.new
41
+ end
42
+
43
+ def complete?( sql, utf16=false )
44
+ API.send( utf16 ? :sqlite3_complete16 : :sqlite3_complete, sql ) != 0
45
+ end
46
+
47
+ def busy_handler( db, data=nil, &block )
48
+ if block
49
+ cb = API::CallbackData.new
50
+ cb.proc = block
51
+ cb.data = data
52
+ end
53
+
54
+ API.sqlite3_busy_handler( db,
55
+ block ? API::Sqlite3_ruby_busy_handler : nil, cb )
56
+ end
57
+
58
+ def set_authorizer( db, data=nil, &block )
59
+ if block
60
+ cb = API::CallbackData.new
61
+ cb.proc = block
62
+ cb.data = data
63
+ end
64
+
65
+ API.sqlite3_set_authorizer( db,
66
+ block ? API::Sqlite3_ruby_authorizer : nil, cb )
67
+ end
68
+
69
+ def trace( db, data=nil, &block )
70
+ if block
71
+ cb = API::CallbackData.new
72
+ cb.proc = block
73
+ cb.data = data
74
+ end
75
+
76
+ API.sqlite3_trace( db,
77
+ block ? API::Sqlite3_ruby_trace : nil, cb )
78
+ end
79
+
80
+ def open( filename, utf16=false )
81
+ API.send( utf16 ? :sqlite3_open16 : :sqlite3_open, filename )
82
+ end
83
+
84
+ def errmsg( db, utf16=false )
85
+ API.send( utf16 ? :sqlite3_errmsg16 : :sqlite3_errmsg, db )
86
+ end
87
+
88
+ def prepare( db, sql, utf16=false )
89
+ API.send( ( utf16 ? :sqlite3_prepare16 : :sqlite3_prepare ),
90
+ db, sql )
91
+ end
92
+
93
+ def bind_text( stmt, index, value, utf16=false )
94
+ API.send( ( utf16 ? :sqlite3_bind_text16 : :sqlite3_bind_text ),
95
+ stmt, index, value )
96
+ end
97
+
98
+ def column_name( stmt, index, utf16=false )
99
+ API.send( ( utf16 ? :sqlite3_column_name16 : :sqlite3_column_name ),
100
+ stmt, index )
101
+ end
102
+
103
+ def column_decltype( stmt, index, utf16=false )
104
+ API.send(
105
+ ( utf16 ? :sqlite3_column_decltype16 : :sqlite3_column_decltype ),
106
+ stmt, index )
107
+ end
108
+
109
+ def column_text( stmt, index, utf16=false )
110
+ API.send( ( utf16 ? :sqlite3_column_text16 : :sqlite3_column_text ),
111
+ stmt, index )
112
+ end
113
+
114
+ def create_function( db, name, args, text, cookie, func, step, final )
115
+ if func || ( step && final )
116
+ cb = API::CallbackData.new
117
+ cb.proc = cb.proc2 = nil
118
+ cb.data = cookie
119
+ @callback_data[ name ] = cb
120
+ else
121
+ @callback_data.delete( name )
122
+ end
123
+
124
+ if func
125
+ cb.proc = func
126
+
127
+ func = API::Sqlite3_ruby_function_step
128
+ step = final = nil
129
+ elsif step && final
130
+ cb.proc = step
131
+ cb.proc2 = final
132
+
133
+ func = nil
134
+ step = API::Sqlite3_ruby_function_step
135
+ final = API::Sqlite3_ruby_function_final
136
+ end
137
+
138
+ API.sqlite3_create_function( db, name, args, text, cb, func, step, final )
139
+ end
140
+
141
+ def value_text( value, utf16=false )
142
+ method = case utf16
143
+ when nil, false then :sqlite3_value_text
144
+ when :le then :sqlite3_value_text16le
145
+ when :be then :sqlite3_value_text16be
146
+ else :sqlite3_value_text16
147
+ end
148
+
149
+ API.send( method, value )
150
+ end
151
+
152
+ def result_text( context, result, utf16=false )
153
+ method = case utf16
154
+ when nil, false then :sqlite3_result_text
155
+ when :le then :sqlite3_result_text16le
156
+ when :be then :sqlite3_result_text16be
157
+ else :sqlite3_result_text16
158
+ end
159
+
160
+ API.send( method, context, result.to_s )
161
+ end
162
+
163
+ def result_error( context, value, utf16=false )
164
+ API.send( ( utf16 ? :sqlite3_result_error16 : :sqlite3_result_error ),
165
+ context, value )
166
+ end
167
+
168
+ def self.api_delegate( name )
169
+ define_method( name ) { |*args| API.send( "sqlite3_#{name}", *args ) }
170
+ end
171
+
172
+ api_delegate :libversion
173
+ api_delegate :close
174
+ api_delegate :last_insert_rowid
175
+ api_delegate :changes
176
+ api_delegate :total_changes
177
+ api_delegate :interrupt
178
+ api_delegate :busy_timeout
179
+ api_delegate :errcode
180
+ api_delegate :bind_blob
181
+ api_delegate :bind_double
182
+ api_delegate :bind_int
183
+ api_delegate :bind_int64
184
+ api_delegate :bind_null
185
+ api_delegate :bind_parameter_count
186
+ api_delegate :bind_parameter_name
187
+ api_delegate :bind_parameter_index
188
+ api_delegate :column_count
189
+ api_delegate :step
190
+ api_delegate :data_count
191
+ api_delegate :column_blob
192
+ api_delegate :column_bytes
193
+ api_delegate :column_bytes16
194
+ api_delegate :column_double
195
+ api_delegate :column_int
196
+ api_delegate :column_int64
197
+ api_delegate :column_type
198
+ api_delegate :finalize
199
+ api_delegate :reset
200
+ api_delegate :aggregate_count
201
+ api_delegate :value_blob
202
+ api_delegate :value_bytes
203
+ api_delegate :value_bytes16
204
+ api_delegate :value_double
205
+ api_delegate :value_int
206
+ api_delegate :value_int64
207
+ api_delegate :value_type
208
+ api_delegate :result_blob
209
+ api_delegate :result_double
210
+ api_delegate :result_int
211
+ api_delegate :result_int64
212
+ api_delegate :result_null
213
+ api_delegate :result_value
214
+ api_delegate :aggregate_context
215
+
216
+ end
217
+
218
+ end ; end ; end
@@ -81,7 +81,7 @@ module SQLite3
81
81
  # can be rewound and reiterated.
82
82
  def reset( *bind_params )
83
83
  @driver.reset( @stmt.handle )
84
- @stmt.bind_params *bind_params
84
+ @stmt.bind_params( *bind_params )
85
85
  @eof = false
86
86
  commence
87
87
  end
@@ -35,7 +35,7 @@ module SQLite3
35
35
  module Version
36
36
 
37
37
  MAJOR = 0
38
- MINOR = 6
38
+ MINOR = 9
39
39
  TINY = 0
40
40
 
41
41
  STRING = [ MAJOR, MINOR, TINY ].join( "." )
@@ -0,0 +1,126 @@
1
+ $:.unshift "../lib", "../ext/sqlite3_api"
2
+
3
+ require 'sqlite3'
4
+
5
+ require 'benchmark'
6
+
7
+ N = 1000
8
+
9
+ $VERBOSE=nil
10
+
11
+ puts "database creation..."
12
+ Benchmark.bm( 7 ) do |x|
13
+ x.report('dl') do
14
+ N.times do
15
+ File.delete "test.db" rescue nil
16
+ SQLite3::Database.open( "test.db", :driver => "DL" ).close
17
+ end
18
+ end
19
+ x.report('native') do
20
+ N.times do
21
+ File.delete "test.db" rescue nil
22
+ SQLite3::Database.open( "test.db", :driver => "Native" ).close
23
+ end
24
+ end
25
+ end
26
+ File.delete "test.db" rescue nil
27
+
28
+ SQLite3::Database.open( "test.db" ).close
29
+
30
+ puts
31
+ puts "database open..."
32
+ Benchmark.bm( 7 ) do |x|
33
+ x.report('dl') do
34
+ N.times do
35
+ SQLite3::Database.open( "test.db", :driver => "DL" ).close
36
+ end
37
+ end
38
+ x.report('native') do
39
+ N.times do
40
+ SQLite3::Database.open( "test.db", :driver => "Native" ).close
41
+ end
42
+ end
43
+ end
44
+ File.delete "test.db" rescue nil
45
+
46
+ dl = SQLite3::Database.open( "test-dl.db", :driver => "DL" )
47
+ native = SQLite3::Database.open( "test-native.db", :driver => "Native" )
48
+
49
+ dl.execute "create table foo (a,b)"
50
+ native.execute "create table foo (a,b)"
51
+
52
+ puts
53
+ puts "insertions"
54
+ Benchmark.bm( 7 ) do |x|
55
+ x.report('dl') do
56
+ dl.transaction do
57
+ N.times do |i|
58
+ dl.execute "insert into foo values (#{i}, #{i+1})"
59
+ end
60
+ end
61
+ end
62
+ x.report('native') do
63
+ native.transaction do
64
+ N.times do |i|
65
+ native.execute "insert into foo values (#{i}, #{i+1})"
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ puts
72
+ puts "insertions using prepared statement"
73
+ Benchmark.bm( 7 ) do |x|
74
+ x.report('dl') do
75
+ dl.transaction do
76
+ dl.prepare "insert into foo values (?,?)" do |stmt|
77
+ N.times { |i| stmt.execute i, i+1 }
78
+ end
79
+ end
80
+ end
81
+ x.report('native') do
82
+ native.transaction do
83
+ native.prepare( "insert into foo values (?,?)" ) do |stmt|
84
+ N.times { |i| stmt.execute i, i+1 }
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ dl.close
91
+ native.close
92
+ File.delete "test-dl.db" rescue nil
93
+ File.delete "test-native.db" rescue nil
94
+
95
+ dl = SQLite3::Database.open( "test-dl.db", :driver => "DL" )
96
+ native = SQLite3::Database.open( "test-native.db", :driver => "Native" )
97
+
98
+ dl.execute "create table foo (a,b)"
99
+ dl.execute "insert into foo values (1,2)"
100
+ dl.execute "insert into foo values (3,4)"
101
+ dl.execute "insert into foo values (5,6)"
102
+
103
+ native.execute "create table foo (a,b)"
104
+ native.execute "insert into foo values (1,2)"
105
+ native.execute "insert into foo values (3,4)"
106
+ native.execute "insert into foo values (5,6)"
107
+
108
+ puts
109
+ puts "queries"
110
+ Benchmark.bm( 7 ) do |x|
111
+ x.report('dl') do
112
+ N.times do
113
+ dl.execute "select * from foo"
114
+ end
115
+ end
116
+ x.report('native') do
117
+ N.times do
118
+ native.execute "select * from foo"
119
+ end
120
+ end
121
+ end
122
+
123
+ dl.close
124
+ native.close
125
+ File.delete "test-dl.db" rescue nil
126
+ File.delete "test-native.db" rescue nil