sqlite-ruby 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/faq/faq.html +28 -28
- data/ext/sqlite-api.c +1 -49
- data/lib/sqlite/statement.rb +34 -2
- data/lib/sqlite/version.rb +1 -1
- data/test/tc_database.rb +34 -0
- metadata +2 -2
data/doc/faq/faq.html
CHANGED
@@ -62,25 +62,25 @@
|
|
62
62
|
<ul>
|
63
63
|
<li>How do I do a database query?
|
64
64
|
<ul>
|
65
|
-
<li><a href='#
|
66
|
-
<li><a href='#
|
67
|
-
<li><a href='#
|
68
|
-
<li><a href='#
|
69
|
-
<li><a href='#
|
70
|
-
<li><a href='#
|
65
|
+
<li><a href='#538840882'>I just want an array of the rows…</a></li>
|
66
|
+
<li><a href='#538840832'>I’d like to use a block to iterate through the rows…</a></li>
|
67
|
+
<li><a href='#538840792'>I need to get the column names as well as the rows…</a></li>
|
68
|
+
<li><a href='#538840732'>I need the result set object itself…</a></li>
|
69
|
+
<li><a href='#538840692'>I just want the first row of the result set…</a></li>
|
70
|
+
<li><a href='#538840632'>I just want the first value of the first row of the result set…</a></li>
|
71
71
|
</ul>
|
72
72
|
</li>
|
73
|
-
<li><a href='#
|
74
|
-
<li><a href='#
|
75
|
-
<li><a href='#
|
76
|
-
<li><a href='#
|
77
|
-
<li><a href='#
|
78
|
-
<li><a href='#
|
79
|
-
<li><a href='#
|
80
|
-
<li><a href='#
|
73
|
+
<li><a href='#538840552'>How do I prepare a statement for repeated execution?</a></li>
|
74
|
+
<li><a href='#538840502'>How do I use placeholders in an <span class="caps">SQL</span> statement?</a></li>
|
75
|
+
<li><a href='#538840462'>How do I discover metadata about a query?</a></li>
|
76
|
+
<li><a href='#538840402'>I’d like the rows to be indexible by column name.</a></li>
|
77
|
+
<li><a href='#538840362'>I’d like the values from a query to be the correct types, instead of String.</a></li>
|
78
|
+
<li><a href='#538840302'>How do I do a <span class="caps">DDL </span>(insert, update, delete) statement?</a></li>
|
79
|
+
<li><a href='#538840262'>How do I execute multiple statements in a single string?</a></li>
|
80
|
+
<li><a href='#538840212'>How do I begin/end a transaction?</a></li>
|
81
81
|
</ul>
|
82
82
|
</div>
|
83
|
-
<a name='
|
83
|
+
<a name='538840882'></a>
|
84
84
|
<div class='faq-title'>How do I do a database query? I just want an array of the rows…</div>
|
85
85
|
<div class='faq-answer'><p>Use the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a> method. If you don’t give it a block, it will return an array of all the rows:</p>
|
86
86
|
|
@@ -90,7 +90,7 @@
|
|
90
90
|
db = SQLite::<a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database</a>.new( "test.db" )
|
91
91
|
rows = db.execute( "select * from test" )
|
92
92
|
</pre></div>
|
93
|
-
<a name='
|
93
|
+
<a name='538840832'></a>
|
94
94
|
<div class='faq-title'>How do I do a database query? I’d like to use a block to iterate through the rows…</div>
|
95
95
|
<div class='faq-answer'><p>Use the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a> method. If you give it a block, each row of the result will be yielded to the block:</p>
|
96
96
|
|
@@ -102,7 +102,7 @@
|
|
102
102
|
...
|
103
103
|
end
|
104
104
|
</pre></div>
|
105
|
-
<a name='
|
105
|
+
<a name='538840792'></a>
|
106
106
|
<div class='faq-title'>How do I do a database query? I need to get the column names as well as the rows…</div>
|
107
107
|
<div class='faq-answer'><p>Use the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute2</a> method. This works just like <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a>; if you don’t give it a block, it returns an array of rows; otherwise, it will yield each row to the block. <em>However</em>, the first row returned is always an array of the column names from the query:</p>
|
108
108
|
|
@@ -123,7 +123,7 @@
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
</pre></div>
|
126
|
-
<a name='
|
126
|
+
<a name='538840732'></a>
|
127
127
|
<div class='faq-title'>How do I do a database query? I need the result set object itself…</div>
|
128
128
|
<div class='faq-answer'><p>Sometimes you don’t want all the rows at once, and yet you’d like to be able to iterate through the results. For instance, you may want to pass the results to some other function (or series of functions) and have them pull rows from the results on demand. This is more effecient for very large queries.</p>
|
129
129
|
|
@@ -167,7 +167,7 @@
|
|
167
167
|
</pre>
|
168
168
|
|
169
169
|
<p>In general, <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#query</a> is not a very good choice for such operations…</p></div>
|
170
|
-
<a name='
|
170
|
+
<a name='538840692'></a>
|
171
171
|
<div class='faq-title'>How do I do a database query? I just want the first row of the result set…</div>
|
172
172
|
<div class='faq-answer'><p>Easy. Just call <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#get_first_row</a>:</p>
|
173
173
|
|
@@ -176,7 +176,7 @@
|
|
176
176
|
</pre>
|
177
177
|
|
178
178
|
<p>This also supports bind variables, just like <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a> and friends.</p></div>
|
179
|
-
<a name='
|
179
|
+
<a name='538840632'></a>
|
180
180
|
<div class='faq-title'>How do I do a database query? I just want the first value of the first row of the result set…</div>
|
181
181
|
<div class='faq-answer'><p>Also easy. Just call <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#get_first_value</a>:</p>
|
182
182
|
|
@@ -185,7 +185,7 @@
|
|
185
185
|
</pre>
|
186
186
|
|
187
187
|
<p>This also supports bind variables, just like <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a> and friends.</p></div>
|
188
|
-
<a name='
|
188
|
+
<a name='538840552'></a>
|
189
189
|
<div class='faq-title'>How do I prepare a statement for repeated execution?</div>
|
190
190
|
<div class='faq-answer'><p>If the same statement is going to be executed repeatedly, you can speed things up a bit by <em>preparing</em> the statement. You do this via the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#prepare</a> method. It returns a <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Statement.html'>Statement</a> object, and you can then invoke #execute on that to get the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/ResultSet.html'>ResultSet</a>:</p>
|
191
191
|
|
@@ -200,7 +200,7 @@
|
|
200
200
|
</pre>
|
201
201
|
|
202
202
|
<p>This is made more useful by the ability to bind variables to placeholders via the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Statement.html'>Statement#bind_param</a> and <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Statement.html'>Statement#bind_params</a> methods. (See the next <span class="caps">FAQ</span> for details.)</p></div>
|
203
|
-
<a name='
|
203
|
+
<a name='538840502'></a>
|
204
204
|
<div class='faq-title'>How do I use placeholders in an <span class="caps">SQL</span> statement?</div>
|
205
205
|
<div class='faq-answer'><p>Placeholders in an <span class="caps">SQL</span> statement take any of the following formats:</p>
|
206
206
|
|
@@ -258,7 +258,7 @@
|
|
258
258
|
|
259
259
|
stmt.bind_params( "value", "name" => "bob" )
|
260
260
|
</pre></div>
|
261
|
-
<a name='
|
261
|
+
<a name='538840462'></a>
|
262
262
|
<div class='faq-title'>How do I discover metadata about a query?</div>
|
263
263
|
<div class='faq-answer'><p>If you ever want to know the names or types of the columns in a result set, you can do it in several ways.</p>
|
264
264
|
|
@@ -287,7 +287,7 @@
|
|
287
287
|
p stmt.columns
|
288
288
|
p stmt.types
|
289
289
|
</pre></div>
|
290
|
-
<a name='
|
290
|
+
<a name='538840402'></a>
|
291
291
|
<div class='faq-title'>I’d like the rows to be indexible by column name.</div>
|
292
292
|
<div class='faq-answer'><p>By default, each row from a query is returned as an Array of values. This means that you can only obtain values by their index. Sometimes, however, you would like to obtain values by their column name.</p>
|
293
293
|
|
@@ -312,7 +312,7 @@
|
|
312
312
|
p row[1] == row['column2']
|
313
313
|
end
|
314
314
|
</pre></div>
|
315
|
-
<a name='
|
315
|
+
<a name='538840362'></a>
|
316
316
|
<div class='faq-title'>I’d like the values from a query to be the correct types, instead of String.</div>
|
317
317
|
<div class='faq-answer'><p>You can turn on “type translation” by setting <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#type_translation</a> to true:</p>
|
318
318
|
|
@@ -347,14 +347,14 @@
|
|
347
347
|
obj = db.get_first_value( "select thing from objects where name='bob'" )
|
348
348
|
p obj == h
|
349
349
|
</pre></div>
|
350
|
-
<a name='
|
350
|
+
<a name='538840302'></a>
|
351
351
|
<div class='faq-title'>How do I do a <span class="caps">DDL </span>(insert, update, delete) statement?</div>
|
352
352
|
<div class='faq-answer'><p>You can actually do inserts, updates, and deletes in exactly the same way as selects, but in general the <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a> method will be most convenient:</p>
|
353
353
|
|
354
354
|
<pre>
|
355
355
|
db.execute( "insert into table values ( ?, ? )", *bind_vars )
|
356
356
|
</pre></div>
|
357
|
-
<a name='
|
357
|
+
<a name='538840262'></a>
|
358
358
|
<div class='faq-title'>How do I execute multiple statements in a single string?</div>
|
359
359
|
<div class='faq-answer'><p>The standard query methods (<a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute</a>, <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute2</a>, <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#query</a>, and <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Statement.html'>Statement#execute</a>) will only execute the first statement in the string that is given to them. Thus, if you have a string with multiple <span class="caps">SQL</span> statements, each separated by a string, you can’t use those methods to execute them all at once.</p>
|
360
360
|
|
@@ -376,7 +376,7 @@
|
|
376
376
|
</pre>
|
377
377
|
|
378
378
|
<p>Unlike the other query methods, <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#execute_batch</a> accepts no block. It will also only ever return <ins>nil</ins>. Thus, it is really only suitable for batch processing of <span class="caps">DDL</span> statements.</p></div>
|
379
|
-
<a name='
|
379
|
+
<a name='538840212'></a>
|
380
380
|
<div class='faq-title'>How do I begin/end a transaction?</div>
|
381
381
|
<div class='faq-answer'><p>Use <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#transaction</a> to start a transaction. If you give it a block, the block will be automatically committed at the end of the block, unless an exception was raised, in which case the transaction will be rolled back. (Never explicitly call <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#commit</a> or <a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/Database.html'>Database#rollback</a> inside of a transaction block—you’ll get errors when the block terminates!)</p>
|
382
382
|
|
data/ext/sqlite-api.c
CHANGED
@@ -86,7 +86,7 @@ static ID idTypes;
|
|
86
86
|
static ID idCall;
|
87
87
|
|
88
88
|
static struct {
|
89
|
-
char *name;
|
89
|
+
const char *name;
|
90
90
|
VALUE object;
|
91
91
|
} g_sqlite_exceptions[] = {
|
92
92
|
{ "OK", 0 },
|
@@ -173,15 +173,9 @@ static_api_close( VALUE module, VALUE db );
|
|
173
173
|
static VALUE
|
174
174
|
static_api_compile( VALUE module, VALUE db, VALUE sql );
|
175
175
|
|
176
|
-
static VALUE
|
177
|
-
static_api_bind( VALUE module, VALUE vm, VALUE idx, VALUE value );
|
178
|
-
|
179
176
|
static VALUE
|
180
177
|
static_api_finalize( VALUE module, VALUE vm );
|
181
178
|
|
182
|
-
static VALUE
|
183
|
-
static_api_reset( VALUE module, VALUE vm );
|
184
|
-
|
185
179
|
static VALUE
|
186
180
|
static_api_last_insert_row_id( VALUE module, VALUE db );
|
187
181
|
|
@@ -200,12 +194,6 @@ static_api_busy_handler( VALUE module, VALUE db, VALUE handler );
|
|
200
194
|
static VALUE
|
201
195
|
static_api_busy_timeout( VALUE module, VALUE db, VALUE ms );
|
202
196
|
|
203
|
-
static VALUE
|
204
|
-
static_api_progress_handler( VALUE module, VALUE db, VALUE n, VALUE handler );
|
205
|
-
|
206
|
-
static VALUE
|
207
|
-
static_api_commit_hook( VALUE module, VALUE db, VALUE handler );
|
208
|
-
|
209
197
|
static VALUE
|
210
198
|
static_api_create_function( VALUE module, VALUE db, VALUE name, VALUE n,
|
211
199
|
VALUE proc );
|
@@ -251,12 +239,6 @@ static_free_vm( sqlite_vm *vm );
|
|
251
239
|
static int
|
252
240
|
static_busy_handler( void* cookie, const char *entity, int times );
|
253
241
|
|
254
|
-
static int
|
255
|
-
static_progress_handler( void* cookie );
|
256
|
-
|
257
|
-
static int
|
258
|
-
static_commit_hook( void* cookie );
|
259
|
-
|
260
242
|
static void
|
261
243
|
static_function_callback( sqlite_func *func, int argc, const char **argv );
|
262
244
|
|
@@ -1231,34 +1213,6 @@ static_busy_handler( void* cookie, const char *entity, int times )
|
|
1231
1213
|
return 1;
|
1232
1214
|
}
|
1233
1215
|
|
1234
|
-
static int
|
1235
|
-
static_progress_handler( void* cookie )
|
1236
|
-
{
|
1237
|
-
VALUE handler = (VALUE)cookie;
|
1238
|
-
VALUE result;
|
1239
|
-
|
1240
|
-
result = rb_funcall( handler, idCall, 0 );
|
1241
|
-
|
1242
|
-
if( result == Qnil || result == Qfalse )
|
1243
|
-
return 0;
|
1244
|
-
|
1245
|
-
return 1;
|
1246
|
-
}
|
1247
|
-
|
1248
|
-
static int
|
1249
|
-
static_commit_hook( void* cookie )
|
1250
|
-
{
|
1251
|
-
VALUE handler = (VALUE)cookie;
|
1252
|
-
VALUE result;
|
1253
|
-
|
1254
|
-
result = rb_funcall( handler, idCall, 0 );
|
1255
|
-
|
1256
|
-
if( result == Qnil || result == Qfalse )
|
1257
|
-
return 0;
|
1258
|
-
|
1259
|
-
return 1;
|
1260
|
-
}
|
1261
|
-
|
1262
1216
|
static VALUE
|
1263
1217
|
static_protected_function_callback( VALUE args )
|
1264
1218
|
{
|
@@ -1354,8 +1308,6 @@ NO_RDOC
|
|
1354
1308
|
*/
|
1355
1309
|
void Init_sqlite_api()
|
1356
1310
|
{
|
1357
|
-
VALUE version;
|
1358
|
-
|
1359
1311
|
idRow = rb_intern( "row" );
|
1360
1312
|
idColumns = rb_intern( "columns" );
|
1361
1313
|
idTypes = rb_intern( "types" );
|
data/lib/sqlite/statement.rb
CHANGED
@@ -89,6 +89,8 @@ module SQLite
|
|
89
89
|
# returned. In that case, it is the client's responsibility to close the
|
90
90
|
# ResultSet.
|
91
91
|
#
|
92
|
+
# Any parameters will be bound to the statement using #bind_params.
|
93
|
+
#
|
92
94
|
# Example:
|
93
95
|
#
|
94
96
|
# stmt = db.prepare( "select * from table" )
|
@@ -96,8 +98,9 @@ module SQLite
|
|
96
98
|
# ...
|
97
99
|
# end
|
98
100
|
#
|
99
|
-
# See also #bind_params
|
100
|
-
def execute
|
101
|
+
# See also #bind_params, #execute!.
|
102
|
+
def execute( *bind_vars )
|
103
|
+
bind_params *bind_vars unless bind_vars.empty?
|
101
104
|
results = ResultSet.new( @db, @statement.to_s )
|
102
105
|
|
103
106
|
if block_given?
|
@@ -111,6 +114,35 @@ module SQLite
|
|
111
114
|
end
|
112
115
|
end
|
113
116
|
|
117
|
+
# Execute the statement. If no block was given, this returns an array of
|
118
|
+
# rows returned by executing the statement. Otherwise, each row will be
|
119
|
+
# yielded to the block and then closed.
|
120
|
+
#
|
121
|
+
# Any parameters will be bound to the statement using #bind_params.
|
122
|
+
#
|
123
|
+
# Example:
|
124
|
+
#
|
125
|
+
# stmt = db.prepare( "select * from table" )
|
126
|
+
# stmt.execute! do |row|
|
127
|
+
# ...
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# See also #bind_params, #execute.
|
131
|
+
def execute!( *bind_vars )
|
132
|
+
result = execute( *bind_vars )
|
133
|
+
rows = [] unless block_given?
|
134
|
+
while row = result.next
|
135
|
+
if block_given?
|
136
|
+
yield row
|
137
|
+
else
|
138
|
+
rows << row
|
139
|
+
end
|
140
|
+
end
|
141
|
+
rows
|
142
|
+
ensure
|
143
|
+
result.close if result
|
144
|
+
end
|
145
|
+
|
114
146
|
# Return an array of the column names for this statement. Note that this
|
115
147
|
# may execute the statement in order to obtain the metadata; this makes it
|
116
148
|
# a (potentially) expensive operation.
|
data/lib/sqlite/version.rb
CHANGED
data/test/tc_database.rb
CHANGED
@@ -237,6 +237,40 @@ class TC_Database < Test::Unit::TestCase
|
|
237
237
|
end
|
238
238
|
end
|
239
239
|
|
240
|
+
def test_prepare_bind_execute
|
241
|
+
stmt = @db.prepare( "select * from A where age = ?" )
|
242
|
+
stmt.bind_params 1
|
243
|
+
stmt.execute do |result|
|
244
|
+
row = result.next
|
245
|
+
assert_equal [ "Zephyr", "1" ], row
|
246
|
+
assert_nil result.next
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_prepare_bind_execute!
|
251
|
+
stmt = @db.prepare( "select * from A where age = ?" )
|
252
|
+
stmt.bind_params 1
|
253
|
+
rows = stmt.execute!
|
254
|
+
assert_equal 1, rows.length
|
255
|
+
assert_equal [ "Zephyr", "1" ], rows.first
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_prepare_execute
|
259
|
+
stmt = @db.prepare( "select * from A where age = ?" )
|
260
|
+
stmt.execute( 1 ) do |result|
|
261
|
+
row = result.next
|
262
|
+
assert_equal [ "Zephyr", "1" ], row
|
263
|
+
assert_nil result.next
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_prepare_execute!
|
268
|
+
stmt = @db.prepare( "select * from A where age = ?" )
|
269
|
+
rows = stmt.execute!( 1 )
|
270
|
+
assert_equal 1, rows.length
|
271
|
+
assert_equal [ "Zephyr", "1" ], rows.first
|
272
|
+
end
|
273
|
+
|
240
274
|
def test_execute_batch
|
241
275
|
count = @db.get_first_value( "select count(*) from A" ).to_i
|
242
276
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.1
|
|
3
3
|
specification_version: 1
|
4
4
|
name: sqlite-ruby
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 2.
|
7
|
-
date: 2004-
|
6
|
+
version: 2.2.0
|
7
|
+
date: 2004-10-26
|
8
8
|
summary: SQLite/Ruby is a module to allow Ruby scripts to interface with a SQLite database.
|
9
9
|
require_paths:
|
10
10
|
- lib
|