ruby-mysql 2.11.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -0
- data/README.md +28 -0
- data/lib/mysql/protocol.rb +81 -147
- data/lib/mysql.rb +182 -359
- data/test/test_mysql.rb +217 -550
- metadata +10 -7
- data/README.rdoc +0 -69
    
        data/lib/mysql.rb
    CHANGED
    
    | @@ -2,6 +2,8 @@ | |
| 2 2 | 
             
            # Copyright (C) 2008 TOMITA Masahiro
         | 
| 3 3 | 
             
            # mailto:tommy@tmtm.org
         | 
| 4 4 |  | 
| 5 | 
            +
            require 'uri'
         | 
| 6 | 
            +
             | 
| 5 7 | 
             
            # MySQL connection class.
         | 
| 6 8 | 
             
            # @example
         | 
| 7 9 | 
             
            #  my = Mysql.connect('hostname', 'user', 'password', 'dbname')
         | 
| @@ -11,44 +13,76 @@ | |
| 11 13 | 
             
            #  end
         | 
| 12 14 | 
             
            class Mysql
         | 
| 13 15 |  | 
| 14 | 
            -
               | 
| 15 | 
            -
               | 
| 16 | 
            -
               | 
| 17 | 
            -
               | 
| 18 | 
            -
               | 
| 16 | 
            +
              require_relative "mysql/constants"
         | 
| 17 | 
            +
              require_relative "mysql/error"
         | 
| 18 | 
            +
              require_relative "mysql/charset"
         | 
| 19 | 
            +
              require_relative "mysql/protocol"
         | 
| 20 | 
            +
              require_relative "mysql/packet.rb"
         | 
| 19 21 |  | 
| 20 | 
            -
              VERSION            =  | 
| 22 | 
            +
              VERSION            = '3.0.0'             # Version number of this library
         | 
| 21 23 | 
             
              MYSQL_UNIX_PORT    = "/tmp/mysql.sock"   # UNIX domain socket filename
         | 
| 22 24 | 
             
              MYSQL_TCP_PORT     = 3306                # TCP socket port number
         | 
| 23 25 |  | 
| 24 | 
            -
              #  | 
| 25 | 
            -
               | 
| 26 | 
            +
              # @!attribute [rw] host
         | 
| 27 | 
            +
              #   @return [String, nil]
         | 
| 28 | 
            +
              # @!attribute [rw] username
         | 
| 29 | 
            +
              #   @return [String, nil]
         | 
| 30 | 
            +
              # @!attribute [rw] password
         | 
| 31 | 
            +
              #   @return [String, nil]
         | 
| 32 | 
            +
              # @!attribute [rw] database
         | 
| 33 | 
            +
              #   @return [String, nil]
         | 
| 34 | 
            +
              # @!attribute [rw] port
         | 
| 35 | 
            +
              #   @return [Integer, String, nil]
         | 
| 36 | 
            +
              # @!attribute [rw] socket
         | 
| 37 | 
            +
              #   @return [String, nil] socket filename
         | 
| 38 | 
            +
              # @!attribute [rw] flags
         | 
| 39 | 
            +
              #   @return [Integer, nil]
         | 
| 40 | 
            +
              # @!attribute [rw] connect_timeout
         | 
| 41 | 
            +
              #   @return [Numeric, nil]
         | 
| 42 | 
            +
              # @!attribute [rw] read_timeout
         | 
| 43 | 
            +
              #   @return [Numeric, nil]
         | 
| 44 | 
            +
              # @!attribute [rw] write_timeout
         | 
| 45 | 
            +
              #   @return [Numeric, nil]
         | 
| 46 | 
            +
              # @!attribute [rw] init_command
         | 
| 47 | 
            +
              #   @return [String, nil]
         | 
| 48 | 
            +
              # @!attribute [rw] local_infile
         | 
| 49 | 
            +
              #   @return [Boolean]
         | 
| 50 | 
            +
              # @!attribute [rw] load_data_local_dir
         | 
| 51 | 
            +
              #   @return [String, nil]
         | 
| 52 | 
            +
              # @!attribute [rw] ssl_mode
         | 
| 53 | 
            +
              #   @return [String, Integer] 1 or "disabled" / 2 or "preferred" / 3 or "required"
         | 
| 54 | 
            +
              # @!attribute [rw] get_server_public_key
         | 
| 55 | 
            +
              #   @return [Boolean]
         | 
| 56 | 
            +
              DEFAULT_OPTS = {
         | 
| 57 | 
            +
                host: nil,
         | 
| 58 | 
            +
                username: nil,
         | 
| 59 | 
            +
                password: nil,
         | 
| 60 | 
            +
                database: nil,
         | 
| 61 | 
            +
                port: nil,
         | 
| 62 | 
            +
                socket: nil,
         | 
| 63 | 
            +
                flags: 0,
         | 
| 64 | 
            +
                charset: nil,
         | 
| 65 | 
            +
                connect_timeout: nil,
         | 
| 66 | 
            +
                read_timeout: nil,
         | 
| 67 | 
            +
                write_timeout: nil,
         | 
| 68 | 
            +
                init_command: nil,
         | 
| 69 | 
            +
                local_infile: nil,
         | 
| 70 | 
            +
                load_data_local_dir: nil,
         | 
| 71 | 
            +
                ssl_mode: SSL_MODE_PREFERRED,
         | 
| 72 | 
            +
                get_server_public_key: false,
         | 
| 73 | 
            +
              }.freeze
         | 
| 74 | 
            +
             | 
| 26 75 | 
             
              # @private
         | 
| 27 76 | 
             
              attr_reader :protocol
         | 
| 28 77 |  | 
| 29 | 
            -
              # @return [Boolean] if true, {#query} return {Mysql::Result}.
         | 
| 30 | 
            -
              attr_accessor :query_with_result
         | 
| 31 | 
            -
             | 
| 32 78 | 
             
              class << self
         | 
| 33 | 
            -
                # Make Mysql object without connecting.
         | 
| 34 | 
            -
                # @return [Mysql]
         | 
| 35 | 
            -
                def init
         | 
| 36 | 
            -
                  my = self.allocate
         | 
| 37 | 
            -
                  my.instance_eval{initialize}
         | 
| 38 | 
            -
                  my
         | 
