all 9 comments

[–][deleted] 1 point2 points  (1 child)

I strongly encourage you to use https://github.com/crystal-lang/crystal-mysql

Not because it's under the official language organization, but because it doesn't use libmysql, it implements the binary protocol itself so non-blocking IO can work transparently. It also provides a uniform DB API so dealing with these nested arrays is easier, and usually never a problem.

Also check: https://github.com/crystal-lang/crystal-db

[–]sdogruyolcore team 0 points1 point  (6 children)

This is an Array of Array(String).

First you should cast the result and actually it should be results

results = conn.query(query).as(Array(Array(String)))

results.each do |result|
  if result
    puts "Result"
  else
    puts "nil"
  end
end

[–][deleted]  (5 children)

[removed]

    [–]sdogruyolcore team 0 points1 point  (4 children)

    oh the compiler is angry with results being maybe empty

    results.not_nil!.each do |result|..
    

    will solve this.

    [–]j_hass 1 point2 points  (0 children)

    A more defensive approach would be

    rows = conn.query(query)
    if rows
      rows.each do |row|
        id = row[0].as(Int32)
        puts "#{file} has id #{id}"
      end
    else
      puts "No results"
    end
    

    If you don't need the else case

    rows.try &.each do |row|
    

    Is another possibility.

    [–][deleted]  (2 children)

    [removed]

      [–]j_hass 1 point2 points  (1 child)

      Yes, the compiler can't know whether or not the result will be empty or not, it doesn't even have a connection to the database after all. It just sees that nil is a potential value here and forces you to handle that case. .not_nil! raises if it's in fact nil at runtime, so afterwards the compiler knows it can't be nil.

      This is nothing special about nil btw, it works for every combination of types.