rdo-sqlite 0.0.1
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/.gitignore +19 -0
- data/.rspec +1 -0
- data/Gemfile +9 -0
- data/LICENSE +22 -0
- data/README.md +89 -0
- data/Rakefile +14 -0
- data/ext/rdo_sqlite/driver.c +99 -0
- data/ext/rdo_sqlite/driver.h +18 -0
- data/ext/rdo_sqlite/extconf.rb +23 -0
- data/ext/rdo_sqlite/macros.h +193 -0
- data/ext/rdo_sqlite/rdo_sqlite.c +15 -0
- data/ext/rdo_sqlite/statements.c +269 -0
- data/ext/rdo_sqlite/statements.h +15 -0
- data/lib/rdo/sqlite/driver.rb +23 -0
- data/lib/rdo/sqlite/version.rb +12 -0
- data/lib/rdo/sqlite.rb +16 -0
- data/lib/rdo-sqlite.rb +1 -0
- data/rdo-sqlite.gemspec +23 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/sqlite/bind_params_spec.rb +316 -0
- data/spec/sqlite/driver_spec.rb +279 -0
- data/spec/sqlite/type_cast_spec.rb +48 -0
- metadata +121 -0
@@ -0,0 +1,279 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
describe RDO::SQLite::Driver do
|
5
|
+
let(:options) { connection_uri }
|
6
|
+
let(:db) { RDO.open(options) }
|
7
|
+
|
8
|
+
after(:each) { db.close rescue nil }
|
9
|
+
|
10
|
+
describe "#initialize" do
|
11
|
+
context "with a relative path to a database" do
|
12
|
+
let(:path) { "./tmp/test.db" }
|
13
|
+
let(:options) { "sqlite:#{path}" }
|
14
|
+
|
15
|
+
before(:each) { File.delete(path) if File.exist?(path) }
|
16
|
+
after(:each) { File.delete(path) if File.exist?(path) }
|
17
|
+
|
18
|
+
it "opens a database file" do
|
19
|
+
db.should be_open
|
20
|
+
end
|
21
|
+
|
22
|
+
it "creates the database file" do
|
23
|
+
db
|
24
|
+
File.should exist(path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with an absolute path to a database" do
|
29
|
+
let(:path) { "/tmp/test.db" }
|
30
|
+
let(:options) { "sqlite:#{path}" }
|
31
|
+
|
32
|
+
before(:each) { File.delete(path) if File.exist?(path) }
|
33
|
+
after(:each) { File.delete(path) if File.exist?(path) }
|
34
|
+
|
35
|
+
it "opens a database file" do
|
36
|
+
db.should be_open
|
37
|
+
end
|
38
|
+
|
39
|
+
it "creates the database file" do
|
40
|
+
db
|
41
|
+
File.should exist(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "with an in-memory database" do
|
46
|
+
let(:options) { "sqlite::memory:" }
|
47
|
+
|
48
|
+
it "opens a database in memory" do
|
49
|
+
db.should be_open
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "with a temporary file database" do
|
54
|
+
let(:options) { "sqlite:" }
|
55
|
+
|
56
|
+
it "opens a database file" do
|
57
|
+
db.should be_open
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "with an unusable path" do
|
62
|
+
let(:options) { "sqlite:/some/bad/path/to/a.db" }
|
63
|
+
|
64
|
+
it "raises an RDO::Exception" do
|
65
|
+
expect { db }.to raise_error(RDO::Exception)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "provides a meaningful error message" do
|
69
|
+
begin
|
70
|
+
db && fail("RDO::Exception should be raised")
|
71
|
+
rescue RDO::Exception =>e
|
72
|
+
e.message.should =~ /sqlite.*file/i
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "#close" do
|
79
|
+
it "closes the database" do
|
80
|
+
db.close
|
81
|
+
db.should_not be_open
|
82
|
+
end
|
83
|
+
|
84
|
+
it "returns true" do
|
85
|
+
db.close.should == true
|
86
|
+
end
|
87
|
+
|
88
|
+
context "called multiple times" do
|
89
|
+
it "has no negative side-effects" do
|
90
|
+
5.times { db.close }
|
91
|
+
db.should_not be_open
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "#open" do
|
97
|
+
it "opens the database" do
|
98
|
+
db.close && db.open
|
99
|
+
db.should be_open
|
100
|
+
end
|
101
|
+
|
102
|
+
it "returns true" do
|
103
|
+
db.close
|
104
|
+
db.open.should == true
|
105
|
+
end
|
106
|
+
|
107
|
+
context "called multiple times" do
|
108
|
+
it "has no negative side-effects" do
|
109
|
+
db.close
|
110
|
+
5.times { db.open }
|
111
|
+
db.should be_open
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "#execute" do
|
117
|
+
let(:options) { "sqlite::memory:" }
|
118
|
+
|
119
|
+
before(:each) do
|
120
|
+
db.execute <<-SQL
|
121
|
+
CREATE TABLE test (
|
122
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
123
|
+
name VARCHAR(32),
|
124
|
+
age INTEGER
|
125
|
+
)
|
126
|
+
SQL
|
127
|
+
end
|
128
|
+
|
129
|
+
context "with a bad query" do
|
130
|
+
let(:result) { db.execute("SELECT * FROM bad_table") }
|
131
|
+
|
132
|
+
it "raises an RDO::Exception" do
|
133
|
+
expect { result }.to raise_error(RDO::Exception)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "provides a meaningful error message" do
|
137
|
+
begin
|
138
|
+
result && fail("RDO::Exception should be raised")
|
139
|
+
rescue RDO::Exception => e
|
140
|
+
e.message.should =~ /bad_table/
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context "with an insert" do
|
146
|
+
let(:result) { db.execute("INSERT INTO test (name, age) VALUES ('bob', 12)") }
|
147
|
+
|
148
|
+
it "returns a RDO::Result" do
|
149
|
+
result.should be_a_kind_of(RDO::Result)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "provides the #insert_id" do
|
153
|
+
result.insert_id.should == 1
|
154
|
+
end
|
155
|
+
|
156
|
+
context "using bind parameters" do
|
157
|
+
let(:result) { db.execute("INSERT INTO test (name, age) VALUES (?, ?)", "bob", 12) }
|
158
|
+
|
159
|
+
it "returns a RDO::Result" do
|
160
|
+
result.should be_a_kind_of(RDO::Result)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "provides the #insert_id" do
|
164
|
+
result.insert_id.should == 1
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "with a select" do
|
170
|
+
before(:each) do
|
171
|
+
db.execute("INSERT INTO test (name, age) VALUES ('bob', 12)")
|
172
|
+
db.execute("INSERT INTO test (name, age) VALUES ('jane', 23)")
|
173
|
+
end
|
174
|
+
|
175
|
+
let(:result) { db.execute("SELECT * FROM test") }
|
176
|
+
|
177
|
+
it "returns a RDO::Result" do
|
178
|
+
result.should be_a_kind_of(RDO::Result)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "provides the #count" do
|
182
|
+
result.count.should == 2
|
183
|
+
end
|
184
|
+
|
185
|
+
it "allows enumeration of the rows" do
|
186
|
+
rows = []
|
187
|
+
result.each {|row| rows << row}
|
188
|
+
rows.should == [{id: 1, name: "bob", age: 12}, {id: 2, name: "jane", age: 23}]
|
189
|
+
end
|
190
|
+
|
191
|
+
context "using bind parameters" do
|
192
|
+
let(:result) { db.execute("SELECT * FROM test WHERE name = ?", "bob") }
|
193
|
+
|
194
|
+
it "returns a RDO::Result" do
|
195
|
+
result.should be_a_kind_of(RDO::Result)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "provides the #count" do
|
199
|
+
result.count.should == 1
|
200
|
+
end
|
201
|
+
|
202
|
+
it "allows enumeration of the rows" do
|
203
|
+
rows = []
|
204
|
+
result.each {|row| rows << row}
|
205
|
+
rows.should == [{id: 1, name: "bob", age: 12}]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
context "with an update" do
|
211
|
+
before(:each) do
|
212
|
+
db.execute("INSERT INTO test (name, age) VALUES ('bob', 12)")
|
213
|
+
db.execute("INSERT INTO test (name, age) VALUES ('jane', 23)")
|
214
|
+
end
|
215
|
+
|
216
|
+
let(:result) { db.execute("UPDATE test SET age = age + 3") }
|
217
|
+
|
218
|
+
it "returns a RDO::Result" do
|
219
|
+
result.should be_a_kind_of(RDO::Result)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "provides the number of #affected_rows" do
|
223
|
+
result.affected_rows.should == 2
|
224
|
+
end
|
225
|
+
|
226
|
+
context "using bind parameters" do
|
227
|
+
let(:result) { db.execute("UPDATE test SET age = age + ?", 2) }
|
228
|
+
|
229
|
+
it "returns a RDO::Result" do
|
230
|
+
result.should be_a_kind_of(RDO::Result)
|
231
|
+
end
|
232
|
+
|
233
|
+
it "provides the #affected_rows" do
|
234
|
+
result.affected_rows.should == 2
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "#prepare" do
|
241
|
+
before(:each) do
|
242
|
+
db.execute("CREATE TABLE test (id integer primary key, name text, age integer)")
|
243
|
+
end
|
244
|
+
|
245
|
+
it "creates a RDO::Statement" do
|
246
|
+
db.prepare("INSERT INTO test (name, age) VALUES (?, ?)").should be_a_kind_of(RDO::Statement)
|
247
|
+
end
|
248
|
+
|
249
|
+
context "when executed" do
|
250
|
+
let(:stmt) { db.prepare("INSERT INTO test (name, age) VALUES (?, ?)") }
|
251
|
+
|
252
|
+
it "returns a RDO::Result" do
|
253
|
+
stmt.execute("bob", 27).should be_a_kind_of(RDO::Result)
|
254
|
+
end
|
255
|
+
|
256
|
+
context "multiple times" do
|
257
|
+
before(:each) do
|
258
|
+
stmt.execute("bob", 27)
|
259
|
+
stmt.execute("jim", 19)
|
260
|
+
end
|
261
|
+
|
262
|
+
it "returns a Result for each execution" do
|
263
|
+
stmt2 = db.prepare("SELECT * FROM test WHERE name = ?")
|
264
|
+
result1 = stmt2.execute("bob")
|
265
|
+
result2 = stmt2.execute("jim")
|
266
|
+
|
267
|
+
result1.first[:age].should == 27
|
268
|
+
result2.first[:age].should == 19
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "#quote" do
|
275
|
+
it "returns a value safe to insert into SQL" do
|
276
|
+
db.quote("That's a quote!").should == "That''s a quote!"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe RDO::SQLite::Driver, "type casting" do
|
4
|
+
let(:options) { "sqlite::memory:" }
|
5
|
+
let(:db) { RDO.open(options) }
|
6
|
+
|
7
|
+
after(:each) { db.close rescue nil }
|
8
|
+
|
9
|
+
describe "null cast" do
|
10
|
+
let(:value) { db.execute("SELECT NULL").first_value }
|
11
|
+
|
12
|
+
it "returns nil" do
|
13
|
+
value.should be_nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "text cast" do
|
18
|
+
let(:value) { db.execute("SELECT CAST(42 AS TEXT)").first_value }
|
19
|
+
|
20
|
+
it "returns a String" do
|
21
|
+
value.should == "42"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "integer cast" do
|
26
|
+
let(:value) { db.execute("SELECT CAST('57' AS INTEGER)").first_value }
|
27
|
+
|
28
|
+
it "returns a Fixnum" do
|
29
|
+
value.should == 57
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "float cast" do
|
34
|
+
let(:value) { db.execute("SELECT CAST('56.4' AS FLOAT)").first_value }
|
35
|
+
|
36
|
+
it "returns a Float" do
|
37
|
+
value.should == 56.4
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "blob cast" do
|
42
|
+
let(:value) { db.execute("SELECT CAST(x'001122' AS BLOB)").first_value }
|
43
|
+
|
44
|
+
it "returns a String" do
|
45
|
+
value.should == "\x00\x11\x22"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdo-sqlite
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- d11wtq
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-27 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rdo
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.0.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.0.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rake-compiler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Provides access to SQLite3 using the RDO interface
|
63
|
+
email:
|
64
|
+
- chris@w3style.co.uk
|
65
|
+
executables: []
|
66
|
+
extensions:
|
67
|
+
- ext/rdo_sqlite/extconf.rb
|
68
|
+
extra_rdoc_files: []
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- .rspec
|
72
|
+
- Gemfile
|
73
|
+
- LICENSE
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- ext/rdo_sqlite/driver.c
|
77
|
+
- ext/rdo_sqlite/driver.h
|
78
|
+
- ext/rdo_sqlite/extconf.rb
|
79
|
+
- ext/rdo_sqlite/macros.h
|
80
|
+
- ext/rdo_sqlite/rdo_sqlite.c
|
81
|
+
- ext/rdo_sqlite/statements.c
|
82
|
+
- ext/rdo_sqlite/statements.h
|
83
|
+
- lib/rdo-sqlite.rb
|
84
|
+
- lib/rdo/sqlite.rb
|
85
|
+
- lib/rdo/sqlite/driver.rb
|
86
|
+
- lib/rdo/sqlite/version.rb
|
87
|
+
- rdo-sqlite.gemspec
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
- spec/sqlite/bind_params_spec.rb
|
90
|
+
- spec/sqlite/driver_spec.rb
|
91
|
+
- spec/sqlite/type_cast_spec.rb
|
92
|
+
homepage: https://github.com/d11wtq/rdo-sqlite
|
93
|
+
licenses: []
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubyforge_project:
|
112
|
+
rubygems_version: 1.8.23
|
113
|
+
signing_key:
|
114
|
+
specification_version: 3
|
115
|
+
summary: SQLite3 Driver for RDO
|
116
|
+
test_files:
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
- spec/sqlite/bind_params_spec.rb
|
119
|
+
- spec/sqlite/driver_spec.rb
|
120
|
+
- spec/sqlite/type_cast_spec.rb
|
121
|
+
has_rdoc:
|