| 39 | 
            -
                end
         | 
| 40 | 
            -
             | 
| 41 79 | 
             
                # Make Mysql object and connect to mysqld.
         | 
| 42 | 
            -
                #  | 
| 80 | 
            +
                # parameter is same as arguments for {#initialize}.
         | 
| 43 81 | 
             
                # @return [Mysql]
         | 
| 44 | 
            -
                def  | 
| 45 | 
            -
                   | 
| 46 | 
            -
                  my.connect(*args)
         | 
| 82 | 
            +
                def connect(*args, **opts)
         | 
| 83 | 
            +
                  self.new(*args, **opts).connect
         | 
| 47 84 | 
             
                end
         | 
| 48 85 |  | 
| 49 | 
            -
                alias real_connect new
         | 
| 50 | 
            -
                alias connect new
         | 
| 51 | 
            -
             | 
| 52 86 | 
             
                # Escape special character in string.
         | 
| 53 87 | 
             
                # @param [String] str
         | 
| 54 88 | 
             
                # @return [String]
         | 
| @@ -64,62 +98,116 @@ class Mysql | |
| 64 98 | 
             
                  end
         | 
| 65 99 | 
             
                end
         | 
| 66 100 | 
             
                alias quote escape_string
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                # @return [String] client version. This value is dummy for MySQL/Ruby compatibility.
         | 
| 69 | 
            -
                def client_info
         | 
| 70 | 
            -
                  "5.0.0"
         | 
| 71 | 
            -
                end
         | 
| 72 | 
            -
                alias get_client_info client_info
         | 
| 73 | 
            -
             | 
| 74 | 
            -
                # @return [Integer] client version. This value is dummy for MySQL/Ruby compatibility.
         | 
| 75 | 
            -
                def client_version
         | 
| 76 | 
            -
                  50000
         | 
| 77 | 
            -
                end
         | 
| 78 | 
            -
                alias get_client_version client_version
         | 
| 79 101 | 
             
              end
         | 
| 80 102 |  | 
| 81 | 
            -
               | 
| 103 | 
            +
              # @overload initialize(uri, **opts)
         | 
| 104 | 
            +
              #   @param uri [String, URI] "mysql://username:password@host:port/database?param=value&..." / "mysql://username:password@%2Ftmp%2Fmysql.sock/database" / "mysql://username:password@/database?socket=/tmp/mysql.sock"
         | 
| 105 | 
            +
              #   @param opts [Hash] options
         | 
| 106 | 
            +
              # @overload initialize(host, username, password, database, port, socket, flags, **opts)
         | 
| 107 | 
            +
              #   @param host [String] hostname mysqld running
         | 
| 108 | 
            +
              #   @param username [String] username to connect to mysqld
         | 
| 109 | 
            +
              #   @param password [String] password to connect to mysqld
         | 
| 110 | 
            +
              #   @param database [String] initial database name
         | 
| 111 | 
            +
              #   @param port [String] port number (used if host is not 'localhost' or nil)
         | 
| 112 | 
            +
              #   @param socket [String] socket filename (used if host is 'localhost' or nil)
         | 
| 113 | 
            +
              #   @param flags [Integer] connection flag. Mysql::CLIENT_* ORed
         | 
| 114 | 
            +
              #   @param opts [Hash] options
         | 
| 115 | 
            +
              # @overload initialize(host: nil, username: nil, password: nil, database: nil, port: nil, socket: nil, flags: nil, **opts)
         | 
| 116 | 
            +
              #   @param host [String] hostname mysqld running
         | 
| 117 | 
            +
              #   @param username [String] username to connect to mysqld
         | 
| 118 | 
            +
              #   @param password [String] password to connect to mysqld
         | 
| 119 | 
            +
              #   @param database [String] initial database name
         | 
| 120 | 
            +
              #   @param port [String] port number (used if host is not 'localhost' or nil)
         | 
| 121 | 
            +
              #   @param socket [String] socket filename (used if host is 'localhost' or nil)
         | 
| 122 | 
            +
              #   @param flags [Integer] connection flag. Mysql::CLIENT_* ORed
         | 
| 123 | 
            +
              #   @param opts [Hash] options
         | 
| 124 | 
            +
              #   @option opts :host [String] hostname mysqld running
         | 
| 125 | 
            +
              #   @option opts :username [String] username to connect to mysqld
         | 
| 126 | 
            +
              #   @option opts :password [String] password to connect to mysqld
         | 
| 127 | 
            +
              #   @option opts :database [String] initial database name
         | 
| 128 | 
            +
              #   @option opts :port [String] port number (used if host is not 'localhost' or nil)
         | 
| 129 | 
            +
              #   @option opts :socket [String] socket filename (used if host is 'localhost' or nil)
         | 
| 130 | 
            +
              #   @option opts :flags [Integer] connection flag. Mysql::CLIENT_* ORed
         | 
| 131 | 
            +
              #   @option opts :charset [Mysql::Charset, String] character set
         | 
| 132 | 
            +
              #   @option opts :connect_timeout [Numeric, nil]
         | 
| 133 | 
            +
              #   @option opts :read_timeout [Numeric, nil]
         | 
| 134 | 
            +
              #   @option opts :write_timeout [Numeric, nil]
         | 
| 135 | 
            +
              #   @option opts :local_infile [Boolean]
         | 
| 136 | 
            +
              #   @option opts :load_data_local_dir [String]
         | 
| 137 | 
            +
              #   @option opts :ssl_mode [Integer]
         | 
| 138 | 
            +
              #   @option opts :get_server_public_key [Boolean]
         | 
| 139 | 
            +
              def initialize(*args, **opts)
         | 
| 82 140 | 
             
                @fields = nil
         | 
| 83 141 | 
             
                @protocol = nil
         | 
| 84 | 
            -
                @charset = nil
         | 
| 85 | 
            -
                @init_command = nil
         | 
| 86 142 | 
             
                @sqlstate = "00000"
         | 
| 87 | 
            -
                @query_with_result = true
         | 
| 88 143 | 
             
                @host_info = nil
         | 
| 89 144 | 
             
                @last_error = nil
         | 
| 90 145 | 
             
                @result_exist = false
         | 
| 91 | 
            -
                @opts =  | 
| 92 | 
            -
             | 
