Class: Exwiw::Adapter::MysqlClient
- Inherits:
-
Object
- Object
- Exwiw::Adapter::MysqlClient
- Defined in:
- lib/exwiw/adapter/mysql_client.rb
Overview
Thin wrapper over the MySQL driver so MysqlAdapter does not care whether the host app ships the ‘mysql2` gem or the `trilogy` gem. exwiw only runs simple SELECT / EXPLAIN queries, so both drivers are normalized to the same shape: rows as arrays of String|nil plus the column names.
Values are normalized to strings to match mysql2’s ‘cast: false` mode, where every column comes back as a raw string and is quoted uniformly downstream (see MysqlAdapter#escape_value). mysql2 already returns strings in that mode; trilogy always casts to Ruby types (Integer / BigDecimal / Time / Date / …), so its values are stringified back into the same literal form here.
Defined Under Namespace
Classes: Result
Instance Attribute Summary collapse
-
#driver ⇒ Object
readonly
Returns the value of attribute driver.
Class Method Summary collapse
-
.detect_driver ⇒ Object
Pick the available driver, preferring mysql2 (exwiw’s historical default).
-
.stringify_value(value) ⇒ Object
Render a driver-returned value as the raw string mysql2’s ‘cast: false` would have produced, so trilogy’s typed values quote identically.
Instance Method Summary collapse
-
#initialize(connection_config, driver: nil) ⇒ MysqlClient
constructor
‘driver:` is mainly a test seam to force a specific driver; in normal use it is auto-detected.
-
#query(sql) ⇒ Result
Fields (Array<String>) and rows (Array<Array<String|nil>>).
Constructor Details
#initialize(connection_config, driver: nil) ⇒ MysqlClient
‘driver:` is mainly a test seam to force a specific driver; in normal use it is auto-detected.
65 66 67 68 69 |
# File 'lib/exwiw/adapter/mysql_client.rb', line 65 def initialize(connection_config, driver: nil) @connection_config = connection_config @driver = (driver || self.class.detect_driver).to_sym ensure_driver_loaded! end |
Instance Attribute Details
#driver ⇒ Object (readonly)
Returns the value of attribute driver.
61 62 63 |
# File 'lib/exwiw/adapter/mysql_client.rb', line 61 def driver @driver end |
Class Method Details
.detect_driver ⇒ Object
Pick the available driver, preferring mysql2 (exwiw’s historical default). require returns false when already loaded, so this is safe to call repeatedly.
23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/exwiw/adapter/mysql_client.rb', line 23 def self.detect_driver require 'mysql2' :mysql2 rescue LoadError begin require 'trilogy' :trilogy rescue LoadError raise LoadError, "exwiw needs the 'mysql2' or 'trilogy' gem to connect to MySQL. " \ "Add `gem \"mysql2\"` (or `gem \"trilogy\"`) to your Gemfile." end end |
.stringify_value(value) ⇒ Object
Render a driver-returned value as the raw string mysql2’s ‘cast: false` would have produced, so trilogy’s typed values quote identically.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/exwiw/adapter/mysql_client.rb', line 39 def self.stringify_value(value) case value when nil then nil when String then value when Time # Emit fractional seconds only when present. A Time can't tell us the # column's declared precision, so a zero fraction on a DATETIME(6) # column comes out as "...:00" here whereas mysql2's `cast: false` # echoes the raw "...:00.000000"; both re-insert to the same instant. value.nsec.zero? ? value.strftime('%Y-%m-%d %H:%M:%S') : value.strftime('%Y-%m-%d %H:%M:%S.%6N') when Date then value.strftime('%Y-%m-%d') when true then '1' when false then '0' else if defined?(BigDecimal) && value.is_a?(BigDecimal) value.to_s('F') else value.to_s end end end |
Instance Method Details
#query(sql) ⇒ Result
Returns fields (Array<String>) and rows (Array<Array<String|nil>>).
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/exwiw/adapter/mysql_client.rb', line 73 def query(sql) case @driver when :mysql2 res = raw.query(sql, cast: false, as: :array) Result.new(res.fields, res.to_a) when :trilogy res = raw.query(sql) rows = res.rows.map { |row| row.map { |value| self.class.stringify_value(value) } } Result.new(res.fields, rows) else raise "Unsupported MySQL driver: #{@driver.inspect}" end end |