rdbi-driver-sqlite3 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +24 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +72 -0
- data/VERSION +1 -0
- data/lib/rdbi/driver/sqlite3.rb +274 -0
- data/rdbi-driver-sqlite3.gemspec +69 -0
- data/test/helper.rb +28 -0
- data/test/test_database.rb +295 -0
- metadata +165 -0
data/.document
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
coverage
|
18
|
+
rdoc
|
19
|
+
pkg
|
20
|
+
doc
|
21
|
+
.yardoc
|
22
|
+
rdbi-dbd-sqlite3.gemspec
|
23
|
+
|
24
|
+
## PROJECT::SPECIFIC
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Erik Hollensbe
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= SQLite3 driver for RDBI
|
2
|
+
|
3
|
+
Please see the documentation in RDBI::Driver::SQLite3.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Erik Hollensbe. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
version = (File.exist?('VERSION') ? File.read('VERSION') : "").chomp
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'jeweler'
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "rdbi-driver-sqlite3"
|
10
|
+
gem.summary = %Q{sqlite3 driver for RDBI}
|
11
|
+
gem.description = %Q{sqlite3 driver for RDBI}
|
12
|
+
gem.email = "erik@hollensbe.org"
|
13
|
+
gem.homepage = "http://github.com/RDBI/rdbi-driver-sqlite3"
|
14
|
+
gem.authors = ["Erik Hollensbe"]
|
15
|
+
|
16
|
+
gem.add_development_dependency 'test-unit'
|
17
|
+
gem.add_development_dependency 'rdoc'
|
18
|
+
|
19
|
+
gem.add_dependency 'rdbi'
|
20
|
+
gem.add_dependency 'sqlite3-ruby', '= 1.3.1'
|
21
|
+
gem.add_dependency 'methlab'
|
22
|
+
gem.add_dependency 'epoxy', '>= 0.3.1'
|
23
|
+
|
24
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
25
|
+
end
|
26
|
+
Jeweler::GemcutterTasks.new
|
27
|
+
rescue LoadError
|
28
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'rake/testtask'
|
32
|
+
Rake::TestTask.new(:test) do |test|
|
33
|
+
test.libs << 'lib' << 'test'
|
34
|
+
test.pattern = 'test/**/test_*.rb'
|
35
|
+
test.verbose = true
|
36
|
+
end
|
37
|
+
|
38
|
+
begin
|
39
|
+
require 'rcov/rcovtask'
|
40
|
+
Rcov::RcovTask.new do |test|
|
41
|
+
test.libs << 'test'
|
42
|
+
test.pattern = 'test/**/test_*.rb'
|
43
|
+
test.verbose = true
|
44
|
+
end
|
45
|
+
rescue LoadError
|
46
|
+
task :rcov do
|
47
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
task :test => :check_dependencies
|
52
|
+
|
53
|
+
task :default => :test
|
54
|
+
|
55
|
+
begin
|
56
|
+
require 'yard'
|
57
|
+
YARD::Rake::YardocTask.new do |yard|
|
58
|
+
yard.files = %w[lib/**/*.rb README*]
|
59
|
+
yard.options = %w[--protected --private ]
|
60
|
+
end
|
61
|
+
|
62
|
+
task :rdoc => [:yard]
|
63
|
+
task :clobber_rdoc => [:yard]
|
64
|
+
rescue LoadError => e
|
65
|
+
[:rdoc, :yard, :clobber_rdoc].each do |my_task|
|
66
|
+
task my_task do
|
67
|
+
abort "YARD is not available, which is needed to generate this documentation"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
task :install => [:test, :build]
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.9.0
|
@@ -0,0 +1,274 @@
|
|
1
|
+
require 'rdbi'
|
2
|
+
require 'epoxy'
|
3
|
+
require 'methlab'
|
4
|
+
|
5
|
+
gem 'sqlite3-ruby', '= 1.3.1'
|
6
|
+
require 'sqlite3'
|
7
|
+
|
8
|
+
class RDBI::Driver::SQLite3 < RDBI::Driver
|
9
|
+
def initialize(*args)
|
10
|
+
super(Database, *args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class RDBI::Driver::SQLite3 < RDBI::Driver
|
15
|
+
class Database < RDBI::Database
|
16
|
+
extend MethLab
|
17
|
+
|
18
|
+
attr_accessor :handle
|
19
|
+
|
20
|
+
def initialize(*args)
|
21
|
+
super
|
22
|
+
self.database_name = @connect_args[:database]
|
23
|
+
sqlite3_connect
|
24
|
+
@preprocess_quoter = proc do |x, named, indexed|
|
25
|
+
::SQLite3::Database.quote((named[x] || indexed[x]).to_s)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def reconnect
|
30
|
+
super
|
31
|
+
sqlite3_connect
|
32
|
+
end
|
33
|
+
|
34
|
+
def disconnect
|
35
|
+
super
|
36
|
+
@handle.close
|
37
|
+
end
|
38
|
+
|
39
|
+
def transaction(&block)
|
40
|
+
raise RDBI::TransactionError, "already in a transaction" if in_transaction?
|
41
|
+
@handle.transaction
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
def new_statement(query)
|
46
|
+
sth = Statement.new(query, self)
|
47
|
+
return sth
|
48
|
+
end
|
49
|
+
|
50
|
+
def schema
|
51
|
+
sch = { }
|
52
|
+
execute("SELECT name, type FROM sqlite_master WHERE type='table' or type='view'").fetch(:all).each do |row|
|
53
|
+
table_name_sym, table_name, table_type_sym = row[0].to_sym, row[0], row[1].to_sym
|
54
|
+
sch[table_name_sym] = table_schema(table_name, table_type_sym)
|
55
|
+
end
|
56
|
+
return sch
|
57
|
+
end
|
58
|
+
|
59
|
+
def table_schema(table_name, type = nil) # overloaded for performance
|
60
|
+
sch = RDBI::Schema.new([], [], type)
|
61
|
+
sch.tables << table_name.to_sym
|
62
|
+
|
63
|
+
unless sch.type
|
64
|
+
sch.type = execute("select type from sqlite_master where (type='table' or type='view') and name=?", table_name.to_s).fetch(:first)[0].to_sym rescue nil
|
65
|
+
return nil unless sch.type
|
66
|
+
end
|
67
|
+
|
68
|
+
@handle.table_info(table_name) do |hash|
|
69
|
+
col = RDBI::Column.new
|
70
|
+
col.name = hash['name'].to_sym
|
71
|
+
col.type = hash['type'].to_sym
|
72
|
+
col.ruby_type = hash['type'].to_sym
|
73
|
+
col.nullable = !(hash['notnull'] == "0")
|
74
|
+
sch.columns << col
|
75
|
+
end
|
76
|
+
|
77
|
+
return sch
|
78
|
+
end
|
79
|
+
|
80
|
+
inline(:ping) { 0 }
|
81
|
+
|
82
|
+
def rollback
|
83
|
+
raise RDBI::TransactionError, "not in a transaction during rollback" unless in_transaction?
|
84
|
+
@handle.rollback
|
85
|
+
super()
|
86
|
+
end
|
87
|
+
|
88
|
+
def commit
|
89
|
+
raise RDBI::TransactionError, "not in a transaction during commit" unless in_transaction?
|
90
|
+
@handle.commit
|
91
|
+
super()
|
92
|
+
end
|
93
|
+
|
94
|
+
protected
|
95
|
+
|
96
|
+
def sqlite3_connect
|
97
|
+
@handle = ::SQLite3::Database.new(database_name)
|
98
|
+
@handle.type_translation = false # XXX RDBI should handle this.
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
#
|
103
|
+
# Because SQLite3's ruby implementation does not support everything that our
|
104
|
+
# cursor implementation does, some methods, when called, will fetch the
|
105
|
+
# entire result set. In the instance this is done, the resulting array is
|
106
|
+
# used for all future operations.
|
107
|
+
#
|
108
|
+
class Cursor < RDBI::Cursor
|
109
|
+
def initialize(handle)
|
110
|
+
super(handle)
|
111
|
+
@index = 0
|
112
|
+
end
|
113
|
+
|
114
|
+
def fetch(count=1)
|
115
|
+
return [] if last_row?
|
116
|
+
a = []
|
117
|
+
count.times { a.push(next_row) }
|
118
|
+
return a
|
119
|
+
end
|
120
|
+
|
121
|
+
def next_row
|
122
|
+
val = if @array_handle
|
123
|
+
@array_handle[@index]
|
124
|
+
else
|
125
|
+
@handle.next
|
126
|
+
end
|
127
|
+
|
128
|
+
@index += 1
|
129
|
+
val
|
130
|
+
end
|
131
|
+
|
132
|
+
def result_count
|
133
|
+
coerce_to_array
|
134
|
+
@array_handle.size
|
135
|
+
end
|
136
|
+
|
137
|
+
def affected_count
|
138
|
+
# sqlite3-ruby does not support affected counts
|
139
|
+
0
|
140
|
+
end
|
141
|
+
|
142
|
+
def first
|
143
|
+
if @array_handle
|
144
|
+
@array_handle.first
|
145
|
+
else
|
146
|
+
@handle.first
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def last
|
151
|
+
coerce_to_array
|
152
|
+
@array_handle[-1]
|
153
|
+
end
|
154
|
+
|
155
|
+
def rest
|
156
|
+
coerce_to_array
|
157
|
+
oindex, @index = @index, @array_handle.size
|
158
|
+
@array_handle[oindex, @index]
|
159
|
+
end
|
160
|
+
|
161
|
+
def all
|
162
|
+
coerce_to_array
|
163
|
+
@array_handle.dup
|
164
|
+
end
|
165
|
+
|
166
|
+
def [](index)
|
167
|
+
coerce_to_array
|
168
|
+
@array_handle[index]
|
169
|
+
end
|
170
|
+
|
171
|
+
def last_row?
|
172
|
+
if @array_handle
|
173
|
+
@index == @array_handle.size
|
174
|
+
else
|
175
|
+
@handle.eof?
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def rewind
|
180
|
+
@index = 0
|
181
|
+
@handle.reset unless @handle.closed?
|
182
|
+
end
|
183
|
+
|
184
|
+
def empty?
|
185
|
+
coerce_to_array
|
186
|
+
@array_handle.empty?
|
187
|
+
end
|
188
|
+
|
189
|
+
def finish
|
190
|
+
@handle.close unless @handle.closed?
|
191
|
+
end
|
192
|
+
|
193
|
+
def coerce_to_array
|
194
|
+
unless @array_handle
|
195
|
+
@array_handle = @handle.to_a
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
class Statement < RDBI::Statement
|
201
|
+
extend MethLab
|
202
|
+
|
203
|
+
attr_accessor :handle
|
204
|
+
|
205
|
+
def initialize(query, dbh)
|
206
|
+
super
|
207
|
+
|
208
|
+
ep = Epoxy.new(query)
|
209
|
+
@index_map = ep.indexed_binds
|
210
|
+
|
211
|
+
# sanitizes the query of named binds so we can use SQLite3's native
|
212
|
+
# binder with our extended syntax. @index_map makes a reappearance in
|
213
|
+
# new_execution().
|
214
|
+
query = ep.quote(@index_map.compact.inject({}) { |x,y| x.merge({ y => nil }) }) { '?' }
|
215
|
+
|
216
|
+
@handle = check_exception { dbh.handle.prepare(query) }
|
217
|
+
@input_type_map = RDBI::Type.create_type_hash(RDBI::Type::In)
|
218
|
+
@output_type_map = RDBI::Type.create_type_hash(RDBI::Type::Out)
|
219
|
+
end
|
220
|
+
|
221
|
+
def new_execution(*binds)
|
222
|
+
|
223
|
+
# XXX is there a patron saint of being too clever? I don't like this
|
224
|
+
# code.
|
225
|
+
|
226
|
+
# FIXME move to RDBI::Util or something.
|
227
|
+
hashes, binds = binds.partition { |x| x.kind_of?(Hash) }
|
228
|
+
hash = hashes.inject({}) { |x, y| x.merge(y) }
|
229
|
+
hash.keys.each do |key|
|
230
|
+
if index = @index_map.index(key)
|
231
|
+
binds.insert(index, hash[key])
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# but this code is still ok.
|
236
|
+
|
237
|
+
rs = check_exception { @handle.execute(*binds) }
|
238
|
+
|
239
|
+
# FIXME type management
|
240
|
+
columns = rs.columns.zip(rs.types)
|
241
|
+
columns.collect! do |col|
|
242
|
+
newcol = RDBI::Column.new
|
243
|
+
newcol.name = col[0].to_sym
|
244
|
+
newcol.type = col[1]
|
245
|
+
newcol.ruby_type = (col[1].to_sym rescue nil)
|
246
|
+
newcol
|
247
|
+
end
|
248
|
+
|
249
|
+
this_schema = RDBI::Schema.new
|
250
|
+
this_schema.columns = columns
|
251
|
+
|
252
|
+
return Cursor.new(rs), this_schema, @output_type_map
|
253
|
+
end
|
254
|
+
|
255
|
+
def finish
|
256
|
+
@handle.close rescue nil
|
257
|
+
super
|
258
|
+
end
|
259
|
+
|
260
|
+
protected
|
261
|
+
|
262
|
+
def check_exception(&block)
|
263
|
+
begin
|
264
|
+
yield
|
265
|
+
rescue ArgumentError => e
|
266
|
+
if dbh.handle.closed?
|
267
|
+
raise RDBI::DisconnectedError, "database is disconnected"
|
268
|
+
else
|
269
|
+
raise e
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{rdbi-driver-sqlite3}
|
8
|
+
s.version = "0.9.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Erik Hollensbe"]
|
12
|
+
s.date = %q{2010-08-21}
|
13
|
+
s.description = %q{sqlite3 driver for RDBI}
|
14
|
+
s.email = %q{erik@hollensbe.org}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/rdbi/driver/sqlite3.rb",
|
27
|
+
"rdbi-driver-sqlite3.gemspec",
|
28
|
+
"test/helper.rb",
|
29
|
+
"test/test_database.rb"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/RDBI/rdbi-driver-sqlite3}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
35
|
+
s.summary = %q{sqlite3 driver for RDBI}
|
36
|
+
s.test_files = [
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/test_database.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<test-unit>, [">= 0"])
|
47
|
+
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
48
|
+
s.add_runtime_dependency(%q<rdbi>, [">= 0"])
|
49
|
+
s.add_runtime_dependency(%q<sqlite3-ruby>, ["= 1.3.1"])
|
50
|
+
s.add_runtime_dependency(%q<methlab>, [">= 0"])
|
51
|
+
s.add_runtime_dependency(%q<epoxy>, [">= 0.3.1"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<test-unit>, [">= 0"])
|
54
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
55
|
+
s.add_dependency(%q<rdbi>, [">= 0"])
|
56
|
+
s.add_dependency(%q<sqlite3-ruby>, ["= 1.3.1"])
|
57
|
+
s.add_dependency(%q<methlab>, [">= 0"])
|
58
|
+
s.add_dependency(%q<epoxy>, [">= 0.3.1"])
|
59
|
+
end
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<test-unit>, [">= 0"])
|
62
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rdbi>, [">= 0"])
|
64
|
+
s.add_dependency(%q<sqlite3-ruby>, ["= 1.3.1"])
|
65
|
+
s.add_dependency(%q<methlab>, [">= 0"])
|
66
|
+
s.add_dependency(%q<epoxy>, [">= 0.3.1"])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'test-unit'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
require 'rdbi'
|
9
|
+
require 'rdbi/driver/sqlite3'
|
10
|
+
|
11
|
+
class Test::Unit::TestCase
|
12
|
+
|
13
|
+
SQL = [
|
14
|
+
'create table foo (bar integer)',
|
15
|
+
'create table time_test (my_date timestamp)',
|
16
|
+
'create table multi_fields (foo integer, bar varchar)'
|
17
|
+
]
|
18
|
+
|
19
|
+
def new_database
|
20
|
+
RDBI.connect(:SQLite3, :database => ":memory:")
|
21
|
+
end
|
22
|
+
|
23
|
+
def init_database
|
24
|
+
dbh = new_database
|
25
|
+
SQL.each { |query| dbh.execute(query) }
|
26
|
+
return dbh
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,295 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDatabase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
attr_accessor :dbh
|
6
|
+
|
7
|
+
def teardown
|
8
|
+
@dbh.disconnect if (@dbh and @dbh.connected?)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_01_connect
|
12
|
+
self.dbh = new_database
|
13
|
+
assert(dbh)
|
14
|
+
assert_kind_of(RDBI::Driver::SQLite3::Database, dbh)
|
15
|
+
assert_kind_of(RDBI::Database, dbh)
|
16
|
+
assert_equal(dbh.database_name, ":memory:")
|
17
|
+
dbh.disconnect
|
18
|
+
assert(!dbh.connected?)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_02_ping
|
22
|
+
assert_equal(0, RDBI.ping(:SQLite3, :database => ":memory:"))
|
23
|
+
self.dbh = new_database
|
24
|
+
assert_equal(0, dbh.ping)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_03_execute
|
28
|
+
self.dbh = init_database
|
29
|
+
res = dbh.execute("insert into foo (bar) values (?)", 1)
|
30
|
+
assert(res)
|
31
|
+
assert_kind_of(RDBI::Result, res)
|
32
|
+
|
33
|
+
res = dbh.execute("select * from foo")
|
34
|
+
assert(res)
|
35
|
+
assert_kind_of(RDBI::Result, res)
|
36
|
+
assert_equal([[1]], res.fetch(:all))
|
37
|
+
|
38
|
+
rows = res.as(:Struct).fetch(:all)
|
39
|
+
row = rows[0]
|
40
|
+
assert_equal(1, row.bar)
|
41
|
+
|
42
|
+
res = dbh.execute("select * from foo where bar = ?bar", { :bar => 1 })
|
43
|
+
assert(res)
|
44
|
+
assert_equal([[1]], res.fetch(:all))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_04_prepare
|
48
|
+
self.dbh = init_database
|
49
|
+
|
50
|
+
sth = dbh.prepare("insert into foo (bar) values (?)")
|
51
|
+
assert(sth)
|
52
|
+
assert_kind_of(RDBI::Statement, sth)
|
53
|
+
assert_respond_to(sth, :execute)
|
54
|
+
|
55
|
+
5.times { sth.execute(1) }
|
56
|
+
|
57
|
+
assert_equal(dbh.last_statement.object_id, sth.object_id)
|
58
|
+
|
59
|
+
sth2 = dbh.prepare("select * from foo")
|
60
|
+
assert(sth)
|
61
|
+
assert_kind_of(RDBI::Statement, sth)
|
62
|
+
assert_respond_to(sth, :execute)
|
63
|
+
|
64
|
+
res = sth2.execute
|
65
|
+
assert(res)
|
66
|
+
assert_kind_of(RDBI::Result, res)
|
67
|
+
assert_equal([[1]] * 5, res.fetch(:all))
|
68
|
+
|
69
|
+
sth.execute(1)
|
70
|
+
|
71
|
+
res = sth2.execute
|
72
|
+
assert(res)
|
73
|
+
assert_kind_of(RDBI::Result, res)
|
74
|
+
assert_equal([[1]] * 6, res.fetch(:all))
|
75
|
+
|
76
|
+
sth.finish
|
77
|
+
sth2.finish
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_05_transaction
|
81
|
+
self.dbh = init_database
|
82
|
+
|
83
|
+
dbh.transaction do
|
84
|
+
assert(dbh.in_transaction?)
|
85
|
+
5.times { dbh.execute("insert into foo (bar) values (?)", 1) }
|
86
|
+
dbh.rollback
|
87
|
+
assert(!dbh.in_transaction?)
|
88
|
+
end
|
89
|
+
|
90
|
+
assert(!dbh.in_transaction?)
|
91
|
+
|
92
|
+
assert_equal([], dbh.execute("select * from foo").fetch(:all))
|
93
|
+
|
94
|
+
dbh.transaction do
|
95
|
+
assert(dbh.in_transaction?)
|
96
|
+
5.times { dbh.execute("insert into foo (bar) values (?)", 1) }
|
97
|
+
assert_equal([[1]] * 5, dbh.execute("select * from foo").fetch(:all))
|
98
|
+
dbh.commit
|
99
|
+
end
|
100
|
+
|
101
|
+
assert(!dbh.in_transaction?)
|
102
|
+
|
103
|
+
dbh.transaction do
|
104
|
+
assert_raises(RDBI::TransactionError.new("already in a transaction")) do
|
105
|
+
dbh.transaction
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
assert_raises(RDBI::TransactionError.new("not in a transaction during rollback")) do
|
110
|
+
dbh.rollback
|
111
|
+
end
|
112
|
+
|
113
|
+
assert_raises(RDBI::TransactionError.new("not in a transaction during commit")) do
|
114
|
+
dbh.commit
|
115
|
+
end
|
116
|
+
|
117
|
+
assert_equal([[1]] * 5, dbh.execute("select * from foo").fetch(:all))
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_06_preprocess_query
|
121
|
+
self.dbh = init_database
|
122
|
+
assert_equal(
|
123
|
+
"insert into foo (bar) values (1)",
|
124
|
+
dbh.preprocess_query("insert into foo (bar) values (?)", 1)
|
125
|
+
)
|
126
|
+
|
127
|
+
assert_equal(
|
128
|
+
"insert into foo (bar) values (1)",
|
129
|
+
dbh.preprocess_query("insert into foo (bar) values (?bar)", { :bar => 1 })
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_07_schema
|
134
|
+
self.dbh = init_database
|
135
|
+
|
136
|
+
dbh.execute("create table bar (foo varchar, bar integer)")
|
137
|
+
dbh.execute("insert into bar (foo, bar) values (?, ?)", "foo", 1)
|
138
|
+
res = dbh.execute("select * from bar")
|
139
|
+
|
140
|
+
assert(res)
|
141
|
+
assert(res.schema)
|
142
|
+
assert_kind_of(RDBI::Schema, res.schema)
|
143
|
+
assert(res.schema.columns)
|
144
|
+
res.schema.columns.each { |x| assert_kind_of(RDBI::Column, x) }
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_08_datetime
|
148
|
+
self.dbh = init_database
|
149
|
+
|
150
|
+
dt = DateTime.now
|
151
|
+
dbh.execute('insert into time_test (my_date) values (?)', dt)
|
152
|
+
dt2 = dbh.execute('select * from time_test limit 1').fetch(1)[0][0]
|
153
|
+
|
154
|
+
assert_kind_of(DateTime, dt2)
|
155
|
+
assert_equal(dt2.to_s, dt.to_s)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_09_basic_schema
|
159
|
+
self.dbh = init_database
|
160
|
+
assert_respond_to(dbh, :schema)
|
161
|
+
schema = dbh.schema
|
162
|
+
|
163
|
+
tables = [:foo, :time_test, :multi_fields]
|
164
|
+
columns = {
|
165
|
+
:foo => { :bar => :integer },
|
166
|
+
:time_test => { :my_date => :timestamp },
|
167
|
+
:multi_fields => { :foo => :integer, :bar => :varchar }
|
168
|
+
}
|
169
|
+
|
170
|
+
schema.each do |key, sch|
|
171
|
+
assert_kind_of(RDBI::Schema, sch)
|
172
|
+
assert_equal(key, sch.tables[0])
|
173
|
+
assert(tables.include?(sch.tables[0]))
|
174
|
+
assert(tables.include?(key))
|
175
|
+
assert_equal(:table, sch.type)
|
176
|
+
|
177
|
+
sch.columns.each do |col|
|
178
|
+
assert_kind_of(RDBI::Column, col)
|
179
|
+
assert_equal(columns[key][col.name], col.type)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_10_table_schema
|
185
|
+
self.dbh = init_database
|
186
|
+
assert_respond_to(dbh, :table_schema)
|
187
|
+
|
188
|
+
schema = dbh.table_schema( :foo )
|
189
|
+
columns = schema.columns
|
190
|
+
assert_equal columns.size, 1
|
191
|
+
c = columns[ 0 ]
|
192
|
+
assert_equal c.name, :bar
|
193
|
+
assert_equal c.type, :integer
|
194
|
+
|
195
|
+
schema = dbh.table_schema(:multi_fields)
|
196
|
+
columns = schema.columns
|
197
|
+
assert_equal columns.size, 2
|
198
|
+
columns.each do |c|
|
199
|
+
case c.name
|
200
|
+
when :foo
|
201
|
+
assert_equal :integer, c.type
|
202
|
+
when :bar
|
203
|
+
assert_equal :varchar, c.type
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
assert_nil dbh.table_schema(:non_existent)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_11_disconnection
|
211
|
+
self.dbh = init_database
|
212
|
+
sth = dbh.prepare("select 1")
|
213
|
+
sth.finish
|
214
|
+
dbh.disconnect
|
215
|
+
|
216
|
+
methods = {:schema => [], :execute => ["select 1"], :prepare => ["select 1"]}
|
217
|
+
methods.each do |meth, args|
|
218
|
+
assert_raises(RDBI::DisconnectedError.new("database is disconnected")) do
|
219
|
+
dbh.send(meth, *args)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
assert_raises(StandardError.new("you may not execute a finished handle")) do
|
224
|
+
sth.execute
|
225
|
+
end
|
226
|
+
sth.finish
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_12_multiple_fields
|
230
|
+
self.dbh = init_database
|
231
|
+
sth = dbh.prepare("insert into multi_fields (foo, bar) values (?, ?)")
|
232
|
+
sth.execute(1, "foo")
|
233
|
+
sth.execute(2, "bar")
|
234
|
+
sth.finish
|
235
|
+
|
236
|
+
sth = dbh.prepare("select foo, bar from multi_fields")
|
237
|
+
res = sth.execute
|
238
|
+
|
239
|
+
assert(res)
|
240
|
+
|
241
|
+
assert_equal(2, res.fetch(:all).length)
|
242
|
+
assert_equal(2, res.fetch(:all)[0].length)
|
243
|
+
|
244
|
+
assert_equal([1, "foo"], res.fetch(1)[0])
|
245
|
+
assert_equal([2, "bar"], res.fetch(1)[0])
|
246
|
+
sth.finish
|
247
|
+
|
248
|
+
res = dbh.execute("select foo, bar from multi_fields where foo = ? and bar = ?bar", 1, { :bar => "foo" })
|
249
|
+
assert(res)
|
250
|
+
assert_equal([[1, "foo"]], res.fetch(:all))
|
251
|
+
|
252
|
+
res = dbh.execute("select foo, bar from multi_fields where foo = ? and bar = ?bar", { :bar => "foo" }, 1)
|
253
|
+
assert(res)
|
254
|
+
assert_equal([[1, "foo"]], res.fetch(:all))
|
255
|
+
|
256
|
+
res = dbh.execute("select foo, bar from multi_fields where foo = ?foo and bar = ?bar", { :foo => 1, :bar => "foo" })
|
257
|
+
assert(res)
|
258
|
+
assert_equal([[1, "foo"]], res.fetch(:all))
|
259
|
+
|
260
|
+
res = dbh.execute("select foo, bar from multi_fields where foo = ?foo and bar = ?", { :foo => 1 }, "foo")
|
261
|
+
assert(res)
|
262
|
+
assert_equal([[1, "foo"]], res.fetch(:all))
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_13_reconnection
|
266
|
+
self.dbh = init_database
|
267
|
+
|
268
|
+
assert_nothing_raised do
|
269
|
+
dbh.reconnect
|
270
|
+
dbh.disconnect
|
271
|
+
dbh.reconnect
|
272
|
+
end
|
273
|
+
|
274
|
+
sth = dbh.prepare("select 1")
|
275
|
+
$stderr.puts "You should see the next warning exactly once"
|
276
|
+
dbh.reconnect
|
277
|
+
dbh.disconnect
|
278
|
+
dbh.reconnect
|
279
|
+
end
|
280
|
+
|
281
|
+
def test_14_aggregates
|
282
|
+
self.dbh = init_database
|
283
|
+
|
284
|
+
res = dbh.execute("select count(*) from multi_fields")
|
285
|
+
assert_equal([0], res.fetch(:first))
|
286
|
+
|
287
|
+
sth = dbh.prepare("insert into multi_fields (foo, bar) values (?, ?)")
|
288
|
+
sth.execute(1, "foo")
|
289
|
+
sth.execute(2, "bar")
|
290
|
+
sth.finish
|
291
|
+
|
292
|
+
res = dbh.execute("select count(*) from multi_fields")
|
293
|
+
assert_equal([2], res.fetch(:first))
|
294
|
+
end
|
295
|
+
end
|
metadata
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdbi-driver-sqlite3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 59
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 9
|
9
|
+
- 0
|
10
|
+
version: 0.9.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Erik Hollensbe
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-21 00:00:00 -04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: test-unit
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rdoc
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rdbi
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :runtime
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: sqlite3-ruby
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - "="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 25
|
72
|
+
segments:
|
73
|
+
- 1
|
74
|
+
- 3
|
75
|
+
- 1
|
76
|
+
version: 1.3.1
|
77
|
+
type: :runtime
|
78
|
+
version_requirements: *id004
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
name: methlab
|
81
|
+
prerelease: false
|
82
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
type: :runtime
|
92
|
+
version_requirements: *id005
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: epoxy
|
95
|
+
prerelease: false
|
96
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
hash: 17
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
- 3
|
105
|
+
- 1
|
106
|
+
version: 0.3.1
|
107
|
+
type: :runtime
|
108
|
+
version_requirements: *id006
|
109
|
+
description: sqlite3 driver for RDBI
|
110
|
+
email: erik@hollensbe.org
|
111
|
+
executables: []
|
112
|
+
|
113
|
+
extensions: []
|
114
|
+
|
115
|
+
extra_rdoc_files:
|
116
|
+
- LICENSE
|
117
|
+
- README.rdoc
|
118
|
+
files:
|
119
|
+
- .document
|
120
|
+
- .gitignore
|
121
|
+
- LICENSE
|
122
|
+
- README.rdoc
|
123
|
+
- Rakefile
|
124
|
+
- VERSION
|
125
|
+
- lib/rdbi/driver/sqlite3.rb
|
126
|
+
- rdbi-driver-sqlite3.gemspec
|
127
|
+
- test/helper.rb
|
128
|
+
- test/test_database.rb
|
129
|
+
has_rdoc: true
|
130
|
+
homepage: http://github.com/RDBI/rdbi-driver-sqlite3
|
131
|
+
licenses: []
|
132
|
+
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options:
|
135
|
+
- --charset=UTF-8
|
136
|
+
require_paths:
|
137
|
+
- lib
|
138
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
hash: 3
|
144
|
+
segments:
|
145
|
+
- 0
|
146
|
+
version: "0"
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
none: false
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
hash: 3
|
153
|
+
segments:
|
154
|
+
- 0
|
155
|
+
version: "0"
|
156
|
+
requirements: []
|
157
|
+
|
158
|
+
rubyforge_project:
|
159
|
+
rubygems_version: 1.3.7
|
160
|
+
signing_key:
|
161
|
+
specification_version: 3
|
162
|
+
summary: sqlite3 driver for RDBI
|
163
|
+
test_files:
|
164
|
+
- test/helper.rb
|
165
|
+
- test/test_database.rb
|