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.
- data/lib/sqlite3/database.rb +27 -3
- data/lib/sqlite3/driver/dl/api.rb +1 -1
- data/lib/sqlite3/errors.rb +20 -4
- data/lib/sqlite3/resultset.rb +17 -0
- data/lib/sqlite3/statement.rb +22 -0
- data/lib/sqlite3/version.rb +2 -2
- data/test/tc_errors.rb +54 -0
- data/test/tc_integration.rb +93 -0
- metadata +3 -2
data/lib/sqlite3/database.rb
CHANGED
@@ -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"
|
data/lib/sqlite3/errors.rb
CHANGED
@@ -34,7 +34,19 @@ require 'sqlite3/constants'
|
|
34
34
|
|
35
35
|
module SQLite3
|
36
36
|
|
37
|
-
class Exception < ::Exception
|
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
|
data/lib/sqlite3/resultset.rb
CHANGED
@@ -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
|
data/lib/sqlite3/statement.rb
CHANGED
@@ -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
|
data/lib/sqlite3/version.rb
CHANGED
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
|
data/test/tc_integration.rb
CHANGED
@@ -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
|
7
|
-
date: 2005-02-
|
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
|