Class: MysqlPR::Stmt

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/mysql-pr.rb,
lib/mysql-pr/constants.rb

Overview

Prepared statement

Constant Summary collapse

CURSOR_TYPE_NO_CURSOR =

Cursor type

0
CURSOR_TYPE_READ_ONLY =
1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(protocol, charset) ⇒ Stmt

Returns a new instance of Stmt.

Parameters:



857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
# File 'lib/mysql-pr.rb', line 857

def initialize(protocol, charset)
  @protocol = protocol
  @charset = charset
  @statement_id = nil
  @affected_rows = 0
  @insert_id = 0
  @server_status = 0
  @warning_count = 0
  @sqlstate = "00000"
  @param_count = nil
  @bind_result = nil
  @result = nil
  @fields = nil
  @last_error = nil
end

Instance Attribute Details

#affected_rowsInteger (readonly)

Returns:

  • (Integer)


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

#fieldsArray<MysqlPR::Field> (readonly)

Returns:



844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

#insert_idInteger (readonly)

Returns:

  • (Integer)


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

#param_countInteger (readonly)

Returns:

  • (Integer)


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

#server_statusInteger (readonly)

Returns:

  • (Integer)


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

#sqlstateString (readonly)

Returns:

  • (String)


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

#warning_countInteger (readonly)

Returns:

  • (Integer)


844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
# File 'lib/mysql-pr.rb', line 844

class Stmt
  include Enumerable

  attr_reader :affected_rows, :insert_id, :server_status, :warning_count, :param_count, :fields, :sqlstate

  def self.finalizer(protocol, statement_id)
    proc do
      protocol.gc_stmt(statement_id)
    end
  end

  # @param [MysqlPR::Protocol] protocol
  # @param [MysqlPR::Charset] charset
  def initialize(protocol, charset)
    @protocol = protocol
    @charset = charset
    @statement_id = nil
    @affected_rows = 0
    @insert_id = 0
    @server_status = 0
    @warning_count = 0
    @sqlstate = "00000"
    @param_count = nil
    @bind_result = nil
    @result = nil
    @fields = nil
    @last_error = nil
  end

  # Parse prepared-statement and return {MysqlPR::Stmt} object
  # @param [String] str query string
  # @return [MysqlPR::Stmt] self
  def prepare(str)
    close
    begin
      @sqlstate = "00000"
      @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
    ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
    self
  end

  # Execute prepared statement.
  # @param [Object] values values passed to query
  # @return [MysqlPR::Stmt] self
  def execute(*values)
    raise ClientError, "not prepared" unless @param_count
    raise ClientError, "parameter count mismatch" if values.length != @param_count

    values = values.map { |v| @charset.convert(v) }
    begin
      @sqlstate = "00000"
      nfields = @protocol.stmt_execute_command(@statement_id, values)
      if nfields
        @fields = @protocol.retr_fields(nfields)
        @result = StatementResult.new(@fields, @protocol, @charset)
      else
        @affected_rows = @protocol.affected_rows
        @insert_id = @protocol.insert_id
        @server_status = @protocol.server_status
        @warning_count = @protocol.warning_count
        @info = @protocol.message
      end
      self
    rescue ServerError => e
      @last_error = e
      @sqlstate = e.sqlstate
      raise
    end
  end

  # Close prepared statement
  # @return [void]
  def close
    ObjectSpace.undefine_finalizer(self)
    @protocol.stmt_close_command(@statement_id) if @statement_id
    @statement_id = nil
  end

  # @return [Array, nil] current record data
  def fetch
    row = @result.fetch
    return row unless @bind_result

    row.zip(@bind_result).map do |col, type|
      if col.nil?
        nil
      elsif [Numeric, Integer].include?(type)
        col.to_i
      elsif type == String
        col.to_s
      elsif type == Float && !col.is_a?(Float)
        col.to_i.to_f
      elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
        parse_time_value(col)
      else
        col
      end
    end
  end

  # Return data of current record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @return [Hash, nil] record data
  def fetch_hash(with_table = nil)
    @result.fetch_hash(with_table)
  end

  # Set retrieve type of value
  # @param [Class] args value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)
  # @return [MysqlPR::Stmt] self
  def bind_result(*args)
    if @fields.length != args.length
      raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
    end

    args.each do |a|
      unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
        raise TypeError, "unsupported type: #{a}"
      end
    end
    @bind_result = args
    self
  end

  # Iterate block with record.
  # @yield [Array] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each(&block)
    return enum_for(:each) unless block

    while (rec = fetch)
      block.call(rec)
    end
    self
  end

  # Iterate block with record as Hash.
  # @param [Boolean] with_table if true, hash key is "table_name.field_name"
  # @yield [Hash] record data
  # @return [MysqlPR::Stmt, Enumerator] self or Enumerator if block not specified
  def each_hash(with_table = nil, &block)
    return enum_for(:each_hash, with_table) unless block

    while (rec = fetch_hash(with_table))
      block.call(rec)
    end
    self
  end

  # @return [Integer] number of records
  def size
    @result.size
  end
  alias num_rows size

  # Set record position
  # @param [Integer] n record index
  # @return [void]
  def data_seek(n)
    @result.data_seek(n)
  end

  # @return [Integer] current record position
  def row_tell
    @result.row_tell
  end

  # Set current position of record
  # @param [Integer] n record index
  # @return [Integer] previous position
  def row_seek(n)
    @result.row_seek(n)
  end

  # @return [Integer] number of columns for last query
  def field_count
    @fields.length
  end

  # @return [void]
  def free_result; end

  # Returns MysqlPR::Result object that is empty.
  # Use fetch_fields to get list of fields.
  # @return [MysqlPR::Result, nil]
  def 
    return nil if @fields.empty?

    Result.new(@fields)
  end

  private

  def parse_time_value(col)
    return MysqlPR::Time.new unless col.to_s =~ /\A\d+\z/

    i = col.to_s.to_i
    if i < 100_000_000
      y = i / 10_000
      m = (i / 100) % 100
      d = i % 100
      h = mm = s = 0
    else
      y = i / 10_000_000_000
      m = (i / 100_000_000) % 100
      d = (i / 1_000_000) % 100
      h = (i / 10_000) % 100
      mm = (i / 100) % 100
      s = i % 100
    end
    y += 2000 if y < 70
    y += 1900 if y >= 70 && y < 100
    MysqlPR::Time.new(y, m, d, h, mm, s)
  end
