test_database.rb 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. require 'helper'
  2. module SQLite3
  3. class TestDatabase < SQLite3::TestCase
  4. attr_reader :db
  5. def setup
  6. @db = SQLite3::Database.new(':memory:')
  7. end
  8. def test_segv
  9. assert_raises(TypeError) { SQLite3::Database.new 1 }
  10. end
  11. def test_bignum
  12. num = 4907021672125087844
  13. db.execute 'CREATE TABLE "employees" ("token" integer(8), "name" varchar(20) NOT NULL)'
  14. db.execute "INSERT INTO employees(name, token) VALUES('employee-1', ?)", [num]
  15. rows = db.execute 'select token from employees'
  16. assert_equal num, rows.first.first
  17. end
  18. def test_blob
  19. @db.execute("CREATE TABLE blobs ( id INTEGER, hash BLOB(10) )")
  20. str = "\0foo"
  21. @db.execute("INSERT INTO blobs VALUES (0, ?)", [str])
  22. assert_equal [[0, str]], @db.execute("SELECT * FROM blobs")
  23. end
  24. def test_get_first_row
  25. assert_equal [1], @db.get_first_row('SELECT 1')
  26. end
  27. def test_get_first_row_with_type_translation_and_hash_results
  28. @db.results_as_hash = true
  29. assert_equal({0=>1, "1"=>1}, @db.get_first_row('SELECT 1'))
  30. end
  31. def test_execute_with_type_translation_and_hash
  32. @db.results_as_hash = true
  33. rows = []
  34. @db.execute('SELECT 1') { |row| rows << row }
  35. assert_equal({0=>1, "1"=>1}, rows.first)
  36. end
  37. def test_encoding
  38. assert @db.encoding, 'database has encoding'
  39. end
  40. def test_changes
  41. @db.execute("CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, number integer)")
  42. assert_equal 0, @db.changes
  43. @db.execute("INSERT INTO items (number) VALUES (10)")
  44. assert_equal 1, @db.changes
  45. @db.execute_batch(
  46. "UPDATE items SET number = (number + :nn) WHERE (number = :n)",
  47. {"nn" => 20, "n" => 10})
  48. assert_equal 1, @db.changes
  49. assert_equal [[30]], @db.execute("select number from items")
  50. end
  51. def test_new
  52. db = SQLite3::Database.new(':memory:')
  53. assert db
  54. end
  55. def test_new_yields_self
  56. thing = nil
  57. SQLite3::Database.new(':memory:') do |db|
  58. thing = db
  59. end
  60. assert_instance_of(SQLite3::Database, thing)
  61. end
  62. def test_new_with_options
  63. # determine if Ruby is running on Big Endian platform
  64. utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
  65. if RUBY_VERSION >= "1.9"
  66. db = SQLite3::Database.new(':memory:'.encode(utf16), :utf16 => true)
  67. else
  68. db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
  69. :utf16 => true)
  70. end
  71. assert db
  72. end
  73. def test_close
  74. db = SQLite3::Database.new(':memory:')
  75. db.close
  76. assert db.closed?
  77. end
  78. def test_block_closes_self
  79. thing = nil
  80. SQLite3::Database.new(':memory:') do |db|
  81. thing = db
  82. assert !thing.closed?
  83. end
  84. assert thing.closed?
  85. end
  86. def test_prepare
  87. db = SQLite3::Database.new(':memory:')
  88. stmt = db.prepare('select "hello world"')
  89. assert_instance_of(SQLite3::Statement, stmt)
  90. end
  91. def test_total_changes
  92. db = SQLite3::Database.new(':memory:')
  93. db.execute("create table foo ( a integer primary key, b text )")
  94. db.execute("insert into foo (b) values ('hello')")
  95. assert_equal 1, db.total_changes
  96. end
  97. def test_execute_returns_list_of_hash
  98. db = SQLite3::Database.new(':memory:', :results_as_hash => true)
  99. db.execute("create table foo ( a integer primary key, b text )")
  100. db.execute("insert into foo (b) values ('hello')")
  101. rows = db.execute("select * from foo")
  102. assert_equal [{0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}], rows
  103. end
  104. def test_execute_yields_hash
  105. db = SQLite3::Database.new(':memory:', :results_as_hash => true)
  106. db.execute("create table foo ( a integer primary key, b text )")
  107. db.execute("insert into foo (b) values ('hello')")
  108. db.execute("select * from foo") do |row|
  109. assert_equal({0=>1, "a"=>1, "b"=>"hello", 1=>"hello"}, row)
  110. end
  111. end
  112. def test_table_info
  113. db = SQLite3::Database.new(':memory:', :results_as_hash => true)
  114. db.execute("create table foo ( a integer primary key, b text )")
  115. info = [{
  116. "name" => "a",
  117. "pk" => 1,
  118. "notnull" => 0,
  119. "type" => "integer",
  120. "dflt_value" => nil,
  121. "cid" => 0
  122. },
  123. {
  124. "name" => "b",
  125. "pk" => 0,
  126. "notnull" => 0,
  127. "type" => "text",
  128. "dflt_value" => nil,
  129. "cid" => 1
  130. }]
  131. assert_equal info, db.table_info('foo')
  132. end
  133. def test_total_changes_closed
  134. db = SQLite3::Database.new(':memory:')
  135. db.close
  136. assert_raise(SQLite3::Exception) do
  137. db.total_changes
  138. end
  139. end
  140. def test_trace_requires_opendb
  141. @db.close
  142. assert_raise(SQLite3::Exception) do
  143. @db.trace { |x| }
  144. end
  145. end
  146. def test_trace_with_block
  147. result = nil
  148. @db.trace { |sql| result = sql }
  149. @db.execute "select 'foo'"
  150. assert_equal "select 'foo'", result
  151. end
  152. def test_trace_with_object
  153. obj = Class.new {
  154. attr_accessor :result
  155. def call sql; @result = sql end
  156. }.new
  157. @db.trace(obj)
  158. @db.execute "select 'foo'"
  159. assert_equal "select 'foo'", obj.result
  160. end
  161. def test_trace_takes_nil
  162. @db.trace(nil)
  163. @db.execute "select 'foo'"
  164. end
  165. def test_last_insert_row_id_closed
  166. @db.close
  167. assert_raise(SQLite3::Exception) do
  168. @db.last_insert_row_id
  169. end
  170. end
  171. def test_define_function
  172. called_with = nil
  173. @db.define_function("hello") do |value|
  174. called_with = value
  175. end
  176. @db.execute("select hello(10)")
  177. assert_equal 10, called_with
  178. end
  179. def test_call_func_arg_type
  180. called_with = nil
  181. @db.define_function("hello") do |b, c, d|
  182. called_with = [b, c, d]
  183. nil
  184. end
  185. @db.execute("select hello(2.2, 'foo', NULL)")
  186. assert_equal [2.2, 'foo', nil], called_with
  187. end
  188. def test_define_varargs
  189. called_with = nil
  190. @db.define_function("hello") do |*args|
  191. called_with = args
  192. nil
  193. end
  194. @db.execute("select hello(2.2, 'foo', NULL)")
  195. assert_equal [2.2, 'foo', nil], called_with
  196. end
  197. def test_function_return
  198. @db.define_function("hello") { |a| 10 }
  199. assert_equal [10], @db.execute("select hello('world')").first
  200. end
  201. def test_function_return_types
  202. [10, 2.2, nil, "foo"].each do |thing|
  203. @db.define_function("hello") { |a| thing }
  204. assert_equal [thing], @db.execute("select hello('world')").first
  205. end
  206. end
  207. def test_define_function_closed
  208. @db.close
  209. assert_raise(SQLite3::Exception) do
  210. @db.define_function('foo') { }
  211. end
  212. end
  213. def test_inerrupt_closed
  214. @db.close
  215. assert_raise(SQLite3::Exception) do
  216. @db.interrupt
  217. end
  218. end
  219. def test_define_aggregate
  220. @db.execute "create table foo ( a integer primary key, b text )"
  221. @db.execute "insert into foo ( b ) values ( 'foo' )"
  222. @db.execute "insert into foo ( b ) values ( 'bar' )"
  223. @db.execute "insert into foo ( b ) values ( 'baz' )"
  224. acc = Class.new {
  225. attr_reader :sum
  226. alias :finalize :sum
  227. def initialize
  228. @sum = 0
  229. end
  230. def step a
  231. @sum += a
  232. end
  233. }.new
  234. @db.define_aggregator("accumulate", acc)
  235. value = @db.get_first_value( "select accumulate(a) from foo" )
  236. assert_equal 6, value
  237. end
  238. def test_authorizer_ok
  239. @db.authorizer = Class.new {
  240. def call action, a, b, c, d; true end
  241. }.new
  242. @db.prepare("select 'fooooo'")
  243. @db.authorizer = Class.new {
  244. def call action, a, b, c, d; 0 end
  245. }.new
  246. @db.prepare("select 'fooooo'")
  247. end
  248. def test_authorizer_ignore
  249. @db.authorizer = Class.new {
  250. def call action, a, b, c, d; nil end
  251. }.new
  252. stmt = @db.prepare("select 'fooooo'")
  253. assert_equal nil, stmt.step
  254. end
  255. def test_authorizer_fail
  256. @db.authorizer = Class.new {
  257. def call action, a, b, c, d; false end
  258. }.new
  259. assert_raises(SQLite3::AuthorizationException) do
  260. @db.prepare("select 'fooooo'")
  261. end
  262. end
  263. def test_remove_auth
  264. @db.authorizer = Class.new {
  265. def call action, a, b, c, d; false end
  266. }.new
  267. assert_raises(SQLite3::AuthorizationException) do
  268. @db.prepare("select 'fooooo'")
  269. end
  270. @db.authorizer = nil
  271. @db.prepare("select 'fooooo'")
  272. end
  273. def test_close_with_open_statements
  274. @db.prepare("select 'foo'")
  275. assert_raises(SQLite3::BusyException) do
  276. @db.close
  277. end
  278. end
  279. def test_execute_with_empty_bind_params
  280. assert_equal [['foo']], @db.execute("select 'foo'", [])
  281. end
  282. def test_query_with_named_bind_params
  283. assert_equal [['foo']], @db.query("select :n", {'n' => 'foo'}).to_a
  284. end
  285. def test_execute_with_named_bind_params
  286. assert_equal [['foo']], @db.execute("select :n", {'n' => 'foo'})
  287. end
  288. end
  289. end