Skip to content

Commit

Permalink
Merge 3f4b640 into 67fcfef
Browse files Browse the repository at this point in the history
  • Loading branch information
knu committed Jul 25, 2014
2 parents 67fcfef + 3f4b640 commit 8a99f70
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 22 deletions.
3 changes: 3 additions & 0 deletions config/initializers/ar_mysql_column_charset.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ActiveSupport.on_load :active_record do
require 'ar_mysql_column_charset'
end
74 changes: 74 additions & 0 deletions db/migrate/20140725064905_set_charset_for_mysql.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
class SetCharsetForMysql < ActiveRecord::Migration
def all_models
@all_models ||= [
Agent,
AgentLog,
Contact,
Event,
Link,
Scenario,
ScenarioMembership,
User,
UserCredential,
]
end

def change
conn = ActiveRecord::Base.connection

# This is migration is for MySQL only.
return unless conn.is_a?(ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter)

reversible do |dir|
dir.up do
all_models.each { |model|
table_name = model.table_name

# `contacts` may not exist
next unless connection.table_exists? table_name

model.columns.each { |column|
name = column.name
type = column.type
limit = column.limit
options = {
limit: limit,
null: column.null,
default: column.default,
}

case type
when :string, :text
case name
when 'username'
options.update(limit: 767 / 4, charset: 'utf8mb4', collation: 'utf8mb4_bin')
when 'message', 'options', 'name', 'memory',
'handler', 'last_error', 'payload', 'description'
options.update(charset: 'utf8mb4', collation: 'utf8mb4_bin')
# Below is a bit of paranoia
when 'guid'
options.update(charset: 'ascii', collation: 'ascii_bin')
when 'email'
options.update(collation: 'utf8_bin')
else
next
end
else
next
end

change_column table_name, name, type, options
}

execute 'ALTER TABLE %s CHARACTER SET utf8 COLLATE utf8_general_ci' % table_name
}

execute 'ALTER DATABASE %s CHARACTER SET utf8 COLLATE utf8_general_ci' % conn.current_database
end

dir.down do
# Do nada; no use to go back
end
end
end
end
44 changes: 22 additions & 22 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20140605032822) do
ActiveRecord::Schema.define(version: 20140725064905) do

create_table "agent_logs", force: true do |t|
t.integer "agent_id", null: false
t.text "message", limit: 16777215, null: false
t.text "message", limit: 16777215, null: false, charset: "utf8mb4", collation: "utf8mb4_bin"
t.integer "level", default: 3, null: false
t.integer "inbound_event_id"
t.integer "outbound_event_id"
Expand All @@ -25,24 +25,24 @@

create_table "agents", force: true do |t|
t.integer "user_id"
t.text "options", limit: 16777215
t.text "options", limit: 16777215, charset: "utf8mb4", collation: "utf8mb4_bin"
t.string "type"
t.string "name"
t.string "name", charset: "utf8mb4", collation: "utf8mb4_bin"
t.string "schedule"
t.integer "events_count"
t.datetime "last_check_at"
t.datetime "last_receive_at"
t.integer "last_checked_event_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "memory", limit: 2147483647
t.text "memory", limit: 2147483647, charset: "utf8mb4", collation: "utf8mb4_bin"
t.datetime "last_web_request_at"
t.datetime "last_event_at"
t.datetime "last_error_log_at"
t.integer "keep_events_for", default: 0, null: false
t.boolean "propagate_immediately", default: false, null: false
t.boolean "disabled", default: false, null: false
t.string "guid", null: false
t.string "guid", null: false, charset: "ascii", collation: "ascii_bin"
end

add_index "agents", ["guid"], name: "index_agents_on_guid", using: :btree
Expand All @@ -53,8 +53,8 @@
create_table "delayed_jobs", force: true do |t|
t.integer "priority", default: 0
t.integer "attempts", default: 0
t.text "handler", limit: 16777215
t.text "last_error", limit: 16777215
t.text "handler", limit: 16777215, charset: "utf8mb4", collation: "utf8mb4_bin"
t.text "last_error", limit: 16777215, charset: "utf8mb4", collation: "utf8mb4_bin"
t.datetime "run_at"
t.datetime "locked_at"
t.datetime "failed_at"
Expand All @@ -71,7 +71,7 @@
t.integer "agent_id"
t.decimal "lat", precision: 15, scale: 10
t.decimal "lng", precision: 15, scale: 10
t.text "payload", limit: 2147483647
t.text "payload", limit: 2147483647, charset: "utf8mb4", collation: "utf8mb4_bin"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "expires_at"
Expand Down Expand Up @@ -103,13 +103,13 @@
add_index "scenario_memberships", ["scenario_id"], name: "index_scenario_memberships_on_scenario_id", using: :btree

create_table "scenarios", force: true do |t|
t.string "name", null: false
t.string "name", null: false, charset: "utf8mb4", collation: "utf8mb4_bin"
t.integer "user_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.text "description"
t.text "description", charset: "utf8mb4", collation: "utf8mb4_bin"
t.boolean "public", default: false, null: false
t.string "guid", null: false
t.string "guid", null: false, charset: "ascii", collation: "ascii_bin"
t.string "source_url"
end

Expand All @@ -127,25 +127,25 @@
add_index "user_credentials", ["user_id", "credential_name"], name: "index_user_credentials_on_user_id_and_credential_name", unique: true, using: :btree

create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "email", default: "", null: false, collation: "utf8_bin"
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0
t.integer "sign_in_count", default: 0
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin", default: false, null: false
t.integer "failed_attempts", default: 0
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin", default: false, null: false
t.integer "failed_attempts", default: 0
t.string "unlock_token"
t.datetime "locked_at"
t.string "username", null: false
t.string "invitation_code", null: false
t.integer "scenario_count", default: 0, null: false
t.string "username", limit: 191, null: false, charset: "utf8mb4", collation: "utf8mb4_bin"
t.string "invitation_code", null: false
t.integer "scenario_count", default: 0, null: false
end

add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
Expand Down
80 changes: 80 additions & 0 deletions lib/ar_mysql_column_charset.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
require 'active_record'

module ActiveRecord::ConnectionAdapters
class ColumnDefinition
module CharsetSupport
attr_accessor :charset, :collation
end

prepend CharsetSupport
end

class TableDefinition
module CharsetSupport
def new_column_definition(name, type, options)
column = super
column.charset = options[:charset]
column.collation = options[:collation]
column
end
end

prepend CharsetSupport
end

class AbstractMysqlAdapter
module CharsetSupport
def prepare_column_options(column, types)
spec = super
conn = ActiveRecord::Base.connection
spec[:charset] = column.charset.inspect if column.charset && column.charset != conn.charset
spec[:collation] = column.collation.inspect if column.collation && column.collation != conn.collation
spec
end

def migration_keys
super + [:charset, :collation]
end
end

prepend CharsetSupport

class SchemaCreation
module CharsetSupport
def column_options(o)
column_options = super
column_options[:charset] = o.charset unless o.charset.nil?
column_options[:collation] = o.collation unless o.collation.nil?
column_options
end

def add_column_options!(sql, options)
if options[:charset]
sql << " CHARACTER SET #{options[:charset]}"
end

if options[:collation]
sql << " COLLATE #{options[:collation]}"
end

super
end
end

prepend CharsetSupport
end

class Column
module CharsetSupport
attr_reader :charset

def initialize(*args)
super
@charset = @collation[/\A[^_]+/] unless @collation.nil?
end
end

prepend CharsetSupport
end
end
end if Module.method_defined?(:prepend) # ruby >=2.0

0 comments on commit 8a99f70

Please sign in to comment.