sqlite3-ruby 1.2.5-x86-mingw32 → 1.3.0.beta.1-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/API_CHANGES.rdoc +48 -0
  2. data/{History.txt → CHANGELOG.rdoc} +24 -0
  3. data/Manifest.txt +14 -14
  4. data/{README.txt → README.rdoc} +1 -6
  5. data/Rakefile +8 -3
  6. data/ext/sqlite3/database.c +687 -0
  7. data/ext/sqlite3/database.h +15 -0
  8. data/ext/sqlite3/exception.c +94 -0
  9. data/ext/sqlite3/exception.h +8 -0
  10. data/ext/sqlite3/extconf.rb +26 -0
  11. data/ext/sqlite3/sqlite3.c +33 -0
  12. data/ext/sqlite3/sqlite3_ruby.h +43 -0
  13. data/ext/sqlite3/statement.c +412 -0
  14. data/ext/sqlite3/statement.h +16 -0
  15. data/lib/sqlite3/1.8/sqlite3_native.so +0 -0
  16. data/lib/sqlite3/1.9/sqlite3_native.so +0 -0
  17. data/lib/sqlite3/database.rb +94 -302
  18. data/lib/sqlite3/errors.rb +0 -24
  19. data/lib/sqlite3/pragmas.rb +16 -7
  20. data/lib/sqlite3/resultset.rb +25 -81
  21. data/lib/sqlite3/statement.rb +22 -107
  22. data/lib/sqlite3/version.rb +4 -4
  23. data/lib/sqlite3.rb +9 -0
  24. data/setup.rb +2 -2
  25. data/tasks/native.rake +13 -17
  26. data/tasks/vendor_sqlite3.rake +10 -7
  27. data/test/helper.rb +1 -65
  28. data/test/test_database.rb +239 -189
  29. data/test/test_encoding.rb +115 -0
  30. data/test/test_integration.rb +38 -35
  31. data/test/test_integration_open_close.rb +1 -1
  32. data/test/test_integration_pending.rb +6 -4
  33. data/test/test_integration_resultset.rb +20 -8
  34. data/test/test_integration_statement.rb +1 -2
  35. data/test/test_sqlite3.rb +9 -0
  36. data/test/test_statement.rb +193 -0
  37. metadata +84 -49
  38. data/ext/sqlite3_api/extconf.rb +0 -10
  39. data/ext/sqlite3_api/sqlite3_api.i +0 -362
  40. data/ext/sqlite3_api/sqlite3_api_wrap.c +0 -5018
  41. data/lib/1.8/sqlite3_api.so +0 -0
  42. data/lib/1.9/sqlite3_api.so +0 -0
  43. data/lib/sqlite3/driver/dl/api.rb +0 -152
  44. data/lib/sqlite3/driver/dl/driver.rb +0 -307
  45. data/lib/sqlite3/driver/native/driver.rb +0 -219
  46. data/tasks/benchmark.rake +0 -9
  47. data/tasks/gem.rake +0 -32
  48. data/test/bm.rb +0 -140
  49. data/test/driver/dl/tc_driver.rb +0 -292
  50. data/test/native-vs-dl.rb +0 -126
  51. data/test/test_errors.rb +0 -17
@@ -1,7 +1,6 @@
1
1
  require 'sqlite3/constants'
2
2
 
3
3
  module SQLite3
4
-
5
4
  class Exception < ::StandardError
6
5
  @code = 0
7
6
 
@@ -42,27 +41,4 @@ module SQLite3
42
41
  class FormatException < Exception; end
43
42
  class RangeException < Exception; end
44
43
  class NotADatabaseException < Exception; end
45
-
46
- EXCEPTIONS = [
47
- nil,
48
- SQLException, InternalException, PermissionException,
49
- AbortException, BusyException, LockedException, MemoryException,
50
- ReadOnlyException, InterruptException, IOException, CorruptException,
51
- NotFoundException, FullException, CantOpenException, ProtocolException,
52
- EmptyException, SchemaChangedException, TooBigException,
53
- ConstraintException, MismatchException, MisuseException,
54
- UnsupportedException, AuthorizationException, FormatException,
55
- RangeException, NotADatabaseException
56
- ].each_with_index { |e,i| e.instance_variable_set( :@code, i ) if e }
57
-
58
- module Error
59
- def check( result, db=nil, msg=nil )
60
- unless result == Constants::ErrorCode::OK
61
- msg = ( msg ? msg + ": " : "" ) + db.errmsg if db
62
- raise(( EXCEPTIONS[result] || SQLite3::Exception ), msg)
63
- end
64
- end
65
- module_function :check
66
- end
67
-
68
44
  end