| 93 | 
            -
                  read_timeout: nil,
         | 
| 94 | 
            -
                  write_timeout: nil,
         | 
| 95 | 
            -
                  local_infile: nil,
         | 
| 96 | 
            -
                  ssl_mode: SSL_MODE_PREFERRED,
         | 
| 97 | 
            -
                  get_server_public_key: false,
         | 
| 98 | 
            -
                }
         | 
| 146 | 
            +
                @opts = DEFAULT_OPTS.dup
         | 
| 147 | 
            +
                parse_args(args, opts)
         | 
| 99 148 | 
             
              end
         | 
| 100 149 |  | 
| 101 150 | 
             
              # Connect to mysqld.
         | 
| 102 | 
            -
              #  | 
| 103 | 
            -
              # @ | 
| 104 | 
            -
               | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
              # @param [String / nil] socket socket file name (used if host is 'localhost' or nil)
         | 
| 108 | 
            -
              # @param [Integer / nil] flag connection flag. Mysql::CLIENT_* ORed
         | 
| 109 | 
            -
              # @return self
         | 
| 110 | 
            -
              def connect(host=nil, user=nil, passwd=nil, db=nil, port=nil, socket=nil, flag=0)
         | 
| 111 | 
            -
                if flag & CLIENT_COMPRESS != 0
         | 
| 151 | 
            +
              # parameter is same as arguments for {#initialize}.
         | 
| 152 | 
            +
              # @return [Mysql] self
         | 
| 153 | 
            +
              def connect(*args, **opts)
         | 
| 154 | 
            +
                parse_args(args, opts)
         | 
| 155 | 
            +
                if @opts[:flags] & CLIENT_COMPRESS != 0
         | 
| 112 156 | 
             
                  warn 'unsupported flag: CLIENT_COMPRESS' if $VERBOSE
         | 
| 113 | 
            -
                   | 
| 157 | 
            +
                  @opts[:flags] &= ~CLIENT_COMPRESS
         | 
| 114 158 | 
             
                end
         | 
