add initial ActiveRecord driver
This commit is contained in:
parent
288ed22806
commit
1c9e94f7e9
|
@ -0,0 +1,160 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
require 'mysql2' unless defined? Mysql2
|
||||||
|
require 'active_record/connection_adapters/mysql_adapter'
|
||||||
|
|
||||||
|
module ActiveRecord
|
||||||
|
class Base
|
||||||
|
def self.mysql2_connection(config)
|
||||||
|
client = Mysql2::Client.new(config.symbolize_keys)
|
||||||
|
options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
|
||||||
|
ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ConnectionAdapters
|
||||||
|
class Mysql2Column < MysqlColumn
|
||||||
|
# Returns the Ruby class that corresponds to the abstract data type.
|
||||||
|
def klass
|
||||||
|
case type
|
||||||
|
when :integer then Fixnum
|
||||||
|
when :float then Float
|
||||||
|
when :decimal then BigDecimal
|
||||||
|
when :datetime then Time
|
||||||
|
when :date then Time
|
||||||
|
when :timestamp then Time
|
||||||
|
when :time then Time
|
||||||
|
when :text, :string then String
|
||||||
|
when :binary then String
|
||||||
|
when :boolean then Object
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_cast(value)
|
||||||
|
if type == :boolean
|
||||||
|
self.class.value_to_boolean(value)
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_cast_code(var_name)
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Mysql2Adapter < MysqlAdapter
|
||||||
|
PRIMARY = "PRIMARY".freeze
|
||||||
|
|
||||||
|
# QUOTING ==================================================
|
||||||
|
def quote_string(string)
|
||||||
|
@connection.escape(string)
|
||||||
|
end
|
||||||
|
|
||||||
|
# CONNECTION MANAGEMENT ====================================
|
||||||
|
|
||||||
|
def active?
|
||||||
|
@connection.query 'select 1'
|
||||||
|
true
|
||||||
|
rescue Mysql2::Error
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def reconnect!
|
||||||
|
reset!
|
||||||
|
end
|
||||||
|
|
||||||
|
def disconnect!
|
||||||
|
@connection = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def reset!
|
||||||
|
@connection = Mysql2::Client.new(@config)
|
||||||
|
end
|
||||||
|
|
||||||
|
# DATABASE STATEMENTS ======================================
|
||||||
|
|
||||||
|
def select_values(sql, name = nil)
|
||||||
|
result = select_rows(sql, name)
|
||||||
|
result.map { |row| row.values.first }
|
||||||
|
end
|
||||||
|
|
||||||
|
def select_rows(sql, name = nil)
|
||||||
|
select(sql, name)
|
||||||
|
end
|
||||||
|
|
||||||
|
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
||||||
|
super sql, name
|
||||||
|
id_value || @connection.last_id
|
||||||
|
end
|
||||||
|
alias :create :insert_sql
|
||||||
|
|
||||||
|
# SCHEMA STATEMENTS ========================================
|
||||||
|
|
||||||
|
def tables(name = nil)
|
||||||
|
tables = []
|
||||||
|
execute("SHOW TABLES", name).each(:symbolize_keys => true) do |field|
|
||||||
|
tables << field.values.first
|
||||||
|
end
|
||||||
|
tables
|
||||||
|
end
|
||||||
|
|
||||||
|
def indexes(table_name, name = nil)
|
||||||
|
indexes = []
|
||||||
|
current_index = nil
|
||||||
|
result = execute("SHOW KEYS FROM #{quote_table_name(table_name)}", name)
|
||||||
|
result.each(:symbolize_keys => true) do |row|
|
||||||
|
if current_index != row[:Key_name]
|
||||||
|
next if row[:Key_name] == PRIMARY # skip the primary key
|
||||||
|
current_index = row[:Key_name]
|
||||||
|
indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, [])
|
||||||
|
end
|
||||||
|
|
||||||
|
indexes.last.columns << row[:Column_name]
|
||||||
|
end
|
||||||
|
indexes
|
||||||
|
end
|
||||||
|
|
||||||
|
def columns(table_name, name = nil)
|
||||||
|
sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
|
||||||
|
columns = []
|
||||||
|
result = execute(sql, :skip_logging)
|
||||||
|
result.each(:symbolize_keys => true) { |field|
|
||||||
|
columns << Mysql2Column.new(field[:Field], field[:Default], field[:Type], field[:Null] == "YES")
|
||||||
|
}
|
||||||
|
columns
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_variable(name)
|
||||||
|
variables = select_all("SHOW VARIABLES LIKE '#{name}'")
|
||||||
|
variables.first[:Value] unless variables.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def pk_and_sequence_for(table)
|
||||||
|
keys = []
|
||||||
|
result = execute("describe #{quote_table_name(table)}")
|
||||||
|
result.each(:symbolize_keys) do |row|
|
||||||
|
keys << row[:Field] if row[:Key] == "PRI"
|
||||||
|
end
|
||||||
|
keys.length == 1 ? [keys.first, nil] : nil
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def connect
|
||||||
|
# no-op
|
||||||
|
end
|
||||||
|
|
||||||
|
def select(sql, name = nil)
|
||||||
|
execute(sql, name).to_a
|
||||||
|
end
|
||||||
|
|
||||||
|
def supports_views?
|
||||||
|
version[0] >= 5
|
||||||
|
end
|
||||||
|
|
||||||
|
def version
|
||||||
|
@version ||= @connection.info[:version].scan(/^(\d+)\.(\d+)\.(\d+)/).flatten.map { |v| v.to_i }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
# encoding: UTF-8
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper.rb')
|
||||||
|
require 'active_record'
|
||||||
|
require 'active_record/connection_adapters/mysql2_adapter'
|
||||||
|
|
||||||
|
describe ActiveRecord::ConnectionAdapters::Mysql2Adapter do
|
||||||
|
it "should be able to connect" do
|
||||||
|
lambda {
|
||||||
|
ActiveRecord::Base.establish_connection(:adapter => 'mysql2')
|
||||||
|
}.should_not raise_error(Mysql2::Error)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "once connected" do
|
||||||
|
before(:each) do
|
||||||
|
@connection = ActiveRecord::Base.connection
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should be able to execute a raw query" do
|
||||||
|
@connection.execute("SELECT 1 as one").first['one'].should eql(1)
|
||||||
|
@connection.execute("SELECT NOW() as n").first['n'].class.should eql(Time)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue