sqlite3-ruby 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

@@ -204,7 +204,7 @@ module SQLite3
204
204
  # by the query. Otherwise, any results are accumulated into an array and
205
205
  # returned wholesale.
206
206
  #
207
- # See also #execute2, and #execute_batch for additional ways of
207
+ # See also #execute2, #query, and #execute_batch for additional ways of
208
208
  # executing statements.
209
209
  def execute( sql, *bind_vars )
210
210
  prepare( sql ) do |stmt|
@@ -225,7 +225,7 @@ module SQLite3
225
225
  # Thus, even if the query itself returns no rows, this method will always
226
226
  # return at least one row--the names of the columns.
227
227
  #
228
- # See also #execute, and #execute_batch for additional ways of
228
+ # See also #execute, #query, and #execute_batch for additional ways of
229
229
  # executing statements.
230
230
  def execute2( sql, *bind_vars )
231
231
  prepare( sql ) do |stmt|
@@ -259,6 +259,30 @@ module SQLite3
259
259
  nil
260
260
  end
261
261
 
262
+ # This is a convenience method for creating a statement, binding
263
+ # paramters to it, and calling execute:
264
+ #
265
+ # result = db.query( "select * from foo where a=?", 5 )
266
+ # # is the same as
267
+ # result = db.prepare( "select * from foo where a=?" ).execute( 5 )
268
+ #
269
+ # You must be sure to call +close+ on the ResultSet instance that is
270
+ # returned, or you could have problems with locks on the table. If called
271
+ # with a block, +close+ will be invoked implicitly when the block
272
+ # terminates.
273
+ def query( sql, *bind_vars )
274
+ result = prepare( sql ).execute( *bind_vars )
275
+ if block_given?
276
+ begin
277
+ yield result
278
+ ensure
279
+ result.close
280
+ end
281
+ else
282
+ return result
283
+ end
284
+ end
285
+
262
286
  # A convenience method for obtaining the first row of a result set, and
263
287
  # discarding all others. It is otherwise identical to #execute.
264
288
  #
@@ -620,7 +644,7 @@ module SQLite3
620
644
  break
621
645
  rescue SyntaxError
622
646
  raise
623
- rescue ScriptError, Exception
647
+ rescue ScriptError, Exception, NameError
624
648
  end
625
649
  end
626
650
  raise "no driver for sqlite3 found" unless driver
@@ -40,7 +40,7 @@ module SQLite3 ; module Driver; module DL;
40
40
  library_name = case RUBY_PLATFORM.downcase
41
41
  when /darwin/
42
42
  "libsqlite3.dylib"
43
- when /linux/, /freebsd|netbsd|openbsd|dragonfly/
43
+ when /linux/, /freebsd|netbsd|openbsd|dragonfly/, /solaris/
44
44
  "libsqlite3.so"
45
45
  when /win32/
46
46
  "sqlite3.dll"
@@ -34,7 +34,19 @@ require 'sqlite3/constants'
34
34
 
35
35
  module SQLite3
36
36
 
37
- class Exception < ::Exception; end
37
+ class Exception < ::Exception
38
+ @code = 0
39
+
40
+ # The numeric error code that this exception represents.
41
+ def self.code
42
+ @code
43
+ end
44
+
45
+ # A convenience for accessing the error code for this exception.
46
+ def code
47
+ self.class.code
48
+ end
49
+ end
38
50
 
39
51
  class SQLException < Exception; end
40
52
  class InternalException < Exception; end
@@ -59,6 +71,9 @@ module SQLite3
59
71
  class MisuseException < Exception; end
60
72
  class UnsupportedException < Exception; end
61
73
  class AuthorizationException < Exception; end
74
+ class FormatException < Exception; end
75
+ class RangeException < Exception; end
76
+ class NotADatabaseException < Exception; end
62
77
 
63
78
  EXCEPTIONS = [
64
79
  nil,
@@ -68,14 +83,15 @@ module SQLite3
68
83
  NotFoundException, FullException, CantOpenException, ProtocolException,
69
84
  EmptyException, SchemaChangedException, TooBigException,
70
85
  ConstraintException, MismatchException, MisuseException,
71
- UnsupportedException, AuthorizationException
72
- ]
86
+ UnsupportedException, AuthorizationException, FormatException,
87
+ RangeException, NotADatabaseException
88
+ ].each_with_index { |e,i| e.instance_variable_set( :@code, i ) if e }
73
89
 
74
90
  module Error
75
91
  def check( result, db=nil, msg=nil )
76
92
  unless result == Constants::ErrorCode::OK
77
93
  msg = ( msg ? msg + ": " : "" ) + db.errmsg if db
78
- raise EXCEPTIONS[result], msg
94
+ raise ( EXCEPTIONS[result] || SQLite3::Exception ), msg
79
95
  end
80
96
  end
81
97
  module_function :check
@@ -80,6 +80,7 @@ module SQLite3
80
80
  # Reset the cursor, so that a result set which has reached end-of-file
