Class: DB::MariaDB::Native::Connection

Inherits:
FFI::Pointer
  • Object
show all
Defined in:
lib/db/mariadb/native/connection.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(address, io, types) ⇒ Connection

Returns a new instance of Connection.



103
104
105
106
107
108
109
110
# File 'lib/db/mariadb/native/connection.rb', line 103

def initialize(address, io, types)
  super(address)
  
  @io = io
  @result = nil
  
  @types = types
end

Class Method Details

.connect(io: IO, host: 'localhost', user: nil, password: nil, database: nil, port: 0, unix_socket: nil, client_flags: 0, compression: false, types: DEFAULT_TYPES, **options) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/db/mariadb/native/connection.rb', line 66

def self.connect(io: IO, host: 'localhost', user: nil, password: nil, database: nil, port: 0, unix_socket: nil, client_flags: 0, compression: false, types: DEFAULT_TYPES, **options)
  pointer = Native.mysql_init(nil)
  Native.mysql_options(pointer, MYSQL_OPT_NONBLOCK, nil)
  
  client_flags |= CLIENT_MULTI_STATEMENT | CLIENT_MULTI_RESULTS
  
  if compression
    client_flags |= CLIENT_COMPRESSION
  end
  
  result = FFI::MemoryPointer.new(:pointer)
  
  status = Native.mysql_real_connect_start(result, pointer, host, user, password, database, port, unix_socket, client_flags);
  
  if status > 0
    io = IO.new(Native.mysql_get_socket(pointer), "r+")
    
    while status > 0
      if status & MYSQL_WAIT_READ
        io.wait_readable
      elsif status & MYSQL_WAIT_WRITE
        io.wait_writable
      else
        io.wait_any
      end
      
      status = Native.mysql_real_connect_cont(result, pointer, status)
    end
  end
  
  if result.read_pointer.null?
    raise "Could not connect: #{Native.mysql_error(pointer)}!"
  end
  
  return self.new(pointer, io, types, **options)
end

Instance Method Details

#affected_rowsObject



196
197
198
# File 'lib/db/mariadb/native/connection.rb', line 196

def affected_rows
  Native.mysql_affected_rows(self)
end

#check_error!(message) ⇒ Object



120
121
122
123
124
# File 'lib/db/mariadb/native/connection.rb', line 120

def check_error!(message)
  if Native.mysql_errno(self) != 0
    raise "#{message}: #{Native.mysql_error(self)}!"
  end
end

#closeObject



138
139
140
141
142
143
144
# File 'lib/db/mariadb/native/connection.rb', line 138

def close
  self.free_result
  
  Native.mysql_close(self)
  
  @io.close
end

#escape(value) ⇒ Object



146
147
148
149
150
151
152
153
154
155
# File 'lib/db/mariadb/native/connection.rb', line 146

def escape(value)
  value = value.to_s
  
  maximum_length = value.bytesize * 2 + 1
  out = FFI::MemoryPointer.new(:char, maximum_length)
  
  Native.mysql_real_escape_string(self, out, value, value.bytesize)
  
  return out.read_string
end

#free_resultObject



130
131
132
133
134
135
136
# File 'lib/db/mariadb/native/connection.rb', line 130

def free_result
  if @result
    Native.mysql_free_result(@result)
    
    @result = nil
  end
end

#infoObject



204
205
206
# File 'lib/db/mariadb/native/connection.rb', line 204

def info
  Native.mysql_info(self)
end

#insert_idObject



200
201
202
# File 'lib/db/mariadb/native/connection.rb', line 200

def insert_id
  Native.mysql_insert_id(self)
end

#next_result(types: @types) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/db/mariadb/native/connection.rb', line 175

def next_result(types: @types)
  if @result
    self.free_result
    
    # Successful and there are no more results:
    return if Native.mysql_next_result(self) == -1
    
    check_error!("Next result")
  end
  
  @result = Native.mysql_use_result(self)
  
  if @result.null?
    check_error!("Next result")
    
    return nil
  else
    return Result.new(self, types, @result)
  end
end

#send_query(statement) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/db/mariadb/native/connection.rb', line 157

def send_query(statement)
  self.free_result
  
  error = FFI::MemoryPointer.new(:int)
  
  status = Native.mysql_real_query_start(error, self, statement, statement.bytesize)
  
  while status != 0
    self.wait_for(status)
    
    status = Native.mysql_real_query_cont(error, self, status)
  end
  
  if error.read_int != 0
    raise "Could not send query: #{Native.mysql_error(self)}!"
  end
end

#statusObject



126
127
128
# File 'lib/db/mariadb/native/connection.rb', line 126

def status
  Native.mysql_stat(self)
end

#wait_for(status) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/db/mariadb/native/connection.rb', line 112

def wait_for(status)
  if status & MYSQL_WAIT_READ
    @io.wait_readable
  elsif status & MYSQL_WAIT_WRITE
    @io.wait_writable
  end
end