end

Class Method Details

.finalizer(protocol, statement_id) ⇒ Object



849
850
851
852
853
# File 'lib/mysql-pr.rb', line 849

def self.finalizer(protocol, statement_id)
  proc do
    protocol.gc_stmt(statement_id)
  end
end

Instance Method Details

#bind_result(*args) ⇒ MysqlPR::Stmt

Set retrieve type of value

Parameters:

  • args (Class)

    value type (Numeric, Integer, Float, String, MysqlPR::Time, or nil)

Returns:



959
960
961
962
963
964
965
966
967
968
969
970
971
# File 'lib/mysql-pr.rb', line 959

def bind_result(*args)
  if @fields.length != args.length
    raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
  end

  args.each do |a|
    unless [Numeric, Integer, Float, String, MysqlPR::Time, nil].include?(a)
      raise TypeError, "unsupported type: #{a}"
    end
  end
  @bind_result = args
  self
end

#closevoid

This method returns an undefined value.

Close prepared statement



921
922
923
924
925
# File 'lib/mysql-pr.rb', line 921

def close
  ObjectSpace.undefine_finalizer(self)
  @protocol.stmt_close_command(@statement_id) if @statement_id
  @statement_id = nil
end

#data_seek(n) ⇒ void

This method returns an undefined value.

Set record position

Parameters:

  • n (Integer)

    record index



1007
1008
1009
# File 'lib/mysql-pr.rb', line 1007

def data_seek(n)
  @result.data_seek(n)
end

#each {|Array| ... } ⇒ MysqlPR::Stmt, Enumerator

Iterate block with record.

Yields:

  • (Array)

    record data

Returns:

  • (MysqlPR::Stmt, Enumerator)

    self or Enumerator if block not specified



976
977
978
979
980
981
982
983
# File 'lib/mysql-pr.rb', line 976

def each(&block)
  return enum_for(:each) unless block

  while (rec = fetch)
    block.call(rec)
  end
  self
end

#each_hash(with_table = nil) {|Hash| ... } ⇒ MysqlPR::Stmt, Enumerator

Iterate block with record as Hash.

Parameters:

  • with_table (Boolean) (defaults to: nil)

    if true, hash key is “table_name.field_name”

Yields:

  • (Hash)

    record data

Returns:

  • (MysqlPR::Stmt, Enumerator)

    self or Enumerator if block not specified