81
81
  # can be rewound and reiterated.
82
82
  def reset( *bind_params )
83
+ @stmt.must_be_open!
83
84
  @driver.reset( @stmt.handle )
84
85
  @stmt.bind_params( *bind_params )
85
86
  @eof = false
@@ -107,6 +108,8 @@ module SQLite3
107
108
  def next
108
109
  return nil if @eof
109
110
 
111
+ @stmt.must_be_open!
112
+
110
113
  unless @first_row
111
114
  result = @driver.step( @stmt.handle )
112
115
  check result
@@ -159,10 +162,24 @@ module SQLite3
159
162
  end
160
163
  end
161
164
 
165
+ # Closes the statement that spawned this result set.
166
+ # <em>Use with caution!</em> Closing a result set will automatically
167
+ # close any other result sets that were spawned from the same statement.
168
+ def close
169
+ @stmt.close
170
+ end
171
+
172
+ # Queries whether the underlying statement has been closed or not.
173
+ def closed?
174
+ @stmt.closed?
175
+ end
176
+
177
+ # Returns the types of the columns returned by this result set.
162
178
  def types
163
179
  @stmt.types
164
180
  end
165
181
 
182
+ # Returns the names of the columns returned by this result set.
166
183
  def columns
167
184
  @stmt.columns
168
185
  end
@@ -65,14 +65,24 @@ module SQLite3
65
65
  def initialize( db, sql, utf16=false )
66
66
  @db = db
67
67
  @driver = @db.driver
68
+ @closed = false
68
69
  result, @handle, @remainder = @driver.prepare( @db.handle, sql )
69
70
  Error.check( result, @db )
70
71
  end
71
72
 
73
+ # Closes the statement by finalizing the underlying statement
74
+ # handle. The statement must not be used after being closed.
72
75
  def close
76
+ must_be_open!
77
+ @closed = true
73
78
  @driver.finalize( @handle )
74
79
  end
75
80
 
81
+ # Returns true if the underlying statement has been closed.
82
+ def closed?
83
+ @closed
84
+ end
85
+
76
86
  # Binds the given variables to the corresponding placeholders in the SQL
77
87
  # text.
78
88
  #
@@ -104,6 +114,7 @@ module SQLite3
104
114
  #
105
115
  # See also #bind_params.
106
116
  def bind_param( param, value )
117
+ must_be_open!
107
118
  if Fixnum === param
108
119
  case value
109
120
  when Integer then
@@ -140,6 +151,7 @@ module SQLite3
140
151
  #
141
152
  # See also #bind_params, #execute!.
142
153
  def execute( *bind_vars )
154
+ must_be_open!
143
155
  @driver.reset( @handle ) if @results
144
156
 
145
157
  bind_params *bind_vars unless bind_vars.empty?
@@ -199,6 +211,8 @@ module SQLite3
199
211
  # that this will actually execute the SQL, which means it can be a
200
212
  # (potentially) expensive operation.
201
213
  def get_metadata
214
+ must_be_open!
215
+
202
216
  @columns = []
203
217
  @types = []
204
218
 
@@ -213,6 +227,14 @@ module SQLite3
213
227
  end
214
228
  private :get_metadata
215
229
 
230
+ # Performs a sanity check to ensure that the statement is not
231
+ # closed. If it is, an exception is raised.
232
+ def must_be_open! # :nodoc:
233
+ if @closed
234
+ raise SQLite3::Exception, "cannot use a closed statement"
235
+ end
236
+ end
237
+
216
238
  end
217
239
 
218
240
  end
@@ -35,8 +35,8 @@ module SQLite3
35
35
  module Version
36
36
 
37
37
  MAJOR = 1
38
- MINOR = 0
39
- TINY = 1
38
+ MINOR = 1
39
+ TINY = 0
40
40
 
41
41
  STRING = [ MAJOR, MINOR, TINY ].join( "." )
42
42
 
data/test/tc_errors.rb ADDED
@@ -0,0 +1,54 @@
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
+ $:.unshift "../lib"
34
+
35
+ require 'sqlite3/errors'
36
+ require 'test/unit'
37
+ require 'flexmock'
38
+
39
+ class TC_Errors < Test::Unit::TestCase
40
+ (1..26).each do |code|
41
+ define_method( "test_error_code_%02d" % code ) do
42
+ db = FlexMock.new
43
+ db.mock_handle( :errmsg ) { "message" }
44
+ begin
45
+ SQLite3::Error.check( code, db )
46
+ rescue SQLite3::Exception => e
47
+ assert_instance_of SQLite3::EXCEPTIONS[code], e
48
+ assert_equal code, e.code
49
+ assert_equal code, e.class.code
50
+ assert_equal "message", e.message
51
+ end
52
+ end
53
+ end
54
+ end
@@ -302,6 +302,70 @@ module Integration
302
302
  assert_equal %w{1 1 1}, rows
303
303
  end
304
304
 
