rdbi-driver-sqlite3 0.9.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.
- 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
|