sqlite3-ruby 0.5.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.

@@ -0,0 +1,84 @@
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/constants'
34
+
35
+ module SQLite3
36
+
37
+ class Exception < ::Exception; end
38
+
39
+ class SQLException < Exception; end
40
+ class InternalException < Exception; end
41
+ class PermissionException < Exception; end
42
+ class AbortException < Exception; end
43
+ class BusyException < Exception; end
44
+ class LockedException < Exception; end
45
+ class MemoryException < Exception; end
46
+ class ReadOnlyException < Exception; end
47
+ class InterruptException < Exception; end
48
+ class IOException < Exception; end
49
+ class CorruptException < Exception; end
50
+ class NotFoundException < Exception; end
51
+ class FullException < Exception; end
52
+ class CantOpenException < Exception; end
53
+ class ProtocolException < Exception; end
54
+ class EmptyException < Exception; end
55
+ class SchemaChangedException < Exception; end
56
+ class TooBigException < Exception; end
57
+ class ConstraintException < Exception; end
58
+ class MismatchException < Exception; end
59
+ class MisuseException < Exception; end
60
+ class UnsupportedException < Exception; end
61
+ class AuthorizationException < Exception; end
62
+
63
+ EXCEPTIONS = [
64
+ nil,
65
+ SQLException, InternalException, PermissionException,
66
+ AbortException, BusyException, LockedException, MemoryException,
67
+ ReadOnlyException, InterruptException, IOException, CorruptException,
68
+ NotFoundException, FullException, CantOpenException, ProtocolException,
69
+ EmptyException, SchemaChangedException, TooBigException,
70
+ ConstraintException, MismatchException, MisuseException,
71
+ UnsupportedException, AuthorizationException
72
+ ]
73
+
74
+ module Error
75
+ def check( result, db=nil, msg=nil )
76
+ unless result == Constants::ErrorCode::OK
77
+ msg = ( msg ? msg + ": " : "" ) + db.errmsg if db
78
+ raise EXCEPTIONS[result], msg
79
+ end
80
+ end
81
+ module_function :check
82
+ end
83
+
84
+ end
@@ -0,0 +1,254 @@
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/errors'
34
+
35
+ module SQLite3
36
+
37
+ # This module is intended for inclusion solely by the Database class. It
38
+ # defines convenience methods for the various pragmas supported by SQLite3.
39
+ #
40
+ # For a detailed description of these pragmas, see the SQLite3 documentation
41
+ # at http://sqlite.org/pragma.html.
42
+ module Pragmas
43
+
44
+ # Returns +true+ or +false+ depending on the value of the named pragma.
45
+ def get_boolean_pragma( name )
46
+ get_first_value( "PRAGMA #{name}" ) != "0"
47
+ end
48
+ private :get_boolean_pragma
49
+
50
+ # Sets the given pragma to the given boolean value. The value itself
51
+ # may be +true+ or +false+, or any other commonly used string or
52
+ # integer that represents truth.
53
+ def set_boolean_pragma( name, mode )
54
+ case mode
55
+ when String
56
+ case mode.downcase
57
+ when "on", "yes", "true", "y", "t": mode = "'ON'"
58
+ when "off", "no", "false", "n", "f": mode = "'OFF'"
59
+ else
60
+ raise Exception,
61
+ "unrecognized pragma parameter #{mode.inspect}"
62
+ end
63
+ when true, 1
64
+ mode = "ON"
65
+ when false, 0, nil
66
+ mode = "OFF"
67
+ else
68
+ raise Exception,
69
+ "unrecognized pragma parameter #{mode.inspect}"
70
+ end
71
+
72
+ execute( "PRAGMA #{name}=#{mode}" )
73
+ end
74
+ private :set_boolean_pragma
75
+
76
+ # Requests the given pragma (and parameters), and if the block is given,
77
+ # each row of the result set will be yielded to it. Otherwise, the results
78
+ # are returned as an array.
79
+ def get_query_pragma( name, *parms, &block ) # :yields: row
80
+ if parms.empty?
81
+ execute( "PRAGMA #{name}", &block )
82
+ else
83
+ args = "'" + parms.join("','") + "'"
84
+ execute( "PRAGMA #{name}( #{args} )", &block )
85
+ end
86
+ end
87
+ private :get_query_pragma
88
+
89
+ # Return the value of the given pragma.
90
+ def get_enum_pragma( name )
91
+ get_first_value( "PRAGMA #{name}" )
92
+ end
93
+ private :get_enum_pragma
94
+
95
+ # Set the value of the given pragma to +mode+. The +mode+ parameter must
96
+ # conform to one of the values in the given +enum+ array. Each entry in
97
+ # the array is another array comprised of elements in the enumeration that
98
+ # have duplicate values. See #synchronous, #default_synchronous,
99
+ # #temp_store, and #default_temp_store for usage examples.
100
+ def set_enum_pragma( name, mode, enums )
101
+ match = enums.find { |p| p.find { |i| i.to_s.downcase == mode.to_s.downcase } }
102
+ raise Exception,
103
+ "unrecognized #{name} #{mode.inspect}" unless match
104
+ execute( "PRAGMA #{name}='#{match.first.upcase}'" )
105
+ end
106
+ private :set_enum_pragma
107
+
108
+ # Returns the value of the given pragma as an integer.
109
+ def get_int_pragma( name )
110
+ get_first_value( "PRAGMA #{name}" ).to_i
111
+ end
112
+ private :get_int_pragma
113
+
114
+ # Set the value of the given pragma to the integer value of the +value+
115
+ # parameter.
116
+ def set_int_pragma( name, value )
117
+ execute( "PRAGMA #{name}=#{value.to_i}" )
118
+ end
119
+ private :set_int_pragma
120
+
121
+ # The enumeration of valid synchronous modes.
122
+ SYNCHRONOUS_MODES = [ [ 'full', 2 ], [ 'normal', 1 ], [ 'off', 0 ] ]
123
+
124
+ # The enumeration of valid temp store modes.
125
+ TEMP_STORE_MODES = [ [ 'default', 0 ], [ 'file', 1 ], [ 'memory', 2 ] ]
126
+
127
+ # Does an integrity check on the database. If the check fails, a
128
+ # SQLite3::Exception will be raised. Otherwise it
129
+ # returns silently.
130
+ def integrity_check
131
+ execute( "PRAGMA integrity_check" ) do |row|
132
+ raise Exception, row[0] if row[0] != "ok"
133
+ end
134
+ end
135
+
136
+ def auto_vacuum
137
+ get_boolean_pragma "auto_vacuum"
138
+ end
139
+
140
+ def auto_vacuum=( mode )
141
+ set_boolean_pragma "auto_vacuum", mode
142
+ end
143
+
144
+ def schema_cookie
145
+ get_int_pragma "schema_cookie"
146
+ end
147
+
148
+ def schema_cookie=( cookie )
149
+ set_int_pragma "schema_cookie", cookie
150
+ end
151
+
152
+ def user_cookie
153
+ get_int_pragma "user_cookie"
154
+ end
155
+
156
+ def user_cookie=( cookie )
157
+ set_int_pragma "user_cookie", cookie
158
+ end
159
+
160
+ def cache_size
161
+ get_int_pragma "cache_size"
162
+ end
163
+
164
+ def cache_size=( size )
165
+ set_int_pragma "cache_size", size
166
+ end
167
+
168
+ def default_cache_size
169
+ get_int_pragma "default_cache_size"
170
+ end
171
+
172
+ def default_cache_size=( size )
173
+ set_int_pragma "default_cache_size", size
174
+ end
175
+
176
+ def default_synchronous
177
+ get_enum_pragma "default_synchronous"
178
+ end
179
+
180
+ def default_synchronous=( mode )
181
+ set_enum_pragma "default_synchronous", mode, SYNCHRONOUS_MODES
182
+ end
183
+
184
+ def synchronous
185
+ get_enum_pragma "synchronous"
186
+ end
187
+
188
+ def synchronous=( mode )
189
+ set_enum_pragma "synchronous", mode, SYNCHRONOUS_MODES
190
+ end
191
+
192
+ def default_temp_store
193
+ get_enum_pragma "default_temp_store"
194
+ end
195
+
196
+ def default_temp_store=( mode )
197
+ set_enum_pragma "default_temp_store", mode, TEMP_STORE_MODES
198
+ end
199
+
200
+ def temp_store
201
+ get_enum_pragma "temp_store"
202
+ end
203
+
204
+ def temp_store=( mode )
205
+ set_enum_pragma "temp_store", mode, TEMP_STORE_MODES
206
+ end
207
+
208
+ def full_column_names
209
+ get_boolean_pragma "full_column_names"
210
+ end
211
+
212
+ def full_column_names=( mode )
213
+ set_boolean_pragma "full_column_names", mode
214
+ end
215
+
216
+ def parser_trace
217
+ get_boolean_pragma "parser_trace"
218
+ end
219
+
220
+ def parser_trace=( mode )
221
+ set_boolean_pragma "parser_trace", mode
222
+ end
223
+
224
+ def vdbe_trace
225
+ get_boolean_pragma "vdbe_trace"
226
+ end
227
+
228
+ def vdbe_trace=( mode )
229
+ set_boolean_pragma "vdbe_trace", mode
230
+ end
231
+
232
+ def database_list( &block ) # :yields: row
233
+ get_query_pragma "database_list", &block
234
+ end
235
+
236
+ def foreign_key_list( table, &block ) # :yields: row
237
+ get_query_pragma "foreign_key_list", table, &block
238
+ end
239
+
240
+ def index_info( index, &block ) # :yields: row
241
+ get_query_pragma "index_info", index, &block
242
+ end
243
+
244
+ def index_list( table, &block ) # :yields: row
245
+ get_query_pragma "index_list", table, &block
246
+ end
247
+
248
+ def table_info( table, &block ) # :yields: row
249
+ get_query_pragma "table_info", table, &block
250
+ end
251
+
252
+ end
253
+
254
+ end
@@ -0,0 +1,172 @@
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/constants'
34
+ require 'sqlite3/errors'
35
+
36
+ module SQLite3
37
+
38
+ # The ResultSet object encapsulates the enumerability of a query's output.
39
+ # It is a simple cursor over the data that the query returns. It will
40
+ # very rarely (if ever) be instantiated directly. Instead, client's should
41
+ # obtain a ResultSet instance via Statement#execute.
42
+ class ResultSet
43
+ include Enumerable
44
+
45
+ # A trivial module for adding a +types+ accessor to an object.
46
+ module TypesContainer
47
+ attr_accessor :types
48
+ end
49
+
50
+ # A trivial module for adding a +fields+ accessor to an object.
51
+ module FieldsContainer
52
+ attr_accessor :fields
53
+ end
54
+
55
+ # Create a new ResultSet attached to the given database, using the
56
+ # given sql text.
57
+ def initialize( db, stmt )
58
+ @db = db
59
+ @driver = @db.driver
60
+ @stmt = stmt
61
+ commence
62
+ end
63
+
64
+ # A convenience method for compiling the virtual machine and stepping
65
+ # to the first row of the result set.
66
+ def commence
67
+ result = @driver.step( @stmt.handle )
68
+ check result
69
+ @first_row = true
70
+ end
71
+ private :commence
72
+
73
+ def check( result )
74
+ @eof = ( result == Constants::ErrorCode::DONE )
75
+ found = ( result == Constants::ErrorCode::ROW )
76
+ Error.check( result, @db ) unless @eof || found
77
+ end
78
+ private :check
79
+
80
+ # Reset the cursor, so that a result set which has reached end-of-file
81
+ # can be rewound and reiterated.
82
+ def reset( *bind_params )
83
+ @driver.reset( @stmt.handle )
84
+ @stmt.bind_params *bind_params
85
+ @eof = false
86
+ commence
87
+ end
88
+
89
+ # Query whether the cursor has reached the end of the result set or not.
90
+ def eof?
91
+ @eof
92
+ end
93
+
94
+ # Obtain the next row from the cursor. If there are no more rows to be
95
+ # had, this will return +nil+. If type translation is active on the
96
+ # corresponding database, the values in the row will be translated
97
+ # according to their types.
98
+ #
99
+ # The returned value will be an array, unless Database#results_as_hash has
100
+ # been set to +true+, in which case the returned value will be a hash.
101
+ #
102
+ # For arrays, the column names are accessible via the +fields+ property,
103
+ # and the column types are accessible via the +types+ property.
104
+ #
105
+ # For hashes, the column names are the keys of the hash, and the column
106
+ # types are accessible via the +types+ property.
107
+ def next
108
+ return nil if @eof
109
+
110
+ unless @first_row
111
+ result = @driver.step( @stmt.handle )
112
+ check result
113
+ end
114
+
115
+ @first_row = false
116
+
117
+ unless @eof
118
+ row = []
119
+ @driver.data_count( @stmt.handle ).times do |column|
120
+ case @driver.column_type( @stmt.handle, column )
121
+ when Constants::ColumnType::NULL then
122
+ row << nil
123
+ when Constants::ColumnType::BLOB then
124
+ row << @driver.column_blob( @stmt.handle, column )
125
+ else
126
+ row << @driver.column_text( @stmt.handle, column )
127
+ end
128
+ end
129
+
130
+ if @db.type_translation
131
+ row = @stmt.types.zip( row ).map do |type, value|
132
+ @db.translator.translate( type, value )
133
+ end
134
+ end
135
+
136
+ if @db.results_as_hash
137
+ new_row = Hash[ *( @stmt.columns.zip( row ).flatten ) ]
138
+ row.each_with_index { |value,idx| new_row[idx] = value }
139
+ row = new_row
140
+ else
141
+ row.extend FieldsContainer unless row.respond_to?(:fields)
142
+ row.fields = @stmt.columns
143
+ end
144
+
145
+ row.extend TypesContainer
146
+ row.types = @stmt.types
147
+
148
+ return row
149
+ end
150
+
151
+ nil
152
+ end
153
+
154
+ # Required by the Enumerable mixin. Provides an internal iterator over the
155
+ # rows of the result set.
156
+ def each
157
+ while row=self.next
158
+ yield row
159
+ end
160
+ end
161
+
162
+ def types
163
+ @stmt.types
164
+ end
165
+
166
+ def columns
167
+ @stmt.columns
168
+ end
169
+
170
+ end
171
+
172
+ end