sqlite3-ruby 1.2.5-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/ChangeLog.cvs +88 -0
  2. data/History.txt +68 -0
  3. data/LICENSE +27 -0
  4. data/Manifest.txt +41 -0
  5. data/README.txt +56 -0
  6. data/Rakefile +5 -0
  7. data/ext/sqlite3_api/extconf.rb +10 -0
  8. data/ext/sqlite3_api/sqlite3_api.i +362 -0
  9. data/ext/sqlite3_api/sqlite3_api_wrap.c +5018 -0
  10. data/faq/faq.rb +145 -0
  11. data/faq/faq.yml +426 -0
  12. data/lib/1.8/sqlite3_api.so +0 -0
  13. data/lib/1.9/sqlite3_api.so +0 -0
  14. data/lib/sqlite3.rb +1 -0
  15. data/lib/sqlite3/constants.rb +49 -0
  16. data/lib/sqlite3/database.rb +721 -0
  17. data/lib/sqlite3/driver/dl/api.rb +152 -0
  18. data/lib/sqlite3/driver/dl/driver.rb +307 -0
  19. data/lib/sqlite3/driver/native/driver.rb +219 -0
  20. data/lib/sqlite3/errors.rb +68 -0
  21. data/lib/sqlite3/pragmas.rb +271 -0
  22. data/lib/sqlite3/resultset.rb +180 -0
  23. data/lib/sqlite3/statement.rb +231 -0
  24. data/lib/sqlite3/translator.rb +109 -0
  25. data/lib/sqlite3/value.rb +57 -0
  26. data/lib/sqlite3/version.rb +16 -0
  27. data/setup.rb +1333 -0
  28. data/tasks/benchmark.rake +9 -0
  29. data/tasks/faq.rake +9 -0
  30. data/tasks/gem.rake +32 -0
  31. data/tasks/native.rake +35 -0
  32. data/tasks/vendor_sqlite3.rake +104 -0
  33. data/test/bm.rb +140 -0
  34. data/test/driver/dl/tc_driver.rb +292 -0
  35. data/test/helper.rb +67 -0
  36. data/test/native-vs-dl.rb +126 -0
  37. data/test/test_database.rb +217 -0
  38. data/test/test_errors.rb +17 -0
  39. data/test/test_integration.rb +542 -0
  40. data/test/test_integration_open_close.rb +30 -0
  41. data/test/test_integration_pending.rb +111 -0
  42. data/test/test_integration_resultset.rb +159 -0
  43. data/test/test_integration_statement.rb +195 -0
  44. metadata +143 -0
