Skip to content

Commit

Permalink
Replace driver_spec for db/spec
Browse files Browse the repository at this point in the history
Update to crystal-db ~> 0.4.1
  • Loading branch information
Brian J. Cardiff committed Apr 10, 2017
1 parent 629ed9a commit 6ab44d8
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 404 deletions.
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ version: 0.3.2
dependencies:
db:
github: crystal-lang/crystal-db
version: ~> 0.4.0
version: ~> 0.4.1

authors:
- Juan Wajnerman <jwajnerman@manas.tech>
Expand Down
158 changes: 158 additions & 0 deletions spec/db_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
require "./spec_helper"
require "db/spec"
require "semantic_version"

private class NotSupportedType
end

DB::DriverSpecs(MySql::Any).run do
before do
DB.open "mysql://root@localhost" do |db|
db.exec "DROP DATABASE IF EXISTS crystal_mysql_test"
db.exec "CREATE DATABASE crystal_mysql_test"
end
end
after do
DB.open "mysql://root@localhost" do |db|
db.exec "DROP DATABASE IF EXISTS crystal_mysql_test"
end
end

connection_string "mysql://root@localhost/crystal_mysql_test"

sample_value true, "bool", "true", type_safe_value: false
sample_value false, "bool", "false", type_safe_value: false
sample_value 5_i8, "tinyint(1)", "5", type_safe_value: false
sample_value 54_i16, "smallint(2)", "54", type_safe_value: false
sample_value 1, "int", "1", type_safe_value: false
sample_value 1_i64, "bigint", "1"
sample_value "hello", "varchar(25)", "'hello'"
sample_value 1.5_f32, "float", "1.5", type_safe_value: false
sample_value 1.5, "double", "1.5"
sample_value Time.new(2016, 2, 15), "datetime", "TIMESTAMP '2016-02-15 00:00:00.000'"
sample_value Time.new(2016, 2, 15, 10, 15, 30), "datetime", "TIMESTAMP '2016-02-15 10:15:30.000'"

with_db do |db|
# needs to check version, microsecond support >= 5.7
dbversion = SemanticVersion.parse(db.scalar("SELECT VERSION();").as(String))
if dbversion >= SemanticVersion.new(5, 7, 0)
sample_value Time.new(2016, 2, 15, 10, 15, 30, 543), "datetime(3)", "TIMESTAMP '2016-02-15 10:15:30.543'"
end

# zero dates http://dev.mysql.com/doc/refman/5.7/en/datetime.html - work on some mysql not others,
# NO_ZERO_IN_DATE enabled as part of strict mode in MySQL 5.7.8. - http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-changes
mode = db.scalar("SELECT @@sql_mode").as(String)
if !mode.match(/NO_ZERO_DATE/)
sample_value Time.new(0), "datetime", "TIMESTAMP '0000-00-00 00:00:00'"
end
end

ary = UInt8[0x41, 0x5A, 0x61, 0x7A]
sample_value Bytes.new(ary.to_unsafe, ary.size), "BLOB", "X'415A617A'", type_safe_value: false

[
{"TINYBLOB", 10},
{"BLOB", 1000},
{"MEDIUMBLOB", 10000},
{"LONGBLOB", 100000},
].each do |type, size|
sample_value Bytes.new((ary * size).to_unsafe, ary.size * size), type, "X'#{"415A617A" * size}'", type_safe_value: false
end

[
{"TINYTEXT", 10},
{"TEXT", 1000},
{"MEDIUMTEXT", 10000},
{"LONGTEXT", 100000},
].each do |type, size|
value = "Ham Sandwich" * size
sample_value value, type, "'#{value}'"
end

binding_syntax do |index|
"?"
end

create_table_1column_syntax do |table_name, col1|
"create table #{table_name} (#{col1.name} #{col1.sql_type} #{col1.null ? "NULL" : "NOT NULL"})"
end

create_table_2columns_syntax do |table_name, col1, col2|
"create table #{table_name} (#{col1.name} #{col1.sql_type} #{col1.null ? "NULL" : "NOT NULL"}, #{col2.name} #{col2.sql_type} #{col2.null ? "NULL" : "NOT NULL"})"
end

select_1column_syntax do |table_name, col1|
"select #{col1.name} from #{table_name}"
end

select_2columns_syntax do |table_name, col1, col2|
"select #{col1.name}, #{col2.name} from #{table_name}"
end

select_count_syntax do |table_name|
"select count(*) from #{table_name}"
end

select_scalar_syntax do |expression|
"select #{expression}"
end

insert_1column_syntax do |table_name, col, expression|
"insert into #{table_name} (#{col.name}) values (#{expression})"
end

insert_2columns_syntax do |table_name, col1, expr1, col2, expr2|
"insert into #{table_name} (#{col1.name}, #{col2.name}) values (#{expr1}, #{expr2})"
end

drop_table_if_exists_syntax do |table_name|
"drop table if exists #{table_name}"
end

it "gets last insert row id", prepared: :both do |db|
db.exec "create table person (id int not null primary key auto_increment, name varchar(25), age int)"
db.exec %(insert into person (name, age) values ("foo", 10))
res = db.exec %(insert into person (name, age) values ("foo", 10))
res.last_insert_id.should eq(2)
res.rows_affected.should eq(1)
end

it "get timestamp from table" do |db|
db.exec "create table table1 (m int, dt datetime, ts timestamp DEFAULT CURRENT_TIMESTAMP)"
db.exec "insert into table1 (m, dt) values(?, NOW())", 1

dt, ts = db.query_one "SELECT dt, ts from table1", as: {Time, Time}
(ts - dt).total_seconds.should be_close(0.0, 0.5)
end

it "raises on unsupported param types" do |db|
expect_raises Exception, "MySql::Type does not support NotSupportedType values" do
db.query "select ?", NotSupportedType.new
end
# TODO raising exception does not close the connection and pool is exhausted
end

it "ensures statements are closed" do |db|
db.exec %(create table if not exists a (i int not null, str text not null);)
db.exec %(insert into a (i, str) values (23, "bai bai");)

2.times do |i|
DB.open db.uri do |db|
begin
db.query("SELECT i, str FROM a WHERE i = ?", 23) do |rs|
rs.move_next
break
end
rescue e
fail("Expected no exception, but got \"#{e.message}\"")
end

begin
db.exec("UPDATE a SET i = ? WHERE i = ?", 23, 23)
rescue e
fail("Expected no exception, but got \"#{e.message}\"")
end
end
end
end
end
Loading

0 comments on commit 6ab44d8

Please sign in to comment.