activerecord_enum 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in activerecord_enum.gemspec
4
+ gemspec
data/README.markdown ADDED
@@ -0,0 +1,16 @@
1
+ # ActiveRecord Enum
2
+
3
+ Provides ActiveRecord support for the nonstandard `ENUM` and `SET` data types.
4
+
5
+ ## Hypothetically asked questions
6
+
7
+ ### Y U NO WORK?!
8
+ Sorry, it currently only works with Rails 3.0.x and the mysql2 adapter. I plan to support 3.1.x and other adapters at some point.
9
+
10
+ ### Why doesn't it validate anything?
11
+ Right now it really only supports schema operations - attribute access is left untouched. I'll be working on that too at some point.
12
+
13
+ ### Nonstandard SQL?! What's your problem, jerkweed?
14
+ This isn't a plugin everyone should use. There are a number of plugins to simulate enum behavior backed by standard datatypes. Personally, I like [https://github.com/nofxx/symbolize].
15
+
16
+ However, sometimes we can't or won't avoid working with these data types. When that happens, I got you covered.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake'
5
+ desc 'Default: run unit tests.'
6
+ task :default => :spec
7
+
8
+ require "rspec/core/rake_task"
9
+ desc 'Run the test suite.'
10
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "activerecord_enum/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "activerecord_enum"
7
+ s.version = ActiverecordEnum::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Ian Young"]
10
+ s.email = ["ian.greenleaf+github@gmail.com"]
11
+ s.homepage = ""
12
+ s.summary = %q{Enum data types for ActiveRecord}
13
+ s.description = %q{Adds the ENUM data type natively to ActiveRecord.}
14
+
15
+ s.rubyforge_project = "activerecord_enum"
16
+
17
+ s.add_dependency "activerecord", "~> 3.0.9"
18
+ s.add_development_dependency "rake"
19
+ s.add_development_dependency "bundler"
20
+ s.add_development_dependency "mysql2", "~> 0.2.0"
21
+ s.add_development_dependency "rspec", "~> 2.6.0"
22
+
23
+ s.files = `git ls-files`.split("\n")
24
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
25
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
26
+ s.require_paths = ["lib"]
27
+ end
@@ -0,0 +1,3 @@
1
+ module ActiverecordEnum
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,89 @@
1
+ require 'active_record'
2
+ require 'active_record/connection_adapters/mysql2_adapter'
3
+ require 'active_record/connection_adapters/abstract/schema_definitions.rb'
4
+
5
+ module ActiverecordEnum
6
+ end
7
+
8
+ module ActiveRecord
9
+ module ConnectionAdapters
10
+ class Mysql2Adapter < AbstractAdapter
11
+ def native_database_types_with_enum
12
+ native_database_types_without_enum.merge( :enum => { :name => "enum" }, :set => { :name => "set" } )
13
+ end
14
+ alias_method :native_database_types_without_enum, :native_database_types
15
+ alias_method :native_database_types, :native_database_types_with_enum
16
+
17
+ def type_to_sql_with_enum type, limit=nil, *args
18
+ if type.to_s == "enum" || type.to_s == "set"
19
+ "#{type}(#{quoted_comma_list limit})"
20
+ else
21
+ type_to_sql_without_enum type, limit, *args
22
+ end
23
+ end
24
+ alias_method :type_to_sql_without_enum, :type_to_sql
25
+ alias_method :type_to_sql, :type_to_sql_with_enum
26
+
27
+ private
28
+ def quoted_comma_list list
29
+ list.to_a.map{|n| "'#{n}'"}.join(",")
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ module ActiveRecord
36
+ module ConnectionAdapters
37
+ class Column
38
+ def initialize_with_enum name, default, sql_type=nil, *args
39
+ initialize_without_enum name, default, sql_type, *args
40
+ @type = simplified_type_with_enum sql_type
41
+ @limit = extract_limit_with_enum sql_type
42
+ @default = extract_default_with_enum default
43
+ end
44
+ alias_method :initialize_without_enum, :initialize
45
+ alias_method :initialize, :initialize_with_enum
46
+
47
+ def simplified_type_with_enum field_type
48
+ if field_type =~ /enum|set/i
49
+ $&.to_sym
50
+ else
51
+ simplified_type field_type
52
+ end
53
+ end
54
+
55
+ def extract_limit_with_enum field_type
56
+ if field_type =~ /(?:enum|set)\(([^)]+)\)/i
57
+ $1.scan( /'([^']*)'/ ).flatten
58
+ else
59
+ extract_limit field_type
60
+ end
61
+ end
62
+
63
+ def extract_default_with_enum default
64
+ if type == :set
65
+ default.split "," if default.present?
66
+ else
67
+ extract_default default
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ module ActiveRecord
74
+ module ConnectionAdapters
75
+ class TableDefinition
76
+ def enum *args
77
+ options = args.extract_options!
78
+ column_names = args
79
+ column_names.each { |name| column(name, :enum, options) }
80
+ end
81
+ def set *args
82
+ options = args.extract_options!
83
+ options[:default] = options[:default].join "," if options[:default].present?
84
+ column_names = args
85
+ column_names.each { |name| column(name, :set, options) }
86
+ end
87
+ end
88
+ end
89
+ end
data/spec/enum_spec.rb ADDED
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe "ENUM datatype" do
4
+
5
+ describe "schema dump" do
6
+ before { load_schema "enum_old" }
7
+ subject { dumped_schema }
8
+
9
+ it "dumps native format" do
10
+ subject.should match %r{t\.enum\s+"color",\s+:limit => \["blue", "red", "yellow"\]}
11
+ end
12
+
13
+ it "dumps default option" do
14
+ subject.should match %r{t\.enum\s+"color",.+:default => "red"}
15
+ end
16
+
17
+ it "dumps null option" do
18
+ subject.should match %r{t\.enum\s+"color",.+:null => false$}
19
+ end
20
+ end
21
+
22
+ describe "schema loading" do
23
+ before { load_schema "enum_new" }
24
+ subject { ActiveRecord::Base.connection.select_one "SHOW FIELDS FROM balloons WHERE Field='color'" }
25
+
26
+ it "loads native format" do
27
+ subject[ "Type" ].should == "enum('red','gold')"
28
+ end
29
+
30
+ it "loads default option" do
31
+ subject[ "Default" ].should == "gold"
32
+ end
33
+
34
+ it "loads null option" do
35
+ subject[ "Null" ].should == "NO"
36
+ end
37
+
38
+ it "loads native column format" do
39
+ subject = ActiveRecord::Base.connection.select_one "SHOW FIELDS FROM balloons WHERE Field='size'"
40
+ subject[ "Type" ].should == "enum('small','medium','large')"
41
+ end
42
+ end
43
+
44
+ describe "validation" do
45
+ it "validates assigned value is member of the list"
46
+ it "allows nil when null enabled"
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :balloons, :force => true do |t|
3
+ t.integer "id"
4
+ t.enum "color", :limit => ['red', 'gold'], :default => 'gold', :null => false
5
+ t.column "size", :enum, :limit => ['small', 'medium', 'large']
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :aircraft, :force => true do |t|
3
+ t.integer "id"
4
+ t.column "color", "enum('blue','red','yellow')", :default => 'red', :null => false
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :balloons, :force => true do |t|
3
+ t.integer "id"
4
+ t.set "ribbons", :limit => ['red', 'green', 'gold'], :default => ['gold', 'green'], :null => false
5
+ t.column "gasses", :set, :limit => ['helium', 'hydrogen']
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+ ActiveRecord::Schema.define do
2
+ create_table :aircraft, :force => true do |t|
3
+ t.integer "id"
4
+ t.column "gadgets", "set('propeller','tail gun','gps')", :default => 'propeller,gps', :null => false
5
+ end
6
+ end
data/spec/set_spec.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe "SET datatype" do
4
+
5
+ describe "schema dump" do
6
+ before { load_schema "set_old" }
7
+ subject { dumped_schema }
8
+
9
+ it "dumps native format" do
10
+ subject.should match %r{t\.set\s+"gadgets",\s+:limit => \["propeller", "tail gun", "gps"\]}
11
+ end
12
+
13
+ it "dumps default option" do
14
+ subject.should match %r{t\.set\s+"gadgets",.+:default => \["propeller", "gps"\]}
15
+ end
16
+
17
+ it "dumps null option" do
18
+ subject.should match %r{t\.set\s+"gadgets",.+:null => false$}
19
+ end
20
+ end
21
+
22
+ describe "schema loading" do
23
+ before { load_schema "set_new" }
24
+ subject { ActiveRecord::Base.connection.select_one "SHOW FIELDS FROM balloons WHERE Field='ribbons'" }
25
+
26
+ it "loads native format" do
27
+ subject[ "Type" ].should == "set('red','green','gold')"
28
+ end
29
+
30
+ it "loads default option" do
31
+ subject[ "Default" ].should == "green,gold"
32
+ end
33
+
34
+ it "loads null option" do
35
+ subject[ "Null" ].should == "NO"
36
+ end
37
+
38
+ it "loads native column format" do
39
+ subject = ActiveRecord::Base.connection.select_one "SHOW FIELDS FROM balloons WHERE Field='gasses'"
40
+ subject[ "Type" ].should == "set('helium','hydrogen')"
41
+ end
42
+ end
43
+
44
+ describe "assignment" do
45
+ it "accepts single value"
46
+ it "accepts array of values"
47
+ it "accepts comma-separated values"
48
+ end
49
+
50
+ describe "validation" do
51
+ it "validates assigned values are members of the list"
52
+ it "allows nil when null enabled"
53
+ it "allows empty list"
54
+ end
55
+ end
@@ -0,0 +1,33 @@
1
+ require 'rspec'
2
+ require 'activerecord_enum'
3
+
4
+ def load_schema filename
5
+ # silence verbose schema loading
6
+ original_stdout = $stdout
7
+ $stdout = StringIO.new
8
+
9
+ root = File.expand_path(File.dirname(__FILE__))
10
+ load root + "/schema/#{filename}.rb"
11
+
12
+ ensure
13
+ $stdout = original_stdout
14
+ end
15
+
16
+ def dumped_schema
17
+ stream = StringIO.new
18
+ ActiveRecord::SchemaDumper.ignore_tables = []
19
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
20
+ stream.string.lines.select {|l| /^\s*#/.match(l).nil? }.join
21
+ end
22
+
23
+ ActiveRecord::Base.configurations = {
24
+ "enum_test" => {
25
+ :adapter => "mysql2",
26
+ :host => "localhost",
27
+ :username => "enum_test",
28
+ :password => "enum_test",
29
+ :database => "enum_test",
30
+ :socket => "/tmp/mysql.sock"
31
+ },
32
+ }
33
+ ActiveRecord::Base.establish_connection "enum_test"
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord_enum
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Ian Young
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-08-19 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 21
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 9
34
+ version: 3.0.9
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: bundler
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: mysql2
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ~>
72
+ - !ruby/object:Gem::Version
73
+ hash: 23
74
+ segments:
75
+ - 0
76
+ - 2
77
+ - 0
78
+ version: 0.2.0
79
+ type: :development
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec
83
+ prerelease: false
84
+ requirement: &id005 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ hash: 23
90
+ segments:
91
+ - 2
92
+ - 6
93
+ - 0
94
+ version: 2.6.0
95
+ type: :development
96
+ version_requirements: *id005
97
+ description: Adds the ENUM data type natively to ActiveRecord.
98
+ email:
99
+ - ian.greenleaf+github@gmail.com
100
+ executables: []
101
+
102
+ extensions: []
103
+
104
+ extra_rdoc_files: []
105
+
106
+ files:
107
+ - .gitignore
108
+ - Gemfile
109
+ - README.markdown
110
+ - Rakefile
111
+ - activerecord_enum.gemspec
112
+ - lib/activerecord_enum.rb
113
+ - lib/activerecord_enum/version.rb
114
+ - spec/enum_spec.rb
115
+ - spec/schema/enum_new.rb
116
+ - spec/schema/enum_old.rb
117
+ - spec/schema/set_new.rb
118
+ - spec/schema/set_old.rb
119
+ - spec/set_spec.rb
120
+ - spec/spec_helper.rb
121
+ has_rdoc: true
122
+ homepage: ""
123
+ licenses: []
124
+
125
+ post_install_message:
126
+ rdoc_options: []
127
+
128
+ require_paths:
129
+ - lib
130
+ required_ruby_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ hash: 3
136
+ segments:
137
+ - 0
138
+ version: "0"
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ hash: 3
145
+ segments:
146
+ - 0
147
+ version: "0"
148
+ requirements: []
149
+
150
+ rubyforge_project: activerecord_enum
151
+ rubygems_version: 1.6.2
152
+ signing_key:
153
+ specification_version: 3
154
+ summary: Enum data types for ActiveRecord
155
+ test_files:
156
+ - spec/enum_spec.rb
157
+ - spec/schema/enum_new.rb
158
+ - spec/schema/enum_old.rb
159
+ - spec/schema/set_new.rb
160
+ - spec/schema/set_old.rb
161
+ - spec/set_spec.rb
162
+ - spec/spec_helper.rb