Class: Baza::Driver::Mysql2

Inherits:
MysqlBaseDriver show all
Defined in:
lib/baza/drivers/mysql2.rb

Defined Under Namespace

Classes: Column, Columns, Database, Databases, Index, Indexes, Result, Table, Tables

Instance Attribute Summary collapse

Attributes inherited from BaseSqlDriver

#baza, #cols, #indexes, #sep_col, #sep_table, #sep_val, #tables

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from MysqlBaseDriver

args, #insert_multi, #transaction

Methods inherited from BaseSqlDriver

#escape_column, #insert, #insert_multi, #supports_multiple_databases?, #transaction

Constructor Details

#initialize(baza) ⇒ Mysql2

Returns a new instance of Mysql2.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/baza/drivers/mysql2.rb', line 38

def initialize(baza)
  super

  @opts = @baza.opts

  require "monitor"
  @mutex = Monitor.new

  if @opts[:encoding]
    @encoding = @opts[:encoding]
  else
    @encoding = "utf8"
  end

  if @baza.opts.key?(:port)
    @port = @baza.opts[:port].to_i
  else
    @port = 3306
  end

  reconnect
end

Instance Attribute Details

#connObject (readonly)

Returns the value of attribute conn.



18
19
20
# File 'lib/baza/drivers/mysql2.rb', line 18

def conn
  @conn
end

#connsObject (readonly)

Returns the value of attribute conns.



18
19
20
# File 'lib/baza/drivers/mysql2.rb', line 18

def conns
  @conns
end

Class Method Details

.from_object(args) ⇒ Object

Helper to enable automatic registering of database using Baza::Db.from_object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/baza/drivers/mysql2.rb', line 21

def self.from_object(args)
  if args[:object].class.name == "Mysql2::Client"
    return {
      type: :success,
      args: {
        type: :mysql2,
        conn: args[:object],
        query_args: {
          symbolize_keys: true
        }
      }
    }
  end

  nil
end

Instance Method Details

#cleanObject

Cleans the wref-map holding the tables.



62
63
64
# File 'lib/baza/drivers/mysql2.rb', line 62

def clean
  tables.clean if tables
end

#closeObject

Closes the connection threadsafe.



161
162
163
# File 'lib/baza/drivers/mysql2.rb', line 161

def close
  @mutex.synchronize { @conn.close }
end

#destroyObject

Destroyes the connection.



166
167
168
169
170
171
172
173
# File 'lib/baza/drivers/mysql2.rb', line 166

def destroy
  @conn = nil
  @baza = nil
  @mutex = nil
  @encoding = nil
  @query_args = nil
  @port = nil
end

#escape(string) ⇒ Object

Escapes a string to be safe to use in a query.



151
152
153
# File 'lib/baza/drivers/mysql2.rb', line 151

def escape(string)
  @conn.escape(string.to_s)
end

#last_idObject

Returns the last inserted ID for the connection.



156
157
158
# File 'lib/baza/drivers/mysql2.rb', line 156

def last_id
  @mutex.synchronize { return @conn.last_id.to_i }
end

#query(str) ⇒ Object

Executes a query and returns the result.



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/baza/drivers/mysql2.rb', line 117

def query(str)
  str = str.to_s
  str = str.force_encoding("UTF-8") if @encoding == "utf8" && str.respond_to?(:force_encoding)
  tries = 0

  begin
    tries += 1
    @mutex.synchronize do
      return Baza::Driver::Mysql2::Result.new(self, @conn.query(str, @query_args))
    end
  rescue => e
    if tries <= 3
      if e.message == "MySQL server has gone away" || e.message == "closed MySQL connection" || e.message == "Can't connect to local MySQL server through socket"
        sleep 0.5
        reconnect
        retry
      elsif e.message.include?("No operations allowed after connection closed") || e.message == "This connection is still waiting for a result, try again once you have the result" || e.message == "Lock wait timeout exceeded; try restarting transaction"
        reconnect
        retry
      end
    end

    raise e
  end
end

#query_ubuf(str, _args = nil, &_blk) ⇒ Object

Executes an unbuffered query and returns the result that can be used to access the data.



144
145
146
147
148
# File 'lib/baza/drivers/mysql2.rb', line 144

def query_ubuf(str, _args = nil, &_blk)
  @mutex.synchronize do
    return Baza::Driver::Mysql2::Result.new(self, @conn.query(str, @query_args.merge(stream: true)))
  end
end

#reconnectObject

Respawns the connection to the MySQL-database.



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
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/baza/drivers/mysql2.rb', line 67

def reconnect
  @mutex.synchronize do
    args = {
      host: @baza.opts[:host],
      username: @baza.opts[:user],
      password: @baza.opts[:pass],
      database: @baza.opts[:db],
      port: @port,
      symbolize_keys: true,
      cache_rows: false
    }

    # Symbolize keys should also be given here, else table-data wont be symbolized for some reason - knj.
    @query_args = {symbolize_keys: true}
    @query_args[:cast] = false unless @baza.opts[:type_translation]
    @query_args.merge!(@baza.opts[:query_args]) if @baza.opts[:query_args]

    pos_args = [:as, :async, :cast_booleans, :database_timezone, :application_timezone, :cache_rows, :connect_flags, :cast]
    pos_args.each do |key|
      args[key] = @baza.opts[key] if @baza.opts.key?(key)
    end

    args[:as] = :array

    tries = 0
    begin
      tries += 1
      if @baza.opts[:conn]
        @conn = @baza.opts[:conn]
      else
        require "mysql2"
        @conn = Mysql2::Client.new(args)
      end
    rescue => e
      if tries <= 3
        if e.message == "Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (111)"
          sleep 1
          tries += 1
          retry
        end
      end

      raise e
    end

    query("SET NAMES '#{esc(@encoding)}'") if @encoding
  end
end