305
+ define_method( "test_query_no_block_no_bind_no_match" ) do
306
+ result = @db.query( "select * from foo where a > 100" )
307
+ assert_nil result.next
308
+ result.close
309
+ end
310
+
311
+ define_method( "test_query_with_block_no_bind_no_match" ) do
312
+ r = nil
313
+ @db.query( "select * from foo where a > 100" ) do |result|
314
+ assert_nil result.next
315
+ r = result
316
+ end
317
+ assert r.closed?
318
+ end
319
+
320
+ define_method( "test_query_no_block_with_bind_no_match" ) do
321
+ result = @db.query( "select * from foo where a > ?", 100 )
322
+ assert_nil result.next
323
+ result.close
324
+ end
325
+
326
+ define_method( "test_query_with_block_with_bind_no_match" ) do
327
+ r = nil
328
+ @db.query( "select * from foo where a > ?", 100 ) do |result|
329
+ assert_nil result.next
330
+ r = result
331
+ end
332
+ assert r.closed?
333
+ end
334
+
335
+ define_method( "test_query_no_block_no_bind_with_match" ) do
336
+ result = @db.query( "select * from foo where a = 1" )
337
+ assert_not_nil result.next
338
+ assert_nil result.next
339
+ result.close
340
+ end
341
+
342
+ define_method( "test_query_with_block_no_bind_with_match" ) do
343
+ r = nil
344
+ @db.query( "select * from foo where a = 1" ) do |result|
345
+ assert_not_nil result.next
346
+ assert_nil result.next
347
+ r = result
348
+ end
349
+ assert r.closed?
350
+ end
351
+
352
+ define_method( "test_query_no_block_with_bind_with_match" ) do
353
+ result = @db.query( "select * from foo where a = ?", 1 )
354
+ assert_not_nil result.next
355
+ assert_nil result.next
356
+ result.close
357
+ end
358
+
359
+ define_method( "test_query_with_block_with_bind_with_match" ) do
360
+ r = nil
361
+ @db.query( "select * from foo where a = ?", 1 ) do |result|
362
+ assert_not_nil result.next
363
+ assert_nil result.next
364
+ r = result
365
+ end
366
+ assert r.closed?
367
+ end
368
+
305
369
  define_method( "test_get_first_row_no_bind_no_match" ) do
306
370
  result = @db.get_first_row( "select * from foo where a=100" )
307
371
  assert_nil result
@@ -741,6 +805,20 @@ module Integration
741
805
  end
742
806
  assert called
743
807
  end
808
+
809
+ define_method( "test_close" ) do
810
+ stmt = @db.prepare( "select * from foo" )
811
+ assert !stmt.closed?
812
+ stmt.close
813
+ assert stmt.closed?
814
+ assert_raise( SQLite3::Exception ) { stmt.execute }
815
+ assert_raise( SQLite3::Exception ) { stmt.execute! }
816
+ assert_raise( SQLite3::Exception ) { stmt.close }
817
+ assert_raise( SQLite3::Exception ) { stmt.bind_params 5 }
818
+ assert_raise( SQLite3::Exception ) { stmt.bind_param 1, 5 }
819
+ assert_raise( SQLite3::Exception ) { stmt.columns }
820
+ assert_raise( SQLite3::Exception ) { stmt.types }
821
+ end
744
822
  end
745
823
  const_set( "TC_Statement_#{driver}", test_case )
746
824
 
@@ -837,6 +915,21 @@ module Integration
837
915
  define_method( "test_columns" ) do
838
916
  assert_equal [ "a", "b" ], @result.columns
839
917
  end
918
+
919
+ define_method( "test_close" ) do
920
+ stmt = @db.prepare( "select * from foo" )
921
+ result = stmt.execute
922
+ assert !result.closed?
923
+ result.close
924
+ assert result.closed?
925
+ assert stmt.closed?
926
+ assert_raise( SQLite3::Exception ) { result.reset }
927
+ assert_raise( SQLite3::Exception ) { result.next }
928
+ assert_raise( SQLite3::Exception ) { result.each }
929
+ assert_raise( SQLite3::Exception ) { result.close }
930
+ assert_raise( SQLite3::Exception ) { result.types }
931
+ assert_raise( SQLite3::Exception ) { result.columns }
932
+ end
840
933
  end
841
934
  const_set( "TC_ResultSet_#{driver}", test_case )
842
935
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.4
3
3
  specification_version: 1
4
4
  name: sqlite3-ruby
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.1
7
- date: 2005-02-06
6
+ version: 1.1.0
7
+ date: 2005-02-15
8
8
  summary: SQLite3/Ruby is a module to allow Ruby scripts to interface with a SQLite3 database.
9
9
  require_paths:
10
10
  - lib
@@ -58,6 +58,7 @@ files:
58
58
  - test/mocks.rb
59
59
  - test/tests.rb
60
60
  - test/tc_integration.rb
61
+ - test/tc_errors.rb
61
62
  - test/driver
62
63
  - test/native-vs-dl.rb
63
64
  - test/tc_database.rb