2016-01-28 23:31:35 +00:00
|
|
|
module DB
|
2016-01-31 22:40:02 +00:00
|
|
|
# The response of a query performed on a `Database`.
|
|
|
|
#
|
|
|
|
# See `DB` for a complete sample.
|
|
|
|
#
|
|
|
|
# Each `#read` call consumes the result and moves to the next column.
|
|
|
|
#
|
|
|
|
# ### Note to implementors
|
|
|
|
#
|
|
|
|
# 1. Override `#move_next` to move to the next row.
|
|
|
|
# 2. Override `#read?(t)` for all `t` in `DB::TYPES`.
|
|
|
|
# 3. (Optional) Override `#read(t)` for all `t` in `DB::TYPES`.
|
|
|
|
# 4. Override `#column_count`, `#column_name`.
|
|
|
|
# 5. Override `#column_type`. It must return a type in `DB::TYPES`.
|
2016-01-28 23:31:35 +00:00
|
|
|
abstract class ResultSet
|
|
|
|
getter statement
|
|
|
|
|
|
|
|
def initialize(@statement : Statement)
|
|
|
|
end
|
|
|
|
|
2016-02-02 00:55:30 +00:00
|
|
|
# TODO add_next_result_set : Bool
|
|
|
|
|
2016-01-31 22:40:02 +00:00
|
|
|
# Iterates over all the rows
|
2016-01-28 23:51:03 +00:00
|
|
|
def each
|
2016-01-29 19:13:01 +00:00
|
|
|
while move_next
|
2016-01-28 23:51:03 +00:00
|
|
|
yield
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-02 00:55:30 +00:00
|
|
|
# Closes this result set.
|
2016-01-30 00:57:00 +00:00
|
|
|
def close
|
2016-02-02 00:55:30 +00:00
|
|
|
return if @closed
|
|
|
|
@closed = true
|
|
|
|
do_close
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns `true` if this result set is closed. See `#close`.
|
|
|
|
def closed?
|
|
|
|
@closed
|
|
|
|
end
|
|
|
|
|
|
|
|
# :nodoc:
|
|
|
|
def finalize
|
|
|
|
close
|
|
|
|
end
|
|
|
|
|
|
|
|
protected def do_close
|
2016-01-30 00:57:00 +00:00
|
|
|
end
|
|
|
|
|
2016-01-31 22:40:02 +00:00
|
|
|
# Move the next row in the result.
|
|
|
|
# Return `false` if no more rows are available.
|
|
|
|
# See `#each`
|
2016-01-29 19:13:01 +00:00
|
|
|
abstract def move_next : Bool
|
2016-01-28 23:31:35 +00:00
|
|
|
|
2016-01-30 22:46:43 +00:00
|
|
|
# TODO def empty? : Bool, handle internally with move_next (?)
|
|
|
|
|
2016-01-31 22:40:02 +00:00
|
|
|
# Returns the number of columns in the result
|
2016-01-30 00:57:00 +00:00
|
|
|
abstract def column_count : Int32
|
2016-01-31 22:40:02 +00:00
|
|
|
|
|
|
|
# Returns the name of the column in `index` 0-based position.
|
2016-01-30 00:57:00 +00:00
|
|
|
abstract def column_name(index : Int32) : String
|
2016-01-31 22:40:02 +00:00
|
|
|
|
|
|
|
# Returns the type of the column in `index` 0-based position.
|
|
|
|
# The result is one of `DB::TYPES`.
|
2016-01-30 22:46:43 +00:00
|
|
|
abstract def column_type(index : Int32)
|
2016-01-30 00:57:00 +00:00
|
|
|
|
2016-01-28 23:31:35 +00:00
|
|
|
# list datatypes that must be supported form the driver
|
2016-01-29 19:13:01 +00:00
|
|
|
# users will call read(String) or read?(String) for nillables
|
2016-01-31 22:40:02 +00:00
|
|
|
|
2016-01-29 19:13:01 +00:00
|
|
|
{% for t in DB::TYPES %}
|
2016-01-31 22:40:02 +00:00
|
|
|
# Reads the next column as a nillable {{t}}.
|
2016-01-29 19:13:01 +00:00
|
|
|
abstract def read?(t : {{t}}.class) : {{t}}?
|
|
|
|
|
2016-01-31 22:40:02 +00:00
|
|
|
# Reads the next column as a {{t}}.
|
2016-01-28 23:31:35 +00:00
|
|
|
def read(t : {{t}}.class) : {{t}}
|
2016-01-29 19:13:01 +00:00
|
|
|
read?({{t}}).not_nil!
|
2016-01-28 23:31:35 +00:00
|
|
|
end
|
|
|
|
{% end %}
|
2016-02-02 00:55:30 +00:00
|
|
|
|
|
|
|
# def read_blob
|
|
|
|
# yield ... io ....
|
|
|
|
# end
|
|
|
|
|
|
|
|
# def read_text
|
|
|
|
# yield ... io ....
|
|
|
|
# end
|
2016-01-28 23:31:35 +00:00
|
|
|
end
|
|
|
|
end
|