diff --git a/enum_column.gemspec b/enum_column.gemspec index ec33446..772ce95 100644 --- a/enum_column.gemspec +++ b/enum_column.gemspec @@ -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 - diff --git a/lib/enum/enum_adapter.rb b/lib/enum/enum_adapter.rb index ede5cb6..b7b6b0c 100644 --- a/lib/enum/enum_adapter.rb +++ b/lib/enum/enum_adapter.rb @@ -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 diff --git a/lib/enum/enum_column_adapter.rb b/lib/enum/enum_column_adapter.rb new file mode 100644 index 0000000..4f95271 --- /dev/null +++ b/lib/enum/enum_column_adapter.rb @@ -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 diff --git a/lib/enum/enum_type.rb b/lib/enum/enum_type.rb new file mode 100644 index 0000000..9ae0678 --- /dev/null +++ b/lib/enum/enum_type.rb @@ -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 diff --git a/lib/enum/mysql_adapter.rb b/lib/enum/mysql_adapter.rb index 7ce64d5..d7729f5 100644 --- a/lib/enum/mysql_adapter.rb +++ b/lib/enum/mysql_adapter.rb @@ -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 \ No newline at end of file +end + +if adapter_class + adapter_class.prepend(EnumColumn::ConnectionAdapters::EnumAdapter) +end diff --git a/lib/enum/quoting.rb b/lib/enum/quoting.rb index 637ac40..1b6c1f9 100644 --- a/lib/enum/quoting.rb +++ b/lib/enum/quoting.rb @@ -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 diff --git a/lib/enum/schema_statements.rb b/lib/enum/schema_statements.rb deleted file mode 100644 index 6895bd8..0000000 --- a/lib/enum/schema_statements.rb +++ /dev/null @@ -1,27 +0,0 @@ -module ActiveRecord - module ConnectionAdapters # :nodoc: - module SchemaStatements - alias __type_to_sql_enum type_to_sql - - # 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) #:nodoc: - if type == :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 - __type_to_sql_enum(type, limit, precision, scale) - end - end - end - end -end diff --git a/lib/enum_column.rb b/lib/enum_column.rb index 7d951bb..fe343b3 100644 --- a/lib/enum_column.rb +++ b/lib/enum_column.rb @@ -3,8 +3,9 @@ class EnumColumnRailtie < Rails::Railtie initializer 'enum_column.initialize', :after => 'active_record.initialize_database' do |app| ActiveSupport.on_load :active_record do require 'enum/mysql_adapter' + require 'enum/enum_type' require 'enum/enum_adapter' - require 'enum/schema_statements' + require 'enum/enum_column_adapter' require 'enum/schema_definitions' require 'enum/quoting' require 'enum/validations' @@ -15,4 +16,4 @@ class EnumColumnRailtie < Rails::Railtie end end end -end \ No newline at end of file +end