@@ -213,16 +213,24 @@ module SQLite3
213
213
  get_query_pragma "index_list", table, &block
214
214
  end
215
215
 
216
- def table_info( table, &block ) # :yields: row
217
- columns, *rows = execute2("PRAGMA table_info(#{table})")
216
+ ###
217
+ # Returns information about +table+. Yields each row of table information
218
+ # if a block is provided.
219
+ def table_info table
220
+ stmt = prepare "PRAGMA table_info(#{table})"
221
+ columns = stmt.columns
218
222
 
219
- needs_tweak_default = version_compare(driver.libversion, "3.3.7") > 0
223
+ needs_tweak_default =
224
+ version_compare(SQLite3.libversion.to_s, "3.3.7") > 0
220
225
 
221
226
  result = [] unless block_given?
222
- rows.each do |row|
223
- new_row = {}
224
- columns.each_with_index do |name, index|
225
- new_row[name] = row[index]
227
+ stmt.each do |row|
228
+ new_row = Hash[*columns.zip(row).flatten]
229
+
230
+ # FIXME: This should be removed but is required for older versions
231
+ # of rails
232
+ if(Object.const_defined?(:ActiveRecord))
233
+ new_row['notnull'] = new_row['notnull'].to_s
226
234
  end
227
235
 
228
236
  tweak_default(new_row) if needs_tweak_default
@@ -233,6 +241,7 @@ module SQLite3
233
241
  result << new_row
234
242
  end
235
243
  end
244
+ stmt.close
236
245
 
237
246
  result
238
247
  end
@@ -31,46 +31,22 @@ module SQLite3
31
31
 
32
32
  # Create a new ResultSet attached to the given database, using the
33
33
  # given sql text.
34
- def initialize( db, stmt )
35
- @db = db
36
- @driver = @db.driver
34
+ def initialize db, stmt
35
+ @db = db
37
36
  @stmt = stmt
38
- commence
39
37
  end
40
38
 
41
- # A convenience method for compiling the virtual machine and stepping
42
- # to the first row of the result set.
43
- def commence
44
- result = @driver.step( @stmt.handle )
45
- if result == Constants::ErrorCode::ERROR
46
- @driver.reset( @stmt.handle )
47
- end
48
- check result
49
- @first_row = true
50
- end
51
- private :commence
52
-
53
- def check( result )
54
- @eof = ( result == Constants::ErrorCode::DONE )
55
- found = ( result == Constants::ErrorCode::ROW )
56
- Error.check( result, @db ) unless @eof || found
57
- end
58
- private :check
59
-
60
39
  # Reset the cursor, so that a result set which has reached end-of-file
61
40
  # can be rewound and reiterated.
62
41
  def reset( *bind_params )
63
- @stmt.must_be_open!
64
- @stmt.reset!(false)
65
- @driver.reset( @stmt.handle )
42
+ @stmt.reset!
66
43
  @stmt.bind_params( *bind_params )
67
44
  @eof = false
68
- commence
69
45
  end
70
46
 
71
47
  # Query whether the cursor has reached the end of the result set or not.
72
48
  def eof?
73
- @eof
49
+ @stmt.done?
74
50
  end
75
51
 
76
52
  # Obtain the next row from the cursor. If there are no more rows to be
@@ -87,70 +63,38 @@ module SQLite3
87
63
  # For hashes, the column names are the keys of the hash, and the column
88
64
  # types are accessible via the +types+ property.
89
65
  def next
90
- return nil if @eof
91
-
92
- @stmt.must_be_open!
93
-
94
- unless @first_row
95
- result = @driver.step( @stmt.handle )
96
- check result
97
- end
98
-
99
- @first_row = false
100
-
101
- unless @eof
102
- row = []
103
- @driver.data_count( @stmt.handle ).times do |column|
104
- type = @driver.column_type( @stmt.handle, column )
105
-
106
- if type == Constants::ColumnType::TEXT
107
- row << @driver.column_text( @stmt.handle, column )
108
- elsif type == Constants::ColumnType::NULL
109
- row << nil
110
- elsif type == Constants::ColumnType::BLOB
111
- row << @driver.column_blob( @stmt.handle, column )
112
- else
113
- row << @driver.column_text( @stmt.handle, column )
114
- end
115
- end
66
+ row = @stmt.step
67
+ return nil if @stmt.done?
116
68
 
117
- if @db.type_translation
118
- row = @stmt.types.zip( row ).map do |type, value|
119
- @db.translator.translate( type, value )
120
- end
69
+ if @db.type_translation
70
+ row = @stmt.types.zip(row).map do |type, value|
71
+ @db.translator.translate( type, value )
121
72
  end
73
+ end
122
74
 
