Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proper fix for Rails 4.2 #27

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a08246f
Avoid typecasting unexpected strings to symbols to prevent DoS due to…
HonoreDB Jun 27, 2013
be82807
Slight code cleanup
HonoreDB Jul 17, 2013
3ca204e
Assume ownership, update README
HonoreDB Aug 6, 2013
0d6797e
Merge pull request #1 from mdsol/develop
mtanasie Aug 6, 2013
cbca08a
Rename initializer file to match new gem name
HonoreDB Aug 8, 2013
8ffa96e
makes compatible with Mysql2SpatialAdapter
agodel Jul 1, 2015
01be142
makes gem compatible with mysql2spatial adapter
agodel Jul 2, 2015
3ae9184
removes commented code
agodel Jul 2, 2015
04f27ba
Merge pull request #2 from mdsol/compatible_with_spatial_adapter
HonoreDB Jul 2, 2015
a25508b
Merge pull request #3 from mdsol/develop
HonoreDB Jul 2, 2015
b59ec1d
V0.1.5: Move alias statements to after method definitions
stanimal Aug 18, 2015
ec80e81
Revert alias lines being moved
Aug 19, 2015
a760013
Fixes and compatability with Rails 4.2
Aug 20, 2015
504730c
Update version
Aug 20, 2015
8dd883a
Backwards compatability for Rails 4.1
Aug 20, 2015
074d852
Prevent aliasing of initialize_type_map on older Rails versions
Aug 20, 2015
c98e7ec
Protect type_cast_from_database from bc breaks
Aug 20, 2015
64f2552
Situational method declaration based on Rails versions
Aug 20, 2015
c3f51a0
Restore simplified_type
Aug 20, 2015
afd4e47
See if method_defined is more reliable
Aug 20, 2015
bf6e15d
Turns out that instance_methods and private_instance_methods are the …
Aug 20, 2015
0088bb1
Must not forget about forwards compatability
Aug 20, 2015
00e451e
Add parameter to type_cast_for_database
Aug 20, 2015
b269e21
Bump to 0.1.7: Fix mapping of nil value for enum
stanimal Aug 31, 2015
0e5bea9
v0.1.8: Fix default value not returning as a symbol
Sep 14, 2015
7f426ca
Version bump the gemspec to 0.1.8
Sep 14, 2015
9b29aff
Add new adapter name and bump gemspec
May 9, 2017
96dcebf
Remove klass alias and method as Rails5 seems to have deprecated it
May 9, 2017
2e7d879
Bump gemspec to 5.0.0
May 9, 2017
ebffc00
Remove second argument in enum_column quoting for Rails 5.1
May 12, 2017
a1db70c
Implement modified ColumnDumper for enum type
May 17, 2017
f7899cb
Utilize the new prepend methodology and add the new register_type to …
May 19, 2017
6e7ec8d
Version bump to 5.1.1
May 19, 2017
3440eaa
Fix type_to_sql method to use the new keyword argument syntax
May 29, 2017
9e81474
limit var in type_to_sql is now direct, not a hash
May 31, 2017
17b6315
Set default parameter
stanimal Aug 9, 2018
c3f769b
Simple retrofit to ensure that enum_column doesn't collide when testi…
Jun 27, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 13 additions & 39 deletions enum_column.gemspec
Original file line number Diff line number Diff line change
@@ -1,43 +1,17 @@
# -*- encoding: utf-8 -*-
# stub: enum_column3 0.1.4 ruby lib

Gem::Specification.new do |s|
s.name = %q{enum_column3}
s.version = "0.1.4"
s.authors = ['Nick Pohodnya']
s.name = "enum_column3"
s.version = "5.1.1"