@@ -0,0 +1,145 @@
1
+ require 'yaml'
2
+ require 'redcloth'
3
+
4
+ def process_faq_list( faqs )
5
+ puts "<ul>"
6
+ faqs.each do |faq|
7
+ process_faq_list_item faq
8
+ end
9
+ puts "</ul>"
10
+ end
11
+
12
+ def process_faq_list_item( faq )
13
+ question = faq.keys.first
14
+ answer = faq.values.first
15
+
16
+ print "<li>"
17
+
18
+ question_text = RedCloth.new(question).to_html.gsub( %r{</?p>},"" )
19
+ if answer.is_a?( Array )
20
+ puts question_text
21
+ process_faq_list answer
22
+ else
23
+ print "<a href='##{question.object_id}'>#{question_text}</a>"
24
+ end
25
+
26
+ puts "</li>"
27
+ end
28
+
29
+ def process_faq_descriptions( faqs, path=nil )
30
+ faqs.each do |faq|
31
+ process_faq_description faq, path
32
+ end
33
+ end
34
+
35
+ def process_faq_description( faq, path )
36
+ question = faq.keys.first
37
+ path = ( path ? path + " " : "" ) + question
38
+ answer = faq.values.first
39
+
40
+ if answer.is_a?( Array )
41
+ process_faq_descriptions( answer, path )
42
+ else
43
+ title = RedCloth.new( path ).to_html.gsub( %r{</?p>}, "" )
44
+ answer = RedCloth.new( answer || "" )
45
+
46
+ puts "<a name='#{question.object_id}'></a>"
47
+ puts "<div class='faq-title'>#{title}</div>"
48
+ puts "<div class='faq-answer'>#{add_api_links(answer.to_html)}</div>"
49
+ end
50
+ end
51
+
52
+ API_OBJECTS = [ "Database", "Statement", "ResultSet",
53
+ "ParsedStatement", "Pragmas", "Translator" ].inject( "(" ) { |acc,name|
54
+ acc << "|" if acc.length > 1
55
+ acc << name
56
+ acc
57
+ } + ")"
58
+
59
+ def add_api_links( text )
60
+ text.gsub( /#{API_OBJECTS}(#(\w+))?/ ) do
61
+ disp_obj = obj = $1
62
+
63
+ case obj
64
+ when "Pragmas"; disp_obj = "Database"
65
+ end
66
+
67
+ method = $3
68
+ s = "<a href='http://sqlite-ruby.rubyforge.org/classes/SQLite/#{obj}.html'>#{disp_obj}"
69
+ s << "##{method}" if method
70
+ s << "</a>"
71
+ s
72
+ end
73
+ end
74
+
75
+ faqs = YAML.load( File.read( "faq.yml" ) )
76
+
77
+ puts <<-EOF
78
+ <html>
79
+ <head>
80
+ <title>SQLite3/Ruby FAQ</title>
81
+ <style type="text/css">
82
+ a, a:visited, a:active {
83
+ color: #00F;
84
+ text-decoration: none;
85
+ }
86
+
87
+ a:hover {
88
+ text-decoration: underline;
89
+ }
90
+
91
+ .faq-list {
92
+ color: #000;
93
+ font-family: vera-sans, verdana, arial, sans-serif;
94
+ }
95
+
96
+ .faq-title {
97
+ background: #007;
98
+ color: #FFF;
99
+ font-family: vera-sans, verdana, arial, sans-serif;
100
+ padding-left: 1em;
101
+ padding-top: 0.5em;
102
+ padding-bottom: 0.5em;
103
+ font-weight: bold;
104
+ font-size: large;
105
+ border: 1px solid #000;
106
+ }
107
+
108
+ .faq-answer {
109
+ margin-left: 1em;
110
+ color: #000;
111
+ font-family: vera-sans, verdana, arial, sans-serif;
112
+ }
113
+
114
+ .faq-answer pre {
115
+ margin-left: 1em;
116
+ color: #000;
117
+ background: #FFE;
118
+ font-size: normal;
119
+ border: 1px dotted #CCC;
120
+ padding: 1em;
121
+ }
122
+
123
+ h1 {
124
+ background: #005;
125
+ color: #FFF;
126
+ font-family: vera-sans, verdana, arial, sans-serif;
127
+ padding-left: 1em;
128
+ padding-top: 1em;
129
+ padding-bottom: 1em;
130
+ font-weight: bold;
131
+ font-size: x-large;
132
+ border: 1px solid #00F;
133
+ }
134
+ </style>
135
+ </head>
136
+ <body>
137
+ <h1>SQLite/Ruby FAQ</h1>
138
+ <div class="faq-list">
139
+ EOF
140
+
141
+ process_faq_list( faqs )
142
+ puts "</div>"
143
+ process_faq_descriptions( faqs )
144
+
145
+ puts "</body></html>"
@@ -0,0 +1,426 @@
1
+ ---
2
+ - "How do I do a database query?":
3
+ - "I just want an array of the rows...": >-
4
+
5
+ Use the Database#execute method. If you don't give it a block, it will
6
+ return an array of all the rows:
7
+
8
+
9
+ <pre>
10
+ require 'sqlite3'
11
+
12
+ db = SQLite3::Database.new( "test.db" )
13
+ rows = db.execute( "select * from test" )
14
+ </pre>
15
+
16
+ - "I'd like to use a block to iterate through the rows...": >-
17
+
18
+ Use the Database#execute method. If you give it a block, each row of the
19
+ result will be yielded to the block:
20
+
21
+
22
+ <pre>
23
+ require 'sqlite3'
24
+
25
+ db = SQLite3::Database.new( "test.db" )
26
+ db.execute( "select * from test" ) do |row|
27
+ ...
28
+ end
29
+ </pre>
30
+
31
+ - "I need to get the column names as well as the rows...": >-
32
+
33
+ Use the Database#execute2 method. This works just like Database#execute;
34
+ if you don't give it a block, it returns an array of rows; otherwise, it
35
+ will yield each row to the block. _However_, the first row returned is
36
+ always an array of the column names from the query:
37
+
38
+
39
+ <pre>
40
+ require 'sqlite3'
41
+
42
+ db = SQLite3::Database.new( "test.db" )
43
+ columns, *rows = db.execute2( "select * from test" )
44
+
45
+ # or use a block:
46
+
47
+ columns = nil
48
+ db.execute2( "select * from test" ) do |row|
49
+ if columns.nil?
50
+ columns = row
51
+ else
52
+ # process row
53
+ end
54
+ end
55
+ </pre>
56
+
57
+ - "I just want the first row of the result set...": >-
58
+
59
+ Easy. Just call Database#get_first_row:
60
+
61
+
62
+ <pre>
63
+ row = db.get_first_row( "select * from table" )
64
+ </pre>
65
+
66
+
67
+ This also supports bind variables, just like Database#execute
68
+ and friends.
69
+
70
+ - "I just want the first value of the first row of the result set...": >-
71
+
72
+ Also easy. Just call Database#get_first_value:
73
+
74
+
75
+ <pre>
76
+ count = db.get_first_value( "select count(*) from table" )
77
+ </pre>
78
+
79
+
80
+ This also supports bind variables, just like Database#execute
81
+ and friends.
82
+
83
+ - "How do I prepare a statement for repeated execution?": >-
84
+ If the same statement is going to be executed repeatedly, you can speed
85
+ things up a bit by _preparing_ the statement. You do this via the
86
+ Database#prepare method. It returns a Statement object, and you can
87
+ then invoke #execute on that to get the ResultSet:
88
+
89
+
90
+ <pre>
91
+ stmt = db.prepare( "select * from person" )
92
+
93
+ 1000.times do
94
+ stmt.execute do |result|
95
+ ...
96
+ end
97
+ end
98
+
99
+ stmt.close
100
+
101
+ # or, use a block
102
+
103
+ db.prepare( "select * from person" ) do |stmt|
104
+ 1000.times do
105
+ stmt.execute do |result|
106
+ ...
107
+ end
108
+ end
109
+ end
110
+ </pre>
111
+
112
+
113
+ This is made more useful by the ability to bind variables to placeholders
114
+ via the Statement#bind_param and Statement#bind_params methods. (See the
115
+ next FAQ for details.)
116
+
117
+ - "How do I use placeholders in an SQL statement?": >-
118
+ Placeholders in an SQL statement take any of the following formats:
119
+
120
+
121
+ * @?@
122
+
123
+ * @?_nnn_@
124
+
125
+ * @:_word_@
126
+
127
+
128
+ Where _n_ is an integer, and _word_ is an alpha-numeric identifier (or
129
+ number). When the placeholder is associated with a number, that number
130
+ identifies the index of the bind variable to replace it with. When it
131
+ is an identifier, it identifies the name of the correponding bind
132
+ variable. (In the instance of the first format--a single question
133
+ mark--the placeholder is assigned a number one greater than the last
134
+ index used, or 1 if it is the first.)
135
+
136
+
137
+ For example, here is a query using these placeholder formats:
138
+
139
+
140
+ <pre>
141
+ select *
142
+ from table
143
+ where ( c = ?2 or c = ? )
144
+ and d = :name
145
+ and e = :1
146
+ </pre>
147
+
148
+
149
+ This defines 5 different placeholders: 1, 2, 3, and "name".
150
+
151
+
152
+ You replace these placeholders by _binding_ them to values. This can be
153
+ accomplished in a variety of ways.
154
+
155
+
156
+ The Database#execute, and Database#execute2 methods all accept additional
157
+ arguments following the SQL statement. These arguments are assumed to be
158
+ bind parameters, and they are bound (positionally) to their corresponding
159
+ placeholders:
160
+
161
+
162
+ <pre>
163
+ db.execute( "select * from table where a = ? and b = ?",
164
+ "hello",
165
+ "world" )
166
+ </pre>
167
+
168
+
169
+ The above would replace the first question mark with 'hello' and the
170
+ second with 'world'. If the placeholders have an explicit index given, they
171
+ will be replaced with the bind parameter at that index (1-based).
172
+
173
+
174
+ If a Hash is given as a bind parameter, then its key/value pairs are bound
175
+ to the placeholders. This is how you bind by name:
176
+
177
+
178
+ <pre>
179
+ db.execute( "select * from table where a = :name and b = :value",
180
+ "name" => "bob",
181
+ "value" => "priceless" )
182
+ </pre>
183
+
184
+
185
+ You can also bind explicitly using the Statement object itself. Just pass
186
+ additional parameters to the Statement#execute statement:
187
+
188
+
189
+ <pre>
190
+ db.prepare( "select * from table where a = :name and b = ?" ) do |stmt|
191
+ stmt.execute "value", "name" => "bob"
192
+ end
193
+ </pre>
194
+
195
+
196
+ Or do a Database#prepare to get the Statement, and then use either
197
+ Statement#bind_param or Statement#bind_params:
198
+
199
+
200
+ <pre>
201
+ stmt = db.prepare( "select * from table where a = :name and b = ?" )
202
+
203
+ stmt.bind_param( "name", "bob" )
204
+ stmt.bind_param( 1, "value" )
205
+
206
+ # or
207
+
208
+ stmt.bind_params( "value", "name" => "bob" )
209
+ </pre>
210
+
211
+ - "How do I discover metadata about a query?": >-
212
+
213
+ If you ever want to know the names or types of the columns in a result
214
+ set, you can do it in several ways.
215
+
216
+
217
+ The first way is to ask the row object itself. Each row will have a
218
+ property "fields" that returns an array of the column names. The row
219
+ will also have a property "types" that returns an array of the column
220
+ types:
221
+
222
+
223
+ <pre>
224
+ rows = db.execute( "select * from table" )
225
+ p rows[0].fields
226
+ p rows[0].types
227
+ </pre>
228
+
229
+
230
+ Obviously, this approach requires you to execute a statement that actually
231
+ returns data. If you don't know if the statement will return any rows, but
232
+ you still need the metadata, you can use Database#query and ask the
233
+ ResultSet object itself:
234
+
235
+
236
+ <pre>
237
+ db.query( "select * from table" ) do |result|
238
+ p result.columns
239
+ p result.types
240
+ ...
241
+ end
242
+ </pre>
243
+
244
+
245
+ Lastly, you can use Database#prepare and ask the Statement object what
246
+ the metadata are:
247
+
248
+
249
+ <pre>
250
+ stmt = db.prepare( "select * from table" )
251
+ p stmt.columns
252
+ p stmt.types
253
+ </pre>
254
+
255
+ - "I'd like the rows to be indexible by column name.": >-
256
+ By default, each row from a query is returned as an Array of values. This
257
+ means that you can only obtain values by their index. Sometimes, however,
258
+ you would like to obtain values by their column name.
259
+
260
+
261
+ The first way to do this is to set the Database property "results_as_hash"
262
+ to true. If you do this, then all rows will be returned as Hash objects,
263
+ with the column names as the keys. (In this case, the "fields" property
264
+ is unavailable on the row, although the "types" property remains.)
265
+
266
+
267
+ <pre>
268
+ db.results_as_hash = true
269
+ db.execute( "select * from table" ) do |row|
270
+ p row['column1']
271
+ p row['column2']
272
+ end
273
+ </pre>
274
+
275
+
276
+ The other way is to use Ara Howard's
277
+ "ArrayFields":http://rubyforge.org/projects/arrayfields
278
+ module. Just require "arrayfields", and all of your rows will be indexable
279
+ by column name, even though they are still arrays!
280
+
281
+
282
+ <pre>
283
+ require 'arrayfields'
284
+
285
+ ...
286
+ db.execute( "select * from table" ) do |row|
287
+ p row[0] == row['column1']
288
+ p row[1] == row['column2']
289
+ end
290
+ </pre>
291
+
292
+ - "I'd like the values from a query to be the correct types, instead of String.": >-
293
+ You can turn on "type translation" by setting Database#type_translation to
294
+ true:
295
+
296
+
297
+ <pre>
298
+ db.type_translation = true
299
+ db.execute( "select * from table" ) do |row|
300
+ p row
301
+ end
302
+ </pre>
303
+
304
+
305
+ By doing this, each return value for each row will be translated to its
306
+ correct type, based on its declared column type.
307
+
308
+
309
+ You can even declare your own translation routines, if (for example) you are
310
+ using an SQL type that is not handled by default:
311
+
312
+
313
+ <pre>
314
+ # assume "objects" table has the following schema:
315
+ # create table objects (
316
+ # name varchar2(20),
317
+ # thing object
318
+ # )
319
+
320
+ db.type_translation = true
321
+ db.translator.add_translator( "object" ) do |type, value|
322
+ db.decode( value )
323
+ end
324
+
325
+ h = { :one=>:two, "three"=>"four", 5=>6 }
326
+ dump = db.encode( h )
327
+
328
+ db.execute( "insert into objects values ( ?, ? )", "bob", dump )
329
+
330
+ obj = db.get_first_value( "select thing from objects where name='bob'" )
331
+ p obj == h
332
+ </pre>
333
+
334
+ - "How do insert binary data into the database?": >-
335
+ Use blobs. Blobs are new features of SQLite3. You have to use bind
336
+ variables to make it work:
337
+
338
+
339
+ <pre>
340
+ db.execute( "insert into foo ( ?, ? )",
341
+ SQLite3::Blob.new( "\0\1\2\3\4\5" ),
342
+ SQLite3::Blob.new( "a\0b\0c\0d ) )
343
+ </pre>
344
+
345
+
346
+ The blob values must be indicated explicitly by binding each parameter to
347
+ a value of type SQLite3::Blob.
348
+
349
+ - "How do I do a DDL (insert, update, delete) statement?": >-
350
+ You can actually do inserts, updates, and deletes in exactly the same way
351
+ as selects, but in general the Database#execute method will be most
352
+ convenient:
353
+
354
+
355
+ <pre>
356
+ db.execute( "insert into table values ( ?, ? )", *bind_vars )
357
+ </pre>
358
+
359
+ - "How do I execute multiple statements in a single string?": >-
360
+ The standard query methods (Database#execute, Database#execute2,
361
+ Database#query, and Statement#execute) will only execute the first
362
+ statement in the string that is given to them. Thus, if you have a
363
+ string with multiple SQL statements, each separated by a string,
364
+ you can't use those methods to execute them all at once.
365
+
366
+
367
+ Instead, use Database#execute_batch:
368
+
369
+
370
+ <pre>
371
+ sql = <<SQL
372
+ create table the_table (
373
+ a varchar2(30),
374
+ b varchar2(30)
375
+ );
376
+
377
+ insert into the_table values ( 'one', 'two' );
378
+ insert into the_table values ( 'three', 'four' );
379
+ insert into the_table values ( 'five', 'six' );
380
+ SQL
381
+
382
+ db.execute_batch( sql )
383
+ </pre>
384
+
385
+
386
+ Unlike the other query methods, Database#execute_batch accepts no
387
+ block. It will also only ever return +nil+. Thus, it is really only
388
+ suitable for batch processing of DDL statements.
389
+
390
+ - "How do I begin/end a transaction?":
391
+ Use Database#transaction to start a transaction. If you give it a block,
392
+ the block will be automatically committed at the end of the block,
393
+ unless an exception was raised, in which case the transaction will be
394
+ rolled back. (Never explicitly call Database#commit or Database#rollback
395
+ inside of a transaction block--you'll get errors when the block
396
+ terminates!)
397
+
398
+
399
+ <pre>
400
+ database.transaction do |db|
401
+ db.execute( "insert into table values ( 'a', 'b', 'c' )" )
402
+ ...
403
+ end
404
+ </pre>
405
+
406
+
407
+ Alternatively, if you don't give a block to Database#transaction, the
408
+ transaction remains open until you explicitly call Database#commit or
409
+ Database#rollback.
410
+
411
+
412
+ <pre>
413
+ db.transaction
414
+ db.execute( "insert into table values ( 'a', 'b', 'c' )" )
415
+ db.commit
416
+ </pre>
417
+
418
+
419
+ Note that SQLite does not allow nested transactions, so you'll get errors
420
+ if you try to open a new transaction while one is already active. Use
421
+ Database#transaction_active? to determine whether a transaction is
422
+ active or not.
423
+
424
+ #- "How do I discover metadata about a table/index?":
425
+ #
426
+ #- "How do I do tweak database settings?":