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

@@ -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