123
- if @db.results_as_hash
124
- new_row = HashWithTypes[ *( @stmt.columns.zip( row ).to_a.flatten ) ]
125
- row.each_with_index { |value,idx|
126
- value.taint
127
- new_row[idx] = value
128
- }
129
- row = new_row
75
+ if @db.results_as_hash
76
+ new_row = HashWithTypes[*@stmt.columns.zip(row).flatten]
77
+ row.each_with_index { |value,idx|
78
+ new_row[idx] = value
79
+ }
80
+ row = new_row
81
+ else
82
+ if row.respond_to?(:fields)
83
+ row = ArrayWithTypes.new(row)
130
84
  else
131
- if row.respond_to?(:fields)
132
- row = ArrayWithTypes.new(row)
133
- else
134
- row = ArrayWithTypesAndFields.new(row)
135
- end
136
- row.fields = @stmt.columns
137
- row.each { |column| column.taint }
85
+ row = ArrayWithTypesAndFields.new(row)
138
86
  end
139
-
140
- row.types = @stmt.types
141
-
142
- return row
87
+ row.fields = @stmt.columns
143
88
  end
144
89
 
145
- nil
90
+ row.types = @stmt.types
91
+ row
146
92
  end
147
93
 
148
94
  # Required by the Enumerable mixin. Provides an internal iterator over the
149
95
  # rows of the result set.
150
- def each
151
- while row=self.next
152
- yield row
153
- end
96
+ def each( &block )
97
+ @stmt.each(&block)
154
98
  end
155
99
 
156
100
  # Closes the statement that spawned this result set.
@@ -8,51 +8,17 @@ class String
8
8
  end
9
9
 
10
10
  module SQLite3
11
-
12
- # A class for differentiating between strings and blobs, when binding them
13
- # into statements.
14
- class Blob < String; end
15
-
16
11
  # A statement represents a prepared-but-unexecuted SQL query. It will rarely
17
12
  # (if ever) be instantiated directly by a client, and is most often obtained
18
13
  # via the Database#prepare method.
19
14
  class Statement
15
+ include Enumerable
20
16
 
21
17
  # This is any text that followed the first valid SQL statement in the text
22
18
  # with which the statement was initialized. If there was no trailing text,
23
19
  # this will be the empty string.
24
20
  attr_reader :remainder
25
21
 
26
- # The underlying opaque handle used to access the SQLite @driver.
27
- attr_reader :handle
28
-
29
- # Create a new statement attached to the given Database instance, and which
30
- # encapsulates the given SQL text. If the text contains more than one
31
- # statement (i.e., separated by semicolons), then the #remainder property
32
- # will be set to the trailing text.
33
- def initialize( db, sql, utf16=false )
34
- raise ArgumentError, "nil argument passed as sql text" unless sql
35
- @db = db
36
- @driver = @db.driver
37
- @closed = false
38
- @results = @columns = nil
39
- result, @handle, @remainder = @driver.prepare( @db.handle, sql )
40
- Error.check( result, @db )
41
- end
42
-
43
- # Closes the statement by finalizing the underlying statement
44
- # handle. The statement must not be used after being closed.
45
- def close
46
- must_be_open!
47
- @closed = true
48
- @driver.finalize( @handle )
49
- end
50
-
51
- # Returns true if the underlying statement has been closed.
52
- def closed?
53
- @closed
54
- end
55
-
56
22
  # Binds the given variables to the corresponding placeholders in the SQL
57
23
  # text.
58
24
  #
@@ -78,42 +44,6 @@ module SQLite3
78
44
  end
79
45
  end
80
46
 
81
- # Binds value to the named (or positional) placeholder. If +param+ is a
82
- # Fixnum, it is treated as an index for a positional placeholder.
83
- # Otherwise it is used as the name of the placeholder to bind to.
84
- #
85
- # See also #bind_params.
86
- def bind_param( param, value )
87
- must_be_open!
88
- reset! if active?
89
- if Fixnum === param
90
- case value
91
- when Bignum then
92
- @driver.bind_int64( @handle, param, value )
93
- when Integer then
94
- if value >= (2 ** 31)
95
- @driver.bind_int64( @handle, param, value )
96
- else
97
- @driver.bind_int( @handle, param, value )
98
- end
99
- when Numeric then
100
- @driver.bind_double( @handle, param, value.to_f )
101
- when Blob then
102
- @driver.bind_blob( @handle, param, value )
103
- when nil then
104
- @driver.bind_null( @handle, param )
105
- else
106
- @driver.bind_text( @handle, param, value )
107
- end
108
- else
109
- param = param.to_s
110
- param = ":#{param}" unless param[0] == ?:
111
- index = @driver.bind_parameter_index( @handle, param )
112
- raise Exception, "no such bind parameter '#{param}'" if index == 0
113
- bind_param index, value
114
- end
115
- end
116
-
117
47
  # Execute the statement. This creates a new ResultSet object for the