989
990
991
992
993
994
995
996
# File 'lib/mysql-pr.rb', line 989

def each_hash(with_table = nil, &block)
  return enum_for(:each_hash, with_table) unless block

  while (rec = fetch_hash(with_table))
    block.call(rec)
  end
  self
end

#execute(*values) ⇒ MysqlPR::Stmt

Execute prepared statement.

Parameters:

  • values (Object)

    values passed to query

Returns:

Raises:



893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
# File 'lib/mysql-pr.rb', line 893

def execute(*values)
  raise ClientError, "not prepared" unless @param_count
  raise ClientError, "parameter count mismatch" if values.length != @param_count

  values = values.map { |v| @charset.convert(v) }
  begin
    @sqlstate = "00000"
    nfields = @protocol.stmt_execute_command(@statement_id, values)
    if nfields
      @fields = @protocol.retr_fields(nfields)
      @result = StatementResult.new(@fields, @protocol, @charset)
    else
      @affected_rows = @protocol.affected_rows
      @insert_id = @protocol.insert_id
      @server_status = @protocol.server_status
      @warning_count = @protocol.warning_count
      @info = @protocol.message
    end
    self
  rescue ServerError => e
    @last_error = e
    @sqlstate = e.sqlstate
    raise
  end
end

#fetchArray?

Returns current record data.

Returns:

  • (Array, nil)

    current record data



928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
# File 'lib/mysql-pr.rb', line 928

def fetch
  row = @result.fetch
  return row unless @bind_result

  row.zip(@bind_result).map do |col, type|
    if col.nil?
      nil
    elsif [Numeric, Integer].include?(type)
      col.to_i
    elsif type == String
      col.to_s
    elsif type == Float && !col.is_a?(Float)
      col.to_i.to_f
    elsif type == MysqlPR::Time && !col.is_a?(MysqlPR::Time)
      parse_time_value(col)
    else
      col
    end
  end
end

#fetch_hash(with_table = nil) ⇒ Hash?

Return data of current record as Hash.

Parameters:

  • with_table (Boolean) (defaults to: nil)

    if true, hash key is “table_name.field_name”

Returns:

  • (Hash, nil)

    record data



952
953
954
# File 'lib/mysql-pr.rb', line 952

def fetch_hash(with_table = nil)
  @result.fetch_hash(with_table)
end

#field_countInteger

Returns number of columns for last query.

Returns:

  • (Integer)

    number of columns for last query



1024
1025
1026
# File 'lib/mysql-pr.rb', line 1024

def field_count
  @fields.length
end

#free_resultvoid

This method returns an undefined value.



1029
# File 'lib/mysql-pr.rb', line 1029

def free_result; end

#prepare(str) ⇒ MysqlPR::Stmt

Parse prepared-statement and return MysqlPR::Stmt object

Parameters:

  • str (String)

    query string

Returns:



876
877
878
879
880
881
882
883
884
885
886
887
888
# File 'lib/mysql-pr.rb', line 876

def prepare(str)
  close
  begin
    @sqlstate = "00000"
    @statement_id, @param_count, @fields = @protocol.stmt_prepare_command(str)
  rescue ServerError => e
    @last_error = e
    @sqlstate = e.sqlstate
    raise
  end
  ObjectSpace.define_finalizer(self, self.class.finalizer(@protocol, @statement_id))
  self
end

#result_metadataMysqlPR::Result?

Returns MysqlPR::Result object that is empty. Use fetch_fields to get list of fields.

Returns:



1034
1035
1036
1037
1038
# File 'lib/mysql-pr.rb', line 1034

def 
  return nil if @fields.empty?

  Result.new(@fields)
end

#row_seek(n) ⇒ Integer

Set current position of record

Parameters:

  • n (Integer)

    record index

Returns:

  • (Integer)

    previous position



1019
1020
1021
# File 'lib/mysql-pr.rb', line 1019

def row_seek(n)
  @result.row_seek(n)
end

#row_tellInteger

Returns current record position.

Returns:

  • (Integer)

    current record position



1012
1013
1014
# File 'lib/mysql-pr.rb', line 1012

def row_tell
  @result.row_tell
end

#sizeInteger Also known as: num_rows

Returns number of records.

Returns:

  • (Integer)

    number of records



999
1000
1001
# File 'lib/mysql-pr.rb', line 999

def size
  @result.size
end