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 ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
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