s.files = [
"README.txt",
"LICENSE",
"init.rb",
"lib/enum_column.rb",
"lib/enum_column3.rb",
"lib/enum/active_record_helper.rb",
"lib/enum/enum_adapter.rb",
"lib/enum/mysql_adapter.rb",
"lib/enum/quoting.rb",
"lib/enum/schema_definitions.rb",
"lib/enum/schema_statements.rb",
"lib/enum/validations.rb"
]
s.homepage = %q{http://github.com/electronick/enum_column}
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.require_paths = ["lib"]
s.summary = %q{Enable enum type for MySQL db.}
s.test_files = [
"test/test_helper.rb",
"test/db/schema.rb",
"test/fixtures/enumeration.rb",
"test/fixtures/enum_controller.rb",
"test/enum_controller_test.rb",
"test/enum_mysql_test.rb"
]

if s.respond_to? :specification_version then
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
s.specification_version = 3

if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
else
end
else
end

s.authors = ["Nick Pohodnya"]
s.date = "2015-08-19"
s.files = ["LICENSE", "README.txt", "init.rb", "lib/enum/active_record_helper.rb", "lib/enum/enum_adapter.rb", "lib/enum/mysql_adapter.rb", "lib/enum/quoting.rb", "lib/enum/schema_definitions.rb", "lib/enum/schema_statements.rb", "lib/enum/validations.rb", "lib/enum_column.rb", "lib/enum_column3.rb", "test/db/schema.rb", "test/enum_controller_test.rb", "test/enum_mysql_test.rb", "test/fixtures/enum_controller.rb", "test/fixtures/enumeration.rb", "test/test_helper.rb"]
s.homepage = "http://github.com/electronick/enum_column"
s.rubygems_version = "2.4.8"
s.summary = "Enable enum type for MySQL db."
s.test_files = ["test/test_helper.rb", "test/db/schema.rb", "test/fixtures/enumeration.rb", "test/fixtures/enum_controller.rb", "test/enum_controller_test.rb", "test/enum_mysql_test.rb"]
end

94 changes: 17 additions & 77 deletions lib/enum/enum_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,85 +1,25 @@
# This module provides all the column helper methods to deal with the
# values and adds the common type management code for the adapters.


# try rails 3.1, then rails 3.2+, mysql column adapters
column_class = if defined? ActiveRecord::ConnectionAdapters::Mysql2Column
ActiveRecord::ConnectionAdapters::Mysql2Column
elsif defined? ActiveRecord::ConnectionAdapters::MysqlColumn
ActiveRecord::ConnectionAdapters::MysqlColumn
elsif defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column
ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column
elsif defined? ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
else
ObviousHint::NoMysqlAdapterFound
adapter_class = if defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter
ActiveRecord::ConnectionAdapters::Mysql2Adapter
elsif defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
ActiveRecord::ConnectionAdapters::MysqlAdapter
end

column_class.module_eval do

alias __klass_enum klass
# The class for enum is Symbol.
def klass
if type == :enum
Symbol
else
__klass_enum
end
end

alias __type_cast_enum type_cast
# Convert to a symbol.
def type_cast(value)
if type == :enum
self.class.value_to_symbol(value)
else
__type_cast_enum(value)
end
end

alias __type_cast_code_enum type_cast_code
# Code to convert to a symbol.
def type_cast_code(var_name)
if type == :enum
"#{self.class.name}.value_to_symbol(#{var_name})"
else
__type_cast_code_enum(var_name)
end
end

class << self
# Safely convert the value to a symbol.
def value_to_symbol(value)
case value
when Symbol
value
when String
value.empty? ? nil : value.intern
else
nil
if adapter_class
adapter_class.class_eval do

protected
if instance_methods.include?(:initialize_type_map)
def initialize_type_map_with_enum_types(m)
initialize_type_map_without_enum_types(m)
m.register_type(%r(enum)i) do |sql_type|
limit = sql_type.sub(/^enum\('(.+)'\)/i, '\1').split("','").map { |v| v.intern }
ActiveRecord::Type::Enum.new(limit: limit)
end
end
alias_method_chain :initialize_type_map, :enum_types
end
end
end

private
alias __simplified_type_enum simplified_type
# The enum simple type.
def simplified_type(field_type)
if field_type =~ /enum/i
:enum
else
__simplified_type_enum(field_type)
end
end

alias __extract_limit_enum extract_limit
def extract_limit(sql_type)
if sql_type =~ /^enum/i
sql_type.sub(/^enum\('(.+)'\)/i, '\1').split("','").map { |v| v.intern }
else
__extract_limit_enum(sql_type)
end
end


end
111 changes: 111 additions & 0 deletions lib/enum/enum_column_adapter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# This module provides all the column helper methods to deal with the
# values and adds the common type management code for the adapters.


# try rails 3.1, then rails 3.2+, mysql column adapters
column_class = if defined? ActiveRecord::ConnectionAdapters::Mysql2Column
ActiveRecord::ConnectionAdapters::Mysql2Column
elsif defined? ActiveRecord::ConnectionAdapters::MysqlColumn
ActiveRecord::ConnectionAdapters::MysqlColumn
elsif defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column
ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column
elsif defined? ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
elsif defined? ActiveRecord::ConnectionAdapters::MySQL::Column
ActiveRecord::ConnectionAdapters::MySQL::Column
end

if column_class
column_class.class_eval do

if instance_methods.include?(:extract_default)
alias __extract_default_enum extract_default
def extract_default
if type == :enum
if @default == '' || @default.nil?
@default = nil
else
@default = @default.intern
end
end
__extract_default_enum
end
end

def __enum_type_cast(value)
if type == :enum
self.class.value_to_symbol(value)
else
__type_cast_enum(value)
end
end

if instance_methods.include?(:type_cast_from_database)
alias __type_cast_enum type_cast_from_database
# Convert to a symbol.
def type_cast_from_database(value)
__enum_type_cast(value)
end
elsif instance_methods.include?(:type_cast)
alias __type_cast_enum type_cast
def type_cast(value)
__enum_type_cast(value)
end
end

# Deprecated in Rails 4.1
if instance_methods.include?(:type_cast_code)
alias __type_cast_code_enum type_cast_code
# Code to convert to a symbol.
def type_cast_code(var_name)
if type == :enum
"#{self.class.name}.value_to_symbol(#{var_name})"
else
__type_cast_code_enum(var_name)
end
end
end

class << self
# Safely convert the value to a symbol.
def value_to_symbol(value)
case value
when Symbol
value
when String
value.empty? ? nil : value.intern
else
nil
end
end
end

private

# Deprecated in Rails 4.2
if private_instance_methods.include?(:simplified_type)
alias __simplified_type_enum simplified_type
# The enum simple type.
def simplified_type(field_type)
if field_type =~ /enum/i
:enum
else
__simplified_type_enum(field_type)
end
end
end

# Deprecated in Rails 4.2
if private_instance_methods.include?(:extract_limit)
alias __extract_limit_enum extract_limit
def extract_limit(sql_type)
if sql_type =~ /^enum/i
sql_type.sub(/^enum\('(.+)'\)/i, '\1').split("','").map { |v| v.intern }
else
__extract_limit_enum(sql_type)
end
end
end

end
end
29 changes: 29 additions & 0 deletions lib/enum/enum_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
if defined? ActiveRecord::Type::Value
module ActiveRecord
module Type
class Enum < Value # :nodoc:
def type
:enum
end

def type_cast_for_database(value)
if value.nil? || value == ''
nil
else
value.to_s
end
end

private

def cast_value(value)
if value.nil? || value == ''
nil
else
value.to_sym
end
end
end
end
end
end
53 changes: 46 additions & 7 deletions lib/enum/mysql_adapter.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,56 @@
adapter_class = if defined? ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
# elsif defined? ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
# ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter
elsif defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter
ActiveRecord::ConnectionAdapters::Mysql2Adapter
elsif defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
ActiveRecord::ConnectionAdapters::MysqlAdapter
end

adapter_class.module_eval do
alias __native_database_types_enum native_database_types
module EnumColumn
module ConnectionAdapters
module EnumAdapter

def native_database_types #:nodoc
types = __native_database_types_enum
types[:enum] = { :name => "enum" }
types
def native_database_types #:nodoc
types = super
types[:enum] = { :name => "enum" }
types
end

# Add enumeration support for schema statement creation. This
# will have to be adapted for every adapter if the type requires
# anything by a list of allowed values. The overrides the standard
# type_to_sql method and chains back to the default. This could
# be done on a per adapter basis, but is generalized here.
#
# will generate enum('a', 'b', 'c') for :limit => [:a, :b, :c]
def type_to_sql(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **) # :nodoc:
if type.to_s == 'enum'
native = native_database_types[type]
column_type_sql = (native || {})[:name] || 'enum'

column_type_sql << "(#{limit.map { |v| quote(v) }.join(',')})"

column_type_sql
else
super(type, limit: limit, precision: precision, scale: scale, unsigned: unsigned)
end
end

private
def initialize_type_map(m = type_map)
super

m.register_type(%r(enum)i) do |sql_type|
limit = sql_type.sub(/^enum\('(.+)'\)/i, '\1').split("','").map { |v| v.intern }
ActiveRecord::Type::Enum.new(limit: limit)
end
end
end
end
end
end

if adapter_class
adapter_class.prepend(EnumColumn::ConnectionAdapters::EnumAdapter)
end
4 changes: 2 additions & 2 deletions lib/enum/quoting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ module Quoting

# Quote a symbol as a normal string. This will support quoting of
# enumerated values.
def quote(value, column = nil)
def quote(value)
if !value.is_a? Symbol
__quote_enum(value, column)
__quote_enum(value)
else
ActiveRecord::Base.send(:quote_bound_value, value.to_s)
end
Expand Down
Loading