118
48
  # statement's virtual machine. If a block was given, the new ResultSet will
119
49
  # be yielded to it; otherwise, the ResultSet will be returned.
@@ -129,17 +59,13 @@ module SQLite3
129
59
  #
130
60
  # See also #bind_params, #execute!.
131
61
  def execute( *bind_vars )
132
- must_be_open!
133
- reset! if active?
62
+ reset! if active? || done?
134
63
 
135
64
  bind_params(*bind_vars) unless bind_vars.empty?
136
- @results = ResultSet.new( @db, self )
65
+ @results = ResultSet.new(@connection, self)
137
66
 
138
- if block_given?
139
- yield @results
140
- else
141
- return @results
142
- end
67
+ yield @results if block_given?
68
+ @results
143
69
  end
144
70
 
145
71
  # Execute the statement. If no block was given, this returns an array of
@@ -156,30 +82,15 @@ module SQLite3
156
82
  # end
157
83
  #
158
84
  # See also #bind_params, #execute.
159
- def execute!( *bind_vars )
160
- result = execute( *bind_vars )
161
- rows = [] unless block_given?
162
- while row = result.next
163
- if block_given?
164
- yield row
165
- else
166
- rows << row
167
- end
168
- end
169
- rows
170
- end
171
-
172
- # Resets the statement. This is typically done internally, though it might
173
- # occassionally be necessary to manually reset the statement.
174
- def reset!(clear_result=true)
175
- @driver.reset(@handle)
176
- @results = nil if clear_result
85
+ def execute!( *bind_vars, &block )
86
+ execute(*bind_vars)
87
+ block_given? ? each(&block) : to_a
177
88
  end
178
89
 
179
90
  # Returns true if the statement is currently active, meaning it has an
180
91
  # open result set.
181
92
  def active?
182
- not @results.nil?
93
+ !done?
183
94
  end
184
95
 
185
96
  # Return an array of the column names for this statement. Note that this
@@ -190,11 +101,20 @@ module SQLite3
190
101
  return @columns
191
102
  end
192
103
 
104
+ def each
105
+ loop do
106
+ val = step
107
+ break self if done?
108
+ yield val
109
+ end
110
+ end
111
+
193
112
  # Return an array of the data types for each column in this statement. Note
194
113
  # that this may execute the statement in order to obtain the metadata; this
195
114
  # makes it a (potentially) expensive operation.
196
115
  def types
197
- get_metadata unless defined?(@types)
116
+ must_be_open!
117
+ get_metadata unless @types
198
118
  @types
199
119
  end
200
120
 
@@ -202,15 +122,12 @@ module SQLite3
202
122
  # that this will actually execute the SQL, which means it can be a
203
123
  # (potentially) expensive operation.
204
124
  def get_metadata
205
- must_be_open!
206
-
207
125
  @columns = []
208
126
  @types = []
209
127
 
210
- column_count = @driver.column_count( @handle )
211
128
  column_count.times do |column|
212
- @columns << @driver.column_name( @handle, column )
213
- @types << @driver.column_decltype( @handle, column )
129
+ @columns << column_name(column)
130
+ @types << column_decltype(column)
214
131
  end
215
132
 
216
133
  @columns.freeze
@@ -221,11 +138,9 @@ module SQLite3
221
138
  # Performs a sanity check to ensure that the statement is not
222
139
  # closed. If it is, an exception is raised.
223
140
  def must_be_open! # :nodoc:
224
- if @closed
141
+ if closed?
225
142
  raise SQLite3::Exception, "cannot use a closed statement"
226
143
  end
227
144
  end
228
-
229
145
  end
230
-
231
146
  end
@@ -3,14 +3,14 @@ module SQLite3
3
3
  module Version
4
4
 
5
5
  MAJOR = 1
6
- MINOR = 2
7
- TINY = 5
8
- BUILD = nil
6
+ MINOR = 3
7
+ TINY = 0
8
+ BUILD = "beta.1"
9
9
 
10
10
  STRING = [ MAJOR, MINOR, TINY, BUILD ].compact.join( "." )
11
11
  #:beta-tag:
12
12
 
13
- VERSION = '1.2.5'
13
+ VERSION = '1.3.0.beta.1'
14
14
  end
15
15
 
16
16
  end
data/lib/sqlite3.rb CHANGED
@@ -1 +1,10 @@
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
+
1
9
  require 'sqlite3/database'
10
+ require 'sqlite3/version'