| 115 | 
            -
                @protocol = Protocol.new( | 
| 116 | 
            -
                @protocol.authenticate | 
| 117 | 
            -
                @ | 
| 118 | 
            -
                @ | 
| 119 | 
            -
                query @init_command if @init_command
         | 
| 159 | 
            +
                @protocol = Protocol.new(@opts)
         | 
| 160 | 
            +
                @protocol.authenticate
         | 
| 161 | 
            +
                @host_info = (@opts[:host].nil? || @opts[:host] == "localhost") ? 'Localhost via UNIX socket' : "#{@opts[:host]} via TCP/IP"
         | 
| 162 | 
            +
                query @opts[:init_command] if @opts[:init_command]
         | 
| 120 163 | 
             
                return self
         | 
| 121 164 | 
             
              end
         | 
| 122 | 
            -
             | 
| 165 | 
            +
             | 
| 166 | 
            +
              def parse_args(args, opts)
         | 
| 167 | 
            +
                case args[0]
         | 
| 168 | 
            +
                when URI
         | 
| 169 | 
            +
                  uri = args[0]
         | 
| 170 | 
            +
                when /\Amysql:\/\//
         | 
| 171 | 
            +
                  uri = URI.parse(args[0])
         | 
| 172 | 
            +
                when String
         | 
| 173 | 
            +
                  @opts[:host], user, passwd, dbname, port, socket, flags = *args
         | 
| 174 | 
            +
                  @opts[:username] = user if user
         | 
| 175 | 
            +
                  @opts[:password] = passwd if passwd
         | 
| 176 | 
            +
                  @opts[:database] = dbname if dbname
         | 
| 177 | 
            +
                  @opts[:port] = port if port
         | 
| 178 | 
            +
                  @opts[:socket] = socket if socket
         | 
| 179 | 
            +
                  @opts[:flags] = flags if flags
         | 
| 180 | 
            +
                when Hash
         | 
| 181 | 
            +
                  # skip
         | 
| 182 | 
            +
                when nil
         | 
| 183 | 
            +
                  # skip
         | 
| 184 | 
            +
                end
         | 
| 185 | 
            +
                if uri
         | 
| 186 | 
            +
                  host = uri.hostname.to_s
         | 
| 187 | 
            +
                  host = URI.decode_www_form_component(host)
         | 
| 188 | 
            +
                  if host.start_with?('/')
         | 
| 189 | 
            +
                    @opts[:socket] = host
         | 
| 190 | 
            +
                    host = ''
         | 
| 191 | 
            +
                  end
         | 
| 192 | 
            +
                  @opts[:host] = host
         | 
| 193 | 
            +
                  @opts[:username] = URI.decode_www_form_component(uri.user.to_s)
         | 
| 194 | 
            +
                  @opts[:password] = URI.decode_www_form_component(uri.password.to_s)
         | 
| 195 | 
            +
                  @opts[:database] = uri.path.sub(/\A\/+/, '')
         | 
| 196 | 
            +
                  @opts[:port] = uri.port
         | 
| 197 | 
            +
                  opts = URI.decode_www_form(uri.query).to_h.transform_keys(&:intern).merge(opts) if uri.query
         | 
| 198 | 
            +
                  opts[:flags] = opts[:flags].to_i if opts[:flags]
         | 
| 199 | 
            +
                end
         | 
| 200 | 
            +
                if args.last.kind_of? Hash
         | 
| 201 | 
            +
                  opts = opts.merge(args.last)
         | 
| 202 | 
            +
                end
         | 
| 203 | 
            +
                @opts.update(opts)
         | 
| 204 | 
            +
              end
         | 
| 205 | 
            +
             | 
| 206 | 
            +
              DEFAULT_OPTS.each_key do |var|
         | 
| 207 | 
            +
                next if var == :charset
         | 
| 208 | 
            +
                define_method(var){@opts[var]}
         | 
| 209 | 
            +
                define_method("#{var}="){|val| @opts[var] = val}
         | 
| 210 | 
            +
              end
         | 
| 123 211 |  | 
| 124 212 | 
             
              # Disconnect from mysql.
         | 
| 125 213 | 
             
              # @return [Mysql] self
         | 
| @@ -141,77 +229,6 @@ class Mysql | |
| 141 229 | 
             
                return self
         | 
| 142 230 | 
             
              end
         | 
| 143 231 |  | 
| 144 | 
            -
              # Set option for connection.
         | 
| 145 | 
            -
              #
         | 
| 146 | 
            -
              # Available options:
         | 
| 147 | 
            -
              #   Mysql::INIT_COMMAND, Mysql::OPT_CONNECT_TIMEOUT, Mysql::OPT_GET_SERVER_PUBLIC_KEY,
         | 
| 148 | 
            -
              #   Mysql::OPT_LOAD_DATA_LOCAL_DIR, Mysql::OPT_LOCAL_INFILE, Mysql::OPT_READ_TIMEOUT,
         | 
| 149 | 
            -
              #   Mysql::OPT_SSL_MODE, Mysql::OPT_WRITE_TIMEOUT, Mysql::SET_CHARSET_NAME
         | 
| 150 | 
            -
              # @param [Integer] opt option
         | 
| 151 | 
            -
              # @param [Integer] value option value that is depend on opt
         | 
| 152 | 
            -
              # @return [Mysql] self
         | 
| 153 | 
            -
              def options(opt, value=nil)
         | 
| 154 | 
            -
                case opt
         | 
| 155 | 
            -
            #    when Mysql::DEFAULT_AUTH
         | 
| 156 | 
            -
            #    when Mysql::ENABLE_CLEARTEXT_PLUGIN
         | 
| 157 | 
            -
                when Mysql::INIT_COMMAND
         | 
| 158 | 
            -
                  @init_command = value.to_s
         | 
| 159 | 
            -
            #    when Mysql::OPT_BIND
         | 
| 160 | 
            -
            #    when Mysql::OPT_CAN_HANDLE_EXPIRED_PASSWORDS
         | 
| 161 | 
            -
            #    when Mysql::OPT_COMPRESS
         | 
| 162 | 
            -
            #    when Mysql::OPT_COMPRESSION_ALGORITHMS
         | 
| 163 | 
            -
            #    when Mysql::OPT_CONNECT_ATTR_ADD
         | 
| 164 | 
            -
            #    when Mysql::OPT_CONNECT_ATTR_DELETE
         | 
| 165 | 
            -
            #    when Mysql::OPT_CONNECT_ATTR_RESET
         | 
| 166 | 
            -
                when Mysql::OPT_CONNECT_TIMEOUT
         | 
| 167 | 
            -
                  @opts[:connect_timeout] = value
         | 
| 168 | 
            -
                when Mysql::OPT_GET_SERVER_PUBLIC_KEY
         | 
| 169 | 
            -
                  @opts[:get_server_public_key] = value
         | 
| 170 | 
            -
                when Mysql::OPT_LOAD_DATA_LOCAL_DIR
         | 
| 171 | 
            -
                  @opts[:local_infile] = value
         | 
| 172 | 
            -
                when Mysql::OPT_LOCAL_INFILE
         | 
| 173 | 
            -
                  @opts[:local_infile] = value ? '' : nil
         | 
| 174 | 
            -
            #    when Mysql::OPT_MAX_ALLOWED_PACKET
         | 
| 175 | 
            -
            #    when Mysql::OPT_NAMED_PIPE
         | 
| 176 | 
            -
            #    when Mysql::OPT_NET_BUFFER_LENGTH
         | 
| 177 | 
            -
            #    when Mysql::OPT_OPTIONAL_RESULTSET_METADATA
         | 
| 178 | 
            -
            #    when Mysql::OPT_PROTOCOL
         | 
| 179 | 
            -
                when Mysql::OPT_READ_TIMEOUT
         | 
| 180 | 
            -
                  @opts[:read_timeout] = value
         | 
| 181 | 
            -
            #    when Mysql::OPT_RECONNECT
         | 
| 182 | 
            -
            #    when Mysql::OPT_RETRY_COUNT
         | 
| 183 | 
            -
            #    when Mysql::SET_CLIENT_IP
         | 
| 184 | 
            -
            #    when Mysql::OPT_SSL_CA
         | 
| 185 | 
            -
            #    when Mysql::OPT_SSL_CAPATH
         | 
| 186 | 
            -
            #    when Mysql::OPT_SSL_CERT
         | 
| 187 | 
            -
            #    when Mysql::OPT_SSL_CIPHER
         | 
| 188 | 
            -
            #    when Mysql::OPT_SSL_CRL
         | 
| 189 | 
            -
            #    when Mysql::OPT_SSL_CRLPATH
         | 
| 190 | 
            -
            #    when Mysql::OPT_SSL_FIPS_MODE
         | 
| 191 | 
            -
            #    when Mysql::OPT_SSL_KEY
         | 
| 192 | 
            -
                when Mysql::OPT_SSL_MODE
         | 
| 193 | 
            -
                  @opts[:ssl_mode] = value
         | 
| 194 | 
            -
            #    when Mysql::OPT_TLS_CIPHERSUITES
         | 
| 195 | 
            -
            #    when Mysql::OPT_TLS_VERSION
         | 
| 196 | 
            -
            #    when Mysql::OPT_USE_RESULT
         | 
| 197 | 
            -
                when Mysql::OPT_WRITE_TIMEOUT
         | 
| 198 | 
            -
                  @opts[:write_timeout] = value
         | 
| 199 | 
            -
            #    when Mysql::OPT_ZSTD_COMPRESSION_LEVEL
         | 
| 200 | 
            -
            #    when Mysql::PLUGIN_DIR
         | 
| 201 | 
            -
            #    when Mysql::READ_DEFAULT_FILE
         | 
| 202 | 
            -
            #    when Mysql::READ_DEFAULT_GROUP
         | 
| 203 | 
            -
            #    when Mysql::REPORT_DATA_TRUNCATION
         | 
| 204 | 
            -
            #    when Mysql::SERVER_PUBLIC_KEY
         | 
| 205 | 
            -
            #    when Mysql::SET_CHARSET_DIR
         | 
| 206 | 
            -
                when Mysql::SET_CHARSET_NAME
         | 
| 207 | 
            -
                  @charset = Charset.by_name value.to_s
         | 
| 208 | 
            -
            #    when Mysql::SHARED_MEMORY_BASE_NAME
         | 
| 209 | 
            -
                else
         | 
| 210 | 
            -
                  warn "option not implemented: #{opt}" if $VERBOSE
         | 
| 211 | 
            -
                end
         | 
| 212 | 
            -
                self
         | 
| 213 | 
            -
              end
         | 
| 214 | 
            -
             | 
| 215 232 | 
             
              # Escape special character in MySQL.
         | 
| 216 233 | 
             
              #
         | 
| 217 234 | 
             
              # @param [String] str
         | 
| @@ -221,33 +238,26 @@ class Mysql | |
| 221 238 | 
             
              end
         | 
| 222 239 | 
             
              alias quote escape_string
         | 
| 223 240 |  | 
| 224 | 
            -
              # @return [ | 
| 225 | 
            -
              def  | 
| 226 | 
            -
                 | 
| 227 | 
            -
              end
         | 
| 228 | 
            -
              alias get_client_info client_info
         | 
| 229 | 
            -
             | 
| 230 | 
            -
              # @return [Integer] client version
         | 
| 231 | 
            -
              def client_version
         | 
| 232 | 
            -
                self.class.client_version
         | 
| 241 | 
            +
              # @return [Mysql::Charset] character set of MySQL connection
         | 
| 242 | 
            +
              def charset
         | 
| 243 | 
            +
                @opts[:charset]
         | 
| 233 244 | 
             
              end
         | 
| 234 | 
            -
              alias get_client_version client_version
         | 
| 235 245 |  | 
| 236 246 | 
             
              # Set charset of MySQL connection.
         | 
| 237 | 
            -
              # @param [String  | 
| 247 | 
            +
              # @param [String, Mysql::Charset] cs
         | 
| 238 248 | 
             
              def charset=(cs)
         | 
| 239 249 | 
             
                charset = cs.is_a?(Charset) ? cs : Charset.by_name(cs)
         | 
| 240 250 | 
             
                if @protocol
         | 
| 241 251 | 
             
                  @protocol.charset = charset
         | 
| 242 252 | 
             
                  query "SET NAMES #{charset.name}"
         | 
| 243 253 | 
             
                end
         | 
| 244 | 
            -
                @charset = charset
         | 
| 254 | 
            +
                @opts[:charset] = charset
         | 
| 245 255 | 
             
                cs
         | 
| 246 256 | 
             
              end
         | 
| 247 257 |  | 
| 248 258 | 
             
              # @return [String] charset name
         | 
| 249 259 | 
             
              def character_set_name
         | 
| 250 | 
            -
                @charset.name
         | 
| 260 | 
            +
                @protocol.charset.name
         | 
| 251 261 | 
             
              end
         | 
| 252 262 |  | 
| 253 263 | 
             
              # @return [Integer] last error number
         | 
| @@ -274,27 +284,18 @@ class Mysql | |
| 274 284 | 
             
              def host_info
         | 
| 275 285 | 
             
                @host_info
         | 
| 276 286 | 
             
              end
         | 
| 277 | 
            -
              alias get_host_info host_info
         | 
| 278 | 
            -
             | 
| 279 | 
            -
              # @return [Integer] protocol version
         | 
| 280 | 
            -
              def proto_info
         | 
| 281 | 
            -
                Mysql::Protocol::VERSION
         | 
| 282 | 
            -
              end
         | 
| 283 | 
            -
              alias get_proto_info proto_info
         | 
| 284 287 |  | 
| 285 288 | 
             
              # @return [String] server version
         | 
| 286 289 | 
             
              def server_info
         | 
| 287 290 | 
             
                check_connection
         | 
| 288 291 | 
             
                @protocol.server_info
         | 
| 289 292 | 
             
              end
         | 
| 290 | 
            -
              alias get_server_info server_info
         | 
| 291 293 |  | 
| 292 294 | 
             
              # @return [Integer] server version
         | 
| 293 295 | 
             
              def server_version
         | 
| 294 296 | 
             
                check_connection
         | 
| 295 297 | 
             
                @protocol.server_version
         | 
| 296 298 | 
             
              end
         | 
| 297 | 
            -
              alias get_server_version server_version
         | 
| 298 299 |  | 
| 299 300 | 
             
              # @return [String] information for last query
         | 
| 300 301 | 
             
              def info
         | 
| @@ -325,22 +326,18 @@ class Mysql | |
| 325 326 | 
             
                self
         | 
| 326 327 | 
             
              end
         | 
| 327 328 |  | 
| 328 | 
            -
              # database list.
         | 
| 329 | 
            -
              # @param [String] db database name that may contain wild card.
         | 
| 330 | 
            -
              # @return [Array<String>] database list
         | 
| 331 | 
            -
              def list_dbs(db=nil)
         | 
| 332 | 
            -
                db &&= db.gsub(/[\\\']/){"\\#{$&}"}
         | 
| 333 | 
            -
                query(db ? "show databases like '#{db}'" : "show databases").map(&:first)
         | 
| 334 | 
            -
              end
         | 
| 335 | 
            -
             | 
| 336 329 | 
             
              # Execute query string.
         | 
| 337 | 
            -
              # @ | 
| 338 | 
            -
              # | 
| 339 | 
            -
              # | 
| 340 | 
            -
              # | 
| 341 | 
            -
              # @ | 
| 330 | 
            +
              # @overload query(str)
         | 
| 331 | 
            +
              #   @param [String] str Query.
         | 
| 332 | 
            +
              #   @return [Mysql::Result]
         | 
| 333 | 
            +
              #   @return [nil] if the query does not return result set.
         | 
| 334 | 
            +
              # @overload query(str, &block)
         | 
| 335 | 
            +
              #   @param [String] str Query.
         | 
| 336 | 
            +
              #   @yield [Mysql::Result] evaluated per query.
         | 
| 337 | 
            +
              #   @return [self]
         | 
| 342 338 | 
             
              # @example
         | 
| 343 339 | 
             
              #  my.query("select 1,NULL,'abc'").fetch  # => [1, nil, "abc"]
         | 
| 340 | 
            +
              #  my.query("select 1,NULL,'abc'"){|res| res.fetch}
         | 
| 344 341 | 
             
              def query(str, &block)
         | 
| 345 342 | 
             
                check_connection
         | 
| 346 343 | 
             
                @fields = nil
         | 
| @@ -357,20 +354,15 @@ class Mysql | |
| 357 354 | 
             
                    end
         | 
| 358 355 | 
             
                    return self
         | 
| 359 356 | 
             
                  end
         | 
| 360 | 
            -
                   | 
| 361 | 
            -
                    return @fields ? store_result : nil
         | 
| 362 | 
            -
                  else
         | 
| 363 | 
            -
                    return self
         | 
| 364 | 
            -
                  end
         | 
| 357 | 
            +
                  return @fields ? store_result : nil
         | 
| 365 358 | 
             
                rescue ServerError => e
         | 
| 366 359 | 
             
                  @last_error = e
         | 
| 367 360 | 
             
                  @sqlstate = e.sqlstate
         | 
| 368 361 | 
             
                  raise
         | 
| 369 362 | 
             
                end
         | 
| 370 363 | 
             
              end
         | 
| 371 | 
            -
              alias real_query query
         | 
| 372 364 |  | 
| 373 | 
            -
              # Get all data for last query | 
| 365 | 
            +
              # Get all data for last query.
         | 
| 374 366 | 
             
              # @return [Mysql::Result]
         | 
| 375 367 | 
             
              def store_result
         | 
| 376 368 | 
             
                check_connection
         | 
| @@ -386,12 +378,6 @@ class Mysql | |
| 386 378 | 
             
                @protocol.thread_id
         | 
| 387 379 | 
             
              end
         | 
| 388 380 |  | 
| 389 | 
            -
              # Use result of query. The result data is retrieved when you use Mysql::Result#fetch.
         | 
| 390 | 
            -
              # @return [Mysql::Result]
         | 
| 391 | 
            -
              def use_result
         | 
| 392 | 
            -
                store_result
         | 
| 393 | 
            -
              end
         | 
| 394 | 
            -
             | 
| 395 381 | 
             
              # Set server option.
         | 
| 396 382 | 
             
              # @param [Integer] opt {Mysql::OPTION_MULTI_STATEMENTS_ON} or {Mysql::OPTION_MULTI_STATEMENTS_OFF}
         | 
| 397 383 | 
             
              # @return [Mysql] self
         | 
| @@ -425,7 +411,7 @@ class Mysql | |
| 425 411 | 
             
              # @param [String] str query string
         | 
| 426 412 | 
             
              # @return [Mysql::Stmt] Prepared-statement object
         | 
| 427 413 | 
             
              def prepare(str)
         | 
| 428 | 
            -
                st = Stmt.new @protocol | 
| 414 | 
            +
                st = Stmt.new @protocol
         | 
| 429 415 | 
             
                st.prepare str
         | 
| 430 416 | 
             
                st
         | 
| 431 417 | 
             
              end
         | 
| @@ -433,40 +419,8 @@ class Mysql | |
| 433 419 | 
             
              # @private
         | 
| 434 420 | 
             
              # Make empty prepared-statement object.
         | 
| 435 421 | 
             
              # @return [Mysql::Stmt] If block is not specified.
         | 
| 436 | 
            -
              def  | 
| 437 | 
            -
                Stmt.new @protocol | 
| 438 | 
            -
              end
         | 
| 439 | 
            -
             | 
| 440 | 
            -
              # Returns Mysql::Result object that is empty.
         | 
| 441 | 
            -
              # Use fetch_fields to get list of fields.
         | 
| 442 | 
            -
              # @param [String] table table name.
         | 
| 443 | 
            -
              # @param [String] field field name that may contain wild card.
         | 
| 444 | 
            -
              # @return [Mysql::Result]
         | 
| 445 | 
            -
              def list_fields(table, field=nil)
         | 
| 446 | 
            -
                check_connection
         | 
| 447 | 
            -
                begin
         | 
| 448 | 
            -
                  fields = @protocol.field_list_command table, field
         | 
| 449 | 
            -
                  return Result.new fields
         | 
| 450 | 
            -
                rescue ServerError => e
         | 
| 451 | 
            -
                  @last_error = e
         | 
| 452 | 
            -
                  @sqlstate = e.sqlstate
         | 
| 453 | 
            -
                  raise
         | 
| 454 | 
            -
                end
         | 
| 455 | 
            -
              end
         | 
| 456 | 
            -
             | 
| 457 | 
            -
              # @return [Mysql::Result] containing process list
         | 
| 458 | 
            -
              def list_processes
         | 
| 459 | 
            -
                check_connection
         | 
| 460 | 
            -
                @fields = @protocol.process_info_command
         | 
| 461 | 
            -
                @result_exist = true
         | 
| 462 | 
            -
                store_result
         | 
| 463 | 
            -
              end
         | 
| 464 | 
            -
             | 
| 465 | 
            -
              # @param [String] table database name that may contain wild card.
         | 
| 466 | 
            -
              # @return [Array<String>] list of table name.
         | 
| 467 | 
            -
              def list_tables(table=nil)
         | 
| 468 | 
            -
                q = table ? "show tables like '#{quote table}'" : "show tables"
         | 
| 469 | 
            -
                query(q).map(&:first)
         | 
| 422 | 
            +
              def stmt
         | 
| 423 | 
            +
                Stmt.new @protocol
         | 
| 470 424 | 
             
              end
         | 
| 471 425 |  | 
| 472 426 | 
             
              # Check whether the  connection is available.
         | 
| @@ -579,7 +533,7 @@ class Mysql | |
| 579 533 | 
             
                end
         | 
| 580 534 |  | 
| 581 535 | 
             
                # @return [Hash] field information
         | 
| 582 | 
            -
                def  | 
| 536 | 
            +
                def to_hash
         | 
| 583 537 | 
             
                  {
         | 
| 584 538 | 
             
                    "name"       => @name,
         | 
| 585 539 | 
             
                    "table"      => @table,
         | 
| @@ -815,10 +769,9 @@ class Mysql | |
| 815 769 | 
             
                # @private
         | 
| 816 770 | 
             
                # @param [Array<Mysql::Field>] fields
         | 
| 817 771 | 
             
                # @param [Mysql::Protocol] protocol
         | 
| 818 | 
            -
                 | 
| 819 | 
            -
                def initialize(fields, protocol, charset)
         | 
| 772 | 
            +
                def initialize(fields, protocol)
         | 
| 820 773 | 
             
                  super fields
         | 
| 821 | 
            -
                  @records = protocol.stmt_retr_all_records @fields, charset
         | 
| 774 | 
            +
                  @records = protocol.stmt_retr_all_records @fields, protocol.charset
         | 
| 822 775 | 
             
                end
         | 
| 823 776 | 
             
              end
         | 
| 824 777 |  | 
| @@ -853,15 +806,12 @@ class Mysql | |
| 853 806 |  | 
| 854 807 | 
             
                # @private
         | 
| 855 808 | 
             
                # @param [Mysql::Protocol] protocol
         | 
| 856 | 
            -
                 | 
| 857 | 
            -
                def initialize(protocol, charset)
         | 
| 809 | 
            +
                def initialize(protocol)
         | 
| 858 810 | 
             
                  @protocol = protocol
         | 
| 859 | 
            -
                  @charset = charset
         | 
| 860 811 | 
             
                  @statement_id = nil
         | 
| 861 812 | 
             
                  @affected_rows = @insert_id = @server_status = @warning_count = 0
         | 
| 862 813 | 
             
                  @sqlstate = "00000"
         | 
| 863 814 | 
             
                  @param_count = nil
         | 
| 864 | 
            -
                  @bind_result = nil
         | 
| 865 815 | 
             
                end
         | 
| 866 816 |  | 
| 867 817 | 
             
                # @private
         | 
| @@ -888,13 +838,13 @@ class Mysql | |
| 888 838 | 
             
                def execute(*values)
         | 
| 889 839 | 
             
                  raise ClientError, "not prepared" unless @param_count
         | 
| 890 840 | 
             
                  raise ClientError, "parameter count mismatch" if values.length != @param_count
         | 
| 891 | 
            -
                  values = values.map{|v| @charset.convert v}
         | 
| 841 | 
            +
                  values = values.map{|v| @protocol.charset.convert v}
         | 
| 892 842 | 
             
                  begin
         | 
| 893 843 | 
             
                    @sqlstate = "00000"
         | 
| 894 844 | 
             
                    nfields = @protocol.stmt_execute_command @statement_id, values
         | 
| 895 845 | 
             
                    if nfields
         | 
| 896 846 | 
             
                      @fields = @protocol.retr_fields nfields
         | 
| 897 | 
            -
                      @result = StatementResult.new @fields, @protocol | 
| 847 | 
            +
                      @result = StatementResult.new @fields, @protocol
         | 
| 898 848 | 
             
                    else
         | 
| 899 849 | 
             
                      @affected_rows, @insert_id, @server_status, @warning_count, @info =
         | 
| 900 850 | 
             
                        @protocol.affected_rows, @protocol.insert_id, @protocol.server_status, @protocol.warning_count, @protocol.message
         | 
| @@ -917,46 +867,7 @@ class Mysql | |
| 917 867 |  | 
| 918 868 | 
             
                # @return [Array] current record data
         | 
| 919 869 | 
             
                def fetch
         | 
| 920 | 
            -
                   | 
| 921 | 
            -
                  return row unless @bind_result
         | 
| 922 | 
            -
                  row.zip(@bind_result).map do |col, type|
         | 
| 923 | 
            -
                    if col.nil?
         | 
| 924 | 
            -
                      nil
         | 
| 925 | 
            -
                    elsif [Numeric, Integer].include? type
         | 
| 926 | 
            -
                      col.to_i
         | 
| 927 | 
            -
                    elsif type == String
         | 
| 928 | 
            -
                      col.to_s
         | 
| 929 | 
            -
                    elsif type == Float && !col.is_a?(Float)
         | 
| 930 | 
            -
                      col.to_i.to_f
         | 
| 931 | 
            -
                    elsif type == Mysql::Time && !col.is_a?(Mysql::Time)
         | 
| 932 | 
            -
                      if col.to_s =~ /\A\d+\z/
         | 
| 933 | 
            -
                        i = col.to_s.to_i
         | 
| 934 | 
            -
                        if i < 100000000
         | 
| 935 | 
            -
                          y = i/10000
         | 
| 936 | 
            -
                          m = i/100%100
         | 
| 937 | 
            -
                          d = i%100
         | 
| 938 | 
            -
                          h, mm, s = 0
         | 
| 939 | 
            -
                        else
         | 
| 940 | 
            -
                          y = i/10000000000
         | 
| 941 | 
            -
                          m = i/100000000%100
         | 
| 942 | 
            -
                          d = i/1000000%100
         | 
| 943 | 
            -
                          h = i/10000%100
         | 
| 944 | 
            -
                          mm= i/100%100
         | 
| 945 | 
            -
                          s = i%100
         | 
| 946 | 
            -
                        end
         | 
| 947 | 
            -
                        if y < 70
         | 
| 948 | 
            -
                          y += 2000
         | 
| 949 | 
            -
                        elsif y < 100
         | 
| 950 | 
            -
                          y += 1900
         | 
| 951 | 
            -
                        end
         | 
| 952 | 
            -
                        Mysql::Time.new(y, m, d, h, mm, s)
         | 
| 953 | 
            -
                      else
         | 
| 954 | 
            -
                        Mysql::Time.new
         | 
| 955 | 
            -
                      end
         | 
| 956 | 
            -
                    else
         | 
| 957 | 
            -
                      col
         | 
| 958 | 
            -
                    end
         | 
| 959 | 
            -
                  end
         | 
| 870 | 
            +
                  @result.fetch
         | 
| 960 871 | 
             
                end
         | 
| 961 872 |  | 
| 962 873 | 
             
                # Return data of current record as Hash.
         | 
| @@ -967,20 +878,6 @@ class Mysql | |
| 967 878 | 
             
                  @result.fetch_hash with_table
         | 
| 968 879 | 
             
                end
         | 
| 969 880 |  | 
| 970 | 
            -
                # Set retrieve type of value
         | 
| 971 | 
            -
                # @param [Numeric / Fixnum / Integer / Float / String / Mysql::Time / nil] args value type
         | 
| 972 | 
            -
                # @return [Mysql::Stmt] self
         | 
| 973 | 
            -
                def bind_result(*args)
         | 
| 974 | 
            -
                  if @fields.length != args.length
         | 
| 975 | 
            -
                    raise ClientError, "bind_result: result value count(#{@fields.length}) != number of argument(#{args.length})"
         | 
| 976 | 
            -
                  end
         | 
| 977 | 
            -
                  args.each do |a|
         | 
| 978 | 
            -
                    raise TypeError unless [Numeric, Integer, Float, String, Mysql::Time, nil].include? a
         | 
| 979 | 
            -
                  end
         | 
| 980 | 
            -
                  @bind_result = args
         | 
| 981 | 
            -
                  self
         | 
| 982 | 
            -
                end
         | 
| 983 | 
            -
             | 
| 984 881 | 
             
                # Iterate block with record.
         | 
| 985 882 | 
             
                # @yield [Array] record data
         | 
| 986 883 | 
             
                # @return [Mysql::Stmt] self
         | 
| @@ -1049,78 +946,4 @@ class Mysql | |
| 1049 946 | 
             
                  Result.new @fields
         | 
| 1050 947 | 
             
                end
         | 
| 1051 948 | 
             
              end
         | 
| 1052 | 
            -
             | 
| 1053 | 
            -
              # @!visibility public
         | 
| 1054 | 
            -
              # @!attribute [rw] year
         | 
| 1055 | 
            -
              #   @return [Integer]
         | 
| 1056 | 
            -
              # @!attribute [rw] month
         | 
| 1057 | 
            -
              #   @return [Integer]
         | 
| 1058 | 
            -
              # @!attribute [rw] day
         | 
| 1059 | 
            -
              #   @return [Integer]
         | 
| 1060 | 
            -
              # @!attribute [rw] hour
         | 
| 1061 | 
            -
              #   @return [Integer]
         | 
| 1062 | 
            -
              # @!attribute [rw] minute
         | 
| 1063 | 
            -
              #   @return [Integer]
         | 
| 1064 | 
            -
              # @!attribute [rw] second
         | 
| 1065 | 
            -
              #   @return [Integer]
         | 
| 1066 | 
            -
              # @!attribute [rw] neg
         | 
| 1067 | 
            -
              #   @return [Boolean] negative flag
         | 
| 1068 | 
            -
              # @!attribute [rw] second_part
         | 
| 1069 | 
            -
              #   @return [Integer]
         | 
| 1070 | 
            -
              class Time
         | 
| 1071 | 
            -
                # @param [Integer] year
         | 
| 1072 | 
            -
                # @param [Integer] month
         | 
| 1073 | 
            -
                # @param [Integer] day
         | 
| 1074 | 
            -
                # @param [Integer] hour
         | 
| 1075 | 
            -
                # @param [Integer] minute
         | 
| 1076 | 
            -
                # @param [Integer] second
         | 
| 1077 | 
            -
                # @param [Boolean] neg negative flag
         | 
| 1078 | 
            -
                # @param [Integer] second_part
         | 
| 1079 | 
            -
                def initialize(year=0, month=0, day=0, hour=0, minute=0, second=0, neg=false, second_part=0)
         | 
| 1080 | 
            -
                  @date_flag = !(hour && minute && second)
         | 
| 1081 | 
            -
                  @year, @month, @day, @hour, @minute, @second, @neg, @second_part =
         | 
| 1082 | 
            -
                    year.to_i, month.to_i, day.to_i, hour.to_i, minute.to_i, second.to_i, neg, second_part.to_i
         | 
| 1083 | 
            -
                end
         | 
| 1084 | 
            -
                attr_accessor :year, :month, :day, :hour, :minute, :second, :neg, :second_part
         | 
| 1085 | 
            -
                alias mon month
         | 
| 1086 | 
            -
                alias min minute
         | 
| 1087 | 
            -
                alias sec second
         | 
| 1088 | 
            -
             | 
| 1089 | 
            -
                # @private
         | 
| 1090 | 
            -
                def ==(other)
         | 
| 1091 | 
            -
                  other.is_a?(Mysql::Time) &&
         | 
| 1092 | 
            -
                    @year == other.year && @month == other.month && @day == other.day &&
         | 
| 1093 | 
            -
                    @hour == other.hour && @minute == other.minute && @second == other.second &&
         | 
| 1094 | 
            -
                    @neg == neg && @second_part == other.second_part
         | 
| 1095 | 
            -
                end
         | 
| 1096 | 
            -
             | 
| 1097 | 
            -
                # @private
         | 
| 1098 | 
            -
                def eql?(other)
         | 
| 1099 | 
            -
                  self == other
         | 
| 1100 | 
            -
                end
         | 
| 1101 | 
            -
             | 
| 1102 | 
            -
                # @return [String] "yyyy-mm-dd HH:MM:SS"
         | 
| 1103 | 
            -
                def to_s
         | 
| 1104 | 
            -
                  if @date_flag
         | 
| 1105 | 
            -
                    sprintf "%04d-%02d-%02d", year, mon, day
         | 
| 1106 | 
            -
                  elsif year == 0 and mon == 0 and day == 0
         | 
| 1107 | 
            -
                    h = neg ? hour * -1 : hour
         | 
| 1108 | 
            -
                    sprintf "%02d:%02d:%02d", h, min, sec
         | 
| 1109 | 
            -
                  else
         | 
| 1110 | 
            -
                    sprintf "%04d-%02d-%02d %02d:%02d:%02d", year, mon, day, hour, min, sec
         | 
| 1111 | 
            -
                  end
         | 
| 1112 | 
            -
                end
         | 
| 1113 | 
            -
             | 
| 1114 | 
            -
                # @return [Integer] yyyymmddHHMMSS
         | 
| 1115 | 
            -
                def to_i
         | 
| 1116 | 
            -
                  sprintf("%04d%02d%02d%02d%02d%02d", year, mon, day, hour, min, sec).to_i
         | 
| 1117 | 
            -
                end
         | 
| 1118 | 
            -
             | 
| 1119 | 
            -
                # @private
         | 
| 1120 | 
            -
                def inspect
         | 
| 1121 | 
            -
                  sprintf "#<#{self.class.name}:%04d-%02d-%02d %02d:%02d:%02d>", year, mon, day, hour, min, sec
         | 
| 1122 | 
            -
                end
         | 
| 1123 | 
            -
             | 
| 1124 | 
            -
              end
         | 
| 1125 | 
            -
             | 
| 1126 949 | 
             
            end
         |