crystal-lang / crystal-mysql

MySQL connector for Crystal
MIT License
107 stars 36 forks source link

mariadb 10.0.22 problem #5

Closed tophe closed 8 years ago

tophe commented 8 years ago

hello,

I have issue using the driver, as I run the readme code exemple it work, but when I run that:

require "mysl"
DB.open "mysql://user:pass@host/rtx" do |db|
  sql ="set names utf8"
  db.exec sql

  db.exec "drop table if exists stx"

  db.exec "CREATE TABLE `stx` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `label` VARCHAR(30)  NOT NULL DEFAULT '0',
  `description` VARCHAR(255) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) "

  sql ="select id from stx limit 1"
  db.query sql do |row|
        puts "#{row.column_name(0)}"

        puts row.read(Int32)

  end
end

I have :

id
Nil assertion failed (Exception)
[4491223] *CallStack::unwind:Array(Pointer(Void)) +87
[4491114] *CallStack#initialize:Array(Pointer(Void)) +10
[4491066] *CallStack::new:CallStack +42
[4455400] *raise<Exception>:NoReturn +24
[4455374] ???
[4541680] *Nil#not_nil!:NoReturn +16
[4663121] *MySql::ResultSet#read?<Int32:Class>:(Int32 | Nil) +65
[4662980] *MySql::ResultSet +36
[4433049] ???
[4468553] main +41
[140332662660805] __libc_start_main +245
[4428537] ???
[0] ???

using Crystal 0.18.7 68783f1 on ubuntu 14.4, mariadb 10.0.22

bcardiff commented 8 years ago

Hi @tophe . I added quoting-code to your comment to facilitate reading it.

When you use Database#query

db.query sql do |rs|
  # rs is a ResultSet, not a row.

  # you can ask column information, yes
  puts rs.column_name(0)

  # but you need to call ResultSet#each to iterate over the rows 
  rs.each do
    puts rs.read(Int32)
  end
end

Alternative you can use Database#query_one instead of Database#query that will return you a ResultSet alread positioned in the first row (it will also fail if more than 1 row is returned)

db.query_one sql do |rs|
  puts rs.column_name(0)
  puts rs.read(Int32)
end

Or if you just want the id Database#scalar will do it.

puts db.scalar sql

Your issue was calling ResultSet#read without calling first ResultSet#move_next.

tophe commented 8 years ago

Oh, thank you for that clean explanation ! I have reread the readme.md, and every thing was already there ! I close the issue .

tophe commented 8 years ago

just to be sure, right now we can read String with are nullable on mysql. because if I write lastname = rs.read(String) and lastname is null on mysql I got:

Nil assertion failed (Exception) [4950583] CallStack::unwind:Array(Pointer(Void)) +87 [4950474] CallStack#initialize:Array(Pointer(Void)) +10 [4950426] CallStack::new:CallStack +42 [4841448] raise:NoReturn +24 [4841422] ??? [5123328] Nil#not_nil!:NoReturn +16 [5662846] MySql::ResultSet +46 [5700726] Finder::Store#store_build_mysql:DB::Database +550 [5699697] Finder::Store#initialize<Finder::RMode, Logger::Severity, Int32>:(HTTP::Server::Response::Output | IO::FileDescriptor+ | Int32 | Nil) +1761 [5697905] Finder::Store#initialize:mode:log_level<Finder::RMode, Logger::Severity>:(HTTP::Server::Response::Output | IO::FileDescriptor+ | Int32 | Nil) +49 [5697823] Finder::Store::new:mode:log_level<Finder::RMode, Logger::Severity>:Finder::Store +127 [4798603] ??? [4859817] main +41 [139983727992517] __libc_start_main +245 [4791833] ??? [0] ???

asterite commented 8 years ago

@tophe use rs.read(String?) and generally T? for things that can be NULL in SQL (so nil in Crystal)